Bỏ qua đến nội dung chính

Admission Webhook for K8s

1. Tổng quan & Tài liệu cho Casbin K8s-Gatekeeper

Casbin K8s-GateKeeper là một webhook kiểm soát truy cập của Kubernetes tích hợp Casbin như công cụ Quản lý Truy cập. Bằng cách sử dụng Casbin K8s-GateKeeper, bạn có thể thiết lập các quy tắc linh hoạt để ủy quyền hoặc chặn bất kỳ hoạt động nào trên tài nguyên K8s, KHÔNG CẦN viết bất kỳ đoạn mã nào, chỉ với một vài dòng cấu hình khai báo của mô hình và chính sách Casbin, đó là một phần của ngôn ngữ ACL (Access Control List) của Casbin.

Casbin K8s-GateKeeper được phát triển và bảo trì bởi cộng đồng Casbin. Kho lưu trữ của dự án này có sẵn tại đây: https://github.com/casbin/k8s-gatekeeper

0.1 Ví dụ Đơn Giản

Ví dụ, bạn không cần phải viết bất kỳ mã nào, nhưng sử dụng các dòng cấu hình sau để đạt được chức năng này: "Cấm sử dụng các image có những tag được chỉ định trong bất kỳ deployment nào":

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

Đây là trong ngôn ngữ ACL thông thường của Casbin. Giả sử bạn đã đọc các chương về chúng, nó sẽ rất dễ hiểu.

Casbin K8s-GateKeeper có những ưu điểm sau:

  • Dễ sử dụng. Viết một vài dòng mã ACL tốt hơn nhiều so với viết một lượng lớn mã nguồn.
  • Nó cho phép cập nhật cấu hình nóng. Bạn không cần phải tắt toàn bộ plugin để sửa đổi cấu hình.
  • Nó rất linh hoạt. Có thể tạo các quy tắc tùy ý trên bất kỳ tài nguyên K8s nào, có thể khám phá với kubectl gatekeeper.
  • Nó đơn giản hóa việc triển khai webhook kiểm soát truy cập K8s, điều này rất phức tạp. Bạn không cần biết webhook kiểm soát truy cập K8s là gì hoặc làm thế nào để viết mã cho nó. Tất cả những gì bạn cần làm là biết tài nguyên mà bạn muốn đặt ràng buộc và sau đó viết mã ACL Casbin. Mọi người đều biết rằng K8s rất phức tạp, nhưng bằng cách sử dụng Casbin K8s-Gatekeeper, thời gian của bạn có thể được tiết kiệm.
  • Nó được duy trì bởi cộng đồng Casbin. Hãy thoải mái liên hệ với chúng tôi nếu bạn có bất kỳ thắc mắc nào về plugin này hoặc gặp phải bất kỳ vấn đề gì khi thử nghiệm.

1.1 Cách Casbin K8s-Gatekeeper hoạt động?

K8s-Gatekeeper là một admission webhook cho K8s sử dụng Casbin để áp dụng các quy tắc kiểm soát truy cập do người dùng định nghĩa tùy ý, giúp ngăn chặn bất kỳ hoạt động nào trên K8s mà quản trị viên không muốn.

Casbin là một thư viện kiểm soát truy cập mã nguồn mở mạnh mẽ và hiệu quả. Nó cung cấp hỗ trợ cho việc thực thi ủy quyền dựa trên nhiều mô hình kiểm soát truy cập khác nhau. Để biết thêm chi tiết về Casbin, hãy xem Tổng quan.

Admission webhooks trong K8s là các cuộc gọi lại HTTP nhận 'yêu cầu admission' và thực hiện một việc gì đó với chúng. Đặc biệt, K8s-Gatekeeper là một loại admission webhook đặc biệt: 'ValidatingAdmissionWebhook', có thể quyết định chấp nhận hay từ chối yêu cầu admission này. Đối với yêu cầu admission, chúng là các yêu cầu HTTP mô tả một hoạt động trên các tài nguyên được chỉ định của K8s (ví dụ: tạo/xóa một deployment). Để biết thêm về admission webhooks, hãy xem Tài liệu chính thức của K8s.

