Langkau ke kandungan utama

Admission Webhook for K8s

1. Gambaran Keseluruhan & Dokumen untuk Casbin K8s-Gatekeeper

Casbin K8s-GateKeeper ialah webhook kehadiran Kubernetes yang mengintegrasikan Casbin sebagai alat Kawalan Akses. Dengan menggunakan Casbin K8s-GateKeeper, anda boleh menubuhkan peraturan yang fleksibel untuk membenarkan atau menyekat sebarang operasi pada sumber K8s, TANPA menulis sebarang bahagian kod, tetapi hanya beberapa baris konfigurasi deklaratif model dan dasar Casbin, yang merupakan sebahagian daripada bahasa ACL (Senarai Kawalan Akses) Casbin.

Casbin K8s-GateKeeper dikembangkan dan diselenggarakan oleh komunitas Casbin. Repositori projek ini boleh didapati di sini: https://github.com/casbin/k8s-gatekeeper

0.1 Contoh Mudah

Sebagai contoh, anda tidak perlu menulis sebarang kod, tetapi gunakan baris konfigurasi berikut untuk mencapai fungsi ini: "Larang penggunaan imej dengan tag tertentu dalam sebarang penempatan":

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

Ini adalah dalam bahasa ACL Casbin biasa. Andaikan anda telah membaca bab mengenai mereka, ia akan menjadi sangat mudah untuk difahami.

Casbin K8s-GateKeeper mempunyai kelebihan berikut:

  • Mudah digunakan. Menulis beberapa baris ACL jauh lebih baik daripada menulis banyak kod.
  • Ia membolehkan kemas kini panas konfigurasi. Anda tidak perlu mematikan seluruh plugin untuk mengubah suai konfigurasi.
  • Ia adalah fleksibel. Peraturan sewenang-wenangnya boleh dibuat pada sumber K8s apa pun, yang boleh dieksplorasi dengan kubectl gatekeeper.
  • Ia memudahkan pelaksanaan webhook kehadiran K8s, yang sangat rumit. Anda tidak perlu tahu apa itu webhook kehadiran K8s atau bagaimana menulis kod untuk itu. Yang anda perlukan hanyalah mengetahui sumber yang ingin anda letakkan sekatan dan kemudian menulis ACL Casbin. Semua orang tahu bahawa K8s adalah kompleks, tetapi dengan menggunakan Casbin K8s-Gatekeeper, masa anda dapat diselamatkan.
  • Ia dikekalkan oleh komuniti Casbin. Jangan ragu untuk menghubungi kami jika ada sesuatu mengenai plugin ini yang membingungkan anda atau jika anda menghadapi sebarang masalah ketika mencuba ini.

1.1 Bagaimana Casbin K8s-Gatekeeper Berfungsi?

K8s-Gatekeeper adalah webhook pengammit untuk K8s yang menggunakan Casbin untuk menggunakan peraturan kawalan akses yang ditentukan pengguna secara sewenang-wenangnya untuk membantu mencegah sebarang operasi pada K8s yang tidak diingini oleh pentadbir.

Casbin adalah perpustakaan kawalan akses sumber terbuka yang berkuasa dan cekap. Ia menyediakan sokongan untuk menguatkuasakan kebenaran berdasarkan pelbagai model kawalan akses. Untuk maklumat lanjut mengenai Casbin, lihat Gambaran Keseluruhan.

Webhook pengammit dalam K8s adalah panggilan balik HTTP yang menerima 'permintaan pengammit' dan melakukan sesuatu dengannya. Khususnya, K8s-Gatekeeper adalah jenis webhook pengammit khas: 'ValidatingAdmissionWebhook', yang boleh membuat keputusan sama ada untuk menerima atau menolak permintaan pengammit ini atau tidak. Bagi permintaan pengammit, ia adalah permintaan HTTP yang menerangkan operasi pada sumber yang ditentukan K8s (contohnya, mencipta/menghapuskan penerapan). Untuk maklumat lanjut mengenai webhook pengammit, lihat dokumentasi rasmi K8s.

1.2 Contoh Menggambarkan Cara Kerjanya

Sebagai contoh, apabila seseorang ingin membuat penempatan yang mengandungi pod yang menjalankan nginx (menggunakan kubectl atau klien K8s), K8s akan menjana permintaan kehadiran, yang (jika diterjemahkan ke dalam format YAML) boleh menjadi seperti ini:

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

