Bagian dokumentasi Kubernetes ini berisi halaman-halaman yang perlihatkan bagaimana melakukan setiap tugas (task). Halaman tugas menunjukkan cara melakukan satu hal saja, biasanya dengan memberikan urutan langkah pendek.
Melakukan deploy dan mengakses dashboard berbasis web untuk membantu kamu mengelola dan memantau aplikasi yang dimasukkan ke dalam container di Kubernetes.
Instalasi dan konfigurasi utilitas baris perintah kubectl yang digunakan untuk
mengelola secara langsung klaster Kubernetes.
Melakukan tugas konfigurasi yang umum untuk Pod dan Container.
Melakukan tugas manajemen aplikasi secara umum, seperti rolling updates, memasukkan informasi ke dalam Pod, dan penskalaan Pod secara horisontal.
Menjalankan Job dengan menggunakan pemrosesan paralel.
Mengkonfigurasi load balancing, port forwarding, atau membangun firewall atau konfigurasi DNS untuk mengakses aplikasi dalam sebuah klaster.
Mengatur monitoring (pemantauan) dan logging (pencatatan) untuk memecahkan masalah klaster atau melakukan debug (pelacakan) aplikasi yang dikontainerisasi.
Mempelajari berbagai metode untuk mengakses API Kubernetes secara langsung.
Mengkonfigurasi aplikasi kamu untuk percaya dan menggunakan klaster Certificate Authority (CA).
Mempelajari tugas umum untuk mengelola klaster.
Melakukan tugas umum untuk mengelola aplikasi yang Stateful, termasuk penskalaan, penghapusan, dan debugging StatefulSets.
Melakukan tugas-tugas umum untuk mengelola DaemonSet, seperti melakukan rolling updates.
Mengkonfigurasi dan menjadwalkan GPU NVIDIA untuk digunakan sebagai sumber daya oleh Node dalam sebuah klaster.
Mengkonfigurasi dan menjadwalkan HugePages sebagai sumber daya yang dapat dijadwalkan dalam sebuah klaster.
Jika kamu ingin menulis halaman tugas (task), silahkan lihat Membuat Dokumentasi Pull Request.
Perangkat baris perintah Kubernetes, kubectl,
memungkinkan kamu untuk menjalankan perintah pada klaster Kubernetes.
Kamu dapat menggunakan kubectl untuk menerapkan aplikasi, memeriksa dan mengelola sumber daya klaster,
dan melihat log (catatan). Untuk informasi lebih lanjut termasuk daftar lengkap operasi kubectl, lihat
referensi dokumentasi kubectl.
kubectl dapat diinstal pada berbagai platform Linux, macOS dan Windows. Pilihlah sistem operasi pilihan kamu di bawah ini.
kind memberikan kamu kemampuan untuk
menjalankan Kubernetes pada komputer lokal kamu. Perangkat ini membutuhkan
Docker yang sudah diinstal dan
terkonfigurasi.
Halaman Memulai Cepat kind
memperlihatkan kepada kamu tentang apa yang perlu kamu lakukan untuk kind
berjalan dan bekerja.
Seperti halnya dengan kind, minikube
merupakan perangkat yang memungkinkan kamu untuk menjalankan Kubernetes
secara lokal. minikube menjalankan sebuah klaster Kubernetes dengan
satu node saja dalam komputer pribadi (termasuk Windows, macOS dan Linux)
sehingga kamu dapat mencoba Kubernetes atau untuk pekerjaan pengembangan
sehari-hari.
Kamu bisa mengikuti petunjuk resmi
Memulai!
minikube jika kamu ingin fokus agar perangkat ini terinstal.
Lihat Panduan Memulai! Minikube
Setelah kamu memiliki minikube yang bekerja, kamu bisa menggunakannya
untuk menjalankan aplikasi contoh.
Kamu dapat menggunakan kubeadm
untuk membuat dan mengatur klaster Kubernetes.
kubeadm menjalankan langkah-langkah yang diperlukan untuk mendapatkan klaster
dengan kelaikan dan keamanan minimum, aktif dan berjalan dengan cara yang mudah
bagi pengguna.
Instalasi kubeadm memperlihatkan tentang bagaimana melakukan instalasi kubeadm. Setelah terinstal, kamu dapat menggunakannya untuk membuat klaster.
Lihat panduan instalasi kubeadm
Kubectl adalah alat baris perintah (command line tool) Kubernetes yang digunakan untuk menjalankan berbagai perintah untuk klaster Kubernetes. Kamu dapat menggunakan kubectl untuk men-deploy aplikasi, mengatur sumber daya klaster, dan melihat log. Daftar operasi kubectl dapat dilihat di Ikhtisar kubectl.
Kamu harus menggunakan kubectl dengan perbedaan maksimal satu versi minor dengan klaster kamu. Misalnya, klien v1.2 masih dapat digunakan dengan master v1.1, v1.2, dan 1.3. Menggunakan versi terbaru kubectl dapat menghindari permasalahan yang tidak terduga.
Unduh versi terbarunya dengan perintah:
curl -LO https://dl.k8s.io/release/`curl -LS https://dl.k8s.io/release/stable.txt`/bin/linux/amd64/kubectl
Untuk mengunduh versi spesifik, ganti bagian curl -LS https://dl.k8s.io/release/stable.txt dengan versi yang diinginkan.
Misalnya, untuk mengunduh versi 1.35.0 di Linux, ketik:
curl -LO https://dl.k8s.io/release/v1.35.0/bin/linux/amd64/kubectl
Jadikan program kubectl dapat dieksekusi.
chmod +x ./kubectl
Pindahkan ke PATH kamu.
sudo mv ./kubectl /usr/local/bin/kubectl
Pastikan instalasinya sudah berhasil dengan melakukan pengecekan versi:
kubectl version --client
sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
sudo chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo chmod 644 /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/repodata/repomd.xml.key
EOF
sudo yum install -y kubectl
Unduh versi terbarunya dengan perintah:
curl -LO "https://dl.k8s.io/release/$(curl -LS https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl"
Untuk mengunduh versi spesifik, ganti bagian curl -LS https://dl.k8s.io/release/stable.txt dengan versi yang diinginkan.
Misalnya, untuk mengunduh versi 1.35.0 pada macOS, ketik:
curl -LO https://dl.k8s.io/release/v1.35.0/bin/darwin/amd64/kubectl
Buat agar program kubectl dapat dijalankan.
chmod +x ./kubectl
Pindahkan ke PATH kamu.
sudo mv ./kubectl /usr/local/bin/kubectl
Pastikan instalasinya sudah berhasil dengan melakukan pengecekan versi:
kubectl version --client
Jika kamu menggunakan macOS dan manajer paket Homebrew, kamu dapat menginstal kubectl langsung dengan Homebrew.
Jalankan perintah:
brew install kubectl
atau
brew install kubernetes-cli
Pastikan instalasinya sudah berhasil dengan melakukan pengecekan versi:
kubectl version --client
Jika kamu menggunakan macOS dan manajer paket Macports, kamu dapat menginstal kubectl langsung dengan Macports.
Jalankan perintah:
sudo port selfupdate
sudo port install kubectl
Pastikan instalasinya sudah berhasil dengan melakukan pengecekan versi:
kubectl version --client
Unduh versi terbarunya 1.35.0 dari tautan ini.
Atau jika sudah ada curl pada mesin kamu, jalankan perintah ini:
curl -LO https://dl.k8s.io/release/v1.35.0/bin/windows/amd64/kubectl.exe
Untuk mendapatkan versi stabil terakhir (misalnya untuk scripting), lihat di https://dl.k8s.io/release/stable.txt.
Tambahkan program yang sudah diunduh tersebut ke PATH kamu.
Pastikan instalasinya sudah berhasil dengan melakukan pengecekan versi:
kubectl version --client
kubectl-nya sendiri ke PATH. Jika kamu sudah menginstal Docker Desktop, kamu harus menambahkan entrinya ke PATH sebelum yang ditambahkan oleh penginstal (installer) Docker Desktop atau kamu dapat menghapus kubectl bawaan dari Docker Desktop.Jika kamu menggunakan Windows dan manajer paket Powershell Gallery, kamu dapat menginstal dan melakukan pembaruan kubectl dengan Powershell.
Jalankan perintah berikut (jangan lupa untuk memasukkan DownloadLocation):
Install-Script -Name install-kubectl -Scope CurrentUser -Force
install-kubectl.ps1 [-DownloadLocation <path>]
DownloadLocation, kubectl akan diinstal di dalam direktori temp pengguna.Penginstal akan membuat $HOME/.kube dan membuat berkas konfigurasi
Pastikan instalasinya sudah berhasil dengan melakukan pengecekan versi:
kubectl version --client
Untuk menginstal kubectl pada Windows, kamu dapat menggunakan manajer paket Chocolatey atau penginstal baris perintah Scoop.
choco install kubernetes-cli
scoop install kubectl
Pastikan instalasinya sudah berhasil dengan melakukan pengecekan versi:
kubectl version --client
Pindah ke direktori utama:
cd %USERPROFILE%
Buat direktori .kube:
mkdir .kube
Pindah ke direktori .kube yang baru saja dibuat:
cd .kube
Lakukan konfigurasi kubectl untuk menggunakan klaster Kubernetes remote:
New-Item config -type file
Kamu dapat menginstal kubectl sebagai bagian dari Google Cloud SDK.
Instal Google Cloud SDK.
Jalankan perintah instalasi kubectl:
gcloud components install kubectl
Pastikan instalasinya sudah berhasil dengan melakukan pengecekan versi:
kubectl version --client
Agar kubectl dapat mengakses klaster Kubernetes, dibutuhkan sebuah berkas kubeconfig, yang akan otomatis dibuat ketika kamu membuat klaster baru menggunakan kube-up.sh atau setelah berhasil men-deploy klaster Minikube. Secara bawaan, konfigurasi kubectl disimpan di ~/.kube/config.
Kamu dapat memeriksa apakah konfigurasi kubectl sudah benar dengan mengambil keadaan klaster:
kubectl cluster-info
Jika kamu melihat respons berupa URL, maka konfigurasi klaster kubectl sudah benar.
Tetapi, jika kamu melihat pesan seperti di bawah, maka kubectl belum dikonfigurasi dengan benar atau tidak dapat terhubung ke klaster Kubernetes.
The connection to the server <server-name:port> was refused - did you specify the right host or port?
Selanjutnya, jika kamu ingin menjalankan klaster Kubernetes di laptop (lokal) kamu, kamu memerlukan sebuah perangkat seperti Minikube sebelum menjalankan ulang perintah yang ada di atas.
Jika kubectl cluster-info mengembalikan respons URL tetapi kamu masih belum dapat mengakses klaster, kamu bisa menggunakan perintah di bawah untuk memeriksa apakah klaster sudah dikonfigurasi dengan benar.
kubectl cluster-info dump
kubectl menyediakan fitur penyelesaian otomatis (auto complete) untuk Bash dan Zsh yang dapat memudahkanmu ketika mengetik di terminal.
Ikuti petunjuk di bawah untuk menyalakan penyelesaian otomatis untuk Bash dan Zsh.
Skrip penyelesaian (completion script) kubectl untuk Bash dapat dibuat dengan perintah kubectl completion bash. Masukkan skrip tersebut ke dalam terminal sebagai sumber untuk menyalakan penyelesaian otomatis dari kubectl.
Namun, skrip penyelesaian tersebut bergantung pada bash-completion, yang artinya kamu harus menginstal program tersebut terlebih dahulu (kamu dapat memeriksa apakah kamu sudah memiliki bash-completion dengan menjalankan perintah type _init_completion).
bash-completion disediakan oleh banyak manajer paket (lihat di sini). Kamu dapat menginstalnya dengan menggunakan perintah apt-get install bash-completion atau yum install bash-completion, dsb.
Perintah di atas akan membuat skrip utama bash-completion di /usr/share/bash-completion/bash_completion. Terkadang kamu juga harus menambahkan skrip tersebut ke dalam berkas ~/.bashrc, tergantung manajer paket yang kamu pakai.
Untuk memastikannya, muat ulang terminalmu dan jalankan type _init_completion. Jika perintah tersebut berhasil, maka instalasi selesai. Jika tidak, tambahkan teks berikut ke dalam berkas ~/.bashrc:
source /usr/share/bash-completion/bash_completion
Muat ulang terminalmu dan pastikan bash-completion sudah berhasil diinstal dengan menjalankan type _init_completion.
Sekarang kamu harus memastikan bahwa skrip penyelesaian untuk kubectl sudah dimasukkan sebagai sumber penyelesaian otomatis pada semua sesi terminal. Kamu dapat melakukannya dengan dua cara:
Masukkan skrip penyelesaian sebagai sumber di berkas ~/.bashrc:
echo 'source <(kubectl completion bash)' >>~/.bashrc
Tambahkan skrip penyelesaian ke direktori /etc/bash_completion.d:
kubectl completion bash >/etc/bash_completion.d/kubectl
Jika kamu menggunakan alias untuk kubectl, kamu masih dapat menggunakan fitur penyelesaian otomatis dengan menjalankan perintah:
```shell
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -F __start_kubectl k' >>~/.bashrc
```
/etc/bash_completion.d.Kedua cara tersebut sama, kamu bisa memilih salah satunya. Setelah memuat ulang terminal, penyelesaian otomatis dari kubectl seharusnya sudah dapat bekerja.
Skrip penyelesaian (completion script) kubectl untuk Bash dapat dibuat dengan perintah kubectl completion bash. Masukkan skrip tersebut ke dalam terminal sebagai sumber untuk menyalakan penyelesaian otomatis dari kubectl.
Namun, skrip penyelesaian tersebut bergantung pada bash-completion, yang artinya kamu harus menginstal program tersebut terlebih dahulu.
kubectl tidak kompatibel dengan bash-completion v1 dan Bash 3.2. Dibutuhkan bash-completion v2 dan Bash 4.1+ agar skrip penyelesaian kubectl dapat bekerja dengan baik. Maka dari itu, kamu harus menginstal dan menggunakan Bash 4.1+ (panduan) untuk dapat menggunakan fitur penyelesaian otomatis dari kubectl. Ikuti panduan di bawah setelah kamu menginstal Bash 4.1+ (yaitu, Bash versi 4.1 atau lebih baru).Panduan di bawah berasumsi kamu menggunakan Bash 4.1+. Kamu dapat memeriksa versi Bash dengan menjalankan:
echo $BASH_VERSION
Jika versinya sudah terlalu usang, kamu dapat menginstal/memutakhirkannya dengan menggunakan Homebrew:
brew install bash
Muat ulang terminalmu dan pastikan versi yang diharapkan sudah dipakai:
echo $BASH_VERSION $SHELL
Homebrew biasanya akan menginstalnya di /usr/local/bin/bash.
kubectl tidak kompatibel dengan Bash 3.2 dan bash-completion v1).Kamu dapat memeriksa apakah kamu sudah memiliki bash-completion v2 dengan perintah type _init_completion. Jika belum, kamu dapat menginstalnya dengan menggunakan Homebrew:
brew install bash-completion@2
Seperti yang disarankan pada keluaran perintah di atas, tambahkan teks berikut ke berkas ~/.bashrc:
export BASH_COMPLETION_COMPAT_DIR="/usr/local/etc/bash_completion.d"
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
Muat ulang terminalmu dan pastikan bash-completion v2 sudah terinstal dengan perintah type _init_completion.
Sekarang kamu harus memastikan bahwa skrip penyelesaian untuk kubectl sudah dimasukkan sebagai sumber penyelesaian otomatis di semua sesi terminal. Kamu dapat melakukannya dengan beberapa cara:
Masukkan skrip penyelesaian sebagai sumber di berkas ~/.bashrc:
echo 'source <(kubectl completion bash)' >>~/.bashrc
Menambahkan skrip penyelesaian ke direktori /etc/bash_completion.d:
kubectl completion bash >/etc/bash_completion.d/kubectl
Jika kamu menggunakan alias untuk kubectl, kamu masih dapat menggunakan fitur penyelesaian otomatis dengan menjalankan perintah:
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -F __start_kubectl k' >>~/.bashrc
Jika kamu menginstal kubectl dengan Homebrew (seperti yang sudah dijelaskan di atas), maka skrip penyelesaian untuk kubectl sudah berada di /usr/local/etc/bash_completion.d/kubectl. Kamu tidak perlu melakukan apa-apa lagi.
BASH_COMPLETION_COMPAT_DIR, itulah alasannya dua cara terakhir dapat bekerja.Setelah memuat ulang terminal, penyelesaian otomatis dari kubectl seharusnya sudah dapat bekerja.
Skrip penyelesaian (completion script) kubectl untuk Zsh dapat dibuat dengan perintah kubectl completion zsh. Masukkan skrip tersebut ke dalam terminal sebagai sumber untuk menyalakan penyelesaian otomatis dari kubectl.
Tambahkan baris berikut di berkas ~/.zshrc untuk menyalakan penyelesaian otomatis dari kubectl:
source <(kubectl completion zsh)
Jika kamu menggunakan alias untuk kubectl, kamu masih dapat menggunakan fitur penyelesaian otomatis dengan menjalankan perintah:
echo 'alias k=kubectl' >>~/.zshrc
echo 'compdef __start_kubectl k' >>~/.zshrc
Setelah memuat ulang terminal, penyelesaian otomatis dari kubectl seharusnya sudah dapat bekerja.
Jika kamu mendapatkan pesan gagal seperti complete:13: command not found: compdef, maka tambahkan teks berikut ke awal berkas ~/.zshrc:
autoload -Uz compinit
compinit
Kamu dapat menggunakan CronJob untuk menjalankan Job yang dijadwalkan berbasis waktu. Job akan berjalan seperti pekerjaan-pekerjaan Cron di Linux atau sistem UNIX.
CronJob sangat berguna untuk membuat pekerjaan yang berjalan secara periodik dan berulang, misalnya menjalankan (backup) atau mengirim email. CronJob juga dapat menjalankan pekerjaan individu pada waktu tertentu, misalnya jika kamu ingin menjadwalkan sebuah pekerjaan dengan periode aktivitas yang rendah.
CronJob memiliki keterbatasan dan kekhasan. Misalnya, dalam keadaan tertentu, sebuah CronJob dapat membuat banyak Job. Karena itu, Job haruslah idempotent.
Untuk informasi lanjut mengenai keterbatasan, lihat CronJob.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
CronJob membutuhkan sebuah berkas konfigurasi.
Ini adalah contoh dari berkas konfigurasi CronJob .spec yang akan mencetak waktu sekarang dan pesan "hello" setiap menit:
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "* * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
Jalankan contoh CronJob menggunakan perintah berikut:
kubectl create -f https://k8s.io/examples/application/job/cronjob.yaml
Keluaran akan mirip dengan ini:
cronjob.batch/hello created
Kamu juga dapat menggunakan kubectl run untuk membuat sebuah CronJob tanpa menulis sebuah konfigurasi yang lengkap:
kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
Setelah membuat sebuah CronJob, untuk mengecek statusnya kamu dapat menggunakan perintah berikut:
kubectl get cronjob hello
Keluaran akan mirip dengan ini:
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 <none> 10s
Seperti yang kamu lihat dari hasil perintah di atas, CronJob belum menjadwalkan atau menjalankan pekerjaan apa pun. Waktu yang biasanya dibutuhkan untuk mengamati Job hingga Job tersebut dibuat akan membutuhkan sekitar satu menit:
kubectl get jobs --watch
Keluaran akan mirip dengan ini:
NAME COMPLETIONS DURATION AGE
hello-4111706356 0/1 0s
hello-4111706356 0/1 0s 0s
hello-4111706356 1/1 5s 5s
Sekarang kamu telah melihat satu Job berjalan yang dijadwalkan oleh "hello" CronJob. Kamu dapat berhenti mengamati Job dan melihat CronJob lagi untuk melihat CronJob menjadwalkan sebuah Job:
kubectl get cronjob hello
Keluaran akan mirip dengan ini:
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 50s 75s
Kamu dapat melihat bahwa CronJob hello berhasil menjadwalkan sebuah Job pada waktu yang ditentukan dalam LAST SCHEDULE. Saat ini ada 0 Job yang aktif, berarti sebuah Job telah selesai atau gagal.
Sekarang, temukan Pod yang dibuat oleh jadwal Job terakhir dan melihat keluaran bawaan dari salah satu Pod.
# Ganti "hello-4111706356" dengan nama Job di sistem kamu
pods=$(kubectl get pods --selector=job-name=hello-4111706356 --output=jsonpath={.items[*].metadata.name})
Menampilkan log sebuah Pod:
kubectl logs $pods
Keluaran akan mirip dengan ini:
Fri Feb 22 11:02:09 UTC 2019
Hello from the Kubernetes cluster
Ketika kamu tidak membutuhkan sebuah CronJob lagi, kamu dapat megnhapusnya dengan perintah kubectl delete cronjob <cronjob name>:
kubectl delete cronjob hello
Menghapus CronJob akan menghapus semua Job dan Pod yang telah terbuat dan menghentikanya dari pembuatan Job tambahan. Kamu dapat membaca lebih lanjut tentang menghapus Job di garbage collection.
Seperti semua konfigurasi Kubernetes, sebuah CronJob membutuhkan field apiVersion, kind, dan metadata. Untuk informasi
umum tentang bekerja dengan berkas konfigurasi, lihat dokumentasi men-deploy aplikasi,
dan mengunakan kubectl untuk manajemen sumber daya.
Sebuah konfigurasi CronJob juga membutuhkan sebuah bagian .spec.
.spec, akan diterapkan pada proses berikut..spec.schedule adalah field yang wajib diisi dari sebuah .spec
Dibutuhkan sebuah format string Cron, misalnya 0 * * * * atau @hourly, sebagai jadwal Job untuk dibuat dan dieksekusi.
Format ini juga mencakup nilai langkah "Vixie cron". Seperti penjelasan di FreeBSD manual:
Nilai langkah dapat digunakan bersama dengan rentang. Sebuah rentang diikuti dengan
/<number>menentukan lompatan angka melalui rentang. Misalnya,0-23/2dapat digunakan dalam jam untuk menentukan perintah akan dieksekusi setiap jam (alternatif dalam bawaan v7 adalah0,2,4,6,8,10,12,14,16,18,20,22). Langkah-langkah juga diizinkan setelah tanda bintang, jadi jika kamu menginginkan "setiap dua jam", gunakan saja*/2.
?) dalam penjadwalan memiliki makna yang sama dengan tanda bintang *, yaitu, singkatan dari nilai apa pun yang tersedia untuk field tertentu..spec.JobTemplate adalah templat untuk sebuah Job, dan itu wajib.
Templat Job memiliki skema yang sama dengan Job, kecuali jika bersarang dan tidak memiliki sebuah apiVersion atau kind.
Untuk informasi lebih lanjut tentang menulis sebuah Job .spec lihat Menulis spesifikasi Job.
Field .spec.startingDeadlineSeconds adalah field opsional.
Field tersebut berarti batas waktu dalam satuan detik untuk memulai sebuah Job jika Job melewatkan waktu yang telah dijadwalkan karena alasan apapun.
Setelah mencapai batas waktu, CronJob tidak akan memulai sebuah Job.
Job yang tidak memenuhi batas waktu, dengan cara ini dianggap sebagai Job yang gagal.
Jika field ini tidak ditentukan, maka Job tidak memiliki batas waktu.
Controller CronJob menghitung berapa banyak jadwal yang terlewat untuk sebuah CronJob. jika lebih dari 100 jadwal yang terlewat, maka tidak ada lagi CronJob yang akan dijadwalkan. Ketika .spec.startingDeadlineSeconds tidak disetel, CronJob Controller menghitung jadwal yang terlewat dari status.lastScheduleTime hingga sekarang.
Misalnya, sebuah CronJob seharusnya berjalan setiap menit, status.lastScheduleTime CronJob adalah pukul 5:00am, tetapi sekarang pukul 07:00am. Itu berarti ada 120 jadwal yang terlewat, maka tidak ada lagi CronJob yang akan dijadwalkan.
Jika field .spec.startingDeadlineSeconds disetel (tidak kosong), CronJob Controller akah menghitung berapa banyak Job yang terlewat dari nilai .spec.startingDeadlineSeconds hingga sekarang.
Misalnya, jika disetel ke 200, CronJob Controller akan menghitung jadwal yang terlewat dalam 200 detik terakhir. Pada kasus ini, jika terdapat lebih dari 100 jadwal yang terlewat dalam 200 detik terakhir, maka tidak ada lagi CronJob yang akan dijadwalkan.
Field .spec.concurrencyPolicy juga opsional.
Field tersebut menentukan bagaimana memperlakukan eksekusi concurrent dari sebuah Job yang dibuat oleh CronJob.
Kamu dapat menetapkan hanya satu dari kebijakan concurrency:
Allow (bawaan): CronJob mengizinkan Job berjalan secara concurrentForbid : Job tidak mengizinkan Job berjalan secara concurrent; jika sudah saatnya untuk menjalankan Job baru dan Job sebelumnya belum selesai, maka CronJob akan melewatkan Job baru yang akan berjalanReplace: Jika sudah saatnya untuk menjalankan Job baru dan Job sebelumnya belum selesai, maka CronJob akan mengganti Job yang sedang berjalan dengan Job baru.Perhatikan bahwa kebijakan concurrency hanya berlaku untuk Job yang dibuat dengan CronJob yang sama. Jika terdapat banyak CronJob, Job akan selalu diizinkan untuk berjalan secara concurrent.
Field .spec.suspend juga opsional.
Jika field tersebut disetel true, semua eksekusi selanjutnya akan ditangguhkan.
Konfigurasi ini tidak dapat berlaku untuk eksekusi yang sudah dimulai.
Secara bawaan false.
.spec.suspend diubah dari true ke false pada CronJob yang memiliki konfigurasi tanpa batas waktu, Job yang terlewat akan dijadwalkan segera.Field .spec.successfulJobsHistoryLimit dan .spec.failedJobsHistoryLimit juga opsional.
Field tersebut menentukan berapa banyak Job yang sudah selesai dan gagal yang harus disimpan.
Secara bawaan, masing-masing field tersebut disetel 3 dan 1. Mensetel batas ke 0 untuk menjaga tidak ada Job yang sesuai setelah Job tersebut selesai.
Laman ini menunjukkan bagaimana menetapkan permintaan dan batasan memori untuk Container. Container dijamin memiliki memori sebanyak yang diminta, tetapi tidak diperbolehkan untuk menggunakan memori melebihi batas.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Setiap Node pada klaster kamu harus memiliki memori setidaknya 300 MiB.
Beberapa langkah pada laman ini mengharuskan kamu menjalankan Service metrics-server pada klaster kamu. Jika kamu memiliki metrics-server yang sudah berjalan, kamu dapat melewati langkah-langkah berikut ini.
Jika kamu menjalankan Minikube, jalankan perintah berikut untuk mengaktifkan metrics-server:
minikube addons enable metrics-server
Untuk melihat apakah metrics-server sudah berjalan, atau penyedia lain dari API metrik sumber daya
(metrics.k8s.io), jalankan perintah berikut ini:
kubectl get apiservices
Jika API metrik sumber daya telah tersedia, keluarannya meliputi seperti
acuan pada metrics.k8s.io.
NAME
v1beta1.metrics.k8s.io
Buat Namespace sehingga sumber daya yang kamu buat dalam latihan ini terisolasi dari klaster kamu yang lain.
kubectl create namespace mem-example
Untuk menentukan permintaan memori untuk Container, sertakan field resources:requests
pada manifes sumber daya dari Container. Untuk menentukan batasan memori, sertakan resources:limits.
Dalam latihan ini, kamu akan membuat Pod yang memiliki satu Container. Container memiliki permintaan memori sebesar 100 MiB dan batasan memori sebesar 200 MiB. Berikut berkas konfigurasi untuk Pod:
apiVersion: v1
kind: Pod
metadata:
name: memory-demo
namespace: mem-example
spec:
containers:
- name: memory-demo-ctr
image: polinux/stress
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
Bagian args dalam berkas konfigurasi memberikan argumen untuk Container pada saat dimulai.
Argumen"--vm-bytes", "150M" memberi tahu Container agar mencoba mengalokasikan memori sebesar 150 MiB.
Buatlah Pod:
kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit.yaml --namespace=mem-example
Verifikasi apakah Container dalam Pod sudah berjalan:
kubectl get pod memory-demo --namespace=mem-example
Lihat informasi mendetil tentang Pod:
kubectl get pod memory-demo --output=yaml --namespace=mem-example
Keluarannya menunjukkan bahwa satu Container dalam Pod memiliki permintaan memori sebesar 100 MiB dan batasan memori sebesar 200 MiB.
...
resources:
limits:
memory: 200Mi
requests:
memory: 100Mi
...
Jalankan kubectl top untuk mengambil metrik dari Pod:
kubectl top pod memory-demo --namespace=mem-example
Keluarannya menunjukkan bahwa Pod menggunakan memori sekitar 162.900.000 byte, dimana sekitar 150 MiB. Ini lebih besar dari permintaannya sebesar 100 MiB Pod, tetapi masih di dalam batasan Pod sebesar 200 MiB.
NAME CPU(cores) MEMORY(bytes)
memory-demo <something> 162856960
Hapuslah Pod:
kubectl delete pod memory-demo --namespace=mem-example
Container dapat melebihi permintaan memorinya jika Node memiliki memori yang tersedia. Tapi sebuah Container tidak diperbolehkan untuk menggunakan lebih dari batasan memorinya. Jika Container mengalokasikan lebih banyak memori daripada batasannya, Container menjadi kandidat untuk dihentikan. Jika Container terus berlanjut mengkonsumsi memori melebihi batasnya, maka Container akan diakhiri. Jika Container dihentikan dan bisa di mulai ulang, kubelet akan memulai ulang, sama seperti jenis kegagalan runtime yang lainnya.
Dalam latihan ini, kamu membuat Pod yang mencoba mengalokasikan lebih banyak memori dari batasannya. Berikut adalah berkas konfigurasi untuk Pod yang memiliki satu Container dengan berkas permintaan memori sebesar 50 MiB dan batasan memori sebesar 100 MiB:
apiVersion: v1
kind: Pod
metadata:
name: memory-demo-2
namespace: mem-example
spec:
containers:
- name: memory-demo-2-ctr
image: polinux/stress
resources:
requests:
memory: "50Mi"
limits:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]
Dalam bagian args dari berkas konfigurasi, kamu dapat melihat bahwa Container tersebut
akan mencoba mengalokasikan memori sebesar 250 MiB, yang jauh di atas batas yaitu 100 MiB.
Buatlah Pod:
kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit-2.yaml --namespace=mem-example
Lihat informasi mendetail tentang Pod:
kubectl get pod memory-demo-2 --namespace=mem-example
Sampai sini, Container mungkin sedang berjalan atau dimatikan. Ulangi perintah sebelumnya hingga Container dimatikan:
NAME READY STATUS RESTARTS AGE
memory-demo-2 0/1 OOMKilled 1 24s
Dapatkan tampilan yang lebih mendetail tentang status Container:
kubectl get pod memory-demo-2 --output=yaml --namespace=mem-example
Keluarannya menunjukkan bahwa Container dimatikan karena kehabisan memori (OOM):
lastState:
terminated:
containerID: docker://65183c1877aaec2e8427bc95609cc52677a454b56fcb24340dbd22917c23b10f
exitCode: 137
finishedAt: 2017-06-20T20:52:19Z
reason: OOMKilled
startedAt: null
Container dalam latihan ini dapat dimulai ulang, sehingga kubelet akan memulai ulangnya. Ulangi perintah ini beberapa kali untuk melihat bahwa Container berulang kali dimatikan dan dimulai ulang:
kubectl get pod memory-demo-2 --namespace=mem-example
Keluarannya menunjukkan bahwa Container dimatikan, dimulai ulang, dimatikan lagi, dimulai ulang lagi, dan seterusnya:
kubectl get pod memory-demo-2 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-2 0/1 OOMKilled 1 37s
kubectl get pod memory-demo-2 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-2 1/1 Running 2 40s
Lihat informasi mendetail tentang riwayat Pod:
kubectl describe pod memory-demo-2 --namespace=mem-example
Keluarannya menunjukkan bahwa Container dimulai dan gagal berulang kali:
... Normal Created Created container with id 66a3a20aa7980e61be4922780bf9d24d1a1d8b7395c09861225b0eba1b1f8511
... Warning BackOff Back-off restarting failed container
Lihat informasi mendetail tentang Node klaster Anda:
kubectl describe nodes
Keluarannya mencakup rekaman Container yang dimatikan karena kondisi kehabisan memori:
Warning OOMKilling Memory cgroup out of memory: Kill process 4481 (stress) score 1994 or sacrifice child
Hapus Pod kamu:
kubectl delete pod memory-demo-2 --namespace=mem-example
Permintaan dan batasan memori yang dikaitkan dengan Container, berguna untuk berpikir apakah sebuah Pod yang memiliki permintaan dan batasan memori. Permintaan memori untuk Pod tersebut adalah jumlah permintaan memori untuk semua Container dalam Pod. Begitu juga dengan batasan memori untuk Pod adalah jumlah batasan memori dari semua Container di dalam Pod.
Penjadwalan Pod didasarkan pada permintaan. Sebuah Pod dijadwalkan untuk berjalan di sebuah Node hanya jika sebuah Node memiliki cukup memori yang tersedia untuk memenuhi permintaan memori dari Pod tersebut.
Dalam latihan ini, kamu membuat Pod yang memiliki permintaan memori yang sangat besar sehingga melebihi kapasitas dari Node mana pun dalam klaster kamu. Berikut adalah berkas konfigurasi untuk Pod yang memiliki Container dengan permintaan memori 1000 GiB, yang kemungkinan besar melebihi kapasitas dari setiap Node dalam klaster kamu.
apiVersion: v1
kind: Pod
metadata:
name: memory-demo-3
namespace: mem-example
spec:
containers:
- name: memory-demo-3-ctr
image: polinux/stress
resources:
limits:
memory: "1000Gi"
requests:
memory: "1000Gi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
Buatlah Pod:
kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit-3.yaml --namespace=mem-example
Lihat status Pod:
kubectl get pod memory-demo-3 --namespace=mem-example
Keluarannya menunjukkan bahwa status Pod adalah PENDING. Artinya, Pod tidak dijadwalkan untuk berjalan di Node mana pun, dan Pod akan tetap dalam status PENDING tanpa batas waktu:
kubectl get pod memory-demo-3 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-3 0/1 Pending 0 25s
Lihat informasi mendetail tentang Pod, termasuk event:
kubectl describe pod memory-demo-3 --namespace=mem-example
Keluarannya menunjukkan bahwa Container tidak dapat dijadwalkan karena memori yang tidak cukup pada Node:
Events:
... Reason Message
------ -------
... FailedScheduling No nodes are available that match all of the following predicates:: Insufficient memory (3).
Sumber daya memori diukur dalam satuan byte. Kamu dapat mengekspresikan memori sebagai bilangan bulat biasa atau bilangan bulan fixed-point dengan salah satu akhiran ini: E, P, T, G, M, K, Ei, Pi, Ti, Gi, Mi, Ki. Contoh berikut ini mewakili nilai yang kira-kira sama:
128974848, 129e6, 129M , 123Mi
Hapuslah Pod kamu:
kubectl delete pod memory-demo-3 --namespace=mem-example
Jika kamu tidak menentukan batasan memori untuk sebuah Container, salah satu dari situasi berikut ini berlaku:
Container tidak memiliki batasan maksimum jumlah memori yang digunakannya. Container dapat menggunakan semua memori yang tersedia dalam Node dimana Container itu berjalan yang pada gilirannya dapat memanggil penyetop OOM (out-of-memory). Lebih lanjut, dalam kasus menghentikan OOM, Container tanpa batas sumber daya akan memiliki peluang lebih besar untuk dihentikan.
Container berjalan pada Namespace yang memiliki batasan bawaan memori, dan Container secara otomatis menetapkan batasan bawaan. Administrator klaster dapat menggunakan LimitRange untuk menentukan batasan memori secara bawaan.
Dengan mengonfigurasi permintaan dan batasan memori untuk Container yang berjalan pada berkas klaster, kamu dapat menggunakan sumber daya memori yang tersedia pada Node klaster kamu secara efisien. Dengan menjaga permintaan memori pada Pod tetap rendah, kamu memberikan kesempatan yang baik untuk Pod tersebut dijadwalkan. Dengan memiliki batas memori yang lebih besar dari permintaan memori, Anda mencapai dua hal:
Hapus Namespace kamu. Ini akan menghapus semua Pod yang kamu buat untuk tugas ini:
kubectl delete namespace mem-example
Mengonfigurasi permintaan dan batasan bawaan memori untuk Namespace
Mengonfigurasi permintaan dan batasan bawaan CPU untuk Namespace
Mengonfigurasi batasan memori minimum dan maksimum untuk Namespace
Mengonfigurasi batasan CPU minimum dan maksimum untuk Namespace
Laman ini menunjukkan bagaimana mengonfigurasi Pod agar ditempatkan pada kelas Quality of Service (QoS) tertentu. Kubernetes menggunakan kelas QoS untuk membuat keputusan tentang penjadwalan dan pengeluaran Pod.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Saat membuat Pod, Kubernetes menempatkan salah satu kelas QoS berikut untuknya:
Buat sebuah Namespace sehingga sumber daya yang kamu buat dalam latihan ini terisolasi dari klaster kamu yang lain.
kubectl create namespace qos-example
Agar sebuah Pod memiliki kelas QoS Guaranteed:
Berikut adalah berkas konfigurasi untuk sebuah Pod dengan satu Container. Container tersebut memiliki sebuah batasan memori dan sebuah permintaan memori, keduanya sama dengan 200MiB. Container itu juga mempunyai batasan CPU dan permintaan CPU yang sama sebesar 700 milliCPU:
apiVersion: v1
kind: Pod
metadata:
name: qos-demo
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
Buatlah Pod:
kubectl create -f https://k8s.io/examples/pods/qos/qos-pod.yaml --namespace=qos-example
Tampilkan informasi detail Pod yang telah dibuat:
kubectl get pod qos-demo --namespace=qos-example --output=yaml
Keluaran dari perintah di atas menunjukkan Kubernetes memberikan kelas QoS Guaranteed pada Pod. Keluaran tersebut juga membuktikan bahwa Container pada Pod memiliki permintaan memori yang sesuai dengan batasan memori dan permintaan CPU yang juga sesuai dengan batasan CPU yang dispesifikasikan.
spec:
containers:
...
resources:
limits:
cpu: 700m
memory: 200Mi
requests:
cpu: 700m
memory: 200Mi
...
status:
qosClass: Guaranteed
Hapuslah Pod:
kubectl delete pod qos-demo --namespace=qos-example
Sebuah Pod akan mendapatkan kelas QoS Burstable apabila:
Berikut adalah berkas konfigurasi untuk Pod dengan satu Container. Container yang dimaksud memiliki batasan memori sebesar 200MiB dan permintaan memori sebesar 100MiB.
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-2
namespace: qos-example
spec:
containers:
- name: qos-demo-2-ctr
image: nginx
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
Buatlah Pod:
kubectl create -f https://k8s.io/examples/pods/qos/qos-pod-2.yaml --namespace=qos-example
Tampilkan informasi detail Pod yang telah dibuat:
kubectl get pod qos-demo-2 --namespace=qos-example --output=yaml
Keluaran dari perintah di atas menunjukkan Kubernetes memberikan kelas QoS Burstable pada Pod.
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: qos-demo-2-ctr
resources:
limits:
memory: 200Mi
requests:
memory: 100Mi
...
status:
qosClass: Burstable
Hapuslah Pod:
kubectl delete pod qos-demo-2 --namespace=qos-example
Agar Pod mendapatkan kelas QoS BestEffort, Container dalam pod tidak boleh memiliki batasan atau permintaan memori atau CPU.
Berikut adalah berkas konfigurasi untuk Pod dengan satu Container. Container yang dimaksud tidak memiliki batasan atau permintaan memori atau CPU apapun.
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-3
namespace: qos-example
spec:
containers:
- name: qos-demo-3-ctr
image: nginx
Buatlah Pod:
kubectl create -f https://k8s.io/examples/pods/qos/qos-pod-3.yaml --namespace=qos-example
Tampilkan informasi detail Pod yang telah dibuat:
kubectl get pod qos-demo-3 --namespace=qos-example --output=yaml
Keluaran dari perintah di atas menunjukkan Kubernetes memberikan kelas QoS BestEffort pada Pod.
spec:
containers:
...
resources: {}
...
status:
qosClass: BestEffort
Hapuslah Pod:
kubectl delete pod qos-demo-3 --namespace=qos-example
Berikut adalah konfigurasi berkas untuk Pod yang memiliki dua Container. Satu Container menentukan permintaan memori sebesar 200MiB. Container yang lain tidak menentukan permintaan atau batasan apapun.
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-4
namespace: qos-example
spec:
containers:
- name: qos-demo-4-ctr-1
image: nginx
resources:
requests:
memory: "200Mi"
- name: qos-demo-4-ctr-2
image: redis
Perhatikan bahwa Pod ini memenuhi kriteria untuk kelas QoS Burstable. Maksudnya, Container tersebut tidak memenuhi kriteria untuk kelas QoS Guaranteed, dan satu dari Container tersebut memiliki permintaan memori.
Buatlah Pod:
kubectl create -f https://k8s.io/examples/pods/qos/qos-pod-4.yaml --namespace=qos-example
Tampilkan informasi detail Pod yang telah dibuat:
kubectl get pod qos-demo-4 --namespace=qos-example --output=yaml
Keluaran dari perintah di atas menunjukkan Kubernetes memberikan kelas QoS Burstable pada Pod.
spec:
containers:
...
name: qos-demo-4-ctr-1
resources:
requests:
memory: 200Mi
...
name: qos-demo-4-ctr-2
resources: {}
...
status:
qosClass: Burstable
Hapuslah Pod:
kubectl delete pod qos-demo-4 --namespace=qos-example
Hapuslah Namespace:
kubectl delete namespace qos-example
Mengonfigurasi permintaan dan batasan bawaan memori untuk Namespace
Mengonfigurasi permintaan dan batasan bawaan CPU untuk Namespace
Mengonfigurasi batasan memori minimum dan maksimum untuk Namespace
Mengonfigurasi batasan CPU minimum dan maksimum untuk Namespace
Laman ini menjelaskan bagaimana cara mengatur sebuah Pod untuk menggunakan Volume sebagai tempat penyimpanan.
Filesystem dari sebuah Container hanya hidup selama Container itu juga hidup. Saat Container berakhir dan dimulai ulang, perubahan pada filesystem akan hilang. Untuk penyimpanan konsisten yang independen dari Container, kamu dapat menggunakan Volume. Hal ini penting terutama untuk aplikasi stateful, seperti key-value stores (contohnya Redis) dan database.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Pada latihan ini, kamu membuat sebuah Pod yang menjalankan sebuah Container. Pod ini memiliki sebuah Volume dengan tipe emptyDir yang tetap bertahan, meski Container berakhir dan dimulai ulang. Berikut berkas konfigurasi untuk Pod:
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}
Membuat Pod:
kubectl apply -f https://k8s.io/examples/pods/storage/redis.yaml
Verifikasi apakah Container dari Pod berjalan sukses, lalu mengamati perubahan terhadap Pod:
kubectl get pod redis --watch
Hasil keluaran seperti ini:
NAME READY STATUS RESTARTS AGE
redis 1/1 Running 0 13s
Pada terminal lain, buka shell untuk masuk ke Container yang sedang berjalan:
kubectl exec -it redis -- /bin/bash
Di dalam shell, pergi ke /data/redis, kemudian buat sebuah berkas:
root@redis:/data# cd /data/redis/
root@redis:/data/redis# echo Hello > test-file
Di dalam shell, munculkan daftar proses-proses yang sedang berjalan:
root@redis:/data/redis# apt-get update
root@redis:/data/redis# apt-get install procps
root@redis:/data/redis# ps aux
Keluarannya mirip seperti ini:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
redis 1 0.1 0.1 33308 3828 ? Ssl 00:46 0:00 redis-server *:6379
root 12 0.0 0.0 20228 3020 ? Ss 00:47 0:00 /bin/bash
root 15 0.0 0.0 17500 2072 ? R+ 00:48 0:00 ps aux
Di dalam shell, matikan proses Redis:
root@redis:/data/redis# kill <pid>
dengan <pid> adalah ID proses Redis (PID).
Di dalam terminal awal, amati perubahan terhadap Pod Redis. Sampai akhirnya kamu akan melihat hal seperti ini:
NAME READY STATUS RESTARTS AGE
redis 1/1 Running 0 13s
redis 0/1 Completed 0 6m
redis 1/1 Running 1 6m
Sampai di sini, Container telah berakhir dan dimuat ulang. Hal ini karena Pod Redis memiliki
restartPolicy
dengan nilai Always.
Gunakan shell untuk masuk ke dalam Container yang telah dimuat ulang:
kubectl exec -it redis -- /bin/bash
Di dalam shell, pergi ke /data/redis, dan verifikasi apakah test-file masih ada.
root@redis:/data/redis# cd /data/redis/
root@redis:/data/redis# ls
test-file
Hapus Pod yang kamu buat untuk latihan ini:
kubectl delete pod redis
Lihat Volume.
Lihat Pod.
Selain penyimpanan pada disk lokal yang di sediakan oleh emptyDir, Kubernetes
juga mendukung solusi penyimpanan network-attached, termasuk PD pada
GCE dan EBS dari EC2, yang cenderung lebih disukai untuk data sangat penting dan akan menangani urusan detil seperti mounting dan unmounting perangkat pada Node. Lihat
Volume untuk informasi detil.
Laman ini akan menjelaskan bagaimana kamu dapat mengatur sebuah Pod dengan menggunakan PersistentVolumeClaim untuk penyimpanan. Berikut ringkasan prosesnya:
Kamu, sebagai seorang administrator klaster, membuat sebuah PersistentVolume yang didukung oleh penyimpanan fisik. Kamu tidak mengaitkan volume dengan Pod apapun.
Kamu, sekarang mengambil peran sebagai seorang developer / pengguna klaster, membuat sebuah PersistentVolumeClaim yang secara otomatis terikat dengan PersistentVolume yang sesuai.
Kamu membuat sebuah Pod yang menggunakan PersistentVolumeClaim di atas untuk penyimpanan.
Kamu membutuhkan sebuah klaster Kubernetes yang hanya memiliki satu Node, dan kubectl alat baris perintah yang sudah diatur untuk berkomunikasi dengan klaster kamu. Jika kamu tidak memiliki sebuah klaster dengan Node tunggal, kamu dapat membuatnya dengan Minikube.
Familiar dengan materi di Persistent Volumes.
Buka sebuah shell ke Node tunggal di klaster kamu. Bagaimana kamu membuka sebuah shell tergantung
dengan bagaimana kamu mengatur klaster kamu. Contoh, jika kamu menggunakan Minikube, kamu
dapat membuka sebuah shell ke Node kamu dengan memasukkan minikube ssh.
Di dalam shell kamu pada Node itu, buat sebuah direktori dengan nama /mnt/data:
# Asumsikan Node kamu menggunakan "sudo" untuk menjalankan perintah
# sebagai superuser
sudo mkdir /mnt/data
Di dalam direktori /mnt/data, buat sebuah berkas dengan nama index.html:
# Disini kembali asumsikan bahwa Node kamu menggunakan "sudo" untuk menjalankan perintah
# sebagai superuser
sudo sh -c "echo 'Hello from Kubernetes storage' > /mnt/data/index.html"
sudo, kamu dapat
membuat ini bekerja jika mengganti sudo dengan nama dari alat lainnya.Menguji bahwa berkas index.html ada:
cat /mnt/data/index.html
Keluaran akan seperti ini:
Hello from Kubernetes storage
Sekarang kamu dapat menutup shell di Node kamu.
Pada latihan ini, kamu akan membuat sebuah hostPath PersistentVolume. Kubernetes mendukung hostPath untuk pengembangan dan pengujian di dalam klaster Node tunggal. Sebuah hostPath PersistentVolume menggunakan berkas atau direktori di dalam Node untuk meniru penyimpanan terhubung jaringan (NAS, network-attached storage).
Di dalam klaster production, kamu tidak dapat menggunakan hostPath. Sebagai gantinya sebuah administrator klaster akan menyediakan sumberdaya jaringan seperti Google Compute Engine persistent disk, NFS share, atau sebuah Amazon Elastic Block Store volume. Administrator klaster juga dapat menggunakan StorageClass untuk mengatur provisioning secara dinamis.
Berikut berkas konfigurasi untuk hostPath PersistentVolume:
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
Berkas konfigurasi tersebut menentukan bahwa volume berada di /mnt/data pada
klaster Node. Konfigurasi tersebut juga menentukan ukuran dari 10 gibibytes dan
mode akses ReadWriteOnce, yang berarti volume dapat di pasang sebagai
read-write oleh Node tunggal. Konfigurasi ini menggunakan nama dari StorageClass
manual untuk PersistentVolume, yang akan digunakan untuk mengikat
permintaan PeristentVolumeClaim ke PersistentVolume ini.
Membuat sebuah PersistentVolume:
kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
Melihat informasi tentang PersistentVolume:
kubectl get pv task-pv-volume
Keluaran menunjuk PersistentVolume memliki sebuah STATUS dari Available. Ini
berarti PersistentVolume belum terikat ke PersistentVolumeClaim.
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Available manual 4s
Langkah selanjutnya adalah membuat sebuah PersistentVolumeClaim. Pod menggunakan PersistentVolumeClaim untuk meminta penyimpanan fisik. Pada latihan ini, kamu akan membuat sebuah PersistentVolumeClaim yang meminta sebuah volume minimal tiga gibibytes dengan mode akses read-write setidaknya untuk satu Node.
Berikut berkas konfigurasi untuk PersistentVolumeClaim:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
Membuat sebuah PersistentVolumeClaim:
kubectl apply -f https://k8s.io/examples/pods/storage/pv-claim.yaml
Setelah membuat sebuah PersistentVolumeClaim, Kubernetes control plane terlihat untuk sebuah PersistentVolumeClaim yang memenuhi persyaratan claim's. Jika control plane menemukan PersistentVolume yang cocok dengan StorageClass, maka akan mengikat claim ke dalam volume tersebut.
Lihat kembali PersistentVolume:
kubectl get pv task-pv-volume
Sekarang keluaran menunjukan sebuah STATUS dari Bound.
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Bound default/task-pv-claim manual 2m
Lihat PersistentVolumeClaim:
kubectl get pvc task-pv-claim
Keluaran menunjukan PersistentVolumeClaim terlah terikat dengan PersistentVolume,
task-pv-volume.
NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE
task-pv-claim Bound task-pv-volume 10Gi RWO manual 30s
Langkah selanjutnya adalah membuat sebuah Pod yang akan menggunakan PersistentVolumeClaim sebagai volume.
Berikut berkas konfigurasi untuk Pod:
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
Perhatikan bahwa berkas konfigurasi Pod menentukan sebuah PersistentVolumeClaim, tetapi tidak menentukan PeristentVolume. Dari sudut pandang Pod, claim adalah volume.
Membuat Pod:
kubectl apply -f https://k8s.io/examples/pods/storage/pv-pod.yaml
Pastikan bahwa Container di dalam Pod berjalan:
kubectl get pod task-pv-pod
Mendapatkan sebuah shell ke Container yang sedang berjalan di Pod kamu:
kubectl exec -it task-pv-pod -- /bin/bash
Di dalam shell, pastikan bahwa nginx menyajikan berkas index.html dari dalam
hostPath volume:
# Pastikan kamu menjalankan 3 perintah ini di dalam shell root yang berasal dari
# "kubectl exec" dari langkah sebelumnya
apt update
apt install curl
curl http://localhost/
Keluaran akan menunjukan sebuah teks yang telah kamu tulis di berkas index.html
di dalam hostPath volume:
Hello from Kubernetes storage
Jika kamu melihat pesan tersebut, kamu telah berhasil mengatur sebuah Pod untuk menggunakan penyimpanan dari PersistentVolumeClaim.
Hapus Pod, PersistentVolumeClaim dan PersistentVolume:
kubectl delete pod task-pv-pod
kubectl delete pvc task-pv-claim
kubectl delete pv task-pv-volume
Jika kamu belum memiliki shell yang telah dibuka ke Node di klaster kamu, buka shell baru dengan cara yang sama yang telah kamu lakukan sebelumnya.
Di dalam shell Node kamu, hapus berkas dan direktori yang telah kamu buat:
# Asumsikan Node kamu menggunakan "sudo" untuk menjalankan perintah
# sebagai superuser
sudo rm /mnt/data/index.html
sudo rmdir /mnt/data
Sekarang kamu dapat menutup shell Node kamu.
Penyimpanan yang telah terkonfigurasi dengan group ID (GID) memungkinkan akses menulis hanya dari Pod yang menggunakan GID yang sama. GID yang tidak cocok atau hilang akan menyebabkan kesalahan izin ditolak. Untuk mengurangi kebutuhan koordinasi dengan pengguna, administrator dapat membuat anotasi sebuah PersistentVolume dengan GID. Kemudian GID akan otomatis ditambahkan ke Pod yang menggunakan PersistentVolume.
Gunakan anotasi pv.beta.kubernetes.io/gid sebagai berikut:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
annotations:
pv.beta.kubernetes.io/gid: "1234"
Ketika sebuah Pod mengkonsumsi PersistentVolume yang memiliki anotasi GID, anotasi GID tersebut akan diterapkan ke semua container di dalam Pod dengan cara yang sama yang ditentukan di dalam GID Pod security context. Settiap GID, baik berasal dari anotasi PersistentVolume atau Pod, diterapkan pada proses pertama yang dijalankan di setiap container.
Konteks keamanan (security context) menentukan wewenang (privilege) dan aturan kontrol akses untuk sebuah Pod atau Container. Aturan konteks keamanan meliputi hal-hal berikut ini namun tidak terbatas pada hal-hal tersebut:
Kontrol akses bersifat diskresi: Izin untuk mengakses objek, seperti sebuah berkas, yang didasarkan pada ID pengguna atau user ID (UID) dan ID grup atau group ID (GID).
Security Enhanced Linux (SELinux): Di mana objek diberi label keamanan.
Menjalankan dengan wewenang (privileged) atau tanpa wewenang (unprivileged).
Kapabilitas Linux (Linux Capabilities): Memberi sebuah proses beberapa wewenang, namun tidak semua wewenang dari pengguna root.
AppArmor: Menggunakan profil program untuk membatasi kemampuan dari masing-masing program.
Seccomp: Menyaring panggilan sistem (system calls) dari suatu proses.
AllowPrivilegeEscalation: Mengontrol apakah suatu proses dapat memperoleh lebih banyak wewenang daripada proses induknya. Pilihan ini mengontrol secara langsung apakah opsi no_new_privs diaktifkan pada proses dalam Container. AllowPrivilegeEscalation selalu aktif (true) ketika Container: 1) berjalan dengan wewenang ATAU 2) memiliki CAP_SYS_ADMIN.
readOnlyRootFilesystem: Menambatkan (mount) sistem berkas (file system) root dari sebuah Container hanya sebatas untuk dibaca saja (read-only).
Poin-poin di atas bukanlah sekumpulan lengkap dari aturan konteks keamanan - silakan lihat SecurityContext untuk daftar lengkapnya.
Untuk informasi lebih lanjut tentang mekanisme keamanan pada Linux, silahkan lihat ikhtisar fitur keamanan pada Kernel Linux
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Untuk menentukan aturan keamanan pada Pod, masukkan bagian securityContext
dalam spesifikasi Pod. Bagian securityContext adalah sebuah objek
PodSecurityContext.
Aturan keamanan yang kamu tetapkan untuk Pod akan berlaku untuk semua Container dalam Pod tersebut.
Berikut sebuah berkas konfigurasi untuk Pod yang memiliki volume securityContext dan emptyDir:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
volumes:
- name: sec-ctx-vol
emptyDir: {}
containers:
- name: sec-ctx-demo
image: busybox
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: sec-ctx-vol
mountPath: /data/demo
securityContext:
allowPrivilegeEscalation: false
Dalam berkas konfigurasi ini, bagian runAsUser menentukan bahwa dalam setiap Container pada
Pod, semua proses dijalankan oleh ID pengguna 1000. Bagian runAsGroup menentukan grup utama dengan ID 3000 untuk
semua proses dalam setiap Container pada Pod. Jika bagian ini diabaikan, maka ID grup utama dari Container
akan berubah menjadi root(0). Berkas apa pun yang dibuat juga akan dimiliki oleh pengguna dengan ID 1000 dan grup dengan ID 3000 ketika runAsGroup ditentukan.
Karena fsGroup ditentukan, semua proses milik Container juga merupakan bagian dari grup tambahan dengan ID 2000.
Pemilik volume /data/demo dan berkas apa pun yang dibuat dalam volume tersebut adalah grup dengan ID 2000.
Buatlah Pod tersebut:
kubectl apply -f https://k8s.io/examples/pods/security/security-context.yaml
Periksa apakah Container dari Pod sedang berjalan:
kubectl get pod security-context-demo
Masuk ke shell dari Container yang sedang berjalan tersebut:
kubectl exec -it security-context-demo -- sh
Pada shell kamu, lihat daftar proses yang berjalan:
ps
Keluarannya menunjukkan bahwa proses dijalankan oleh pengguna dengan ID 1000, yang merupakan nilai dari bagian runAsUser:
PID USER TIME COMMAND
1 1000 0:00 sleep 1h
6 1000 0:00 sh
...
Pada shell kamu, pindah ke direktori /data, dan lihat isinya:
cd /data
ls -l
Keluarannya menunjukkan bahwa direktori /data/demo memiliki grup dengan ID 2000, yang merupakan
nilai dari bagian fsGroup.
drwxrwsrwx 2 root 2000 4096 Jun 6 20:08 demo
Pada shell kamu, pindah ke direktori /data/demo, dan buatlah sebuah berkas didalamnya:
cd demo
echo hello > testfile
Lihatlah daftar berkas dalam direktori /data/demo:
ls -l
Keluarannya menunjukkan bahwa testfile memiliki grup dengan ID 2000, dimana merupakan nilai dari bagian fsGroup.
-rw-r--r-- 1 1000 2000 6 Jun 6 20:08 testfile
Jalankan perintah berikut ini:
$ id
uid=1000 gid=3000 groups=2000
Kamu akan melihat bahwa nilai gid adalah 3000, sama dengan bagian runAsGroup. Jika runAsGroup diabaikan maka nilai gid akan
tetap bernilai 0(root) dan proses akan dapat berinteraksi dengan berkas-berkas yang dimiliki oleh grup root(0) dan yang memiliki
izin grup untuk grup root(0).
Keluarlah dari shell kamu:
exit
Kubernetes v1.18 [alpha]
Secara bawaan, Kubernetes mengubah kepemilikan dan izin secara rekursif untuk konten masing-masing
volume untuk mencocokkan fsGroup yang ditentukan dalam securityContext dari Pod pada saat volume itu
ditambatkan (mounted). Untuk volume yang besar, memeriksa dan mengubah kepemilikan dan izin dapat memerlukan waktu yang sangat lama,
sehingga memperlambat proses menjalankan Pod. Kamu dapat menggunakan bagian fsGroupChangePolicy dalam sebuah securityContext
untuk mengontrol cara Kubernetes memeriksa dan mengelola kepemilikan dan izin
untuk sebuah volume.
fsGroupChangePolicy - fsGroupChangePolicy mendefinisikan perilaku untuk mengubah kepemilikan dan izin volume
sebelum diekspos di dalam sebuah Pod. Bagian ini hanya berlaku untuk tipe volume yang mendukung
fsGroup untuk mengontrol kepemilikan dan izin. Bagian ini memiliki dua nilai yang dapat dimasukkan:
Sebagai contoh:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
fsGroupChangePolicy: "OnRootMismatch"
Ini adalah fitur alpha. Untuk menggunakannya, silahkan aktifkan gerbang fitur ConfigurableFSGroupPolicy untuk kube-api-server, kube-controller-manager, dan kubelet.
secret,
configMap,
dan emptyDir.Untuk menentukan aturan keamanan untuk suatu Container, sertakan bagian securityContext
dalam manifes Container. Bagian securityContext adalah sebuah objek
SecurityContext.
Aturan keamanan yang kamu tentukan untuk Container hanya berlaku untuk
Container secara individu, dan aturan tersebut menimpa aturan yang dibuat pada tingkat Pod apabila
ada aturan yang tumpang tindih. Aturan pada Container mempengaruhi volume pada Pod.
Berikut berkas konfigurasi untuk Pod yang hanya memiliki satu Container. Keduanya, baik Pod
dan Container memiliki bagian securityContext sebagai berikut:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-2
spec:
securityContext:
runAsUser: 1000
containers:
- name: sec-ctx-demo-2
image: gcr.io/google-samples/node-hello:1.0
securityContext:
runAsUser: 2000
allowPrivilegeEscalation: false
Buatlah Pod tersebut:
kubectl apply -f https://k8s.io/examples/pods/security/security-context-2.yaml
Periksa jika Container dalam Pod sedang berjalan:
kubectl get pod security-context-demo-2
Masuk ke dalam shell Container yang sedang berjalan tersebut:
kubectl exec -it security-context-demo-2 -- sh
Pada shell kamu, lihat daftar proses yang sedang berjalan:
ps aux
Keluarannya menunjukkan bahwa proses dijalankan oleh user dengan ID 2000, yang merupakan
nilai dari runAsUser seperti yang telah ditentukan untuk Container tersebut. Nilai tersebut menimpa nilai ID 1000 yang
ditentukan untuk Pod-nya.
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
2000 1 0.0 0.0 4336 764 ? Ss 20:36 0:00 /bin/sh -c node server.js
2000 8 0.1 0.5 772124 22604 ? Sl 20:36 0:00 node server.js
...
Keluar dari shell anda:
exit
Dengan menggunakan Kapabilitas Linux (Linux Capabilities),
kamu dapat memberikan wewenang tertentu kepada suatu proses tanpa memberikan semua wewenang
dari pengguna root. Untuk menambah atau menghapus Kapabilitas Linux pada suatu Container, masukkan
bagian capabilities pada securityContext di manifes Container-nya.
Pertama-tama, mari melihat apa yang terjadi ketika kamu tidak menyertakan bagian capabilities.
Berikut ini adalah berkas konfigurasi yang tidak menambah atau mengurangi kemampuan apa pun dari Container:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-3
spec:
containers:
- name: sec-ctx-3
image: gcr.io/google-samples/node-hello:1.0
Buatlah Pod tersebut:
kubectl apply -f https://k8s.io/examples/pods/security/security-context-3.yaml
Periksa apakah Container dari Pod tersebut sedang berjalan:
kubectl get pod security-context-demo-3
Masuk ke dalam shell dari Container yang berjalan:
kubectl exec -it security-context-demo-3 -- sh
Dalam shell tersebut, lihatlah daftar proses yang berjalan:
ps aux
Keluarannya menunjukkan ID dari proses atau process IDs (PIDs) untuk Container tersebut:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 4336 796 ? Ss 18:17 0:00 /bin/sh -c node server.js
root 5 0.1 0.5 772124 22700 ? Sl 18:17 0:00 node server.js
Dalam shell kamu, lihat status dari proses dengan ID 1:
cd /proc/1
cat status
Keluarannya menunjukkan bitmap dari kapabilitas untuk proses tersebut:
...
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
...
Buatlah catatan untuk bitmap dari kapabilitas tersebut, dan keluarlah dari shell kamu:
exit
Berikutnya, jalankan Container yang sama seperti dengan Container sebelumnya, namun Container ini memiliki kapabilitas tambahan yang sudah ditentukan.
Berikut ini adalah berkas konfigurasi untuk Pod yang hanya menjalankan satu Container. Konfigurasi
ini menambahkan kapabilitas CAP_NET_ADMIN dan CAP_SYS_TIME:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-4
spec:
containers:
- name: sec-ctx-4
image: gcr.io/google-samples/node-hello:1.0
securityContext:
capabilities:
add: ["NET_ADMIN", "SYS_TIME"]
Buatlah Pod tersebut:
kubectl apply -f https://k8s.io/examples/pods/security/security-context-4.yaml
Masuk ke dalam shell dari Container yang berjalan:
kubectl exec -it security-context-demo-4 -- sh
Di dalam shell kamu, lihatlah kapabilitas dari proses dengan ID 1:
cd /proc/1
cat status
Keluarannya menunjukkan bitmap kapabilitas untuk proses tersebut:
...
CapPrm: 00000000aa0435fb
CapEff: 00000000aa0435fb
...
Bandingkan kemampuan dari kedua Containers tersebut:
00000000a80425fb
00000000aa0435fb
Dalam bitmap kapabilitas pada Container pertama, bit-12 dan ke-25 tidak diatur. Sedangkan dalam Container kedua,
bit ke-12 dan ke-25 diatur. Bit ke-12 adalah kapabilitas CAP_NET_ADMIN, dan bit-25 adalah kapabilitas CAP_SYS_TIME.
Lihatlah capability.h
untuk nilai dari konstanta kapabilitas-kapabilitas yang lainnya.
CAP_XXX. Tetapi ketika kamu memasukkan daftar kemampuan dalam manifes Container kamu, kamu harus menghilangkan bagian CAP_ dari konstantanya. Misalnya, untuk menambahkan CAP_SYS_TIME, masukkan SYS_TIME ke dalam daftar kapabilitas Container kamu.Untuk memberikan label SELinux pada sebuah Container, masukkan bagian seLinuxOptions pada
bagian securityContext dari manifes Pod atau Container kamu.
Bagian seLinuxOptions adalah sebuah objek SELinuxOptions.
Berikut ini adalah contoh yang menerapkan sebuah level dari SELinux:
...
securityContext:
seLinuxOptions:
level: "s0:c123,c456"
Konteks keamanan untuk sebuah Pod berlaku juga untuk Container yang berada dalam Pod tersebut dan juga untuk
volume dari Pod tersebut jika ada. Terkhusus untuk fsGroup dan seLinuxOptions
akan diterapkan pada volume seperti berikut:
fsGroup: Volume yang mendukung manajemen kepemilikan (ownership) akan dimodifikasi agar dapat dimiliki
dan ditulis oleh ID group (GID) yang disebutkan dalam fsGroup. Lihatlah
Dokumen Desain untuk Manajemen Kepemilikan
untuk lebih lanjut.
seLinuxOptions: Volume yang mendukung pelabelan SELinux akan dilabel ulang agar dapat diakses
oleh label yang ditentukan pada seLinuxOptions. Biasanya kamu hanya
perlu mengatur bagian level. Dimana ini akan menetapkan label
Keamanan multi-kategori (Multi-Category Security) (MCS)
yang diberikan kepada semua Container dalam Pod serta Volume yang ada didalamnya.
Hapus Pod-Pod tersebut:
kubectl delete pod security-context-demo
kubectl delete pod security-context-demo-2
kubectl delete pod security-context-demo-3
kubectl delete pod security-context-demo-4
ServiceAccount menyediakan identitas untuk proses yang sedang berjalan dalam sebuah Pod.
Ketika kamu mengakses klaster (contohnya menggunakan kubectl), kamu terautentikasi oleh apiserver sebagai sebuah akun pengguna (untuk sekarang umumnya sebagai admin, kecuali jika administrator klastermu telah melakukan pengubahan). Berbagai proses yang ada di dalam kontainer dalam Pod juga dapat mengontak apiserver. Ketika itu terjadi, mereka akan diautentikasi sebagai sebuah ServiceAccount (contohnya sebagai default).
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Ketika kamu membuat sebuah Pod, jika kamu tidak menentukan sebuah ServiceAccount, maka ia akan otomatis ditetapkan sebagai ServiceAccountdefault di Namespace yang sama. Jika kamu mendapatkan json atau yaml mentah untuk sebuah Pod yang telah kamu buat (contohnya menggunakan kubectl get pods/<podname> -o yaml), kamu akan melihat field spec.serviceAccountName yang telah secara otomatis ditentukan.
Kamu dapat mengakses API dari dalam Pod menggunakan kredensial ServiceAccount yang ditambahkan secara otomatis seperti yang dijelaskan dalam Mengakses Klaster. Hak akses API dari ServiceAccount menyesuaikan dengan kebijakan dan plugin otorisasi yang sedang digunakan.
Di versi 1.6+, kamu dapat tidak memilih automounting kredensial API dari sebuah ServiceAccount dengan mengatur automountServiceAccountToken: false pada ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
automountServiceAccountToken: false
...
Di versi 1.6+, kamu juga dapat tidak memilih automounting kredensial API dari suatu Pod tertentu:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: build-robot
automountServiceAccountToken: false
...
Pengaturan dari spesifikasi Pod didahulukan dibanding ServiceAccount jika keduanya menentukan nilai dari automountServiceAccountToken.
Setiap Namespace memiliki sumber daya ServiceAccount standar default.
Kamu dapat melihatnya dan sumber daya serviceAccount lainnya di Namespace tersebut dengan perintah:
kubectl get serviceaccounts
Keluarannya akan serupa dengan:
NAME SECRETS AGE
default 1 1d
Kamu dapat membuat objek ServiceAccount tambahan seperti ini:
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
EOF
Nama dari objek ServiceAccount haruslah sebuah nama subdomain DNS yang valid.
Jika kamu mendapatkan objek ServiceAccount secara komplit, seperti ini:
kubectl get serviceaccounts/build-robot -o yaml
Keluarannya akan serupa dengan:
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2015-06-16T00:12:59Z
name: build-robot
namespace: default
resourceVersion: "272500"
uid: 721ab723-13bc-11e5-aec2-42010af0021e
secrets:
- name: build-robot-token-bvbk5
maka kamu dapat melihat bahwa token telah dibuat secara otomatis dan dirujuk oleh ServiceAccount.
Kamu dapat menggunakan plugin otorisasi untuk mengatur hak akses dari ServiceAccount.
Untuk menggunakan ServiceAccount selain nilai standar, atur field spec.serviceAccountName dari Pod menjadi nama dari ServiceAccount yang hendak kamu gunakan.
Service account harus ada ketika Pod dibuat, jika tidak maka akan ditolak.
Kamu tidak dapat memperbarui ServiceAccount dari Pod yang telah dibuat.
Kamu dapat menghapus ServiceAccount dari contoh seperti ini:
kubectl delete serviceaccount/build-robot
Asumsikan kita memiliki ServiceAccount dengan nama "build-robot" seperti yang disebukan di atas, dan kita membuat Secret secara manual.
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: build-robot-secret
annotations:
kubernetes.io/service-account.name: build-robot
type: kubernetes.io/service-account-token
EOF
Sekarang kamu dapat mengonfirmasi bahwa Secret yang baru saja dibuat diisi dengan token API dari ServiceAccount "build-robot".
Setiap token dari ServiceAccount yang tidak ada akan dihapus oleh token controller.
kubectl describe secrets/build-robot-secret
Keluarannya akan serupa dengan:
Name: build-robot-secret
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: build-robot
kubernetes.io/service-account.uid: da68f9c6-9d26-11e7-b84e-002dc52800da
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1338 bytes
namespace: 7 bytes
token: ...
token tidak dirinci di sini.Membuat sebuah imagePullSecret, seperti yang dijelaskan pada Menentukan ImagePullSecret pada Pod.
kubectl create secret docker-registry myregistrykey --docker-server=<registry name> \
--docker-username=DUMMY_USERNAME --docker-password=DUMMY_DOCKER_PASSWORD \
--docker-email=DUMMY_DOCKER_EMAIL
Memastikan bahwa Secret telah terbuat.
kubectl get secrets myregistrykey
Keluarannya akan serupa dengan:
NAME TYPE DATA AGE
myregistrykey  kubernetes.io/.dockerconfigjson  1    1d
Selanjutnya, modifikasi ServiceAccount standar dari Namespace untuk menggunakan Secret ini sebagai imagePullSecret.
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'
Sebagai gantinya kamu dapat menggunakan kubectl edit, atau melakukan pengubahan secara manual manifes YAML seperti di bawah ini:
kubectl get serviceaccounts default -o yaml > ./sa.yaml
Keluaran dari berkas sa.yaml akan serupa dengan:
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2015-08-07T22:02:39Z
name: default
namespace: default
resourceVersion: "243024"
uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
secrets:
- name: default-token-uudge
Menggunakan editor pilihanmu (misalnya vi), buka berkas sa.yaml, hapus baris dengan key resourceVersion, tambahkan baris dengan imagePullSecrets: dan simpan.
Keluaran dari berkas sa.yaml akan serupa dengan:
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2015-08-07T22:02:39Z
name: default
namespace: default
uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
secrets:
- name: default-token-uudge
imagePullSecrets:
- name: myregistrykey
Terakhir ganti serviceaccount dengan berkas sa.yaml yang telah diperbarui.
kubectl replace serviceaccount default -f ./sa.yaml
Ketika Pod baru dibuat dalam Namespace yang sedang aktif dan menggunakan ServiceAccount, Pod baru akan memiliki field spec.imagePullSecrets yang ditentukan secara otomatis:
kubectl run nginx --image=<registry name>/nginx --restart=Never
kubectl get pod nginx -o=jsonpath='{.spec.imagePullSecrets[0].name}{"\n"}'
Keluarannya adalah:
myregistrykey
Kubernetes v1.12 [beta]
ServiceAccountTokenVolumeProjection masih dalam tahap beta untuk versi 1.12 dan diaktifkan dengan memberikan flag berikut ini ke API server:
--service-account-issuer--service-account-signing-key-file--service-account-api-audiencesKubelet juga dapat memproyeksikan token ServiceAccount ke Pod. Kamu dapat menentukan properti yang diinginkan dari token seperti target pengguna dan durasi validitas. Properti tersebut tidak dapat diubah pada token ServiceAccount standar. Token ServiceAccount juga akan menjadi tidak valid terhadap API ketika Pod atau ServiceAccount dihapus.
Perilaku ini diatur pada PodSpec menggunakan tipe ProjectedVolume yaitu ServiceAccountToken. Untuk memungkinkan Pod dengan token dengan pengguna bertipe "vault" dan durasi validitas selama dua jam, kamu harus mengubah bagian ini pada PodSpec:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /var/run/secrets/tokens
name: vault-token
serviceAccountName: build-robot
volumes:
- name: vault-token
projected:
sources:
- serviceAccountToken:
path: vault-token
expirationSeconds: 7200
audience: vault
Buat Pod:
kubectl create -f https://k8s.io/examples/pods/pod-projected-svc-token.yaml
Token yang mewakili Pod akan diminta dan disimpan kubelet, lalu kubelet akan membuat token yang dapat diakses oleh Pod pada file path yang ditentukan, dan melakukan refresh token ketika telah mendekati waktu berakhir. Token akan diganti oleh kubelet jika token telah melewati 80% dari total TTL, atau jika token telah melebihi waktu 24 jam.
Aplikasi bertanggung jawab untuk memuat ulang token ketika terjadi penggantian. Pemuatan ulang teratur (misalnya sekali setiap 5 menit) cukup untuk mencakup kebanyakan kasus.
Kubernetes v1.18 [alpha]
Fitur ServiceAccountIssuerDiscovery diaktifkan dengan mengaktifkan gerbang fitur ServiceAccountIssuerDiscovery dan mengaktifkan fitur Service Account Token Volume Projection seperti yang telah dijelaskan di atas.
URL issuer harus sesuai dengan OIDC Discovery Spec. Pada implementasinya, hal ini berarti URL harus menggunakan skema https dan harus menyediakan konfigurasi penyedia OpenID pada {service-account-issuer}/.well-known/openid-configuration.
Jika URL tidak sesuai dengan aturan, endpoint ServiceAccountIssuerDiscovery tidak akan didaftarkan meskipun fitur telah diaktifkan.
Fitur Service Account Issuer Discovery memungkinkan federasi dari berbagai token ServiceAccount Kubernetes yang dibuat oleh sebuah klaster (penyedia identitas) dan sistem eksternal.
Ketika diaktifkan, server API Kubernetes menyediakan dokumen OpenID Provider Configuration pada /.well-known/openid-configuration dan JSON Web Key Set (JWKS) terkait pada /openid/v1/jwks. OpenID Provider Configuration terkadang disebut juga dengan sebutan discovery document.
Ketika diaktifkan, klaster juga dikonfigurasi dengan RBAC ClusterRole standar yaitu system:service-account-issuer-discovery. Role binding tidak disediakan secara default. Administrator dimungkinkan untuk, sebagai contoh, menentukan apakah peran akan disematkan ke system:authenticated atau system:unauthenticated tergantung terhadap kebutuhan keamanan dan sistem eksternal yang direncakanan untuk diintegrasikan.
/.well-known/openid-configuration dan/openid/v1/jwks dirancang untuk kompatibel dengan OIDC, tetapi tidak sepenuhnya sesuai dengan ketentuan OIDC. Dokumen tersebut hanya berisi parameter yang dibutuhkan untuk melakukan validasi terhadap token ServiceAccount Kubernetes.Respons JWKS memuat kunci publik yang dapat digunakan oleh sistem eksternal untuk melakukan validasi token ServiceAccount Kubernetes. Awalnya sistem eksternal akan mengkueri OpenID Provider Configuration, dan selanjutnya dapat menggunakan field jwks_uri pada respons kueri untuk mendapatkan JWKS.
Pada banyak kasus, server API Kubernetes tidak tersedia di internet publik, namun endpoint publik yang menyediakan respons hasil cache dari server API dapat dibuat menjadi tersedia oleh pengguna atau penyedia servis. Pada kasus ini, dimungkinkan untuk mengganti jwks_uri pada OpenID Provider Configuration untuk diarahkan ke endpoint publik sebagai ganti alamat server API dengan memberikan flag --service-account-jwks-uri ke API server. serupa dengan URL issuer, URI JWKS diharuskan untuk menggunakan skema https.
Lihat juga:
Laman ini menunjukkan cara membuat Pod dengan menggunakan Secret untuk menarik image dari sebuah register atau repositori pribadi untuk Docker.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Untuk melakukan latihan ini, kamu memerlukan sebuah nama pengguna (ID) Docker dan kata sandi (password).
Pada laptop kamu, kamu harus melakukan autentikasi dengan register untuk menarik image pribadi:
docker login
Ketika diminta, masukkan nama pengguna dan kata sandi Docker kamu.
Proses login membuat atau memperbarui berkas config.json yang menyimpan sebuah token otorisasi.
Lihatlah berkas config.json:
cat ~/.docker/config.json
Keluaran berisi bagian yang serupa dengan ini:
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "c3R...zE2"
}
}
}
auth tetapi entri credsStore dengan nama tempat penyimpanan sebagai nilainya.Klaster Kubernetes menggunakan Secret dari tipe docker-registry untuk melakukan autentikasi dengan
register Container untuk menarik image pribadi.
Jika kamu sudah menjalankan docker login, kamu dapat menyalin kredensial itu ke Kubernetes:
kubectl create secret generic regcred \
--from-file=.dockerconfigjson=<path/to/.docker/config.json> \
--type=kubernetes.io/dockerconfigjson
Jika kamu memerlukan lebih banyak kontrol (misalnya, untuk mengatur Namespace atau label baru pada Secret) maka kamu dapat menyesuaikan Secret tersebut sebelum menyimpannya. Pastikan untuk:
.dockerconfigjsondata[".dockerconfigjson"]type menjadi kubernetes.io/dockerconfigjsonSebagai contoh:
apiVersion: v1
kind: Secret
metadata:
name: myregistrykey
namespace: awesomeapps
data:
.dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg==
type: kubernetes.io/dockerconfigjson
Jika kamu mendapat pesan kesalahan error: no objects passed to create, ini berarti pengkodean base64 dari urutan huruf tersebut tidak valid.
Jika kamu mendapat pesan kesalahan seperti Secret "myregistrykey" is invalid: data[.dockerconfigjson]: invalid value ..., ini berarti
enkode base64 dari urutan huruf dalam data tersebut sukses didekodekan, tetapi tidak bisa diuraikan menjadi berkas .docker/config.json.
Buatlah Secret ini, dan berilah nama regcred:
kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
dimana:
<your-registry-server> merupakan FQDN dari register privat Docker kamu. (https://index.docker.io/v1/ untuk DockerHub)<your-name> adalah nama pengguna Docker kamu.<your-pword> adalah kata sandi Docker kamu.<your-email> adalah alamat email Docker kamu.Kamu telah berhasil mengatur kredensial untuk Docker kamu pada klaster sebagai sebuah Secret yang dipanggil dengan nama regcred.
kubectl sedang berjalan.regcredUntuk memahami isi Secret regcred yang baru saja kamu buat, mulailah dengan melihat Secret dalam format YAML:
kubectl get secret regcred --output=yaml
Keluarannya akan seperti ini:
apiVersion: v1
kind: Secret
metadata:
...
name: regcred
...
data:
.dockerconfigjson: eyJodHRwczovL2luZGV4L ... J0QUl6RTIifX0=
type: kubernetes.io/dockerconfigjson
Nilai dari bidang .dockerconfigjson merupakan representasi dalam base64 dari kredensial Docker kamu.
Untuk memahami apa yang ada dalam bidang .dockerconfigjson, ubahlah data Secret menjadi format yang bisa terbaca:
kubectl get secret regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
Keluarannya akan seperti ini:
{"auths":{"your.private.registry.example.com":{"username":"janedoe","password":"xxxxxxxxxxx","email":"jdoe@example.com","auth":"c3R...zE2"}}}
Untuk memahami apa yang ada dalam bidang auth, ubahlah data Secret menjadi format yang bisa terbaca:
echo "c3R...zE2" | base64 --decode
Keluarannya, nama pengguna dan kata sandi yang digabungkan dengan tanda :, seperti dibawah ini:
janedoe:xxxxxxxxxxx
Perhatikan bahwa data Secret berisi token otorisasi yang serupa dengan berkas ~/.docker/config.json lokal kamu.
Kamu telah berhasil menetapkan kredensial Docker kamu sebagai sebuah Secret yang dipanggil dengan regcred pada klaster.
Berikut ini adalah berkas konfigurasi untuk Pod yang memerlukan akses ke kredensial Docker kamu pada regcred:
apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image: <image-pribadi-kamu>
imagePullSecrets:
- name: regcred
Unduh berkas diatas:
wget -O my-private-reg-pod.yaml https://k8s.io/examples/pods/private-reg-pod.yaml
Dalam berkas my-private-reg-pod.yaml, ubah <your-private-image> dengan tautan ke image dalam register pribadi seperti ini:
your.private.registry.example.com/janedoe/jdoe-private:v1
Untuk menarik image dari register pribadi, Kubernetes memerlukan kredensial.
Bidang imagePullSecrets dalam berkas konfigurasi menentukan bahwa Kubernetes harus mendapatkan kredensial dari Secret yang bernama regcred.
Buatlah Pod yang menggunakan Secret kamu, dan verifikasi bahwa Pod tersebut berjalan:
kubectl apply -f my-private-reg-pod.yaml
kubectl get pod private-reg
imagePullSecrets dari PodSpec.Laman ini memperlihatkan bagaimana cara untuk mengatur probe liveness, readiness, dan startup untuk Container.
Probe liveness digunakan oleh kubelet untuk mengetahui kapan perlu mengulang kembali (restart) sebuah Container. Sebagai contoh, probe liveness dapat mendeteksi deadlock, ketika aplikasi sedang berjalan tapi tidak dapat berfungsi dengan baik. Mengulang Container dengan state tersebut dapat membantu ketersediaan aplikasi yang lebih baik walaupun ada kekutu (bug).
Probe readiness digunakan oleh kubelet untuk mengetahui kapan sebuah Container telah siap untuk menerima lalu lintas jaringan (traffic). Suatu Pod dianggap siap saat semua Container di dalamnya telah siap. Sinyal ini berguna untuk mengontrol Pod-Pod mana yang digunakan sebagai backend dari Service. Ketika Pod dalam kondisi tidak siap, Pod tersebut dihapus dari Service load balancer.
Probe startup digunakan oleh kubelet untuk mengetahui kapan sebuah aplikasi Container telah mulai berjalan. Jika probe tersebut dinyalakan, probe akan menonaktifkan pemeriksaan liveness dan readiness sampai berhasil, kamu harus memastikan probe tersebut tidak mengganggu startup dari aplikasi. Mekanisme ini dapat digunakan untuk mengadopsi pemeriksaan liveness pada saat memulai Container yang lambat, untuk menghindari Container dimatikan oleh kubelet sebelum Container mulai dan berjalan.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Kebanyakan aplikasi yang telah berjalan dalam waktu lama pada akhirnya akan bertransisi ke state yang rusak (broken), dan tidak dapat pulih kecuali diulang kembali. Kubernetes menyediakan probe liveness untuk mendeteksi dan memperbaiki situasi tersebut.
Pada latihan ini, kamu akan membuat Pod yang menjalankan Container dari image
registry.k8s.io/busybox. Berikut ini adalah berkas konfigurasi untuk Pod tersebut:
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: registry.k8s.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
Pada berkas konfigurasi di atas, kamu dapat melihat bahwa Pod memiliki satu Container.
Field periodSeconds menentukan bahwa kubelet harus melakukan probe liveness setiap 5 detik.
Field initialDelaySeconds memberitahu kubelet untuk menunggu 5 detik sebelum mengerjakan
probe yang pertama. Untuk mengerjakan probe, kubelet menjalankan perintah cat /tmp/healthy
pada Container tujuan. Jika perintah berhasil, kode 0 akan dikembalikan, dan kubelet menganggap
Container sedang dalam kondisi hidup (alive) dan sehat (healthy). Jika perintah mengembalikan
kode selain 0, maka kubelet akan mematikan Container dan mengulangnya kembali.
Saat dimulai, Container akan menjalankan perintah berikut:
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600"
Container memiliki berkas /tmp/healthy pada saat 30 detik pertama setelah dijalankan.
Kemudian, perintah cat /tmp/healthy mengembalikan kode sukses. Namun setelah 30 detik,
cat /tmp/healthy mengembalikan kode gagal.
Buatlah sebuah Pod:
kubectl apply -f https://k8s.io/examples/pods/probe/exec-liveness.yaml
Dalam 30 detik pertama, lihatlah event dari Pod:
kubectl describe pod liveness-exec
Keluaran dari perintah tersebut memperlihatkan bahwa belum ada probe liveness yang gagal:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "registry.k8s.io/busybox"
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "registry.k8s.io/busybox"
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
Setelah 35 detik, lihatlah lagi event Pod tersebut:
kubectl describe pod liveness-exec
Baris terakhir dari keluaran tersebut memperlihatkan pesan bahwa probe liveness mengalami kegagalan, dan Container telah dimatikan dan dibuat ulang.
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "registry.k8s.io/busybox"
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "registry.k8s.io/busybox"
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
Tunggu 30 detik lagi, dan verifikasi bahwa Container telah diulang kembali:
kubectl get pod liveness-exec
Keluaran perintah tersebut memperlihatkan bahwa jumlah RESTARTS telah meningkat:
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 1 1m
Jenis kedua dari probe liveness menggunakan sebuah permintaan GET HTTP. Berikut ini
berkas konfigurasi untuk Pod yang menjalankan Container dari image registry.k8s.io/e2e-test-images/agnhost.
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: registry.k8s.io/e2e-test-images/agnhost:2.40
args:
- liveness
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
Pada berkas konfigurasi tersebut, kamu dapat melihat Pod memiliki sebuah Container.
Field periodSeconds menentukan bahwa kubelet harus mengerjakan probe liveness setiap 3 detik.
Field initialDelaySeconds memberitahu kubelet untuk menunggu 3 detik sebelum mengerjakan
probe yang pertama. Untuk mengerjakan probe tersebut, kubelet mengirimkan sebuah permintaan
GET HTTP ke server yang sedang berjalan di dalam Container dan mendengarkan (listen) pada porta 8080.
Jika handler path /healthz yang dimiliki server mengembalikan kode sukses, kubelet menganggap
Container sedang dalam kondisi hidup dan sehat. Jika handler mengembalikan kode gagal,
kubelet mematikan Container dan mengulangnya kembali.
Kode yang lebih besar atau sama dengan 200 dan kurang dari 400 mengindikasikan kesuksesan. Kode selain ini mengindikasikan kegagalan.
Kamu dapat melihat kode program untuk server ini pada server.go.
Untuk 10 detik pertama setelah Container hidup (alive), handler /healthz mengembalikan
status 200. Setelah itu, handler mengembalikan status 500.
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
duration := time.Now().Sub(started)
if duration.Seconds() > 10 {
w.WriteHeader(500)
w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds())))
} else {
w.WriteHeader(200)
w.Write([]byte("ok"))
}
})
Pemeriksaan kesehatan (health check) dilakukan kubelet 3 detik setelah Container dimulai, sehingga beberapa pemeriksaaan pertama akan berhasil. Namun setelah 10 detik, pemeriksaan akan gagal, dan kubelet akan mematikan dan mengulang Container kembali.
Untuk mencoba pemeriksaan liveness HTTP, marilah membuat sebuah Pod:
kubectl apply -f https://k8s.io/examples/pods/probe/http-liveness.yaml
Setelah 10 detik, lihatlah event Pod untuk memverifikasi bahwa probe liveness telah gagal dan Container telah diulang kembali:
kubectl describe pod liveness-http
Untuk rilis sebelum v1.13 (termasuk v1.13), jika variabel lingkungan
http_proxy (atau HTTP_PROXY) telah diatur pada Node dimana Pod
berjalan, probe liveness HTTP akan menggunakan proksi tersebut.
Untuk rilis setelah v1.13, pengaturan variabel lingkungan pada proksi HTTP lokal
tidak mempengaruhi probe liveness HTTP.
Jenis ketiga dari probe liveness menggunakaan sebuah soket TCP. Dengan konfigurasi ini, kubelet akan mencoba untuk membuka soket pada Container kamu dengan porta tertentu. Jika koneksi dapat terbentuk dengan sukses, maka Container dianggap dalam kondisi sehat. Namun jika tidak berhasil terbentuk, maka Container dianggap gagal.
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: registry.k8s.io/goproxy:0.1
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
Seperti yang terlihat, konfigurasi untuk pemeriksaan TCP cukup mirip dengan
pemeriksaan HTTP. Contoh ini menggunakan probe readiness dan liveness.
Probe readiness yang pertama akan dikirimkan oleh kubelet, 5 detik setelah
Container mulai dijalankan. Container akan coba dihubungkan oleh kubelet dengan
goproxy pada porta 8080. Jika probe berhasil, maka Pod akan ditandai menjadi
ready. Pemeriksaan ini akan dilanjutkan oleh kubelet setiap 10 detik.
Selain probe readiness, probe liveness juga termasuk di dalam konfigurasi.
Probe liveness yang pertama akan dijalankan oleh kubelet, 15 detik setelah Container
mulai dijalankan. Sama seperti probe readiness, kubelet akan mencoba untuk
terhubung dengan Container goproxy pada porta 8080. Jika probe liveness gagal,
maka Container akan diulang kembali.
Untuk mencoba pemeriksaan liveness TCP, marilah membuat sebuah Pod:
kubectl apply -f https://k8s.io/examples/pods/probe/tcp-liveness-readiness.yaml
Setelah 15 detik, lihatlah event Pod untuk memverifikasi probe liveness tersebut:
kubectl describe pod goproxy
Kamu dapat menggunakan ContainerPort dengan nama untuk melakukan pemeriksaan liveness HTTP atau TCP:
ports:
- name: liveness-port
containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
Terkadang kamu harus berurusan dengan aplikasi peninggalan (legacy) yang
memerlukan waktu tambahan untuk mulai berjalan pada saat pertama kali diinisialisasi.
Pada kasus ini, cukup rumit untuk mengatur parameter probe liveness tanpa
mengkompromikan respons yang cepat terhadap deadlock yang memotivasi digunakannya
probe_ tersebut. Triknya adalah mengatur probe startup dengan perintah yang sama,
baik pemeriksaan HTTP ataupun TCP, dengan failureThreshold * periodSeconds yang
mencukupi untuk kemungkinan waktu memulai yang terburuk.
Sehingga, contoh sebelumnya menjadi:
ports:
- name: liveness-port
containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 1
periodSeconds: 10
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10
Berkat probe startup, aplikasi akan memiliki paling lambat 5 menit (30 * 10 = 300 detik)
untuk selesai memulai.
Ketika probe startup telah berhasil satu kali, maka probe liveness akan
mengambil alih untuk menyediakan respons cepat terhadap deadlock Container.
Jika probe startup tidak pernah berhasil, maka Container akan dimatikan setelah
300 detik dan perilakunya akan bergantung pada restartPolicy yang dimiliki Pod.
Terkadang aplikasi tidak dapat melayani lalu lintas jaringan sementara. Contohnya, aplikasi mungkin perlu untuk memuat data besar atau berkas konfigurasi saat dimulai, atau aplikasi bergantung pada layanan eksternal setelah dimulai. Pada kasus-kasus ini, kamu tidak ingin mematikan aplikasi, tetapi kamu tidak ingin juga mengirimkan permintaan ke aplikasi tersebut. Kubernetes menyediakan probe readiness sebagai solusinya. Sebuah Pod dengan Container yang melaporkan dirinya tidak siap, tidak akan menerima lalu lintas jaringan dari Kubernetes Service.
Probe readiness memiliki pengaturan yang mirip dengan probe liveness. Perbedaan
satu-satunya adalah kamu menggunakan field readinessProbe, bukan field livenessProbe.
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
Pengaturan untuk probe readiness untuk HTTP dan TCP juga sama persis dengan pengaturan untuk probe liveness.
Probe readiness dan liveness dapat digunakan secara bersamaan untuk Container yang sama. Apabila keduanya digunakan sekaligus, lalu lintas jaringan tidak akan sampai ke Container yang belum siap, dan Container akan diulang kembali (restart) saat mengalami kegagalan.
Probe memiliki beberapa field yang dapat digunakan untuk mengendalikan pemeriksaan liveness dan readiness secara presisi.
initialDelaySeconds: Durasi dalam detik setelah Container dimulai,
sebelum probe liveness atau readiness diinisiasi. Nilai bawaannya adalah 0 detik. Nilai minimalnya adalah 0.periodSeconds: Seberapa sering (dalam detik) probe dijalankan. Nilai bawaannya adalah 10 detik.
Nilai minimalnya adalah 0.timeoutSeconds: Durasi dalam detik setelah probe mengalami timeout. Nilai bawaannya adalah 1 detik.
Nilai minimalnya adalah 0.successThreshold: Jumlah minimal sukses yang berurutan untuk probe dianggap berhasil
setelah mengalami kegagalan. Nilai bawaannya adalah 1. Nilanya harus 1 untuk liveness.
Nilai minimalnya adalah 1.failureThreshold: Ketika sebuah Pod dimulai dan probe mengalami kegagalan, Kubernetes
akan mencoba beberapa kali sesuai nilai failureThreshold sebelum menyerah. Menyerah dalam
kasus probe liveness berarti Container akan diulang kembali. Untuk probe readiness, menyerah
akan menandai Pod menjadi "tidak siap" (Unready). Nilai bawaannya adalah 3. Nilai minimalnya adalah 1.Probe HTTP
memiliki field-field tambahan yang bisa diatur melalui httpGet:
host: Nama dari host yang akan terhubung, nilai bawaannya adalah IP dari Pod. Kamu mungkin
juga ingin mengatur "Host" pada httpHeaders.scheme: Skema yang digunakan untuk terhubung pada host (HTTP atau HTTPS). Nilai bawaannya adalah HTTP.path: Path untuk mengakses server HTTP.httpHeaders: Header khusus yang diatur dalam permintaan HTTP. HTTP memperbolehkan header yang berulang.port: Nama atau angka dari porta untuk mengakses Container. Angkanya harus ada di antara 1 sampai 65535.Untuk sebuah probe HTTP, kubelet mengirimkan permintaan HTTP untuk path yang ditentukan
dan porta untuk mengerjakan pemeriksaan. Probe dikirimkan oleh kubelet untuk alamat IP Pod,
kecuali saat alamat digantikan oleh field opsional pada httpGet. Jika field scheme
diatur menjadi HTTPS, maka kubelet mengirimkan permintaan HTTPS dan melewati langkah verifikasi
sertifikat. Pada skenario kebanyakan, kamu tidak menginginkan field host.
Berikut satu skenario yang memerlukan host. Misalkan Container mendengarkan permintaan
melalui 127.0.0.1 dan field hostNetwork pada Pod bernilai true. Kemudian host, melalui
httpGet, harus diatur menjadi 127.0.0.1. Jika Pod kamu bergantung pada host virtual, dimana
untuk kasus-kasus umum, kamu tidak perlu menggunakan host, tetapi perlu mengatur header
Host pada httpHeaders.
Untuk probe TCP, kubelet membuat koneksi probe pada Node, tidak pada Pod, yang berarti bahwa
kamu tidak menggunakan nama Service di dalam parameter host karena kubelet tidak bisa
me-resolve-nya.
Kamu juga dapat membaca rujukan API untuk:
Dokumen ini menunjukkan cara menempatkan Pod Kubernetes pada sebuah Node menggunakan Afinitas Node di dalam klaster Kubernetes.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Kubernetes servermu harus dalam versi yang sama atau lebih baru dari v1.10.Untuk melihat versi, tekan kubectl version.
Jabarkan Node-Node yang ada pada klaster kamu, bersamaan dengan label yang ada:
kubectl get nodes --show-labels
Keluaran dari perintah tersebut akan berupa:
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
Pilihkan salah satu dari Node yang ada dan tambahkan label pada Node tersebut.
kubectl label nodes <nama-node-kamu> disktype=ssd
dimana <nama-node-kamu> merupakan nama dari Node yang kamu pilih.
Keluaran dari Node yang kamu pilih dan sudah memiliki label disktype=ssd:
kubectl get nodes --show-labels
Keluaran dari perintah tersebut akan berupa:
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,disktype=ssd,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
Pada keluaran dari perintah di atas, kamu dapat melihat bahwa Node worker0
memiliki label disktype=ssd.
Konfigurasi ini menunjukkan sebuah Pod yang memiliki afinitas node requiredDuringSchedulingIgnoredDuringExecution, disktype: ssd.
Dengan kata lain, Pod hanya akan dijadwalkan hanya pada Node yang memiliki label disktype=ssd.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
Terapkan konfigurasi berikut untuk membuat sebuah Pod yang akan dijadwalkan pada Node yang kamu pilih:
kubectl apply -f https://k8s.io/examples/pods/pod-nginx-required-affinity.yaml
Verifikasi apakah Pod yang kamu pilih sudah dijalankan pada Node yang kamu pilih:
kubectl get pods --output=wide
Keluaran dari perintah tersebut akan berupa:
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
Konfigurasi ini memberikan deskripsi sebuah Pod yang memiliki afinitas Node preferredDuringSchedulingIgnoredDuringExecution,disktype: ssd.
Artinya Pod akan diutamakan dijalankan pada Node yang memiliki label disktype=ssd.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
Terapkan konfigurasi berikut untuk membuat sebuah Pod yang akan dijadwalkan pada Node yang kamu pilih:
kubectl apply -f https://k8s.io/examples/pods/pod-nginx-preferred-affinity.yaml
Verifikasi apakah Pod yang kamu pilih sudah dijalankan pada Node yang kamu pilih:
kubectl get pods --output=wide
Keluaran dari perintah tersebut akan berupa:
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
Pelajari lebih lanjut mengenai Afinitas Node.
ConfigMap mengizinkan kamu untuk memisahkan artifak-artifak konfigurasi dari konten image untuk menjaga aplikasi yang dikontainerisasi tetap portabel. Artikel ini menyediakan sekumpulan contoh penerapan yang mendemonstrasikan bagaimana cara membuat ConfigMap dan mengatur Pod menggunakan data yang disimpan di dalam ConfigMap.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Kamu dapat menggunakan kubectl create configmap ataupun generator ConfigMap pada kustomization.yaml untuk membuat sebuah ConfigMap. Perlu diingat bahwa kubectl mulai mendukung kustomization.yaml sejak versi 1.14.
Gunakan perintah kubectl create configmap untuk membuat ConfigMap dari direktori, berkas, ataupun nilai-nilai yang harfiah (literal values):
kubectl create configmap <map-name> <data-source>
di mana <map-name> merupakan nama yang ingin kamu berikan pada ConfigMap tersebut dan <data-source> adalah direktori, berkas, atau nilai harfiah yang digunakan sebagai sumber data. Nama dari sebuah objek ConfigMap haruslah berupa nama subdomain DNS yang sah.
Ketika kamu membuat ConfigMap dari sebuah berkas, secara bawaan, basename dari berkas tersebut akan menjadi kunci pada <data-source>, dan isi dari berkas tersebut akan menjadi nilai dari kunci tersebut.
Kamu dapat menggunakan kubectl describe atau
kubectl get untuk mengambil informasi
mengenai sebuah ConfigMap.
Kamu dapat menggunakan kubectl create configmap untuk membuat sebuah ConfigMap dari banyak berkas dalam sebuah direktori yang sama. Ketika kamu membuat sebuah ConfigMap dari sebuah direktori, kubectl akan mengidentifikasi berkas-berkas yang memiliki basename yang merupakan sebuah kunci yang sah pada direktori dan mengemas tiap berkas tersebut ke dalam sebuah ConfigMap baru. Seluruh entri direktori kecuali berkas reguler akan diabaikan (subdirektori, symlink, device, pipe, dsb).
Sebagai contoh:
# Membuat direktori lokal
mkdir -p configure-pod-container/configmap/
# Mengunduh berkas-berkas sampel ke dalam direktori `configure-pod-container/configmap/`
wget https://kubernetes.io/examples/configmap/game.properties -O configure-pod-cont1ainer/configmap/game.properties
wget https://kubernetes.io/examples/configmap/ui.properties -O configure-pod-container/configmap/ui.properties
# Membuat configmap
kubectl create configmap game-config --from-file=configure-pod-container/configmap/
Perintah di atas mengemas tiap berkas, dalam kasus ini, game.properties dan ui.properties dalam direktori configure-pod-container/configmap/ ke dalam ConfigMap dengan nama game-config. Kamu dapat menampilkan detail dari ConfigMap menggunakan perintah berikut:
kubectl describe configmaps game-config
Keluaran akan tampil seperti berikut:
Name: game-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties:
----
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
Berkas-berkas game.properties dan ui.properties pada direktori configure-pod-container/configmap/ direpresentasikan oleh bagian data pada ConfigMap.
kubectl get configmaps game-config -o yaml
Keluaran akan tampil seperti berikut:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T18:52:05Z
name: game-config
namespace: default
resourceVersion: "516"
uid: b4952dc3-d670-11e5-8cd0-68f728db1985
data:
game.properties: |
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
Kamu dapat menggunakan kubectl create configmap untuk membuat sebuah ConfigMap dari berkas individual, atau dari banyak berkas.
Sebagai contoh,
kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties
akan menghasilkan ConfigMap berikut:
kubectl describe configmaps game-config-2
dengan keluaran seperti berikut:
Name: game-config-2
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
Kamu dapat memasukkan argumen --from-file beberapa kali untuk membuat sebuah ConfigMap dari banyak sumber data.
kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties --from-file=configure-pod-container/configmap/ui.properties
Kamu dapat menampilkan detail dari ConfigMap game-config-2 menggunakan perintah berikut:
kubectl describe configmaps game-config-2
Keluaran akan tampil seperti berikut:
Name: game-config-2
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties:
----
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
Gunakan opsi --from-env-file untuk membuat sebuah ConfigMap dari sebuah env-file, sebagai contoh:
# Env-file berisi sebuah daftar variabel _environment_.
# Ada aturan-aturan sintaks yang berlaku:
# Tiap baris pada sebuah env file harus memiliki format VAR=VAL.
# Baris yang diawali # (komentar) akan diabaikan.
# Baris-baris kosong akan diabaikan.
# Tidak ada penanganan spesial untuk tanda kutip (tanda kutip akan menjadi bagian dari nilai pada ConfigMap).
# Mengunduh berkas-berkas sampel berikut ke dalam direktori `configure-pod-container/configmap/`
wget https://kubernetes.io/examples/configmap/game-env-file.properties -O configure-pod-container/configmap/game-env-file.properties
# Berkas env-file `game-env-file.properties` berisi sebagai berikut:
cat configure-pod-container/configmap/game-env-file.properties
enemies=aliens
lives=3
allowed="true"
# Komentar ini dan baris kosong di atasnya akan diabaikan.
kubectl create configmap game-config-env-file \
--from-env-file=configure-pod-container/configmap/game-env-file.properties
akan menghasilkan ConfigMap sebagai berikut:
kubectl get configmap game-config-env-file -o yaml
dengan keluaran seperti berikut:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2017-12-27T18:36:28Z
name: game-config-env-file
namespace: default
resourceVersion: "809965"
uid: d9d1ca5b-eb34-11e7-887b-42010a8002b8
data:
allowed: '"true"'
enemies: aliens
lives: "3"
--from-env-file beberapa kali untuk membuat sebuah ConfigMap dari beberapa sumber data, hanya env-file terakhir yang akan digunakan.Contoh perilaku memasukkan --from-env-file beberapa kali didemonstrasikan dengan:
# Mengunduh berkas-berkas sampel berikut ke dalam direktori `configure-pod-container/configmap/`
wget https://kubernetes.io/examples/configmap/ui-env-file.properties -O configure-pod-container/configmap/ui-env-file.properties
# Membuat configmap
kubectl create configmap config-multi-env-files \
--from-env-file=configure-pod-container/configmap/game-env-file.properties \
--from-env-file=configure-pod-container/configmap/ui-env-file.properties
akan menghasilkan ConfigMap sebagai berikut:
kubectl get configmap config-multi-env-files -o yaml
dengan keluaran seperti berikut:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2017-12-27T18:38:34Z
name: config-multi-env-files
namespace: default
resourceVersion: "810136"
uid: 252c4572-eb35-11e7-887b-42010a8002b8
data:
color: purple
how: fairlyNice
textmode: "true"
Kamu dapat menentukan kunci selain dari nama berkas untuk digunakan pada bagian data pada ConfigMap yang kamu buat menggunakan argumen --from-file:
kubectl create configmap game-config-3 --from-file=<my-key-name>=<path-to-file>
di mana <my-key-name> merupakan kunci yang ingin kamu gunakan pada ConfigMap dan <path-to-file> merupakan lokasi dari berkas sumber data yang akan menjadi nilai dari kunci tersebut.
Sebagai contoh:
kubectl create configmap game-config-3 --from-file=game-special-key=configure-pod-container/configmap/game.properties
akan menghasilkan ConfigMap sebagai berikut:
kubectl get configmaps game-config-3 -o yaml
dengan keluaran seperti berikut:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T18:54:22Z
name: game-config-3
namespace: default
resourceVersion: "530"
uid: 05f8da22-d671-11e5-8cd0-68f728db1985
data:
game-special-key: |
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
Kamu dapat menggunakan kubectl create configmap dengan argumen --from-literal untuk menentukan nilai harfiah dari baris perintah:
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
Kamu dapat memasukkan beberapa pasang kunci-nilai. Tiap pasang yang dimasukkan pada command line direpresentasikan sebagai sebuah entri terpisah pada bagian data dari ConfigMap.
kubectl get configmaps special-config -o yaml
Keluaran akan tampil seperti berikut:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T19:14:38Z
name: special-config
namespace: default
resourceVersion: "651"
uid: dadce046-d673-11e5-8cd0-68f728db1985
data:
special.how: very
special.type: charm
kubectl mendukung kustomization.yaml sejak versi 1.14.
Kamu juga dapat membuat ConfigMap dari generator lalu menggunakannya untuk membuat objek tersebut pada
peladen API. Generator
harus dituliskan pada kustomization.yaml dalam sebuah direktori.
Sebagai contoh, untuk menghasilkan ConfigMap dari berkas configure-pod-container/configmap/game.properties
# Membuat berkas kustomization.yaml dengan ConfigMapGenerator
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: game-config-4
files:
- configure-pod-container/configmap/game.properties
EOF
Gunakan direktori kustomization untuk membuat objek ConfigMap.
kubectl apply -k .
configmap/game-config-4-m9dm2f92bt created
Kamu dapat melihat ConfigMap yang dihasilkan seperti berikut:
kubectl get configmap
NAME DATA AGE
game-config-4-m9dm2f92bt 1 37s
kubectl describe configmaps/game-config-4-m9dm2f92bt
Name: game-config-4-m9dm2f92bt
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","data":{"game.properties":"enemies=aliens\nlives=3\nenemies.cheat=true\nenemies.cheat.level=noGoodRotten\nsecret.code.p...
Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
Events: <none>
Perlu diingat baha nama dari ConfigMap yang dihasilkan memiliki sufiks yang ditambahkan dengan melakukan hashing terhadap konten dari ConfigMap tersebut. Hal ini memastikan bahwa sebuah ConfigMap baru akan dihasilkan setiap kali konten dimodifikasi.
Kamu dapat menentukan kunci selain nama berkas untuk digunakan pada generator ConfigMap.
Sebagai contoh, untuk menghasilkan sebuah ConfigMap dari berkas configure-pod-container/configmap/game.properties
dengan kunci game-special-key
# Membuat berkas kustomization.yaml dengan ConfigMapGenerator
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: game-config-5
files:
- game-special-key=configure-pod-container/configmap/game.properties
EOF
Gunakan direktori kustomization untuk membuat objek ConfigMap.
kubectl apply -k .
configmap/game-config-5-m67dt67794 created
Untuk menghasilkan ConfigMap dari nilai-nilai harfiah special.type=charm dan special.how=very,
kamu dapat menentukan generator ConfigMap pada kustomization.yaml sebagai berikut
# Membuat berkas kustomization.yaml dengan ConfigMapGenerator
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: special-config-2
literals:
- special.how=very
- special.type=charm
EOF
Gunakan direktori kustomization untuk membuat objek ConfigMap.
kubectl apply -k .
configmap/special-config-2-c92b5mmcf2 created
Menentukan sebuah variabel environment sebagai sepasang kunci-nilai pada ConfigMap:
kubectl create configmap special-config --from-literal=special.how=very
Memberikan nilai special.how yang sudah terdapat pada ConfigMap pada variabel environment SPECIAL_LEVEL_KEY di spesifikasi Pod.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
# Tentukan variabel environment
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
# ConfigMap berisi nilai yang ingin kamu berikan pada SPECIAL_LEVEL_KEY
name: special-config
# Tentukan kunci yang diasosiasikan dengan nilainya
key: special.how
restartPolicy: Never
Buat Pod:
kubectl create -f https://kubernetes.io/id/examples/pods/pod-single-configmap-env-variable.yaml
Sekarang, keluaran dari Pod meliputi variabel environment SPECIAL_LEVEL_KEY=very.
Seperti pada contoh sebelumnya, buat ConfigMap terlebih dahulu.
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
---
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config
namespace: default
data:
log_level: INFO
Buat ConfigMap:
kubectl create -f https://kubernetes.io/examples/configmap/configmaps.yaml
Tentukan variabel environment pada spesifikasi Pod.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.how
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: env-config
key: log_level
restartPolicy: Never
Buat Pod:
kubectl create -f https://kubernetes.io/id/examples/pods/pod-multiple-configmap-env-variable.yaml
Sekarang, keluaran Pod meliputi variabel environment SPECIAL_LEVEL_KEY=very dan LOG_LEVEL=INFO.
Buat ConfigMap yang berisi beberapa pasangan kunci-nilai.
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm
Buat ConfigMap:
kubectl create -f https://kubernetes.io/examples/configmap/configmap-multikeys.yaml
envFrom untuk menentukan seluruh data pada ConfigMap sebagai variabel environment kontainer. Kunci dari ConfigMap akan menjadi nama variabel environment di dalam Pod.apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: special-config
restartPolicy: Never
Buat Pod:
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-envFrom.yaml
Sekarang, Pod keluaran pod meliputi variabel environment SPECIAL_LEVEL=very dan SPECIAL_TYPE=charm.
Kamu dapat menggunakan variabel environment yang ditentukan ConfigMap pada bagian command dari spesifikasi Pod menggunakan sintaks substitusi Kubernetes $(VAR_NAME).
Sebagai contoh, spesifikasi Pod berikut
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: SPECIAL_LEVEL
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: SPECIAL_TYPE
restartPolicy: Never
dibuat dengan menjalankan
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-env-var-valueFrom.yaml
menghasilkan keluaran pada kontainer test-container seperti berikut:
kubectl logs dapi-test-pod
very charm
Seperti yang sudah dijelaskan pada Membuat ConfigMap dari berkas, ketika kamu membuat ConfigMap menggunakan --from-file, nama dari berkas tersebut akan menjadi kunci yang disimpan pada bagian data dari ConfigMap. Isi berkas tersebut akan menjadi nilai dari kunci tersebut.
Contoh pada bagian ini merujuk pada ConfigMap bernama special-config, Seperti berikut.
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm
Buat ConfigMap:
kubectl create -f https://kubernetes.io/examples/configmap/configmap-multikeys.yaml
Tambahkan nama ConfigMap di bawah bagian volumes pada spesifikasi Pod.
Hal ini akan menambahkan data ConfigMap pada direktori yang ditentukan oleh volumeMounts.mountPath (pada kasus ini, /etc/config).
Bagian command berisi daftar berkas pada direktori dengan nama-nama yang sesuai dengan kunci-kunci pada ConfigMap.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "ls /etc/config/" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
# Berikan nama dari ConfigMap yang berisi berkas-berkas yang ingin kamu
# tambahkan ke kontainer
name: special-config
restartPolicy: Never
Buat Pod:
kubectl create -f https://kubernetes.io/i/examples/pods/pod-configmap-volume.yaml
Ketika Pod berjalan, perintah ls /etc/config/ akan menghasilkan keluaran di bawah:
SPECIAL_LEVEL
SPECIAL_TYPE
/etc/config/, berkas-berkas tersebut akan dihapus.Gunakan kolom path untuk menentukan jalur berkas yang diinginkan untuk butir tertentu pada ConfigMap (butir ConfigMap tertentu).
Pada kasus ini, butir SPECIAL_LEVEL akan akan dipasangkan sebagai config-volume pada /etc/config/keys.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh","-c","cat /etc/config/keys" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
items:
- key: SPECIAL_LEVEL
path: keys
restartPolicy: Never
Buat Pod:
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-volume-specific-key.yaml
Ketika Pod berjalan, perintah cat /etc/config/keys akan menghasilkan keluaran di bawah:
very
/etc/config/ akan dihapus.Kamu dapat memproyeksikan kunci ke jalur dan perizinan tertentu pada setiap berkas. Panduan pengguna Secret menjelaskan mengenai sintaks-sintaksnya.
Ketika sebuah ConfigMap yang sudah dipasang pada sebuah volume diperbarui, kunci-kunci yang diproyeksikan akan turut diperbarui. Kubelet akan memeriksa apakah ConfigMap yang dipasang merupakan yang terbaru pada sinkronisasi berkala. Namun, ConfigMap menggunakan cache lokal berbasis ttl (time-to-live) miliknya untuk mendapatkan nilai dari ConfigMap saat ini. Hasilnya, keseluruhan penundaan dari saat ketika ConfigMap diperbarui sampai saat ketika kunci-kunci baru diproyeksikan ke pada Pod bisa selama periode sinkronisasi kubelet (secara bawaan selama 1 menit) + ttl dari cache ConfigMap (secara bawaan selama 1 menit) pada kubelet. Kamu dapat memicu pembaruan langsung dengan memperbarui salah satu dari anotasi Pod.
Sumber daya API ConfigMap menyimpan data konfigurasi sebagai pasangan kunci-nilai. Data tersebut dapat dikonsumsi oleh Pod atau sebagai penyedia konfigurasi untuk komponen-komponen sistem seperti kontroler. ConfigMap mirip dengan Secret, tetapi ConfigMap dimaksudkan untuk mengolah tulisan yang tidak memiliki informasi yang sensitif. Baik pengguna maupun komponen sistem dapat menyimpan data konfigurasi pada ConfigMap.
/etc beserta isinya pada Linux. Sebagai contoh, jika kamu membuat sebuah Volume Kubernetes dari ConfigMap, tiap butir data pada ConfigMap direpresentasikan sebagai sebuah berkas pada volume.Kolom data pada ConfigMap berisi data konfigurasi. Seperti pada contoh di bawah, hal ini bisa berupa sesuatu yang sederhana -- seperti properti individual yang ditentukan menggunakan --from-literal -- atau sesuatu yang kompleks -- seperti berkas konfigurasi atau blob JSON yang ditentukan dengan --from-file.
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T19:14:38Z
name: example-config
namespace: default
data:
# contoh properti yang sederhana yang ditentukan menggunakan --from-literal
example.property.1: hello
example.property.2: world
# contoh properti yang kompleks yang ditentukan menggunakan --from-file
example.property.file: |-
property.1=value-1
property.2=value-2
property.3=value-3
Kamu harus membuat ConfigMap sebelum merujuknya pada spesifikasi Pod (kecuali kamu menandai ConfigMap sebagai "optional"). Jika kamu merujuk sebuah ConfigMap yang tidak ada, Pod tersebut tidak akan berjalan. Sama halnya, mereferensikan kunci yang tidak ada pada ConfigMap akan mencegah Pod untuk berjalan.
Jika kamu menggunakan envFrom untuk menentukan variabel environment dari ConfigMap, kunci-kunci yang dianggap tidak sah akan dilewat. Pod akan diizinkan untuk berjalan, tetapi nama-nama yang tidak sah akan direkam pada event log (InvalidVariableNames). Pesan log tersebut mencantumkan tiap kunci yang dilewat. Sebagai contoh:
kubectl get events
Keluaran akan tampil seperti berikut:
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE
0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames {kubelet, 127.0.0.1} Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names.
ConfigMap berada pada Namespace tertentu. ConfigMap hanya dapat dirujuk oleh Pod yang berada pada Namespace yang sama.
Kamu tidak dapat menggunakan ConfigMap untuk Pod statis, karena Kubelet tidak mendukung hal ini.
Kubernetes v1.17 [stable]
Dokumen ini akan menjelaskan menkanisme konfigurasi pembagian namespace process dalam sebuah Pod. Ketika pembagian namespace proses diaktifkan untuk sebuah Pod, proses yang ada di dalam Container akan bersifat transparan pada semua Container yang terdapat di dalam Pod tersebut.
Kamu dapat mengaktifkan fitur ini untuk melakukan konfigurasi kontainer yang saling terhubung, misalnya saja kontainer sidecar yang bertugas dalam urusan log, atau untuk melakukan proses pemecahan masalah (troubleshoot) image kontainer yang tidak memiliki utilitas debugging seperti shell.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Kubernetes servermu harus dalam versi yang sama atau lebih baru dari v1.10.Untuk melihat versi, tekan kubectl version.
Pembagian namespace proses (Process Namespace Sharing) diaktifkan menggunakan field shareProcessNamespace
v1.PodSpec. Sebagai contoh:
Buatlah sebuah Pod nginx di dalam klaster kamu:
kubectl apply -f https://k8s.io/examples/pods/share-process-namespace.yaml
Tempelkan kontainer shell dan jalankan perintah ps:
kubectl exec -it nginx -c shell -- /bin/sh
Jika kamu tidak melihat prompt perintah, kamu dapat menekan tombol enter:
/ # ps ax
PID USER TIME COMMAND
1 root 0:00 /pause
8 root 0:00 nginx: master process nginx -g daemon off;
14 101 0:00 nginx: worker process
15 root 0:00 sh
21 root 0:00 ps ax
Kamu dapat memberikan sinyal pada kontainer lain. Misalnya saja, mengirim sinyal SIGHUP pada
nginx untuk menjalankan ulang proses worker. Hal ini membutuhkan kapabilitas SYS_PTRACE.
/ # kill -HUP 8
/ # ps ax
PID USER TIME COMMAND
1 root 0:00 /pause
8 root 0:00 nginx: master process nginx -g daemon off;
15 root 0:00 sh
22 101 0:00 nginx: worker process
23 root 0:00 ps ax
Hal ini juga merupakan alasan mengapa kita dapat mengakses kontainer lain menggunakan
tautan (link) /proc/$pid/root.
/ # head /proc/8/root/etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
Pod berbagi banyak sumber daya yang ada sehingga memungkinkan adanya pembagian namespace proses. Beberapa image kontainer bisa jadi terisolasi dari kontainer lainnya, meskipun begitu, memahami beberapa perbedaan berikut juga merupakan hal yang penting untuk diketahui:
Proses kontainer tidak lagi memiliki PID 1. Beberapa image kontainer akan menolak
untuk dijalankan (contohnya, kontainer yang menggunakan systemd) atau menjalankan
perintah seperti kill -HUP 1 untuk memberikan sinyal pada proses kontainer. Di dalam Pod dengan
sebuah namespace process terbagi, sinyal kill -HUP 1 akan diberikan pada sandbox Pod.
(/pause pada contoh di atas.)
Proses-proses yang ada akan transparan pada kontainer lain di dalam Pod. Hal ini termasuk
informasi pada /proc, seperti kata sandi yang diberikan sebagai argumen atau environment variable.
Hal ini hanya dilindungi oleh perizinan reguler Unix.
Berkas sistem (filesystem) kontainer bersifat transparan pada kontainer lain di dalam Pod melalui link
/proc/$pid/root. Hal ini memungkinkan proses debugging menjadi lebih mudah, meskipun begitu hal ini
juga berarti kata kunci (secret) yang ada di dalam filesystem juga hanya dilindungi oleh perizinan filesystem saja.
Pod statis dikelola langsung oleh daemon kubelet pada suatu Node spesifik, tanpa API server mengobservasi mereka. Tidak seperti Pod yang dikelola oleh control plane (contohnya, Deployment); kubelet akan memantau setiap Pod statis (dan menjalankan ulang jika Pod mengalami kegagalan).
Pod statis selalu terikat pada satu Kubelet di dalam Node spesifik.
Kubelet secara otomatis akan mengulang untuk membuat sebuah Pod mirror pada server API Kubernetes untuk setiap Pod statis. Ini berarti Pod yang berjalan pada Node akan terlihat oleh API server, namun tidak dapat mengontrol dari sana.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Laman ini mengasumsikan kamu menggunakan CRI-O untuk menjalankan Pod, dan Node kamu berjalan menggunakan sistem operasi Fedora. Instruksi untuk distribusi lain atau instalasi Kubernetes mungkin berbeda.
Kamu dapat mengatur Pod statis dengan menggunakan sebuah berkas konfigurasi pada file system atau sebuah berkas konfigurasi ditempatkan pada web.
Manifes adalah standar definisi Pod dalam format JSON atau YAML pada suatu direktori.
Gunakan field staticPodPath: <direktori> pada
berkas konfigurasi kubelet,
yang akan membaca direktori
secara berkala dan membuat atau menghapus Pod statis sesuai dengan berkas YAML/JSON
yang bertambah atau berkurang disana.
Catatan bahwa kubelet akan mengabaikan berkas yang diawali dengan titik (dot) ketika memindai suatu direktori.
Sebagai contoh, ini cara untuk memulai server web sederhana sebagai Pod statis:
Pilih Node yang kamu pilih untuk menjalankan Pod statis. Dalam contoh ini adalah my-node1.
ssh my-node1
Pilih sebuah direktori, katakan /etc/kubelet.d dan letakkan berkas definisi Pod untuk web server disana, contohnya /etc/kubelet.d/static-web.yaml:
# Jalankan perintah ini pada Node tempat kubelet sedang berjalan
mkdir /etc/kubelet.d/
cat <<EOF >/etc/kubelet.d/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
EOF
Atur kubelet pada Node untuk menggunakan direktori ini dengan menjalankannya menggunakan argumen --pod-manifest-path=/etc/kubelet.d/. Pada Fedora, ubah berkas /etc/kubernetes/kubelet dengan menambahkan baris berikut:
KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubelet.d/"
atau tambahkan field staticPodPath: <direktori> pada berkas konfigurasi kubelet.
Jalankan ulang kubelet. Pada Fedora, kamu dapat menjalankan:
# Jalankan perintah berikut pada Node tempat kubelet berjalan
systemctl restart kubelet
Berkas yang ditentukan pada argumen --manifest-url=<URL> akan diunduh oleh kubelet secara berkala
dan kubelet akan menginterpretasinya sebagai sebuah berkas JSON/YAML yang berisikan definisi Pod.
Mirip dengan cara kerja manifes pada filesystem,
kubelet akan mengambil manifes berdasarkan jadwal. Jika ada perubahan pada daftar
Pod statis, maka kubelet akan menerapkannya.
Untuk menggunakan cara ini:
Buat sebuah berkas YAML dan simpan pada suatu web server sehingga kamu pada memberikan URL tersebut pada kubelet.
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
Atur kubelet pada suatu Node untuk menggunakan manifes pada web ini dengan menjalankan menggunakan argumen --manifest-url=<url-manifes>. Pada Fedora, ubah pada /etc/kubernetes/kubelet untuk menambahkan baris ini:
KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=<url-manifes>"
Jalankan ulang kubelet. Pada Fedora, kamu dapat menjalankan:
# Jalankan perintah ini pada Node tempat kubelet berjalan
systemctl restart kubelet
Ketika kubelet berjalan, secara otomatis akan menjalankan semua Pod statis yang terdefinisi. Ketika kamu mendefinisikan Pod statis dan menjalankan ulang kubelet, Pod statis yang baru akan dijalankan.
Kamu dapat melihat Container yang berjalan (termasuk Pod statis) dengan menjalankan (pada Node):
# Jalankan perintah ini pada Node tempat kubelet berjalan
crictl ps
Keluarannya kira-kira seperti berikut:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f6d05272b57e nginx:latest "nginx" 8 minutes ago Up 8 minutes k8s_web.6f802af4_static-web-fk-node1_default_67e24ed9466ba55986d120c867395f3c_378e5f3c
Kamu dapat melihat Pod mirror tersebut pada API server:
kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web 1/1 Running 0 2m
Label dari Pod statis akan dibuat juga pada Pod mirror. Kamu dapat menggunakan label tersebut seperti biasa menggunakan selector, atau yang lainnya.
Kamu dapat mencoba untuk menggunakan kubelet untuk menghapus Pod mirror tersebut pada API server, namun kubelet tidak akan menghapus Pod statis:
kubectl delete pod static-web
pod "static-web" deleted
Kamu akan melihat bahwa Pod tersebut tetap berjalan:
kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web 1/1 Running 0 4s
Kembali ke Node tempat kubelet berjalan, kamu dapat mencoba menghentikan Container Docker secara manual. Kamu akan melihat, setelah beberapa saat, kubelet akan mengetahui dan akan menjalankan ulang Pod secara otomatis:
# Jalankan perintah ini pada Node tempat kubelet berjalan
crictl stop 129fd7d382018 # ganti dengan ID pada Container-mu
sleep 20
crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
89db4553e1eeb docker.io/library/nginx@sha256:... 19 seconds ago Running web 1 34533c6729106
Direktori konfigurasi (/etc/kubelet.d pada contoh kita) akan dipindai secara berkala oleh kubelet
untuk melakukan perubahan dan penambahan/pengurangan
Pod sesuai dengan penambahan/pengurangan berkas pada direktori tersebut.
# Ini mengasumsikan kamu menggunakan konfigurasi Pod statis pada _filesystem_
# Jalankan perintah ini pada Node tempat kubelet berjalan
#
mv /etc/kubernetes/manifests/static-web.yaml /tmp
sleep 20
crictl ps
# Kamu mendapatkan bahwa tidak ada Container nginx yang berjalan
mv /tmp/static-web.yaml /etc/kubernetes/manifests/
sleep 20
crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
f427638871c35 docker.io/library/nginx@sha256:... 19 seconds ago Running web 1 34533c6729106
Laman ini menunjukkan beberapa cara cepat untuk membuat klaster Calico pada Kubernetes.
Putuskan apakah kamu ingin menggelar (deploy) sebuah klaster di cloud atau di lokal.
Prasyarat: gcloud.
Untuk meluncurkan klaster GKE dengan Calico, cukup sertakan opsi --enable-network-policy.
Sintaksis
gcloud container clusters create [CLUSTER_NAME] --enable-network-policy
Contoh
gcloud container clusters create my-calico-cluster --enable-network-policy
Untuk memverifikasi penggelaran, gunakanlah perintah berikut ini.
kubectl get pods --namespace=kube-system
Pod Calico dimulai dengan kata calico. Periksa untuk memastikan bahwa statusnya Running.
Untuk membuat satu klaster Calico dengan hos tunggal dalam waktu lima belas menit dengan menggunakan kubeadm, silakan merujuk pada
Setelah klaster kamu berjalan, kamu dapat mengikuti Mendeklarasikan Kebijakan Jaringan untuk mencoba NetworkPolicy Kubernetes.
Laman ini menunjukkan cara untuk mengatur nilai minimum dan maksimum memori yang digunakan oleh Container yang berjalan pada sebuah Namespace. Kamu dapat menentukan nilai minimum dan maksimum memori pada objek LimitRange. Jika sebuah Pod tidak memenuhi batasan yang ditentukan oleh LimitRange, maka Pod tersebut tidak dapat dibuat pada Namespace tersebut.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Tiap Node dalam klastermu harus memiliki setidaknya 1 GiB memori.
Buat sebuah Namespace sehingga sumber daya yang kamu buat pada latihan ini terisolasi dari komponen lain pada klastermu.
kubectl create namespace constraints-mem-example
Berikut berkas konfigurasi untuk sebuah LimitRange:
apiVersion: v1
kind: LimitRange
metadata:
name: mem-min-max-demo-lr
spec:
limits:
- max:
memory: 1Gi
min:
memory: 500Mi
type: Container
Membuat LimitRange:
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints.yaml --namespace=constraints-mem-example
Melihat informasi mendetail mengenai LimitRange:
kubectl get limitrange mem-min-max-demo-lr --namespace=constraints-mem-example --output=yaml
Keluaran yang dihasilkan menunjukkan batasan minimum dan maksimum dari memori seperti yang diharapkan. Tetapi perhatikan hal berikut, meskipun kamu tidak menentukan nilai bawaan pada berkas konfigurasi untuk LimitRange, namun nilai tersebut akan dibuat secara otomatis.
limits:
- default:
memory: 1Gi
defaultRequest:
memory: 1Gi
max:
memory: 1Gi
min:
memory: 500Mi
type: Container
Mulai sekarang setiap Container yang dibuat pada Namespace constraints-mem-example, Kubernetes akan menjalankan langkah-langkah berikut:
Jika Container tersebut tidak menentukan permintaan dan limit memori, maka diberikan nilai permintaan dan limit memori bawaan pada Container.
Memastikan Container memiliki permintaan memori yang lebih besar atau sama dengan 500 MiB.
Memastikan Container memiliki limit memori yang lebih kecil atau kurang dari 1 GiB.
Berikut berkas konfigurasi Pod yang memiliki satu Container. Manifes Container menentukan permintaan memori 600 MiB dan limit memori 800 MiB. Nilai tersebut memenuhi batasan minimum dan maksimum memori yang ditentukan oleh LimitRange.
apiVersion: v1
kind: Pod
metadata:
name: constraints-mem-demo
spec:
containers:
- name: constraints-mem-demo-ctr
image: nginx
resources:
limits:
memory: "800Mi"
requests:
memory: "600Mi"
Membuat Pod:
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod.yaml --namespace=constraints-mem-example
Memastikan Container pada Pod sudah berjalan:
kubectl get pod constraints-mem-demo --namespace=constraints-mem-example
Melihat informasi mendetail tentang Pod:
kubectl get pod constraints-mem-demo --output=yaml --namespace=constraints-mem-example
Keluaran yang dihasilkan menunjukkan Container memiliki permintaan memori 600 MiB dan limit memori 800 MiB. Nilai tersebut memenuhi batasan yang ditentukan oleh LimitRange.
resources:
limits:
memory: 800Mi
requests:
memory: 600Mi
Menghapus Podmu:
kubectl delete pod constraints-mem-demo --namespace=constraints-mem-example
Berikut berkas konfigurasi untuk sebuah Pod yang memiliki satu Container. Container tersebut menentukan permintaan memori 800 MiB dan batas memori 1.5 GiB.
apiVersion: v1
kind: Pod
metadata:
name: constraints-mem-demo-2
spec:
containers:
- name: constraints-mem-demo-2-ctr
image: nginx
resources:
limits:
memory: "1.5Gi"
requests:
memory: "800Mi"
Mencoba membuat Pod:
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-2.yaml --namespace=constraints-mem-example
Keluaran yang dihasilkan menunjukkan Pod tidak dibuat, karena Container menentukan limit memori yang terlalu besar:
Error from server (Forbidden): error when creating "examples/admin/resource/memory-constraints-pod-2.yaml":
pods "constraints-mem-demo-2" is forbidden: maximum memory usage per Container is 1Gi, but limit is 1536Mi.
Berikut berkas konfigurasi untuk sebuah Pod yang memiliki satu Container. Container tersebut menentukan permintaan memori 100 MiB dan limit memori 800 MiB.
apiVersion: v1
kind: Pod
metadata:
name: constraints-mem-demo-3
spec:
containers:
- name: constraints-mem-demo-3-ctr
image: nginx
resources:
limits:
memory: "800Mi"
requests:
memory: "100Mi"
Mencoba membuat Pod:
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-3.yaml --namespace=constraints-mem-example
Keluaran yang dihasilkan menunjukkan Pod tidak dibuat, karena Container menentukan permintaan memori yang terlalu kecil:
Error from server (Forbidden): error when creating "examples/admin/resource/memory-constraints-pod-3.yaml":
pods "constraints-mem-demo-3" is forbidden: minimum memory usage per Container is 500Mi, but request is 100Mi.
Berikut berkas konfigurasi untuk sebuah Pod yang memiliki satu Container. Container tersebut tidak menentukan permintaan memori dan juga limit memori.
apiVersion: v1
kind: Pod
metadata:
name: constraints-mem-demo-4
spec:
containers:
- name: constraints-mem-demo-4-ctr
image: nginx
Mencoba membuat Pod:
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-4.yaml --namespace=constraints-mem-example
Melihat informasi mendetail tentang Pod:
kubectl get pod constraints-mem-demo-4 --namespace=constraints-mem-example --output=yaml
Keluaran yang dihasilkan menunjukkan Container pada Pod memiliki permintaan memori 1 GiB dan limit memori 1 GiB. Bagaimana Container mendapatkan nilai tersebut?
resources:
limits:
memory: 1Gi
requests:
memory: 1Gi
Karena Containermu tidak menentukan permintaan dan limit memori, Container tersebut diberikan permintaan dan limit memori bawaan dari LimitRange.
Pada tahap ini, Containermu mungkin saja berjalan ataupun mungkin juga tidak berjalan. Ingat bahwa prasyarat untuk tugas ini adalah Node harus memiliki setidaknya 1 GiB memori. Jika tiap Node hanya memiliki 1 GiB memori, maka tidak akan ada cukup memori untuk dialokasikan pada setiap Node untuk memenuhi permintaan 1 GiB memori. Jika ternyata kamu menggunakan Node dengan 2 GiB memori, maka kamu mungkin memiliki cukup ruang untuk memenuhi permintaan 1 GiB tersebut.
Menghapus Pod:
kubectl delete pod constraints-mem-demo-4 --namespace=constraints-mem-example
Batasan maksimum dan minimum memori yang yang ditetapkan pada sebuah Namespace oleh LimitRange dilaksanakan hanya ketika Pod dibuat atau diperbarui. Jika kamu mengubah LimitRange, hal tersebut tidak akan memengaruhi Pods yang telah dibuat sebelumnya.
Sebagai seorang administrator klaster, kamu mungkin ingin menetapkan pembatasan jumlah memori yang dapat digunakan oleh Pod. Sebagai contoh:
Tiap Node dalam sebuah klaster memiliki 2 GB memori. Kamu tidak ingin menerima Pod yang meminta lebih dari 2 GB memori, karena tidak ada Node pada klater yang dapat memenuhi permintaan tersebut.
Sebuah klaster digunakan bersama pada departemen produksi dan pengembangan. Kamu ingin mengizinkan beban kerja (workload) pada produksi untuk menggunakan hingga 8 GB memori, tapi kamu ingin beban kerja pada pengembangan cukup terbatas sampai dengan 512 MB saja. Kamu membuat Namespace terpisah untuk produksi dan pengembangan, dan kamu menerapkan batasan memori pada tiap Namespace.
Menghapus Namespace:
kubectl delete namespace constraints-mem-example
Mengatur Permintaan dan Limit Memori Bawaan untuk Sebuah Namespace
Mengatur Permintaan dan Limit CPU Bawaan untuk Sebuah Namespace
Mengatur Batas Minimum dan Maksimum CPU untuk Sebuah Namespace
Laman ini menyediakan beberapa petunjuk untuk mendiagnosis masalah DNS.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Kubernetes servermu harus dalam versi yang sama atau lebih baru dari v1.6.
Untuk melihat versi, tekan kubectl version.
apiVersion: v1
kind: Pod
metadata:
name: dnsutils
namespace: default
spec:
containers:
- name: dnsutils
image: registry.k8s.io/e2e-test-images/agnhost:2.39
imagePullPolicy: IfNotPresent
restartPolicy: Always
Gunakan manifes berikut untuk membuat sebuah Pod:
kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
pod/dnsutils created
…dan verifikasi statusnya:
kubectl get pods dnsutils
NAME READY STATUS RESTARTS AGE
dnsutils 1/1 Running 0 <some-time>
Setelah Pod tersebut berjalan, kamu dapat menjalankan perintah nslookup di lingkungan tersebut.
Jika kamu melihat hal seperti ini, maka DNS sudah berjalan dengan benar.
kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10
Name: kubernetes.default
Address 1: 10.0.0.1
Jika perintah nslookup gagal, periksa hal berikut:
Periksa isi dari berkas resolv.conf. (Lihat Inheriting DNS dari node dan Isu-isu yang dikenal di bawah ini untuk informasi lebih lanjut)
kubectl exec -ti dnsutils -- cat /etc/resolv.conf
Verifikasi path pencarian dan nama server telah dibuat agar tampil seperti di bawah ini (perlu diperhatikan bahwa path pencarian dapat berbeda tergantung dari penyedia layanan cloud):
search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal
nameserver 10.0.0.10
options ndots:5
Kesalahan yang muncul berikut ini mengindikasikan terdapat masalah dengan add-on CoreDNS (atau kube-dns) atau Service terkait:
kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10
nslookup: can't resolve 'kubernetes.default'
atau
kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
nslookup: can't resolve 'kubernetes.default'
Gunakan perintah kubectl get pods untuk memverifikasi apakah Pod DNS sedang berjalan.
kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE
...
coredns-7b96bf9f76-5hsxb 1/1 Running 0 1h
coredns-7b96bf9f76-mvmmt 1/1 Running 0 1h
...
k8s-app adalah kube-dns baik untuk CoreDNS maupun kube-dns.Jika kamu melihat tidak ada Pod CoreDNS yang sedang berjalan atau Pod tersebut gagal/telah selesai, add-on DNS mungkin tidak dijalankan (deployed) secara bawaan di lingkunganmu saat ini dan kamu harus menjalankannya secara manual.
Gunakan perintah kubectl logs untuk melihat log dari Container DNS.
Untuk CoreDNS:
kubectl logs --namespace=kube-system -l k8s-app=kube-dns
Berikut contoh log dari CoreDNS yang sehat (healthy):
.:53
2018/08/15 14:37:17 [INFO] CoreDNS-1.2.2
2018/08/15 14:37:17 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.2
linux/amd64, go1.10.3, 2e322f6
2018/08/15 14:37:17 [INFO] plugin/reload: Running configuration MD5 = 24e6c59e83ce706f07bcc82c31b1ea1c
Periksa jika ada pesan mencurigakan atau tidak terduga dalam log.
Verifikasi apakah layanan DNS berjalan dengan menggunakan perintah kubectl get service.
kubectl get svc --namespace=kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 1h
...
kube-dns baik untuk CoreDNS maupun kube-dns.Jika kamu telah membuat Service atau seharusnya Service telah dibuat secara bawaan namun ternyata tidak muncul, lihat debugging Service untuk informasi lebih lanjut.
Kamu dapat memverifikasikan apakah endpoint DNS telah diekspos dengan menggunakan perintah kubectl get endpoints.
kubectl get endpoints kube-dns --namespace=kube-system
NAME ENDPOINTS AGE
kube-dns 10.180.3.17:53,10.180.3.17:53 1h
Jika kamu tidak melihat endpoint, lihat bagian endpoint pada dokumentasi debugging Service.
Untuk tambahan contoh Kubernetes DNS, lihat contoh cluster-dns pada repositori Kubernetes GitHub.
Kamu dapat memverifikasi apakah kueri telah diterima oleh CoreDNS dengan menambahkan plugin log pada konfigurasi CoreDNS (alias Corefile).
CoreDNS Corefile disimpan pada ConfigMap dengan nama coredns. Untuk mengeditnya, gunakan perintah:
kubectl -n kube-system edit configmap coredns
Lalu tambahkan log pada bagian Corefile seperti contoh berikut:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
log
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
proxy . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
Setelah perubahan disimpan, perubahan dapat memakan waktu satu hingga dua menit untuk Kubernetes menyebarkan perubahan ini pada Pod CoreDNS.
Berikutnya, coba buat beberapa kueri dan lihat log pada bagian atas dari dokumen ini. Jika pod CoreDNS menerima kueri, kamu seharusnya akan melihatnya pada log.
Berikut ini contoh kueri yang terdapat di dalam log:
.:53
2018/08/15 14:37:15 [INFO] CoreDNS-1.2.0
2018/08/15 14:37:15 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.0
linux/amd64, go1.10.3, 2e322f6
2018/09/07 15:29:04 [INFO] plugin/reload: Running configuration MD5 = 162475cdf272d8aa601e6fe67a6ad42f
2018/09/07 15:29:04 [INFO] Reloading complete
172.17.0.18:41675 - [07/Sep/2018:15:29:11 +0000] 59925 "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR qr,aa,rd,ra 106 0.000066649s
Beberapa distribusi Linux (contoh Ubuntu) menggunakan resolver DNS lokal secara bawaan (systemd-resolved).
Systemd-resolved memindahkan dan mengganti /etc/resolv.conf dengan berkas stub yang dapat menyebabkan forwarding loop yang fatal saat meresolusi nama pada server upstream. Ini dapat diatasi secara manual dengan menggunakan flag kubelet --resolv-conf
untuk mengarahkan ke resolv.conf yang benar (Pada systemd-resolved, ini berada di /run/systemd/resolve/resolv.conf).
kubeadm akan otomatis mendeteksi systemd-resolved, dan menyesuaikan flag kubelet sebagai mana mestinya.
Pemasangan Kubernetes tidak menggunakan berkas resolv.conf pada node untuk digunakan sebagai klaster DNS secara default, karena proses ini umumnya spesifik pada distribusi tertentu. Hal ini bisa jadi akan diimplementasi nantinya.
Libc Linux (alias glibc) secara bawaan memiliki batasan nameserver DNS sebanyak 3 rekaman (records). Selain itu, pada glibc versi yang lebih lama dari glibc-2.17-222 (versi terbaru lihat isu ini), jumlah rekaman DNS search dibatasi sejumlah 6 (lihat masalah sejak 2005 ini). Kubernetes membutuhkan 1 rekaman nameserver dan 3 rekaman search. Ini berarti jika instalasi lokal telah menggunakan 3 nameserver atau menggunakan lebih dari 3 search,sementara versi glibc kamu termasuk yang terkena dampak, beberapa dari pengaturan tersebut akan hilang. Untuk menyiasati batasan rekaman DNS nameserver, node dapat menjalankan dnsmasq,yang akan menyediakan nameserver lebih banyak. Kamu juga dapat menggunakan kubelet --resolv-conf flag. Untuk menyiasati batasan rekaman search, pertimbangkan untuk memperbarui distribusi linux kamu atau memperbarui glibc ke versi yang tidak terdampak.
Jika kamu menggunakan Alpine versi 3.3 atau lebih lama sebagai dasar image kamu, DNS mungkin tidak dapat bekerja dengan benar disebabkan masalah dengan Alpine. Masalah 30215 Kubernetes menyediakan informasi lebih detil tentang ini.
Laman ini menjelaskan cara mengonfigurasi DNS Pod kamu dan menyesuaikan proses resolusi DNS pada klaster kamu.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Klaster kamu harus menjalankan tambahan (add-on) CoreDNS terlebih dahulu.
Migrasi ke CoreDNS
menjelaskan tentang bagaimana menggunakan kubeadm untuk melakukan migrasi dari kube-dns.
Kubernetes servermu harus dalam versi yang sama atau lebih baru dari v1.12.
Untuk melihat versi, tekan kubectl version.
DNS adalah Service bawaan dalam Kubernetes yang diluncurkan secara otomatis melalui addon manager add-on klaster.
Sejak Kubernetes v1.12, CoreDNS adalah server DNS yang direkomendasikan untuk menggantikan kube-dns. Jika klaster kamu
sebelumnya menggunakan kube-dns, maka kamu mungkin masih menggunakan kube-dns daripada CoreDNS.
kube-dns pada field metadata.name.
Hal ini agar ada interoperabilitas yang lebih besar dengan beban kerja yang bergantung pada nama Service kube-dns lama untuk me-resolve alamat internal ke dalam klaster. Dengan menggunakan sebuah Service yang bernama kube-dns mengabstraksi detail implementasi yang dijalankan oleh penyedia DNS di belakang nama umum tersebut.Jika kamu menjalankan CoreDNS sebagai sebuah Deployment, maka biasanya akan ditampilkan sebagai sebuah Service Kubernetes dengan alamat IP yang statis.
Kubelet meneruskan informasi DNS resolver ke setiap Container dengan argumen --cluster-dns=<dns-service-ip>.
Nama DNS juga membutuhkan domain. Kamu dapat mengonfigurasi domain lokal di kubelet
dengan argumen --cluster-domain=<default-local-domain>.
Server DNS mendukung forward lookup (record A dan AAAA), port lookup (record SRV), reverse lookup alamat IP (record PTR), dan lain sebagainya. Untuk informasi lebih lanjut, lihatlah DNS untuk Service dan Pod.
Jika dnsPolicy dari Pod diatur menjadi default, itu berarti mewarisi konfigurasi resolusi nama
dari Node yang dijalankan Pod. Resolusi DNS pada Pod
harus berperilaku sama dengan Node tersebut.
Tapi lihat Isu-isu yang telah diketahui.
Jika kamu tidak menginginkan hal ini, atau jika kamu menginginkan konfigurasi DNS untuk Pod berbeda, kamu bisa
menggunakan argumen --resolv-conf pada kubelet. Atur argumen ini menjadi "" untuk mencegah Pod tidak
mewarisi konfigurasi DNS. Atur ke jalur (path) berkas yang tepat untuk berkas yang berbeda dengan
/etc/resolv.conf untuk menghindari mewarisi konfigurasi DNS.
CoreDNS adalah server DNS otoritatif untuk kegunaan secara umum yang dapat berfungsi sebagai Service DNS untuk klaster, yang sesuai dengan spesifikasi dns.
CoreDNS adalah server DNS yang modular dan mudah dipasang, dan setiap plugin dapat menambahkan fungsionalitas baru ke CoreDNS. Fitur ini dapat dikonfigurasikan dengan menjaga berkas Corefile, yang merupakan berkas konfigurasi dari CoreDNS. Sebagai administrator klaster, kamu dapat memodifikasi ConfigMap untuk Corefile dari CoreDNS dengan mengubah cara perilaku pencarian Service DNS pada klaster tersebut.
Di Kubernetes, CoreDNS diinstal dengan menggunakan konfigurasi Corefile bawaan sebagai berikut:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
Konfigurasi Corefile meliputi plugin berikut ini dari CoreDNS:
http://localhost:8080/health. Dalam sintaks yang diperluas lameduck akan menangani proses tidak sehat agar menunggu selama 5 detik sebelum proses tersebut dimatikan.ttl memungkinkan kamu untuk mengatur TTL khusus untuk respon dari pertanyaan DNS. Standarnya adalah 5 detik. TTL minimum yang diizinkan adalah 0 detik, dan maksimum hanya dibatasi sampai 3600 detik. Mengatur TTL ke 0 akan mencegah record untuk di simpan sementara dalam cache.pods insecure disediakan untuk kompatibilitas dengan Service kube-dns sebelumnya. Kamu dapat menggunakan opsi pods verified, yang mengembalikan record A hanya jika ada Pod pada Namespace yang sama untuk alamat IP yang sesuai. Opsi pods disabled dapat digunakan jika kamu tidak menggunakan record Pod.http://localhost:9153/metrics dalam format yang sesuai dengan Prometheus (dikenal juga sebagai OpenMetrics).Kamu dapat memodifikasi perilaku CoreDNS bawaan dengan memodifikasi ConfigMap.
CoreDNS memiliki kemampuan untuk mengonfigurasi stubdomain dan nameserver upstream dengan menggunakan plugin forward.
Jika operator klaster memiliki sebuah server domain Consul yang terletak di 10.150.0.1, dan semua nama Consul memiliki akhiran .consul.local. Untuk mengonfigurasinya di CoreDNS, administrator klaster membuat bait (stanza) berikut dalam ConfigMap CoreDNS.
consul.local:53 {
errors
cache 30
forward . 10.150.0.1
}
Untuk memaksa secara eksplisit semua pencarian DNS non-cluster melalui nameserver khusus pada 172.16.0.1, arahkan forward ke nameserver bukan ke /etc/resolv.conf
forward . 172.16.0.1
ConfigMap terakhir bersama dengan konfigurasi Corefile bawaan terlihat seperti berikut:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . 172.16.0.1
cache 30
loop
reload
loadbalance
}
consul.local:53 {
errors
cache 30
forward . 10.150.0.1
}
Perangkat kubeadm mendukung terjemahan otomatis dari ConfigMap kube-dns
ke ConfigMap CoreDNS yang setara.
CoreDNS mendukung fitur kube-dns dan banyak lagi lainnya.
ConfigMap dibuat agar kube-dns mendukung StubDomains dan upstreamNameservers untuk diterjemahkan ke plugin forward dalam CoreDNS.
Begitu pula dengan plugin Federations dalam kube-dns melakukan translasi untuk plugin federation dalam CoreDNS.
Contoh ConfigMap ini untuk kube-dns menentukan federasi, stub domain dan server upstream nameserver:
apiVersion: v1
data:
federations: |
{"foo" : "foo.feddomain.com"}
stubDomains: |
{"abc.com" : ["1.2.3.4"], "my.cluster.local" : ["2.3.4.5"]}
upstreamNameservers: |
["8.8.8.8", "8.8.4.4"]
kind: ConfigMap
Untuk konfigurasi yang setara dengan CoreDNS buat Corefile berikut:
federation cluster.local {
foo foo.feddomain.com
}
abc.com:53 {
errors
cache 30
forward . 1.2.3.4
}
my.cluster.local:53 {
errors
cache 30
forward . 2.3.4.5
}
Corefile lengkap dengan plugin bawaan:
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
federation cluster.local {
foo foo.feddomain.com
}
prometheus :9153
forward . 8.8.8.8 8.8.4.4
cache 30
}
abc.com:53 {
errors
cache 30
forward . 1.2.3.4
}
my.cluster.local:53 {
errors
cache 30
forward . 2.3.4.5
}
Untuk bermigrasi dari kube-dns ke CoreDNS, artikel blog yang detail tersedia untuk membantu pengguna mengadaptasi CoreDNS sebagai pengganti dari kube-dns.
Kamu juga dapat bermigrasi dengan menggunakan skrip deploy CoreDNS yang resmi.
Node Kubernetes dapat dijadwalkan sesuai dengan kapasitas. Secara bawaan, Pod dapat menggunakan semua kapasitas yang tersedia pada sebuah Node. Ini merupakan masalah karena Node sebenarnya menjalankan beberapa daemon sistem yang diperlukan oleh OS dan Kubernetes itu sendiri. Jika sumber daya pada Node tidak direservasi untuk daemon-daemon tersebut, maka Pod dan daemon akan berlomba-lomba menggunakan sumber daya yang tersedia, sehingga menyebabkan starvation sumber daya pada Node.
Fitur bernama Allocatable pada Node diekspos oleh kubelet yang berfungsi untuk melakukan
reservasi sumber daya komputasi untuk daemon sistem. Kubernetes merekomendasikan admin
klaster untuk mengatur Allocatable pada Node berdasarkan tingkat kepadatan (density) beban kerja setiap Node.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Kubernetes servermu harus dalam versi yang sama atau lebih baru dari 1.8.Untuk melihat versi, tekan kubectl version.
--reserved-cpus untuk
menyetel daftar reservasi CPU secara eksplisit.
Kapasitas Node
------------------------------
| kube-reserved |
|----------------------------|
| system-reserved |
|----------------------------|
| eviction-threshold |
| (batas pengusiran) |
|----------------------------|
| |
| allocatable |
| (dapat digunakan oleh Pod) |
| |
| |
------------------------------
Allocatable atau sumber daya yang dialokasikan pada sebuah Node Kubernetes merupakan
jumlah sumber daya komputasi yang dapat digunakan oleh Pod. Penjadwal tidak
dapat melakukan penjadwalan melebihi Allocatable. Saat ini dukungan terhadap
CPU, memory dan ephemeral-storage tersedia.
Allocatable pada Node diekspos oleh objek API v1.Node dan merupakan
bagian dari baris perintah kubectl describe node.
Sumber daya dapat direservasi untuk dua kategori daemon sistem melalui kubelet.
Untuk menerapkan batasan Allocatable pada Node, kamu harus mengaktifkan
hierarki cgroup yang baru melalui flag --cgroups-per-qos. Secara bawaan, flag ini
telah aktif. Saat aktif, kubelet akan memasukkan semua Pod pengguna di bawah
sebuah hierarki cgroup yang dikelola oleh kubelet.
Manipulasi terhadap hierarki cgroup pada hos melalui driver cgroup didukung oleh kubelet.
Driver dikonfigurasi melalui flag --cgroup-driver.
Nilai yang didukung adalah sebagai berikut:
cgroupfs merupakan driver bawaan yang melakukan manipulasi secara langsung
terhadap filesystem cgroup pada hos untuk mengelola sandbox cgroup.systemd merupakan driver alternatif yang mengelola sandbox cgroup menggunakan
bagian dari sumber daya yang didukung oleh sistem init yang digunakan.Tergantung dari konfigurasi runtime Container yang digunakan,
operator dapat memilih driver cgroup tertentu untuk memastikan perilaku sistem yang tepat.
Misalnya, jika operator menggunakan driver cgroup systemd yang disediakan oleh
runtime docker, maka kubelet harus diatur untuk menggunakan driver cgroup systemd.
--kube-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]--kube-reserved-cgroup=kube-reserved berfungsi untuk mengambil informasi sumber daya reservasi
untuk daemon sistem Kubernetes, seperti kubelet, runtime Container, detektor masalah pada Node, dsb.
kube-reserved tidak berfungsi untuk mereservasi sumber daya untuk daemon sistem yang berjalan
sebagai Pod. kube-reserved merupakan fungsi dari kepadatan Pod pada Node.
Selain dari cpu, memory, dan ephemeral-storage,pid juga dapat
diatur untuk mereservasi jumlah ID proses untuk daemon sistem Kubernetes.
Secara opsional, kamu dapat memaksa daemon sistem melalui setelan kube-reserved.
Ini dilakukan dengan menspesifikasikan parent cgroup sebagai nilai dari flag --kube-reserved-cgroup pada kubelet.
Kami merekomendasikan daemon sistem Kubernetes untuk ditempatkan pada
tingkatan cgroup yang tertinggi (contohnya, runtime.slice pada mesin systemd).
Secara ideal, setiap daemon sistem sebaiknya dijalankan pada child cgroup
di bawah parent ini. Lihat dokumentasi
untuk mengetahui rekomendasi hierarki cgroup secara detail.
Catatan: kubelet tidak membuat --kube-reserved-cgroup jika cgroup
yang diberikan tidak ada pada sistem. Jika cgroup yang tidak valid diberikan,
maka kubelet akan mengalami kegagalan.
--system-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]--system-reserved-cgroup=system-reserved berfungsi untuk mengetahui reservasi sumber daya untuk
daemon sistem pada OS, seperti sshd, udev, dan lainnya. system-reserved sebaiknya
mereservasi memori untuk kernel juga, karena memori kernel tidak termasuk dalam
hitungan kalkulasi Pod pada Kubernetes. Kami juga merekomendasikan reservasi sumber daya
untuk sesi (session) login pengguna (contohnya, user.slice di dalam dunia systemd).
Kubernetes v1.17 [stable]
--reserved-cpus=0-3reserved-cpus berfungsi untuk mendefinisikan cpuset secara eksplisit untuk
daemon sistem OS dan daemon sistem Kubernetes. reserved-cpus dimaksudkan untuk
sistem-sistem yang tidak mendefinisikan tingkatan cgroup tertinggi secara terpisah untuk
daemon sistem OS dan daemon sistem Kubernetes yang berkaitan dengan sumber daya cpuset.
Jika kubelet tidak memiliki --system-reserved-cgroup dan --kube-reserved-cgroup,
cpuset akan diberikan secara eksplisit oleh reserved-cpus, yang akan menimpa definisi
yang diberikan oleh opsi --kube-reserved dan --system-reserved.
Opsi ini dirancang secara spesifik untuk kasus-kasus Telco/NFV, di mana interrupt atau timer yang tidak terkontrol bisa memengaruhi performa dari beban kerja. Kamu dapat menggunakan opsi untuk untuk mendefinisikan cpuset secara eksplisit untuk daemon sistem/Kubernetes dan interrupt/timer, sehingga CPU sisanya dalam sistem akan digunakan untuk beban kerja saja, dengan dampak yang sedikit terhadap interrupt/timer yang tidak terkontrol. Untuk memindahkan daemon sistem, daemon Kubernetes serta interrrupt/timer Kubernetes supaya menggunakan cpuset yang eksplisit didefinisikan oleh opsi ini, sebaiknya digunakan mekanisme lain di luar Kubernetes. Contohnya: pada Centos, kamu dapat melakukan ini dengan menggunakan toolset yang sudah disetel.
--eviction-hard=[memory.available<500Mi]Tekanan memori pada tingkatan Node menyebabkan sistem OOM (Out Of Memory) yang
berdampak pada Node secara keseluruhan dan semua Pod yang dijalankan di dalamnya.
Node dapat berubah menjadi offline sementara sampai memori berhasil diklaim kembali.
Untuk menghindari sistem OOM, atau mengurangi kemungkinan terjadinya OOM, kubelet
menyediakan fungsi untuk pengelolaan saat Kehabisan Sumber Daya (Out of Resource).
Pengusiran dapat dilakukan hanya untuk kasus kehabisan memory dan ephemeral-storage. Dengan mereservasi
sebagian memori melalui flag --eviction-hard, kubelet akan berusaha untuk "mengusir" (evict)
Pod ketika ketersediaan memori pada Node jatuh di bawah nilai yang telah direservasi.
Dalam bahasa sederhana, jika daemon sistem tidak ada pada Node, maka Pod tidak dapat menggunakan
memori melebihi nilai yang ditentukan oleh flag --eviction-hard. Karena alasan ini,
sumber daya yang direservasi untuk pengusiran tidak tersedia untuk Pod.
--enforce-node-allocatable=pods[,][system-reserved][,][kube-reserved]Penjadwal menganggap Allocatable sebagai kapasitas yang tersedia untuk digunakan oleh Pod.
Secara bawaan, kubelet memaksakan Allocatable untuk semua Pod. Pemaksaan dilakukan
dengan cara "mengusir" Pod-Pod ketika penggunaan sumber daya Pod secara keseluruhan telah
melewati nilai Allocatable. Lihat bagian ini
untuk mengetahui kebijakan pengusiran secara detail. Pemaksaan ini dikendalikan dengan
cara memberikan nilai Pod melalui flag --enforce-node-allocatable pada kubelet.
Secara opsional, kubelet dapat diatur untuk memaksakan kube-reserved dan
system-reserved dengan memberikan nilai melalui flag tersebut. Sebagai catatan,
jika kamu mengatur kube-reserved, maka kamu juga harus mengatur --kube-reserved-cgroup. Begitu pula
jika kamu mengatur system-reserved, maka kamu juga harus mengatur --system-reserved-cgroup.
Daemon sistem dilayani mirip seperti Pod Guaranteed yang terjamin sumber dayanya.
Daemon sistem dapat melakukan burst di dalam jangkauan cgroup. Perilaku ini
dikelola sebagai bagian dari penggelaran (deployment) Kubernetes. Sebagai contoh,
kubelet harus memiliki cgroup sendiri dan membagikan sumber daya kube-reserved dengan
runtime Container. Namun begitu, kubelet tidak dapat melakukan burst dan menggunakan
semua sumber daya yang tersedia pada Node jika kube-reserved telah dipaksakan pada sistem.
Kamu harus berhati-hati ekstra ketika memaksakan reservasi system-reserved karena dapat
menyebabkan layanan sistem yang terpenting mengalami CPU starvation, OOM killed, atau tidak
dapat melakukan fork pada Node. Kami menyarankan untuk memaksakan system-reserved hanya
jika pengguna telah melakukan profiling sebaik mungkin pada Node mereka untuk
mendapatkan estimasi yang akurat dan percaya diri terhadap kemampuan mereka untuk
memulihkan sistem ketika ada grup yang terkena OOM killed.
Allocatable pada Pod.kube-reserved berdasarkan penggunakan heuristik.system-reserved secara bertahap.Sumber daya yang diperlukan oleh daemon sistem Kubernetes dapat tumbuh seiring waktu dengan
adanya penambahan fitur-fitur baru. Proyek Kubernetes akan berusaha untuk menurunkan penggunaan sumber daya
dari daemon sistem Node, tetapi belum menjadi prioritas untuk saat ini.
Kamu dapat berekspektasi bahwa fitur kapasitas Allocatable ini akan dihapus pada versi yang akan datang.
Berikut ini merupakan contoh yang menggambarkan komputasi Allocatable pada Node:
--kube-reserved diatur menjadi cpu=1,memory=2Gi,ephemeral-storage=1Gi--system-reserved diatur menjadi cpu=500m,memory=1Gi,ephemeral-storage=1Gi--eviction-hard diatur menjadi memory.available<500Mi,nodefs.available<10%Dalam skenario ini, Allocatable akan menjadi 14.5 CPU, memori 28.5Gi, dan penyimpanan
lokal 88Gi.
Penjadwal memastikan bahwa semua Pod yang berjalan pada Node ini secara total tidak meminta memori melebihi
28.5Gi dan tidak menggunakan penyimpanan lokal melebihi 88Gi.
Pengusiran Pod akan dilakukan kubelet ketika penggunaan memori keseluruhan oleh Pod telah melebihi 28.5Gi,
atau jika penggunaan penyimpanan keseluruhan telah melebihi 88Gi. Jika semua proses pada Node mengonsumsi
CPU sebanyak-banyaknya, Pod-Pod tidak dapat mengonsumsi lebih dari 14.5 CPU.
Jika kube-reserved dan/atau system-reserved tidak dipaksakan dan daemon sistem
melebihi reservasi mereka, maka kubelet akan mengusir Pod ketika penggunaan memori pada Node
melebihi 31.5Gi atau penggunaan penyimpanan melebihi 90Gi.
Laman ini menunjukkan bagaimana cara melihat, menggunakan dan menghapus namespaces. Laman ini juga menunjukkan bagaimana cara menggunakan Namespace Kubernetes namespaces untuk membagi klaster kamu.
kubectl get namespaces
NAME STATUS AGE
default Active 11d
kube-system Active 11d
kube-public Active 11d
Kubernetes mulai dengan tiga Namespace pertama:
default Namespace bawaan untuk objek-objek yang belum terkait dengan Namespace lainkube-system Namespace untuk objek-objek yang dibuat oleh sistem Kuberneteskube-public Namespace ini dibuat secara otomatis dan dapat dibaca oleh seluruh pengguna (termasuk yang tidak terotentikasi). Namespace ini sering dicadangkan untuk kepentingan klaster, untuk kasus dimana beberapa sumber daya seharusnya dapat terlihat dan dapat terlihat secara publik di seluruh klaster. Aspek publik pada Namespace ini hanya sebuah konvensi bukan suatu kebutuhan.Kamu bisa mendapat ringkasan Namespace tertentu dengan menggunakan:
kubectl get namespaces <name>
Atau kamu bisa mendapatkan informasi detail menggunakan:
kubectl describe namespaces <name>
Name: default
Labels: <none>
Annotations: <none>
Status: Active
No resource quota.
Resource Limits
Type Resource Min Max Default
---- -------- --- --- ---
Container cpu - - 100m
Sebagai catatan, detail diatas menunjukkan baik kuota sumber daya (jika ada) dan juga jangkauan batas sumber daya.
Kuota sumber daya melacak penggunaan total sumber daya didalam Namespace dan mengijinkan operator-operator klaster mendefinisikan batas atas penggunaan sumber daya yang dapat di gunakan sebuah Namespace.
Jangkauan batas mendefinisikan pertimbangan min/maks jumlah sumber daya yang dapat di gunakan oleh sebuah entitas dalam sebuah Namespace.
Lihatlah Kontrol Admisi: Rentang Batas
Sebuah Namespace dapat berada dalam salah satu dari dua buah fase:
Active Namespace sedang digunakanTerminating Namespace sedang dihapus dan tidak dapat digunakan untuk objek-objek baruLihat dokumentasi desain untuk detil lebih lanjut.
Hindari membuat Namespace dengan awalan `kube-`, karena awalan ini dicadangkan untuk Namespace dari sistem Kubernetes.
Buat berkas YAML baru dengan nama my-namespace.yaml dengan isi berikut ini:
apiVersion: v1
kind: Namespace
metadata:
name: <masukkan-nama-namespace-disini>
Then run:
kubectl create -f ./my-namespace.yaml
Sebagai alternatif, kamu bisa membuat Namespace menggunakan perintah dibawah ini:
kubectl create namespace <masukkan-nama-namespace-disini>
Nama Namespace kamu harus merupakan Label DNS yang valid.
Ada kolom opsional finalizers, yang memungkinkan observables untuk membersihkan sumber daya ketika Namespace dihapus. Ingat bahwa jika kamu memberikan finalizer yang tidak ada, Namespace akan dibuat tapi akan berhenti pada status Terminating jika pengguna mencoba untuk menghapusnya.
Informasi lebih lanjut mengenai finalizers bisa dibaca pada dokumentasi desain dari Namespace.
Hapus Namespace dengan
kubectl delete namespaces <insert-some-namespace-name>
Proses penghapusan ini asinkron, jadi untuk beberapa waktu kamu akan melihat Namespace dalam status Terminating.
Pahami Namespace bawaan
Secara bawaan, sebuah klaster Kubernetes akan membuat Namespace bawaan ketika menyediakan klaster untuk menampung Pod, Service, dan Deployment yang digunakan oleh klaster.
Dengan asumsi kamu memiliki klaster baru, kamu bisa mengecek Namespace yang tersedia dengan melakukan hal berikut:
kubectl get namespaces
NAME STATUS AGE
default Active 13m
Membuat Namespace baru
Untuk latihan ini, kita akan membuat dua Namespace Kubernetes tambahan untuk menyimpan konten kita
Dalam sebuah skenario dimana sebuah organisasi menggunakan klaster Kubernetes yang digunakan bersama untuk penggunaan pengembangan dan produksi:
Tim pengembang ingin mengelola ruang di dalam klaster dimana mereka bisa melihat daftar Pod, Service, dan Deployment yang digunakan untuk membangun dan menjalankan apliksi mereka. Di ruang ini sumber daya akan datang dan pergi, dan pembatasan yang tidak ketat mengenai siapa yang bisa atau tidak bisa memodifikasi sumber daya untuk mendukung pengembangan secara gesit (agile).
Tim operasi ingin mengelola ruang didalam klaster dimana mereka bisa memaksakan prosedur ketat mengenai siapa yang bisa atau tidak bisa melakukan manipulasi pada kumpulan Pod, Layanan, dan Deployment yang berjalan pada situs produksi.
Satu pola yang bisa diikuti organisasi ini adalah dengan membagi klaster Kubernetes menjadi dua Namespace: development dan production
Mari kita buat dua Namespace untuk menyimpan hasil kerja kita.
Buat Namespace development menggunakan kubectl:
kubectl create -f https://k8s.io/examples/admin/namespace-dev.json
Kemudian mari kita buat Namespace production menggunakan kubectl:
kubectl create -f https://k8s.io/examples/admin/namespace-prod.json
Untuk memastikan apa yang kita lakukan benar, lihat seluruh Namespace dalam klaster.
kubectl get namespaces --show-labels
NAME STATUS AGE LABELS
default Active 32m <none>
development Active 29s name=development
production Active 23s name=production
Buat pod pada setiap Namespace
Sebuah Namespace Kubernetes memberikan batasan untuk Pod, Service, dan Deployment dalam klaster.
Pengguna yang berinteraksi dengan salah satu Namespace tidak melihat konten di dalam Namespace lain
Untuk menunjukkan hal ini, mari kita jalankan Deployment dan Pod sederhana di dalam Namespace development.
kubectl create deployment snowflake --image=registry.k8s.io/serve_hostname -n=development
kubectl scale deployment snowflake --replicas=2 -n=development
Kita baru aja membuat sebuah Deployment yang memiliki ukuran replika dua yang menjalankan Pod dengan nama snowflake dengan sebuah Container dasar yang hanya melayani hostname.
kubectl get deployment -n=development
NAME READY UP-TO-DATE AVAILABLE AGE
snowflake 2/2 2 2 2m
kubectl get pods -l app=snowflake -n=development
NAME READY STATUS RESTARTS AGE
snowflake-3968820950-9dgr8 1/1 Running 0 2m
snowflake-3968820950-vgc4n 1/1 Running 0 2m
Dan ini merupakan sesuatu yang bagus, dimana pengembang bisa melakukan hal yang ingin mereka lakukan tanpa harus khawatir hal itu akan mempengaruhi konten pada namespace production.
Mari kita pindah ke Namespace production dan menujukkan bagaimana sumber daya di satu Namespace disembunyikan dari yang lain
Namespace production seharusnya kosong, dan perintah berikut ini seharusnya tidak menghasilkan apapun.
kubectl get deployment -n=production
kubectl get pods -n=production
Production Namespace ingin menjalankan cattle, mari kita buat beberapa Pod cattle.
kubectl create deployment cattle --image=registry.k8s.io/serve_hostname -n=production
kubectl scale deployment cattle --replicas=5 -n=production
kubectl get deployment -n=production
NAME READY UP-TO-DATE AVAILABLE AGE
cattle 5/5 5 5 10s
kubectl get pods -l app=cattle -n=production
NAME READY STATUS RESTARTS AGE
cattle-2263376956-41xy6 1/1 Running 0 34s
cattle-2263376956-kw466 1/1 Running 0 34s
cattle-2263376956-n4v97 1/1 Running 0 34s
cattle-2263376956-p5p3i 1/1 Running 0 34s
cattle-2263376956-sxpth 1/1 Running 0 34s
Sampai sini, seharusnya sudah jelas bahwa sumber daya yang dibuat pengguna pada sebuah Namespace disembunyikan dari Namespace lainnya.
Seiring dengan evolusi dukungan kebijakan di Kubernetes, kami akan memperluas skenario ini untuk menunjukkan bagaimana kamu bisa menyediakan aturan otorisasi yang berbeda untuk tiap Namespace.
Sebuah klaster tunggal umumnya bisa memenuhi kebutuhan pengguna yang berbeda atau kelompok pengguna (itulah sebabnya disebut 'komunitas pengguna').
Namespace Kubernetes membantu proyek-proyek, tim-tim dan pelanggan yang berbeda untuk berbagi klaster Kubernetes.
Ini dilakukan dengan menyediakan hal berikut:
Penggunaan Namespace berbeda merupakan hal opsional.
Tiap komunitas pengguna ingin bisa bekerja secara terisolasi dari komunitas lainnya.
Tiap komunitas pengguna memiliki hal berikut sendiri:
Seorang operator klaster dapat membuat sebuah Namespace untuk tiap komunitas user yang unik.
Namespace tersebut memberikan cakupan yang unik untuk:
Contoh penggunaan mencakup
Ketika kamu membuat sebuah Service, akan terbentuk entri DNS untuk Service tersebut.
Entri DNS ini dalam bentuk <service-name>.<namespace-name>.svc.cluster.local, yang berarti jika sebuah Container hanya menggunakan <service-name> maka dia akan me-resolve ke layanan yang lokal dalam Namespace yang sama. Ini berguna untuk menggunakan konfigurasi yang sama pada Namespace yang berbeda seperti Development, Staging dan Production. Jika kami ingin menjangkau antar Namespace, kamu harus menggunakan fully qualified domain name (FQDN).
Kubernetes v1.5 [alpha]
Kamu dapat mereplikasi control plane Kubernetes dalam skrip kube-up atau kube-down untuk Google Compute Engine (GCE).
Dokumen ini menjelaskan cara menggunakan skrip kube-up/down untuk mengelola control plane dengan ketersedian tinggi atau high_availability (HA) dan bagaimana control plane HA diimplementasikan untuk digunakan dalam GCE.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Untuk membuat klaster yang kompatibel dengan HA, kamu harus mengatur tanda ini pada skrip kube-up:
MULTIZONE=true - untuk mencegah penghapusan replika control plane kubelet dari zona yang berbeda dengan zona bawaan server.
Ini diperlukan jika kamu ingin menjalankan replika control plane pada zona berbeda, dimana hal ini disarankan.
ENABLE_ETCD_QUORUM_READ=true - untuk memastikan bahwa pembacaan dari semua server API akan mengembalikan data terbaru.
Jika true, bacaan akan diarahkan ke replika pemimpin dari etcd.
Menetapkan nilai ini menjadi true bersifat opsional: pembacaan akan lebih dapat diandalkan tetapi juga akan menjadi lebih lambat.
Sebagai pilihan, kamu dapat menentukan zona GCE tempat dimana replika control plane pertama akan dibuat. Atur tanda berikut:
KUBE_GCE_ZONE=zone - zona tempat di mana replika control plane pertama akan berjalan.Berikut ini contoh perintah untuk mengatur klaster yang kompatibel dengan HA pada zona GCE europe-west1-b:
MULTIZONE=true KUBE_GCE_ZONE=europe-west1-b ENABLE_ETCD_QUORUM_READS=true ./cluster/kube-up.sh
Perhatikan bahwa perintah di atas digunakan untuk membuat klaster dengan sebuah control plane; Namun, kamu bisa menambahkan replika control plane baru ke klaster dengan perintah berikutnya.
Setelah kamu membuat klaster yang kompatibel dengan HA, kamu bisa menambahkan replika control plane ke sana.
Kamu bisa menambahkan replika control plane dengan menggunakan skrip kube-up dengan tanda berikut ini:
KUBE_REPLICATE_EXISTING_MASTER=true - untuk membuat replika dari control plane yang sudah ada.
KUBE_GCE_ZONE=zone - zona di mana replika control plane itu berjalan.
Region ini harus sama dengan region dari zona replika yang lain.
Kamu tidak perlu mengatur tanda MULTIZONE atau ENABLE_ETCD_QUORUM_READS,
karena tanda itu diturunkan pada saat kamu memulai klaster yang kompatible dengan HA.
Berikut ini contoh perintah untuk mereplikasi control plane pada klaster sebelumnya yang kompatibel dengan HA:
KUBE_GCE_ZONE=europe-west1-c KUBE_REPLICATE_EXISTING_MASTER=true ./cluster/kube-up.sh
Kamu dapat menghapus replika control plane dari klaster HA dengan menggunakan skrip kube-down dengan tanda berikut:
KUBE_DELETE_NODES=false - untuk mencegah penghapusan kubelet.
KUBE_GCE_ZONE=zone - zona di mana replika control plane akan dihapus.
KUBE_REPLICA_NAME=replica_name - (opsional) nama replika control plane yang akan dihapus.
Jika kosong: replika mana saja dari zona yang diberikan akan dihapus.
Berikut ini contoh perintah untuk menghapus replika control plane dari klaster HA yang sudah ada sebelumnya:
KUBE_DELETE_NODES=false KUBE_GCE_ZONE=europe-west1-c ./cluster/kube-down.sh
Jika salah satu replika control plane di klaster HA kamu gagal, praktek terbaik adalah menghapus replika dari klaster kamu dan menambahkan replika baru pada zona yang sama. Berikut ini contoh perintah yang menunjukkan proses tersebut:
KUBE_DELETE_NODES=false KUBE_GCE_ZONE=replica_zone KUBE_REPLICA_NAME=replica_name ./cluster/kube-down.sh
KUBE_GCE_ZONE=replica-zone KUBE_REPLICATE_EXISTING_MASTER=true ./cluster/kube-up.sh
Usahakan untuk menempatkan replika control plane pada zona yang berbeda. Pada saat terjadi kegagalan zona, semua control plane yang ditempatkan dalam zona tersebut akan gagal pula. Untuk bertahan dari kegagalan pada sebuah zona, tempatkan juga Node pada beberapa zona yang lain (Lihatlah multi-zona untuk lebih detail).
Jangan gunakan klaster dengan dua replika control plane. Konsensus pada klaster dengan dua replika membutuhkan kedua replika tersebut berjalan pada saat mengubah keadaan yang persisten. Akibatnya, kedua replika tersebut diperlukan dan kegagalan salah satu replika mana pun mengubah klaster dalam status kegagalan mayoritas. Dengan demikian klaster dengan dua replika lebih buruk, dalam hal HA, daripada klaster dengan replika tunggal.
Ketika kamu menambahkan sebuah replika control plane, status klaster (etcd) disalin ke sebuah instance baru. Jika klaster itu besar, mungkin butuh waktu yang lama untuk menduplikasi keadaannya. Operasi ini dapat dipercepat dengan memigrasi direktori data etcd, seperti yang dijelaskan di sini (Kami sedang mempertimbangkan untuk menambahkan dukungan untuk migrasi direktori data etcd di masa mendatang).

Setiap replika control plane akan menjalankan komponen berikut dalam mode berikut:
instance etcd: semua instance akan dikelompokkan bersama menggunakan konsensus;
server API : setiap server akan berbicara dengan lokal etcd - semua server API pada cluster akan tersedia;
pengontrol (controller), penjadwal (scheduler), dan scaler klaster automatis: akan menggunakan mekanisme sewa - dimana hanya satu instance dari masing-masing mereka yang akan aktif dalam klaster;
manajer tambahan (add-on): setiap manajer akan bekerja secara independen untuk mencoba menjaga tambahan dalam sinkronisasi.
Selain itu, akan ada penyeimbang beban (load balancer) di depan server API yang akan mengarahkan lalu lintas eksternal dan internal menuju mereka.
Saat memulai replika control plane kedua, penyeimbang beban yang berisi dua replika akan dibuat dan alamat IP dari replika pertama akan dipromosikan ke alamat IP penyeimbang beban. Demikian pula, setelah penghapusan replika control plane kedua yang dimulai dari paling akhir, penyeimbang beban akan dihapus dan alamat IP-nya akan diberikan ke replika terakhir yang ada. Mohon perhatikan bahwa pembuatan dan penghapusan penyeimbang beban adalah operasi yang rumit dan mungkin perlu beberapa waktu (~20 menit) untuk dipropagasikan.
Daripada sistem mencoba untuk menjaga daftar terbaru dari apiserver Kubernetes yang ada dalam Service Kubernetes, sistem akan mengarahkan semua lalu lintas ke IP eksternal:
dalam klaster dengan satu control plane, IP diarahkan ke control plane tunggal.
dalam klaster dengan multiple control plane, IP diarahkan ke penyeimbang beban yang ada di depan control plane.
Demikian pula, IP eksternal akan digunakan oleh kubelet untuk berkomunikasi dengan control plane.
Kubernetes menghasilkan sertifikat TLS control plane untuk IP publik eksternal dan IP lokal untuk setiap replika. Tidak ada sertifikat untuk IP publik sementara (ephemeral) dari replika; Untuk mengakses replika melalui IP publik sementara, kamu harus melewatkan verifikasi TLS.
Untuk mengizinkan pengelompokkan etcd, porta yang diperlukan untuk berkomunikasi antara instance etcd akan dibuka (untuk komunikasi dalam klaster). Untuk membuat penyebaran itu aman, komunikasi antara instance etcd diotorisasi menggunakan SSL.
Dokumen desain - Penyebaran master HA automatis
Kubernetes v1.12 [beta]
Dokumen ini menjelaskan tentang cara mengonfigurasi dan menggunakan parameter kernel dalam sebuah klaster Kubernetes dengan menggunakan antarmuka sysctl.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Dalam Linux, antarmuka sysctl memungkinkan administrator untuk memodifikasi kernel
parameter pada runtime. Parameter tersedia melalui sistem file virtual dari proses /proc/sys/.
Parameter mencakup berbagai subsistem seperti:
kernel.)net.)vm.)dev.)Untuk mendapatkan daftar semua parameter, kamu bisa menjalankan perintah:
sudo sysctl -a
Sysctl dikelompokkan menjadi sysctl safe dan sysctl unsafe. Sebagai tambahan untuk pengaturan Namespace yang benar, sebuah sysctl safe harus diisolasikan dengan benar diantara Pod dalam Node yang sama. Hal ini berarti mengatur sysctl safe dalam satu Pod:
Sejauh ini, sebagian besar sysctl yang diatur sebagai Namespace belum tentu dianggap sysctl safe. Sysctl berikut ini didukung dalam kelompok safe:
kernel.shm_rmid_forced,net.ipv4.ip_local_port_range,net.ipv4.tcp_syncookies,net.ipv4.ping_group_range (sejak Kubernetes 1.18),net.ipv4.ip_unprivileged_port_start (sejak Kubernetes 1.22).net.ipv4.tcp_syncookies bukan merupakan Namespace pada kernel Linux versi 4.4 atau lebih rendah.Daftar ini akan terus dikembangkan dalam versi Kubernetes berikutnya ketika kubelet mendukung mekanisme isolasi yang lebih baik.
Semua sysctl safe diaktifkan secara bawaan.
Semua sysctl unsafe dinon-aktifkan secara bawaan dan harus diizinkan secara manual oleh administrator klaster untuk setiap Node. Pod dengan sysctl unsafe yang dinon-aktifkan akan dijadwalkan, tetapi akan gagal untuk dijalankan.
Dengan mengingat peringatan di atas, administrator klaster dapat mengizinkan sysctl unsafe tertentu untuk situasi yang sangat spesial seperti pada saat kinerja tinggi atau penyetelan aplikasi secara real-time. Unsafe syctl diaktifkan Node demi Node melalui flag pada kubelet; sebagai contoh:
kubelet --allowed-unsafe-sysctls \
'kernel.msg*,net.core.somaxconn' ...
Untuk Minikube, ini dapat dilakukan melalui flag extra-config:
minikube start --extra-config="kubelet.allowed-unsafe-sysctls=kernel.msg*,net.core.somaxconn"...
Hanya sysctl yang diatur sebagai Namespace dapat diaktifkan dengan cara ini.
Sejumlah sysctl adalah diatur sebagai Namespace dalam Kernel Linux hari ini. Ini berarti mereka dapat diatur secara independen untuk setiap Pod dalam sebuah Node. Hanya sysctl dengan Namespace yang dapat dikonfigurasi melalui Pod securityContext dalam Kubernetes.
Sysctl berikut dikenal sebagai Namespace. Daftar ini dapat berubah pada versi kernel Linux yang akan datang.
kernel.shm*,kernel.msg*,kernel.sem,fs.mqueue.*,net.* dapat diatur sebagai Namespace dari container networking
Namun, ada beberapa perkecualian (seperti
net.netfilter.nf_conntrack_max dan net.netfilter.nf_conntrack_expect_max
yang dapat diatur dalam Namespace container networking padahal bukan merupakan Namespace).Sysctl tanpa Namespace disebut dengan sysctl node-level. Jika kamu perlu mengatur mereka, kamu harus secara manual mengonfigurasi mereka pada sistem operasi setiap Node, atau dengan menggunakan DaemonSet melalui Container yang berwenang.
Gunakan securityContext dari Pod untuk mengonfigurasi sysctl Namespace. securityContext berlaku untuk semua Container dalam Pod yang sama.
Contoh ini menggunakan securityContext dari Pod untuk mengatur sebuah sysctl safe
kernel.shm_rmid_forced, dan dua buah sysctl unsafe net.core.somaxconn dan
kernel.msgmax. Tidak ada perbedaan antara sysctl safe dan sysctl unsafe dalam
spesifikasi tersebut.
apiVersion: v1
kind: Pod
metadata:
name: sysctl-example
spec:
securityContext:
sysctls:
- name: kernel.shm_rmid_forced
value: "0"
- name: net.core.somaxconn
value: "1024"
- name: kernel.msgmax
value: "65536"
...
Merupakan sebuah praktik yang baik untuk mempertimbangkan Node dengan pengaturan sysctl khusus sebagai Node yang tercemar (tainted) dalam sebuah cluster, dan hanya menjadwalkan Pod yang membutuhkan pengaturan sysctl. Sangat disarankan untuk menggunakan Kubernetes fitur taints and toleration untuk mengimplementasikannya.
Pod dengan sysctl unsafe akan gagal diluncurkan pada sembarang Node yang belum mengaktifkan kedua sysctl unsafe secara eksplisit. Seperti halnya sysctl node-level sangat disarankan untuk menggunakan fitur taints and toleration atau pencemaran dalam Node untuk Pod dalam Node yang tepat.
Kamu selanjutnya dapat mengontrol sysctl mana saja yang dapat diatur dalam Pod dengan menentukan daftar
sysctl atau pola (pattern) sysctl dalam forbiddenSysctls dan/atau field
allowedUnsafeSysctls dari PodSecurityPolicy. Pola sysctl diakhiri
dengan karakter *, seperti kernel.*. Karakter * saja akan mencakup
semua sysctl.
Secara bawaan, semua sysctl safe diizinkan.
Kedua forbiddenSysctls dan allowedUnsafeSysctls merupakan daftar dari nama sysctl
atau pola sysctl yang polos (yang diakhiri dengan karakter *). Karakter * saja berarti sesuai dengan semua sysctl.
Field forbiddenSysctls tidak memasukkan sysctl tertentu. Kamu dapat melarang
kombinasi sysctl safe dan sysctl unsafe dalam daftar tersebut. Untuk melarang pengaturan
sysctl, hanya gunakan * saja.
Jika kamu menyebutkan sysctl unsafe pada field allowedUnsafeSysctls dan
tidak ada pada field forbiddenSysctls, maka sysctl dapat digunakan pada Pod
dengan menggunakan PodSecurityPolicy ini. Untuk mengizinkan semua sysctl unsafe diatur dalam
PodSecurityPolicy, gunakan karakter * saja.
Jangan mengonfigurasi kedua field ini sampai tumpang tindih, dimana sysctl yang diberikan akan diperbolehkan dan dilarang sekaligus.
allowUnsafeSysctls
pada PodSecurityPolicy, Pod apa pun yang menggunakan sysctl seperti itu akan gagal dimulai
jika sysctl unsafe tidak diperbolehkan dalam flag kubelet --allowed-unsafe-sysctls
pada Node tersebut.Ini merupakan contoh sysctl unsafe yang diawali dengan kernel.msg yang diperbolehkan dan
sysctl kernel.shm_rmid_forced yang dilarang.
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: sysctl-psp
spec:
allowedUnsafeSysctls:
- kernel.msg*
forbiddenSysctls:
- kernel.shm_rmid_forced
...
etcd adalah penyimpanan key value konsisten yang digunakan sebagai penyimpanan data klaster Kubernetes.
Selalu perhatikan mekanisme untuk mem-backup data etcd pada klaster Kubernetes kamu. Untuk informasi lebih lanjut tentang etcd, lihat dokumentasi etcd.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Jalankan etcd sebagai klaster dimana anggotanya berjumlah ganjil.
Etcd adalah sistem terdistribusi berbasis leader. Pastikan leader secara berkala mengirimkan heartbeat dengan tepat waktu ke semua pengikutnya untuk menjaga kestabilan klaster.
Pastikan tidak terjadi kekurangan sumber daya.
Kinerja dan stabilitas dari klaster sensitif terhadap jaringan dan IO disk. Kekurangan sumber daya apa pun dapat menyebabkan timeout dari heartbeat, yang menyebabkan ketidakstabilan klaster. Etcd yang tidak stabil mengindikasikan bahwa tidak ada leader yang terpilih. Dalam keadaan seperti itu, sebuah klaster tidak dapat membuat perubahan apa pun ke kondisi saat ini, yang menyebabkan tidak ada Pod baru yang dapat dijadwalkan.
Menjaga kestabilan klaster etcd sangat penting untuk stabilitas klaster Kubernetes. Karenanya, jalankan klaster etcd pada mesin khusus atau lingkungan terisolasi untuk persyaratan sumber daya terjamin.
Versi minimum yang disarankan untuk etcd yang dijalankan dalam lingkungan produksi adalah 3.2.10+.
Mengoperasikan etcd dengan sumber daya terbatas hanya cocok untuk tujuan pengujian. Untuk peluncuran dalam lingkungan produksi, diperlukan konfigurasi perangkat keras lanjutan. Sebelum meluncurkan etcd dalam produksi, lihat dokumentasi referensi persyaratan sumber daya.
Bagian ini mencakup bagaimana memulai klaster etcd dalam Node tunggal dan Node multipel.
Gunakan Klaster etcd Node tunggal hanya untuk tujuan pengujian
Jalankan perintah berikut ini:
./etcd --listen-client-urls=http://$PRIVATE_IP:2379 --advertise-client-urls=http://$PRIVATE_IP:2379
Start server API Kubernetes dengan flag --etcd-servers=$PRIVATE_IP:2379.
Ganti PRIVATE_IP dengan IP klien etcd kamu.
Untuk daya tahan dan ketersediaan tinggi, jalankan etcd sebagai klaster dengan Node multipel dalam lingkungan produksi dan cadangkan secara berkala. Sebuah klaster dengan lima anggota direkomendasikan dalam lingkungan produksi. Untuk informasi lebih lanjut, lihat Dokumentasi FAQ.
Mengkonfigurasi klaster etcd baik dengan informasi anggota statis atau dengan penemuan dinamis. Untuk informasi lebih lanjut tentang pengklasteran, lihat Dokumentasi pengklasteran etcd.
Sebagai contoh, tinjau sebuah klaster etcd dengan lima anggota yang berjalan dengan URL klien berikut: http://$IP1:2379, http://$IP2:2379, http://$IP3:2379, http://$IP4:2379, dan http://$IP5:2379. Untuk memulai server API Kubernetes:
Jalankan perintah berikut ini:
./etcd --listen-client-urls=http://$IP1:2379, http://$IP2:2379, http://$IP3:2379, http://$IP4:2379, http://$IP5:2379 --advertise-client-urls=http://$IP1:2379, http://$IP2:2379, http://$IP3:2379, http://$IP4:2379, http://$IP5:2379
Start server Kubernetes API dengan flag --etcd-servers=$IP1:2379, $IP2:2379, $IP3:2379, $IP4:2379, $IP5:2379.
Ganti IP dengan alamat IP klien kamu.
Untuk menjalankan penyeimbangan beban (load balancing) untuk klaster etcd:
$LB.--etcd-servers=$LB:2379.Akses ke etcd setara dengan izin root pada klaster sehingga idealnya hanya server API yang memiliki akses ke etcd. Dengan pertimbangan sensitivitas data, disarankan untuk memberikan izin hanya kepada Node-Node yang membutuhkan akses ke klaster etcd.
Untuk mengamankan etcd, tetapkan aturan firewall atau gunakan fitur keamanan yang disediakan oleh etcd. Fitur keamanan etcd tergantung pada Infrastruktur Kunci Publik / Public Key Infrastructure (PKI) x509. Untuk memulai, buat saluran komunikasi yang aman dengan menghasilkan pasangan kunci dan sertifikat. Sebagai contoh, gunakan pasangan kunci peer.key dan peer.cert untuk mengamankan komunikasi antara anggota etcd, dan client.key dan client.cert untuk mengamankan komunikasi antara etcd dan kliennya. Lihat contoh skrip yang disediakan oleh proyek etcd untuk menghasilkan pasangan kunci dan berkas CA untuk otentikasi klien.
Untuk mengonfigurasi etcd dengan secure peer communication, tentukan flag --peer-key-file=peer.key dan --peer-cert-file=peer.cert, dan gunakan https sebagai skema URL.
Demikian pula, untuk mengonfigurasi etcd dengan secure client communication, tentukan flag --key-file=k8sclient.key dan --cert-file=k8sclient.cert, dan gunakan https sebagai skema URL.
Setelah konfigurasi komunikasi aman, batasi akses klaster etcd hanya ke server API Kubernetes. Gunakan otentikasi TLS untuk melakukannya.
Sebagai contoh, anggap pasangan kunci k8sclient.key dan k8sclient.cert dipercaya oleh CA etcd.ca. Ketika etcd dikonfigurasi dengan --client-cert-auth bersama dengan TLS, etcd memverifikasi sertifikat dari klien dengan menggunakan CA dari sistem atau CA yang dilewati oleh flag --trusted-ca-file. Menentukan flag --client-cert-auth=true dan --trusted-ca-file=etcd.ca akan membatasi akses kepada klien yang mempunyai sertifikat k8sclient.cert.
Setelah etcd dikonfigurasi dengan benar, hanya klien dengan sertifikat yang valid dapat mengaksesnya. Untuk memberikan akses kepada server Kubernetes API, konfigurasikan dengan flag --etcd-certfile=k8sclient.cert,--etcd-keyfile=k8sclient.key dan --etcd-cafile=ca.cert.
Etcd klaster mencapai ketersediaan tinggi dengan mentolerir kegagalan dari sebagian kecil anggota. Namun, untuk meningkatkan kesehatan keseluruhan dari klaster, segera ganti anggota yang gagal. Ketika banyak anggota yang gagal, gantilah satu per satu. Mengganti anggota yang gagal melibatkan dua langkah: menghapus anggota yang gagal dan menambahkan anggota baru.
Meskipun etcd menyimpan ID anggota unik secara internal, disarankan untuk menggunakan nama unik untuk setiap anggota untuk menghindari kesalahan manusia. Sebagai contoh, sebuah klaster etcd dengan tiga anggota. Jadikan URL-nya, member1=http://10.0.0.1, member2=http://10.0.0.2, and member3=http://10.0.0.3. Ketika member1 gagal, ganti dengan member4=http://10.0.0.4.
Dapatkan ID anggota yang gagal dari member1:
etcdctl --endpoints=http://10.0.0.2,http://10.0.0.3 member list
Akan tampil pesan berikut:
8211f1d0f64f3269, started, member1, http://10.0.0.1:2380, http://10.0.0.1:2379
91bc3c398fb3c146, started, member2, http://10.0.0.2:2380, http://10.0.0.2:2379
fd422379fda50e48, started, member3, http://10.0.0.3:2380, http://10.0.0.3:2379
Hapus anggota yang gagal:
etcdctl member remove 8211f1d0f64f3269
Akan tampil pesan berikut:
Removed member 8211f1d0f64f3269 from cluster
Tambahkan anggota baru:
./etcdctl member add member4 --peer-urls=http://10.0.0.4:2380
Akan tampil pesan berikut:
Member 2be1eb8f84b7f63e added to cluster ef37ad9dc622a7c4
Jalankan anggota yang baru ditambahkan pada mesin dengan IP 10.0.0.4:
export ETCD_NAME="member4"
export ETCD_INITIAL_CLUSTER="member2=http://10.0.0.2:2380,member3=http://10.0.0.3:2380,member4=http://10.0.0.4:2380"
export ETCD_INITIAL_CLUSTER_STATE=existing
etcd [flags]
Lakukan salah satu dari yang berikut:
--etcd-server untuk membuat Kubernetes mengetahui perubahan konfigurasi, lalu start ulang server API Kubernetes.Untuk informasi lebih lanjut tentang konfigurasi ulang klaster, lihat Dokumentasi Konfigurasi etcd.
Semua objek Kubernetes disimpan dalam etcd. Mencadangkan secara berkala data klaster etcd penting untuk memulihkan klaster Kubernetes di bawah skenario bencana, seperti kehilangan semua Node control plane. Berkas snapshot berisi semua status Kubernetes dan informasi penting. Untuk menjaga data Kubernetes yang sensitif aman, enkripsi berkas snapshot.
Mencadangkan klaster etcd dapat dilakukan dengan dua cara: snapshot etcd bawaan dan snapshot volume.
Fitur snapshot didukung oleh etcd secara bawaan, jadi mencadangkan klaster etcd lebih mudah. Snapshot dapat diambil dari anggota langsung dengan command etcdctl snapshot save atau dengan menyalin member/snap/db berkas dari etcd direktori data yang saat ini tidak digunakan oleh proses etcd. Mengambil snapshot biasanya tidak akan mempengaruhi kinerja anggota.
Di bawah ini adalah contoh untuk mengambil snapshot dari keyspace yang dilayani oleh $ENDPOINT ke berkas snapshotdb:
ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshotdb
# keluar 0
# memverifikasi hasil snapshot
ETCDCTL_API=3 etcdctl --write-out=table snapshot status snapshotdb
+----------+----------+------------+------------+
| HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| fe01cf57 | 10 | 7 | 2.1 MB |
+----------+----------+------------+------------+
Jika etcd berjalan pada volume penyimpanan yang mendukung cadangan, seperti Amazon Elastic Block Store, buat cadangan data etcd dengan mengambil snapshot dari volume penyimpanan.
Peningkatan skala klaster etcd meningkatkan ketersediaan dengan menukarnya untuk kinerja. Penyekalaan tidak akan meningkatkan kinerja atau kemampuan klaster. Aturan umum adalah untuk tidak melakukan penyekalaan naik atau turun untuk klaster etcd. Jangan mengonfigurasi grup penyekalaan otomatis untuk klaster etcd. Sangat disarankan untuk selalu menjalankan klaster etcd statis dengan lima anggota untuk klaster produksi Kubernetes untuk setiap skala yang didukung secara resmi.
Penyekalaan yang wajar adalah untuk meningkatkan klaster dengan tiga anggota menjadi dengan lima anggota, ketika dibutuhkan lebih banyak keandalan. Lihat Dokumentasi Rekonfigurasi etcd untuk informasi tentang cara menambahkan anggota ke klaster yang ada.
Etcd mendukung pemulihan dari snapshot yang diambil dari proses etcd dari versi major.minor. Memulihkan versi dari versi patch lain dari etcd juga didukung. Operasi pemulihan digunakan untuk memulihkan data klaster yang gagal.
Sebelum memulai operasi pemulihan, berkas snapshot harus ada. Ini bisa berupa berkas snapshot dari operasi pencadangan sebelumnya, atau dari sisa direktori data. Untuk informasi dan contoh lebih lanjut tentang memulihkan klaster dari berkas snapshot, lihat dokumentasi pemulihan bencana etcd.
Jika akses URL dari klaster yang dipulihkan berubah dari klaster sebelumnya, maka server API Kubernetes harus dikonfigurasi ulang sesuai dengan URL tersebut. Pada kasus ini, start kembali server API Kubernetes dengan flag --etcd-servers=$NEW_ETCD_CLUSTER bukan flag --etcd-servers=$OLD_ETCD_CLUSTER. Ganti $NEW_ETCD_CLUSTER dan $OLD_ETCD_CLUSTER dengan alamat IP masing-masing. Jika load balancer digunakan di depan klaster etcd, kamu mungkin hanya perlu memperbarui load balancer sebagai gantinya.
Jika mayoritas anggota etcd telah gagal secara permanen, klaster etcd dianggap gagal. Dalam skenario ini, Kubernetes tidak dapat membuat perubahan apa pun ke kondisi saat ini. Meskipun Pod terjadwal mungkin terus berjalan, tidak ada Pod baru yang bisa dijadwalkan. Dalam kasus seperti itu, pulihkan klaster etcd dan kemungkinan juga untuk mengonfigurasi ulang server API Kubernetes untuk memperbaiki masalah ini.
Pada Kubernetes v1.13.0, etcd2 tidak lagi didukung sebagai backend penyimpanan untuk klaster Kubernetes baru atau yang sudah ada. Timeline untuk dukungan Kubernetes untuk etcd2 dan etcd3 adalah sebagai berikut:
kube-up.sh adalah etcd3,
dan kube-apiserver standarnya ke etcd3kube-apiserver akan
menolak untuk start dengan --storage-backend=etcd2, dengan pesan
etcd2 is no longer a supported storage backendSebelum memutakhirkan v1.12.x kube-apiserver menggunakan --storage-backend=etcd2 ke
v1.13.x, data etcd v2 harus dimigrasikan ke backend penyimpanan v3 dan
permintaan kube-apiserver harus diubah untuk menggunakan --storage-backend=etcd3.
Proses untuk bermigrasi dari etcd2 ke etcd3 sangat tergantung pada bagaimana klaster etcd diluncurkan dan dikonfigurasi, serta bagaimana klaster Kubernetes diluncurkan dan dikonfigurasi. Kami menyarankan kamu berkonsultasi dengan dokumentasi penyedia klaster kamu untuk melihat apakah ada solusi yang telah ditentukan.
Jika klaster kamu dibuat melalui kube-up.sh dan masih menggunakan etcd2 sebagai penyimpanan backend, silakan baca Kubernetes v1.12 etcd cluster upgrade docs
Klien etcd v3, dirilis pada etcd v3.3.13 atau sebelumnya, memiliki critical bug yang mempengaruhi kube-apiserver dan penyebaran HA. Pemindahan kegagalan (failover) penyeimbang klien etcd tidak bekerja dengan baik dengan secure endpoint. Sebagai hasilnya, server etcd boleh gagal atau terputus sesaat dari kube-apiserver. Hal ini mempengaruhi peluncuran HA dari kube-apiserver.
Perbaikan dibuat di etcd v3.4 (dan di-backport ke v3.3.14 atau yang lebih baru): klien baru sekarang membuat bundel kredensial sendiri untuk menetapkan target otoritas dengan benar dalam fungsi dial.
Karena perbaikan tersebut memerlukan pemutakhiran dependensi dari gRPC (ke v1.23.0), downstream Kubernetes tidak mendukung upgrade etcd, yang berarti perbaikan etcd di kube-apiserver hanya tersedia mulai Kubernetes 1.16.
Untuk segera memperbaiki celah keamanan (bug) ini untuk Kubernetes 1.15 atau sebelumnya, buat kube-apiserver khusus. kamu dapat membuat perubahan lokal ke vendor/google.golang.org/grpc/credentials/credentials.go dengan etcd@db61ee106.
Lihat "kube-apiserver 1.13.x menolak untuk bekerja ketika server etcd pertama tidak tersedia".
Objek-objek Kubernetes dapat dibuat, diperbarui, dan dihapus dengan menjalankan perintah kubectl apply terhadap file-file konfigurasi objek yang disimpan dalam sebuah direktori secara rekursif sesuai dengan kebutuhan. Perintah kubectl diff bisa digunakan untuk menampilkan pratinjau tentang perubahan apa saja yang akan dibuat oleh perintah kubectil apply.
Perintah kubectl memungkinkan tiga cara untuk mengelola objek:
Lihat Pengelolaan Objek Kubernetes untuk menyimak diskusi mengenai kelebihan dan kekurangan dari tiap cara pengelolaan objek.
Konfigurasi objek secara deklaratif membutuhkan pemahaman yang baik tentang definisi dan konfigurasi objek-objek Kubernetes. Jika belum pernah, kamu disarankan untuk membaca terlebih dulu dokumen-dokumen berikut:
Berikut adalah beberapa defnisi dari istilah-istilah yang digunakan dalam dokumen ini:
kubectl apply. File-file konfigurasi biasanya disimpan di sebuah source control seperti Git.kubectl apply untuk menulis perubahan-perubahan tersebut.Gunakan perintah kubectl apply untuk membuat semua objek, kecuali objek-objek yang sudah ada sebelumnya, yang didefinisikan di file-file konfigurasi dalam direktori yang ditentukan:
kubectl apply -f <directory>/
Perintah di atas akan memberi anotasi kubectl.kubernetes.io/last-applied-configuration: '{...}' pada setiap objek yang dibuat. Anotasi ini berisi konten dari file konfigurasi objek yang digunakan untuk membuat objek tersebut.
-R untuk memproses seluruh direktori secara rekursif.Berikut sebuah contoh file konfigurasi objek:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
minReadySeconds: 5
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Jalankan perintah kubectl diff untuk menampilkan objek yang akan dibuat:
kubectl diff -f https://k8s.io/examples/application/simple_deployment.yaml
Buat objek dengan perintah kubectl apply:
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
Tampilkan konfigurasi live dengan perintah kubectl get:
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
Keluaran perintah di atas akan menunjukkan bahwa anotasi kubectl.kubernetes.io/last-applied-configuration sudah dituliskan ke konfigurasi live, dan anotasi tersebut sesuai dengan file konfigurasi:
kind: Deployment
metadata:
annotations:
# ...
# Ini merupakan representasi dari simple_deployment.yaml dalam format json
# Ini ditulis oleh perintah `kubectl apply` ketika objek dibuat
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.7.9
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
Kamu juga bisa menggunakan kubectl apply untuk memperbarui semua objek yang didefinisikan dalam sebuah direktori, termasuk objek-objek yang sudah ada sebelumnya. Cara ini akan melakukan hal-hal berikut:
kubectl diff -f <directory>/
kubectl apply -f <directory>/
-R untuk memproses seluruh direktori secara rekursif.Berikut sebuah contoh file konfigurasi:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
minReadySeconds: 5
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Buat objek dengan perintah kubectl apply::
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
Tampilkan konfigurasi live dengan perintah kubectl get:
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
Keluaran perintah di atas akan menunjukkan bahwa anotasi kubectl.kubernetes.io/last-applied-configuration sudah dituliskan ke konfigurasi live, dan anotasi tersebut sesuai dengan file konfigurasi:
kind: Deployment
metadata:
annotations:
# ...
# Berikut merupakan representasi dari simple_deployment.yaml dalam format json
# Representasi berikut ditulis oleh perintah kubectl apply ketika objek dibuat
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.7.9
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
Perbarui nilai replicas secara langsung di konfigurasi live dengan menggunakan perintah kubectl scale. Pembaruan ini tidak menggunakan perintah kubectl apply:
kubectl scale deployment/nginx-deployment --replicas=2
Tampilkan konfigurasi live dengan perintah kubectl get:
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
Keluaran perintah di atas akan menunjukkan bahwa nilai replicas telah diubah menjadi 2, dan anotasi last-applied-configuration tidak memuat nilai replicas:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# perhatikan bahwa anotasi tidak memuat nilai replicas
# karena nilai tersebut tidak diperbarui melalui perintah kubectl-apply
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
replicas: 2 # ditulis oleh perintah kubectl scale
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.7.9
# ...
name: nginx
ports:
- containerPort: 80
# ...
Perbarui file konfigurasi simple_deployment.yaml, ubah image dari nginx:1.7.9 ke nginx:1.11.9, dan hapus field minReadySeconds:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.11.9 # perbarui image
ports:
- containerPort: 80
Terapkan perubahan yang telah dibuat di file konfigurasi:
kubectl diff -f https://k8s.io/examples/application/update_deployment.yaml
kubectl apply -f https://k8s.io/examples/application/update_deployment.yaml
Tampilkan konfigurasi live dengan perintah kubectl get:
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
Keluaran perintah di atas akan menunjukkan perubahan-perubahan berikut pada konfiguasi live:
replicas tetap bernilai 2 sesuai dengan nilai yang diatur oleh perintah kubectl scale. Hal ini karena field replicas dihapuskan dari file konfigurasi.image telah diperbarui menjadi nginx:1.11.9 dari nginx:1.7.9.last-applied-configuration telah diperbari dengan image terbaru.minReadySeconds telah dihapus.last-applied-configuration tidak lagi memuat field minReadySeconds.apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# Anotasi memuat image yang telah diperbarui ke nginx 1.11.9,
# tetapi tidak memuat nilai replica yang telah diperbarui menjadi 2
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.11.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
replicas: 2 # Diatur oleh `kubectl scale`, tidak diubah oleh `kubectl apply`.
# minReadySeconds dihapuskan oleh `kubectl apply`
# ...
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.11.9 # Diatur oleh `kubectl apply`
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
kubectl apply dengan perintah imperatif untuk konfigurasi objek seperti create dan replace tidak dimungkinkan. Hal ini karena create dan replace tidak menyimpan anotasi kubectl.kubernetes.io/last-applied-configuration yang diperlukan oleh kubectl aplly untuk melakukan pembaruan.Ada dua cara untuk menghapus objek-objek yang dikelola dengan kubectl apply.
kubectl delete -f <filename>Penghapusan objek secara manual dengan menggunakan perintah imperatif merupakan cara yang direkomendasikan karena lebih eksplisit dalam menentukan objek apa yang akan dihapus dan lebih kecil kemungkinannya untuk pengguna menghapus objek lain secara tidak sengaja:
kubectl delete -f <filename>
kubectl apply -f <directory/> --prune -l your=labelLakukan ini hanya jika kamu benar-benar mengetahui apa yang kamu lakukan.
kubectl apply --prune masih dalam versi alpha dan perubahan-perubahan yang tidak memiliki kompatibilitas dengan versi sebelumnya mungkin akan diperkenalkan pada rilis-rilis berikutnya.Sebagai alternatif dari kubectl delete, kamu bisa menggunakan kubectl apply untuk mengidentifikasi objek-objek yang hendak dihapus setelah berkas konfigurasi objek-objek tersebut dihapus dari direktori. Ketika dijalankan dengan argumen --prune, perintah kubectl apply akan melakukan query ke API server untuk mencari semua objek yang sesuai dengan himpunan label-label tertentu, dan berusaha untuk mencocokkan kofigurasi objek live yg diperoleh terhadap file konfigurasi objek. Jika sebuah objek cocok dengan query yang dilakukan, dan objek tersebut tidak memiliki file konfigurasi di direktori serta tidak memiliki anotasi last-applied-configuration, objek tersebut akan dihapus.
kubectl apply -f <directory/> --prune -l <labels>
kubectl apply dengan argumen --prune sebaiknya hanya dijalankan terhadap direktori root yang berisi file-file konfigurasi objek. Menjalankan perintah tadi terhadap sub direktori bisa menyebabkan terhapusnya objek-objek lain secara tidak disengaja jika objek-objek tersebut memenuhi kriteria selektor label yang dispesifikasikan oleh argumen -l <label> dan tidak muncul di sub direktori.Kamu bisa menggunakan perintah kubectl get dengan parameter -o yaml untuk melihat konfigurasi dari sebuah objek live:
kubectl get -f <filename|url> -o yaml
kubectl apply menghitung perbedaan dan menggabungkan perubahanKetika memperbarui konfigurasi live dari sebuah objek, kubectl apply melakukannya dengan mengirimkan request untuk melakukan patch ke API server. Patch mendefinisikan pembaruan-pembaruan yang likungpnya sepsifik terhadap sejumlah field dari objek konfigurasi live. Perintah kubectl apply menghitung patch request ini menggunakan file konfigurasi, konfigurasi live, dan anotasi last-applied-configuration yang tersimpan di konfigurasi live.
Perintah kubectl apply menulis konten dari berkas konfigurasi ke anotasi kubectl.kubernetes.io/last-applied-configuration. Ini digunakan untuk mengidentifikasi field apa saja yang telah dihapus dari file konfigurasi dan perlu dihapus dari konfigurasi live. Berikut adalah langkah-langkah yang digunakan untuk menghitung field apa saja yang harus dihapus atau diubah:
last-applied-configuration tapi tidak ada di file konfigurasi.Agar lebih jelas, simak contoh berikut. Misalkan, berikut adalah file konfigurasi untuk sebuah objek Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.11.9 # perbarui image
ports:
- containerPort: 80
Juga, misalkan, berikut adalah konfigurasi live dari objek Deployment yang sama:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# perhatikan bagaimana anotasi berikut tidak memuat replicas
# karena replicas tidak diperbarui melalui perintah kubectl apply
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
replicas: 2 # ditulis oleh perintah kubectl scale
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.7.9
# ...
name: nginx
ports:
- containerPort: 80
# ...
Berikut merupakan perhitungan penggabungan yang akan dilakukan oleh perintah kubectl apply:
last-applied-configuration dan membandingkannya dengan nilai yang ada di file konfigurasi. Hapus semua field yang nilainya secara eksplisit diubah menjadi null pada file konfigurasi objek lokal terlepas dari apakah field-field tersebut ada di anotasi last-applied-configuration atau tidak. Pada contoh di atas, field minReadySeconds muncul pada anotasi last-applied-configuration, tapi tidak ada di file konfigurasi. Aksi: Hapus minReadySeconds dari konfigurasi live.image di file konfigurasi tidak sama dengan nilai dari konfigurasi live. Aksi: Ubah nilai image pada konfigurasi live.last-applied-configuration agar sesuai dengan nilai yang ada di file konfigurasi.Berikut konfigurasi live yang dihasilkan oleh proses penggabungan pada contoh di atas:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# Anotasi memuat pembaruan image menjadi nginx 1.11.9,
# tetapi tidak memuat pembaruan replicas menjadi 2
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.11.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
selector:
matchLabels:
# ...
app: nginx
replicas: 2 # Diubah oleh `kubectl scale`, tidak diubah oleh `kubectl apply`.
# minReadySeconds dihapus oleh `kubectl apply`
# ...
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.11.9 # Diubah oleh `kubectl apply`
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
Cara sebuah field terentu dalam sebuah file konfigurasi digabungkan dengan konfigurasi live bergantung pada tipe field tersebut. Ada beberapa tipe field:
primitif: field yang bertipe string, integer, atau boolean. Sebagai contoh, image dan replicas termasuk sebagai field primitif. Aksi: Replace.
map, atau objek: field yang bertipe map atau tipe kompleks yang mengandung sub field. Sebagai contoh, labels, annotations, spec, dan metadata termasuk sebagai map. Aksi: Lakukan penggabungan tiap-tiap elemen atau sub field.
list: field yang berisi sejumlah item yang tiap itemnya bisa berupa tipe primitif maupun map. Sebagai contoh, containers, ports, dan args termasuk sebagai list. Aksi: Bervariasi.
Ketika digunakan untuk memperbarui sebuah field bertipe map atau list, perintah kubectl apply memperbarui nilai tiap-tiap sub elemen ketimbang mengganti nilai semua field. Misalnya, ketika menggabungkan field spec pada sebuah Deployment, bukan keseluruhan field spec yang diubah nilainya. Alih-alih, sub field dari spec seperti replicas yang kemudian dibandingkan nilainya dan digabungkan.
Field primitif diganti nilainya atau dihapus sama sekali.
- digunakan untuk menandai sebuah nilai "not applicable" karena nilai tersebut tidak digunakan.| Field pada file konfigurasi objek | Field pada objek konfigurasi live | Field pada last-applied-configuration | Aksi |
|---|---|---|---|
| Ya | Ya | - | Ubah nilai di konfigurasi live mengikuti nilai pada file konfigurasi. |
| Ya | Tidak | - | Ubah nilai di konfigurasi live mengikuti nilai pada konfigurasi lokal. |
| Tidak | - | Ya | Hapus dari konfigurasi live. |
| Tidak | - | Tidak | Tidak melakukan apa-apa, pertahankan nilai konfigurasi live. |
Field yang bertipe map digabungkan dengan membandingkan tiap sub field atau elemen dari map:
- digunakan untuk menandai sebuah nilai "not applicable" karena nilai tersebut tidak digunakan.| Key pada file konfigurasi objek | Key pada objek konfigurasi live | Field pada last-applied-configuration | Aksi |
|---|---|---|---|
| Ya | Ya | - | Bandingkan nilai tiap sub field. |
| Ya | Tidak | - | Ubah nilai pada konfigurasi live mengikuti nilai pada konfigurasi lokal. |
| Tidak | - | Ya | Hapus dari konfigurasi live. |
| Tidak | - | Tidak | Tidak melakukan apa-apa, pertahankan nilai konfigurasi live. |
Penggabungan perubahan pada sebuah list bisa menggunakan salah satu dari tiga strategi:
Pilihan strategi dibuat berbeda-beda bergantung tipe tiap field.
Perlakukan list sama dengan field primitif. Ganti atau hapus keseluruhan list. Ini akan menjaga urutan dari list.
Contoh: Gunakan kubectl apply untuk memperbarui field args pada sebuah kontainer di dalam sebuah pod. Ini akan mengubah nilai args di konfigurasi live mengikuti nilai di file konfigurasi. Elemen args apapun yang sebelumnya ditambahkan ke konfigurasi live akan hilang. Urutan dari elemen-elemen args yang didefinisikan di file konfigurasi akan dipertahankan ketika ditulis ke konfigurasi live.
# nilai last-applied-configuration*
args: ["a", "b"]
# nilai berkas konfigurasi
args: ["a", "c"]
# nilai konfigurasi live
args: ["a", "b", "d"]
# hasil setelah penggabungan
args: ["a", "c"]
Penjelasan: Penggabungan menggunakan nilai pada file konfigurasi sebagai nilai baru untuk list args.
Perlakukan list selayaknya sebuah map, perlakukan field spesifik dari tiap element sebagai sebuah key. Tambah, hapus, atau perbarui tiap-tiap elemen. Operasi ini tidak mempertahankan urutan elemen di dalam list.
Strategi penggabungan ini menggunakan tag khusus patchMergeKey pada tiap field. Tag patchMergeKey didefinisikan untuk tiap field pada source code Kubernetes: types.go. Ketika menggabungkan sebuah list yang berisi map, field yang dispesifikasikan sebagai patchMergeKey untuk tiap elemen digunakan sebagai map key untuk elemen tersebut.
Contoh: Gunakan kubectl apply untuk memperbarui field containers pada sebuah PodSpec. Perintah ini akan menggabungkan list containers seolah-olah list tersebut adalah sebuah map dan tiap elemennya menggunakan name sebagai key.
# nilai last-applied-configuration
containers:
- name: nginx
image: nginx:1.10
- name: nginx-helper-a # key: nginx-helper-a; akan dihapus pada hasil akhir
image: helper:1.3
- name: nginx-helper-b # key: nginx-helper-b; akan dipertahankan pada hasil akhir
image: helper:1.3
# nilai berkas konfigurasi
containers:
- name: nginx
image: nginx:1.10
- name: nginx-helper-b
image: helper:1.3
- name: nginx-helper-c # key: nginx-helper-c; akan ditambahkan pada hasil akhir
image: helper:1.3
# konfigurasi live
containers:
- name: nginx
image: nginx:1.10
- name: nginx-helper-a
image: helper:1.3
- name: nginx-helper-b
image: helper:1.3
args: ["run"] # Field ini akan dipertahankan pada hasil akhir
- name: nginx-helper-d # key: nginx-helper-d; akan dipertahankan pada hasil akhir
image: helper:1.3
# hasil akhir setelah penggabungan
containers:
- name: nginx
image: nginx:1.10
# Elemen nginx-helper-a dihapus
- name: nginx-helper-b
image: helper:1.3
args: ["run"] # Field dipertahankan
- name: nginx-helper-c # Elemen ditambahkan
image: helper:1.3
- name: nginx-helper-d # Elemen tidak diubah
image: helper:1.3
Penjelasan:
args pada konfigurasi live. Perintah kubectl apply bisa mengenali bahwa "nginx-helper-b" di konfigurasi live sama dengan "ngnix-helper-b" di file konfigurasi, meskipun keduanya memiliki field yang berbeda (tidak ada args pada file konfigurasi). Ini karena nilai patchMergeKey di kedua konfigurasi identik.Pada versi Kubernetes 1.5, penggabungan list dengan elemen-elemen primitif tidak lagi didukung.
patchStrategy pada types.go. Jika patchStrategy tidak ditentukan untuk sebuah field yang bertipe list, maka list tersebut akan diubah nilainya secara keseluruhan.API server mengisi field tertentu dengan nilai default pada konfigurasi live jika nilai field-field tersebut tidak dispesifikasikan ketika objek dibuat.
Berikut adalah sebuah file konfigurasi untuk sebuah Deployment. Berkas berikut tidak menspesifikasikan strategy:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
minReadySeconds: 5
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Buat objek dengan perintah kubectl apply:
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
Tampilkan konfigurasi live dengan perintah kubectl get:
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
Keluaran dari perintah tadi menunjukkan bahwa API server mengisi beberapa field dengan nilai default pada konfigurasi live. Field-field berikut tidak dispesifikan pada file konfigurasi.
apiVersion: apps/v1
kind: Deployment
# ...
spec:
selector:
matchLabels:
app: nginx
minReadySeconds: 5
replicas: 1 # nilai default dari apiserver
strategy:
rollingUpdate: # nilai default dari apiserver - diturunkan dari strategy.type
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate # nilai default dari apiserver
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.7.9
imagePullPolicy: IfNotPresent # nilai default dari apiserver
name: nginx
ports:
- containerPort: 80
protocol: TCP # nilai default dari apiserver
resources: {} # nilai default dari apiserver
terminationMessagePath: /dev/termination-log # nilai default dari apiserver
dnsPolicy: ClusterFirst # nilai default dari apiserver
restartPolicy: Always # nilai default dari apiserver
securityContext: {} # nilai default dari apiserver
terminationGracePeriodSeconds: 30 # nilai default dari apiserver
# ...
Dalam sebuah patch request, field-field dengan nilai default tidak diisi kembali dengan nilai default kecuali secara eksplisit nilainya dihapuskan sebagai bagian dari patch request. Ini bisa menimbulkan hasil yang tak terduga jika sebagian field diisi dengan nilai default yang diturunkan dari nilai field lainnya. Ketika field lain tersebut nilainya diubah, field-field yang diisi dengan nilai default berdasarkan field yang berubah tadi tidak akan diperbarui kecuali secara eksplisit dihapus.
Oleh karena itu, beberapa field yang nilainya diisi secara default oleh server perlu didefinisikan secara eksplisit di file konfigurasi, meskipun nilai yang diinginkan sudah sesuai dengan nilai default dari server. Ini untuk mempermudah mengenali nilai-nilai yang berselisih yang tidak akan diisi dengan nilai default oleh server.
Contoh:
# last-applied-configuration
spec:
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
# berkas konfigurasi
spec:
strategy:
type: Recreate # nilai yang diperbarui
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
# konfigurasi live
spec:
strategy:
type: RollingUpdate # nilai default
rollingUpdate: # nilai default yang diturunkan dari type
maxSurge : 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
# hasil setelah penggabungan - ERROR!
spec:
strategy:
type: Recreate # nilai yang diperbarui: tidak kompatibel dengan field rollingUpdate
rollingUpdate: # nilai default: tidak kompatibel dengan "type: Recreate"
maxSurge : 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Penjelasan:
strategy.type (seperti yang bisa dilihat pada last-applied-configuration).strategy.type dengan nilai default RollingUpdate dan mengisi strategy.rollingUpdate dengan nilai default pada konfigurasi live.strategy.type menjadi Recreate pada file konfigurasi. Nilai strategy.rollingUpdate tidak berubah dari nilai default, meskipun server sekarang berekspektasi nilai tersebut dihapus. Jika nilai strategy.rollingUpdate didefinisikan di awal pada file konfigurasi, akan jelas bagi server bahwa field tersebut perlu dihapus.kubect apply gagal karena strategy.rollingUpdate tidak dihapus. Field strategy.rollingUpdate tidak bisa didefinisikan jika field strategy.type berisi Recreate.Rekomendasi: Field-field ini harus didefinisikan secara eksplisit di file konfigurasi objek:
Field-field yang tidak muncul di file konfigurasi bisa dihilangkan dengan mengisi nilainya dengan null dan kemudian jalankan kubectl apply dengan file konfigurasi tersebut. Untuk field-field yang nilainya diisi dengan nilai default oleh server, aksi ini akan mmenyebabkan pengisian ulang field dengan nilai default.
Hanya metode-metode berikut yang bisa kamu gunakan untuk mengubah satu field objek:
kubectl apply.kubectl scale.Tambahkan field ke file konfigurasi. Hentikan pembaruan secara langsung ke konfigurasi live tanpa melalui kubectl apply.
Pada versi Kubernetes 1.5, mengubah kepemilikan sebuah field dari file konfigurasi memerlukan langkah-langkah manual:
kubectl.kubernetes.io/last-applied-configuration pada objek live.Objek-objek Kubernetes sebaiknya dikelola dengan satu metode dalam satu waktu. Berpindah dari satu metode ke metode lain dimungkinkan, tetapi memerlukan proses manual.
Migrasi dari pengelolaan objek dengan perintah imperatif ke pengelolaan objek dengan konfigurasi deklaratif memerlukan beberapa langkah manual:
Ekspor objek live ke file konfigurasi lokal:
kubectl get <kind>/<name> -o yaml > <kind>_<name>.yaml
Hapus secara manual field status dari file konfigurasi.
Tahap ini opsional, karena `kubectl apply` tidak memperbarui *field* status meskipun *field* tersebut ada di *file* konfigurasi.
Ubah anotasi kubectl.kubernetes.io/last-applied-configuration pada objek:
kubectl replace --save-config -f <kind>_<name>.yaml
Selanjutnya gunakan kubectl apply secara eksklusif untuk mengelola objek.
Atur anotasi kubectl.kubernetes.io/last-applied-configuration pada objek:
kubectl replace --save-config -f <kind>_<name>.yaml
Gunakan selalu perintah kubectl apply saja untuk mengelola objek.
Cara yang disarankan adalah dengan mendefinisikan sebuah PodTemplate immutable yang hanya digunakan oleh selektor controller tanpa memiliki arti semantik lainnya.
Contoh:
selector:
matchLabels:
controller-selector: "extensions/v1beta1/deployment/nginx"
template:
metadata:
labels:
controller-selector: "extensions/v1beta1/deployment/nginx"
Kustomize merupakan sebuah alat untuk melakukan kustomisasi objek Kubernetes melalui sebuah berkas berkas kustomization.
Sejak versi 1.14, kubectl mendukung pengelolaan objek Kubernetes melalui berkas kustomization. Untuk melihat sumber daya yang ada di dalam direktori yang memiliki berkas kustomization, jalankan perintah berikut:
kubectl kustomize <direktori_kustomization>
Untuk menerapkan sumber daya tersebut, jalankan perintah kubectl apply dengan flag --kustomize atau -k:
kubectl apply -k <kustomization_directory>
Instal kubectl terlebih dahulu.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Kustomize adalah sebuah alat untuk melakukan kustomisasi konfigurasi Kubernetes. Untuk mengelola berkas-berkas konfigurasi, kustomize memiliki fitur -fitur di bawah ini:
ConfigMap dan Secret menyimpan konfigurasi atau data sensitif yang digunakan oleh objek-objek Kubernetes lainnya, seperti Pod.
Biasanya, source of truth dari ConfigMap atau Secret berasal dari luar klaster, seperti berkas .properties atau berkas kunci SSH.
Kustomize memiliki secretGenerator dan configMapGenerator, yang akan membangkitkan (generate) Secret dan ConfigMap dari berkas-berkas atau nilai-nilai literal.
Untuk membangkitkan sebuah ConfigMap dari berkas, tambahkan entri ke daftar files pada configMapGenerator.
Contoh di bawah ini membangkitkan sebuah ConfigMap dengan data dari berkas .properties:
# Membuat berkas application.properties
cat <<EOF >application.properties
FOO=Bar
EOF
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-1
files:
- application.properties
EOF
ConfigMap yang telah dibangkitkan dapat dilihat menggunakan perintah berikut:
kubectl kustomize ./
Isinya seperti di bawah ini:
apiVersion: v1
data:
application.properties: |
FOO: Bar
kind: ConfigMap
metadata:
name: example-configmap-1-42cfbf598f
ConfigMap juga dapat dibangkitkan dari pasangan key-value literal. Untuk membangkitkan secara literal, tambahkan entri pada daftar literals di configMapGenerator.
Contoh di bawah ini membangkitkan ConfigMap dengan data dari pasangan key-value:
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-2
literals:
- FOO=Bar
EOF
ConfigMap yang dibangkitkan dapat dilihat menggunakan perintah berikut:
kubectl kustomize ./
Isinya seperti ini:
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
name: example-configmap-2-g2hdhfc6tk
Kamu dapat membangkitkan Secret dari berkas atau pasangan key-value literal. Untuk membangkitkan dari berkas, tambahkan entri pada daftar files di secretGenerator.
Contoh di bawah ini membangkitkan Secret dengan data dari berkas:
# Membuat berkas password.txt
cat <<EOF >./password.txt
username=admin
password=secret
EOF
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: example-secret-1
files:
- password.txt
EOF
Isinya seperti ini:
apiVersion: v1
data:
password.txt: dXNlcm5hbWU9YWRtaW4KcGFzc3dvcmQ9c2VjcmV0Cg==
kind: Secret
metadata:
name: example-secret-1-t2kt65hgtb
type: Opaque
Untuk membangkitkan secara literal dari pasangan key-value, tambahkan entri pada daftar literals di secretGenerator.
Contoh di bawah ini membangkitkan Secret dengan data dari pasangan key-value:
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: example-secret-2
literals:
- username=admin
- password=secret
EOF
Isinya seperti ini:
apiVersion: v1
data:
password: c2VjcmV0
username: YWRtaW4=
kind: Secret
metadata:
name: example-secret-2-t52t6g96d8
type: Opaque
ConfigMap dan Secret yang dibangkitkan memiliki informasi sufiks hash. Hal ini memastikan bahwa ConfigMap atau Secret yang baru, dibangkitkan saat isinya berubah.
Untuk menonaktifkan penambahan sufiks ini, kamu bisa menggunakan generatorOptions. Selain itu, melalui field ini kamu juga bisa mengatur opsi-opsi yang bersinggungan untuk ConfigMap dan Secret yang dibangkitkan.
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-3
literals:
- FOO=Bar
generatorOptions:
disableNameSuffixHash: true
labels:
type: generated
annotations:
note: generated
EOF
Jalankan perintah kubectl kustomize ./ untuk melihat ConfigMap yang dibangkitkan:
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
annotations:
note: generated
labels:
type: generated
name: example-configmap-3
Mengatur field-field yang bersinggungan untuk semua sumber daya Kubernetes dalam sebuah proyek. Beberapa contoh kasusnya seperti di bawah ini:
Lihat contoh di bawah ini:
# Membuat sebuah deployment.yaml
cat <<EOF >./deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
EOF
cat <<EOF >./kustomization.yaml
namespace: my-namespace
namePrefix: dev-
nameSuffix: "-001"
commonLabels:
app: bingo
commonAnnotations:
oncallPager: 800-555-1212
resources:
- deployment.yaml
EOF
Jalankan perintah kubectl kustomize ./ untuk melihat field-field tersebut telah terisi di dalam sumber daya Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: bingo
name: dev-nginx-deployment-001
namespace: my-namespace
spec:
selector:
matchLabels:
app: bingo
template:
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: bingo
spec:
containers:
- image: nginx
name: nginx
Mengkomposisi kumpulan sumber daya dalam sebuah proyek dan mengelolanya di dalam berkas atau direktori yang sama merupakan hal yang cukup umum dilakukan. Kustomize menyediakan cara untuk mengkomposisi sumber daya dari berkas-berkas yang berbeda, lalu menerapkan patch atau kustomisasi lain di atasnya.
Kustomize mendukung komposisi dari berbagai sumber daya yang berbeda. Field resources pada berkas kustomization.yaml, mendefinisikan daftar sumber daya yang diinginkan dalam sebuah konfigurasi. Atur terlebih dahulu jalur (path) ke berkas konfigurasi sumber daya pada daftar resources.
Contoh di bawah ini merupakan sebuah aplikasi NGINX yang terdiri dari sebuah Deployment dan sebuah Service:
# Membuat berkas deployment.yaml
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Membuat berkas service.yaml
cat <<EOF > service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
EOF
# Membuat berkas kustomization.yaml yang terdiri dari keduanya
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
- service.yaml
EOF
Sumber daya dari kubectl kustomize ./ berisi kedua objek Deployment dan Service.
Patch dapat digunakan untuk menerapkan berbagai macam kustomisasi pada sumber daya. Kustomize mendukung berbagai mekanisme patching yang berbeda melalui patchesStrategicMerge dan patchesJson6902. patchesStrategicMerge adalah daftar dari yang berisi tentang path berkas. Setiap berkas akan dioperasikan dengan cara strategic merge patch. Nama di dalam patch harus sesuai dengan nama sumber daya yang telah dimuat. Kami menyarankan patch-patch kecil yang hanya melakukan satu hal saja.
Contoh membuat sebuah patch di bawah ini akan menambahkan jumlah replika Deployment dan patch lainnya untuk mengatur limit memori.
# Membuat berkas deployment.yaml
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Membuat sebuah patch increase_replicas.yaml
cat <<EOF > increase_replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
EOF
# Membuat patch lainnya set_memory.yaml
cat <<EOF > set_memory.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
template:
spec:
containers:
- name: my-nginx
resources:
limits:
memory: 512Mi
EOF
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
patchesStrategicMerge:
- increase_replicas.yaml
- set_memory.yaml
EOF
Jalankan perintah kubectl kustomize ./ untuk melihat isi dari Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: nginx
limits:
memory: 512Mi
name: my-nginx
ports:
- containerPort: 80
Tidak semua sumber daya atau field mendukung strategic merge patch. Untuk mendukung field sembarang pada sumber daya field, Kustomize
menyediakan penerapan patch JSON melalui patchesJson6902.
Untuk mencari sumber daya yang tepat dengan sebuah patch Json, maka grup, versi, jenis dan nama dari sumber daya harus dispesifikasikan dalam kustomization.yaml.
Contoh di bawah ini menambahkan jumlah replika dari objek Deployment yang bisa juga dilakukan melalui patchesJson6902.
# Membuat berkas deployment.yaml
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Membuat patch json
cat <<EOF > patch.yaml
- op: replace
path: /spec/replicas
value: 3
EOF
# Membuat berkas kustomization.yaml
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
patchesJson6902:
- target:
group: apps
version: v1
kind: Deployment
name: my-nginx
path: patch.yaml
EOF
Jalankan perintah kubectl kustomize ./ untuk melihat field replicas yang telah diperbarui:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: nginx
name: my-nginx
ports:
- containerPort: 80
Selain patch, Kustomize juga menyediakan cara untuk melakukan kustomisasi image Container atau memasukkan nilai field dari objek lainnya ke dalam Container tanpa membuat patch. Sebagai contoh, kamu dapat melakukan kustomisasi image yang digunakan di dalam Container dengan menyebutkan spesifikasi field images di dalam kustomization.yaml.
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
images:
- name: nginx
newName: my.image.registry/nginx
newTag: "1.4.0"
EOF
Jalankan perintah kubectl kustomize ./ untuk melihat image yang sedang digunakan telah diperbarui:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 2
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: my.image.registry/nginx:1.4.0
name: my-nginx
ports:
- containerPort: 80
Terkadang, aplikasi yang berjalan di dalam Pod perlu untuk menggunakan nilai konfigurasi dari objek lainnya.
Contohnya, sebuah Pod dari objek Deployment perlu untuk membaca nama Service dari Env atau sebagai argumen perintah.
Ini karena nama Service bisa saja berubah akibat dari penambahan namePrefix atau nameSuffix pada berkas kustomization.yaml.
Kami tidak menyarankan kamu untuk meng-hardcode nama Service di dalam argumen perintah.
Untuk penggunaan ini, Kustomize dapat memasukkan nama Service ke dalam Container melalui vars.
# Membuat berkas deployment.yaml
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
command: ["start", "--host", "\$(MY_SERVICE_NAME)"]
EOF
# Membuat berkas service.yaml
cat <<EOF > service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
EOF
cat <<EOF >./kustomization.yaml
namePrefix: dev-
nameSuffix: "-001"
resources:
- deployment.yaml
- service.yaml
vars:
- name: MY_SERVICE_NAME
objref:
kind: Service
name: my-nginx
apiVersion: v1
EOF
Jalankan perintah kubectl kustomize ./ untuk melihat nama Service yang dimasukkan ke dalam Container menjadi dev-my-nginx-001:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dev-my-nginx-001
spec:
replicas: 2
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- command:
- start
- --host
- dev-my-nginx-001
image: nginx
name: my-nginx
Kustomize memiliki konsep base dan overlay. base merupakan direktori dengan kustomization.yaml, yang berisi
sekumpulan sumber daya dan kustomisasi yang terkait. base dapat berupa direktori lokal maupun direktori dari repo remote,
asalkan berkas kustomization.yaml ada di dalamnya. overlay merupakan direktori dengan kustomization.yaml yang merujuk pada
direktori kustomization lainnya sebagai base-nya. base tidak memiliki informasi tentang overlay. dan dapat digunakan pada beberapa overlay sekaligus.
overlay bisa memiliki beberapa base dan terdiri dari semua sumber daya yang berasal dari base yang juga dapat memiliki kustomisasi lagi di atasnya.
Contoh di bawah ini memperlihatkan kegunaan dari base:
# Membuat direktori untuk menyimpan base
mkdir base
# Membuat base/deployment.yaml
cat <<EOF > base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
EOF
# Membuat berkas base/service.yaml
cat <<EOF > base/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
EOF
# Membuat berkas base/kustomization.yaml
cat <<EOF > base/kustomization.yaml
resources:
- deployment.yaml
- service.yaml
EOF
base ini dapat digunakan di dalam beberapa overlay sekaligus. Kamu dapat menambahkan namePrefix yang berbeda ataupun
field lainnya yang bersinggungan di dalam overlay berbeda. Di bawah ini merupakan dua buah overlay yang menggunakan base yang sama.
mkdir dev
cat <<EOF > dev/kustomization.yaml
resources:
- ../base
namePrefix: dev-
EOF
mkdir prod
cat <<EOF > prod/kustomization.yaml
resources:
- ../base
namePrefix: prod-
EOF
Gunakan --kustomize atau -k di dalam perintah kubectl untuk mengenali sumber daya yang dikelola oleh kustomization.yaml.
Perhatikan bahwa -k harus merujuk pada direktori kustomization, misalnya:
kubectl apply -k <direktori kustomization>/
Buatlah kustomization.yaml seperti di bawah ini:
# Membuat berkas deployment.yaml
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Membuat berkas kustomization.yaml
cat <<EOF >./kustomization.yaml
namePrefix: dev-
commonLabels:
app: my-nginx
resources:
- deployment.yaml
EOF
Jalankan perintah di bawah ini untuk menerapkan objek Deployment dev-my-nginx:
> kubectl apply -k ./
deployment.apps/dev-my-nginx created
Jalankan perintah di bawah ini untuk melihat objek Deployment dev-my-nginx:
kubectl get -k ./
kubectl describe -k ./
Jalankan perintah di bawah ini untuk membandingkan objek Deployment dev-my-nginx dengan kondisi yang diinginkan pada klaster jika manifes telah berhasil diterapkan:
kubectl diff -k ./
Jalankan perintah di bawah ini untuk menghapus objek Deployment dev-my-nginx:
> kubectl delete -k ./
deployment.apps "dev-my-nginx" deleted
| Field | Tipe | Deskripsi |
|---|---|---|
| namespace | string | menambahkan Namespace untuk semua sumber daya |
| namePrefix | string | nilai dari field ini ditambahkan di awal pada nama dari semua sumber daya |
| nameSuffix | string | nilai dari field ini ditambahkan di akhir pada nama dari semua sumber daya |
| commonLabels | map[string]string | label untuk ditambahkan pada semua sumber daya dan selektor |
| commonAnnotations | map[string]string | anotasi untuk ditambahkan pada semua sumber daya |
| resources | []string | setiap entri di dalam daftar ini harus diselesaikan pada berkas konfigurasi sumber daya yang sudah ada |
| configmapGenerator | []ConfigMapArgs | setiap entri di dalam daftar ini membangkitkan ConfigMap |
| secretGenerator | []SecretArgs | setiap entri di dalam daftar ini membangkitkan Secret |
| generatorOptions | GeneratorOptions | memodifikasi perilaku dari semua generator ConfigMap dan Secret |
| bases | []string | setiap entri di dalam daftar ini harus diselesaikan ke dalam sebuah direktori yang berisi berkas kustomization.yaml |
| patchesStrategicMerge | []string | setiap entri di dalam daftar ini harus diselesaikan dengan strategic merge patch dari sebuah objek Kubernetes |
| patchesJson6902 | []Json6902 | setiap entri di dalam daftar ini harus diselesaikan ke suatu objek Kubernetes atau patch Json |
| vars | []Var | setiap entri digunakan untuk menangkap teks yang berasal dari field sebuah sumber daya |
| images | []Image | setiap entri digunakan untuk memodifikasi nama, tag dan/atau digest untuk sebuah image tanpa membuat patch |
| configurations | []string | setiap entri di dalam daftar ini harus diselesaikan ke sebuah berkas yang berisi konfigurasi transformer Kustomize |
| crds | []string | setiap entri di dalam daftar ini harus diselesaikan ke sebuah berkas definisi OpenAPI untuk tipe Kubernetes |
Objek-objek Kubernetes bisa dibuat, diperbarui, dan dihapus secara langsung dengan menggunakan perintah-perintah imperatif yang ada pada command-line kubectl. Dokumen ini menjelaskan cara perintah-perintah tersebut diorganisir dan cara menggunakan perintah-perintah tersebut untuk mengelola objek live.
Perintah kubectl mendukung tiga cara pengelolaan objek:
Lihat Pengelolaan Objek Kubernetes untuk mengenali lebih lanjut kelebihan dan kekurangan dari tiap pengelolaan objek.
Perangkat kubectl mendukung perintah-perintah berbentuk kata kerja untuk membuat beberapa tipe objek yang paling umum. Perintah-perintah tersebut diberi nama yang mudah dikenali oleh pengguna yang belum familiar dengan tipe-tipe objek Kubernetes.
run: Membuat sebuah objek Deployment untuk menjalankan kontainer di satu atau lebih Pod.expose: Membuat sebuah objek Service untuk mengatur lalu lintas beban antar Pod.autoscale: Membuat sebuah objek Autoscaler untuk melakukan scaling horizontal secara otomatis terhadap sebuah objek controller, misalnya sebuah objek Deployment.Perangkat kubectl juga mendukung perintah-perintah pembuatan objek yang berdasarkan pada tipe objek. Perintah-perintah ini mendukung lebih banyak tipe objek dan lebih eksplisit tentang intensi mereka. Tapi, perintah-perintah ini memerlukan pengguna untuk memahami tipe dari objek-objek yang hendak mereka buat.
create <objecttype> [<subtype>] <instancename>Beberapa tipe objek memiliki sub tipe yang bisa kamu spesifikasikan pada perintah create. Misalnya, objek Service memiliki beberapa sub tipe seperti ClusterIP, LoadBalancer, dan NodePort. Berikut adalah sebuah contoh cara membuat sebuah Service dengan sub tipe NodePort:
kubectl create service nodeport <myservicename>
Pada contoh di atas, perintah create service nodeport merupakan sub perintah dari create service.
Kamu bisa menggunakan parameter -h untuk mencari argumen-argumen dan paramenter-parameter yang didukung oleh sebuah sub perintah:
kubectl create service nodeport -h
Perintah kubectl mendukung perintah-perintah berbasis kata kerja untuk beberapa operasi pembaruan yang umum. Perintah-perintah ini diberi nama yang memudahkan pengguna yang belum familiar dengan objek-objek Kubernetes untuk melakukan pembaruan tanpa terlebih dulu mengetahui field-field spesifik yang harus diperbarui:
scale: Melakukan scaling horizontal terhadap sebuah controller untuk menambah atau menghapus Pod dengan memperbarui jumlah replika dari controller tersebut.annotate: Menambah atau menghapus anotasi sebuah objek.label: Menambah atau menghapus label sebuah objek.Perintah kubectl juga mendukung perintah-perintah pembaruan berdasarkan salah satu aspek dari sebuah objek. Untuk tiap tipe objek yang berbeda, memperbarui sebuah aspek tertentu bisa berarti memperbarui sekumpulan field yang berbeda pula:
set <field>: Memperbarui salah satu aspek dari sebuah objek.Perangkat kubectl juga mendukung beberapa cara lain untuk memperbarui objek live secara langsung, meskipun cara-cara berikut membutuhkan pemahaman yang lebih tentang skema objek Kubernetes.
edit: Secara langsung mengedit konfigurasi mentah dari sebuah objek live dengan membuka konfigurasinya di sebuah editor.patch: Secara langsung memodifikasi field-field spesifik dari sebuah objek live dengan menggunakan patch string. Untuk detil lebih lanjut mengenai patch string, lihat bagian tentang patch pada Konvensi API.Kamu bisa menggunakan perintah delete pada sebuah objek dari sebuah klaster:
delete <type>/<name>kubectl delete baik untuk perintah imperatif maupun konfigurasi objek imperatif. Perbedaannya hanya pada argumen yang diberikan ke perintah tersebut. Untuk menggunakan kubectl delete sebagai perintah imperatif, argumen yang diberikan adalah objek yang hendak dihapus. Berikut adalah sebuah contoh perintah kubectl delete dengan sebuah objek Deployment bernama nginx sebagai argumen:kubectl delete deployment/nginx
Ada beberapa perintah untuk menampilkan informasi tentang sebuah objek:
get: Menampilkan informasi dasar dari objek-objek yang sesuai dengan parameter dari perintah ini. Gunakan get -h untuk melihat daftar opsi yang bisa digunakan.describe: Menampilkan agregat informasi detil dari objek-objek yang sesuai dengan parameter dari perintah ini.logs: Menampilkan isi stdout dan stderr dari sebuah kontainer yang berjalan di sebuah Pod.set untuk memodifikasi objek sebelum dibuatAda beberapa field objek yang tidak memiliki parameter yang bisa kamu gunakan pada perintah create. Pada kasus-kasus tersebut, kamu bisa menggunakan kombinasi dari perintah set dan create untuk menspesifikasikan nilai untuk field-field tersebut sebelum objek dibuat. Ini dilakukan dengan melakukan piping pada hasil dari perintah create ke perintah set, dan kemudian mengembalikan hasilnya ke perintah create. Simak contoh berikut:
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run | kubectl set selector --local -f - 'environment=qa' -o yaml | kubectl create -f -
kubectl create service -o yaml --dry-run membuat konfigurasi untuk sebuah Service, tapi kemudian menuliskan konfigurasi tadi ke stdout dalam format YAML alih-alih mengirimnya ke API Server Kubernetes.kubectl set selector --local -f - -o yaml membaca konfigurasi dari stdin, dan menuliskan pembaruan konfigurasi ke stdout dalam format YAML.kubectl create -f - membuat objek dengan menggunakan konfigurasi yang disediakan pada stdin.--edit untuk memodifikasi objek sebelum dibuatKamu bisa menggunakan perintah kubectl create --edit untuk membuat perubahan terhadap sebuah objek sebelum objek tersebut dibuat. Simak contoh berikut:
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run > /tmp/srv.yaml
kubectl create --edit -f /tmp/srv.yaml
kubectl create service membuat konfigurasi untuk objek Service dan menyimpannya di /tmp/srv.yaml.kubectl create --edit membuka berkas konfigurasi untuk disunting sebelum objek dibuat.Objek-objek Kubernetes bisa dibuat, diperbarui, dan dihapus dengan menggunakan perangkat command-line kubectl dan file konfigurasi objek yang ditulis dalam format YAML atau JSON. Dokumen ini menjelaskan cara mendefinisikan dan mengelola objek dengan menggunakan file konfigurasi.
Perintah kubectl mendukung tiga cara pengelolaan objek:
Lihat Pengelolaan Objek Kubernetes untuk mengenali lebih lanjut kelebihan dan kekurangan dari tiap cara pengelolaan objek.
Kamu bisa menggunakan perintah kubectl create -f untuk membuat sebuah objek dari sebuah file konfigurasi. Rujuk dokumen referensi API Kubernetes untuk detil lebih lanjut.
kubectl create -f <nama-file|url>replace akan menghilangkan semua bagian dari spesifikasi objek yang tidak dispesifikasikan pada file konfigurasi. Oleh karena itu, perintah ini sebaiknya tidak digunakan terhadap objek-objek yang spesifikasinya sebagian dikelola oleh klaster, misalnya Service dengan tipe LoadBalancer, di mana field externalIPs dikelola secara terpisah dari file konfigurasi. Field-field yang dikelola secara terpisah harus disalin ke file konfigurasi untuk mencegah terhapus oleh perintah replace.Kamu bisa menggunakan perintah kubectl replace -f untuk memperbarui sebuah objek live sesuai dengan sebuah file konfigurasi.
kubectl replace -f <nama-file|url>Kamu bisa menggunakan perintah kubectl delete -f untuk menghapus sebuah objek yang dideskripsikan pada sebuah file konfigurasi.
kubectl delete -f <nama-file|url>Kamu bisa menggunakan perintah kubectl get -f untuk melihat informasi tentang sebuah objek yang dideskripsikan pada sebuah file konfigurasi.
kubectl get -f <nama-file|url> -o yamlParameter -o yaml menetapkan bahwa keseluruhan konfigurasi objek ditulis ke file yaml. Gunakan perintah kubectl get -h untuk melihat daftar pilihan selengkapnya.
Perintah-perintah create, replace, dan delete bekerja dengan baik saat tiap konfigurasi dari sebuah objek didefinisikan dan dicatat dengan lengkap pada file konfigurasi objek tersebut. Akan tetapi, ketika sebuah objek live diperbarui dan pembaruannya tidak dicatat di file konfigurasinya, pembaruan tersebut akan hilang ketika perintah replace dieksekusi di waktu berikutnya. Ini bisa terjadi saat sebuah controller, misalnya sebuah HorizontalPodAutoscaler, membuat pembaruan secara langsung ke sebuah objek live. Berikut sebuah contoh:
kubectl replace dari file konfigurasi. Perubahan yang dibuat dari sumber lain pada langkah nomor 2 di atas akan hilang.Jika kamu perlu mendukung beberapa writer untuk objek yang sama, kamu bisa menggunakan kubectl apply untuk mengelola objek tersebut.
Misalkan kamu memiliki URL dari sebuah file konfigurasi objek. Kamu bisa menggunakan kubectl create --edit untuk membuat perubahan pada konfigurasi sebelum objek tersebut dibuat. Langkah ini terutama berguna untuk mengikuti tutorial atau untuk pekerjaan-pekerjaan yang menggunakan sebuah file konfigurasi di URL terentu yang perlu dimodifikasi.
kubectl create -f <url> --edit
Migrsasi dari perintah imperatif ke konfigurasi objek imperatif melibatkan beberapa langkah manual.
kubectl get <kind>/<name> -o yaml --export > <kind>_<name>.yaml
Hapus secara manual field status dari file konfigurasi objek.
Untuk pengelolaan objek selanjutnya, gunakan perintah replace secara eksklusif.
kubectl replace -f <kind>_<name>.yaml
Pendekatan yang direkomendasikan adalah mendefinisikan sebuah label PodTemplate tunggal dan immutable yang hanya digunakan oleh controller selector tersebut, tanpa makna semantik lainnya.
Contoh label:
selector:
matchLabels:
controller-selector: "extensions/v1beta1/deployment/nginx"
template:
metadata:
labels:
controller-selector: "extensions/v1beta1/deployment/nginx"
Laman ini menunjukkan bagaimana cara mendefinisikan perintah-perintah dan argumen-argumen saat kamu menjalankan Container dalam sebuah Pod.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Saat kamu membuat sebuah Pod, kamu dapat mendefinisikan sebuah perintah dan argumen-argumen untuk
Container-Container yang berjalan di dalam Pod. Untuk mendefinisikan sebuah perintah, sertakan
bidang command di dalam berkas konfigurasi. Untuk mendefinisikan argumen-argumen untuk perintah, sertakan
bidang args di dalam berkas konfigurasi. Perintah dan argumen-argumen yang telah
kamu definisikan tidak dapat diganti setelah Pod telah terbuat.
Perintah dan argumen-argumen yang kamu definisikan di dalam berkas konfigurasi membatalkan perintah dan argumen-argumen bawaan yang disediakan oleh image Container. Jika kamu mendefinisikan argumen-argumen, tetapi tidak mendefinisikan sebuah perintah, perintah bawaan digunakan dengan argumen-argumen baru kamu.
command menyerupai entrypoint di beberapa runtime Container.
Merujuk pada catatan di bawah.Pada latihan ini, kamu akan membuat sebuah Pod baru yang menjalankan sebuah Container. Berkas konfigurasi untuk Pod mendefinisikan sebuah perintah dan dua argumen:
apiVersion: v1
kind: Pod
metadata:
name: command-demo
labels:
purpose: demonstrate-command
spec:
containers:
- name: command-demo-container
image: debian
command: ["printenv"]
args: ["HOSTNAME", "KUBERNETES_PORT"]
restartPolicy: OnFailure
Buat sebuah Pod dengan berkas konfigurasi YAML:
kubectl apply -f https://k8s.io/examples/pods/commands.yaml
Daftar Pod yang sedang berjalan
kubectl get pods
Keluaran menunjukkan bahwa Container yang berjalan di dalam Pod command-demo telah selesai.
Untuk melihat keluaran dari perintah yang berjalan di dalam Container, lihat log dari Pod tersebut:
kubectl logs command-demo
Keluaran menunjukan nilai dari variabel lingkungan HOSTNAME dan KUBERNETES_PORT:
command-demo
tcp://10.3.240.1:443
Dalam contoh sebelumnya, kamu mendefinisikan langsung argumen-argumen dengan menyediakan string. Sebagai sebuah alternatif untuk menyediakan string secara langsung, kamu dapat mendefinisikan argumen-argumen dengan menggunakan variabel lingkungan:
env:
- name: MESSAGE
value: "hello world"
command: ["/bin/echo"]
args: ["$(MESSAGE)"]
Ini berarti kamu dapat mendefinisikan sebuah argumen untuk sebuah Pod menggunakan salah satu teknik yang tersedia untuk mendefinisikan variabel-variabel lingkungan, termasuk ConfigMap dan Secret.
"$(VAR)". Ini
dibutuhkan untuk variabel yang akan diperuluas di bidang command atau args.Di beberapa kasus, kamu butuh perintah untuk menjalankan sebuah shell. Contohnya, perintah kamu mungkin terdiri dari beberapa perintah yang digabungkan, atau mungkin berupa skrip shell. Untuk menjalankan perintah kamu di sebuah shell, bungkus seperti ini:
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
Tabel ini merangkum nama-nama bidang yang digunakan oleh Docker dan Kubernetes.
| Deskripsi | Nama bidang pada Docker | Nama bidang pada Kubernetes |
|---|---|---|
| Perintah yang dijalankan oleh Container | Entrypoint | command |
| Argumen diteruskan ke perintah | Cmd | args |
Saat kamu mengesampingkan Entrypoint dan Cmd standar, aturan-aturan ini berlaku:
Jika kamu tidak menyediakan command atau args untuk sebuah Container,
maka command dan args yang didefinisikan di dalam image Docker akan digunakan.
Jika kamu menyediakan command tetapi tidak menyediakan args untuk sebuah Container, akan digunakan
command yang disediakan. Entrypoint dan Cmd bawaan yang didefinisikan di dalam
image Docker diabaikan.
Jika kamu hanya menyediakan args untuk sebuah Container, Entrypoint bawaan yang didefinisikan di dalam
image Docker dijalakan dengan args yang kamu sediakan.
Jika kamu menyediakan command dan args, Entrypoint dan Cmd standar yang didefinisikan
di dalam image Docker diabaikan. command kamu akan dijalankan dengan args kamu.
Berikut ini beberapa contoh:
| Image Entrypoint | Image Cmd | Container command | Container args | Command run |
|---|---|---|---|---|
[/ep-1] |
[foo bar] |
<not set> | <not set> | [ep-1 foo bar] |
[/ep-1] |
[foo bar] |
[/ep-2] |
<not set> | [ep-2] |
[/ep-1] |
[foo bar] |
<not set> | [zoo boo] |
[ep-1 zoo boo] |
[/ep-1] |
[foo bar] |
[/ep-2] |
[zoo boo] |
[ep-2 zoo boo] |
Laman ini menunjukkan bagaimana cara untuk mendefinisikan variabel lingkungan (environment variable) untuk sebuah Container di dalam sebuah Pod Kubernetes.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Ketika kamu membuat sebuah Pod, kamu dapat mengatur variabel lingkungan untuk Container-Container yang berjalan di dalam sebuah Pod.
Untuk mengatur variabel lingkungan, sertakan bagian env atau envFrom pada berkas konfigurasi.
Dalam latihan ini, kamu membuat sebuah Pod yang menjalankan satu buah Container.
Berkas konfigurasi untuk Pod tersebut mendefinisikan sebuah variabel lingkungan dengan nama DEMO_GREETING yang bernilai "Hello from the environment".
Berikut berkas konfigurasi untuk Pod tersebut:
apiVersion: v1
kind: Pod
metadata:
name: envar-demo
labels:
purpose: demonstrate-envars
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/node-hello:1.0
env:
- name: DEMO_GREETING
value: "Hello from the environment"
- name: DEMO_FAREWELL
value: "Such a sweet sorrow"
Buatlah sebuah Pod berdasarkan berkas konfigurasi YAML tersebut:
kubectl apply -f https://k8s.io/examples/pods/inject/envars.yaml
Tampilkan Pod-Pod yang sedang berjalan:
kubectl get pods -l purpose=demonstrate-envars
Keluarannya mirip seperti ini:
NAME READY STATUS RESTARTS AGE
envar-demo 1/1 Running 0 9s
Dapatkan sebuah shell ke Container yang sedang berjalan di Pod kamu:
kubectl exec -it envar-demo -- /bin/bash
Di shell kamu, jalankan perintah printenv untuk melihat daftar variabel lingkungannya.
root@envar-demo:/# printenv
Keluarannya mirip seperti ini:
NODE_VERSION=4.4.2
EXAMPLE_SERVICE_PORT_8080_TCP_ADDR=10.3.245.237
HOSTNAME=envar-demo
...
DEMO_GREETING=Hello from the environment
DEMO_FAREWELL=Such a sweet sorrow
Untuk keluar dari shell tersebut, masukkan perintah exit.
env atau envFrom akan mengesampingkan
variabel-variabel lingkungan yang ditentukan di dalam image kontainer.Variabel-variabel lingkungan yang kamu definisikan di dalam sebuah konfigurasi Pod dapat digunakan di tempat lain dalam konfigurasi, contohnya di dalam perintah-perintah dan argumen-argumen yang kamu atur dalam Container-Container milik Pod.
Pada contoh konfigurasi berikut, variabel-variabel lingkungan GREETING, HONORIFIC, dan NAME disetel masing-masing menjadi Warm greetings to, The Most Honorable, dan Kubernetes.
Variabel-variabel lingkungan tersebut kemudian digunakan dalam argumen CLI yang diteruskan ke Container env-print-demo.
apiVersion: v1
kind: Pod
metadata:
name: print-greeting
spec:
containers:
- name: env-print-demo
image: bash
env:
- name: GREETING
value: "Warm greetings to"
- name: HONORIFIC
value: "The Most Honorable"
- name: NAME
value: "Kubernetes"
command: ["echo"]
args: ["$(GREETING) $(HONORIFIC) $(NAME)"]
Setelah dibuat, perintah echo Warm greetings to The Most Honorable Kubernetes dijalankan di Container tersebut.
Laman ini menjelaskan bagaimana cara menginjeksi data sensitif, seperti kata sandi (password) dan kunci enkripsi, ke dalam Pod.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Misalnya kamu mempunyai dua buah data rahasia: sebuah nama pengguna my-app dan kata sandi
39528$vdg7Jb. Pertama, gunakan alat penyandian Base64 untuk mengubah nama pengguna kamu dan kata sandi ke dalam representasi Base64. Berikut ini contoh menggunakan program Base64 yang umum digunakan:
echo -n 'my-app' | base64
echo -n '39528$vdg7Jb' | base64
Hasil keluaran menampilkan representasi Base64 dari nama pengguna kamu yaitu bXktYXBw,
dan representasi Base64 dari kata sandi kamu yaitu Mzk1MjgkdmRnN0pi.
Berikut ini adalah berkas konfigurasi yang dapat kamu gunakan untuk membuat Secret yang akan menampung nama pengguna dan kata sandi kamu:
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYXBw
password: Mzk1MjgkdmRnN0pi
Membuat Secret
kubectl apply -f https://k8s.io/examples/pods/inject/secret.yaml
Melihat informasi dari Secret:
kubectl get secret test-secret
Hasil keluaran:
NAME TYPE DATA AGE
test-secret Opaque 2 1m
Melihat informasi detil dari Secret:
kubectl describe secret test-secret
Hasil keluaran:
Name: test-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 13 bytes
username: 7 bytes
Jika kamu ingin melompati langkah penyandian dengan Base64, kamu dapat langsung membuat Secret yang sama dengan menggunakan perintah kubectl create secret. Contohnya:
kubectl create secret generic test-secret --from-literal='username=my-app' --from-literal='password=39528$vdg7Jb'
Tentu saja ini lebih mudah. Pendekatan yang mendetil setiap langkah di atas bertujuan untuk mendemonstrasikan apa yang sebenarnya terjadi pada setiap langkah.
Berikut ini adalah berkas konfigurasi yang dapat kamu gunakan untuk membuat Pod:
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
# nama harus sesuai dengan nama Volume di bawah ini
- name: secret-volume
mountPath: /etc/secret-volume
# Data Secret diekspos ke Container di dalam Pod melalui Volume
volumes:
- name: secret-volume
secret:
secretName: test-secret
Membuat Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/secret-pod.yaml
Verifikasikan apakah Pod kamu sudah berjalan:
kubectl get pod secret-test-pod
Hasil keluaran:
NAME READY STATUS RESTARTS AGE
secret-test-pod 1/1 Running 0 42m
Gunakan shell untuk masuk ke dalam Container yang berjalan di dalam Pod kamu:
kubectl exec -i -t secret-test-pod -- /bin/bash
Data Secret terekspos ke Container melalui Volume yang dipasang (mount) pada
/etc/secret-volume.
Di dalam shell kamu, tampilkan berkas yang ada di dalam direktori /etc/secret-volume:
# Jalankan ini di dalam shell dalam Container
ls /etc/secret-volume
Hasil keluaran menampilkan dua buah berkas, masing-masing untuk setiap data Secret:
password username
Di dalam shell kamu, tampilkan konten dari berkas username dan password:
# Jalankan ini di dalam shell dalam Container
echo "$( cat /etc/secret-volume/username )"
echo "$( cat /etc/secret-volume/password )"
Hasil keluarannya adalah nama pengguna dan kata sandi kamu:
my-app
39528$vdg7Jb
Definisikan variabel lingkungan sebagai pasangan key-value pada Secret:
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
Tentukan nilai backend-username yang didefinisikan di Secret ke variabel lingkungan SECRET_USERNAME di dalam spesifikasi Pod.
apiVersion: v1
kind: Pod
metadata:
name: env-single-secret
spec:
containers:
- name: envars-test-container
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: backend-user
key: backend-username
Membuat Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-single-secret-env-variable.yaml
Di dalam shell kamu, tampilkan konten dari variabel lingkungan SECRET_USERNAME dari Container
kubectl exec -i -t env-single-secret -- /bin/sh -c 'echo $SECRET_USERNAME'
Hasil keluarannya
backend-admin
Seperti contoh sebelumnya, buat Secret terlebih dahulu.
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
kubectl create secret generic db-user --from-literal=db-username='db-admin'
Definisikan variabel lingkungan di dalam spesifikasi Pod.
apiVersion: v1
kind: Pod
metadata:
name: envvars-multiple-secrets
spec:
containers:
- name: envars-test-container
image: nginx
env:
- name: BACKEND_USERNAME
valueFrom:
secretKeyRef:
name: backend-user
key: backend-username
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-user
key: db-username
Membuat Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-multiple-secret-env-variable.yaml
Di dalam shell kamu, tampilkan konten dari variabel lingkungan Container
kubectl exec -i -t envvars-multiple-secrets -- /bin/sh -c 'env | grep _USERNAME'
Hasil keluarannya
DB_USERNAME=db-admin
BACKEND_USERNAME=backend-admin
Membuat Secret yang berisi banyak pasangan key-value
kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
Gunakan envFrom untuk mendefinisikan semua data Secret sebagai variabel lingkungan Container. Key dari Secret akan mennjadi nama variabel lingkungan di dalam Pod.
apiVersion: v1
kind: Pod
metadata:
name: envfrom-secret
spec:
containers:
- name: envars-test-container
image: nginx
envFrom:
- secretRef:
name: test-secret
Membuat Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-secret-envFrom.yaml
Di dalam shell kamu, tampilkan variabel lingkungan Container username dan password
kubectl exec -i -t envfrom-secret -- /bin/sh -c 'echo "username: $username\npassword: $password\n"'
Hasil keluarannya
username: my-app
password: 39528$vdg7Jb
Dokumen ini menunjukkan cara bagaimana cara menjalankan sebuah aplikasi menggunakan objek Deployment Kubernetes.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Kubernetes servermu harus dalam versi yang sama atau lebih baru dari v1.9.Untuk melihat versi, tekan kubectl version.
Kamu dapat menjalankan aplikasi dengan membuat sebuah objek Deployment Kubernetes, dan kamu dapat mendeskripsikan sebuah Deployment di dalam berkas YAML. Sebagai contohnya, berkas YAML berikut mendeskripsikan sebuah Deployment yang menjalankan image Docker nginx:1.14.2:
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Buatlah sebuah Deployment berdasarkan berkas YAML:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
Tampilkan informasi dari Deployment:
kubectl describe deployment nginx-deployment
Keluaran dari perintah tersebut akan menyerupai:
Name: nginx-deployment
Namespace: default
CreationTimestamp: Tue, 30 Aug 2016 18:11:37 -0700
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision=1
Selector: app=nginx
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.14.2
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-1771418926 (2/2 replicas created)
No events.
Lihatlah daftar Pod-Pod yang dibuat oleh Deployment:
kubectl get pods -l app=nginx
Keluaran dari perintah tersebut akan menyerupai:
NAME READY STATUS RESTARTS AGE
nginx-deployment-1771418926-7o5ns 1/1 Running 0 16h
nginx-deployment-1771418926-r18az 1/1 Running 0 16h
Tampilkan informasi mengenai Pod:
kubectl describe pod <nama-pod>
dimana <nama-pod> merupakan nama dari Pod kamu.
Kamu dapat mengubah Deployment dengan cara mengaplikasikan berkas YAML yang baru. Berkas YAML ini memberikan spesifikasi Deployment untuk menggunakan Nginx versi 1.16.1.
apiVersion: apps/v1 # untuk versi sebelum 1.9.0 gunakan apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.1 # Memperbarui versi nginx dari 1.14.2 ke 1.16.1
ports:
- containerPort: 80
Terapkan berkas YAML yang baru:
kubectl apply -f https://k8s.io/examples/application/deployment-update.yaml
Perhatikan bahwa Deployment membuat Pod-Pod dengan nama baru dan menghapus Pod-Pod lama:
kubectl get pods -l app=nginx
Kamu dapat meningkatkan jumlah Pod di dalam Deployment dengan menerapkan berkas YAML baru. Berkas YAML ini akan meningkatkan jumlah replika menjadi 4, yang nantinya memberikan spesifikasi agar Deployment memiliki 4 buah Pod.
apiVersion: apps/v1 # untuk versi sebelum 1.9.0 gunakan apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 4 # Memperbarui replica dari 2 menjadi 4
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.1
ports:
- containerPort: 80
Terapkan berkas YAML:
kubectl apply -f https://k8s.io/examples/application/deployment-scale.yaml
Verifikasi Deployment kamu saat ini yang memiliki empat Pod:
kubectl get pods -l app=nginx
Keluaran dari perintah tersebut akan menyerupai:
NAME READY STATUS RESTARTS AGE
nginx-deployment-148880595-4zdqq 1/1 Running 0 25s
nginx-deployment-148880595-6zgi1 1/1 Running 0 25s
nginx-deployment-148880595-fxcez 1/1 Running 0 2m
nginx-deployment-148880595-rwovn 1/1 Running 0 2m
Menghapus Deployment dengan nama:
kubectl delete deployment nginx-deployment
Cara yang dianjurkan untuk membuat aplikasi dengan replika adalah dengan menggunakan Deployment, yang nantinya akan menggunakan ReplicaSet. Sebelum Deployment dan ReplicaSet ditambahkan ke Kubernetes, aplikasi dengan replika dikonfigurasi menggunakan ReplicationController.
Laman ini menjelaskan bagaimana cara menghapus Pod yang menjadi bagian dari sebuah stateful set, dan menjelaskan pertimbangan yang harus diperhatikan saat melakukannya.
Pada operasi normal dari StatefulSet, tidak pernah ada kebutuhan untuk menghapus paksa sebuah Pod StatefulSet. Controller StatefulSet bertanggung jawab terhadap pembuatan, penyekalaan dan penghapusan terhadap anggota dari StatefulSet. Controller akan berusaha menjaga agar jumlah Pod yang ditentukan dari 0 hingga N-1 hidup dan siap sedia. StatefulSet memastikan bahwa, pada waktu kapanpun, akan ada minimal satu Pod dengan identitas yang telah ditetapkan berjalan pada klaster. Hal ini direferensikan sebagai semantik at most one yang disediakan StatefulSet.
Penghapusan paksa secara manual harus dilakukan dengan hati-hati, karena hal tersebut berpotensi melanggar semantik at most one yang melekat pada StatefulSet. StatefulSet dapat digunakan untuk menjalankan aplikasi terklaster dan terdistribusi yang membutuhkan identitas jaringan dan penyimpanan yang stabil dan tetap. Aplikasi-aplikasi ini biasanya memiliki konfigurasi yang tergantung dengan sejumlah anggota dengan identitas yang tetap. Memiliki banyak anggota dengan identitas yang sama berpotensi menimbulkan kerusakan dan kehilangan data (contohnya skenario split brain pada sistem berbasis kuorum).
Kamu dapat melakukan penghapusan Pod secara graceful dengan perintah berikut:
kubectl delete pods <pod>
Agar perintah di atas mengarah ke terminasi secara graceful, Pod tidak boleh menspesifikasikan pod.Spec.TerminationGracePeriodSeconds dengan nilai 0. Praktik untuk mengatur nilai pod.Spec.TerminationGracePeriodSeconds menjadi 0 detik merupakan hal yang tidak aman dan sangat tidak disarankan untuk Pod StatefulSet. Penghapusan secara graceful itu aman dan akan memastikan bahwa Pod akan mati secara gracefully sebelum kubelet menghapus nama dari apiserver.
Kubernetes (versi 1.5 atau lebih baru) tidak akan menghapus Pod hanya karena Node tidak dapat dijangkau. Pod yang berjalan pada Node yang tidak dapat dijangkau akan memasuki keadaan 'Terminating' atau 'Unknown' setelah waktu habis. Pod juga dapat memasuki keadaan ini saat pengguna berusaha melakukan penghapusan secara graceful terhadap Pod pada Node yang tidak dapat dijangkau. Cara yang hanya dapat dilakukan untuk menghapus Pod pada keadaan tersebut dari apiserver adalah:
Praktik terbaik yang direkomendasikan adalah menggunakan pendekatan pertama atau kedua. Jika sebuah Node telah terkonfirmasi mati (contohnya terputus dari jaringan secara permanen, dimatikan, dll), maka objek Node dihapus. Jika Node mengalami partisi jaringan, maka coba selesaikan masalah ini atau menunggu masalah itu terselesaikan. Saat partisi terselesaikan, kubelet akan menyelesaikan penghapusan Pod serta membebaskan namanya dari apiserver.
Normalnya, sistem akan menyelesaikan penghapusan saat Pod tidak lagi berjalan pada Node, atau Node telah dihapus oleh administrator. Kamu dapat mengabaikan hal ini dengan menghapus paksa Pod.
Penghapusan paksa tidak menunggu konfirmasi dari kubelet bahwa Pod telah diterminasi. Terlepas dari apakah penghapusan paksa sukses mematikan sebuah Pod, namanya akan segera dibebaskan dari apiserver. Hal ini berakibat controller StatefulSet akan membuat Pod pengganti dengan identitas yang sama; ini dapat menimbulkan duplikasi terhadap Pod apabila ternyata Pod tersebut masih berjalan, dan jika Pod tersebut masih dapat berkomunikasi dengan anggota Statefulset lainnya, hal ini berakibat terjadi pelanggaran semantik at most one dari StatefulSet yang telah dijamin.
Saat kamu menghapus paksa sebuah Pod StatefulSet, berarti kamu menjamin bahwa Pod tersebut tidak akan pernah lagi berkomunikasi dengan Pod lain pada StatefulSet dan namanya dapat dibebaskan secara aman untuk pembuatan penggantinya.
Jika kamu ingin menghapus paksa Pod dengan menggunakan kubectl versi >= 1.5, lakukan perintah berikut:
kubectl delete pods <pod> --grace-period=0 --force
Jika kamu menggunakan kubectl <= 1.4, kamu harus menghilangkan pilihan --force dan gunakan:
kubectl delete pods <pod> --grace-period=0
Jika setelah perintah ini dijalankan dan Pod tetap berada pada kondisi Unknown, gunakan perintah berikut untuk menghapus Pod dari klaster:
kubectl patch pod <pod> -p '{"metadata":{"finalizers":null}}'
Selalu jalankan penghapusan paksa Pod StatefulSet dengan hati-hati dan penuh pemahaman terhadap risiko yang dapat timbul.
Pelajari lebih lanjut debugging StatefulSet.
HorizontalPodAutoscaler secara otomatis akan memperbanyak jumlah Pod di dalam ReplicationController, Deployment, ReplicaSet ataupun StatefulSet berdasarkan hasil observasi penggunaan CPU(atau, dengan metrik khusus, pada beberapa aplikasi yang menyediakan metrik). Perlu dicatat bahwa HorizontalPodAutoscale tidak dapat diterapkan pada objek yang tidak dapat diperbanyak, seperti DeamonSets.
HorizontalPodAutoscaler diimplementasikan sebagai Kubernetes API resource dan sebuah controller. Resource tersebut akan menentukan perilaku dari controller-nya. Kontroler akan mengubah jumlah replika pada ReplicationController atau pada Deployment untuk menyesuaikan dengan hasil observasi rata-rata penggunaan CPU sesuai dengan yang ditentukan oleh pengguna.
HorizontalPodAutoscaler diimplementasikan sebagai sebuah loop kontrol, yang secara
berkala dikontrol oleh flag --horizontal-pod-autoscaler-sync-period pada controller manager
(dengan nilai bawaan 15 detik).
Dalam setiap periode, controller manager melakukan kueri penggunaan sumber daya dan membandingkan dengan metrik yang dispesifikasikan pada HorizontalPodAutoscaler. Controller manager mendapat metrik dari sumber daya metrik API (untuk metrik per Pod) atau dari API metrik khusus (untuk semua metrik lainnya).
Untuk metrik per Pod (seperti CPU), controller mengambil metrik dari sumber daya metrik API untuk setiap Pod yang ditargetkan oleh HorizontalPodAutoscaler. Kemudian, jika nilai target penggunaan ditentukan, maka controller akan menghitung nilai penggunaan sebagai persentasi dari pengguaan sumber daya dari Container pada masing-masing Pod. Jika target nilai mentah (raw value) ditentukan, maka nilai metrik mentah (raw metric) akan digunakan secara langsung. Controller kemudian mengambil nilai rata-rata penggunaan atau nilai mentah (tergantung dengan tipe target yang ditentukan) dari semua Pod yang ditargetkan dan menghasilkan perbandingan yang digunakan untuk menentukan jumlah replika yang akan diperbanyak.
Perlu dicatat bahwa jika beberapa Container pada Pod tidak memiliki nilai resource request, penggunaan CPU pada Pod tersebut tidak akan ditentukan dan autoscaler tidak akan melakukan tindakan apapun untuk metrik tersebut. Perhatikan pada bagian detail algoritma di bawah ini untuk informasi lebih lanjut mengenai cara kerja algoritma autoscale.
Untuk metrik khusus per Pod, controller bekerja sama seperti sumber daya metrik per Pod, kecuali Pod bekerja dengan nilai mentah, bukan dengan nilai utilisasi (utilization values).
Untuk objek metrik dan metrik eksternal, sebuah metrik diambil, dimana metrik tersebut menggambarkan
objek tersebut. Metrik ini dibandingkan dengan nilai target untuk menghasilkan perbandingan seperti di atas.
Pada API autoscaling/v2beta2, nilai perbandingan dapat secara opsional dibagi dengan jumlah Pod
sebelum perbandingan dibuat.
Pada normalnya, HorizontalPodAutoscaler mengambil metrik dari serangkaian API yang sudah diagregat
(custom.metric.k8s.io, dan external.metrics.k8s.io). API metrics.k8s.io biasanya disediakan oleh
metric-server, dimana metric-server dijalankan secara terpisah. Perhatikan
metrics-server sebagai petunjuk.
HorizontalPodAutoscaler juga mengambil metrik dari Heapster secara langsung.
Kubernetes v1.11 [deprecated]
Pengambian metrik dari Heapster tidak didukung lagi pada Kubernetes versi 1.11.
Perhatikan Dukungan untuk API metrik untuk lebih detail.
Autoscaler mengkases controller yang dapat diperbanyak (seperti ReplicationController, Deployment, dan ReplicaSet) dengan menggunakan scale sub-resource. Untuk lebih detail mengenai scale sub-resource dapat ditemukan di sini.
Dari sudut pandang paling sederhana, controller HorizontalPodAutoscaler mengoperasikan perbandingan metrik yang diinginkan dengan kedaan metrik sekarang.
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
Sebagai contoh, jika nilai metrik sekarang adalah 200m dan nilai metrik yang
diinginkan adalah 100m, jumlah replika akan ditambah dua kali lipat,
karena 200.0 / 100.0 == 2.0. Jika nilai metrik sekarang adalah 50m,
maka jumlah replika akan dikurangi setengah, karena 50.0 / 100.0 == 0.5.
Kita tetap memperbanyak replika (scale) jika nilai perbandingan mendekati 1.0 (dalam toleransi yang
dapat dikonfigurasi secata global, dari flag --horizontal-pod-autoscaler-tolerance
dengan nilai bawaan 0.1.
Ketika targetAverageValue (nilai target rata-rata) atau targetAverageUtilization
(target penggunaan rata-rata) ditentukan, currentMetricValue (nilai metrik sekaraang)
dihitung dengan mengambil rata-rata dari metrik dari semua Pod yang ditargetkan oleh
HorizontalPodAutoscaler. Sebelum mengecek toleransi dan menentukan nilai akhir,
kita mengambil kesiapan Pod dan metrik yang hilang sebagai pertimbangan.
Semua Pod yang memiliki waktu penghapusan (Pod dalam proses penutupan) dan semua Pod yang mengalami kegagalan akan dibuang.
Jika ada metrik yang hilang dari Pod, maka Pod akan dievaluasi nanti. Pod dengan nilai metrik yang hilang akan digunakan untuk menyesuaikan jumlah akhir Pod yang akan diperbanyak atau dikurangi.
Ketika scaling dilakukan karena CPU, jika terdapat Pod yang akan siap (dengan kata lain Pod tersebut sedang dalam tahap inisialisasi) atau metrik terakhir dari Pod adalah metrik sebelum Pod dalam keadaan siap, maka Pod tersebut juga akan dievaluasi nantinya.
Akibat keterbatasan teknis, controller HorizontalPodAutoscaler tidak dapat
menentukan dengan tepat kapan pertama kali Pod akan dalam keadaan siap
ketika menentukan apakah metrik CPU tertentu perlu dibuang. Sebaliknya,
HorizontalPodAutoscaler mempertimbangkan sebuah Pod "tidak dalam keadaan siap"
jika Pod tersebut dalam keadaan tidak siap dan dalam transisi ke status tidak
siap dalam waktu singkat, rentang waktu dapat dikonfigurasi, sejak Pod tersebut dijalankan.
Rentang waktu tersebut dapat dikonfigurasi dengan flag --horizontal-pod-autoscaler-initial-readiness-delay
dan waktu bawaannya adalah 30 detik. Ketika suatu Pod sudah dalam keadaan siap,
Pod tersebut mempertimbangkan untuk siap menjadi yang pertama jika itu terjadi dalam
waktu yang lebih lama, rentang waktu dapat dikonfigurasi, sejak Pod tersebut dijalankan.
Rentang waktu tersebut dapat dikonfigurasi dengan flag --horizontal-pod-autoscaler-cpu-initialization-period
dan nilai bawaannya adalah 5 menit.
Skala perbandingan dasar currentMetricValue / desiredMetricValue
dihitung menggunakan Pod yang tersisa yang belum disisihkan atau dibuang dari
kondisi di atas.
Jika terdapat metrik yang hilang, kita menghitung ulang rata-rata dengan lebih konservatif, dengan asumsi Pod mengkonsumsi 100% dari nilai yang diharapkan jika jumlahnya dikurangi (scale down) dan 0% jika jumlahnya diperbanyak (scale up). Ini akan mengurangi besarnya kemungkinan untuk scale.
Selanjutnya, jika terdapat Pod dalam keadaan tidak siap, dan kita akan memperbanyak replikas (scale up) tanpa memperhitungkan metrik yang hilang atau Pod yang tidak dalam keadaan siap, kita secara konservatif mengasumsikan Pod yang tidak dalam keadaan siap mengkonsumsi 0% dari metrik yang diharapkan, akhirnya meredam jumlah replika yang diperbanyak (scale up).
Seteleh memperhitungkan Pod yang tidak dalam keadaan siap dan metrik yang hilang, kita menghitung ulang menggunakan perbandingan. Jika perbandingan yang baru membalikkan arah scale-nya atau masih di dalam toleransi, kita akan melakukan scale dengan tepat. Jika tidak, kita menggunakan perbandingan yang baru untuk memperbanyak atau mengurangi jumlah replika.
Perlu dicatat bahwa nilai asli untuk rata-rata penggunaan dilaporkan kembali melalui status HorizontalPodAutoscaler, tanpa memperhitungkan Pod yang tidak dalam keadaan siap atau metrik yang hilang, bahkan ketika perbandingan yang baru digunakan.
Jika beberapa metrik ditentukan pada sebuah HorizontalPodAutoscaler, perhitungan
dilakukan untuk setiap metrik dan nilai replika terbesar yang diharapkan akan dipilih.
Jika terdapat metrik yang tidak dapat diubah menjadi jumlah replika yang diharapkan
(contohnya terdapat kesalahan ketika mengambil metrik dari API metrik) dan pengurangan replika
disarankan dari metrik yang dapat diambil, maka scaling akan diabaikan. Ini berarti
HorizontalPodAutoscaler masih mampu untuk memperbanyak replika jika satu atau lebih metrik
memberikan sebuah desiredReplicas lebih besar dari nilai yang sekarang.
Pada akhirnya, sebelum HorizontalPodAutoscaler memperbanyak target, rekomendasi scaling akan
dicatat. Controller mempertimbangkan semua rekomendasi dalam rentang waktu yang dapat
dikonfigurasi untuk memilih rekomendasi tertinggi. Nilai ini dapat dikonfigurasi menggunakan
flag --horizontal-pod-autoscaler-downscale-stabilization, dengan nilai bawaan
5 menit. Ini berarti pengurangan replika akan terjadi secara bertahap, untuk mengurangi dampak dari
perubahan nilai metrik yang cepat.
HorizontalPodAutoscaler adalah sebuah API dalam grup autoscaling pada Kubernetes.
Versi stabil, yang hanya mendukung untuk autoscale CPU, dapat ditemukan pada versi
API autoscaling/v1.
Versi beta, yang mendukung untuk scaling berdasarkan memori dan metrik khusus,
dapat ditemukan pada autoscaling/v2beta2. Field yang baru diperkenalkan pada
autoscaling/v2beta2 adalah preserved sebagai anotasi ketika menggunakan autoscaling/v1.
Ketika kamu membuat sebuah HorizontalPodAutoscaler, pastikan nama yang ditentukan adalah valid nama subdomain DNS. Untuk lebih detail tentang objek API ini dapat ditemukan di Objek HorizontalPodAutoscaler.
Seperti sumber daya API lainnya, HorizontalPodAutoscaler didukung secara bawaan oleh kubectl.
Kita dapat membuat autoscaler yang baru dengan menggunakan perintah kubectl create.
Kita dapat melihat daftar autoscaler dengan perintah kubectl get hpa dan melihat deskripsi
detailnya dengan perintah kubectl describe hpa. Akhirnya, kita dapat menghapus autoscaler
meggunakan perintah kubectl delete hpa.
Sebagai tambahan, terdapat sebuah perintah khusus kubectl autoscaler untuk mempermudah pembuatan
HorizontalPodAutoscaler. Sebagai contoh, mengeksekusi
kubectl autoscaler rs foo --min=2 --max=5 --cpu-percent=80 akan membuat sebuah autoscaler untuk
ReplicaSet foo, dengan target pengguaan CPU 80% dan jumlah replika antara 2 sampai dengan 5.
Dokumentasi lebih detail tentang kubectl autoscaler dapat ditemukan di
sini.
Saat ini, dimungkinkan untuk melakukan rolling update menggunakan objek Deployment, yang akan mengatur ReplicaSet untuk kamu. HorizontalPodAutoscaler hanya mendukung pendekatan terakhir: HorizontalPodAutoscaler terikat dengan objek Deployment, yang mengatur seberapa besar dari objek Deployment tersebut, dan Deployment bertugas untuk mengatur besar dari ReplicaSet.
HorizontalPodAutoscaler tidak bekerja dengan rolling update yang menggunakan manipulasi pada ReplicationContoller secara langsung, dengan kata lain kamu tidak bisa mengikat HorizontalPodAutoscaler dengan ReplicationController dan melakukan rolling update. Alasan HorizontalPodAutoscaler tidak bekerja ketika rolling update membuat ReplicationController yang baru adalah HorizontalPodAutoscaler tidak akan terikat dengan ReplicationController yang baru tersebut.
Ketika mengolah scaleing dari sebuah grup replika menggunakan HorizonalPodAutoscaler, jumlah replika dimungkinkan tetap berubah secara sering disebabkan oleh perubahan dinamis dari metrik yang dievaluasi. Hal ini sering disebut dengan thrashing.
Mulai dari versi 1.6, operator klaster dapat mengatasi masalah ini dengan mengatur
konfigurasi HorizontalPodAutoscaler global sebagai flag kube-controller-manager.
Mulai dari versi 1.12, sebuah algoritma pembaruan baru menghilangkan kebutuhan terhadap penundaan memperbanyak replika (upscale).
--horizontal-pod-autoscaler-downscale-stabilization: Nilai untuk opsi ini adalah
sebuah durasi yang menentukan berapa lama autoscaler menunggu sebelum operasi
pengurangan replika (downscale) yang lain dilakukan seteleh operasi sekarang selesai. Nilai bawaannya
adalah 5 menit (5m0s).Kubernetes versi 1.6 menambah dukungan untuk scaling berdasarkan beberapa metrik.
Kamu dapat menggunakan API versi autoscaling/v2beta2 untuk menentukan beberapa metrik
yang akan digunakan HorizontalPodAutoscaler untuk menambah atau mengurangi jumlah replika.
Kemudian, controller HorizontalPodAutoscaler akan mengevaluasi setiap metrik dan menyarankan jenis
scaling yang baru berdasarkan metrik tersebut. Jumlah replika terbanyak akan digunakan untuk scale
yang baru.
Kubernetes versi 1.6 menambah dukungan untuk menggunakan metrik khusus pada HorizontalPodAutoscaler.
Kamu dapat menambahkan metrik khusus untuk HorizontalPodAutoscaler pada API versi autoscaling/v2beta2.
Kubernetes kemudian memanggil API metrik khusus untuk mengambil nilai dari metrik khusus.
Lihat Dukungan untuk API metrik untuk kubutuhannya.
Secara standar, controller HorizontalPodAutoscaler mengambil metrik dari beberapa API. Untuk dapat mengakses API ini, administrator klaster harus memastikan bahwa:
API Later Pengumpulan diaktifkan.
API berikut ini terdaftar:
Untuk metrik sumber daya, ini adalah API metrics.k8s.io, pada umumnya disediakan oleh
metrics-server. API tersebut dapat
diaktifkan sebagai addon atau tambahan pada klaster.
Untuk metrik khusus, ini adalah API custom.metrics.k8s.io. API ini disediakan oleh API
adaptor server yang disediakan oleh vendor yang memberi solusi untuk metrik. Cek dengan
pipeline metrikmu atau daftar solusi yang sudah diketahui. Jika kamu ingin membuat sendiri, perhatikan
boilerplate berikut untuk memulai.
Untuk metrik eksternal, ini adalah API external.metrics.k8s.io. API ini mungkin disediakan oleh penyedia
metrik khusus diatas.
Nilai dari --horizontal-pod-autoscaler-use-rest-clients adalah true atau tidak ada. Ubah nilai tersebut menjadi
false untuk mengubah ke autoscaling berdasarkan Heapster, dimana ini sudah tidak didukung lagi.
Untuk informasi lebih lanjut mengenai metrik-metrik ini dan bagaimana perbedaan setiap metrik, perhatikan proposal desain untuk HPA V2, custom.metrics.k8s.io dan external.metrics.k8s.io.
Untuk contoh bagaimana menggunakan metrik-metrik ini, perhatikan panduan penggunaan metrik khusus dan panduan penggunaan metrik eksternal.
Mulai dari versi v1.18, API v2beta2 mengizinkan perilaku scaling dapat
dikonfigurasi melalui field behavior pada HorizontalPodAutoscaler. Perilaku scaling up dan scaling down
ditentukan terpisah pada field slaceUp dan field scaleDown, dibawah dari field behavior.
Sebuah stabilisator dapat ditentukan untuk kedua arah scale untuk mencegah perubahan replika yang terlalu
berbeda pada target scaling. Menentukan scaling policies akan mengontrol perubahan replika
ketika scaling.
Satu atau lebih scaling policies dapat ditentukan pada field behavior. Ketika beberapa
policies ditentukan, policy yang mengizinkan scale terbesar akan dipilih secara default.
Contoh berikut menunjukkan perilaku ketika mengurangi replika:
behavior:
scaleDown:
policies:
- type: Pods
value: 4
periodSeconds: 60
- type: Percent
value: 10
periodSeconds: 60
Ketika jumlah Pod lebih besar dari 40, policy kedua akan digunakan untuk scaling down. Misalnya, jika terdapat 80 replika dan target sudah di scale down ke 10 replika, 8 replika akan dikurangi pada tahapan pertama. Pada iterasi berikutnya, ketika jumlah replika adalah 72, 10% dari Pod adalah 7.2 tetapi akan dibulatkan menjadi 8. Dalam setiap iterasi pada controller autoscaler jumlah Pod yang akan diubah akan dihitung ulang berdarkan jumlah replika sekarang. Ketika jumlah replika dibawah 40, policy pertama (Pods) akan digunakan dan 4 replika akan dikurangi dalam satu waktu.
periodSeconds menunjukkan berapa lama waktu pada iterasi terkhir untuk menunjukkan policy
mana yang akan digunakan. Policy pertama mengizinkan maksimal 4 replika di scale down
dalam satu menit. Policy kedua mengixinkan maksimal 10% dari total replika sekarang di
scale down dalam satu menit.
Pemilihan policy dapat diubah dengan menentukannya pada field selectPolicy untuk sebuah
arah scale (baik scale up ataupun scale down). Dengan menentukan nilai Min,
HorizontalPodAutoscaler akan memilih policy yang mengizinkan pergantian replika paling sedikit.
Dengan menuntukan nilai Disable, akan menghentikan scaling pada arah scale tersebut.
Jendela stabilisasi digunakan untuk membatasi perubahan replika yang terlalu drastis ketika
metrik yang digunakan untuk scaling tetap berubah-ubah. Jendela stabilisasi digunakan oleh
algoritma autoscaling untuk memperhitungkan jumlah replika yang diharapkan dari scaling
sebelumnya untuk mencengah *scaling. Berikut adalah contoh penggunaan jendela stabilisasi
pada scaleDown.
scaleDown:
stabilizationWindowSeconds: 300
Ketika metrik menandakan bahwa replika pada target akan dikurangi, algoritma akan memperhatikan jumlah replika yang diharapkan sebelumnya dan menggunakan nilai terbesar dari interval yang ditentukan. Pada contoh diatas, semua jumlah replika yang diharapkan pada 5 menit yang lalu akan dipertimbangkan.
Untuk menggunakan scaling khusus, tidak semua field perlu ditentukan. Hanta nilai yang perlu diubah saja yang ditentukan. Nilai khusus ini akan digabungkan dengan nilai standar. Berikut adalah nilai standar perilaku pada algoritma yang digunakan HorizontalPodAutoscaler.
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
Untuk scaleDown, nilai dari jendela stabilisasi adalah 300 detik (atau nilai dari
flag --horizontal-pod-autoscaler-downscale-stabilization jika ditentukan). Hanya terdapat
satu policy, yaitu mengizinkan menghapus 100% dari replika yang berjalan,
artinya target replikasi di scale ke jumlah replika minimum. Untuk scaleUp, tidak terdapat
jendela stabilisasi. Jika metrik menunjukkan bahwa replika pada target perlu diperbanyak, maka replika akan
diperbanyak di secara langsung. Untuk scaleUp terdapat dua policy, yaitu empat Pod atau 100% dari
replika yang berjalan akan ditambahkan setiap 15 detik sampai HorizontalPodAutoscaler
dalam keadaan stabil.
Untuk membuat jendela stabilisai untuk pengurangan replika selama satu menit, perilaku berikut ditambahkan pada HorizontalPodAutoscaler.
behavior:
scaleDown:
stabilizationWindowSeconds: 60
Untuk membatasi total berapa Pod yang akan dihapus, 10% setiap menut, perilaku berikut ditambahkan pada HorizontalPodAutoscaler.
behavior:
scaleDown:
policies:
- type: Percent
value: 10
periodSeconds: 60
Untuk mengizinkan penghapusan 5 Pod terakhir, policy lain dapat ditambahkan.
behavior:
scaleDown:
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 5
periodSeconds: 60
selectPolicy: Max
Nilai Disable pada selectPolicy akan menonaktifkan scaling pada arah yang
ditentukan. Untuk mencegah pengurangan replika dapat menggunakan policy berikut.
behavior:
scaleDown:
selectPolicy: Disabled
HorizontalPodAutoscaler secara otomatis akan memperbanyak jumlah Pod di dalam ReplicationController, Deployment, ReplicaSet ataupun StatefulSet berdasarkan hasil observasi penggunaan CPU (atau, dengan metrik khusus, pada beberapa aplikasi yang menyediakan metrik).
Laman ini memandu kamu dengan contoh pengaktifan HorizontalPodAutoscaler untuk server php-apache. Untuk informasi lebih lanjut tentang perilaku HorizontalPodAutoscaler, lihat Petunjuk pengguna HorizontalPodAutoscaler.
Contoh dibawah ini membutuhkan klaster Kubernetes dan kubectl di versi 1.2 atau yang lebih baru yang sedang berjalan. Server metrik sebagai pemantauan perlu diluncurkan di dalam sebuah klaster untuk menyediakan metrik melalui metrik API sumber daya, karena HorizontalPodAutoscaler menggunakan API ini untuk mengumpulkan metrik. Petunjuk untuk menerapkan server metrik ada di repositori GitHub dari server metrik, jika kamu mengikuti petunjuk memulai panduan GCE, metrik-pemantauan server akan diaktifkan secara default
Untuk menentukan beberapa metrik sumber daya untuk HorizontalPodAutoscaler, kamu harus memiliki klaster Kubernetes dan kubectl di versi 1.6 atau yang lebih baru. Selanjutnya, untuk menggunakan metrik khusus, klaster kamu harus dapat berkomunikasi dengan server API yang menyediakan API metrik khusus. Terakhir, untuk menggunakan metrik yang tidak terkait dengan objek Kubernetes apa pun, kamu harus memiliki klaster Kubernetes pada versi 1.10 atau yang lebih baru, dan kamu harus dapat berkomunikasi dengan server API yang menyediakan API metrik eksternal. Lihat Panduan pengguna HorizontalPodAutoscaler untuk detail lebih lanjut.
Untuk mendemonstrasikan HorizontalPodAutoscaler kita akan menggunakan image Docker khusus berdasarkan image php-apache. Dockerfile memiliki konten berikut:
FROM php:5-apache
ADD index.php /var/www/html/index.php
RUN chmod a+rx index.php
Bagian ini mendefinisikan laman index.php yang melakukan beberapa komputasi intensif CPU:
<?php
$x = 0.0001;
for ($i = 0; $i <= 1000000; $i++) {
$x += sqrt($x);
}
echo "OK!";
?>
Pertama, kita akan memulai Deployment yang menjalankan image dan mengeksposnya sebagai Service menggunakan konfigurasi berikut:
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
spec:
selector:
matchLabels:
run: php-apache
template:
metadata:
labels:
run: php-apache
spec:
containers:
- name: php-apache
image: registry.k8s.io/hpa-example
ports:
- containerPort: 80
resources:
limits:
cpu: 500m
requests:
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: php-apache
labels:
run: php-apache
spec:
ports:
- port: 80
selector:
run: php-apache
Jalankan perintah berikut:
kubectl apply -f https://k8s.io/examples/application/php-apache.yaml
deployment.apps/php-apache created
service/php-apache created
Sekarang server sudah berjalan, selanjutnya kita akan membuat autoscaler menggunakan
kubectl autoscale.
Perintah berikut akan membuat HorizontalPodAutoscaler yang mengelola antara 1 dan 10 replika Pod yang dikontrol oleh Deployment php-apache yang kita buat pada langkah pertama instruksi ini.
Secara kasar, HPA akan menambah dan mengurangi jumlah replika
(melalui Deployment) untuk mempertahankan pemakaian CPU rata-rata di semua Pod sebesar 50%
(karena setiap Pod meminta 200 mili-core menurut kubectl run), ini berarti penggunaan CPU rata-rata adalah 100 mili-core).
Lihat ini untuk detail lebih lanjut tentang algoritmanya.
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/php-apache autoscaled
Kita dapat memeriksa status autoscaler saat ini dengan menjalankan:
kubectl get hpa
NAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache/scale 0% / 50% 1 10 1 18s
Harap dicatat bahwa konsumsi CPU saat ini adalah 0% karena kita tidak mengirimkan permintaan apa pun ke server
(kolom TARGET menunjukkan nilai rata-rata di semua Pod yang dikontrol oleh Deployment yang sesuai).
Sekarang, kita akan melihat bagaimana autoscaler bereaksi terhadap peningkatan beban. Kita akan memulai sebuah Container, dan mengirimkan perulangan kueri tak terbatas ke Service php-apache (jalankan di terminal yang berbeda):
kubectl run -it --rm load-generator --image=busybox /bin/sh
Hit enter for command prompt
while true; do wget -q -O- http://php-apache; done
Dalam satu menit atau lebih, kita akan melihat beban CPU yang lebih tinggi dengan menjalankan:
kubectl get hpa
NAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache/scale 305% / 50% 1 10 1 3m
Di sini, konsumsi CPU meningkat hingga 305% dari permintaan. Hasilnya, Deployment mengubah ukurannya menjadi 7 replika:
kubectl get deployment php-apache
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 7/7 7 7 19m
Kita akan menyudahi contoh dengan menghentikan beban pengguna.
Di terminal tempat kita membuat Container dengan image busybox, hentikan
pembangkitan beban dengan mengetik <Ctrl> + C.
Kemudian kita akan memverifikasi status hasil (setelah satu menit atau lebih):
kubectl get hpa
NAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache/scale 0% / 50% 1 10 1 11m
kubectl get deployment php-apache
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 1/1 1 1 27m
Di sini penggunaan CPU turun menjadi 0, sehingga HPA secara otomatis melakukan penyekalaan jumlah replika kembali menjadi 1.
Kamu dapat memperkenalkan metrik tambahan untuk digunakan saat melakukan penyekalaan otomatis pada Deployment php-apache dengan menggunakan versi API autoscaling / v2beta2.
Pertama, dapatkan YAML HorizontalPodAutoscaler kamu dalam bentuk autoscaling / v2beta2:
kubectl get hpa.v2beta2.autoscaling -o yaml > /tmp/hpa-v2.yaml
Buka berkas /tmp/hpa-v2.yaml di editor, dan kamu akan melihat YAML yang terlihat seperti ini:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
status:
observedGeneration: 1
lastScaleTime: <some-time>
currentReplicas: 1
desiredReplicas: 1
currentMetrics:
- type: Resource
resource:
name: cpu
current:
averageUtilization: 0
averageValue: 0
Perhatikan bahwa kolom targetCPUUtilizationPercentage telah diganti dengan himpunan yang disebut metrics.
Metrik penggunaan CPU adalah resource metric, merepresentasikan sebagai persentase sumber daya
ditentukan pada Container Pod. Perhatikan bahwa kamu dapat menentukan metrik sumber daya selain CPU. Secara bawaan,
satu-satunya metrik sumber daya lain yang didukung adalah memori. Sumber daya ini tidak mengubah nama dari klaster
ke klaster, dan harus selalu tersedia, selama API metrics.k8s.io tersedia.
Kamu juga dapat menentukan metrik sumber daya dalam nilai secara langsung, bukan sebagai persentase dari
nilai yang diminta, dengan menggunakan target.type dari AverageValue sebagai ganti Utilization, dan
menyetel field target.averageValue yang sesuai, bukan target.averageUtilization.
Ada dua jenis metrik lainnya, keduanya dianggap sebagai metrik khusus: metrik Pod dan metrik objek. Metrik ini memungkinkan untuk memiliki nama yang spesifik untuk klaster, dan membutuhkan lebih banyak pengaturan pemantauan klaster lanjutan.
Jenis metrik alternatif yang pertama adalah metrik Pod. Metrik ini mendeskripsikan Pod, dan
dirata-ratakan bersama di seluruh Pod dan dibandingkan dengan nilai target untuk menentukan jumlah replika.
Mereka bekerja seperti metrik sumber daya, kecuali bahwa mereka hanya mendukung jenis target dari AverageValue.
Metrik Pod ditentukan menggunakan blok metrik seperti ini:
type: Pods
pods:
metric:
name: packets-per-second
target:
type: AverageValue
averageValue: 1k
Jenis metrik alternatif kedua adalah metrik objek. Metrik ini mendeskripsikan perbedaan
objek di Namespace yang sama, bukan mendeskripsikan Pod. Metriknya belum tentu
diambil dari objek; mereka hanya mendeskripsikannya. Metrik objek mendukung jenis target
baik Value dan AverageValue. Dengan Value, target dibandingkan langsung dengan yang dikembalikan
metrik dari API. Dengan AverageValue, nilai yang dikembalikan dari API metrik khusus dibagi
dengan jumlah Pod sebelum dibandingkan dengan target. Contoh berikut adalah YAML
representasi dari metrik requests-per-second.
type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
name: main-route
target:
type: Value
value: 2k
Jika kamu memberikan beberapa blok metrik seperti itu, HorizontalPodAutoscaler akan mempertimbangkan setiap metrik secara bergantian. HorizontalPodAutoscaler akan menghitung jumlah replika yang diusulkan untuk setiap metrik, lalu memilih satu dengan jumlah replika tertinggi.
Misalnya, jika sistem pemantauan kamu mengumpulkan metrik tentang lalu lintas jaringan,
kamu dapat memperbarui definisi di atas menggunakan kubectl edit agar terlihat seperti ini:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Pods
pods:
metric:
name: packets-per-second
target:
type: AverageValue
averageValue: 1k
- type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
name: main-route
target:
type: Value
value: 10k
status:
observedGeneration: 1
lastScaleTime: <some-time>
currentReplicas: 1
desiredReplicas: 1
currentMetrics:
- type: Resource
resource:
name: cpu
current:
averageUtilization: 0
averageValue: 0
- type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
name: main-route
current:
value: 10k
Kemudian, HorizontalPodAutoscaler kamu akan mencoba memastikan bahwa setiap Pod mengonsumsi kira-kira 50% dari CPU yang diminta, melayani 1000 paket per detik, dan semua Pod berada di belakang Ingress rute utama melayani total 10.000 permintaan per detik.
Banyak pipeline metrik memungkinkan kamu mendeskripsikan metrik baik berdasarkan nama atau kumpulan tambahan
deskriptor yang disebut labels. Untuk semua jenis metrik non-sumber daya (Pod, objek, dan eksternal,
dijelaskan seperti dibawah), kamu dapat menentukan pemilih label tambahan yang diteruskan ke pipa metrik kamu. Misalnya, jika kamu mengumpulkan metrik http_requests dengan label verb
, kamu dapat menentukan blok metrik berikut untuk diskalakan hanya pada permintaan GET:
type: Object
object:
metric:
name: http_requests
selector: {matchLabels: {verb: GET}}
Selector ini menggunakan sintaksis yang sama dengan selector lengkap label Kubernetes. Pipa pemantauan
menentukan cara mengecilkan beberapa seri menjadi satu nilai, jika nama dan pemilih cocok dengan
beberapa seri. Selektor bersifat aditif, dan tidak dapat memilih metrik yang mendeskripsikan objek
yang bukan objek target (target pod dalam kasus tipe Pod, dan objek yang dijelaskan dalam kasus tipe Objek).
Aplikasi yang berjalan di Kubernetes mungkin perlu melakukan penyekalaan otomatis berdasarkan metrik yang tidak memiliki hubungan yang jelas dengan objek apa pun di klaster Kubernetes, seperti metrik yang mendeskripsikan layanan yang dihosting tanpa korelasi langsung dengan namespace Kubernetes. Di Kubernetes 1.10 dan yang lebih baru, kamu dapat menangani kasus penggunaan ini dengan metrik eksternal.
Menggunakan metrik eksternal membutuhkan pengetahuan tentang sistem pemantauanmu; penyiapannya mirip dengan yang diperlukan saat menggunakan metrik khusus. Metrik eksternal memungkinkan kamu menskalakan klaster kamu secara otomatis berdasarkan metrik apa pun yang tersedia di sistem pemantauanmu. Cukup berikan blok metric dengan name dan selector (pemilih), seperti di atas, dan gunakan jenis metrik External, bukan Object.
Jika beberapa series cocok dengan metricSelector, jumlah dari nilai mereka akan digunakan oleh HorizontalPodAutoscaler.
Metrik eksternal mendukung jenis target Value dan AverageValue, yang berfungsi persis sama seperti saat kamu menggunakan tipe Object.
Misalnya, jika aplikasi kamu memproses tugas dari layanan antrian yang dihosting, kamu dapat menambahkan bagian berikut ke manifes HorizontalPodAutoscaler untuk menentukan bahwa kamu memerlukan satu pekerja per 30 tugas yang belum diselesaikan.
- type: External
external:
metric:
name: queue_messages_ready
selector: "queue=worker_tasks"
target:
type: AverageValue
averageValue: 30
Jika memungkinkan, lebih baik menggunakan target metrik khusus daripada metrik eksternal, karena lebih mudah bagi administrator klaster untuk mengamankan API metrik khusus. API metrik eksternal berpotensi memungkinkan akses ke metrik apa pun, jadi administrator klaster harus berhati-hati saat mengeksposnya.
Saat menggunakan bentuk autoscaling/v2beta2 dari HorizontalPodAutoscaler, kamu akan dapat melihat
status condition yang ditetapkan oleh Kubernetes pada HorizontalPodAutoscaler. Status condition ini menunjukkan apakah HorizontalPodAutoscaler dapat melakukan penyekalaan atau tidak, dan apakah saat ini dibatasi atau tidak.
Kondisi muncul pada field status.conditions. Untuk melihat kondisi yang memengaruhi HorizontalPodAutoscaler, kita bisa menggunakan kubectl description hpa:
kubectl describe hpa cm-test
Name: cm-test
Namespace: prom
Labels: <none>
Annotations: <none>
CreationTimestamp: Fri, 16 Jun 2017 18:09:22 +0000
Reference: ReplicationController/cm-test
Metrics: ( current / target )
"http_requests" on pods: 66m / 500m
Min replicas: 1
Max replicas: 4
ReplicationController pods: 1 current / 1 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ReadyForNewScale the last scale time was sufficiently old as to warrant a new scale
ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from pods metric http_requests
ScalingLimited False DesiredWithinRange the desired replica count is within the acceptable range
Events:
Untuk HorizontalPodAutoscaler ini, kita dapat melihat beberapa kondisi yang menandakan dalam keadaan sehat. Yang pertama, AbleToScale, menunjukkan apakah HPA dapat mengambil dan memperbarui skala atau tidak, serta apakah kondisi terkait backoff akan mencegah penyekalaan atau tidak. Yang kedua, ScalingActive, menunjukkan apakah HPA diaktifkan atau tidak (yaitu jumlah replika target bukan nol) dan mampu menghitung skala yang diinginkan. Jika False, biasanya menunjukkan masalah dengan
pengambilan metrik. Terakhir, kondisi terakhir, ScalingLimited, menunjukkan bahwa skala yang diinginkan telah dibatasi oleh maksimum atau minimum HorizontalPodAutoscaler. Ini adalah indikasi bahwa kamu mungkin ingin menaikkan atau menurunkan batasan jumlah replika minimum atau maksimum pada HorizontalPodAutoscaler kamu.
Semua metrik di HorizontalPodAutoscaler dan metrik API ditentukan menggunakan notasi bilangan bulat khusus yang dikenal di Kubernetes sebagai kuantitas. Misalnya, kuantitas 10500m akan ditulis sebagai 10.5 dalam notasi desimal. Metrik API akan menampilkan bilangan bulat tanpa sufiks jika memungkinkan, dan secara umum akan mengembalikan kuantitas dalam satuan mili. Ini berarti kamu mungkin melihat nilai metrik berfluktuasi antara 1 dan 1500m, atau 1 dan 1,5 ketika ditulis dalam notasi desimal.
Daripada menggunakan perintah kubectl autoscale untuk membuat HorizontalPodAutoscaler secara imperatif, kita dapat menggunakan berkas berikut untuk membuatnya secara deklaratif:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 50
Kita akan membuat autoscaler dengan menjalankan perintah berikut:
kubectl create -f https://k8s.io/examples/application/hpa/php-apache.yaml
horizontalpodautoscaler.autoscaling/php-apache created
Dashboard adalah antarmuka pengguna Kubernetes. Kamu dapat menggunakan Dashboard untuk men-deploy aplikasi yang sudah dikontainerisasi ke klaster Kubernetes, memecahkan masalah pada aplikasi kamu, dan mengatur sumber daya klaster. Kamu dapat menggunakan Dashboard untuk melihat ringkasan dari aplikasi yang sedang berjalan di klaster kamu, dan juga membuat atau mengedit objek individu sumber daya Kubernetes (seperti Deployment, Job, DaemonSet, dll.). Sebagai contoh, kamu dapat mengembangkan sebuah Deployment, menginisiasi sebuah pembaruan bertahap (rolling update), memulai kembali sebuah Pod atau men-deploy aplikasi baru menggunakan sebuah deploy wizard.
Dashboard juga menyediakan informasi tentang status dari sumber daya Kubernetes di klaster kamu dan kesalahan apapun yang mungkin telah terjadi..

Antarmuka Dashboard tidak ter-deploy secara bawaan. Untuk men-deploy-nya, kamu dapat menjalankan perintah berikut:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
Untuk melindungi data klaster kamu, pen-deploy-an Dashboard menggunakan sebuah konfigurasi RBAC yang minimal secara bawaan. Saat ini, Dashboard hanya mendukung otentikasi dengan Bearer Token. Untuk membuat token untuk demo, kamu dapat mengikuti petunjuk kita untuk membuat sebuah contoh pengguna.
Kamu dapat mengakses Dashboard menggunakan perkakas CLI kubectl dengan menjalankan perintah berikut:
kubectl proxy
Kubectl akan membuat Dashboard tersedia di http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/.
Antarmuka pengguna berbasis web tersebut hanya dapat di akses dari mesin dimana perintah tersebut dijalankan. Lihat kubectl proxy --help untuk lebih lanjut.
Ketika kamu mengakses Dashboard di klaster yang kosong, kamu akan melihat laman selamat datang. Laman ini berisi tautan ke dokumen ini serta tombol untuk men-deploy aplikasi pertama kamu. Selain itu, kamu dapat melihat aplikasi-aplikasi sistem mana saja yang berjalan secara bawaan di Namespace kube-system dari klaster kamu, misalnya Dashboard itu sendiri.

Dashboard memungkinkan kamu untuk membuat dan men-deploy aplikasi yang sudah dikontainerisasi sebagai Deployment dan Service opsional dengan sebuah wizard sederhana. Kamu secara manual dapat menentukan detail aplikasi, atau mengunggah sebuah berkas YAML atau JSON yang berisi konfigurasi aplikasi.
Tekan tombol CREATE di pojok kanan atas di laman apapun untuk memulai.
Deploy wizard meminta kamu untuk menyediakan informasi sebagai berikut:
App name (wajib): Nama dari aplikasi kamu. Sebuah label dengan nama tersebut akan ditambahkan ke Deployment dan Service, jika ada, akan di-deploy.
Nama aplikasi harus unik di dalam Namespace Kubernetes yang kamu pilih. Nama tersebut harus dimulai dengan huruf kecil, dan diakhiri dengan huruf kecil atau angka, dan hanya berisi huruf kecil, angka dan tanda hubung (-). Nama tersebut juga dibatasi hanya 24 karakter. Spasi di depan dan belakang nama tersebut diabaikan.
Container image (wajib): Tautan publik dari sebuah image kontainer Docker pada registry apapun, atau sebuah image privat (biasanya di-hosting di Google Container Registry atau Docker Hub). Spesifikasi image kontainer tersebut harus diakhiri dengan titik dua.
Number of pods (wajib): Berapa banyak Pod yang kamu inginkan untuk men-deploy aplikasimu. Nilainya haruslah sebuah bilangan bulat positif.
Sebuah Deployment akan terbuat untuk mempertahankan jumlah Pod di klaster kamu.
Service (opsional): Untuk beberapa aplikasi (misalnya aplikasi frontend) kamu mungkin akan mengekspos sebuah Service ke alamat IP publik yang mungkin berada diluar klaster kamu(Service eksternal). Untuk Service eksternal, kamu mungkin perlu membuka lebih dari satu porta jaringan untuk mengeksposnya. Lihat lebih lanjut di sini.
Service lainnya yang hanya dapat diakses dari dalam klaster disebut Service internal.
Terlepas dari jenis Service, jika kamu memilih untuk membuat sebuah Service dan Container kamu berjalan di sebuah porta(arah masuk), kamu perlu menentukan dua porta. Service akan memetakan porta(arah masuk) ke porta target yang ada di sisi Container. Service akan mengarahkan ke Pod-Pod kamu yang sudah di-deploy. Protokol yang didukung adalah TCP dan UDP. Nama DNS internal untuk Service ini akan sesuai dengan nama aplikasi yang telah kamu tentukan diatas.
Jika membutuhkan, kamu dapat membuka bagian Advanced options di mana kamu dapat menyetel lebih banyak pengaturan:
Description: Tels yang kamu masukkan ke sini akan ditambahkan sebagai sebuah anotasi ke Deployment dan akan ditampilkan di detail aplikasi.
Labels: Label-label bawaan yang akan digunakan untuk aplikasi kamu adalah name dan version aplikasi. Kamu dapat menentukan label lain untuk diterapkan ke Deployment, Service (jika ada), dan Pod, seperti release, environment, tier, partition, dan track rilis.
Contoh:
release=1.0
tier=frontend
environment=pod
track=stable
Namespace: Kubernetes mendukung beberapa klaster virtual yang berjalan di atas klaster fisik yang sama. Klaster virtual ini disebut Namespace. Mereka mengizinkan kamu untuk mempartisi sumber daya ke beberapa grup yang diberi nama secara logis.
Dashboard menampilkan semua Namespace yang tersedia dalam sebuah daftar dropdown, dan mengizinkan kamu untuk membuat Namespace baru. Nama yang diizinkan untuk Namespace terdiri dari maksimal 63 karakter alfanumerik dan tanda hubung (-), dan tidak boleh ada huruf kapital.
Nama dari Namespace tidak boleh terdiri dari angka saja. Jika nama Namespace disetel menjadi sebuah angka, misalnya 10, maka Pod tersebut akan ditaruh di Namespace default.
Jika pembuatan Namespace berhasil, Namespace tersebut akan dipilih secara bawaan. Jika pembuatannya gagal, maka Namespace yang pertama akan terpilih.
Image Pull Secret: Jika kamu menggunakan image kontainer Docker yang privat, mungkin diperlukan kredensial pull secret.
Dashboard menampilkan semua secret yang tersedia dengan daftar dropdown, dan mengizinkan kamu untuk membuat secret baru. Nama secret tersebut harus mengikuti aturan Nama DNS, misalnya new.image-pull.secret. Isi dari sebuah secret harus dienkode dalam bentuk base64 dan ditentukan dalam sebuah berkas .dockercfg. Nama kredensial dapat berisi maksimal 253 karakter.
Jika pembuatan image pull secret berhasil, image pull secret tersebut akan terpilih secara bawaan. Jika gagal, maka tidak ada secret yang dipilih.
CPU requirement (cores) dan Memory requirement (MiB): Kamu dapat menentukan batasan sumber daya minimal untuk Container. Secara bawaan, Pod-Pod berjalan dengan CPU dan memori yang tak dibatasi.
Run command dan Run command arguments: Secara bawaan, Container-Container kamu akan menjalankan perintah entrypoint bawaan dari image Docker yang ditentukan. Kamu dapat menggunakan opsi Run command dan Run command arguments untuk mengganti bawaannya.
Run as priveleged: Pengaturan ini untuk menentukan sebuah proses yang berjalan dalam privileged container sepadan dengan proses yang berjalan sebagai root pada host-nya. Priveleged container dapat menggunakan kemampuan seperti memanipulasi stack jaringan dan mengakses perangkat-perangkat.
Environment variables: Kubernetes mengekspos Service melalui environment variable. Kamu dapat membuat environment variable atau meneruskan argumen ke perintah-perintah untuk menjalankan Container dengan nilai dari environment variable. Environment Variable dapat digunakan pada aplikasi-aplikasi untuk menemukan sebuah Service. Nilai environment variable dapat merujuk ke variabel lain menggunakan sintaksis $(VAR_NAME).
Kubernetes mendukung pengaturan deklaratif. Dengan cara ini, semua pengaturan disimpan dalam bentuk berkas YAML atau JSON menggunakan skema sumber daya [API.
Sebagai alternatif untuk menentukan detail aplikasi di deploy wizard, kamu dapat menentukan sendiri detail aplikasi kamu dalam berkas YAML atau JSON, dan mengunggah berkas tersebut menggunakan Dashboard.
Bagian ini akan menjelaskan bagian-bagian yang ada pada Antarmuka Dashboard Kubernetes; apa saja yang mereka sediakan dan bagaimana cara menggunakanya.
Ketika ada objek Kubernetes yang sudah didefinisikan di dalam klaster, Dashboard akan menampilkanya di tampilan awalnya. Secara bawaan hanya objek-objek dalam Namespace default saja yang ditampilkan di sini dan kamu dapat menggantinya dengan selektor Namespace yang berada di menu navigasi.
Dashboard menampilkan jenis objek Kubernetes dan mengelompokanya dalam beberapa kategori menu.
Untuk administrasi klaster dan Namespace, Dashboard menampilkan Node, Namespace dan PresistentVolume dan memiliki tampilan yang detail untuk objek-objek tersebut. Daftar Node berisi metrik penggunaan CPU dan memori yang dikumpulkan dari semua Node. Tampilan detail menampilkan metrik-metrik untuk sebuah Node, spesifikasinya, status, sumber daya yang dialokasikan, event-event, dan Pod-Pod yang sedang berjalan di Node tersebut.
Menampilkan semua aplikasi yang sedang berjalan di Namespace yang dipilih. Tampilan ini menampilkan aplikasi berdasarkan jenis beban kerja (misalnya, Deployment, Replica Set, Stateful Set, dll.) dan setiap jenis beban kerja memiliki tampilanya sendiri. Daftar ini merangkum informasi yang dapat ditindaklanjuti, seperti berapa banyak Pod yang siap untuk setiap Replica Set atau penggunaan memori pada sebuah Pod.
Tampilan detail dari beban kerja menampilkan status dan informasi spesifik serta hubungan antara objek. Misalnya, Pod-Pod yang diatur oleh ReplicaSet atau, ReplicaSet-ReplicaSet baru, dan HorizontalPodAutoscaler untuk Deployment.
Menampilkan sumber daya Kubernetes yang mengizinkan untuk mengekspos Service-Service ke jaringan luar dan menemukannya (service discovery) di dalam klaster. Untuk itu, tampilan dari Service dan Ingress menunjukan Pod-Pod yang ditarget oleh mereka, endpoint-endpoint internal untuk koneksi klaster, dan endpoint-endpoint eksternal untuk pengguna eksternal.
Tampilan Storage menampilkan sumber-sumber daya PersistentVolumeClaim yang digunakan oleh aplikasi untuk menyimpan data.
Menampilkan semua sumber daya Kubernetes yang digunakan untuk pengaturan aplikasi yang sedang berjalan di klaster. Pada tampilan ini kamu dapat mengedit dan mengelola objek-objek konfigurasi dan menampilkan kredensial yang tersembunyi secara bawaan.
Laman daftar dan detail Pod tertaut dengan laman penampil log (log viewer). Kamu dapat menelusuri log yang berasal dari Container-Container pada sebuah Pod.

Untuk informasi lebih lanjut, lihat Laman proyek Kubernetes Dashboard.
Topik ini membahas tentang berbagai cara untuk berinteraksi dengan klaster.
Saat mengakses API Kubernetes untuk pertama kalinya, kami sarankan untuk menggunakan
CLI Kubernetes, kubectl.
Untuk mengakses sebuah klaster, kamu perlu mengetahui lokasi klaster dan mempunyai kredensial untuk mengaksesnya. Biasanya, ini secara otomatis diatur saat kamu mengikuti Panduan persiapan, atau orang lain yang mengatur klaster dan memberikan kredensial dan lokasi kepadamu.
Periksa lokasi dan kredensial yang ada pada konfigurasi kubectl-mu melalui perintah ini:
kubectl config view
Beragam contoh menyediakan pengantar penggunaan kubectl, dan dokumentasi lengkap dapat ditemukan di kubectl manual.
Kubectl menangani pencarian dan autentikasi ke apiserver. Jika kamu ingin secara langsung mengakses REST API dengan klien HTTP seperti curl atau wget, atau peramban, ada beberapa cara untuk pencarian dan autentikasi:
Perintah berikut akan menjalankan kubectl dalam mode di mana ia bertindak sebagai proksi terbalik (reverse proxy). Hal ini menangani pencarian dan autentikasi apiserver. Jalankan seperti ini:
kubectl proxy --port=8080
Lihat kubectl proxy untuk lebih jelasnya.
Kemudian kamu dapat menjelajahi API-nya dengan curl, wget, atau peramban, ganti localhost dengan [::1] untuk IPv6, seperti ini:
curl http://localhost:8080/api/
Hasil keluarannya seperti ini:
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
Gunakan kubectl describe secret... untuk mendapatkan token untuk akun servis (service account) default dengan grep/cut:
APISERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ")
SECRET_NAME=$(kubectl get secrets | grep ^default | cut -f1 -d ' ')
TOKEN=$(kubectl describe secret $SECRET_NAME | grep -E '^token' | cut -f2 -d':' | tr -d " ")
curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
Hasil keluarannya seperti ini:
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
Menggunakan jsonpath:
APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
SECRET_NAME=$(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}')
TOKEN=$(kubectl get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)
curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
Hasil keluarannya seperti ini:
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
Contoh di atas menggunakan flag --insecure. Hal ini membuatnya rentan terhadap serangan MITM.
Ketika kubectl mengakses klaster, kubectl menggunakan sertifikat elektronik root yang tersimpan dan sertifikat elektronik klien untuk mengakses server.
(Sertifikat-sertifikat elektronik tersebut diinstal di direktori ~/.kube). Karena sertifikat elektronik klaster biasanya ditandatangani sendiri,
mungkin diperlukan konfigurasi khusus untuk membuat klien HTTP kamu menggunakan sertifikat elektronik root.
Pada beberapa klaster, apiserver tidak memerlukan autentikasi; mungkin apiserver tersebut meladen (serve) di localhost, atau dilindungi oleh sebuah dinding api (firewall). Tidak ada standar untuk ini. Mengonfigurasi Akses ke API menjelaskan bagaimana admin klaster dapat mengonfigurasi hal ini. Pendekatan semacam itu dapat bertentangan dengan dukungan ketersediaan tinggi (high-availability) pada masa depan.
Kubernetes secara resmi mendukung pustaka (library) klien Go dan Python.
go get k8s.io/client-go@kubernetes-<kubernetes-version-number>, lihat INSTALL.md untuk instruksi instalasi yang lebih detail. Lihat https://github.com/kubernetes/client-go untuk melihat versi yang didukung.import "k8s.io/client-go/kubernetes".Klien Go dapat menggunakan berkas kubeconfig yang sama dengan yang digunakan oleh CLI kubectl untuk mencari dan mengautentikasi ke apiserver. Lihat contoh ini.
Jika aplikasi ini digunakan sebagai Pod di klaster, silakan lihat bagian selanjutnya.
Untuk menggunakan klien Python, jalankan perintah berikut: pip install kubernetes. Lihat halaman Pustaka Klien Python untuk opsi instalasi lainnya.
Klien Python dapat menggunakan berkas kubeconfig yang sama dengan yang digunakan oleh CLI kubectl untuk mencari dan mengautentikasi ke apiserver. Lihat contoh.
Ada pustaka klien untuk mengakses API dari bahasa lain. Lihat dokumentasi pustaka lain untuk melihat bagaimana mereka melakukan autentikasi.
Saat mengakses API dari Pod, pencarian dan autentikasi ke apiserver agak berbeda.
Cara yang disarankan untuk menemukan apiserver di dalam Pod adalah dengan nama DNS kubernetes.default.svc,
yang akan mengubah kedalam bentuk Service IP yang pada gilirannya akan dialihkan ke apiserver.
Cara yang disarankan untuk mengautentikasi ke apiserver adalah dengan kredensial akun servis.
Oleh kube-system, Pod dikaitkan dengan sebuah akun servis (service account), dan sebuah kredensial (token) untuk akun servis (service account) tersebut ditempatkan ke pohon sistem berkas (file system tree) dari setiap Container di dalam Pod tersebut,
di /var/run/secrets/kubernetes.io/serviceaccount/token.
Jika tersedia, bundel sertifikat elektronik ditempatkan ke pohon sistem berkas dari setiap Container di /var/run/secrets/kubernetes.io/serviceaccount/ca.crt,
dan itu akan digunakan untuk memverifikasi sertifikat elektronik yang digunakan apiserver untuk meladen.
Terakhir, Namespace default yang akan digunakan untuk operasi API namespaced ditempatkan di dalam berkas /var/run/secrets/kubernetes.io/serviceaccount/namespace di dalam setiap Container.
Dari dalam Pod, cara yang disarankan untuk menghubungi API adalah:
kubectl proxy pada Container sidecar di dalam Pod, atau sebagai proses background di dalam Container.
Perintah tersebut memproksi API Kubernetes pada antarmuka localhost Pod tersebut, sehingga proses lain dalam Container apa pun milik Pod dapat mengaksesnya.rest.InClusterConfig() dan kubernetes.NewForConfig().
Mereka menangani pencarian dan autentikasi ke apiserver. contohPada setiap kasus, kredensial Pod digunakan untuk berkomunikasi secara aman dengan apiserver.
Bagian sebelumnya menjelaskan tentang menghubungi server API Kubernetes. Bagian ini menjelaskan tentang menghubungi servis lain yang berjalan di klaster Kubernetes. Di Kubernetes, semua Node, Pod, dan Service memiliki IP sendiri. Dalam banyak kasus, IP Node, IP Pod, dan beberapa IP Service pada sebuah klaster tidak dapat dirutekan, sehingga mereka tidak terjangkau dari mesin di luar klaster, seperti mesin desktop kamu.
Kamu memiliki beberapa opsi untuk menghubungi Node, Pod, dan Service dari luar klaster:
NodePort atau LoadBalancer untuk membuat Service dapat dijangkau di luar klaster. Lihat dokumentasi Service dan perintah kubectl expose.Biasanya, ada beberapa Service yang dimulai pada sebuah klaster oleh kube-system. Dapatkan daftarnya dengan perintah kubectl cluster-info:
kubectl cluster-info
Keluarannya mirip seperti ini:
Kubernetes master is running at https://104.197.5.247
elasticsearch-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy
kibana-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kibana-logging/proxy
kube-dns is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns/proxy
grafana is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy
Ini menunjukkan URL proxy-verb untuk mengakses setiap Service.
Misalnya, klaster ini mempunyai pencatatan log pada level klaster (cluster-level logging) yang aktif (menggunakan Elasticsearch), yang dapat dicapai di https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/ jika kredensial yang sesuai diberikan.
Pencatatan log dapat pula dicapai dengan sebuah proksi kubectl, misalnya di:
http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/.
(Lihat di atas untuk panduan bagaimana cara meneruskan kredensial atau menggunakan kubectl proxy.)
Seperti disebutkan di atas, kamu menggunakan perintah kubectl cluster-info untuk mendapatkan URL proksi suatu Service.
Untuk membuat URL proksi yang memuat endpoint-endpoint Service, sufiks, dan parameter, kamu cukup menambahkan ke URL proksi Service:
http://alamat_kubernetes_master/api/v1/namespaces/nama_namespace/services/nama_servis[:nama_porta]/proxy
Jika kamu belum menentukan nama untuk porta kamu, kamu tidak perlu memasukan nama_porta di URL.
Secara bawaan, server API memproksi ke Service kamu menggunakan HTTP. Untuk menggunakan HTTPS, awali nama Service dengan https::
http://alamat_kubernetes_master/api/v1/namespaces/nama_namespace/services/https:nama_servis:[nama_porta]/proxy
Format yang didukung untuk segmen nama URL adalah:
<nama_servis> - Memproksi ke porta bawaan atau porta tanpa nama menggunakan HTTP<nama_servis>:<nama_porta> - Memproksi ke porta yang telah ditentukan menggunakan HTTPhttps:<nama_servis>: - Memproksi ke porta bawaan atau porta tanpa nama menggunakan HTTPS (perhatikan tanda adanya titik dua)https:<nama_servis>:<nama_porta> - proksi ke porta yang telah ditentukan menggunakan https_search?q=user:kimchy, kamu dapat menggunakan: http://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchy_cluster/health?pretty=true, kamu dapat menggunakan: https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true{
"cluster_name" : "kubernetes_logging",
"status" : "yellow",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 5,
"active_shards" : 5,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 5
}
Kamu mungkin dapat memasukkan URL proksi apiserver ke bilah alamat peramban. Namun:
/proxy).Kemampuan pengalihan telah usang (deprecated) dan dihapus. Silakan gunakan proksi (lihat di bawah) sebagai gantinya.
Ada beberapa proksi berbeda yang mungkin kamu temui saat menggunakan Kubernetes:
Sebuah Proksi/Load-balancer di depan apiserver:
Cloud Load Balancer pada Service eksternal:
LoadBalancerPengguna Kubernetes biasanya tidak perlu khawatir tentang apa pun selain dua jenis pertama. Admin klaster biasanya akan memastikan bahwa tipe yang terakhir telah diatur dengan benar.
Halaman ini menunjukkan bagaimana mengkonfigurasi akses ke banyak klaster dengan menggunakan
berkas (file) konfigurasi. Setelah semua klaster, pengguna, dan konteks didefinisikan di
satu atau lebih berkas konfigurasi, kamu akan dengan cepat berpindah antar klaster dengan menggunakan
perintah kubectl config use-context.
kubeconfig.Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Misalkan kamu memiliki dua klaster, satu untuk pekerjaan pengembangan dan satu untuk pekerjaan eksperimen (scratch).
Di klaster pengembangan, pengembang frontend kamu bekerja di sebuah Namespace bernama frontend,
dan pengembang penyimpanan kamu bekerja di sebuah Namespace bernama storage. Di klaster scratch kamu,
pengembang bekerja di Namespace default, atau mereka membuat Namespace tambahan sesuai keinginan mereka.
Akses ke klaster development membutuhkan autentikasi dengan sertifikat.
Akses ke klaster scratch membutuhkan autentikasi dengan nama pengguna dan kata sandi.
Buat sebuah direktori bernama config-exercise. Di direktori config-exercise kamu,
buat sebuah berkas bernama config-demo dengan konten ini:
apiVersion: v1
kind: Config
preferences: {}
clusters:
- cluster:
name: development
- cluster:
name: scratch
users:
- name: developer
- name: experimenter
contexts:
- context:
name: dev-frontend
- context:
name: dev-storage
- context:
name: exp-scratch
Berkas konfigurasi di atas mendeskripsikan semua klaster, pengguna, dan konteks.
Berkas config-demo kamu memiliki kerangka kerja untuk mendeskripsikan dua klaster, dua pengguna, dan tiga konteks.
Buka direktori config-exercise kamu. Masukkan perintah-perintah berikut untuk menambahkan detail ke
berkas konfigurasi kamu:
kubectl config --kubeconfig=config-demo set-cluster development --server=https://1.2.3.4 --certificate-authority=fake-ca-file
kubectl config --kubeconfig=config-demo set-cluster scratch --server=https://5.6.7.8 --insecure-skip-tls-verify
Tambahkan detail pengguna ke berkas konfigurasi kamu:
kubectl config --kubeconfig=config-demo set-credentials developer --client-certificate=fake-cert-file --client-key=fake-key-seefile
kubectl config --kubeconfig=config-demo set-credentials experimenter --username=exp --password=some-password
kubectl --kubeconfig=config-demo config unset users.<name>kubectl --kubeconfig=config-demo config unset clusters.<name>kubectl --kubeconfig=config-demo config unset contexts.<name>Tambahkan detail konteks ke berkas konfigurasi kamu:
kubectl config --kubeconfig=config-demo set-context dev-frontend --cluster=development --namespace=frontend --user=developer
kubectl config --kubeconfig=config-demo set-context dev-storage --cluster=development --namespace=storage --user=developer
kubectl config --kubeconfig=config-demo set-context exp-scratch --cluster=scratch --namespace=default --user=experimenter
Buka berkas config-demo kamu untuk melihat detail-detail yang telah ditambah. Sebagai alternatif dari membuka
berkas config-demo, kamu bisa menggunakan perintah config view.
kubectl config --kubeconfig=config-demo view
Keluaran akan menampilkan dua klaster, dua pengguna, dan tiga konteks:
apiVersion: v1
clusters:
- cluster:
certificate-authority: fake-ca-file
server: https://1.2.3.4
name: development
- cluster:
insecure-skip-tls-verify: true
server: https://5.6.7.8
name: scratch
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
- context:
cluster: development
namespace: storage
user: developer
name: dev-storage
- context:
cluster: scratch
namespace: default
user: experimenter
name: exp-scratch
current-context: ""
kind: Config
preferences: {}
users:
- name: developer
user:
client-certificate: fake-cert-file
client-key: fake-key-file
- name: experimenter
user:
password: some-password
username: exp
fake-ca-file, fake-cert-file, dan fake-key-file di atas adalah placeholder
untuk nama jalur (pathname) dari berkas-berkas sertifikat. Kamu harus menggantinya menjadi nama jalur
sebenarnya dari berkas-berkas sertifikat di dalam lingkungan (environment) kamu.
Terkadang kamu mungkin ingin menggunakan data yang disandikan Base64 yang langsung dimasukkan di berkas konfigurasi
daripada menggunakan berkas sertifikat yang terpisah. Dalam kasus ini, kamu perlu menambahkan akhiran -data ke kunci. Contoh, certificate-authority-data, client-certificate-data, dan client-key-data.
Setiap konteks memiliki tiga bagian: klaster, pengguna, dan Namespace.
Sebagai contoh, konteks dev-frontend menyatakan, "Gunakan kredensial dari pengguna developer
untuk mengakses Namespace frontend di klaster development.
Mengatur konteks yang digunakan:
kubectl config --kubeconfig=config-demo use-context dev-frontend
Sekarang kapanpun kamu memasukkan perintah kubectl, aksi tersebut akan diterapkan untuk klaster,
dan Namespace yang terdaftar pada konteks dev-frontend. Dan perintah tersebut akan menggunakan
kredensial dari pengguna yang terdaftar pada konteks dev-frontend.
Untuk melihat hanya informasi konfigurasi yang berkaitan dengan konteks saat ini,
gunakan --minify flag.
kubectl config --kubeconfig=config-demo view --minify
Output menunjukkan informasi konfigurasi yang berkaitan dengan konteks dev-frontend:
apiVersion: v1
clusters:
- cluster:
certificate-authority: fake-ca-file
server: https://1.2.3.4
name: development
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
current-context: dev-frontend
kind: Config
preferences: {}
users:
- name: developer
user:
client-certificate: fake-cert-file
client-key: fake-key-file
Sekarang apabila kamu ingin bekerja sebentar di klaster eksperimen.
Ubah konteks saat ini menjadi exp-scratch:
kubectl config --kubeconfig=config-demo use-context exp-scratch
Sekarang, setiap perintah kubectl yang diberikan akan berlaku untuk Namespace default
dari klaster scratch. Dan perintah akan menggunakan kredensial dari pengguna yang
terdaftar di konteks exp-scratch.
Untuk melihat konfigurasi yang berkaitan dengan konteks saat ini, exp-scratch.
kubectl config --kubeconfig=config-demo view --minify
Akhirnya, misalkan kamu ingin bekerja sebentar di Namespace storage pada
klaster development.
Ubah konteks saat ini menjadi dev-storage:
kubectl config --kubeconfig=config-demo use-context dev-storage
Untuk melihat konfigurasi yang berkaitan dengan konteks baru saat ini, dev-storage.
kubectl config --kubeconfig=config-demo view --minify
Di direktori config-exercise kamu, buat sebuah berkas bernama config-demo-2 dengan konten ini:
apiVersion: v1
kind: Config
preferences: {}
contexts:
- context:
cluster: development
namespace: ramp
user: developer
name: dev-ramp-up
Berkas konfigurasi di atas mendefinisikan sebuah konteks baru bernama dev-ramp-up.
Lihat apakah kamu sudah memiliki sebuah variabel lingkungan bernama KUBECONFIG.
Jika iya, simpan nilai saat ini dari variabel lingkungan KUBECONFIG kamu, sehingga kamu dapat mengembalikannya nanti.
Sebagai contohL
export KUBECONFIG_SAVED=$KUBECONFIG
$Env:KUBECONFIG_SAVED=$ENV:KUBECONFIG
Variabel lingkungan KUBECONFIG adalah sebuah daftar dari jalur-jalur (beragam path) menuju berkas konfigurasi.
Daftar ini dibatasi oleh tanda titik dua untuk Linux dan Mac, dan tanda titik koma untuk Windows. Jika kamu
memiliki sebuah variabel lingkungan KUBECONFIG, biasakan diri kamu dengan berkas-berkas konfigurasi
yang ada pada daftar.
Tambahkan sementara dua jalur ke variabel lingkungan KUBECONFIG kamu. Sebagai contoh:
export KUBECONFIG=$KUBECONFIG:config-demo:config-demo-2
$Env:KUBECONFIG=("config-demo;config-demo-2")
Di direktori config-exercise kamu, masukan perintah ini:
kubectl config view
Keluaran menunjukkan informasi gabungan dari semua berkas yang terdaftar dalam variabel lingkungan KUBECONFIG kamu.
Secara khusus, perhatikan bahwa informasi gabungan tersebut memiliki konteks dev-ramp-up, konteks dari berkas
config-demo-2, dan tiga konteks dari berkas config-demo:
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
- context:
cluster: development
namespace: ramp
user: developer
name: dev-ramp-up
- context:
cluster: development
namespace: storage
user: developer
name: dev-storage
- context:
cluster: scratch
namespace: default
user: experimenter
name: exp-scratch
Untuk informasi lebih tentang bagaimana berkas Kubeconfig tergabung, lihat Mengatur Akses Cluster Menggunakan Berkas Kubeconfig
Jika kamu sudah memiliki sebuah klaster, dan kamu bisa menggunakan kubectl untuk berinteraksi dengan
klaster kamu, kemudian kamu mungkin memiliki sebuah berkas bernama config di
direktori $HOME/.kube.
Buka $HOME/.kube, dan lihat berkas-berkas apa saja yang ada. Biasanya ada berkas bernama
config. Mungkin juga ada berkas-berkas konfigurasi lain di direktori ini.
Biasakan diri anda dengan konten-konten yang ada di berkas-berkas tersebut.
Jika kamu memiliki sebuah berkas $HOME/.kube/config, dan belum terdaftar dalam variabel lingungan
KUBECONFIG kamu, tambahkan berkas tersebut ke variabel lingkungan KUBECONFIG kamu sekarang.
Sebagai contoh:
export KUBECONFIG=$KUBECONFIG:$HOME/.kube/config
$Env:KUBECONFIG=($Env:KUBECONFIG;$HOME/.kube/config)
Lihat gabungan informasi konfigurasi dari semua berkas yang sekarang tergabung
dalam variabel lingkungan KUBECONFIG kamu. Di direktori config-exercise kamu, masukkan perintah:
kubectl config view
Kembalikan variabel lingkungan KUBECONFIG kamu ke nilai asilnya. Sebagai contoh:
export KUBECONFIG=$KUBECONFIG_SAVED
$Env:KUBECONFIG=$ENV:KUBECONFIG_SAVED
Halaman ini menunjukkan bagaimana menggunakan kubectl port-forward untuk menghubungkan sebuah server Redis yang sedang berjalan di sebuah klaster Kubernetes. Tipe dari koneksi ini dapat berguna untuk melakukan debugging basis data.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Kubernetes servermu harus dalam versi yang sama atau lebih baru dari v1.10.Untuk melihat versi, tekan kubectl version.
Buat sebuah Deployment yang menjalankan Redis:
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-deployment.yaml
Keluaran dari sebuah perintah yang sukses akan memverifikasi bahwa Deployment telah terbuat:
deployment.apps/redis-master created
Lihat status Pod untuk memeriksa apakah sudah siap:
kubectl get pods
Keluaran menampilkan Pod yang telah terbuat:
NAME READY STATUS RESTARTS AGE
redis-master-765d459796-258hz 1/1 Running 0 50s
Lihat status Deployment:
kubectl get deployment
Keluaran menampilkan bahwa Deployment telah terbuat:
NAME READY UP-TO-DATE AVAILABLE AGE
redis-master 1/1 1 1 55s
Deployment secara otomatis mengatur sebuah ReplicaSet. Lihat status ReplicaSet menggunakan:
kubectl get replicaset
Keluaran menampilkan bahwa ReplicaSet telah terbuat:
NAME DESIRED CURRENT READY AGE
redis-master-765d459796 1 1 1 1m
Buat sebuah Service untuk mengekspos Redis di jaringan:
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-service.yaml
Keluaran dari perintah yang sukses akan memverifikasi bahwa Service telah terbuat:
service/redis-master created
Lihat Service yang telah terbuat menggunakan:
kubectl get service redis-master
Keluaran menampilkan service yang telah terbuat:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-master ClusterIP 10.0.0.213 <none> 6379/TCP 27s
Periksa apakah server Redis berjalan di Pod, dan mendengarkan porta 6379:
# Ubah redis-master-765d459796-258hz menjadi nama Pod
kubectl get pod redis-master-765d459796-258hz --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'
Keluaran akan menampilkan porta dari Redis di Pod tersebut:
6379
(ini adalah porta TCP yang dialokasi untuk Redis di internet)
kubectl port-forward memungkinkan penggunaan nama sumber daya, seperti sebuah nama Pod, untuk memilih Pod yang sesuai untuk melakukan penerusan porta.
# Ubah redis-master-765d459796-258hz menjadi nama Pod
kubectl port-forward redis-master-765d459796-258hz 7000:6379
yang sama seperti
kubectl port-forward pods/redis-master-765d459796-258hz 7000:6379
atau
kubectl port-forward deployment/redis-master 7000:6379
atau
kubectl port-forward replicaset/redis-master 7000:6379
atau
kubectl port-forward service/redis-master 7000:6379
Semua perintah di atas berfungsi. Keluarannya mirip dengan ini:
I0710 14:43:38.274550 3655 portforward.go:225] Forwarding from 127.0.0.1:7000 -> 6379
I0710 14:43:38.274797 3655 portforward.go:225] Forwarding from [::1]:7000 -> 6379
Memulai antarmuka baris perintah (command line) Redis:
redis-cli -p 7000
Pada baris perintah di Redis, masukkan perintah ping:
ping
Sebuah permintaan ping yang sukses akan mengembalikan:
PONG
Koneksi-koneksi yang dibuat ke porta lokal 7000 diteruskan ke porta 6379 dari Pod yang menjalankan server Redis. Dengan koneksi ini, kamu dapat menggunakan workstation lokal untuk melakukan debug basis data yang berjalan di Pod.
kubectl port-forward hanya bisa diimplementasikan untuk porta TCP saja.
Dukungan untuk protokol UDP bisa dilihat di
issue 47862.Belajar lebih tentang kubectl port-forward.
Laman ini menjelaskan bagaimana membuat Load Balancer Eksternal.
Ketika membuat Service, kamu mempunyai opsi untuk tersambung dengan jaringan cloud load balancer secara otomatis. Hal ini menyediakan akses eksternal alamat IP yang dapat mengirim lalu lintas melalui porta yang tepat pada klaster Node kamu asalkan klaster kamu beroperasi pada lingkungan yang mendukung dan terkonfigurasi dengan paket penyedia cloud load balancer yang benar.
Untuk informasi mengenai penyediaan dan penggunaan sumber daya Ingress yang dapat memberikan servis URL yang dapat dijangkau secara eksternal, penyeimbang beban lalu lintas, terminasi SSL, dll., silahkan cek dokumentasi Ingress
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Untuk membuat load balancer eksternal, tambahkan baris di bawah ini ke berkas konfigurasi Service kamu:
type: LoadBalancer
Berkas konfigurasi kamu mungkin terlihat seperti ini:
apiVersion: v1
kind: Service
metadata:
name: example-service
spec:
selector:
app: example
ports:
- port: 8765
targetPort: 9376
type: LoadBalancer
Kamu dapat membuat Service dengan perintah kubectl expose dan
flag --type=LoadBalancer:
kubectl expose rc example --port=8765 --target-port=9376 \
--name=example-service --type=LoadBalancer
Perintah ini membuat Service baru dengan menggunakan pemilih yang sama dengan
sumber daya yang dirujuk (dalam hal contoh di atas, ReplicationController bernama example).
Untuk informasi lebih lanjut, termasuk opsi flag, mengacu kepada
referensi kubectl expose.
Kamu dapat menemukan alamat IP yang telah dibuat untuk Service kamu dengan mendapatkan
informasi Service melalui kubectl:
kubectl describe services example-service
yang seharusnya menghasilkan keluaran seperti ini:
Name: example-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=example
Type: LoadBalancer
IP: 10.67.252.103
LoadBalancer Ingress: 192.0.2.89
Port: <unnamed> 80/TCP
NodePort: <unnamed> 32445/TCP
Endpoints: 10.64.0.4:80,10.64.1.5:80,10.64.2.4:80
Session Affinity: None
Events: <none>
Alamat IP tercantum di sebelah LoadBalancer Ingress.
minikube service example-service --url
Implementasi dari fitur ini menyebabkan sumber IP yang terlihat pada Container target bukan sebagai sumber IP asli dari klien. Untuk mengaktifkan preservasi IP klien, bidang berikut dapat dikonfigurasikan di dalam spek Service (mendukung lingkungan GCE/Google Kubernetes Engine):
service.spec.externalTrafficPolicy - menunjukkan jika Service menginginkan rute lalu lintas
eksternal ke titik akhir node-local atau cluster-wide. Terdapat dua opsi yang tersedia:
Cluster (bawaan) dan Local. Cluster mengaburkan sumber IP klien dan mungkin menyebabkan
hop kedua ke Node berbeda, namun harus mempunyai penyebaran beban (load-spreading) yang baik secara keseluruhan.
Local mempreservasi sumber IP client dan menghindari hop kedua LoadBalancer dan Service dengan tipe NodePort, namun
resiko berpotensi penyebaran lalu lintas yang tidak merata.service.spec.healthCheckNodePort - menentukan pemeriksaan kesehatan porta dari sebuah Node (angka porta numerik) untuk Service.
Jika healthCheckNodePort tidak ditentukan, pengendali Service mengalokasi
porta dari rentang NodePort dari klaster kamu. Kamu dapat mengonfigurasi
rentangan tersebut dari pengaturan opsi barisan perintah API server,
--service-node-port-range. Hal itu menggunakan nilai healthCheckNodePort pengguna spesifik
jika ditentukan oleh klien. Hal itu dapat berefek hanya ketika type diset ke LoadBalancer dan
externalTrafficPolicy diset ke Local.Pengaturan externalTrafficPolicy ke Local pada berkas konfigurasi Service mengaktifkan
fitur ini.
apiVersion: v1
kind: Service
metadata:
name: example-service
spec:
selector:
app: example
ports:
- port: 8765
targetPort: 9376
externalTrafficPolicy: Local
type: LoadBalancer
Kubernetes v1.17 [stable]
Pada kasus biasa, sumber daya load balancer yang berkorelasi pada penyedia cloud perlu dibersihkan segera setelah Service bertipe LoadBalancer dihapus. Namun perlu diketahui bahwa terdapat kasus tepi dimana sumber daya cloud yatim piatu (orphaned) setelah Service yang berkaitan dihapus. Finalizer Protection untuk Service LoadBalancer diperkenalkan untuk mencegah hal ini terjadi. Dengan menggunakan finalizers, sebuah sumber daya Service tidak akan pernah dihapus hingga sumber daya load balancer yang berkorelasi juga dihapus.
Secara khusus, jika Service mempunyai type LoadBalancer, pengendali Service akan melekatkan
finalizer bernama service.kubernetes.io/load-balancer-cleanup.
Finalizer hanya akan dihapus setelah sumber daya load balancer dibersihkan.
Hal ini mencegah sumber daya load balancer yang teruntai bahkan setelah kasus tepi seperti
pengendali Service berhenti.
Penting untuk dicatat bahwa jalur data untuk fungsionalitas ini disediakan oleh load balancer eksternal ke klaster Kubernetes.
Ketika Service type diset LoadBalancer, Kubernetes menyediakan fungsionalitas yang ekuivalen dengan type sebanding ClusterIP
ke berbagai Pod di dalam klaster dan mengekstensinya dengan pemrograman (eksternal dari Kubernetes) load balancer dengan entri pada Pod
Kubernetes. Pengendali Service Kubernetes mengotomasi pembuatan load balancer eksternal, cek kesehatan (jika dibutuhkan),
dinding api (firewall) (jika dibutuhkan), dan mengambil IP eksternal yang dialokasikan oleh penyedia cloud dan mengisinya pada objek Service.
Load balancers GCE/AWS tidak menyediakan bobot pada kolam targetnya (target pools). Hal ini bukan merupakan isu dengan aturan kube-proxy Load balancer lama yang akan menyeimbangkan semua titik akhir dengan benar.
Dengan fungsionalitas yang baru, lalu lintas eksternal tidak menyeimbangkan beban secara merata pada seluruh Pod, namun sebaliknya menyeimbangkan secara merata pada level Node (karena GCE/AWS dan implementasi load balancer eksternal lainnya tidak mempunyai kemampuan untuk menentukan bobot setiap Node, mereka menyeimbangkan secara merata pada semua Node target, mengabaikan jumlah Pod pada tiap Node).
Namun demikian, kita dapat menyatakan bahwa NumServicePods << NumNodes atau NumServicePods >> NumNodes, distribusi yang cukup mendekati sama akan terlihat, meski tanpa bobot.
Sekali load balancer eksternal menyediakan bobot, fungsionalitas ini dapat ditambahkan pada jalur pemrograman load balancer. Pekerjaan Masa Depan: Tidak adanya dukungan untuk bobot yang disediakan untuk rilis 1.4, namun dapat ditambahkan di masa mendatang
Pod internal ke lalu lintas Pod harus berperilaku sama seperti Service ClusterIP, dengan probabilitas yang sama pada seluruh Pod.
Laman ini menunjukkan cara menggunakan kubectl untuk membuat daftar semua image Container untuk Pod yang berjalan dalam sebuah klaster.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Dalam latihan ini kamu akan menggunakan kubectl untuk mengambil semua Pod yang berjalan dalam sebuah klaster, dan mengubah format keluarannya untuk melihat daftar Container untuk masing-masing Pod.
kubectl get pods --all-namespaces-o jsonpath={.items[*].spec.containers[*].image}. Perintah ini akan mem-parsing field
image dari keluaran json yang dihasilkan.
jsonpath.tr, sort, uniq
tr untuk mengganti spasi dengan garis barusort untuk menyortir hasiluniq untuk mengumpulkan jumlah imagekubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" |\
tr -s '[[:space:]]' '\n' |\
sort |\
uniq -c
Perintah di atas secara berulang akan mengembalikan semua field bernama image
dari semua poin yang dikembalikan.
Sebagai pilihan, dimungkinkan juga untuk menggunakan jalur (path) absolut ke field image
di dalam Pod. Hal ini memastikan field yang diambil benar
bahkan ketika nama field tersebut diulangi,
misalnya banyak field disebut dengan name dalam sebuah poin yang diberikan:
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}"
Jsonpath dapat diartikan sebagai berikut:
.items[*]: untuk setiap nilai yang dihasilkan.spec: untuk mendapatkan spesifikasi.containers[*]: untuk setiap Container.image: untuk mendapatkan imagekubectl get pod nginx,
bagian .items[*] dari jalur harus dihilangkan karena hanya akan menghasilkan sebuah Pod
sebagai keluarannya, bukan daftar dari semua Pod.Format dapat dikontrol lebih lanjut dengan menggunakan operasi range untuk
melakukan iterasi untuk setiap elemen secara individual.
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |\
sort
Untuk menargetkan hanya Pod yang cocok dengan label tertentu saja, gunakan tanda -l. Filter
dibawah ini akan menghasilkan Pod dengan label yang cocok dengan app=nginx.
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" -l app=nginx
Untuk hanya menargetkan Pod pada Namespace tertentu, gunakankan tanda Namespace. Filter
dibawah ini hanya menyaring Pod pada Namespace kube-system.
kubectl get pods --namespace kube-system -o jsonpath="{.items[*].spec.containers[*].image}"
Sebagai alternatif untuk jsonpath, kubectl mendukung penggunaan go-template
untuk memformat keluaran seperti berikut:
kubectl get pods --all-namespaces -o go-template --template="{{range .items}}{{range .spec.containers}}{{.image}} {{end}}{{end}}"
Setelah aplikasi kamu berjalan, kamu pasti perlu untuk men-debug masalah yang ada di dalamnya.
Sebelumnya telah dijelaskan bagaimana kamu dapat menggunakan kubectl get pods untuk mengambil informasi status sederhana tentang
Pod kamu. Namun ada sejumlah cara untuk mendapatkan lebih banyak informasi tentang aplikasi kamu.
kubectl describe pod untuk mengambil detil informasi PodDalam contoh ini, kamu menggunakan Deployment untuk membuat dua buah Pod, yang hampir sama dengan contoh sebelumnya.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
Buat Deployment dengan menjalankan perintah ini:
kubectl apply -f https://k8s.io/examples/application/nginx-with-request.yaml
deployment.apps/nginx-deployment created
Cek status dari Pod dengan menggunakan perintah:
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-1006230814-6winp 1/1 Running 0 11s
nginx-deployment-1006230814-fmgu3 1/1 Running 0 11s
Kamu dapat memperoleh lebih banyak informasi tentang masing-masing Pod ini dengan menggunakan perintah kubectl describe pod. Sebagai contoh:
kubectl describe pod nginx-deployment-1006230814-6winp
Name: nginx-deployment-1006230814-6winp
Namespace: default
Node: kubernetes-node-wul5/10.240.0.9
Start Time: Thu, 24 Mar 2016 01:39:49 +0000
Labels: app=nginx,pod-template-hash=1006230814
Annotations: kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicaSet","namespace":"default","name":"nginx-deployment-1956810328","uid":"14e607e7-8ba1-11e7-b5cb-fa16" ...
Status: Running
IP: 10.244.0.6
Controllers: ReplicaSet/nginx-deployment-1006230814
Containers:
nginx:
Container ID: docker://90315cc9f513c724e9957a4788d3e625a078de84750f244a40f97ae355eb1149
Image: nginx
Image ID: docker://6f62f48c4e55d700cf3eb1b5e33fa051802986b77b874cc351cce539e5163707
Port: 80/TCP
QoS Tier:
cpu: Guaranteed
memory: Guaranteed
Limits:
cpu: 500m
memory: 128Mi
Requests:
memory: 128Mi
cpu: 500m
State: Running
Started: Thu, 24 Mar 2016 01:39:51 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-5kdvl (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-4bcbi:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-4bcbi
Optional: false
QoS Class: Guaranteed
Node-Selectors: <none>
Tolerations: <none>
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
54s 54s 1 {default-scheduler } Normal Scheduled Successfully assigned nginx-deployment-1006230814-6winp to kubernetes-node-wul5
54s 54s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Pulling pulling image "nginx"
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Pulled Successfully pulled image "nginx"
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Created Created container with docker id 90315cc9f513
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Started Started container with docker id 90315cc9f513
Di sini kamu dapat melihat informasi konfigurasi tentang Container dan Pod (label, kebutuhan resource, dll.), serta informasi status tentang Container dan Pod (status, kesiapan, berapa kali restart, event, dll.) .
Keadaan (state) Container merupakan salah satu dari keadaan Waiting, Running, atau Terminated. Tergantung dari keadaannya, informasi tambahan akan diberikan - di sini kamu dapat melihat bahwa untuk Container dalam keadaan running, sistem memberi tahu kamu kapan Container tersebut mulai dijalankan.
Ready memberi tahu kepada kamu apakah Container berhasil melewati pemeriksaan kesiapan terakhir. (Dalam kasus ini, Container tidak memiliki pemeriksaan kesiapan yang dikonfigurasi; Container dianggap selalu siap jika tidak ada pemeriksaan kesiapan yang dikonfigurasi.)
Jumlah restart memberi tahu kamu berapa kali Container telah dimulai ulang; informasi ini dapat berguna untuk mendeteksi kemacetan tertutup (crash loop) dalam Container yang dikonfigurasi dengan nilai restart policy 'always.'.
Saat ini, satu-satunya kondisi yang terkait dengan Pod adalah kondisi Binary Ready, yang menunjukkan bahwa Pod tersebut dapat melayani permintaan dan harus ditambahkan ke kumpulan penyeimbang beban (load balancing) dari semua Service yang sesuai.
Terakhir, kamu melihat catatan (log) peristiwa terbaru yang terkait dengan Pod kamu. Sistem mengompresi beberapa peristiwa yang identik dengan menunjukkan kapan pertama dan terakhir kali peristiwa itu dilihat dan berapa kali peristiwa itu dilihat. "From" menunjukkan komponen yang mencatat peristiwa, "SubobjectPath" memberi tahu kamu objek mana (mis. Container dalam pod) yang dimaksud, dan "Reason" dan "Message" memberi tahu kamu apa yang sudah terjadi.
Skenario umum yang bisa kamu deteksi menggunakan peristiwa (event) adalah saat kamu telah membuat Pod yang tidak muat di Node mana pun. Misalnya, karena Pod mungkin meminta lebih banyak sumber daya yang tersedia dalam Node mana pun, atau mungkin Pod menentukan label selector yang tidak sesuai dengan Node mana pun. Katakanlah kamu sebelumnya membuat Deployment dengan 5 replika (bukan 2) dan meminta 600 millicore, bukan 500, pada klaster dengan empat Node di mana setiap mesin (virtual) memiliki 1 CPU. Sehingga salah satu Pod tidak akan bisa dijadwalkan. (Perhatikan bahwa Pod addon seperti fluentd, skydns, dll., yang berjalan di setiap Node pada klaster, tidak bisa dijadwalkan jika kamu meminta sebanyak 1000 millicore.)
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-1006230814-6winp 1/1 Running 0 7m
nginx-deployment-1006230814-fmgu3 1/1 Running 0 7m
nginx-deployment-1370807587-6ekbw 1/1 Running 0 1m
nginx-deployment-1370807587-fg172 0/1 Pending 0 1m
nginx-deployment-1370807587-fz9sd 0/1 Pending 0 1m
Untuk mencari sebab kenapa Pod nginx-deployment-1370807587-fz9sd tidak berjalan, kamu dapat menggunakan kubectl describe pod pada Pod yang pending dan melihat setiap peristiwa yang terjadi di dalamnya:
kubectl describe pod nginx-deployment-1370807587-fz9sd
Name: nginx-deployment-1370807587-fz9sd
Namespace: default
Node: /
Labels: app=nginx,pod-template-hash=1370807587
Status: Pending
IP:
Controllers: ReplicaSet/nginx-deployment-1370807587
Containers:
nginx:
Image: nginx
Port: 80/TCP
QoS Tier:
memory: Guaranteed
cpu: Guaranteed
Limits:
cpu: 1
memory: 128Mi
Requests:
cpu: 1
memory: 128Mi
Environment Variables:
Volumes:
default-token-4bcbi:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-4bcbi
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 48s 7 {default-scheduler } Warning FailedScheduling pod (nginx-deployment-1370807587-fz9sd) failed to fit in any node
fit failure on node (kubernetes-node-6ta5): Node didn't have enough resource: CPU, requested: 1000, used: 1420, capacity: 2000
fit failure on node (kubernetes-node-wul5): Node didn't have enough resource: CPU, requested: 1000, used: 1100, capacity: 2000
Di sini kamu dapat melihat peristiwa yang dibuat oleh penjadwal yang mengatakan bahwa Pod gagal dijadwalkan karena alasan FailedScheduling (dan mungkin karena sebab yang lainnya). Pesan tersebut memberi tahu kamu bahwa tidak ada cukup sumber daya untuk Pod pada salah satu Node.
Untuk memperbaiki situasi ini, kamu dapat menggunakan kubectl scale untuk memperbarui Deployment kamu untuk menentukan empat replika atau yang lebih kecil. (Atau kamu bisa membiarkan satu Pod tertunda, dimana hal ini tidak berbahaya.)
Peristiwa seperti yang kamu lihat di bagian akhir keluaran dari perintah kubectl description pod akan tetap ada dalam etcd dan memberikan informasi tingkat tinggi tentang apa yang terjadi pada klaster. Untuk melihat daftar semua peristiwa kamu dapat menggunakan perintah
kubectl get events
tetapi kamu harus ingat bahwa peristiwa bersifat Namespace. Artinya, jika kamu tertarik dengan peristiwa untuk beberapa objek dalam Namespace (misalnya, apa yang terjadi dengan Pod pada Namespace my-namespace), kamu perlu secara eksplisit menyebutkan Namespace tersebut pada perintah:
kubectl get events --namespace=my-namespace
Untuk melihat peristiwa dari semua Namespace, kamu dapat menggunakan argumen --all-namespaces.
Sebagai tambahan dari perintah kubectl describe pod, cara lain untuk mendapatkan informasi tambahan tentang sebuah Pod (selain yang disediakan oleh kubectl get pod) adalah dengan meneruskan flag format keluaran -o yaml ke perintah kubectl get pod. Ini akan memberikan kamu lebih banyak informasi dalam format YAML daripada kubectl describe pod--semua informasi dasar yang dimiliki sistem tentang Pod. Di sini kamu akan melihat hal-hal seperti anotasi (yang merupakan metadata nilai kunci tanpa batasan label, yang digunakan secara internal oleh komponen sistem Kubernetes), kebijakan mulai ulang, porta, dan volume.
kubectl get pod nginx-deployment-1006230814-6winp -o yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/created-by: |
{"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicaSet","namespace":"default","name":"nginx-deployment-1006230814","uid":"4c84c175-f161-11e5-9a78-42010af00005","apiVersion":"extensions","resourceVersion":"133434"}}
creationTimestamp: 2016-03-24T01:39:50Z
generateName: nginx-deployment-1006230814-
labels:
app: nginx
pod-template-hash: "1006230814"
name: nginx-deployment-1006230814-6winp
namespace: default
resourceVersion: "133447"
uid: 4c879808-f161-11e5-9a78-42010af00005
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 500m
memory: 128Mi
terminationMessagePath: /dev/termination-log
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-4bcbi
readOnly: true
dnsPolicy: ClusterFirst
nodeName: kubernetes-node-wul5
restartPolicy: Always
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
volumes:
- name: default-token-4bcbi
secret:
secretName: default-token-4bcbi
status:
conditions:
- lastProbeTime: null
lastTransitionTime: 2016-03-24T01:39:51Z
status: "True"
type: Ready
containerStatuses:
- containerID: docker://90315cc9f513c724e9957a4788d3e625a078de84750f244a40f97ae355eb1149
image: nginx
imageID: docker://6f62f48c4e55d700cf3eb1b5e33fa051802986b77b874cc351cce539e5163707
lastState: {}
name: nginx
ready: true
restartCount: 0
state:
running:
startedAt: 2016-03-24T01:39:51Z
hostIP: 10.240.0.9
phase: Running
podIP: 10.244.0.6
startTime: 2016-03-24T01:39:49Z
Terkadang saat men-debug melihat status sebuah Node akan sangat berguna - misalnya, karena kamu telah melihat perilaku aneh dari sebuah Pod yang sedang berjalan pada Node tersebut, atau untuk mencari tahu mengapa sebuah Pod tidak dapat dijadwalkan ke dalam Node tersebut. Seperti pada Pod, kamu dapat menggunakan perintah kubectl description node dan kubectl get node -o yaml untuk mengambil informasi mendetil tentang Node. Misalnya, disini kamu akan melihat jika sebuah Node sedang mati (terputus dari jaringan, atau kubelet mati dan tidak mau restart, dll.). Perhatikan peristiwa yang menunjukkan Node tersebut NotReady, dan juga perhatikan bahwa Pod tidak lagi berjalan (mereka akan dikeluarkan setelah lima menit berstatus NotReady).
kubectl get nodes
NAME STATUS ROLES AGE VERSION
kubernetes-node-861h NotReady <none> 1h v1.13.0
kubernetes-node-bols Ready <none> 1h v1.13.0
kubernetes-node-st6x Ready <none> 1h v1.13.0
kubernetes-node-unaj Ready <none> 1h v1.13.0
kubectl describe node kubernetes-node-861h
Name: kubernetes-node-861h
Role
Labels: kubernetes.io/arch=amd64
kubernetes.io/os=linux
kubernetes.io/hostname=kubernetes-node-861h
Annotations: node.alpha.kubernetes.io/ttl=0
volumes.kubernetes.io/controller-managed-attach-detach=true
Taints: <none>
CreationTimestamp: Mon, 04 Sep 2017 17:13:23 +0800
Phase:
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
OutOfDisk Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status.
MemoryPressure Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status.
DiskPressure Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status.
Ready Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status.
Addresses: 10.240.115.55,104.197.0.26
Capacity:
cpu: 2
hugePages: 0
memory: 4046788Ki
pods: 110
Allocatable:
cpu: 1500m
hugePages: 0
memory: 1479263Ki
pods: 110
System Info:
Machine ID: 8e025a21a4254e11b028584d9d8b12c4
System UUID: 349075D1-D169-4F25-9F2A-E886850C47E3
Boot ID: 5cd18b37-c5bd-4658-94e0-e436d3f110e0
Kernel Version: 4.4.0-31-generic
OS Image: Debian GNU/Linux 8 (jessie)
Operating System: linux
Architecture: amd64
Container Runtime Version: docker://1.12.5
Kubelet Version: v1.6.9+a3d1dfa6f4335
Kube-Proxy Version: v1.6.9+a3d1dfa6f4335
ExternalID: 15233045891481496305
Non-terminated Pods: (9 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
......
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
CPU Requests CPU Limits Memory Requests Memory Limits
------------ ---------- --------------- -------------
900m (60%) 2200m (146%) 1009286400 (66%) 5681286400 (375%)
Events: <none>
kubectl get node kubernetes-node-861h -o yaml
apiVersion: v1
kind: Node
metadata:
creationTimestamp: 2015-07-10T21:32:29Z
labels:
kubernetes.io/hostname: kubernetes-node-861h
name: kubernetes-node-861h
resourceVersion: "757"
uid: 2a69374e-274b-11e5-a234-42010af0d969
spec:
externalID: "15233045891481496305"
podCIDR: 10.244.0.0/24
providerID: gce://striped-torus-760/us-central1-b/kubernetes-node-861h
status:
addresses:
- address: 10.240.115.55
type: InternalIP
- address: 104.197.0.26
type: ExternalIP
capacity:
cpu: "1"
memory: 3800808Ki
pods: "100"
conditions:
- lastHeartbeatTime: 2015-07-10T21:34:32Z
lastTransitionTime: 2015-07-10T21:35:15Z
reason: Kubelet stopped posting node status.
status: Unknown
type: Ready
nodeInfo:
bootID: 4e316776-b40d-4f78-a4ea-ab0d73390897
containerRuntimeVersion: docker://Unknown
kernelVersion: 3.16.0-0.bpo.4-amd64
kubeProxyVersion: v0.21.1-185-gffc5a86098dc01
kubeletVersion: v0.21.1-185-gffc5a86098dc01
machineID: ""
osImage: Debian GNU/Linux 7 (wheezy)
systemUUID: ABE5F6B4-D44B-108B-C46A-24CCE16C8B6E
Pelajari tentang alat debugging tambahan, termasuk:
execLaman ini menunjukkan bagaimana cara menggunakan kubectl exec untuk
mendapatkan shell untuk masuk ke dalam Container yang sedang berjalan.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Dalam latihan ini, kamu perlu membuat Pod yang hanya memiliki satu Container saja. Container tersebut menjalankan image nginx. Berikut ini adalah berkas konfigurasi untuk Pod tersebut:
apiVersion: v1
kind: Pod
metadata:
name: shell-demo
spec:
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: nginx
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
hostNetwork: true
dnsPolicy: Default
Buatlah Pod tersebut:
kubectl apply -f https://k8s.io/examples/application/shell-demo.yaml
Pastikan bahwa Container dalam Pod berjalan:
kubectl get pod shell-demo
Dapatkan shell untuk masuk ke dalam Container:
kubectl exec -it shell-demo -- /bin/bash
Di dalam shell kamu, perlihatkan isi dari direktori root:
root@shell-demo:/# ls /
Di dalam shell kamu, cobalah perintah-perintah yang lainnya. Berikut beberapa contohnya:
root@shell-demo:/# ls /
root@shell-demo:/# cat /proc/mounts
root@shell-demo:/# cat /proc/1/maps
root@shell-demo:/# apt-get update
root@shell-demo:/# apt-get install -y tcpdump
root@shell-demo:/# tcpdump
root@shell-demo:/# apt-get install -y lsof
root@shell-demo:/# lsof
root@shell-demo:/# apt-get install -y procps
root@shell-demo:/# ps aux
root@shell-demo:/# ps aux | grep nginx
Lihat kembali berkas konfigurasi untuk Pod kamu. Pod
memiliki volume emptyDir, dan Container melakukan pemasangan (mounting) untuk volume tersebut
pada /usr/share/nginx/html.
Pada shell kamu, buatlah berkas index.html dalam direktori /usr/share/nginx/html:
root@shell-demo:/# echo Hello shell demo > /usr/share/nginx/html/index.html
Pada shell kamu, kirimkan sebuah permintaan (request) GET ke server nginx.
root@shell-demo:/# apt-get update
root@shell-demo:/# apt-get install curl
root@shell-demo:/# curl localhost
Keluarannya akan menunjukkan teks yang kamu tulis pada berkas index.html.
Hello shell demo
Setelah kamu selesai dengan shell kamu, ketiklah exit.
Pada jendela (window) perintah biasa, bukan pada shell kamu di dalam Container, lihatlah daftar variabel lingkungan (environment variable) pada Container yang sedang berjalan:
kubectl exec shell-demo -- env
Cobalah dengan menjalankan perintah lainnya. Berikut beberapa contohnya:
kubectl exec shell-demo ps aux
kubectl exec shell-demo ls /
kubectl exec shell-demo cat /proc/1/mounts
Jika sebuah Pod memiliki lebih dari satu Container, gunakanlah --container atau -c untuk
menentukan Container yang dimaksud pada perintah kubectl exec. Sebagai contoh,
misalkan kamu memiliki Pod yang bernama my-pod, dan Pod tersebut memiliki dua Container
yang bernama main-app dan helper-app. Perintah berikut ini akan membuka sebuah
shell ke Container dengan nama main-app.
kubectl exec -it my-pod --container main-app -- /bin/bash
Untuk melukan penyekalaan aplikasi dan memberikan Service yang handal, kamu perlu memahami bagaimana aplikasi berperilaku ketika aplikasi tersebut digelar (deploy). Kamu bisa memeriksa kinerja aplikasi dalam klaster Kubernetes dengan memeriksa Container, Pod, Service, dan karakteristik klaster secara keseluruhan. Kubernetes memberikan detail informasi tentang penggunaan sumber daya dari aplikasi pada setiap level ini. Informasi ini memungkinkan kamu untuk mengevaluasi kinerja aplikasi kamu dan mengevaluasi di mana kemacetan dapat dihilangkan untuk meningkatkan kinerja secara keseluruhan.
Di Kubernetes, pemantauan aplikasi tidak bergantung pada satu solusi pemantauan saja. Pada klaster baru, kamu bisa menggunakan pipeline metrik sumber daya atau pipeline metrik penuh untuk mengumpulkan statistik pemantauan.
Pipeline metrik sumber daya menyediakan sekumpulan metrik terbatas yang terkait dengan
komponen-komponen klaster seperti controller HorizontalPodAutoscaler, begitu juga dengan utilitas kubectl top.
Metrik ini dikumpulkan oleh memori yang ringan, jangka pendek, dalam
metrics-server dan
diekspos ke API metrics.k8s.io.
Metrics-server menemukan semua Node dalam klaster dan
bertanya ke setiap
kubelet dari Node tentang penggunaan CPU dan
memori. Kubelet bertindak sebagai jembatan antara control plane Kubernetes dan
Node, mengelola Pod dan Container yang berjalan pada sebuah mesin. Kubelet
menerjemahkan setiap Pod ke Container yang menyusunnya dan mengambil masing-masing
statistik penggunaan untuk setiap Container dari runtime Container melalui
antarmuka runtime Container. Kubelet mengambil informasi ini dari cAdvisor yang terintegrasi
untuk pengintegrasian Docker yang lama. Hal ini yang kemudian memperlihatkan
statistik penggunaan sumber daya dari kumpulan Pod melalui API sumber daya metrics-server.
API ini disediakan pada /metrics/resource/v1beta1 pada kubelet yang terautentikasi dan
porta read-only.
Pipeline metrik penuh memberi kamu akses ke metrik yang lebih banyak. Kubernetes bisa
menanggapi metrik ini secara otomatis dengan mengubah skala atau mengadaptasi klaster
berdasarkan kondisi saat ini, dengan menggunakan mekanisme seperti HorizontalPodAutoscaler.
Pipeline pemantauan mengambil metrik dari kubelet dan
kemudian memgekspos ke Kubernetes melalui adaptor dengan mengimplementasikan salah satu dari API
custom.metrics.k8s.io atau API external.metrics.k8s.io.
Prometheus, sebuah proyek CNCF, yang dapat secara alami memonitor Kubernetes, Node, dan Prometheus itu sendiri. Proyek pipeline metrik penuh yang bukan merupakan bagian dari CNCF berada di luar ruang lingkup dari dokumentasi Kubernetes.
Kubernetes menyediakan API certificates.k8s.io yang memungkinkan kamu membuat sertifikat
TLS yang ditandatangani oleh Otoritas Sertifikat (CA) yang kamu kendalikan. CA dan sertifikat ini
bisa digunakan oleh workload untuk membangun kepercayaan.
API certificates.k8s.io menggunakan protokol yang mirip dengan konsep ACME.
certificates.k8s.io ditandatangani oleh CA
khusus. Ini memungkinkan untuk mengkonfigurasi klaster kamu agar menggunakan CA root klaster untuk tujuan ini,
namun jangan pernah mengandalkan ini. Jangan berasumsi bahwa sertifikat ini akan melakukan validasi
dengan CA root klasterKamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekan kubectl version.
Mempercayai CA khusus dari aplikasi yang berjalan sebagai Pod biasanya memerlukan
beberapa tambahan konfigurasi aplikasi. Kamu harus menambahkan bundel sertifikat CA
ke daftar sertifikat CA yang dipercaya klien atau server TLS.
Misalnya, kamu akan melakukan ini dengan konfigurasi TLS golang dengan mengurai rantai sertifikat
dan menambahkan sertifikat yang diurai ke RootCAs di struct
tls.Config.
Kamu bisa mendistribusikan sertifikat CA sebagai sebuah ConfigMap yang bisa diakses oleh Pod kamu.
Bagian berikut mendemonstrasikan cara membuat sertifikat TLS untuk sebuah Service kubernetes yang diakses melalui DNS.
Contoh ini menggunakan cfssl yang dapat diunduh pada https://github.com/cloudflare/cfssl/releases.
Buat kunci pribadi dan CertificateSigningRequest (CSR) dengan menggunakan perintah berikut:
cat <<EOF | cfssl genkey - | cfssljson -bare server
{
"hosts": [
"my-svc.my-namespace.svc.cluster.local",
"my-pod.my-namespace.pod.cluster.local",
"192.0.2.24",
"10.0.34.2"
],
"CN": "my-pod.my-namespace.pod.cluster.local",
"key": {
"algo": "ecdsa",
"size": 256
}
}
EOF
192.0.2.24 adalah klaster IP Service,
my-svc.my-namespace.svc.cluster.local adalah nama DNS Service,
10.0.34.2 adalah IP Pod dan my-pod.my-namespace.pod.cluster.local
adalah nama DNS Pod. Kamu akan melihat keluaran berikut:
2017/03/21 06:48:17 [INFO] generate received request
2017/03/21 06:48:17 [INFO] received CSR
2017/03/21 06:48:17 [INFO] generating key: ecdsa-256
2017/03/21 06:48:17 [INFO] encoded CSR
Perintah ini menghasilkan dua berkas; Ini menghasilkan server.csr yang berisi permintaan sertifikasi PEM
tersandi pkcs#10,
dan server-key.pem yang berisi PEM kunci yang tersandi untuk sertifikat yang
masih harus dibuat.
Buat sebuah yaml CSR dan kirim ke API Server dengan menggunakan perintah berikut:
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: my-svc.my-namespace
spec:
request: $(cat server.csr | base64 | tr -d '\n')
usages:
- digital signature
- key encipherment
- server auth
EOF
Perhatikan bahwa berkas server.csr yang dibuat pada langkah 1 merupakan base64 tersandi
dan disimpan di field .spec.request. Kami juga meminta
sertifikat dengan penggunaan kunci "digital signature", "key enchiperment", dan "server
auth". Kami mendukung semua penggunaan kunci dan penggunaan kunci yang diperpanjang yang terdaftar
di sini
sehingga kamu dapat meminta sertifikat klien dan sertifikat lain menggunakan
API yang sama.
CSR semestinya bisa dilihat dari API pada status Pending. Kamu bisa melihatnya dengan menjalankan:
kubectl describe csr my-svc.my-namespace
Name: my-svc.my-namespace
Labels: <none>
Annotations: <none>
CreationTimestamp: Tue, 21 Mar 2017 07:03:51 -0700
Requesting User: yourname@example.com
Status: Pending
Subject:
Common Name: my-svc.my-namespace.svc.cluster.local
Serial Number:
Subject Alternative Names:
DNS Names: my-svc.my-namespace.svc.cluster.local
IP Addresses: 192.0.2.24
10.0.34.2
Events: <none>
Penyetujuan CertificateSigningRequest dapat dilakukan dengan otomatis atau dilakukan sekali oleh administrator klaster. Informasi lebih lanjut tentang apa yang terjadi dibahas dibawah ini.
Setelah CSR ditandatangani dan disetujui, kamu akan melihat:
kubectl get csr
NAME AGE REQUESTOR CONDITION
my-svc.my-namespace 10m yourname@example.com Approved,Issued
Kamu bisa mengundur sertifikat yang telah diterbitkan dan menyimpannya ke berkas
server.crt dengan menggunakan perintah berikut:
kubectl get csr my-svc.my-namespace -o jsonpath='{.status.certificate}' \
| base64 --decode > server.crt
Sekarang kamu bisa menggunakan server.crt dan server-key.pem sebagai pasangan
kunci untuk memulai server HTTPS kamu.
Administrator Kubernetes (dengan izin yang cukup) dapat menyetujui secara manual
(atau menolak) Certificate Signing Requests dengan menggunakan perintah kubectl certificate approve dan kubectl certificate deny. Namun jika kamu bermaksud
untuk menggunakan API ini secara sering, kamu dapat mempertimbangkan untuk menulis
Certificate controller otomatis.
Baik itu mesin atau manusia yang menggunakan kubectl seperti di atas, peran pemberi persetujuan adalah untuk memverifikasi bahwa CSR memenuhi dua persyaratan:
Jika dan hanya jika kedua persyaratan ini dipenuhi, pemberi persetujuan harus menyetujui CSR dan sebaliknya harus menolak CSR.
Kemampuan untuk menyetujui CSR menentukan siapa yang mempercayai siapa di dalam lingkungan kamu. Kemampuan untuk menyetujui CSR tersebut seharusnya tidak diberikan secara luas. Persyaratan tantangan yang disebutkan di bagian sebelumnya dan dampak dari mengeluarkan sertifikat khusus, harus sepenuhnya dipahami sebelum memberikan izin ini.
Tutorial ini mengasumsikan bahwa penanda tangan diatur untuk melayani API sertifikat.
Kubernetes controller manager menyediakan implementasi bawaan dari penanda tangan. Untuk
mengaktifkan, berikan parameter --cluster-signed-cert-file dan
--cluster-signed-key-file ke controller manager dengan path ke
pasangan kunci CA kamu.
Laman ini memperlihatkan bagaimana caranya untuk melakukan rollback pada sebuah DaemonSet.
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Kubernetes servermu harus dalam versi yang sama atau lebih baru dari 1.7.Untuk melihat versi, tekan kubectl version.
Sebelum lanjut, alangkah baiknya jika kamu telah mengetahui cara untuk melakukan rolling update pada sebuah DaemonSet.
Lompati langkah ini jika kamu hanya ingin kembali (rollback) ke revisi terakhir.
Perintah di bawah ini akan memperlihatkan daftar semua revisi dari DaemonSet:
kubectl rollout history daemonset <nama-daemonset>
Perintah tersebut akan menampilkan daftar revisi seperti di bawah:
daemonsets "<nama-daemonset>"
REVISION CHANGE-CAUSE
1 ...
2 ...
...
kubernetes.io/change-cause yang berkaitan dengan revisi pada DaemonSet. Kamu boleh menyetel flag --record=true melalui kubectl untuk merekam perintah yang dijalankan akibat dari anotasi alasan perubahan.Untuk melihat detail dari revisi tertentu, jalankan perintah di bawah ini:
kubectl rollout history daemonset <daemonset-name> --revision=1
Perintah tersebut memberikan detail soal nomor revisi tertentu:
daemonsets "<nama-daemonset>" with revision #1
Pod Template:
Labels: foo=bar
Containers:
app:
Image: ...
Port: ...
Environment: ...
Mounts: ...
Volumes: ...
# Tentukan nomor revisi yang kamu dapatkan dari Langkah 1 melalui --to-revision
kubectl rollout undo daemonset <nama-daemonset> --to-revision=<nomor-revisi>
Jika telah berhasil, perintah tersebut akan memberikan keluaran berikut:
daemonset "<nama-daemonset>" rolled back
--to-revision tidak diberikan, maka kubectl akan memilihkan revisi yang terakhir.Perintah kubectl rollout undo daemonset memberitahu server untuk memulai rollback DaemonSet.
Rollback sebenarnya terjadi secara asynchronous di dalam klaster _control plane_.
Perintah di bawah ini dilakukan untuk melihat progres dari rollback:
kubectl rollout status ds/<nama-daemonset>
Ketika rollback telah selesai dilakukan, keluaran di bawah akan ditampilkan:
daemonset "<nama-daemonset>" successfully rolled out
Pada langkah kubectl rollout history sebelumnya, kamu telah mendapatkan
daftar revisi DaemonSet. Setiap revisi disimpan di dalam sumber daya bernama ControllerRevision.
Untuk melihat apa yang disimpan pada setiap revisi, dapatkan sumber daya mentah (raw) dari revisi DaemonSet:
kubectl get controllerrevision -l <kunci-selektor-daemonset>=<nilai-selektor-daemonset>
Perintah di atas akan mengembalikan daftar ControllerRevision:
NAME CONTROLLER REVISION AGE
<nama-daemonset>-<hash-revisi> DaemonSet/<nama-daemonset> 1 1h
<nama-daemonset>-<hash-revisi> DaemonSet/<nama-daemonset> 2 1h
Setiap ControllerRevision menyimpan anotasi dan templat dari sebuah revisi DaemonSet.
Perintah kubectl rollout undo mengambil ControllerRevision yang spesifik dan mengganti templat
DaemonSet dengan templat yang tersimpan pada ControllerRevision.
Perintah kubectl rollout undo sama seperti untuk memperbarui templat
DaemonSet ke revisi sebelumnya dengan menggunakan perintah lainnya, seperti kubectl edit atau kubectl apply.
.revision) yang sedang di-rollback akan maju ke depan.
Misalnya, jika kamu memiliki revisi 1 dan 2 pada sistem, lalu rollback dari revisi 2 ke revisi 1,
ControllerRevision dengan .revision: 1 akan menjadi .revision: 3.