1.2 Một Ví Dụ Minh Họa Cách Nó Hoạt Động

Ví dụ, khi ai đó muốn tạo một bản triển khai chứa một pod chạy nginx (sử dụng kubectl hoặc các client K8s), K8s sẽ tạo ra một yêu cầu nhập cảnh, mà (nếu được dịch sang định dạng YAML) có thể giống như thế này:

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

Yêu cầu này sẽ đi qua quá trình xử lý của tất cả các middleware được hiển thị trong hình, bao gồm cả K8s-Gatekeeper của chúng tôi. K8s-Gatekeeper có thể phát hiện tất cả các enforcer Casbin được lưu trữ trong etcd của K8s, được tạo và duy trì bởi người dùng (thông qua kubectl hoặc client Go mà chúng tôi cung cấp). Mỗi enforcer chứa một mô hình Casbin và một chính sách Casbin. Yêu cầu nhập cảnh sẽ được xử lý bởi từng enforcer, một cách tuần tự, và chỉ khi vượt qua tất cả các enforcer thì yêu cầu mới được chấp nhận bởi K8s-Gatekeeper này.

(Nếu bạn không hiểu enforcer Casbin, mô hình, hoặc chính sách là gì, hãy xem tài liệu này: Bắt Đầu).

Ví dụ, vì một lý do nào đó, người quản trị muốn cấm sự xuất hiện của image 'nginx:1.14.1' trong khi cho phép 'nginx:1.3.1'. Một enforcer chứa quy tắc và chính sách sau có thể được tạo ra (Chúng tôi sẽ giải thích cách tạo một enforcer, mô hình và chính sách là gì, và cách viết chúng trong các chương tiếp theo).

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

Bằng cách tạo một enforcer chứa mô hình và chính sách ở trên, yêu cầu nhập cảnh trước đó sẽ bị từ chối bởi enforcer này, điều đó có nghĩa là K8s sẽ không tạo ra bộ triển khai này.

2 Cài đặt K8s-gatekeeper

Có ba phương pháp có sẵn để cài đặt K8s-gatekeeper: Webhook bên ngoài, Webhook nội bộ và Helm.

ghi chú

Lưu ý: Những phương pháp này chỉ dành cho người dùng thử nghiệm K8s-gatekeeper và không an toàn. Nếu bạn muốn sử dụng nó trong môi trường sản xuất, vui lòng đảm bảo rằng bạn đã đọc Chương 5. Cài đặt nâng cao và thực hiện bất kỳ sửa đổi cần thiết nào trước khi cài đặt.

2.1 Webhook nội bộ

2.1.1 Bước 1: Xây dựng hình ảnh

Đối với phương pháp webhook nội bộ, chính webhook sẽ được triển khai như một dịch vụ trong Kubernetes. Để tạo dịch vụ và triển khai cần thiết, bạn cần xây dựng một hình ảnh của K8s-gatekeeper. Bạn có thể xây dựng hình ảnh của riêng mình bằng cách chạy lệnh sau:

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

Lệnh này sẽ tạo một hình ảnh cục bộ có tên 'k8s-gatekeeper:latest'.

ghi chú

Lưu ý: Nếu bạn đang sử dụng minikube, vui lòng thực hiện eval $(minikube -p minikube docker-env) trước khi chạy 'docker build'.

2.1.2 Bước 2: Thiết lập dịch vụ và triển khai cho K8s-gatekeeper

Chạy các lệnh sau:

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

Điều này sẽ bắt đầu chạy K8s-gatekeeper, và bạn có thể xác nhận điều này bằng cách chạy kubectl get pods.

2.1.3 Bước 3: Cài đặt Tài nguyên CRD cho K8s-gatekeeper

Chạy các lệnh sau:

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

2.2 Webhook bên ngoài

