본 가이드는 쿠버네티스 API Server Security 핵심 가이드 및 실전 아키텍처의 핵심 개념, 실전 구성 명령어 및 아키텍처 베스트 프랙티스를 다룹니다. 클라우드 네이티브 및 인프라 엔지니어링 실무에 즉시 활용 가능하도록 체계적으로 정리했습니다.
📑 Table of Contents
- 1. Common
- • Manifests 오류 해결을 위한 로그분석
- 2. Audit-Logging
- • Setup for kube-apiserver
- 3. Admission-Controller
- • NodeRestriction (노드 제한)
- • AlwaysPullImages (이미지 항상 풀)
- • ImagePolicyWebhook (이미지 정책 웹훅)
- • PodSecurity (파드 보안 어드미션)
- 4. CSR Management
- • 1. Create CSR with Openssl
- • 2-1. Sign Certificate via Openssl Manually
- • 2-2. Sign Certificate via API
- • 3. Update Kubeconfig
Common
Manifests 오류 해결을 위한 로그분석
# 컨테이너 재시작여부 확인
crictl ps
# Manifest 문법오류 탐색 (컨테이너가 안뜨므로 치명적임)
journalctl -u kubelet | grep manifest
# 종료된 컨테이너 에러여부 탐색
cat /var/log/pods/kube-system_kube-apiserver-*/kube-apiserver/*.log
cat /var/log/containers/kube-apiserver-*.log
# 컨테이너 재시작: running 컨테이너를 재시작 할 경우
cd /etc/kubernetes/manifests
mv kube-apiserver.yaml ..
crictl ps
mv ../kube-apiserver.yaml .
# 컨테이너 재시작: crictl에서 컨테이너가 안뜨는 상태 (에러 후 복구)
systemctl restart kubelet
Audit-Logging
Setup for kube-apiserver
# 1. Create the directory
mkdir $target_log_dir
# 2. Edit Manifest
### 다음의 요구조건 사전 확인
#### policy_file
#### target_log_dir
#### target_log_file
#### maxsize
#### maxbackup
#### maxage
vi /etc/kubernetes/manifests/kube-apiserver.yaml
```
# enable Audit Logs
spec:
containers:
- command:
- kube-apiserver
- --audit-policy-file=$policy_file
- --audit-log-path=$target_log_dir/$target_log_file
- --audit-log-maxsize=$maxsize #요구조건 있을 경우
- --audit-log-maxbackup=$maxbackup #요구조건 있을 경우
- --audit-log-maxage=$maxage #요구조건 있을 경우
# add new VolumeMounts
volumeMounts:
- mountPath: $policy_file
name: audit-policy
readOnly: true
- mountPath: $target_log_dir
name: audit-logs
readOnly: false
# add new Volumes
volumes:
- name: audit-policy
hostPath:
path: $policy_file
type: File
- name: audit-logs
hostPath:
path: $target_log_dir
type: DirectoryOrCreate
`
# wait
watch crictl ps
Admission-Controller
vi /etc/kubernetes/manifests/kube-apiserver.yaml
```yaml
spec:
containers:
- command:
- kube-apiserver
... #add 1 line
- --enable-admission-plugins=<Plugin Name>
`
NodeRestriction (노드 제한)
Kubernetes의 NodeRestriction Admission Controller는 Kubelet이 API 서버를 통해 수정할 수 있는 Node 및 Pod 객체의 범위를 제한하여, 특정 노드가 탈취되더라도 클러스터 전체로 권한이 상승(Privilege Escalation)하는 것을 방지하는 중요한 보안 컴포넌트입니다.
1. 아키텍처 구조도 (Mermaid)
Kubelet이 API 요청을 보내고, kube-apiserver 내부에서 NodeRestriction이 요청을 검증 및 차단/허용하는 전체적인 아키텍처 흐름입니다.
2. 주요 동작 흐름 및 아키텍처 컴포넌트
- 주체 (Identity) 검증 (Authentication)
- Kubelet은 클러스터에 조인할 때
system:nodes그룹에 속하며,system:node:형식의 사용자명을 가집니다 (예:system:node:node-A). kube-apiserver는 클라이언트 인증서(x509) 또는 토큰을 통해 이 신원을 검증합니다.
- 노드 권한 인가 (Node Authorization)
- Kubelet의 API 요청은 먼저 Node Authorizer라는 특수 목적의 Authorization 모듈을 거칩니다.
- Node Authorizer는 Kubelet이 자신의 노드에 바인딩된 Pod, ConfigMap, Secret, PVC 등의 자원에 접근할 수 있도록 읽기 권한을 제어합니다.
- NodeRestriction Admission Controller (핵심)
인가 단계를 통과한 후, Admission Control 단계에서 NodeRestriction 플러그인이 최종적인 쓰기/수정(Write/Mutate) 권한을 세밀하게 제어합니다.
- Node 객체 보호:
system:node:node-A신원을 가진 Kubelet은 오직 자신의 노드 객체(node-A)만 수정할 수 있습니다.- 다른 노드(
node-B)의 상태를 업데이트하거나 삭제하려는 시도는 무조건 차단됩니다. - Pod 객체 보호:
- Kubelet은 오직 자신에게 스케줄링(bound)된 Pod만 생성, 수정, 삭제할 수 있습니다.
- 다른 노드에서 실행 중인 Pod를 임의로 조작할 수 없습니다.
- 보호된 라벨 (Protected Labels) 수정 제한:
node-restriction.kubernetes.io/프리픽스를 가진 라벨은 Kubelet이 스스로 추가, 수정, 삭제할 수 없습니다.- 이는 공격자가 노드에 특정 라벨을 임의로 붙여 포드 스케줄링(NodeSelector, Affinity)을 왜곡하는 공격을 방어하기 위함입니다.
- 1.16 버전부터는 Kubelet이 허용된 웰노운(Well-known) 라벨 이외의 임의 라벨(
kubernetes.io/또는k8s.io/하위)을 노드에 설정하는 것도 함께 방지합니다.
3. 보안 상의 이점 (Why NodeRestriction?)
| 시나리오 | NodeRestriction 미적용 시 | NodeRestriction 적용 시 |
|---|---|---|
| Worker Node-A 침해 | 공격자가 Node-A의 Kubelet 권한을 획득하여 Node-B의 설정을 임의 변경하거나, Node-B에 도는 민감한 Pod를 강제 종료/재스케줄링 할 수 있음. | 공격자는 오직 침해된 Node-A 범위 내에서만 영향력을 행사할 수 있으며, 타 노드(Node-B)로의 횡적 이동(Lateral Movement)이 원천 차단됨. |
| 노드 라벨 변조 | 공격자가 노드에 중요 라벨(예: role=database-host)을 부착하여 민감한 데이터 처리 Pod를 자기 노드로 유도하여 탈취함. |
Kubelet이 자체적으로 라벨을 변경할 수 없으므로(특히 보호된 라벨), 컨트롤 플레인을 통하지 않은 비인가 라벨링 공격이 무력화됨. |
공식문서 참조
https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction
유형: 검증(Validating)
이 어드미션 컨트롤러는 kubelet이 수정할 수 있는 Node 및 Pod 객체를 제한합니다. 이 어드미션 컨트롤러의 제한을 받으려면, kubelet은 system:nodes 그룹에 속한 자격 증명을 사용해야 하며, 사용자 이름은 system:node:<노드이름> 형태여야 합니다. 이러한 kubelet은 오직 자기 자신의 Node API 객체만 수정할 수 있고, 자신의 노드에 바인딩(할당)된 Pod API 객체만 수정할 수 있습니다. 또한, kubelet은 자신의 Node API 객체에서 테인트(Taint)를 업데이트하거나 제거할 수 없습니다.
NodeRestriction 어드미션 플러그인은 kubelet이 자신의 Node API 객체를 삭제하는 것을 방지하며, kubernetes-restriction.kubernetes.io/ 또는 k8s.io/ 접두사(Prefix) 아래에 있는 레이블을 수정할 때 다음과 같은 규칙을 강제합니다:
- 금지됨 (Kubelet의 수정이 차단됨):
node-restriction.kubernetes.io/접두사가 붙은 레이블: 이 접두사는 관리자가 워크로드 격리를 목적으로 Node 객체에 레이블을 지정할 수 있도록 예약된 공간입니다.node-role.kubernetes.io/접두사가 붙은 레이블 (예:node-role.kubernetes.io/control-plane): 권한이 없는 일반 노드가 스스로 클러스터 내의 특정 역할(Role)을 가졌다고 선언하는 것을 방지하기 위해 제한됩니다.- 허용됨 (Kubelet이 추가/제거/업데이트 가능):
kubernetes.io/hostnamekubernetes.io/archkubernetes.io/osbeta.kubernetes.io/instance-typenode.kubernetes.io/instance-typefailure-domain.beta.kubernetes.io/region(더 이상 사용되지 않음 / Deprecated)failure-domain.beta.kubernetes.io/zone(더 이상 사용되지 않음 / Deprecated)topology.kubernetes.io/regiontopology.kubernetes.io/zonekubelet.kubernetes.io/접두사가 붙은 레이블들node.kubernetes.io/접두사가 붙은 레이블들- 예약됨 (Reserved):
- kubelet이
kubernetes.io또는k8s.io접두사 아래에 있는 그 외의 다른 레이블을 사용하는 것은 제한됩니다.NodeRestriction어드미션 플러그인은 승인되지 않은 셀프 레이블 지정을 방지하기 위해 기본적으로 이러한 레이블을 허용하지 않지만, 향후 새로운 기능의 일부로서 이 접두사 아래의 추가 레이블을 허용할 수도 있습니다.
ServiceAccountNodeAudienceRestriction 기능 게이트(Feature Gate)가 활성화되면, 이 어드미션 플러그인은 kubelet이 TokenRequest API를 통해 서비스 어카운트 토큰을 요청할 수 있는 대상(Audience)도 제한합니다. kubelet은 해당 노드의 파드들이 이미 참조하고 있는 대상(프로젝티드 서비스 어카운트 토큰 볼륨 또는 CSI 드라이버 토큰 요청을 통해)이나, request-serviceaccounts-token-audience 동사를 사용하는 RBAC을 통해 명시적으로 권한을 부여받은 대상에 대해서만 토큰을 요청할 수 있습니다. 자세한 내용은 ‘서비스 어카운트 토큰 대상 제한(Service account token audience restriction)’을 참조하십시오.
향후 버전에서는 kubelet이 올바르게 작동하는 데 필요한 최소한의 권한 세트만 가질 수 있도록 추가적인 제한 사항이 더해질 수 있습니다.
시험 수행 Tip
/etc/kubernetes/manifests/kube-apiserver.yaml수정
# add 1 flagline
kube-apiserver --enable-admission-plugins=NodeRestriction
- 적용 테스트
ssh node01 #worker-node
export KUBECONFIG=/etc/kubernetes/kubelet.conf #kubectl 명령어 활성화
# 노드 스스로에 대한 node-restriction.kubernetes.io/* 라벨 수정 차단됨
k label node node01 node-restriction.kubernetes.io/two=123
```prompt
Error from server (Forbidden): nodes "node01" is forbidden: is not allowed to modify labels: node-restriction.kubernetes.io/two
`
# 컨트롤 플레인 노드 라벨 수정 차단됨
k label node controlplane killercoda/two=123
```prompt
Error from server (Forbidden): nodes "controlplane" is forbidden: User "system:node:node01" cannot get resource "nodes" in API group "" at the cluster scope: node 'node01' cannot read 'controlplane', only its own Node object
`
# 노드 스스로에 대한 적용범위 내의 라벨 수정 허용됨
k label node node01 test/two=123
```prompt
node/node01 labeled
`
# 컨트롤플레인에서는 모두 허용됨
AlwaysPullImages (이미지 항상 풀)
Kubernetes의 AlwaysPullImages Admission Controller는 모든 신규 Pod의 컨테이너 imagePullPolicy를 강제로 Always로 변경하거나 검증하여, 노드 로컬 캐시에 저장된 기존 이미지를 무단으로 재사용하는 것을 방지하고 항상 최신 이미지를 레지스트리로부터 명시적으로 다운로드하도록 강제하는 보안 컴포넌트입니다.
1. 아키텍처 구조도 (Mermaid)
사용자 요청이 오면 AlwaysPullImages 플러그인이 imagePullPolicy를 검증하고 변조(Mutate)하는 흐름입니다.
2. 주요 동작 흐름 및 아키텍처 컴포넌트
- Mutating 단계에서의 강제 적용 (Mutate)
- 사용자가 Pod 생성 시
imagePullPolicy를IfNotPresent또는Never로 설정하거나 아예 생략하더라도,AlwaysPullImages어드미션 컨트롤러는 이를 감지하여 해당 필드를Always로 강제 변조(Mutate)합니다.
- 다중 사용자 및 멀티테넌트 환경에서의 보안 강제 (Validate)
- 이 플러그인은 로컬 노드에 이미 캐싱된 다른 프로젝트나 사용자 소유의 프라이빗 이미지를 권한 없는 사용자가 컨테이너 이미지 이름만 알아내어 무단 사용하는 공격 시나리오를 효과적으로 방어합니다. 항상 레지스트리에 로그인하여 자격 증명(ImagePullSecrets)을 검증하도록 강제합니다.
3. 보안 상의 이점 (Why AlwaysPullImages?)
| 시나리오 | AlwaysPullImages 미적용 시 | AlwaysPullImages 적용 시 |
|---|---|---|
| 타 프로젝트 프라이빗 이미지 무단 도용 | 노드에 이미 캐시된 프라이빗 이미지 이름을 알아내어 imagePullPolicy: IfNotPresent로 설정하면, 본인의 레지스트리 토큰 없이도 타 사용자의 이미지를 띄울 수 있음. |
모든 파드가 생성될 때 항상 이미지 레지스트리로부터 이미지를 풀하도록 강제하므로, 올바른 imagePullSecrets가 없으면 파드 기동이 실패함. |
| 오래되거나 변조된 캐시 이미지 사용 | 이미지 태그가 업데이트되었음에도 노드 캐시의 구버전 이미지가 실행되어 일관되지 않은 동작이 발생할 수 있음. | 항상 최신 버전의 이미지를 레지스트리로부터 풀하여 실행 안정성을 유지함. |
공식문서 참조
https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages
유형: 변조(Mutating) 및 검증(Validating)
이 어드미션 컨트롤러는 다중 사용자(multi-tenant) 클러스터에서 보안을 강화하는 데 유용합니다. 이를 통해 사용자는 노드에서 이미지가 이미 다운로드되었더라도, 이미지를 로컬로 기동하기 전에 해당 이미지를 풀할 수 있는 권한이 있는지 레지스트리에 대해 재차 검증을 받도록 보장됩니다.
시험 수행 Tip
/etc/kubernetes/manifests/kube-apiserver.yaml수정
# add flag in --enable-admission-plugins
kube-apiserver --enable-admission-plugins=NodeRestriction,AlwaysPullImages
- 적용 테스트
# imagePullPolicy를 기재하지 않거나 IfNotPresent로 기재하여 Pod 배포
kubectl run test-pod --image=nginx --restart=Never --dry-run=client -o yaml > pod.yaml
# 생성된 yaml 확인 (기본값 또는 IfNotPresent)
cat pod.yaml | grep imagePullPolicy
# 클러스터에 배포
kubectl apply -f pod.yaml
# 실제 배포된 Pod 정보 조회 시 imagePullPolicy가 Always로 변경된 것을 확인
kubectl get pod test-pod -o jsonpath='{.spec.containers[0].imagePullPolicy}'
```prompt
Always
`
ImagePolicyWebhook (이미지 정책 웹훅)
Kubernetes의 ImagePolicyWebhook Admission Controller는 Pod 생성 또는 업데이트 시 컨테이너 이미지를 승인되지 않은 외부 레지스트리에서 가져오거나, 보안 취약점 검증을 통과하지 못한 경우 API 서버 단에서 요청을 차단할 수 있도록 외부 정책 검증 웹훅 백엔드 서비스로 평가를 위임하는 보안 플러그인입니다.
1. 아키텍처 구조도 (Mermaid)
API 서버가 외부 Webhook 서버에 AdmissionReview 요청을 보내고, Webhook 서버의 승인(AdmissionResponse) 결과에 따라 파드 생성을 최종 승인/거부하는 흐름입니다.
2. 주요 동작 흐름 및 아키텍처 컴포넌트
- AdmissionConfiguration 정의
kube-apiserver에 전달되는 설정 파일로,ImagePolicyWebhook이 사용할kubeconfig의 경로, 로컬 캐시 TTL 및 웹훅 통신 실패 시 기본적으로 요청을 승인할지(Fail-Open/defaultAllow: true) 거부할지(Fail-Closed/defaultAllow: false) 결정합니다.
- 외부 웹훅 서비스와의 통신 (Webhook Callout)
- API 서버는 Pod에 기재된 이미지 목록 정보를 담아
image.k8s.io/v1alpha1ImageReview객체 형태로 JSON 직렬화하여 외부 백엔드 서버에 HTTPS POST 요청을 전달합니다.
- 외부 백엔드의 정책 검증 및 보안 인증서 통신
- 외부 백엔드는 이미지 태그, 다이제스트 해시 등을 분석하여 신뢰할 수 없는 원격지 레지스트리에 속하거나 취약점이 존재하는 경우 거절 메시지를 리턴합니다. 모든 통신은 상호 TLS(mTLS)를 통해 안전하게 보호되어야 합니다.
3. 보안 상의 이점 (Why ImagePolicyWebhook?)
| 시나리오 | ImagePolicyWebhook 미적용 시 | ImagePolicyWebhook 적용 시 |
|---|---|---|
| 취약점이 포함된 악성 이미지 실행 | 임의의 사용자가 퍼블릭 레지스트리(예: Docker Hub)에서 취약점이나 악성코드가 포함된 이미지를 클러스터 내에 무단 배포할 수 있음. | 외부 보안 솔루션(예: Trivy, Anchore 등)의 스캔 결과가 클러스터 정책 기준을 충족해야만 웹훅이 통과되므로, 위험한 이미지의 런타임 진입이 사전 차단됨. |
| 비인가 사설 레지스트리 사용 | 사내 보안 망 외부의 확인되지 않은 사설 레지스트리 이미지를 임의로 사용하여 기밀 데이터 유출 위험이 발생함. | 허용된 화이트리스트 레지스트리 주소(예: .gcr.io, .ecr.aws)가 아닐 경우 API 단계에서 배포 요청 자체를 기각함. |
공식문서 참조
https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook
유형: 검증(Validating)
이 어드미션 컨트롤러는 컨테이너 이미지를 평가하기 위해 백엔드 웹훅 서비스를 호출합니다. 웹훅이 연결되지 않거나 정책 요구 사항을 만족하지 못하면 파드 생성이 실패합니다. 상세한 동작을 위해선 --admission-control-config-file 옵션을 통해 설정 파일(AdmissionConfiguration) 및 통신을 위한 별도의 kubeconfig 파일을 구성해주어야 합니다.
시험 수행 Tip
/etc/kubernetes/admission/admission_config.yaml생성 및 수정
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhook
configuration:
imagePolicy:
kubeConfigFile: /etc/kubernetes/admission/kubeconf.yaml
allowTTL: 50
denyTTL: 50
retryBackoff: 500
defaultAllow: false # 웹훅 통신 장애 시 Fail-Closed (안전)
/etc/kubernetes/admission/kubeconf.yaml(웹훅 정보) 생성
apiVersion: v1
kind: Config
clusters:
- cluster:
server: <https://image-policy-webhook-service.security.svc:2379/validate>
certificate-authority: /etc/kubernetes/admission/ca.crt
name: image-policy-webhook
users:
- name: api-server
user:
client-certificate: /etc/kubernetes/admission/api-server.crt
client-key: /etc/kubernetes/admission/api-server.key
contexts:
- context:
cluster: image-policy-webhook
user: api-server
name: image-policy-webhook
current-context: image-policy-webhook
/etc/kubernetes/manifests/kube-apiserver.yaml수정 및 마운트 추가
# 1. 플러그인 활성화 및 설정파일 플래그 추가
- --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook
- --admission-control-config-file=/etc/kubernetes/admission/admission_config.yaml
# 2. 볼륨 마운트 추가 (admission 디렉토리 내의 설정 및 인증서 사용 가능하도록 호스트 마운트)
...
spec:
containers:
- name: kube-apiserver
volumeMounts:
- mountPath: /etc/kubernetes/admission
name: admission-config
readOnly: true
volumes:
- hostPath:
path: /etc/kubernetes/admission
type: DirectoryOrCreate
name: admission-config
- 적용 테스트
# 승인되지 않은 비인가 이미지를 사용하는 Pod 배포 시도
kubectl run malicious-pod --image=evilregistry.com/malicious-app:latest
```prompt
Error from server (Forbidden): pods "malicious-pod" is forbidden: image evilregistry.com/malicious-app:latest is denied by image policy webhook.
`
PodSecurity (파드 보안 어드미션)
Kubernetes의 PodSecurity Admission Controller는 사전에 정의된 세 가지 파드 보안 표준(Pod Security Standards – Privileged, Baseline, Restricted)에 따라 네임스페이스 수준에서 파드의 명세(Specification)를 검증하고 제어하여, 불필요하게 높은 시스템 권한이나 보안 설정을 가진 파드가 실행되는 것을 방지하는 핵심 보안 컴포넌트입니다. (Kubernetes 1.25버전에서 완전히 제거된 PodSecurityPolicy(PSP)를 완벽히 대체하는 기본 메커니즘입니다.)
1. 아키텍처 구조도 (Mermaid)
파드 생성/수정 요청 시 네임스페이스의 pod-security.kubernetes.io/* 라벨 규칙에 맞춰 정책 수준을 평가하고 enforce, warn, audit 모드에 따라 다르게 차단/허용하는 흐름입니다.
2. 주요 동작 흐름 및 아키텍처 컴포넌트
- 파드 보안 표준 (Pod Security Standards)
- Privileged: 제약이 전혀 없는 정책으로, 호스트 권한(privileged: true, hostPID, hostNetwork 등)이 필요한 시스템/인프라성 파드를 대상으로 합니다.
- Baseline: 기본적인 제약 정책으로, 널리 알려진 특권 에스컬레이션을 방지하면서 일반적인 애플리케이션 파드가 최소한의 번거로움으로 구동될 수 있도록 허용합니다. (예: hostPath, hostPort 제한 등)
- Restricted: 극도의 보안 제약 정책으로, 파드 강화 모범 사례를 강제합니다. (예: root 실행 금지 – runAsNonRoot: true, 리눅스 capability 화이트리스트 제한, 볼륨 제한 등)
- 평가 모드 (Modes)
- enforce: 위반한 파드의 생성/수정을 완전히 거절(Reject)합니다.
- warn: 경고 문구를 사용자 화면(kubectl)에 노출하되 파드 생성은 허용합니다.
- audit: 감사 로그(Audit Log) 상에 규정 위반 사실을 기록하고 파드 생성은 허용합니다.
3. 보안 상의 이점 (Why PodSecurity?)
| 시나리오 | PodSecurity 미적용 시 | PodSecurity 적용 시 |
|---|---|---|
| 루트 권한 및 특권 컨테이너 남용 | 공격자 또는 개발자가 무심코 privileged: true 설정을 기재하여 컨테이너 탈취 시 호스트 OS 장악으로 이어질 수 있음. |
enforce=baseline 또는 restricted가 설정된 네임스페이스에서는 특권 파드 생성이 즉각 차단되어 컨테이너 탈출 공격 위험을 예방함. |
| 호스트 네임스페이스 공유 | 컨테이너가 호스트의 프로세스(hostPID), 네트워크(hostNetwork)를 직접 공유하여 클러스터 네트워크 스니핑 및 도청 가능. | 호스트 영역 공유가 비활성화된 정책 기준만 허용하므로, 컨테이너 환경 간의 강력한 커널 수준 격리를 제공함. |
공식문서 참조
https://kubernetes.io/docs/concepts/security/pod-security-admission/
유형: 검증(Validating)
이 어드미션 컨트롤러는 네임스페이스의 지정된 라벨 정책 수준을 만족하지 못하는 파드의 생성을 차단하거나 경고, 감사 로그 생성을 수행합니다. Kubernetes 1.23버전 이상부터는 기본적으로 활성화되어 작동하므로 별도의 --enable-admission-plugins 수정 없이 즉시 네임스페이스 라벨링을 통해 활용 가능합니다.
시험 수행 Tip
- 네임스페이스 생성 및 PSS 정책 라벨 설정
kubectl create ns secure-apps
# 1. baseline 수준을 강제 적용 (enforce)
kubectl label namespace secure-apps pod-security.kubernetes.io/enforce=baseline
# 2. restricted 수준 위반 시 경고 출력 (warn)
kubectl label namespace secure-apps pod-security.kubernetes.io/warn=restricted
- 적용 테스트
# 특권 권한(Privileged)을 요구하는 Pod yaml 파일 생성
cat <<EOF > priv-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: bad-pod
namespace: secure-apps
spec:
containers:
- name: nginx
image: nginx
securityContext:
privileged: true
EOF
# 배포 시도 (baseline enforce 정책에 의해 생성 차단됨)
kubectl apply -f priv-pod.yaml
```prompt
Error from server (Forbidden): error when creating "priv-pod.yaml": pods "bad-pod" is forbidden: violates PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)
`
CSR Management
1. Create CSR with Openssl
openssl genrsa -out /root/60099.key 2048
openssl req -new -key /root/60099.key -out /root/60099.csr -subj '/[email protected]'
# or
openssl req -new -key /root/60099.key -out 60099.csr
# Common Name에 userName 입력하기.
```prompt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:[email protected]
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
`
2-1. Sign Certificate via Openssl Manually
openssl x509 -req -in 60099.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial \
-out /root/60099.crt \
-days 500
```prompt
Certificate request self-signature ok
subject=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = [email protected]
`
2-2. Sign Certificate via API
Create and Approve CSR
cat <<EOF > csr.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: [email protected] # ADD
spec:
groups:
- system:authenticated
request: $(cat 60099.csr | base64 -w 0)
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
EOF
k apply -f csr.yaml
### or
cat <<EOF kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: [email protected] # ADD
spec:
groups:
- system:authenticated
request: $(cat 60099.csr | base64 -w 0)
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
EOF
k certificate approve [email protected]
k get csr
Save Certificate
k get csr [email protected] \
-ojsonpath="{.status.certificate}" | base64 -d > 60099.crt
3. Update Kubeconfig
k config get-clusters
```prompt
NAME
kubernetes
`
k config set-credentials [email protected] \
--client-key=60099.key \
--client-certificate=60099.crt
```prompt
User "[email protected]" set.
`
k config get-users
```prompt
NAME
[email protected]
kubernetes-admin
`
k config set-context [email protected] \
--cluster=kubernetes \
[email protected]
```prompt
Context "[email protected]" created.
`
k config get-contexts
```prompt
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
[email protected] kubernetes [email protected]
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
`
Leave a Reply