이쿠의 슬기로운 개발생활

함께 성장하기 위한 보안 개발자 EverNote 내용 공유

Kubernetes/Kubernetes 보안

Kubernetes ImagePolicyWebhook

이쿠우우 2021. 4. 5. 23:04
반응형

 

 

ImagePolicyWebhook

 

 

 

목표

 

kubernetes 공식 문서를 확인해보면 ImagePolicyWebhook이란 것이 있다 정도만 설명하지

이외에 자세한 설명은 해놓지 않았음.

리서치를 통해 ImagePolicyWebhook에 대해 자세히 알아보겠음.

 

 

 


 

환경

 

Master Node server

 OS = CentOS 7

 리눅스 커널 버전 : Linux 3.10.0-1062.el7.x86_64

 docker version : 1.13.1

 api verison : 1.26

 

Worker Node server

 OS = CentOS 7

 리눅스 커널 버전 : Linux 3.10.0-1062.el7.x86_64

 docker version : 1.13.1

 api verison : 1.26

 

Kubernetes version

 1.19.2

 

 

 


 

 

ImagePolicyWebhook 이란?

 

kubernetes 보안 설정에 필요한 Admission Controller Plugin 종류 중 하나임.

kubernetes cluster에 배포될 수 있는 container 규칙을 설정할 수 있는 Webhook.

관리자가 개발한 Webhook Server의 Response값에 따라 kubernetes에 pod 배포 허가/불허가를 설정할 수 있음.

 

 

ImagePolicyWebhook의 장점

1. 관리자가 직접 ImagePolicy 용도의 Webhook Server를 개발할 수 있어서

각 환경에 알맞은 Pod배포 정책을 생성 할 수 있음.

 

2. ImagePolicy Webhook Server의 EndPoint에 접근이 불가하면 

상황에 따라 kubernetes cluster에 특정 image를 사용하는 pod 생성을 불허가 할 수 있음.

예) pod 배포 허가/불허가를 ValidatingAdmissionWebhook을 통해 개발한다면

Webhook Server의 EndPoint에 접근이 불가할 시 전부 Pass(허가) 처리함.

 

 

ImagePolicyWebhook의 단점

 

1. kube-apiserver에 access 해야하며 많은 config파일이 생성되어 관리하기가 어려움.

update 또한 어려움.

 

2. systemd를 사용하여 배포하거나 호스트에서 Docker Container로 실행하고 

DNS(/etc/hosts)를 업데이트해야하는 등 

적용 방법이 어려움.

 

 

ImagePolicyWebhook에 해당하는 CIS Benchmark

 

CIS_Kubernetes_Benchmark_v1.6.1 문서의 5.5.1 항목에

Configure Image Provenance using ImagePolicyWebhook admission controller

로 명시되어있음.

 

 

 


 

 

ImagePolicyWebhook과 비교할 수 있는 ValidatingAdmissionWebhook

 

관리자가 개발한 Webhook Server의 Response값에 따라 

kubernetes에 pod 배포 허가/불허가를 설정할 수 있는 또 다른 방법으로는 

ValidatingAdmissionWebhook을 사용할 수 있음.

해당 설정에 대한 자세한 설명은 아래 링크를 참고

 

[ValidatingAdmissionWebhook에 대한 자세한 설명 글]

https://ikcoo.tistory.com/94?category=416817

 

 

ValidatingAdmissionWebhook의 장점

1. Webhook Server가 kubernetes가 관리하는 Pod로 실행되므로 

ImagePolicyWebhook에 비해서 배포가 더 쉬움.

 

2. ValidataAdmissionWebhook 설정에 대한 모든 것이 Kubernetes 리소스가 되어 관리됨.

 

 

ValidatingAdmissionWebhook의 단점

 

1. kubernetes 1.8 version 이상부터는  ValidatingAdmission Webhook EndPoint에 접근이 불가할 시

kube-apiserver에 image를 거부하도록 설정 할 수 없음. 

따라서 EndPoint에 접근이 불가할 시 모든 리소스가 자동으로 수락됨.

 