Permintaan ini akan melalui proses semua perantaraan yang ditunjukkan dalam gambar, termasuk K8s-Gatekeeper kami. K8s-Gatekeeper boleh mengesan semua enforcer Casbin yang disimpan dalam etcd K8s, yang dicipta dan dikekalkan oleh pengguna (melalui kubectl atau klien Go yang kami sediakan). Setiap enforcer mengandungi model Casbin dan polisi Casbin. Permintaan kehadiran akan diproses oleh setiap enforcer, satu demi satu, dan hanya dengan lulus semua enforcer, permintaan boleh diterima oleh K8s-Gatekeeper ini.

(Jika anda tidak memahami apa itu enforcer Casbin, model, atau polisi, lihat dokumen ini: Mulakan).

Sebagai contoh, atas sebab tertentu, pentadbir ingin melarang kemunculan imej 'nginx:1.14.1' sambil membenarkan 'nginx:1.3.1'. Enforcer yang mengandungi peraturan dan polisi berikut boleh dicipta (Kami akan menerangkan cara membuat enforcer, apakah model dan polisi ini, dan bagaimana menulis mereka dalam bab-bab berikut).

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

Dengan mencipta penguatkuasa yang mengandungi model dan polisi di atas, permintaan pengakuan sebelumnya akan ditolak oleh penguatkuasa ini, yang bermaksud K8s tidak akan mencipta penempatan ini.

2 Pasang K8s-gatekeeper

Terdapat tiga kaedah yang tersedia untuk memasang K8s-gatekeeper: Webhook luaran, Webhook dalaman, dan Helm.

nota

Perhatian: Kaedah ini hanya bertujuan untuk pengguna mencuba K8s-gatekeeper dan tidak selamat. Jika anda ingin menggunakannya dalam persekitaran produktif, sila pastikan anda membaca Bab 5. Tetapan lanjutan dan buat sebarang pengubahsuaian yang diperlukan sebelum pemasangan.

2.1 Webhook dalaman

2.1.1 Langkah 1: Bina imej

Bagi kaedah webhook dalaman, webhook itu sendiri akan dilaksanakan sebagai perkhidmatan dalam Kubernetes. Untuk mencipta perkhidmatan dan peluncuran yang diperlukan, anda perlu membina imej K8s-gatekeeper. Anda boleh membina imej anda sendiri dengan menjalankan arahan berikut:

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

Arahan ini akan mencipta imej tempatan yang dipanggil 'k8s-gatekeeper:latest'.

nota

Perhatian: Jika anda menggunakan minikube, sila jalankan eval $(minikube -p minikube docker-env) sebelum menjalankan 'docker build'.

2.1.2 Langkah 2: Sediakan perkhidmatan dan peluncuran untuk K8s-gatekeeper

Jalankan arahan berikut:

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

Ini akan memulakan K8s-gatekeeper, dan anda boleh mengesahkan ini dengan menjalankan kubectl get pods.

2.1.3 Langkah 3: Pasang Sumber CRD untuk K8s-gatekeeper

Jalankan arahan berikut:

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

2.2 Webhook Luaran

Untuk kaedah webhook luaran, K8s-gatekeeper akan berjalan di luar Kubernetes, dan Kubernetes akan mengakses K8s-gatekeeper seperti mengakses laman web biasa. Kubernetes mempunyai keperluan wajib bahawa webhook kehadiran mesti menggunakan HTTPS. Untuk tujuan mencuba K8s-gatekeeper, kami telah menyediakan satu set sijil dan kunci peribadi (walaupun ini tidak selamat). Jika anda lebih suka menggunakan sijil anda sendiri, sila rujuk kepada Bab 5. Tetapan lanjutan untuk arahan mengenai menyesuaikan sijil dan kunci peribadi. Sijil yang kami sediakan dikeluarkan untuk 'webhook.domain.local'.

Oleh itu, ubah hos (contohnya, /etc/hosts) dan titik 'webhook.domain.local' ke alamat IP di mana K8s-gatekeeper berjalan. Kemudian jalankan arahan berikut:

2.3 Pasang K8s-gatekeeper melalui 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 Langkah 1: Bina imej

2.3.1 Step 1: Build the image

Sila rujuk kepada Bab 2.1.1.

2.3.2 Pemasangan Helm

Jalankan arahan helm install k8sgatekeeper ./k8sgatekeeper.

3. Cuba K8s-gatekeeper

3.1 Buat Model dan Polisi Casbin

Anda mempunyai dua kaedah untuk membuat model dan polisi: melalui kubectl atau melalui go-client yang kami sediakan.

3.1.1 Buat/Kemaskini Model dan Polisi Casbin melalui kubectl

