쿠버네티스는 기본적으로 API 요청이 오면 위와 같은 순서로 작업을 처리합니다.
그 중간에 Mutating admission 부분에 Webhook을
이용한 pod injection 예제로 pod injection 하는 부분을 알아보고
예제가 오래된 관계로 v1beta1인 예제를 v1으로 업데이트하는 부분까지 할 예정입니다.
Webhook의 작동 방식
- 출처 mutating webhook tutorial 깃헙
MutatingWebhook은 요청이 etcd에 등록되기 전에 MutatingWebhookConfiguration 의 rule과
일치하는 request를 intercept 합니다.
MutatingWebhook은 webhook 서버에 승인을 요청하여
mutation ( injection이라던지 수정같은 작업) 을 수행합니다.
( webhook 서버는 API를 준수하는 일반 http 서버)
예제
https://github.com/morvencao/kube-mutating-webhook-tutorial
이 튜토리얼은 nginx 사이드카 컨테이너를 파드에 injection 하는 MutatingAdmissionWebhook을 빌드하고 배포하는 방법을 보여줍니다.
조건
- git
- go version v1.12+
- docker version 17.03+
- kubectl version v1.11.3+
- kubernetes v1.11.3+ cluster with admissionregistration.k8s.io/v1beta1 API enabled
- 처음은 v1beta1로 작업하고 추후에 v1으로 수정할 예정.
admissionregistration.k8s.io/v1beta1 API enabled 확인 방법
kubectl api-versions | grep admissionregistration.k8s.io
결과는 아래와 같이 나와야합니다.
admissionregistration.k8s.io/v1 admissionregistration.k8s.io/v1beta1
빌드
- Build binary
# make build
- Build docker image
# make build-image
- push docker image
# make push-image
deploy
- sidecar injector webhook이 배포될 sidecar-injector namespace를 생성
# kubectl create ns sidecar-injector
-
sidecar injector deployment에 사용될 secret 생성
(이 시크릿은 cert와 key 정보를 가지고 있다):
# ./deployment/webhook-create-signed-cert.sh \\ --service sidecar-injector-webhook-svc \\ --secret sidecar-injector-webhook-certs \\ --namespace sidecar-injector
- 위에서 생성한 caBundle 값을 mutatingwebhook.yaml 에 패치를 한 결과를 mutatingwebhook-ca-bundle.yaml로 생성한다.:
# cat deployment/mutatingwebhook.yaml | \\ deployment/webhook-patch-ca-bundle.sh > \\ deployment/mutatingwebhook-ca-bundle.yaml
- 리소스들을 배포한다.:
# kubectl create -f deployment/nginxconfigmap.yaml # kubectl create -f deployment/configmap.yaml # kubectl create -f deployment/deployment.yaml # kubectl create -f deployment/service.yaml # kubectl create -f deployment/mutatingwebhook-ca-bundle.yaml
확인
- sidecar injector webhook이 잘 배포됬나 확인한다.
# kubectl -n sidecar-injector get pod NAME READY STATUS RESTARTS AGE sidecar-injector-webhook-deployment-7c8bc5f4c9-28c84 1/1 Running 0 30s # kubectl -n sidecar-injector get deploy NAME READY UP-TO-DATE AVAILABLE AGE sidecar-injector-webhook-deployment 1/1 1 1 67s
- injection namespace 생성 그리고 sidecar-injector=enabled로 라벨링 한다.
# kubectl create ns injection # kubectl label namespace injection sidecar-injection=enabled # kubectl get namespace -L sidecar-injection NAME STATUS AGE SIDECAR-INJECTION default Active 26m injection Active 13s enabled kube-public Active 26m kube-system Active 26m sidecar-injector Active 17m
- alpine app을 예제로 쿠버네티스 클러스터에 배포한다.
# kubectl run alpine --image=alpine --restart=Never -n injection --overrides='{"apiVersion":"v1","metadata":{"annotations":{"sidecar-injector-webhook.morven.me/inject":"yes"}}}' --command -- sleep infinity
- sidecar container가 injected 됬는지 확인한다.
# kubectl get pod NAME READY STATUS RESTARTS AGE alpine 2/2 Running 0 1m # kubectl -n injection get pod alpine -o jsonpath="{.spec.containers[*].name}" alpine sidecar-nginx
admissionregistration.k8s.io/v1beta1 를 v1으로 업그레이드 하기
webhook의 작동방식부분에서 mutatingadmissionwebhook 부분과 webhook 서버를 보면
admissionReview를 요청하고 응답받는것을 보실수 있습니다.
v1beta1버전에서는 요청에 대한 응답시 kind와 apiversion 을 넣지 않아도 응답을 정상으로 판단 했습니다.
하지만 v1버전에서는 요청에 대한 응답시 kind와 apiversion 버전을 추가시켜줘야 합니다.
위 빈 라인에 아래와 같이 요청으로 들어온 api version 과 kind , uid를 그대로 review 응답에 넣어줍니다.
admissionReview.Response.UID = ar.Request.UID admissionReview.APIVersion = ar.APIVersion admissionReview.Kind = ar.Kind
위와 같이 할 경우 v1beta1로 요청이 들어왔을 경우 그대로 v1beta1로 응답하며
v1로 요청이 왔을 경우 그대로 v1로 응답이 갑니다.
그 후 deployment/mutatingwebhook.yaml 을 수정합니다.
apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: name: sidecar-injector-webhook-cfg labels: app: sidecar-injector webhooks: - name: sidecar-injector.morven.me clientConfig: service: name: sidecar-injector-webhook-svc namespace: sidecar-injector path: "/mutate" caBundle: ${CA_BUNDLE} rules: - operations: ["CREATE", "UPDATE"] apiGroups: [""] apiVersions: ["v1"] resources: ["pods"] namespaceSelector: matchLabels: sidecar-injection: enabled admissionReviewVersions: ["v1"] sideEffects: None
위와 같이 수정하면 v1로 업데이트 완료입니다.
Injection 수정하기
webhook 서버에서 injection 처리 부분은 webhook.go 파일 입니다.
webhook.go 안에 createPatch 부분이 injection 할 내용을 생성하는 부분입니다.
이 부분으로 생성 후 apiserver로 다시 요청을 응답하는 작업이 이루어집니다.
이때 이 부분도 같이 response에 담겨서 응답하게 됩니다.
createPatch 부분을 참고하셔서 수정하시면 자신만의 injection 을 만드실수 있습니다.
createPath의 추가적인 참고는 하단의 tumblr github을 참고해주세요.
정리
mutating webhook은 추가적인 변경이나, 검증을 쉽게 제공해줘서 go를 처음접하는 저로써도
손쉽게 수정하여 저만의 injection 을 만들수 있었습니다.
다만 v1beta1에서 v1 patch부분이나 인증서 관련 부분은 삽질이 좀 필요해서 글로 남기게 됬습니다.
인증서 부분과 webhook 소스내부 설명은 다음글에 남겨보도록 하겠습니다.
'개발 > Kubernetes' 카테고리의 다른 글
왜 apiversion이 변경되어 있을까 (0) | 2021.06.11 |
---|---|
컨테이너 런타임 (0) | 2021.03.07 |
쿠버네티스의 클러스터 구성 (0) | 2021.01.28 |
k8s 에서 spring boot jib image command 수정 (0) | 2020.12.24 |
클러스터 구성 (0) | 2020.09.13 |