2. ValidatingAdmission는 kubernetes 리소스 중 하나라서 

충분한 RBAC 권한을 가진 User는 ValidatingAdmission 설정을 변경할 수 있음.

 

 

 

 

 


 

 

Admission Controller Plugin에서 ImagePolicyWebhook 항목 찾기

 

1. kube-apiserver pod를 조회함

[명령어]

kubectl get pod -n kube-system 

 

2. kube-apiserver pod 안으로 접속

[명령어]

kubectl -exec -it [상위에서 찾은 kube-apiserver pod name] -n kube-system  -- /bin/sh

 

[해당 명령 시 아래와 같은 오류가 발생한다면]

oci runtime error: exec failed: container_linux.go:235: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory"

해당 링크 참고 : https://ikcoo.tistory.com/146

 

 

3. kube-apiserver 명령 사용

 

[kube-apiserver 명령 옵션 참고]

https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/

 

[명령어]

kube-apiserver -h | grep enable-admission-plugins

 

 

확인 결과

default로 활성화 되어있는 Admission Controller Plugin은 아니지만 ImagePolicyWebhook은 존재함.

 

 

 


 

 

 

ImagePolicyWebhook 적용 과정

 

예제 참고 : https://dzone.com/articles/kubernetes-image-policy-webhook-explained

상위 링크를 참고로

Image tag가 latest 인 Pod는 생성되지 않도록하는

ImagePolicyWebhook을 생성해보겠음.

 

반드시 아래 순서대로 해야만 kube-apiserver가 올라오지 않는 오류가 안남.

 

1. ImagePolicyWebhook 작업 Directory 생성

 

예제에서는 ImagePolicyWebhook test directory 경로를

/etc/kubernetes/kube-image-bouncer

로 기준으로 함.

 

 

 

2. Certificates

imagepolicy.cnf 파일 생성

[ req ]
default_bits       = 2048
distinguished_name = req_distinguished_name
req_extensions     = req_ext
[ req_distinguished_name ]
countryName                 = Country Name (2 letter code)
stateOrProvinceName         = State or Province Name (full name)
localityName               = Locality Name (eg, city)
organizationName           = Organization Name (eg, company)
commonName                 = Common Name (e.g. server FQDN or YOUR name)
[ req_ext ]
subjectAltName = @alt_names
[alt_names]
DNS.1   = image-bouncer-webhook.default.svc
DNS.2   = 127.0.0.1

 

 

 

openssl genrsa -out imagepolicy.key 2048

 

openssl req -out imagepolicy.csr -newkey rsa:2048 -nodes -keyout imagepolicy.key -config imagepolicy.cnf

CN (Common Name) 을 아래와 같이 입력

image-bouncer-webhook.default.svc

 

 

openssl req -key imagepolicy.key -x509 -nodes -sha1 -days 365 -in imagepolicy.csr -extensions req_ext -config imagepolicy.cnf -out imagepolicy.crt 

 

 

openssl req -noout -text -in imagepolicy.csr

csr에 SAN 정보가 정상적으로 저장됐는지 확인

 

imagepolicy.crt 에 SAN 정보가 정상적으로 들어가 있는지 확인

확인 사이트 : https://www.sslcert.co.kr/tools/certificate-crt-decoder

 

[명령어]

cat imagepolicy.crt 

 

해당 내용을 복사해서 상위 확인 사이트에 아래와 같이 적어줌.

[결과 확인]

아래와 같이 주체 대체 이름이 있어야 정상적으로 SAN crt 생성완료.

 

 

3. /etc/hosts에 도메인 추가

 

echo "127.0.0.1 image-bouncer-webhook.default.svc" >> /etc/hosts

 

 

 

 

4. ImagePolicyWebhook 용도 docker container RUN

 

test 용도 imagePolicyWebhook Container로

image tag가 latest 면 불허가 하는 Webhook 이미지.

 

Image pull

docker pull kainlite/kube-image-bouncer

 

Run