Đối với phương thức webhook bên ngoài, K8s-gatekeeper sẽ chạy bên ngoài Kubernetes, và Kubernetes sẽ truy cập K8s-gatekeeper như thể nó truy cập một trang web thông thường. Kubernetes có một yêu cầu bắt buộc là webhook kiểm soát truy cập phải sử dụng giao thức HTTPS. Vì mục đích thử nghiệm K8s-gatekeeper, chúng tôi đã cung cấp một bộ chứng chỉ và một khóa riêng (mặc dù điều này không an toàn). Nếu bạn muốn sử dụng chứng chỉ của riêng mình, vui lòng tham khảo Chương 5. Cài đặt nâng cao để được hướng dẫn điều chỉnh chứng chỉ và khóa riêng. Chứng chỉ mà chúng tôi cung cấp được cấp cho 'webhook.domain.local'.

Vì vậy, hãy sửa đổi máy chủ (ví dụ: /etc/hosts) và trỏ 'webhook.domain.local' đến địa chỉ IP mà K8s-gatekeeper đang chạy. Sau đó thực hiện lệnh sau:

2.3 Cài đặt K8s-gatekeeper thông qua Helm

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.1 Bước 1: Xây dựng hình ảnh

2.3.1 Adım 1: Görüntüyü oluşturun

Vui lòng tham khảo Chương 2.1.1.

2.3.2 Cài đặt Helm

Chạy lệnh helm install k8sgatekeeper ./k8sgatekeeper.

3. Thử K8s-gatekeeper

3.1 Tạo Mô hình và Chính sách Casbin

Bạn có hai phương pháp để tạo một mô hình và chính sách: thông qua kubectl hoặc thông qua go-client mà chúng tôi cung cấp.

3.1.1 Tạo/Cập nhật Mô hình và Chính sách Casbin qua kubectl

Trong K8s-gatekeeper, mô hình Casbin được lưu trữ trong một tài nguyên CRD có tên là 'CasbinModel'. Định nghĩa của nó nằm trong config/auth.casbin.org_casbinmodels.yaml.

Có ví dụ trong example/allowed_repo/model.yaml. Chú ý đến các trường sau:

  • metadata.name: tên của mô hình. Tên này PHẢI giống với tên của đối tượng CasbinPolicy liên quan đến mô hình này, để K8s-gatekeeper có thể ghép cặp chúng và tạo một enforcer.
  • spec.enable: nếu trường này được đặt thành "false", mô hình này (cũng như đối tượng CasbinPolicy liên quan đến mô hình này) sẽ bị bỏ qua.
  • spec.modelText: một chuỗi chứa văn bản mô hình của một mô hình Casbin.

Chính sách Casbin được lưu trữ trong một tài nguyên CRD khác được gọi là 'CasbinPolicy', định nghĩa của nó có thể được tìm thấy trong config/auth.casbin.org_casbinpolicies.yaml.

Có ví dụ trong example/allowed_repo/policy.yaml. Chú ý đến các trường sau:

  • metadata.name: tên của chính sách. Tên này PHẢI giống với tên của đối tượng CasbinModel liên quan đến chính sách này, để K8s-gatekeeper có thể ghép cặp chúng và tạo ra một enforcer.
  • spec.policyItem: một chuỗi chứa văn bản chính sách của một mô hình Casbin.

Sau khi tạo các tệp CasbinModel và CasbinPolicy của riêng bạn, sử dụng lệnh sau để áp dụng chúng:

kubectl apply -f <filename>

Một khi một cặp CasbinModel và CasbinPolicy được tạo, K8s-gatekeeper sẽ có thể phát hiện nó trong vòng 5 giây.

3.1.2 Tạo/Cập nhật Mô hình và Chính sách Casbin thông qua go-client mà chúng tôi cung cấp

Chúng tôi hiểu rằng có thể có tình huống mà việc sử dụng shell để thực thi các lệnh trực tiếp trên một nút của cụm K8s không thuận tiện, chẳng hạn như khi bạn đang xây dựng một nền tảng điện toán đám mây tự động cho công ty của mình. Do đó, chúng tôi đã phát triển một go-client để tạo và duy trì CasbinModel và CasbinPolicy.

Thư viện go-client nằm trong pkg/client.

