주요 콘텐츠로 건너뛰기

Admission Webhook for K8s

1. Casbin K8s-Gatekeeper에 대한 개요 및 문서

Casbin K8s-GateKeeper는 Casbin을 액세스 제어 도구로 통합하는 Kubernetes 입장 웹훅입니다. Casbin K8s-GateKeeper를 사용하면, 어떤 코드도 작성하지 않고, Casbin 모델과 정책의 선언적인 설정 몇 줄만으로 K8s 리소스에 대한 모든 작업을 인증하거나 차단하는 유연한 규칙을 설정할 수 있습니다. 이는 Casbin ACL (Access Control List) 언어의 일부입니다.

Casbin K8s-GateKeeper는 Casbin 커뮤니티에 의해 개발되고 유지 관리됩니다. 이 프로젝트의 저장소는 다음 위치에서 사용할 수 있습니다: https://github.com/casbin/k8s-gatekeeper

0.1 간단한 예시

예를 들어, 어떤 코드도 작성할 필요 없이 다음과 같은 설정 줄을 사용하여 이 기능을 달성할 수 있습니다: "특정 태그가 있는 이미지가 어떤 배포에서도 사용되는 것을 금지합니다":

Model:

[request_definition]
r = obj

[policy_definition]
p = obj,eft

[policy_effect]
e = !some(where (p.eft == deny))

[matchers]
m = r.obj.Request.Namespace == "default" && r.obj.Request.Resource.Resource =="deployments" && \
contain(split(accessWithWildcard(${OBJECT}.Spec.Template.Spec.Containers , "*", "Image"),":",1) , p.obj)

And Policy:

p, "1.14.1",deny

이들은 일반적인 Casbin ACL 언어에 있습니다. 이에 대한 장을 이미 읽었다면 이해하기 매우 쉬울 것입니다.

Casbin K8s-Gatekeeper는 다음과 같은 장점이 있습니다:

  • 사용하기 쉽습니다. 많은 코드를 작성하는 것보다 몇 줄의 ACL을 작성하는 것이 훨씬 낫습니다.
  • 설정의 핫 업데이트를 허용합니다. 설정을 수정하기 위해 전체 플러그인을 종료할 필요가 없습니다.
  • 유연합니다. kubectl gatekeeper로 탐색할 수 있는 어떤 K8s 리소스에도 임의의 규칙을 만들 수 있습니다.
  • K8s 입장 웹훅의 구현을 단순화합니다. 이는 매우 복잡합니다. K8s 입장 웹훅이 무엇인지 또는 어떻게 코드를 작성하는지 알 필요가 없습니다. 제약을 두고 싶은 리소스를 알고 Casbin ACL을 작성하는 것이 전부입니다. 모두가 K8s가 복잡하다는 것을 알고 있지만, Casbin K8s-Gatekeeper를 사용하면 시간을 절약할 수 있습니다.
  • Casbin 커뮤니티에서 유지 관리됩니다. 이 플러그인에 대해 혼란스러운 것이 있거나 이것을 시도하면서 문제가 발생하면 언제든지 저희에게 연락하십시오.

1.1 Casbin K8s-Gatekeeper는 어떻게 작동합니까?

K8s-Gatekeeper는 관리자가 원하지 않는 K8s에서의 모든 작업을 방지하기 위해 Casbin을 사용하여 임의의 사용자 정의 액세스 제어 규칙을 적용하는 K8s의 입장 웹훅입니다.

Casbin은 강력하고 효율적인 오픈 소스 액세스 제어 라이브러리입니다. 다양한 액세스 제어 모델에 기반한 인증을 강제하는 지원을 제공합니다. Casbin에 대한 자세한 내용은 개요를 참조하십시오.

K8s의 입장 웹훅은 '입장 요청'을 받아서 무언가를 하는 HTTP 콜백입니다. 특히, K8s-Gatekeeper는 'ValidatingAdmissionWebhook'이라는 특별한 유형의 입학 웹훅입니다. 이 웹훅은 이 입학 요청을 수락할지 거부할지 결정할 수 있습니다. 입학 요청에 대해 말하자면, 이들은 K8s의 지정된 리소스에 대한 작업을 설명하는 HTTP 요청입니다(예: 배포 생성/삭제). 입학 웹훅에 대한 자세한 내용은 K8s 공식 문서를 참조하십시오.

