Mengelola Resource

Kamu telah melakukan deploy pada aplikasimu dan mengeksposnya melalui sebuah service. Lalu? Kubernetes menyediakan berbagai peralatan untuk membantu mengatur mekanisme deploy aplikasi, termasuk pengaturan kapasitas dan pembaruan. Diantara fitur yang akan didiskusikan lebih mendalam yaitu berkas konfigurasi dan label.

Mengelola konfigurasi resource

Banyak aplikasi memerlukan beberapa resource, seperti Deployment dan Service. Pengelolaan beberapa resource dapat disederhanakan dengan mengelompokkannya dalam berkas yang sama (dengan pemisah --- pada YAML). Contohnya:

apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

Beberapa resource dapat dibuat seolah-olah satu resource:

kubectl apply -f https://k8s.io/examples/application/nginx-app.yaml
service/my-nginx-svc created
deployment.apps/my-nginx created

Resource akan dibuat dalam urutan seperti pada berkas. Oleh karena itu, lebih baik menyalakan service lebih dahulu agar menjamin scheduler dapat menyebar pod yang terkait service selagi pod dibangkitkan oleh controller, seperti Deployment.

kubectl apply juga dapat menerima beberapa argumen -f:

kubectl apply -f https://k8s.io/examples/application/nginx/nginx-svc.yaml -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml

Selain berkas, kita dapat juga memasukkan direktori sebagai argumen:

kubectl apply -f https://k8s.io/examples/application/nginx/

kubectl akan membaca berkas apapun yang berakhiran .yaml, .yml, or .json.

Sangat disarankan untuk meletakkan sumber daya yang ada dalam microservice atau tier aplikasi yang sama dalam satu berkas, dan mengelompokkan semua berkas terkait aplikasimu dalam satu direktori. Jika tier masing-masing aplikasi terikat dengan DNS, maka kamu dapat melakukan deploy semua komponen teknologi yang dibutuhkan bersama-sama.

Lokasi konfigurasi dapat juga diberikan dalam bentuk URL. Ini berguna ketika ingin menjalankan berkas konfigurasi dari Github:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx created

Operasi majemuk dalam kubectl

Pembuatan resource bukanlah satu-satunya operasi yang bisa dijalankan kubectl secara majemuk. Contoh lainnya adalah mengekstrak nama resource dari berkas konfigurasi untuk menjalankan operasi lainnya, seperti untuk menghapus resource yang telah dibuat:

kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted

Pada kasus dua resource, mudah untuk memasukkan keduanya pada command line menggunakan sintaks resource/nama:

kubectl delete deployments/my-nginx services/my-nginx-svc

Namun, untuk resource yang lebih banyak, memasukkan selektor (label query) menggunakan -l atau --selector untuk memfilter resource berdasarkan label akan lebih mudah:

kubectl delete deployment,services -l app=nginx
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted

Karena kubectl mengembalikan nama resource yang sama dengan sintaks yang diterima, mudah untuk melanjutkan operasi menggunakan $() atau xargs:

kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service)
NAME           TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)      AGE
my-nginx-svc   LoadBalancer   10.0.0.208   <pending>     80/TCP       0s

Dengan perintah di atas, pertama kita buat resource di dalam examples/application/nginx/. Lalu tampilkan resources yang terbentuk dengan format keluaran -o name (menampilkan tiap resource dalam format resource/nama). Kemudian lakukan grep hanya pada "service", dan tampilkan dengan kubectl get.

Untuk dapat menggunakan perintah di atas pada direktori yang bertingkat, kamu dapat memberi argumen --recursive atau -R bersama dengan argumen --filename,-f.

Misalnya ada sebuah direktori project/k8s/development memuat semua manifests yang berkaitan dengan development environment. Manifest akan tersusun berdasarkan tipe resource:

project/k8s/development
├── configmap
│   └── my-configmap.yaml
├── deployment
│   └── my-deployment.yaml
└── pvc
    └── my-pvc.yaml