Di K8s-gatekeeper, model Casbin disimpan dalam sumber CRD yang dipanggil 'CasbinModel'. Takrifannya terletak di config/auth.casbin.org_casbinmodels.yaml.

Terdapat contoh dalam example/allowed_repo/model.yaml. Perhatikan bidang berikut:

  • metadata.name: nama model tersebut. Nama ini HARUS sama dengan nama objek CasbinPolicy yang berkaitan dengan model ini, agar K8s-gatekeeper dapat memasangkannya dan mencipta penguat.
  • spec.enable: jika bidang ini ditetapkan ke "false", model ini (serta objek CasbinPolicy yang berkaitan dengan model ini) akan diabaikan.
  • spec.modelText: rentetan yang mengandungi teks model Casbin.

Polisi Casbin disimpan dalam sumber CRD lain yang disebut 'CasbinPolicy', yang definisinya boleh didapati di config/auth.casbin.org_casbinpolicies.yaml.

Terdapat contoh dalam example/allowed_repo/policy.yaml. Perhatikan bidang berikut:

  • metadata.name: nama polisi tersebut. Nama ini MESTI sama dengan nama objek CasbinModel yang berkaitan dengan dasar ini, supaya K8s-gatekeeper dapat memasangkannya dan mencipta penguatkuasa.
  • spec.policyItem: rentetan yang mengandungi teks dasar model Casbin.

Selepas mencipta fail CasbinModel dan CasbinPolicy anda sendiri, gunakan arahan berikut untuk menggunakannya:

kubectl apply -f <filename>

Setelah sepasang CasbinModel dan CasbinPolicy dicipta, K8s-gatekeeper akan dapat mengesannya dalam masa 5 saat.

3.1.2 Cipta/Kemas kini Model dan Dasar Casbin melalui go-client yang kami sediakan

Kami faham bahawa mungkin terdapat situasi di mana tidak mudah menggunakan shell untuk melaksanakan arahan secara langsung pada nod kelompok K8s, seperti apabila anda membina platform awan automatik untuk korporasi anda. Oleh itu, kami telah membangunkan go-client untuk mencipta dan mengekalkan CasbinModel dan CasbinPolicy.

Perpustakaan go-client terletak di pkg/client.

Dalam client.go, kami menyediakan fungsi untuk mencipta klien.

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

Parameter externalClient menentukan sama ada K8s-gatekeeper sedang berjalan di dalam kelompok K8s atau tidak.

Dalam model.go, kami menyediakan pelbagai fungsi untuk membuat, menghapus, dan mengubah CasbinModel. Anda boleh mengetahui cara menggunakan antara muka ini dalam model_test.go.

Dalam policy.go, kami menyediakan pelbagai fungsi untuk membuat, menghapus, dan mengubah CasbiPolicy. Anda boleh mengetahui cara menggunakan antara muka ini dalam policy_test.go.

3.1.2 Cuba Samaada K8s-gatekeeper Berfungsi

Anggaplah anda telah mencipta model dan polisi yang tepat dalam example/allowed_repo. Sekarang, cuba arahan berikut:

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

Anda harus mendapati bahawa K8s akan menolak permintaan ini dan menyebut bahawa webhook adalah sebab mengapa permintaan ini ditolak. Namun, apabila anda cuba memohon example/allowed_repo/testcase/approve_2.yaml, ia akan diterima.

4. Cara Menulis Model dan Polisi dengan K8s-gatekeeper

Pertama sekali, pastikan anda sudah biasa dengan tatabahasa asas Model dan Polisi Casbin. Jika tidak, sila baca bahagian Mulakan terlebih dahulu. Dalam bab ini, kami menganggap bahawa anda sudah memahami apakah Model dan Polisi Casbin.

4.1 Takrifan Permintaan Model

Apabila K8s-gatekeeper memberi kuasa kepada permintaan, inputnya selalu objek: objek Go Permintaan Kemasukan. Ini bermakna enforcer akan selalu digunakan seperti ini:

ok, err := enforcer.Enforce(admission)

di mana admission adalah objek AdmissionReview yang ditakrifkan oleh api go rasmi K8s "k8s.io/api/admission/v1". Anda boleh mencari takrifan struktur ini dalam repositori ini: https://github.com/kubernetes/api/blob/master/admission/v1/types.go. Untuk maklumat lanjut, anda juga boleh merujuk kepada https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#webhook-request-and-response.

Oleh itu, bagi sebarang model yang digunakan oleh K8s-gatekeeper, definisi request_definition harus selalu seperti ini:

    [request_definition]
r = obj

Nama 'obj' tidak wajib, selagi nama itu konsisten dengan nama yang digunakan dalam bahagian [matchers].