1.2 작동 방식을 설명하는 예시

예를 들어, 누군가 nginx를 실행하는 파드를 포함하는 배포를 생성하려고 할 때(kubectl 또는 K8s 클라이언트를 사용하여), K8s는 입학 요청을 생성하며, 이는 (YAML 형식으로 번역된다면) 다음과 같을 수 있습니다:

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

이 요청은 그림에 표시된 모든 미들웨어의 과정을 거치게 될 것이며, 이에는 우리의 K8s-Gatekeeper가 포함됩니다. K8s-Gatekeeper는 사용자가 생성하고 유지하는 K8s의 etcd에 저장된 모든 Casbin enforcer를 감지할 수 있습니다(kubectl 또는 우리가 제공하는 Go 클라이언트를 통해). 각 enforcer는 Casbin 모델과 Casbin 정책을 포함합니다. 입학 요청은 각 enforcer에 의해 하나씩 처리되며, 모든 enforcer를 통과해야만 이 K8s-Gatekeeper에 의해 요청이 수락될 수 있습니다.

(Casbin enforcer, 모델, 또는 정책이 무엇인지 이해하지 못한다면, 이 문서를 참조하십시오: 시작하기).

예를 들어, 어떤 이유로 관리자는 'nginx:1.14.1' 이미지의 출현을 금지하면서 'nginx:1.3.1'을 허용하려고 합니다. 다음 규칙과 정책을 포함하는 enforcer를 생성할 수 있습니다(우리는 다음 장에서 enforcer를 생성하는 방법, 이들 모델과 정책이 무엇인지, 그리고 어떻게 작성하는지 설명할 것입니다).

Model:

[request_definition]
r = obj

[policy_definition]
p = obj,eft

[policy_effect]
e = !some(where (p.eft == deny))

[matchers]
m = r.obj.Request.Namespace == "default" && r.obj.Request.Resource.Resource =="deployments" && \
access(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , 0, "Image") == p.obj

Policy:

p, "nginx:1.13.1",allow
p, "nginx:1.14.1",deny

위의 모델과 정책을 포함하는 enforcer를 생성함으로써, 이전의 입학 요청은 이 enforcer에 의해 거부되며, 이는 K8s가 이 배포를 생성하지 않을 것임을 의미합니다.

2 K8s-gatekeeper 설치

K8s-gatekeeper를 설치하는 데는 세 가지 방법이 있습니다: 외부 웹훅, 내부 웹훅, 그리고 Helm.

노트

참고: 이러한 방법들은 사용자가 K8s-gatekeeper를 시험해 보기 위한 것이며, 안전하지 않습니다. 생산 환경에서 사용하려면, 설치 전에 반드시 5장. 고급 설정을 읽고 필요한 수정을 하십시오.

2.1 내부 웹훅

2.1.1 단계 1: 이미지 빌드

내부 웹훅 방법의 경우, 웹훅 자체가 쿠버네티스 내의 서비스로 구현됩니다. 필요한 서비스와 배포를 생성하려면, K8s-gatekeeper의 이미지를 빌드해야 합니다. 다음 명령을 실행하여 자신의 이미지를 빌드할 수 있습니다:

docker build --target webhook -t k8s-gatekeeper .

이 명령은 'k8s-gatekeeper:latest'라는 로컬 이미지를 생성합니다.

노트

참고: minikube를 사용하는 경우, 'docker build'를 실행하기 전에 eval $(minikube -p minikube docker-env)를 실행하십시오.

2.1.2 단계 2: K8s-gatekeeper를 위한 서비스와 배포 설정

다음 명령을 실행하십시오:

kubectl apply -f config/rbac.yaml
kubectl apply -f config/webhook_deployment.yaml
kubectl apply -f config/webhook_internal.yaml

이렇게 하면 K8s-gatekeeper가 실행을 시작하며, kubectl get pods를 실행하여 이를 확인할 수 있습니다.

2.1.3 단계 3: K8s-gatekeeper를 위한 CRD 리소스 설치

다음 명령을 실행하십시오:

kubectl apply -f config/auth.casbin.org_casbinmodels.yaml 
kubectl apply -f config/auth.casbin.org_casbinpolicies.yaml

2.2 외부 웹훅