docker run --rm -v /etc/kubernetes/kube-image-bouncer/imagepolicy.key:/certs/imagepolicy.key:ro -v /etc/kubernetes/kube-image-bouncer/imagepolicy.crt:/certs/imagepolicy.crt:ro -p 1323:1323 --network host kainlite/kube-image-bouncer -k /certs/imagepolicy.key -c /certs/imagepolicy.crt

 

 

Test

curl -v --cacert imagepolicy.crt  https://image-bouncer-webhook.default.svc:1323/image_policy

정상 동작 시 아래와 같음

 

 

 

 

 

 

 

5. Admission Control Config file 생성

 

특정 경로에 admission control config file 을 생성해야함.

 

[파일생성 문법]

{
  "imagePolicy": {
     "kubeConfigFile": "path/to/kubeconfig/for/backend",
     "allowTTL": 50,           // time in s to cache approval
     "denyTTL": 50,            // time in s to cache denial
     "retryBackoff": 500,      // time in ms to wait between retries
     "defaultAllow": true      // determines behavior if the webhook backend fails
  }
}

 

 

예)

admission control config file 생성 : /etc/kubernetes/kube-image-bouncer/admission_configuration.json

 

[admission_configuration.json 에제]

{
  "imagePolicy": {
     "kubeConfigFile": "/etc/kubernetes/kube-image-bouncer/kube-image-bouncer.yml",
     "allowTTL": 50,
     "denyTTL": 50,
     "retryBackoff": 500,
     "defaultAllow": false
  }
}

 

"defaultAllow": false 처리해서

imagePolicyWebhook에 접근 불가할 시 pod가 생성 안되도록 설정함.

 

 

 

6. ImagePolicyWebhook kubeConfigFile 생성

 

경로 : /etc/kubernetes/kube-image-bouncer/kube-image-bouncer.yml

 

[kube-image-bouncer.yml]

apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority: /etc/kubernetes/kube-image-bouncer/imagepolicy.crt
    server: https://image-bouncer-webhook.default.svc:1323/image_policy
  name: bouncer_webhook
contexts:
- context:
    cluster: bouncer_webhook
    user: api-server
  name: bouncer_validator
current-context: bouncer_validator
preferences: {}
users:
- name: api-server
  user:
    client-certificate: /etc/kubernetes/pki/apiserver.crt
    client-key:  /etc/kubernetes/pki/apiserver.key

 

 

 

 

 

 

7. ImagePolicyWebhook 활성화

 

kubernetes admission controller 에서 ImagePolicyWebhook은

default로 비활성화 되어있는 상태라 

활성화 작업을 거쳐야함.

 

 

[명령어]

cd /etc/kubernetes/manifests

 

 

[명령어]

vi kube-apiserver.yaml

 

중요

--enable-admission-plugins=ImagePolicyWebhook  설정은 반드시 

--admission-control-config-file=

설정과 함께 사용되어야함.

 

ImagePolicyWebhook 을 활성화 시켰는데

--admission-control-config-file 설정이 없다면 

kube-apiserver가 올라오지 않음.

 

그리고 

--admission-control-config-file=/etc/kubernetes/kube-image-bouncer/admission_configuration.json

설정에서 해당 파일 경로는

master host의 경로가 아니라

kube-apiserver pod 내부에서 해당 경로에 파일이 있어야함.

kube-apiserver도 결국 kube-apiserver pod에서 돌고있기 때문.

그래서 hostpath volume을 사용해서 

pod에서 해당 경로에 접근 할 수 있도록 아래 설정을 추가해줘야함.

 

 

    volumeMounts:

    - mountPath: /etc/kubernetes/kube-image-bouncer

      name: admission

      readOnly: true

...

 

  volumes:

  - hostPath:

      path: /etc/kubernetes/kube-image-bouncer

      type: DirectoryOrCreate

    name: admission

 

 

 

[확인 명령어]

kubectl get all -n kube-system

상위 설정파일을 변경하면 몇초 후 해당 설정이 kube-apiserver에 반영되어

update함.

 

 

 

 

 


 

 

오류 참고1.

 

 