Trong client.go, chúng tôi cung cấp một hàm để tạo một client.

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

Tham số externalClient xác định liệu K8s-gatekeeper có đang chạy bên trong cụm K8s hay không.

Trong model.go, chúng tôi cung cấp nhiều hàm để tạo, xóa và sửa đổi CasbinModel. Bạn có thể tìm hiểu cách sử dụng các giao diện này trong model_test.go.

Trong policy.go, chúng tôi cung cấp nhiều hàm để tạo, xóa và sửa đổi CasbiPolicy. Bạn có thể tìm hiểu cách sử dụng các giao diện này trong policy_test.go.

3.1.2 Thử xem K8s-gatekeeper có hoạt động không

Giả sử bạn đã tạo chính xác mô hình và chính sách trong example/allowed_repo. Bây giờ, hãy thử lệnh sau:

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

Bạn sẽ thấy rằng K8s sẽ từ chối yêu cầu này và đề cập rằng webhook là lý do tại sao yêu cầu này bị từ chối. Tuy nhiên, khi bạn thử áp dụng example/allowed_repo/testcase/approve_2.yaml, nó sẽ được chấp nhận.

4. Cách Viết Mô hình và Chính sách với K8s-gatekeeper

Trước hết, hãy đảm bảo bạn quen thuộc với cú pháp cơ bản của Mô hình và Chính sách Casbin. Nếu không, vui lòng đọc phần Bắt đầu trước. Trong chương này, chúng tôi giả định rằng bạn đã hiểu Mô hình và Chính sách Casbin là gì.

4.1 Định nghĩa Yêu cầu của Mô hình

Khi K8s-gatekeeper đang cấp quyền cho một yêu cầu, đầu vào luôn là một đối tượng: đối tượng Go của Yêu cầu Nhập cảnh. Điều này có nghĩa là enforcer sẽ luôn được sử dụng như thế này:

ok, err := enforcer.Enforce(admission)

trong đó admission là một đối tượng AdmissionReview được định nghĩa bởi api chính thức của K8s "k8s.io/api/admission/v1". Bạn có thể tìm thấy định nghĩa của cấu trúc này trong kho lưu trữ này: https://github.com/kubernetes/api/blob/master/admission/v1/types.go. Để biết thêm thông tin, bạn cũng có thể tham khảo https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#webhook-request-and-response.

Do đó, đối với bất kỳ mô hình nào được sử dụng bởi K8s-gatekeeper, định nghĩa của request_definition luôn phải như sau:

    [request_definition]
r = obj

Tên 'obj' không bắt buộc, miễn là tên đó nhất quán với tên được sử dụng trong phần [matchers].

4.2 Matchers của Mô hình

Bạn được kỳ vọng sử dụng tính năng ABAC của Casbin để viết các quy tắc của bạn. Tuy nhiên, bộ đánh giá biểu thức tích hợp trong Casbin không hỗ trợ lập chỉ mục trong bản đồ hoặc mảng (slices), cũng như không hỗ trợ mở rộng mảng. Do đó, K8s-gatekeeper cung cấp các 'hàm Casbin' khác nhau như các phần mở rộng để thực hiện các tính năng này. Nếu bạn vẫn thấy rằng nhu cầu của bạn không thể được đáp ứng bởi các phần mở rộng này, hãy thoải mái bắt đầu một vấn đề, hoặc tạo một pull request.

Nếu bạn không quen thuộc với các hàm Casbin, bạn có thể tham khảo Function để biết thêm thông tin.

Dưới đây là các hàm mở rộng:

4.2.1 Các hàm mở rộng

4.2.1.1 truy cập

Truy cập được sử dụng để giải quyết vấn đề mà Casbin không hỗ trợ đánh chỉ mục trong bản đồ hoặc mảng. Ví dụ example/allowed_repo/model.yaml minh họa việc sử dụng chức năng này:

[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

Trong bộ so khớp này, access(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , 0, "Image") tương đương với r.obj.Request.Object.Object.Spec.Template.Spec.Containers[0].Image, trong đó r.obj.Request.Object.Object.Spec.Template.Spec.Containers là một slice.

Truy cập cũng có thể gọi các hàm đơn giản không có tham số và trả về một giá trị duy nhất. Ví dụ example/container_resource_limit/model.yaml minh họa điều này:

[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)

Trong bộ so khớp này, access(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , 0, "Resources","Limits","cpu","Value") tương đương với r.obj.Request.Object.Object.Spec.Template.Spec.Containers[0].Resources.Limits["cpu"].Value(), trong đó r.obj.Request.Object.Object.Spec.Template.Spec.Containers[0].Resources.Limits là một bản đồ, và Value() là một hàm đơn giản không có tham số và trả về một giá trị duy nhất.

4.2.1.2 truyCậpVớiKýTựĐạiDiện

Đôi khi, bạn có thể có nhu cầu như thế này: tất cả các phần tử trong một mảng phải có tiền tố "aaa". Tuy nhiên, Casbin không hỗ trợ vòng lặp for. Với accessWithWildcard và tính năng "mở rộng bản đồ/slice", bạn có thể dễ dàng thực hiện yêu cầu như vậy.

Ví dụ, giả sử a.b.c là một mảng [aaa, bbb, ccc, ddd, eee], thì kết quả của accessWithWildcard(a, "b", "c", "*") sẽ là một slice [aaa, bbb, ccc, ddd, eee]. Bằng cách sử dụng ký tự đại diện *, slice được mở rộng.

Tương tự, ký tự đại diện có thể được sử dụng nhiều hơn một lần. Ví dụ, kết quả của accessWithWildcard(a, "b", "c", "*", "*") sẽ là [a.b.c[0][0], a.b.c[0][1], ..., a.b.c[1][0], a.b.c[1][1], ...].

4.2.1.3 Các hàm hỗ trợ đối số có độ dài biến đổi

Trong trình đánh giá biểu thức của Casbin, khi một tham số là một mảng, nó sẽ được tự động mở rộng thành một đối số có độ dài biến đổi. Sử dụng tính năng này để hỗ trợ mở rộng mảng/slice/bản đồ, chúng tôi cũng đã tích hợp một số hàm chấp nhận mảng/slice làm tham số:

  • contain(): chấp nhận nhiều tham số và trả về xem bất kỳ tham số nào (ngoại trừ tham số cuối cùng) có bằng tham số cuối cùng hay không.
  • split(a, b, c..., sep, index): trả về một slice chứa [splits(a, sep)[index], splits(b, sep)[index], splits(a, sep)[index], ...].
  • len(): trả về độ dài của đối số có độ dài thay đổi.
  • matchRegex(a, b, c..., regex): trả về xem tất cả các tham số đã cho (a, b, c, ...) có khớp với regex đã cho.

Đây là một ví dụ trong 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)

Giả sử rằng accessWithWildcard(r.obj.Request.Object.Object.Spec.Template.Spec.Containers, "*", "Image") trả về ["a:b", "c:d", "e:f", "g:h"], bởi vì splits hỗ trợ đối số có độ dài thay đổi và thực hiện phép chia trên mỗi phần tử, phần tử tại chỉ số 1 sẽ được chọn và trả về. Do đó, split(accessWithWildcard(r.obj.Request.Object.Object.Spec.Template.Spec.Containers, "*", "Image"), ":", 1) trả về ["b", "d", "f", "h"]. Và contain(split(accessWithWildcard(r.obj.Request.Object.Object.Spec.Template.Spec.Containers, "*", "Image"), ":", 1), p.obj) trả về xem p.obj có được chứa trong ["b", "d", "f", "h"].

4.2.1.2 Các Hàm Chuyển Đổi Kiểu

  • ParseFloat(): Chuyển đổi một số nguyên thành một số thực (điều này là cần thiết vì bất kỳ số nào được sử dụng trong so sánh phải được chuyển đổi thành số thực).
  • ToString(): Chuyển đổi một đối tượng thành một chuỗi. Đối tượng này phải có một kiểu cơ bản là chuỗi (ví dụ, một đối tượng kiểu XXX khi có một câu lệnh type XXX string).
  • IsNil(): Trả về liệu tham số có phải là nil hay không.