외부 웹훅 방법에 대해, K8s-gatekeeper는 쿠버네티스 외부에서 실행되며, 쿠버네티스는 일반 웹사이트에 접근하는 것처럼 K8s-gatekeeper에 접근할 것입니다. 쿠버네티스는 admission 웹훅이 반드시 HTTPS여야 한다는 필수 요구사항을 가지고 있습니다. K8s-gatekeeper를 시험해 보기 위한 목적으로, 우리는 일련의 인증서와 개인 키를 제공하였습니다(비록 이것이 안전하지는 않습니다). 자신의 인증서를 사용하려면, 인증서와 개인 키를 조정하는 방법에 대한 지침을 위해 5장을 참조하십시오. 고급 설정.

우리가 제공하는 인증서는 'webhook.domain.local'에 대해 발급되었습니다. 그래서, 호스트를 수정하십시오(예: /etc/hosts) 그리고 'webhook.domain.local'을 K8s-gatekeeper가 실행 중인 IP 주소로 지정하십시오.

그런 다음 다음 명령을 실행하십시오:

go mod tidy
go mod vendor
go run cmd/webhook/main.go
kubectl apply -f config/auth.casbin.org_casbinmodels.yaml
kubectl apply -f config/auth.casbin.org_casbinpolicies.yaml
kubectl apply -f config/webhook_external.yaml

2.3 Helm을 통한 K8s-gatekeeper 설치

2.3.1 단계 1: 이미지 빌드

2.1.1장을 참조하십시오.

2.3.2 Helm 설치

helm install k8sgatekeeper ./k8sgatekeeper 명령을 실행하십시오.

3. K8s-gatekeeper 시도하기

3.1 Casbin 모델 및 정책 생성

모델과 정책을 생성하는 두 가지 방법이 있습니다: kubectl을 통해 또는 우리가 제공하는 go-client를 통해.

3.1.1 kubectl을 통한 Casbin 모델 및 정책 생성/업데이트

K8s-gatekeeper에서, Casbin 모델은 'CasbinModel'이라는 CRD 리소스에 저장됩니다. 그 정의는 config/auth.casbin.org_casbinmodels.yaml에 위치해 있습니다.

example/allowed_repo/model.yaml에 예시가 있습니다. 다음 필드에 주의하십시오:

  • metadata.name: 모델의 이름입니다. 이 이름은 반드시 이 모델과 관련된 CasbinPolicy 객체의 이름과 동일해야 하므로, K8s-gatekeeper가 그들을 짝지어 enforcer를 생성할 수 있습니다.
  • spec.enable: 이 필드가 "false"로 설정되면, 이 모델(그리고 이 모델과 관련된 CasbinPolicy 객체)은 무시될 것입니다.
  • spec.modelText: Casbin 모델의 모델 텍스트를 포함하는 문자열입니다.

Casbin 정책은 'CasbinPolicy'라는 다른 CRD 리소스에 저장되며, 그 정의는 config/auth.casbin.org_casbinpolicies.yaml에서 찾을 수 있습니다.

example/allowed_repo/policy.yaml에 예시가 있습니다. 다음 필드에 주의하십시오:

  • metadata.name: 정책의 이름입니다. 이 이름은 이 정책과 관련된 CasbinModel 객체의 이름과 동일해야 하므로, K8s-gatekeeper가 그들을 짝지어 enforcer를 생성할 수 있습니다.
  • spec.policyItem: Casbin 모델의 정책 텍스트를 포함하는 문자열입니다.

자신의 CasbinModel과 CasbinPolicy 파일을 생성한 후, 다음 명령을 사용하여 적용하십시오:

kubectl apply -f <filename>

CasbinModel과 CasbinPolicy의 쌍이 생성되면, K8s-gatekeeper는 5초 이내에 이를 감지할 수 있습니다.

3.1.2 우리가 제공하는 go-client를 통해 Casbin 모델과 정책 생성/업데이트

K8s 클러스터의 노드에서 직접 명령을 실행하는 데 쉘을 사용하는 것이 편리하지 않은 상황이 있을 수 있음을 이해합니다. 예를 들어, 회사의 자동 클라우드 플랫폼을 구축할 때입니다. 따라서, 우리는 CasbinModel과 CasbinPolicy를 생성하고 유지하기 위한 go-client를 개발했습니다.