4.2 Matchers Model

Anda sepatutnya menggunakan ciri ABAC Casbin untuk menulis peraturan anda. Namun, penilai ungkapan yang terintegrasi dalam Casbin tidak menyokong pengindeksan dalam peta atau tatasusunan (slices), atau peluasan tatasusunan. Oleh itu, K8s-gatekeeper menyediakan pelbagai 'fungsi Casbin' sebagai sambungan untuk melaksanakan ciri-ciri ini. Jika anda masih mendapati bahawa permintaan anda tidak dapat dipenuhi oleh sambungan ini, jangan ragu untuk memulakan isu, atau membuat permintaan tarik.

Jika anda tidak biasa dengan fungsi Casbin, anda boleh merujuk kepada Function untuk maklumat lanjut.

Berikut adalah fungsi sambungan:

4.2.1 Fungsi Sambungan

4.2.1.1 akses

Akses digunakan untuk menyelesaikan masalah bahawa Casbin tidak menyokong pengindeksan dalam peta atau tatasusunan. Contoh example/allowed_repo/model.yaml menunjukkan penggunaan fungsi ini:

[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

Dalam pencocok ini, access(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , 0, "Image") setara dengan r.obj.Request.Object.Object.Spec.Template.Spec.Containers[0].Image, di mana r.obj.Request.Object.Object.Spec.Template.Spec.Containers adalah sebuah irisan.

Akses juga boleh memanggil fungsi mudah yang tidak mempunyai parameter dan mengembalikan satu nilai. Contoh example/container_resource_limit/model.yaml menunjukkan ini:

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

Dalam pencocok ini, access(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , 0, "Resources","Limits","cpu","Value") setara dengan r.obj.Request.Object.Object.Spec.Template.Spec.Containers[0].Resources.Limits["cpu"].Value(), di mana r.obj.Request.Object.Object.Spec.Template.Spec.Containers[0].Resources.Limits adalah sebuah peta, dan Value() adalah fungsi mudah yang tidak mempunyai parameter dan mengembalikan satu nilai.

4.2.1.2 aksesDenganWildcard

Kadang kala, anda mungkin mempunyai permintaan seperti ini: semua elemen dalam tatasusunan mesti mempunyai awalan "aaa". Walau bagaimanapun, Casbin tidak menyokong gelung for. Dengan accessWithWildcard dan ciri "pembesaran peta/jalur", anda boleh melaksanakan permintaan tersebut dengan mudah.

Sebagai contoh, andaikan a.b.c ialah tatasusunan [aaa, bbb, ccc, ddd, eee], maka hasil accessWithWildcard(a, "b", "c", "*") akan menjadi jalur [aaa, bbb, ccc, ddd, eee]. Dengan menggunakan wildcard *, jalur itu diperluaskan.

Begitu juga, wildcard boleh digunakan lebih dari sekali. Sebagai contoh, hasil accessWithWildcard(a, "b", "c", "*", "*") akan menjadi [a.b.c[0][0], a.b.c[0][1], ..., a.b.c[1][0], a.b.c[1][1], ...].

4.2.1.3 Fungsi Menyokong Argumen Panjang Berubah

Dalam penilaian ungkapan Casbin, apabila parameter adalah tatasusunan, ia akan dibesarkan secara automatik sebagai argumen panjang berubah. Menggunakan ciri ini untuk menyokong pembesaran tatasusunan/jalur/peta, kami juga telah mengintegrasikan beberapa fungsi yang menerima tatasusunan/jalur sebagai parameter:

  • contain(): menerima pelbagai parameter dan mengembalikan sama ada mana-mana parameter (kecuali parameter terakhir) sama dengan parameter terakhir.
  • split(a, b, c..., sep, index): mengembalikan jalur yang mengandungi [splits(a, sep)[index], splits(b, sep)[index], splits(a, sep)[index], ...].
  • len(): mengembalikan panjang argumen berubah-ubah.
  • matchRegex(a,b,c...,regex): mengembalikan sama ada semua parameter yang diberikan (a, b, c, ...) sesuai dengan regex yang diberikan.

Berikut adalah contoh dalam 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)

Dengan menganggap bahawa accessWithWildcard(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , "*", "Image") mengembalikan ["a:b", "c:d", "e:f", "g:h"], kerana splits menyokong argumen berubah-ubah dan melakukan operasi splits pada setiap elemen, elemen pada indeks 1 akan dipilih dan dikembalikan. Oleh itu, split(accessWithWildcard(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , "*", "Image"),":",1) mengembalikan ["b","d","f","h"]. Dan contain(split(accessWithWildcard(r.obj.Request.Object.Object.Spec.Template.Spec.Containers , "*", "Image"),":",1) , p.obj) mengembalikan sama ada p.obj terkandung dalam ["b","d","f","h"].

