Admission Controller는 kube-apiserver에서 요청을 가로채어 정책을 적용하거나 변경을 가할 수 있는 플러그인 시스템이다. 즉, 클러스터 내부에서 실행될 리소스(Pod, Deployment 등)를 검토하고 승인(또는 거부)하는 역할을 한다.
✅ 보안, 정책 관리, 리소스 제어 등에 사용됨
- 보안 정책 적용 → root 권한 제한, 특정 네임스페이스 제어
- 자동화된 정책 관리 → Pod 자동 라벨링, 사이드카 자동 추가
- 리소스 관리 최적화 → 특정 리소스 사용량 제한
- 하지만 어떠한 authenticate 관련 기능도 하지 않는다.
✅ Kubernetes API 요청이 etcd에 저장되기 전에 실행됨
✅ Mutating(수정)과 Validating(검증) 컨트롤러로 구분됨
📖 Admission Controller의 동작 방식
Kubernetes에서 리소스가 생성될 때, 다음과 같은 과정을 수행한다.
- 클라이언트 요청 (ex: kubectl apply -f pod.yaml)
- API 서버 요청 수신
- Authentication (인증) → RBAC Authorization (권한 확인)
- Admission Controller가 요청을 검토
- Validating Admission Controller: 요청을 검토하고 허용/거부 결정
- Mutating Admission Controller: 요청을 변경 후 승인
- etcd에 저장 & 스케줄링 및 실행
✔ Admission Controller가 활성화되면, 특정 규칙을 위반하는 요청을 자동으로 차단할 수 있음
✔ Mutating Admission Controller를 사용하면, 정책에 따라 요청을 자동으로 변경 가능
📖 Admission Controller의 유형
1. Mutating Admission Controller (변경 가능)
- 요청을 자동으로 수정할 수 있음
- 예제: MutatingWebhook 사용
- 예시: default 네임스페이스에 Pod을 배포하면 자동으로 default SecurityContext를 추가
2. Validating Admission Controller (검증 전용)
- 요청을 검사하고 거부할 수 있음
- 예제: ValidatingWebhook 사용
- 예시: 특정 리소스 제한을 초과하는 Pod이 배포되지 않도록 차단
✔ Mutating Admission Controller → 요청을 자동 수정
✔ Validating Admission Controller → 정책을 위반하는 요청 거부
📖 활성 / 비활성 방법
Enabled Admission Controllers
# kube-apiserver-controlplane
$ kube-apiserver -h | grep enable-adminssion-plugins
controlplane:~$ kubectl exec -it kube-apiserver-controlplane -n kube-system -- kube-apiserver -h | grep enable-admission-plugins
--enable-admission-plugins strings admission plugins that should be enabled in addition to default enabled ones (NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, PodSecurity, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, ClusterTrustBundleAttest, CertificateSubjectRestriction, DefaultIngressClass, MutatingAdmissionPolicy, MutatingAdmissionWebhook, ValidatingAdmissionPolicy, ValidatingAdmissionWebhook, ResourceQuota). Comma-delimited list of admission plugins: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, ClusterTrustBundleAttest, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyServiceExternalIPs, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionPolicy, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PodNodeSelector, PodSecurity, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionPolicy, ValidatingAdmissionWebhook. The order of plugins in this flag does not matter.
controlplane:~$ kubectl describe pod kube-apiserver -n kube-system | grep enable-admission-plugins
--enable-admission-plugins=NodeRestriction
특정 admission 활성화
# Kubernetes API 서버 실행 옵션에 --enable-admission-plugins 추가
$ kube-apiserver --enable-admission-plugins=NamespaceLifecycle,LimitRanger,PodSecurityPolicy
# 권장 admission-plugins
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,Priority,ResourceQuota,PodSecurityPolicy
# kube-apiserver.service 업데이트 or
# kube-apiserver.yaml 업데이트
controlplane:/etc/kubernetes/manifests$ cat kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 172.30.1.2:6443
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --advertise-address=172.30.1.2
- --allow-privileged=true
- --authorization-mode=Node,RBAC
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --enable-admission-plugins=NodeRestriction # 여기에 plugins 업데이트
- --enable-bootstrap-token-auth=true
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
- --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
- --etcd-servers=https://127.0.0.1:2379
- --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
- --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
- --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
- --requestheader-allowed-names=front-proxy-client
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --requestheader-extra-headers-prefix=X-Remote-Extra-
- --requestheader-group-headers=X-Remote-Group
- --requestheader-username-headers=X-Remote-User
- --secure-port=6443
- --service-account-issuer=https://kubernetes.default.svc.cluster.local
- --service-account-key-file=/etc/kubernetes/pki/sa.pub
- --service-account-signing-key-file=/etc/kubernetes/pki/sa.key
- --service-cluster-ip-range=10.96.0.0/12
- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
+ 📄 NamespaceAutoProvision 및 NamespaceExists는 deprecate되어 NamespaceLifeCycle로 대체되었다.
- NamespaceLifeCycle: 존재하지 않는 namespace에 대한 요청을 거부하고, default kube-system, kube-public과 같은 namespace가 삭제될 수 없도록 한다.
특정 plugins 비활성화
- --disable-admission-plugins
$ grep 'admission' /etc/kubernetes/manifests/kube-apiserver.yaml
- --enable-admission-plugins=NodeRestriction,NamespaceAutoProvision
- --disable-admission-plugins=DefaultStorageClass # 이렇게 추가해주면 된다.
- kube-apiserver는 Pod로 실행되기 때문에 ps 명령어로 enable/disable plugins를 확인할 수 있다.
$ ps -ef | grep kube-apiserver | grep admission-plugins
root 17230 17101 0 08:33 ? 00:00:03 kube-apiserver --advertise-address=192.168.63.143 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction,NamespaceAutoProvision --disable-admission-plugins=DefaultStorageClass --enable-bootstrap-token-auth=true --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6443 --service-account-issuer=https://kubernetes.default.svc.cluster.local --service-account-key-file=/etc/kubernetes/pki/sa.pub --service-account-signing-key-file=/etc/kubernetes/pki/sa.key --service-cluster-ip-range=172.20.0.0/16 --tls-cert-file=/etc/kubernetes/pki/apiserver.crt --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
[실습 ] NamespaceAutoProvision
- NamespaceAutoProvision 활성화 하기
$ kubectl run nginx --image nginx -n blue
Error from server (NotFound): namespaces "blue" not found
# blue namespace가 없기 때문에 pod가 생성되지 않는다. (NamespaceExists admission plugins이 활성화 되어있기 때문이다.)
# 존재하지 않는 namespace를 자동으로 만들어주기 위해서, NamespaceAutoProvision admission controller를 활성화시킬 수 있다.
$ vi /etc/kubernetes/manifests/kube-apiserver.yaml
- --enable-admission-plugins=NodeRestriction,NamespaceAutoProvision
# kube-apiserver가 restart된다.
- 존재하지 않는 namespace의 Pod 생성하기
$ kubectl get ns
NAME STATUS AGE
default Active 19m
kube-flannel Active 19m
kube-node-lease Active 19m
kube-public Active 19m
kube-system Active 19m
$ kubectl run nginx --image nginx -n blue
pod/nginx created
# 오류가 발생하지 않는다.
$ kubectl get ns
NAME STATUS AGE
blue Active 3s # 자동으로 생성되었다.
default Active 20m
kube-flannel Active 19m
kube-node-lease Active 20m
kube-public Active 20m
kube-system Active 20m
# The NamespaceLifecycle admission controller will make sure that requests to a non-existent namespace is rejected
# and that the default namespaces such as default, kube-system and kube-public cannot be deleted.
⭐참고:
'Container > Kubernetes' 카테고리의 다른 글
[K8S] Autoscaling - HPA (0) | 2025.02.26 |
---|---|
[K8S] Mutating/Validating Admission Controller (0) | 2025.02.24 |
[K8S] Kustomize Overlay/Components (0) | 2025.02.24 |
[K8S] Kustomize Patches (0) | 2025.02.23 |
[K8S] Kustomize Transformers (0) | 2025.02.23 |