go-client 라이브러리는 pkg/client에 위치해 있습니다.

client.go에서는 클라이언트를 생성하는 함수를 제공합니다.

func NewK8sGateKeeperClient(externalClient bool) (*K8sGateKeeperClient, error) 

externalClient 매개변수는 K8s-gatekeeper가 K8s 클러스터 내부에서 실행되고 있는지 여부를 결정합니다.

model.go에서는 CasbinModel을 생성, 삭제, 수정하는 다양한 함수를 제공합니다. model_test.go에서 이러한 인터페이스를 어떻게 사용하는지 알아볼 수 있습니다.

policy.go에서는 CasbiPolicy를 생성, 삭제, 수정하는 다양한 함수를 제공합니다. policy_test.go에서 이러한 인터페이스를 어떻게 사용하는지 알아볼 수 있습니다.

3.1.2 K8s-gatekeeper 작동 여부 확인

example/allowed_repo에서 정확한 모델과 정책을 이미 생성했다고 가정합니다. 이제, 다음 명령을 시도해 보세요:

kubectl apply -f example/allowed_repo/testcase/reject_1.yaml

K8s가 이 요청을 거부하고, 웹훅이 이 요청이 거부된 이유라고 언급하는 것을 발견해야 합니다. 그러나, example/allowed_repo/testcase/approve_2.yaml을 적용하려고 하면, 이는 수락될 것입니다.

4. K8s-gatekeeper로 모델과 정책 작성 방법

먼저, Casbin 모델과 정책의 기본 문법에 익숙해야 합니다. 그렇지 않다면, 먼저 시작하기 섹션을 읽어보십시오. 이 장에서는 이미 Casbin 모델과 정책이 무엇인지 이해하고 있다고 가정합니다.

4.1 모델의 요청 정의

K8s-gatekeeper가 요청을 인증할 때, 입력은 항상 객체입니다: Admission Request의 Go 객체입니다. 이는 enforcer가 항상 다음과 같이 사용될 것임을 의미합니다:

ok, err := enforcer.Enforce(admission)

여기서 admission은 K8s의 공식 go api인 "k8s.io/api/admission/v1"에 의해 정의된 AdmissionReview 객체입니다. 이 구조체의 정의는 이 저장소에서 찾을 수 있습니다: https://github.com/kubernetes/api/blob/master/admission/v1/types.go. 자세한 정보는 https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#webhook-request-and-response를 참조하실 수 있습니다.

따라서, K8s-gatekeeper에서 사용하는 모든 모델에 대해 request_definition의 정의는 항상 이렇게 되어야 합니다:

    [request_definition]
r = obj

'obj'라는 이름은 필수가 아니며, 이름이 [matchers] 부분에서 사용된 이름과 일치하기만 하면 됩니다.

4.2 모델의 Matchers

규칙을 작성할 때 Casbin의 ABAC 기능을 사용해야 합니다. 그러나, Casbin에 통합된 표현식 평가기는 맵이나 배열(슬라이스)에서의 인덱싱을 지원하지 않으며, 배열의 확장도 지원하지 않습니다. 따라서, K8s-gatekeeper는 이러한 기능을 구현하기 위해 다양한 'Casbin 함수'를 확장으로 제공합니다. 이러한 확장으로도 요구사항을 충족시키지 못한다면, 자유롭게 이슈를 시작하거나 풀 리퀘스트를 생성하십시오.

Casbin 함수에 익숙하지 않다면, 자세한 정보를 얻기 위해 Function을 참조하실 수 있습니다.

다음은 확장 함수입니다:

4.2.1 확장 함수

4.2.1.1 접근

Access는 Casbin이 맵이나 배열에서의 인덱싱을 지원하지 않는 문제를 해결하는 데 사용됩니다. 이 함수의 사용법은 example/allowed_repo/model.yaml 예제에서 확인할 수 있습니다:

[matchers]
m = r.obj.Request.Namespace == "default" && r.obj.Request.Resource.Resource =="deployments" && \
access(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , 0, "Image") == p.obj

이 matcher에서, access(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , 0, "Image")r.obj.Request.Object.Object.Spec.Template.Spec.Containers[0].Image와 동일하며, 여기서 r.obj.Request.Object.Object.Spec.Template.Spec.Containers는 슬라이스입니다.

