Kontainer adalah teknologi untuk mengemas kode (yang telah dikompilasi) menjadi suatu aplikasi beserta dengan dependensi-dependensi yang dibutuhkannya pada saat dijalankan. Setiap kontainer yang Anda jalankan dapat diulang; standardisasi dengan menyertakan dependensinya berarti Anda akan mendapatkan perilaku yang sama di mana pun Anda menjalankannya.
Kontainer memisahkan aplikasi dari infrastruktur host yang ada dibawahnya. Hal ini membuat penyebaran lebih mudah di lingkungan cloud atau OS yang berbeda.
Kontainer image meruapakan paket perangkat lunak yang siap dijalankan, mengandung semua yang diperlukan untuk menjalankan sebuah aplikasi: kode dan setiap runtime yang dibutuhkan, library dari aplikasi dan sistem, dan nilai default untuk penganturan yang penting.
Secara desain, kontainer tidak bisa berubah: Anda tidak dapat mengubah kode dalam kontainer yang sedang berjalan. Jika Anda memiliki aplikasi yang terkontainerisasi dan ingin melakukan perubahan, maka Anda perlu membuat kontainer baru dengan menyertakan perubahannya, kemudian membuat ulang kontainer dengan memulai dari image yang sudah diubah.
Kontainer runtime adalah perangkat lunak yang bertanggung jawab untuk menjalankan kontainer. Kubernetes mendukung beberapa kontainer runtime: Docker, containerd, CRI-O, dan semua implementasi dari Kubernetes CRI (Container Runtime Interface).
Kamu membuat Docker image dan mengunduhnya ke sebuah registri sebelum digunakan di dalam Kubernetes Pod.
Properti image dari sebuah Container mendukung sintaksis yang sama seperti perintah docker, termasuk registri privat dan tag.
Kebijakan pull default adalah IfNotPresent yang membuat Kubelet tidak
lagi mengunduh (pull) sebuah image jika sudah ada terlebih dahulu. Jika kamu ingin agar
selalu diunduh, kamu bisa melakukan salah satu dari berikut:
imagePullPolicy dari Container menjadi Always.imagePullPolicy dan gunakan :latest tag untuk image yang digunakan.imagePullPolicy dan juga tag untuk image.Harap diingat kamu sebaiknya hindari penggunaan tag :latest, lihat panduan konfigurasi untuk informasi lebih lanjut.
Docker CLI saat ini mendukung perintah docker manifest dengan anak perintah create, annotate, dan push. Perintah-perintah ini dapat digunakan
untuk membuat (build) dan mengunggah (push) manifes. Kamu dapat menggunakan perintah docker manifest inspect untuk membaca manifes.
Lihat dokumentasi docker di sini: https://docs.docker.com/edge/engine/reference/commandline/manifest/
Lihat contoh-contoh bagaimana kami menggunakan ini untuk proses build harness: https://cs.k8s.io/?q=docker%20manifest%20(create%7Cpush%7Cannotate)&i=nope&files=&repos=
Perintah-perintah ini bergantung pada Docker CLI, dan diimplementasi hanya di sisi CLI. Kamu harus mengubah $HOME/.docker/config.json dan mengatur key experimental untuk mengaktifkan
atau cukup dengan mengatur DOCKER_CLI_EXPERIMENTAL variabel environment menjadi enabled ketika memanggil perintah-perintah CLI.
Kalau kamu terkena masalah ketika mengunggah manifes-manifes yang rusak, cukup bersihkan manifes-manifes yang lama di $HOME/.docker/manifests untuk memulai dari awal.
Untuk Kubernetes, kami biasanya menggunakan image-image dengan sufiks -$(ARCH). Untuk kompatibilitas (backward compatibility), lakukan generate image-image yang lama dengan sufiks. Idenya adalah men-generate, misalnya pause image yang memiliki manifes untuk semua arsitektur dan misalnya pause-amd64 yang punya kompatibilitas terhadap konfigurasi-konfigurasi lama atau berkas-berkas YAML yang bisa saja punya image-image bersufiks yang di-hardcode.
Biasanya kita memerlukan key untuk membaca image-image yang tersedia pada suatu registri privat. Kredensial ini dapat disediakan melalui beberapa cara:
Masing-masing opsi dijelaskan lebih lanjut di bawah ini.
Kubernetes memiliki dukungan native untuk Google Container Registry (GCR), ketika dijalankan pada Google Compute Engine (GCE). Jika kamu menjalankan klaster pada GCE atau Google Kubernetes Engine, cukup gunakan nama panjang image (misalnya gcr.io/my_project/image:tag).
Semua Pod di dalam klaster akan memiliki akses baca image di registri ini.
Kubelet akan melakukan otentikasi GCR menggunakan service account yang dimiliki
instance Google. Service acccount pada instance akan memiliki sebuah https://www.googleapis.com/auth/devstorage.read_only,
sehingga dapat mengunduh dari GCR di proyek yang sama, tapi tidak untuk unggah.
Kubernetes memiliki dukungan native untuk Amazon Elastic Container Registry, ketika Node adalah AWS EC2 instance.
Cukup gunakan nama panjang image (misalnya ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag) di dalam definisi Pod.
Semua pengguna klaster yang dapat membuat Pod akan bisa menjalankan Pod yang dapat menggunakan image-image di dalam registri ECR.
Kubelet akan mengambil dan secara periodik memperbarui kredensial ECR, yang memerlukan permission sebagai berikut:
ecr:GetAuthorizationTokenecr:BatchCheckLayerAvailabilityecr:GetDownloadUrlForLayerecr:GetRepositoryPolicyecr:DescribeRepositoriesecr:ListImagesecr:BatchGetImagePersyaratan:
v1.2.0 atau lebih (misal jalankan /usr/bin/kubelet --version=true).v1.3.0 atau lebih.Cara troubleshoot:
us-west-2) pada workstation kamu. Lakukan SSH ke dalam host dan jalankan Docker secara manual menggunakan kredensial tersebut. Apakah berhasil?journalctl -u kubelet) di baris-baris yang seperti ini:
aws_credentials.go:109] unable to get ECR credentials from cache, checking ECR APIaws_credentials.go:116] Got ECR credentials from ECR API for <AWS account ID for ECR>.dkr.ecr.<AWS region>.amazonaws.comKetika menggunakan Azure Container Registry kamu dapat melakukan otentikasi menggunakan pengguna admin maupun sebuah service principal. Untuk keduanya, otentikasi dilakukan melalui proses otentikasi Docker standar. Instruksi-instruksi ini menggunakan perangkat azure-cli.
Kamu pertama perlu membuat sebuah registri dan men-generate kredensial, dokumentasi yang lengkap tentang hal ini dapat dilihat pada dokumentasi Azure container registry.
Setelah kamu membuat registri, kamu akan menggunakan kredensial berikut untuk login:
DOCKER_USER : service principal, atau pengguna adminDOCKER_PASSWORD: kata sandi dari service principal, atau kata sandi dari pengguna adminDOCKER_REGISTRY_SERVER: ${some-registry-name}.azurecr.ioDOCKER_EMAIL: ${some-email-address}Ketika kamu sudah memiliki variabel-variabel di atas, kamu dapat mengkonfigurasi sebuah Kubernetes Secret dan menggunakannya untuk deploy sebuah Pod.
IBM Cloud Container Registry menyediakan sebuah registri image privat yang multi-tenant, dapat kamu gunakan untuk menyimpan dan membagikan image-image secara aman. Secara default, image-image di dalam registri privat kamu akan dipindai (scan) oleh Vulnerability Advisor terintegrasi untuk deteksi isu keamanan dan kerentanan (vulnerability) yang berpotensi. Para pengguna di dalam akun IBM Cloud kamu dapat mengakses image, atau kamu dapat menggunakan IAM role dan policy untuk memberikan akses ke namespace di IBM Cloud Container Registry.
Untuk instalasi plugin CLI di IBM Cloud Containerr Registry dan membuat sebuah namespace untuk image-image kamu, lihat Mulai dengan IBM Cloud Container Registry.
Jika kamu menggunakan akun dan wilayah (region) yang sama, kamu dapat melakukan deploy image-image yang disimpan di dalam IBM Cloud Container Registry ke dalam namespace default dari klaster IBM Cloud Kubernetes Service yang kamu miliki tanpa konfigurasi tambahan, lihat Membuat kontainer dari image. Untuk opsi konfigurasi lainnya, lihat Bagaimana cara mengotorasi klaster untuk mengunduh image dari sebuah registri.
.dockercfg pada setiap Node dengan kredensial untuk Google Container Registry. Kamu tidak bisa menggunakan cara ini.auths dan HttpHeaders dari konfigurasi docker. Hal ini berarti bantuan kredensial (credHelpers atau credsStore) tidak didukung.Docker menyimpan key untuk registri privat pada $HOME/.dockercfg atau berkas $HOME/.docker/config.json. Jika kamu menempatkan berkas yang sama
pada daftar jalur pencarian (search path) berikut, kubelet menggunakannya sebagai penyedia kredensial saat mengunduh image.
{--root-dir:-/var/lib/kubelet}/config.json{cwd of kubelet}/config.json${HOME}/.docker/config.json/.docker/config.json{--root-dir:-/var/lib/kubelet}/.dockercfg{cwd of kubelet}/.dockercfg${HOME}/.dockercfg/.dockercfgHOME=/root secara eksplisit pada berkas environment kamu untuk kubelet.Berikut langkah-langkah yang direkomendasikan untuk mengkonfigurasi Node kamu supaya bisa menggunakan registri privat. Pada contoh ini, coba jalankan pada desktop/laptop kamu:
docker login [server] untuk setiap set kredensial yang ingin kamu gunakan. Ini akan memperbarui $HOME/.docker/config.json.$HOME/.docker/config.json menggunakan editor untuk memastikan sudah berisi kredensial yang ingin kamu gunakan.nodes=$(kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}')nodes=$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}').docker/config.json yang ada di lokal kamu pada salah satu jalur pencarian di atas.
for n in $nodes; do scp ~/.docker/config.json root@$n:/var/lib/kubelet/config.json; doneVerifikasi dengana membuat sebuah Pod yanag menggunakan image privat, contohnya:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: private-image-test-1
spec:
containers:
- name: uses-private-image
image: $PRIVATE_IMAGE_NAME
imagePullPolicy: Always
command: [ "echo", "SUCCESS" ]
EOF
pod/private-image-test-1 created
Jika semuanya berjalan dengan baik, maka setelah beberapa lama, kamu dapat menjalankan:
kubectl logs private-image-test-1
dan lihat pada keluaran perintah:
SUCCESS
Jika kamu mencurigai ada perintah yang gagal, kamu dapat menjalankan:
kubectl describe pods/private-image-test-1 | grep 'Failed'
Pada kasus gagal, keluarannya mirip seperti:
Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found
Kamu harus memastikan semua Node di dalam klaster memiliki .docker/config.json yang sama. Jika tidak, Pod-Pod
akan jalan pada beberapa Node saja dan gagal di Node lainnya. Contohnya, jika kamu menggunakan Node autoscaling, maka
setiap templat instance perlu untuk mempunyai .docker/config.json atau mount sebuah penyimpanan yang berisi berkas tersebut.
Semua Pod memiliki akses baca (read) untuk image-image di registri privat manapun ketika
key registri privat ditambahkan pada .docker/config.json.
.dockercfg pada setiap Node dengan kredensial untuk Google Container Registry. Kamu dapat menggunakan cara ini.Secara default, kubelet akan mencoba untuk mengunduh setiap image dari registri yang dispesifikasikan.
Hanya saja, jika properti imagePullPolicy diatur menjadi IfNotPresent atau Never, maka
sebuah image lokal digunakan.
Jika kamu ingin memanfaatkan image pra-unduh sebagai pengganti untuk otentikasi registri, kamu harus memastikan semua Node di dalam klaster memiliki image pra-unduh yang sama.
Cara ini bisa digunakan untuk memuat image tertentu untuk kecepatan atau sebagai alternatif untuk otentikasi untuk sebuah registri privat.
Semua Pod akan mendapatkan akses baca ke image pra-unduh manapun.
Kubernetes mendukung penentuan key registri pada sebuah Pod.
Jalankan perintah berikut, ganti nilai huruf besar dengan yang tepat:
kubectl create secret docker-registry <name> --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
Jika kamu sudah memiliki berkas kredensial Docker, daripada menggunakan perintah di atas,
kamu dapat mengimpor berkas kredensial sebagai Kubernetes Secret.
Membuat sebuah Secret berbasiskan pada kredensial Docker yang sudah ada menjelaskan bagaimana mengatur ini.
Cara ini berguna khususnya jika kamu menggunakan beberapa registri kontainer privat,
perintah kubectl create secret docker-registry akan membuat sebuah Secret yang akan
hanya bekerja menggunakan satu registri privat.
Sekarang, kamu dapat membuat Pod yang mengacu pada Secret dengan menambahkan bagian imagePullSecrets
untuk sebuah definisi Pod.
cat <<EOF > pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: awesomeapps
spec:
containers:
- name: foo
image: janedoe/awesomeapp:v1
imagePullSecrets:
- name: myregistrykey
EOF
cat <<EOF >> ./kustomization.yaml
resources:
- pod.yaml
EOF
Cara ini perlu untuk diselesaikan untuk setiap Pod yang mengguunakan registri privat.
Hanya saja, mengatur field ini dapat diotomasi dengan mengatur imagePullSecrets di dalam sumber daya serviceAccount. Periksa Tambahan ImagePullSecrets untuk sebuah Service Account untuk instruksi yang lebih detail.
Kamu dapat menggunakan cara ini bersama .docker/config.json pada setiap Node. Kredensial-kredensial
akan dapat di-merged. Cara ini akan dapat bekerja pada Google Kubernetes Engine.
Ada beberapa solusi untuk konfigurasi registri privat. Berikut beberapa kasus penggunaan dan solusi yang disarankan.
.docker/config.json secara manual pada setiap Node seperti dijelaskan di atas.imagePullSecrets.Jika kamu memiliki akses pada beberapa registri, kamu dapat membuat satu secret untuk setiap registri.
Kubelet akan melakukan merge imagePullSecrets manapun menjadi sebuah virtual .docker/config.json.
Laman ini menjelaskan berbagai resource yang tersedia di dalam Kontainer pada suatu environment.
Environment Kontainer pada Kubernetes menyediakan beberapa resource penting yang tersedia di dalam Kontainer:
Hostname sebuah Kontainer merupakan nama dari Pod dimana Kontainer dijalankan.
Informasi ini tersedia melalui perintah hostname atau panggilan (function call)
gethostname pada libc.
Nama Pod dan namespace tersedia sebagai variabel environment melalui API downward.
Variabel environment yang ditulis pengguna dalam Pod definition juga tersedia di dalam Kontainer, seperti halnya variabel environment yang ditentukan secara statis di dalam image Docker.
Daftar semua Service yang dijalankan ketika suatu Kontainer dibuat, tersedia di dalam Kontainer tersebut sebagai variabel environment. Variabel-variabel environment tersebut sesuai dengan sintaksis links dari Docker.
Untuk suatu Service bernama foo yang terkait dengan Kontainer bernama bar, variabel-variabel di bawah ini tersedia:
FOO_SERVICE_HOST=<host dimana service dijalankan>
FOO_SERVICE_PORT=<port dimana service dijalankan>
Semua Service memiliki alamat-alamat IP yang bisa didapatkan di dalam Kontainer melalui DNS, jika addon DNS diaktifkan.
Kubernetes v1.14 [beta]
Laman ini menjelaskan tentang resource RuntimeClass dan proses pemilihan runtime.
Runtime ClassRuntimeClass merupakan sebuah fitur untuk memilih konfigurasi runtime kontainer. Konfigurasi tersebut digunakan untuk menjalankan kontainer-kontainer milik suatu Pod.
Pastikan gerbang fitur (feature gate) RuntimeClass sudah aktif (secara default sudah aktif).
Lihat Gerbang Fitur untuk lebih
jelasnya soal pengaktifan gerbang fitur.
Gerbang fitur RuntimeClass ini harus aktif pada semua apiserver dan kubelet.
Pilihan konfigurasi yang tersedia melalui RuntimeClass tergantung pada implementasi Container Runtime Interface (CRI). Lihat bagian (di bawah ini) soal bagaimana melakukan konfigurasi untuk implementasi CRI yang kamu miliki.
Seluruh konfigurasi memiliki nama handler yang terkait, dijadikan referensi oleh RuntimeClass.
Nama handler harus berupa valid label 1123 DNS (alfanumerik + karakter -).
RuntimeClass yang terkaitMasing-masing konfigurasi pada langkah no.1 punya nama handler yang merepresentasikan
konfigurasi-konfigurasi tersebut. Untuk masing-masing handler, buatlah sebuah objek RuntimeClass terkait.
Resource RuntimeClass saat ini hanya memiliki 2 field yang penting: nama RuntimeClass tersebut
(metadata.name) dan handler (handler). Definisi objek tersebut terlihat seperti ini:
apiVersion: node.k8s.io/v1beta1 # RuntimeClass didefinisikan pada grup API node.k8s.io
kind: RuntimeClass
metadata:
name: myclass # Nama dari RuntimeClass yang nantinya akan dijadikan referensi
# RuntimeClass merupakan resource tanpa namespace
handler: myconfiguration # Nama dari konfigurasi CRI terkait
Ketika RuntimeClass sudah dikonfigurasi pada klaster, penggunaannya sangatlah mudah.
Kamu bisa tentukan runtimeClassName di dalam spec sebuah Pod, sebagai contoh:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
runtimeClassName: myclass
# ...
Kubelet akan mendapat instruksi untuk menggunakan RuntimeClass dengan nama yang sudah ditentukan tersebut
untuk menjalankan Pod ini. Jika RuntimeClass dengan nama tersebut tidak ditemukan, atau CRI tidak dapat
menjalankan handler yang terkait, maka Pod akan memasuki tahap Failed.
Lihat event untuk mengetahui pesan error yang terkait.
Jika tidak ada runtimeClassName yang ditentukan di dalam Pod, maka RuntimeHandler yang default akan digunakan.
Untuk kasus ini, perilaku klaster akan seperti saat fitur RuntimeClass dinonaktifkan.
Lihat instalasi CRI untuk lebih detail mengenai pengaturan runtime CRI.
Built-in dockershim CRI yang dimiliki Kubernetes tidak mendukung handler runtime.
Handler runtime diatur melalui konfigurasi containerd pada /etc/containerd/config.toml.
Handler yang valid dapat dikonfigurasi pada bagian runtime:
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.${HANDLER_NAME}]
Lihat dokumentasi konfigurasi containerd untuk lebih detail: https://github.com/containerd/containerd/blob/main/docs/cri/config.md
Handler runtime dapat diatur menggunakan konfigurasi cri-o pada /etc/crio/crio.conf.
Handler yang valid dapat dikonfigurasi pada tabel crio.runtime:
[crio.runtime.runtimes.${HANDLER_NAME}]
runtime_path = "${PATH_TO_BINARY}"
Lihat dokumentasi konfigurasi cri-o untuk lebih detail: https://github.com/kubernetes-sigs/cri-o/blob/master/cmd/crio/config.go
Fitur Beta pada RuntimeClass memiliki perubahan sebagai berikut:
node.k8s.io dan runtimeclasses.node.k8s.io telah dimigrasi ke suatu
API built-in dari CustomResourceDefinition.spec telah disederhakan pada definisi RuntimeClass (tidak ada lagi yang namanya
RuntimeClassSpec).runtimeHandler telah berubah nama menjadi handler.handler sekarang bersifat wajib untuk semua versi API. Artinya, field runtimeHandler
pada API Alpha juga bersifat wajib.handler haruslah berupa label DNS valid (RFC 1123),
yang artinya tidak bisa berisi karakter . (pada semua versi). Handler valid harus sesuai dengan
regular expression ini: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$.Tindakan yang diperlukan: Tindakan-tindaka berikut ini diperlukan untuk melakukan pembaruan fitur RuntimeClass dari versi alpha ke versi beta:
runtimeclasses.node.k8s.io harus dihapus secara manual:
kubectl delete customresourcedefinitions.apiextensions.k8s.io runtimeclasses.node.k8s.io
runtimeHandler tidak ditentukan atau
kosong atau menggunakan karakter . pada handler. Ini harus dimigrasi ke handler dengan
konfigurasi yang valid (lihat petunjuk di atas).Laman ini menjelaskan bagaimana semua Kontainer yang diatur kubelet menggunakan framework lifecycle hook untuk menjalankan kode yang di-trigger oleh event selama lifecycle berlangsung.
Kubernetes menyediakan hook untuk lifecycle Kontainer. Hal ini sejalan dengan framework bahasa pemrograman pada umumnya yang memiliki hook untuk lifecycle komponen, seperti Angular contohnya. Hook tersebut digunakan Kontainer untuk selalu siap menerima event selama lifecycle dan menjalankan kode yang diimplementasi pada suatu handler, ketika hook lifecycle terkait telah dieksekusi.
Ada dua jenis hook yang diekspos pada Kontainer:
PostStart
Hook ini dijalankan segera setelah suatu kontainer dibuat.
Hanya saja, tidak ada jaminan bahwa hook akan tereksekusi sebelum ENTRYPOINT dari kontainer.
Tidak ada parameter yang diberikan pada handler.
PreStop
Hook ini akan dipanggil sesaat sebelum kontainer dimatikan, karena suatu request API atau event pengaturan,
contohnya kegagalan pada liveness probe, preemption, perebutan resource, dan lainnya.
Sebuah panggilan untuk hook PreStop akan gagal jika kontainer tersebut telah ada pada state terminate atau complete.
Hal ini bersifat blocking, yang artinya panggilan bersifat sinkron (synchronous), harus menunggu eksekusi selesai, sebelum melakukan panggilan
untuk menghapus kontainer tersebut.
Tidak ada parameter yang diberikan pada handler.
Penjelasan yang lebih rinci tentang proses terminasi dapat dilihat pada Terminasi Pod.
Kontainer dapat mengakses sebuah hook melalui implementasi dan registrasi sebuah handler untuk hook tersebut. Ada dua jenis handler untuk hook yang dapat diimplementasikan untuk Kontainer:
pre-stop.sh, di dalam cgroups dan namespace suatu Kontainer. Resource yang dikonsumsi oleh perintah tersebut dianggap sebagai bagian dari Kontainer.Ketika manajemen hook untuk suatu lifecycle Kontainer dipanggil, sistem manajemen internal pada Kubernetes akan mengeksekusi handler di dalam Kontainer yang terdaftar untuk hook tersebut.
Panggilan handler untuk hook semuanya bersifat synchronous di dalam konteks Pod yang
memiliki Kontainer tersebut. Artinya, untuk hook PostStart, Kontainer ENTRYPOINT
dan hook dieksekusi secara asyncrhonous. Akan tetapi, jika hook mengambil waktu terlalu lama,
atau hang, Kontainer tersebut tidak bisa sampai ke state running.
Perilaku ini mirip dengan yang terjadi pada hook PreStop.
Jika hook terlalu lama atau hang saat dieksekusi, Pod tersebut tetap ada pada state Terminating
dan akan dimatikan setelah terminationGracePeriodSeconds Pod selesai.
Jika sebuah hook PostStart atau PreStop gagal dieksekusi, Kontainer akan dimatikan.
Para pengguna sangat disarankan membuat handler untuk hook seringan mungkin (lightweight). Biar bagaimanapun, ada beberapa kasus yang memang membutuhkan waktu lama untuk mengeksekusi suatu perintah, misalnya saat proses penyimpanan state sebelum Kontainer dimatikan.
Proses pengiriman hook akan dilakukan paling tidak satu kali.
Artinya suatu hook boleh dipanggil beberapa kali untuk event yang sama,
seperti dalam PostStart atauPreStop.
Namun begitu, implementasi hook masing-masing harus memastikan bagaimana
menangani kasus ini dengan benar.
Pada umumnya, hanya terjadi satu proses pengiriman. Jika misalnya sebuah penerima HTTP hook mati atau tidak bisa menerima trafik, maka tidak ada usaha untuk mengirimkan kembali. Namun demikian, bisa saja terjadi dua kali proses pengiriman untuk kasus tertentu. Contohnya, jika kubelet restart saat di tengah proses pengiriman hook, hook tersebut akan dikirimkan kembali saat kubelet sudah hidup kembali.
Log untuk suatu handler hook tidak terekspos pada event Pod.
Jika handler gagal dieksekusi untuk alasan tertentu, handler akan melakukan broadcast sebuah event.
Untuk PostStart, akan dilakukan broadcast event FailedPostStartHook,
dan untuk PreStop, akan dilakukan broadcast event FailedPreStopHook.
Kamu dapat melihat event-event ini dengan menjalankan perintah kubectl describe pod <pod_name>.
Berikut merupakan contoh keluaran event-event setelah perintah tersebut dijalankan.
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 1m 1 {default-scheduler } Normal Scheduled Successfully assigned test-1730497541-cq1d2 to gke-test-cluster-default-pool-a07e5d30-siqd
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulling pulling image "test:1.0"
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Created Created container with docker id 5c6a256a2567; Security:[seccomp=unconfined]
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulled Successfully pulled image "test:1.0"
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Started Started container with docker id 5c6a256a2567
38s 38s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 5c6a256a2567: PostStart handler: Error executing in Docker Container: 1
37s 37s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 8df9fdfd7054: PostStart handler: Error executing in Docker Container: 1
38s 37s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "main" with RunContainerError: "PostStart handler: Error executing in Docker Container: 1"
1m 22s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Warning FailedPostStartHook