상황.

kube-apiserver에 --enable-admission-plugins=ImagePolicyWebhook

설정만 추가한 뒤 적용했는데

kube-apiserver가 올라오지 않음.

 

 

오류 메세지

kube-apiserver 오류 log를 확인하기 위해

kube-apiserver에서 kube-apiserver tool을 host로 복사 해온 뒤

host에서 실행해서 log를 확인해보니 아래와 같았음.

Error: failed to initialize admission: couldn't init admission plugin "ImagePolicyWebhook": no config specified

 

원인

--admission-control-config-file

설정이 추가되어있지 않아서 발생함.

ImagePolicyWebhook은 admission control config file을 바라보고 

webhook을 찾게 되는데 해당 config file이 없어서 오류가 발생하는 상황..

즉 

--enable-admission-plugin 에서 ImagePolicyWebhook 만 추가하면

오류가 발생한다고 봐야함.

 

해결법

--admission-control-config-file 설정을 추가함

그리고 config파일도 경로에 추가함.

 

결론

--enable-admission-plugins=ImagePolicyWebhook

--admission-control-config-file="config 파일 경로"

2개 설정을 동시에 추가해줘야함.

 


 

 

 

오류 참고2.

 

 

상황.

정상적으로 ImagePolicyWebhook 이 적용된 상태에서 kubernetes 운영 중이였음.

이 상황에서 ImagePolicyWebhook 관련 인증서만 기존거 삭제 후 새로 생성함.

kube-apiserver 에서 hostPath 경로에 들어가서 인증서가 갱신된것을 확인함.

하지만 ImagePolicy Webhook server 접근 시 오류 발생

 

image Policy Server Log

echo: http: TLS handshake error from 127.0.0.1:36468: remote error: tls: bad certificate

와 같은 오류 발생.

 

 

kube-apiserver Log

replicaset-controller  (combined from similar events): Error creating: pods "iksoon-deployment-test-857c947fcf-6qcvj" is forbidden: Post "https://image-bouncer-webhook.default.svc:1323/image_policy?timeout=30s": x509: certificate signed by unknown authority

 

원인

갱신한 인증서가 kube-apiserver에 정상적으로 반영되지 않음.

 

해결 방법

kube-apiserver에서 다시 imagePolicyWebhook 관련 설정을 지워서 원복 시킨 뒤에

원본 kube-apiserver 다시 재기동 확인한 후

다시 kube-apiserver 에 imagePolicyWebhook 설정을 적용해서 기동함.

ImagePolicy Webhook server 가 종료되었다가 재기동 되면 위와같은 상황이 발생하지 않지만

인증서가 갱신되었다면 반드시 kube-apiserver가 재기동 되야함.

 

결론

만약 인증서가 변경되었거나

imagePolicyWebhook 관련 설정이 변경되었다면

kube-apiserver를 반드시 재기동 해줘야함.

hostPath에서 파일변경은 인지하지만 

원인 불명으로 꼭 kube-apiserver가 재기동 되야 

변경된 설정으로 ImagePolicyWebhook 이 적용됨.

 

 

 


 

 

 

 

 

 

ImagePolicyWebhook test

 

 

latest tag 이미지가 생성 안되는지 확인해보기

 

[test_deployment.yaml]

apiVersion: apps/v1
kind: Deployment
metadata:
  name: iksoon-deployment-test
  labels:
    app: iksoon-test-a
spec:
  replicas: 1
  selector:
    matchLabels:
      app: iksoon-pod-testa
  template:
    metadata:
      labels:
        app: iksoon-pod-testa
    spec:
      containers:
      - name: iksoon-nginx-a
        image: nginx
        ports:
        - containerPort: 80

 

 

[결과]

is forbidden: image policy webhook backend denied one or more images: Images using latest tag are not allowed

delployment에 해당하는 replicaset log를 확인해 보면 

latest image를 사용해서 pod생성이 안됨

 

 

latest tag가 아니라면 이미지가 생성 되는지 확인해보기

 

[test_deployment.yaml]