4.2.1.2 Fungsi Penukaran Jenis

  • ParseFloat(): Menukar integer kepada float (ini diperlukan kerana sebarang nombor yang digunakan dalam perbandingan mesti ditukar menjadi float).
  • ToString(): Menukar objek kepada rentetan. Objek ini mesti mempunyai jenis asas rentetan (contohnya, objek jenis XXX apabila terdapat kenyataan type XXX string).
  • IsNil(): Mengembalikan sama ada parameter tersebut adalah nil.

5. Tetapan Lanjutan

5.1 Mengenai Sijil

Dalam Kubernetes (k8s), adalah wajib bahawa webhook harus menggunakan HTTPS. Terdapat dua pendekatan untuk mencapai ini:

  • Gunakan sijil tandatangan sendiri (contoh dalam repositori ini menggunakan kaedah ini)
  • Gunakan sijil biasa

5.1.1 Sijil tandatangan sendiri

Menggunakan sijil yang ditandatangani sendiri bermakna Pihak Berkuasa Sijil (CA) yang mengeluarkan sijil tersebut bukan salah satu daripada CA yang terkenal. Oleh itu, anda mesti memberitahu k8s mengenai CA ini.

Pada masa ini, contoh dalam repositori ini menggunakan CA buatan sendiri, yang mana kunci peribadi dan sijilnya disimpan dalam config/certificate/ca.crt dan config/certificate/ca.key masing-masing. Sijil untuk webhook adalah config/certificate/server.crt, yang dikeluarkan oleh CA buatan sendiri. Domain untuk sijil ini adalah "webhook.domain.local" (untuk webhook luaran) dan "casbin-webhook-svc.default.svc" (untuk webhook dalaman).

Maklumat mengenai CA diberikan kepada k8s melalui fail konfigurasi webhook. Kedua-dua config/webhook_external.yaml dan config/webhook_internal.yaml mempunyai medan yang dipanggil "CABundle", yang mengandungi rentetan terenkod base64 bagi sijil CA.

Sekiranya anda perlu menukar sijil/domain (contohnya, jika anda ingin meletakkan webhook ini ke dalam ruang nama lain k8s sambil menggunakan webhook dalaman, atau jika anda ingin menukar domain sambil menggunakan webhook luaran), prosedur berikut harus diikuti:

  1. Menjana CA baru:

    • Menjana kunci peribadi untuk CA palsu:

      openssl genrsa -des3 -out ca.key 2048
    • Buang perlindungan kata laluan daripada kunci peribadi:

      openssl rsa -in ca.key -out ca.key
  2. Hasilkan kunci peribadi untuk pelayan webhook:

    openssl genrsa -des3 -out server.key 2048
    openssl rsa -in server.key -out server.key
  3. Gunakan CA yang dihasilkan sendiri untuk menandatangani sijil untuk webhook:

    • Salin fail konfigurasi openssl sistem anda untuk kegunaan sementara. Anda boleh mengetahui lokasi fail konfigurasi dengan menjalankan openssl version -a, biasanya dipanggil openssl.cnf.

    • Dalam fail konfigurasi:

      • Cari perenggan [req] dan tambahkan baris berikut: req_extensions = v3_req

      • Cari perenggan [v3_req] dan tambahkan baris berikut: subjectAltName = @alt_names

      • Tambahkan baris berikut ke dalam fail:

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

        Perhatian: Ganti 'casbin-webhook-svc.default.svc' dengan nama perkhidmatan sebenar anda sendiri jika anda memutuskan untuk mengubah nama perkhidmatan.

    • Gunakan fail konfigurasi yang diubah suai untuk menghasilkan fail permintaan sijil:

      openssl req -new -nodes -keyout server.key -out server.csr -config openssl.cnf
    • Gunakan CA buatan sendiri untuk menjawab permintaan dan menandatangani sijil:

      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. Tukar field 'CABundle': Kemas kini field ini dengan sijil baru.

  5. Jika anda menggunakan helm, perubahan yang serupa perlu dilakukan pada carta helm.

5.1.2 Sijil sah

Jika anda menggunakan sijil sah, anda tidak perlu melalui semua prosedur ini. Buang field "CABundle" dalam config/webhook_external.yaml dan config/webhook_internal.yaml, dan tukar domain dalam fail-fail ini kepada domain yang anda miliki.