Secara default, menjalankan operasi majemuk pada project/k8s/development hanya akan terbatas pada direktori terluar saja. Sehingga ketika kita menjalankan operasi pembuatan dengan perintah berikut, kita akan mendapatkan pesan kesalahan:

kubectl apply -f project/k8s/development
error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin)

Solusinya, tambahkan argumen --recursive atau -R bersama dengan --filename,-f, seperti:

kubectl apply -f project/k8s/development --recursive
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created

Argumen --recursive berjalan pada operasi apapun yang menerima argumen --filename,-f seperti: kubectl {create,get,delete,describe,rollout} etc.

Argumen --recursive juga berjalan saat beberapa argumen -f diberikan:

kubectl apply -f project/k8s/namespaces -f project/k8s/development --recursive
namespace/development created
namespace/staging created
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created

Jika kamu tertarik mempelajari lebih lanjut tentang kubectl, silahkan baca Ikhtisar kubectl.

Memakai label secara efektif

Contoh yang kita lihat sejauh ini hanya menggunakan paling banyak satu label pada resource. Ada banyak skenario ketika membutuhkan beberapa label untuk membedakan sebuah kelompok dari yang lainnya.

Sebagai contoh, aplikasi yang berbeda akan menggunakan label app yang berbeda, tapi pada aplikasi multitier, seperti pada contoh buku tamu, tiap tier perlu dibedakan. Misal untuk menandai tier frontend bisa menggunakan label:

     labels:
        app: guestbook
        tier: frontend

sementara itu Redis master dan slave memiliki label tier yang berbeda. Bisa juga menggunakan label tambahan role:

     labels:
        app: guestbook
        tier: backend
        role: master

dan

     labels:
        app: guestbook
        tier: backend
        role: slave

Label memungkinkan kita untuk memilah resource dengan pembeda berupa label:

kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
kubectl get pods -Lapp -Ltier -Lrole
NAME                           READY     STATUS    RESTARTS   AGE       APP         TIER       ROLE
guestbook-fe-4nlpb             1/1       Running   0          1m        guestbook   frontend   <none>
guestbook-fe-ght6d             1/1       Running   0          1m        guestbook   frontend   <none>
guestbook-fe-jpy62             1/1       Running   0          1m        guestbook   frontend   <none>
guestbook-redis-master-5pg3b   1/1       Running   0          1m        guestbook   backend    master
guestbook-redis-slave-2q2yf    1/1       Running   0          1m        guestbook   backend    slave
guestbook-redis-slave-qgazl    1/1       Running   0          1m        guestbook   backend    slave
my-nginx-divi2                 1/1       Running   0          29m       nginx       <none>     <none>
my-nginx-o0ef1                 1/1       Running   0          29m       nginx       <none>     <none>
kubectl get pods -lapp=guestbook,role=slave
NAME                          READY     STATUS    RESTARTS   AGE
guestbook-redis-slave-2q2yf   1/1       Running   0          3m
guestbook-redis-slave-qgazl   1/1       Running   0          3m

Deploy dengan Canary

Skenario lain yang menggunakan beberapa label yaitu saat membedakan deployment komponen yang sama namun dengan rilis atau konfigurasi yang berbeda. Adalah praktik yang umum untuk mendeploy sebuah canary dari rilis aplikasi yang baru (berdasarkan tag image dalam templat pod) bersamaan dengan rilis sebelumnya. Ini memungkinkan rilis yang baru dapat menerima live traffic sebelum benar-benar menggantikan rilis yang lama.

Salah satu alternatif yaitu kamu dapat memakai label track untuk membedakan antar rilis.

Rilis primer dan stabil akan memiliki label track yang berisi stable:

     name: frontend
     replicas: 3
     ...
     labels:
        app: guestbook
        tier: frontend
        track: stable
     ...
     image: gb-frontend:v3

kemudian kamu buat lagi rilis frontend buku tamu yang membawa label track yang berbeda (misal canary), sehingga pod dalam kedua rilis tidak beririsan:

     name: frontend-canary
     replicas: 1
     ...
     labels:
        app: guestbook
        tier: frontend
        track: canary
     ...
     image: gb-frontend:v4