Access는 매개변수가 없고 단일 값을 반환하는 간단한 함수를 호출할 수도 있습니다. 이는 example/container_resource_limit/model.yaml 예제에서 확인할 수 있습니다:

[matchers]
m = r.obj.Request.Namespace == "default" && r.obj.Request.Resource.Resource =="deployments" && \
parseFloat(access(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , 0, "Resources","Limits","cpu","Value")) >= parseFloat(p.cpu) && \
parseFloat(access(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , 0, "Resources","Limits","memory","Value")) >= parseFloat(p.memory)

이 matcher에서, access(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , 0, "Resources","Limits","cpu","Value")r.obj.Request.Object.Object.Spec.Template.Spec.Containers[0].Resources.Limits["cpu"].Value()와 동일하며, 여기서 r.obj.Request.Object.Object.Spec.Template.Spec.Containers[0].Resources.Limits는 맵이고, Value()는 매개변수가 없고 단일 값을 반환하는 간단한 함수입니다.

4.2.1.2 accessWithWildcard

때때로, 배열의 모든 요소가 "aaa" 접두사를 가져야 하는 요구사항이 있을 수 있습니다. 그러나, Casbin은 for 루프를 지원하지 않습니다. accessWithWildcard와 "map/slice expansion" 기능을 사용하면 이러한 요구사항을 쉽게 구현할 수 있습니다.

예를 들어, a.b.c가 배열 [aaa,bbb,ccc,ddd,eee]라면, accessWithWildcard(a,"b","c","*")의 결과는 슬라이스 [aaa,bbb,ccc,ddd,eee]가 됩니다. 와일드카드 *를 사용하면 슬라이스가 확장됩니다.

마찬가지로, 와일드카드는 한 번 이상 사용할 수 있습니다. 예를 들어, accessWithWildcard(a,"b","c","*","*")의 결과는 [a.b.c[0][0], a.b.c[0][1], ..., a.b.c[1][0], a.b.c[1][1], ...]가 됩니다.

4.2.1.3 가변 길이 인수를 지원하는 함수

Casbin의 표현식 평가기에서 매개변수가 배열인 경우, 이는 자동으로 가변 길이 인수로 확장됩니다. 이 기능을 활용하여 배열/슬라이스/맵 확장을 지원하며, 배열/슬라이스를 매개변수로 받는 여러 함수를 통합했습니다:

  • contain(): 여러 매개변수를 받아 마지막 매개변수를 제외한 어떤 매개변수든 마지막 매개변수와 같은지 여부를 반환합니다.
  • split(a,b,c...,sep,index): [splits(a,sep)[index], splits(b,sep)[index], splits(a,sep)[index], ...]를 포함하는 슬라이스를 반환합니다.
  • len(): 가변 길이 인수의 길이를 반환합니다.
  • matchRegex(a,b,c...,regex): 주어진 모든 매개변수 (a, b, c, ...)가 주어진 regex와 일치하는지 여부를 반환합니다.

다음은 example/disallowed_tag/model.yaml에서의 예시입니다:

    [matchers]
m = r.obj.Request.Namespace == "default" && r.obj.Request.Resource.Resource =="deployments" && \
contain(split(accessWithWildcard(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , "*", "Image"),":",1) , p.obj)

accessWithWildcard(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , "*", "Image")["a:b", "c:d", "e:f", "g:h"]를 반환한다고 가정하면, splits는 가변 길이 인수를 지원하고 각 요소에 대해 splits 연산을 수행하므로, 인덱스 1의 요소가 선택되어 반환됩니다. 따라서, split(accessWithWildcard(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , "*", "Image"),":",1)["b","d","f","h"]를 반환합니다. 그리고 contain(split(accessWithWildcard(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , "*", "Image"),":",1) , p.obj)p.obj["b","d","f","h"]에 포함되어 있는지 여부를 반환합니다.

4.2.1.2 타입 변환 함수들

  • ParseFloat(): 정수를 부동소수점으로 변환합니다 (비교에 사용되는 모든 숫자는 부동소수점으로 변환되어야 하기 때문입니다).
  • ToString(): 객체를 문자열로 변환합니다. 이 객체는 기본적으로 문자열 타입이어야 합니다 (예를 들어, type XXX string이라는 문장이 있을 때 XXX 타입의 객체).
  • IsNil(): 매개변수가 nil인지 여부를 반환합니다.