5. Cài đặt Nâng cao

5.1 Về Chứng chỉ

Trong Kubernetes (k8s), bắt buộc phải sử dụng HTTPS cho một webhook. Có hai cách tiếp cận để đạt được điều này:

  • Sử dụng chứng chỉ tự ký (các ví dụ trong kho lưu trữ này sử dụng phương pháp này)
  • Sử dụng chứng chỉ bình thường

5.1.1 Chứng chỉ tự ký

Sử dụng chứng chỉ tự ký có nghĩa là Tổ chức Chứng chỉ (CA) cấp chứng chỉ không phải là một trong những CA nổi tiếng. Do đó, bạn phải cho k8s biết về CA này.

Hiện tại, ví dụ trong kho lưu trữ này sử dụng một CA tự làm, khóa riêng và chứng chỉ của nó được lưu trữ trong config/certificate/ca.crtconfig/certificate/ca.key tương ứng. Chứng chỉ cho webhook là config/certificate/server.crt, được cấp bởi CA tự làm. Các tên miền của chứng chỉ này là "webhook.domain.local" (cho webhook bên ngoài) và "casbin-webhook-svc.default.svc" (cho webhook nội bộ).

Thông tin về CA được truyền cho k8s thông qua các tệp cấu hình webhook. Cả config/webhook_external.yamlconfig/webhook_internal.yaml đều có một trường gọi là "CABundle", chứa một chuỗi được mã hóa base64 của chứng chỉ CA.

Trong trường hợp bạn cần thay đổi chứng chỉ/tên miền (ví dụ, nếu bạn muốn đặt webhook này vào một namespace khác của k8s trong khi sử dụng webhook nội bộ, hoặc nếu bạn muốn thay đổi tên miền trong khi sử dụng webhook bên ngoài), các thủ tục sau đây nên được tuân theo:

  1. Tạo một CA mới:

    • Tạo khóa riêng cho CA giả:

      openssl genrsa -des3 -out ca.key 2048
    • Xóa bảo vệ mật khẩu của khóa riêng:

      openssl rsa -in ca.key -out ca.key
  2. Tạo một khóa riêng cho máy chủ webhook:

    openssl genrsa -des3 -out server.key 2048
    openssl rsa -in server.key -out server.key
  3. Sử dụng CA tự tạo để ký chứng chỉ cho webhook:

    • Sao chép tệp cấu hình openssl của hệ thống của bạn để sử dụng tạm thời. Bạn có thể tìm ra vị trí của tệp cấu hình bằng cách chạy openssl version -a, thường được gọi là openssl.cnf.

    • Trong tệp cấu hình:

      • Tìm đoạn [req] và thêm dòng sau: req_extensions = v3_req

      • Tìm đoạn [v3_req] và thêm dòng sau: subjectAltName = @alt_names

      • Nối các dòng sau vào tệp:

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

        Lưu ý: Thay thế 'casbin-webhook-svc.default.svc' bằng tên dịch vụ thực tế của dịch vụ của bạn nếu bạn quyết định sửa đổi tên dịch vụ.

    • Sử dụng tệp cấu hình đã sửa đổi để tạo tệp yêu cầu chứng chỉ:

      openssl req -new -nodes -keyout server.key -out server.csr -config openssl.cnf
    • Sử dụng CA tự tạo để đáp ứng yêu cầu và ký chứng chỉ:

      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. Thay thế trường 'CABundle': Cập nhật trường này với chứng chỉ mới.

  5. Nếu bạn đang sử dụng helm, cần áp dụng các thay đổi tương tự cho biểu đồ helm.

5.1.2 Chứng chỉ pháp lý

Nếu bạn sử dụng chứng chỉ pháp lý, bạn không cần phải trải qua tất cả các thủ tục này. Xóa trường "CABundle" trong config/webhook_external.yamlconfig/webhook_internal.yaml, và thay đổi tên miền trong các tệp này thành tên miền mà bạn sở hữu.