Servis frontend akan meliputi kedua set replika dengan menentukan subset bersama dari para labelnya (tanpa track). Sehingga traffic akan diarahkan ke kedua aplikasi:

  selector:
     app: guestbook
     tier: frontend

Kamu dapat mengatur jumlah replika rilis stable dan canary untuk menentukan rasio dari tiap rilis yang akan menerima traffic production live (dalam kasus ini 3:1). Ketika telah yakin, kamu dapat memindahkan track stable ke rilis baru dan menghapus canary.

Untuk contoh yang lebih jelas, silahkan cek tutorial melakukan deploy Ghost.

Memperbarui label

Kadang, pod dan resource lain yang sudah ada harus dilabeli ulang sebelum membuat resource baru. Hal ini dapat dilakukan dengan perintah kubectl label. Contohnya jika kamu ingin melabeli ulang semua pod nginx sebagai frontend tier, tinggal jalankan:

kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled

Perintah ini melakukan filter pada semua pod dengan label "app=nginx", lalu melabelinya dengan "tier=fe". Untuk melihat pod yang telah dilabeli, jalankan:

kubectl get pods -l app=nginx -L tier
NAME                        READY     STATUS    RESTARTS   AGE       TIER
my-nginx-2035384211-j5fhi   1/1       Running   0          23m       fe
my-nginx-2035384211-u2c7e   1/1       Running   0          23m       fe
my-nginx-2035384211-u3t6x   1/1       Running   0          23m       fe

Akan muncul semua pod dengan "app=nginx" dan sebuah kolom label tambahan yaitu tier (ditentukan dengan -L atau --label-columns).

Untuk informasi lebih lanjut, silahkan baca label dan kubectl label.

Memperbarui anotasi

Kadang resource perlu ditambahkan anotasi. Anotasi adalah metadata sembarang yang tidak unik, seperti tools, libraries, dsb yang digunakan oleh klien API . Ini dapat dilakukan dengan kubectl annotate. Sebagai contoh:

kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx'
kubectl get pods my-nginx-v4-9gw19 -o yaml
apiVersion: v1
kind: pod
metadata:
  annotations:
    description: my frontend running nginx
...

Untuk informasi lebih lanjut, silahkan lihat laman annotations dan kubectl annotate.

Memperbesar dan memperkecil aplikasi kamu

Saat beban aplikasi naik maupun turun, mudah untuk mengubah kapasitas dengan kubectl. Contohnya, untuk menurunkan jumlah replika nginx dari 3 ke 1, lakukan:

kubectl scale deployment/my-nginx --replicas=1
deployment.apps/my-nginx scaled

Sekarang kamu hanya memiliki satu pod yang dikelola oleh deployment.

kubectl get pods -l app=nginx
NAME                        READY     STATUS    RESTARTS   AGE
my-nginx-2035384211-j5fhi   1/1       Running   0          30m

Agar sistem dapat menyesuaikan jumlah replika nginx yang dibutuhkan secara otomatis dari 1 hingga 3, lakukan:

kubectl autoscale deployment/my-nginx --min=1 --max=3
horizontalpodautoscaler.autoscaling/my-nginx autoscaled

Sekarang jumlah replika nginx akan secara otomatis naik dan turun sesuai kebutuhan.

Informasi tambahan dapat dilihat pada dokumen kubectl scale, kubectl autoscale dan horizontal pod autoscaler.

Pembaruan resource di tempat

Kadang kita perlu membuat pembaruan kecil, yang tidak mengganggu pada resource yang telah dibuat.

kubectl apply

Disarankan untuk menyimpan berkas-berkas konfigurasi dalam source control (lihat konfigurasi sebagai kode). Sehingga berkas dapat dipelihara dan diatur dalam versi bersama dengan kode milik resource yang diatur oleh konfigurasi tersebut. Berikutnya, kamu dapat menggunakan kubectl apply untuk membarui perubahan konfigurasi ke klaster.

Perintah ini akan membandingkan versi konfigurasi yang disuplai dengan versi sebelumnya yang telah berjalan dan memasang perubahan yang kamu buat tanpa mengganti properti yang tidak berubah sama sekali.

kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx configured

Perhatikan bahwa kubectl apply memasang anotasi pada resource untuk menentukan perubahan pada konfigurasi sejak terakhir dipanggil. Ketika dijalankan, kubectl apply melakukan pembandingan three-way antara konfigurasi sebelumnya, masukan yang disuplai, dan konfigurasi resource sekarang, untuk dapat menentukan cara memodifikasi resource.

Saat ini, resource dibuat tanpa ada anotasi. Jadi pemanggilan pertama pada kubectl apply akan dikembalikan pada perbandingan two-way antara masukan pengguna dan konfigurasi resource sekarang. Saat pemanggilan pertama ini, tidak ada penghapusan set properti yang terdeteksi saat resource dibuat. Sehingga, tidak ada yang dihapus.

Tiap kubectl apply, atau perintah lain yang memodifikasi konfigurasi seperti kubectl replace dan kubectl edit dijalankan, anotasi akan diperbarui. Sehingga memungkinkan operasi kubectl apply untuk mendeteksi dan melakukan penghapusan secara perbandingan three-way.

kubectl edit

Sebagai alternatif, kamu juga dapat membarui resource dengan kubectl edit:

kubectl edit deployment/my-nginx

Ini sama dengan melakukan get pada resource, mengubahnya di text editor, kemudian menjalankanapply pada resource dengan versi terkini:

kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml
vi /tmp/nginx.yaml
# lakukan pengubahan, lalu simpan berkas

kubectl apply -f /tmp/nginx.yaml
deployment.apps/my-nginx configured

rm /tmp/nginx.yaml

Cara demikian memungkinkan kamu membuat perubahan signifikan dengan mudah. Lihat bahwa kamu juga dapat menentukan editor dengan variabel environment EDITOR atau KUBE_EDITOR.

Untuk informasi tambahan, silahkan lihat laman kubectl edit.

kubectl patch

Kamu dapat menggunakan kubectl patch untuk membarui obyek API di tempat. Perintah ini mendukung patch JSON, patch gabungan JSON, dan strategic merge patch. Lihat Update API Objects in Place Using kubectl patch dan kubectl patch.

Pembaruan disruptif

Pada kasus tertentu, kamu mungkin perlu memperbarui field resource yang tidak dapat diperbarui setelah diinisiasi atau kamu ingin membuat perubahan rekursif segera, seperti memperbaiki pod yang rusak saat menjalankan Deployment. Untuk mengubah field seperti itu, gunakan replace --force yang akan menghapus dan membuat ulang resource. Dalam kasus ini kamu dapat mengubah berkas konfigurasi awalnya:

kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force
deployment.apps/my-nginx deleted
deployment.apps/my-nginx replaced

Membarui aplikasi tanpa memadamkan servis

Suatu saat, kamu akan perlu untuk membarui aplikasi yang telah terdeploy, biasanya dengan mengganti image atau tag sebagaimana dalam skenario canary deployment di atas. kubectl mendukung beberapa operasi pembaruan, masing-masing dapat digunakan pada skenario berbeda.

Kami akan memandumu untuk membuat dan membarui aplikasi melalui Deployment.

Misal kamu telah menjalankan nginx versi 1.7.9:

kubectl run my-nginx --image=nginx:1.7.9 --replicas=3
deployment.apps/my-nginx created

Untuk memperbarui versi ke 1.9.1, ganti .spec.template.spec.containers[0].image dari nginx:1.7.9 ke nginx:1.9.1, dengan perintah kubectl yang telah dipelajari di atas.

kubectl edit deployment/my-nginx

Selesai! Deployment akan memperbarui aplikasi nginx yang terdeploy secara berangsur di belakang. Dia akan menjamin hanya ada sekian replika lama yang akan down selagi pembaruan berjalan dan hanya ada sekian replika baru akan dibuat melebihi jumlah pod. Untuk mempelajari lebih lanjut, kunjungi laman Deployment.

Selanjutnya

Last modified January 19, 2023 at 11:26 AM PST: [id] fix deployment apiversion error (39fe286b2)