apiVersion: apps/v1
kind: Deployment
metadata:
  name: iksoon-deployment-test
  labels:
    app: iksoon-test-a
spec:
  replicas: 1
  selector:
    matchLabels:
      app: iksoon-pod-testa
  template:
    metadata:
      labels:
        app: iksoon-pod-testa
    spec:
      containers:
      - name: iksoon-nginx-a
        image: nginx:1.19.8
        ports:
        - containerPort: 81

 

 

[결과]

정상적으로 생성됨.

 

 

 

 

 


 

 

시행착오..

 

 

 

Error 해결 1 : kube-apiserver는 누가 관리하는지 알아보자 (원인분석 실패)

 

원인 해결을 위해 

kuberentes api-server, controller 를 관리하는것은 어떤 툴인지 알아보니 

kubelet 이였음

kubelet 을 정지하고 /etc/kubernetes/manifests/kube-apiserver.yaml을 수정하면

해당 수정이 반영되지도 않고

kubectl로 api-server delete 명령을 내려도 명령이 적용되지 않음

 

즉 kube-apiserver 관리는 kubelet이 진행..

 

kubelet log를 살펴봄

 

[명령어]

journalctl -f -u kubelet

 

 

 

로그가 엄청 나오지만 그 중 create 관련 log을 확인해보니 아래와 같음

 

3월 11 11:16:28 kube.master.node kubelet[24965]: E0311 11:16:28.687343   24965 kuberuntime_manager.go:801] container start failed: CreateContainerConfigError: open /var/lib/kubelet/pods/0c27f717a45ba50e9bd38779c6ed404f/etc-hosts: no such file or directory

 

3월 11 11:16:28 kube.master.node kubelet[24965]: E0311 11:16:28.687389   24965 pod_workers.go:191] Error syncing pod 0c27f717a45ba50e9bd38779c6ed404f ("kube-apiserver-kube.master.node_kube-system(0c27f717a45ba50e9bd38779c6ed404f)"), skipping: failed to "StartContainer" for "kube-apiserver" with CreateContainerConfigError: "open /var/lib/kubelet/pods/0c27f717a45ba50e9bd38779c6ed404f/etc-hosts: no such file or directory"

 

3월 11 11:16:28 kube.master.node kubelet[24965]: W0311 11:16:28.694986   24965 helpers.go:289] Unable to create pod sandbox due to conflict. Attempting to remove sandbox "8b2096bc6f627d3471009277b82ff631f97a308512af5e625080301ac2ea4f45"

 

3월 11 11:16:28 kube.master.node kubelet[24965]: E0311 11:16:28.699232   24965 remote_runtime.go:105] RunPodSandbox from runtime service failed: rpc error: code = Unknown desc = failed to create a sandbox for pod "kube-apiserver-kube.master.node": Error response from daemon: Conflict. The container name "/k8s_POD_kube-apiserver-kube.master.node_kube-system_0c27f717a45ba50e9bd38779c6ed404f_0" is already in use by container 8b2096bc6f627d3471009277b82ff631f97a308512af5e625080301ac2ea4f45. You have to remove (or rename) that container to be able to reuse that name.

 

3월 11 11:16:28 kube.master.node kubelet[24965]: E0311 11:16:28.699276   24965 kuberuntime_sandbox.go:68] CreatePodSandbox for pod "kube-apiserver-kube.master.node_kube-system(0c27f717a45ba50e9bd38779c6ed404f)" failed: rpc error: code = Unknown desc = failed to create a sandbox for pod "kube-apiserver-kube.master.node": Error response from daemon: Conflict. The container name "/k8s_POD_kube-apiserver-kube.master.node_kube-system_0c27f717a45ba50e9bd38779c6ed404f_0" is already in use by container 8b2096bc6f627d3471009277b82ff631f97a308512af5e625080301ac2ea4f45. You have to remove (or rename) that container to be able to reuse that name.

 