5. 고급 설정

5.1 인증서에 대하여

쿠버네티스(k8s)에서는 웹훅이 HTTPS를 사용하는 것이 필수입니다. 이를 달성하기 위한 두 가지 접근법이 있습니다:

  • 자체 서명 인증서 사용 (이 저장소의 예제에서는 이 방법을 사용)
  • 일반 인증서 사용

5.1.1 자체 서명 인증서

자체 서명 인증서를 사용한다는 것은 인증서를 발급하는 인증 기관(CA)이 잘 알려진 CA 중 하나가 아니라는 것을 의미합니다. 따라서, k8s에 이 CA를 알려야 합니다.

현재, 이 저장소의 예제에서는 자체 제작 CA를 사용하고 있으며, 그 개인 키와 인증서는 각각 config/certificate/ca.crtconfig/certificate/ca.key에 저장되어 있습니다. 웹훅의 인증서는 config/certificate/server.crt로, 이는 자체 제작 CA에 의해 발급되었습니다. 이 인증서의 도메인은 "webhook.domain.local" (외부 웹훅용)과 "casbin-webhook-svc.default.svc" (내부 웹훅용)입니다.

CA에 대한 정보는 웹훅 설정 파일을 통해 k8s에 전달됩니다. config/webhook_external.yamlconfig/webhook_internal.yaml 모두 "CABundle"이라는 필드를 가지고 있으며, 이는 CA의 인증서의 base64 인코딩 문자열을 포함하고 있습니다.

인증서/도메인을 변경해야 하는 경우 (예를 들어, 내부 웹훅을 사용하면서 이 웹훅을 k8s의 다른 네임스페이스로 옮기고 싶거나, 외부 웹훅을 사용하면서 도메인을 변경하고 싶은 경우) 다음 절차를 따라야 합니다:

  1. 새로운 CA 생성:

    • 가짜 CA의 개인 키를 생성합니다:

      openssl genrsa -des3 -out ca.key 2048
    • 개인 키의 비밀번호 보호를 제거합니다:

      openssl rsa -in ca.key -out ca.key
  2. 웹훅 서버의 개인 키를 생성합니다:

    openssl genrsa -des3 -out server.key 2048
    openssl rsa -in server.key -out server.key
  3. 자체 생성된 CA를 사용하여 웹훅의 인증서에 서명합니다:

    • 임시 사용을 위해 시스템의 openssl 설정 파일을 복사합니다. openssl version -a를 실행하여 설정 파일의 위치를 찾을 수 있으며, 일반적으로 openssl.cnf라고 불립니다.

    • 설정 파일에서:

      • [req] 단락을 찾아 다음 줄을 추가합니다: req_extensions = v3_req

      • [v3_req] 단락을 찾아 다음 줄을 추가합니다: subjectAltName = @alt_names

      • 파일에 다음 줄을 추가합니다:

        [alt_names]
        DNS.2=<The domain you want>

        참고: 서비스 이름을 수정하기로 결정한 경우 실제 서비스의 서비스 이름으로 'casbin-webhook-svc.default.svc'를 교체합니다.

    • 수정된 설정 파일을 사용하여 인증서 요청 파일을 생성합니다:

      openssl req -new -nodes -keyout server.key -out server.csr -config openssl.cnf
    • 자체 제작 CA를 사용하여 요청에 응답하고 인증서에 서명합니다:

      openssl x509 -req -days 3650 -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -extensions v3_req -extensions SAN -extfile openssl.cnf
  4. 'CABundle' 필드를 교체합니다: config/webhook_external.yamlconfig/webhook_internal.yaml에는 CA의 인증서의 base64 인코딩 문자열이 포함된 'CABundle'이라는 필드가 있습니다. 이 필드를 새 인증서로 업데이트합니다.

  5. helm을 사용하는 경우, helm 차트에도 비슷한 변경이 적용되어야 합니다.

5.1.2 법적 인증서

법적 인증서를 사용하는 경우, 이 모든 절차를 거칠 필요가 없습니다. config/webhook_external.yamlconfig/webhook_internal.yaml에서 'CABundle' 필드를 제거하고, 이 파일들의 도메인을 소유한 도메인으로 변경합니다.