3월 11 11:16:28 kube.master.node kubelet[24965]: E0311 11:16:28.699307   24965 kuberuntime_manager.go:727] createPodSandbox for pod "kube-apiserver-kube.master.node_kube-system(0c27f717a45ba50e9bd38779c6ed404f)" failed: rpc error: code = Unknown desc = failed to create a sandbox for pod "kube-apiserver-kube.master.node": Error response from daemon: Conflict. The container name "/k8s_POD_kube-apiserver-kube.master.node_kube-system_0c27f717a45ba50e9bd38779c6ed404f_0" is already in use by container 8b2096bc6f627d3471009277b82ff631f97a308512af5e625080301ac2ea4f45. You have to remove (or rename) that container to be able to reuse that name.

 

3월 11 11:16:28 kube.master.node kubelet[24965]: E0311 11:16:28.699398   24965 pod_workers.go:191] Error syncing pod 0c27f717a45ba50e9bd38779c6ed404f ("kube-apiserver-kube.master.node_kube-system(0c27f717a45ba50e9bd38779c6ed404f)"), skipping: failed to "CreatePodSandbox" for "kube-apiserver-kube.master.node_kube-system(0c27f717a45ba50e9bd38779c6ed404f)" with CreatePodSandboxError: "CreatePodSandbox for pod \"kube-apiserver-kube.master.node_kube-system(0c27f717a45ba50e9bd38779c6ed404f)\" failed: rpc error: code = Unknown desc = failed to create a sandbox for pod \"kube-apiserver-kube.master.node\": Error response from daemon: Conflict. The container name \"/k8s_POD_kube-apiserver-kube.master.node_kube-system_0c27f717a45ba50e9bd38779c6ed404f_0\" is already in use by container 8b2096bc6f627d3471009277b82ff631f97a308512af5e625080301ac2ea4f45. You have to remove (or rename) that container to be able to reuse that name."

 

 

하지만 이 오류는 kube-apiserver가 재생성 될 때 잠시 충돌나는 오류고

ImagePolicyWebhook에 관련된 오류는 아니였음.

 

 

 


 

 

 

Error 해결 2 : kube-apiserver의 Log를 확인해보자

 

결론은 어떻게든 Log을 확인해보고 싶은데

Container가 생성이 안되니

kube-apiserver에 대한 log를 확인할 수가 없었음.

log를 확인하기 위한 방법을 고민하다 아래와 같은 방법을 사용함.

 

또 문제 해결을 위해 git에서 kube-apiserver Opensource 를 직접 분석하면서 원인을 찾아봄

https://github.com/kubernetes/apiserver/blob/master/pkg/server/options/admission.go

 

 

kube-apiserver container에서 kube-apiserver tool을 host로 복사해옴

 

1. container에서 kube-apiserver가 실행 중인지 확인

실행 확인함.

해당 실행 옵션도 미리 복사함.

 

kube-apiserver --advertise-address=192.168.133.128 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction --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 --insecure-port=0 --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-key-file=/etc/kubernetes/pki/sa.pub --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 --audit-log-path=/var/log/kubernetes/kube-apiserver.log --logtostderr=false

 

 

2. container에서 kube-apiserver가 있는 위치를 검색

 

[명령어]

find / -name kube-apiserver

 

[결과]

/usr/local/bin 에 위치하고 있음

 

 

3. kube-apiserver를 host로 복사

 

 

 

복사한 kube-apiserver tool을 host에서 실행시기 전에 기존에 실행 중이던 kube-apiserver를 중지 시킴

 

[명령어]

systemctl stop kubelet

 

docker ps

kube-apiserver container id 확인 후 

docker stop [kube-apiserver container id]

으로 정지

 

 

host에서 복사한 kube-apiserver tool을 host에서 실행시켜봄

 

[결과]

정상적으로 실행됨.

 

 

host에서 kube-apiserver에 ImagePolicyWebhook을 추가하고 실행시켜봄

 

[결과]

드디어 kube-apiserver Log를 확인함.

 

./kube-apiserver --advertise-address=192.168.133.128 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook --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 --insecure-port=0 --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-key-file=/etc/kubernetes/pki/sa.pub --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 --audit-log-path=/var/log/kubernetes/kube-apiserver.log --logtostderr=false

 

Flag --insecure-port has been deprecated, This flag will be removed in a future version.

Error: failed to initialize admission: couldn't init admission plugin "ImagePolicyWebhook": no config specified

 

 

 

Error: failed to initialize admission: couldn't init admission plugin "ImagePolicyWebhook": no config specified

 


 

 

Error: failed to initialize admission: couldn't init admission plugin "ImagePolicyWebhook": no config specified

 

 

원인

--admission-control-config-file

설정이 추가되어있지 않아서 발생함.

ImagePolicyWebhook은 admission control config file을 바라보고 

webhook을 찾게 되는데 해당 config file이 없어서 오류가 발생하는 상황..

즉 

--enable-admission-plugin 에서 ImagePolicyWebhook 만 추가하면

오류가 발생한다고 봐야함.

 

해결법

--admission-control-config-file 설정을 추가

그리고 config파일도 경로에 추가함.

 

예)

--admission-control-config-file=/etc/kubernetes/kube-image-bouncer/admission_configuration.json

 

[admission_configuration.json]

{
  "imagePolicy": {
     "kubeConfigFile": "/etc/kubernetes/kube-image-bouncer/kube-image-bouncer.yml",
     "allowTTL": 50,
     "denyTTL": 50,
     "retryBackoff": 500,
     "defaultAllow": false
  }
}

 

 

[kube-apiserver 실행 명령어]

kube-apiserver --advertise-address=192.168.133.128 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook --admission-control-config-file=/etc/kubernetes/kube-image-bouncer/admission_configuration.json --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 --insecure-port=0 --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-key-file=/etc/kubernetes/pki/sa.pub --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 --audit-log-path=/var/log/kubernetes/kube-apiserver.log --logtostderr=false

 

 

 

결과

 

./kube-apiserver --advertise-address=192.168.133.128 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook --admission-control-config-file=/etc/kubernetes/kube-image-bouncer/admission_configuration.json --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 --insecure-port=0 --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-key-file=/etc/kubernetes/pki/sa.pub --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 --audit-log-path=/var/log/kubernetes/kube-apiserver.log --logtostderr=false

Flag --insecure-port has been deprecated, This flag will be removed in a future version.

 

Error: failed to initialize admission: couldn't init admission plugin "ImagePolicyWebhook": invalid configuration: unable to read certificate-authority /etc/kubernetes/kube-image-bouncer/pki/server.crt for bouncer_webhook due to open /etc/kubernetes/kube-image-bouncer/pki/server.crt: no such file or directory

 

 

 

 

/etc/kubernetes/kube-image-bouncer/pki/server.crt 경로에 해당 파일을 생성함.

 

결과 : 해결된 것 같음.

 

 

 

 

 


제 글을 복사할 시 출처를 명시해주세요.
글에 오타, 오류가 있다면 댓글로 알려주세요! 바로 수정하겠습니다!


 

 

 

 

참고

 

https://dzone.com/articles/kubernetes-image-policy-webhook-explained

https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook

https://github.com/flavio/kube-image-bouncer

https://itnext.io/cks-exam-series-5-imagepolicywebhook-8d09f1ceee70

https://unofficial-kubernetes.readthedocs.io/en/latest/admin/admission-controllers/#imagepolicywebhook

https://laptrinhx.com/cks-exam-series-5-imagepolicywebhook-4223728160/

https://techsquad.rocks/blog/kubernetes_image_policy_webhook_explained/

https://www.youtube.com/watch?v=0A0Z7vlYmyU

 

반응형

'Kubernetes > Kubernetes 보안' 카테고리의 다른 글

kube-bench  (0) 2022.05.01
Portieris (v0.12.2)  (0) 2022.02.23
Kubernetes image인증 - Portieris  (0) 2020.12.22
Kubernetes 인증 ( Proxy )  (0) 2020.08.29
Kubernetes 인증 (Webhook 외부 인증 LDAP)  (0) 2020.08.29