Jika Anda pernah berkecimpung di dunia container, Anda pasti tahu bahwa mengadopsi otomatisasi Kubernetes penuh untuk sistem database cluster cukup menantang, yang biasanya menambah tingkat kerumitan pada container-based arsitektur untuk aplikasi stateful ini. Di situlah Operator Kubernetes dapat membantu kami mengatasi masalah ini. Operator Kubernetes adalah jenis pengontrol khusus yang diperkenalkan untuk menyederhanakan penerapan kompleks yang pada dasarnya memperluas API Kubernetes dengan sumber daya khusus. Ini dibangun di atas konsep dasar sumber daya dan pengontrol Kubernetes tetapi mencakup pengetahuan khusus domain atau aplikasi untuk mengotomatiskan seluruh siklus hidup perangkat lunak yang dikelolanya.
Operator Cluster Percona XtraDB adalah cara yang rapi untuk mengotomatisasi tugas-tugas spesifik Cluster Percona XtraDB seperti penerapan, penskalaan, pencadangan, dan peningkatan dalam Kubernetes, yang dibuat dan dikelola oleh Percona. Ini menyebarkan cluster dalam StatefulSet dengan Volume Persisten, yang memungkinkan kami untuk mempertahankan identitas yang konsisten untuk setiap Pod dalam cluster dan data kami untuk dipertahankan.
Dalam posting blog ini, kita akan menguji penerapan Percona XtraDB Cluster 8.0 dalam lingkungan containerized, yang diatur oleh Operator Kubernetes Cluster Percona XtraDB di Google Cloud Platform.
Membuat Cluster Kubernetes di Google Cloud
Dalam panduan ini, kita akan menggunakan kluster Kubernetes di Google Cloud karena relatif sederhana dan mudah untuk mengaktifkan dan menjalankan Kubernetes. Masuk ke dasbor Google Cloud Platform -> Hitung -> Kubernetes Engine -> Buat Cluster, dan Anda akan disajikan dialog berikut:
Cukup masukkan nama Cluster Kubernetes, pilih zona pilihan Anda dan klik "BUAT " (di bagian bawah halaman). Dalam 5 menit, cluster Kubernetes 3-node akan siap. Sekarang, di workstation Anda, instal gcloud SDK seperti yang ditunjukkan dalam panduan ini, lalu tarik konfigurasi Kubernetes ke workstation Anda:
$ gcloud container clusters get-credentials my-k8s-cluster --zone asia-northeast1-a --project s9s-qa
Fetching cluster endpoint and auth data.
kubeconfig entry generated for my-k8s-cluster.
Anda seharusnya sudah bisa terhubung ke cluster Kubernetes saat ini. Jalankan perintah berikut untuk memverifikasi:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gke-my-k8s-cluster-default-pool-b80902cd-gp09 Ready <none> 139m v1.16.13-gke.401
gke-my-k8s-cluster-default-pool-b80902cd-jdc3 Ready <none> 139m v1.16.13-gke.401
gke-my-k8s-cluster-default-pool-b80902cd-rdv8 Ready <none> 139m v1.16.13-gke.401
Output di atas berarti kita dapat terhubung ke master Kubernetes dan mengambil node cluster Kubernetes. Sekarang, kita siap untuk menjalankan beban kerja Kubernetes.
Men-deploy Cluster Percona XtraDB di Kubernetes
Untuk penyebaran beban kerja, kami akan mengikuti instruksi seperti yang dinyatakan dalam dokumentasi Operator Cluster Percona XtraDB. Pada dasarnya, kami menjalankan perintah berikut di workstation kami untuk membuat sumber daya khusus, namespace, kontrol akses berbasis peran, dan juga operator Kubernetes itu sendiri:
$ git clone -b v1.6.0 https://github.com/percona/percona-xtradb-cluster-operator
$ cd percona-xtradb-cluster-operator/
$ kubectl apply -f deploy/crd.yaml
$ kubectl create namespace pxc
$ kubectl config set-context $(kubectl config current-context) --namespace=pxc
$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value core/account)
$ kubectl apply -f deploy/rbac.yaml
$ kubectl apply -f deploy/operator.yaml
Selanjutnya, kita harus menyiapkan kata sandi (disebut Rahasia dalam istilah Kubernetes) dengan memperbarui nilai di dalam deploy/secrets.yaml dalam format encode base64. Anda dapat menggunakan alat online seperti https://www.base64encode.org/ untuk membuatnya atau menggunakan alat baris perintah seperti berikut:
$ echo -n 'mypassword' | base64
bXlwYXNzd29yZA==
Kemudian, update deploy/secrets.yaml, seperti gambar di bawah ini:
apiVersion: v1
kind: Secret
metadata:
name: my-cluster-secrets
type: Opaque
data:
root: bXlwYXNzd29yZA==
xtrabackup: bXlwYXNzd29yZA==
monitor: bXlwYXNzd29yZA==
clustercheck: bXlwYXNzd29yZA==
proxyadmin: bXlwYXNzd29yZA==
pmmserver: bXlwYXNzd29yZA==
operator: bXlwYXNzd29yZA==
Di atas adalah penyederhanaan super manajemen rahasia, di mana kami mengatur semua kata sandi menjadi sama untuk semua pengguna. Dalam produksi, harap gunakan kata sandi yang lebih kompleks dan tentukan kata sandi yang berbeda untuk setiap pengguna.
Sekarang, kita dapat mendorong konfigurasi rahasia ke Kubernetes:
$ kubectl apply -f deploy/secrets.yaml
Sebelum kita bergerak maju untuk men-deploy Percona XtraDB Cluster, kita perlu meninjau kembali definisi deployment default di dalam deploy/cr.yaml untuk cluster. Ada banyak objek Kubernetes yang didefinisikan di sini, tetapi kebanyakan dari mereka dikomentari. Untuk beban kerja kami, kami akan melakukan modifikasi seperti di bawah ini:
$ cat deploy/cr.yaml
apiVersion: pxc.percona.com/v1-6-0
kind: PerconaXtraDBCluster
metadata:
name: cluster1
finalizers:
- delete-pxc-pods-in-order
spec:
crVersion: 1.6.0
secretsName: my-cluster-secrets
vaultSecretName: keyring-secret-vault
sslSecretName: my-cluster-ssl
sslInternalSecretName: my-cluster-ssl-internal
allowUnsafeConfigurations: false
updateStrategy: SmartUpdate
upgradeOptions:
versionServiceEndpoint: https://check.percona.com
apply: recommended
schedule: "0 4 * * *"
pxc:
size: 3
image: percona/percona-xtradb-cluster:8.0.20-11.1
configuration: |
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_unicode_ci
character-set-server = utf8
default_authentication_plugin = mysql_native_password
resources:
requests:
memory: 1G
affinity:
antiAffinityTopologyKey: "kubernetes.io/hostname"
podDisruptionBudget:
maxUnavailable: 1
volumeSpec:
persistentVolumeClaim:
resources:
requests:
storage: 6Gi
gracePeriod: 600
haproxy:
enabled: true
size: 3
image: percona/percona-xtradb-cluster-operator:1.6.0-haproxy
resources:
requests:
memory: 1G
affinity:
antiAffinityTopologyKey: "kubernetes.io/hostname"
podDisruptionBudget:
maxUnavailable: 1
gracePeriod: 30
backup:
image: percona/percona-xtradb-cluster-operator:1.6.0-pxc8.0-backup
storages:
fs-pvc:
type: filesystem
volume:
persistentVolumeClaim:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 6Gi
schedule:
- name: "daily-backup"
schedule: "0 0 * * *"
keep: 5
storageName: fs-pvc
Kami telah membuat beberapa modifikasi pada cr.yaml yang disediakan untuk membuatnya bekerja dengan aplikasi kami, seperti yang ditunjukkan di atas. Pertama-tama, kita harus mengomentari (atau menghapus) semua baris terkait CPU, misalnya [*].resources.requests.cpu:600m, untuk memastikan Kubernetes dapat menjadwalkan pembuatan pod dengan benar pada node dengan CPU terbatas. Kemudian kita perlu menambahkan beberapa opsi kompatibilitas untuk Percona XtraDB Cluster 8.0 yang berbasis MySQL 8.0, untuk bekerja dengan lancar dengan aplikasi WordPress kita yang akan kita gunakan nanti, seperti yang ditunjukkan dalam kutipan berikut:
Konfigurasi configuration: |
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_unicode_ci
character-set-server = utf8
default_authentication_plugin = mysql_native_password
Di atas akan cocok dengan set karakter default server MySQL dengan driver MySQLi PHP di wadah WordPress kami. Bagian selanjutnya adalah penerapan HAProxy yang disetel ke "enabled:true". Ada juga bagian ProxySQL dengan "enabled:false" - biasanya orang akan memilih salah satu dari proxy terbalik untuk setiap cluster. Bagian terakhir adalah konfigurasi pencadangan, di mana kami ingin membuat pencadangan harian yang dijadwalkan pada pukul 12:00 setiap hari dan menyimpan 5 pencadangan terakhir itu.
Kami sekarang dapat mulai menerapkan Cluster Percona XtraDB 3-node kami:
$ kubectl apply -f deploy/cr.yaml
Proses pembuatannya akan memakan waktu. Operator akan men-deploy pod Percona XtraDB Cluster sebagai Stateful Set, yang berarti satu pembuatan pod pada satu waktu dan setiap Pod di StatefulSet akan diberikan ordinal integer, dari 0 hingga N-1, yang unik di atas set. Proses selesai ketika operator dan Pod telah mencapai status Running:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
cluster1-haproxy-0 2/2 Running 0 71m
cluster1-haproxy-1 2/2 Running 0 70m
cluster1-haproxy-2 2/2 Running 0 70m
cluster1-pxc-0 1/1 Running 0 71m
cluster1-pxc-1 1/1 Running 0 70m
cluster1-pxc-2 1/1 Running 0 69m
percona-xtradb-cluster-operator-79d786dcfb-6clld 1/1 Running 0 121m
Karena operator ini adalah sumber daya khusus, kita dapat memanipulasi sumber daya perconaxtradbcluster seperti sumber daya Kubernetes standar:
$ kubectl get perconaxtradbcluster
NAME ENDPOINT STATUS PXC PROXYSQL HAPROXY AGE
cluster1 cluster1-haproxy.pxc ready 3 3 27h
Anda juga dapat menggunakan nama sumber daya yang lebih pendek, "pxc", dan coba dengan perintah berikut:
$ kubectl describe pxc
$ kubectl edit pxc
Saat melihat kumpulan beban kerja, kita dapat mengetahui bahwa operator telah membuat dua StatefulSets:
$ kubectl get statefulsets -o wide
NAME READY AGE CONTAINERS IMAGES
cluster1-haproxy 3/3 26h haproxy,pxc-monit percona/percona-xtradb-cluster-operator:1.6.0-haproxy,percona/percona-xtradb-cluster-operator:1.6.0-haproxy
cluster1-pxc 3/3 26h pxc percona/percona-xtradb-cluster:8.0.20-11.2
Operator juga akan membuat layanan terkait yang akan memuat koneksi seimbang ke masing-masing pod:
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster1-haproxy ClusterIP 10.40.9.177 <none> 3306/TCP,3309/TCP,33062/TCP 3h27m
cluster1-haproxy-replicas ClusterIP 10.40.0.236 <none> 3306/TCP 3h27m
cluster1-pxc ClusterIP None <none> 3306/TCP,33062/TCP 3h27m
cluster1-pxc-unready ClusterIP None <none> 3306/TCP,33062/TCP 3h27m
Output di atas menunjukkan bahwa operator telah membuat 4 layanan:
- cluster1-haproxy - Layanan untuk master tunggal MySQL (3306), protokol Proksi (3309) dan Admin MySQL (33062) yang seimbang beban - Port administratif baru yang diperkenalkan di MySQL 8.0.14 dan yang lebih baru. Ini adalah nama layanan atau alamat IP cluster yang perlu disambungkan oleh aplikasi untuk memiliki koneksi master tunggal ke cluster Galera.
- cluster1-haproxy-replicas - Layanan untuk multi-master MySQL dengan beban seimbang (3306). Ini adalah nama layanan atau alamat IP cluster yang perlu disambungkan oleh aplikasi agar memiliki koneksi multi-master ke cluster Galera dengan algoritme penyeimbangan round-robin.
- cluster1-pxc - Layanan untuk pod PXC dengan beban seimbang, melewati HAProxy. Dengan menghubungkan langsung ke layanan ini, Kubernetes akan merutekan koneksi secara round-robin ke semua pod PXC, mirip dengan yang disediakan cluster-haproxy-replicase. Layanan tidak memiliki alamat IP publik yang ditetapkan dan tidak tersedia di luar cluster.
- cluster1-pxc-unready - Layanan 'belum siap' diperlukan untuk penemuan alamat Pod selama startup aplikasi terlepas dari status Pod. Pod Proxysql dan pxc harus saling mengetahui sebelum database beroperasi penuh. Layanan yang belum siap tidak memiliki alamat IP publik yang ditetapkan dan tidak tersedia di luar cluster.
Untuk terhubung melalui klien MySQL, cukup jalankan perintah berikut:
$ kubectl run -i --rm --tty percona-client --image=percona:8.0 --restart=Never -- bash -il
Ini akan membuat Pod sementara dan segera memasuki lingkungan container. Kemudian, jalankan perintah klien mysql standar dengan kredensial yang tepat:
bash-4.2$ mysql -uroot -pmypassword -h cluster1-haproxy -P3306 -e 'SELECT @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------+
| @@hostname |
+----------------+
| cluster1-pxc-0 |
+----------------+
Saat kita melihat penempatan Pod, semua Pod Cluster Percona XtraDB berada di host Kubernetes yang berbeda:
$ kubectl get pods -o wide --selector=app.kubernetes.io/component=pxc
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
cluster1-pxc-0 1/1 Running 0 67m 10.36.2.5 gke-my-k8s-cluster-default-pool-b80902cd-gp09 <none> <none>
cluster1-pxc-1 1/1 Running 0 66m 10.36.1.10 gke-my-k8s-cluster-default-pool-b80902cd-rdv8 <none> <none>
cluster1-pxc-2 1/1 Running 0 65m 10.36.0.11 gke-my-k8s-cluster-default-pool-b80902cd-jdc3 <none> <none>
Ini pasti akan meningkatkan ketersediaan layanan, jika salah satu host Kubernetes mati.
Untuk menskalakan hingga 5 pod, kita perlu menyiapkan 2 node Kubernetes baru sebelumnya untuk mengikuti konfigurasi afinitas pod (default ke affinity.antiAffinityTopologyKey.topologyKey="kubernetes.io/hostname"). Kemudian, jalankan perintah patch berikut untuk menskalakan Percona XtraDB Cluster menjadi 5 node:
$ kubectl patch pxc cluster1 \
--type='json' -p='[{"op": "replace", "path": "/spec/pxc/size", "value": 5 }]'
Pantau pembuatan pod dengan menggunakan perintah kubectl get pods:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
cluster1-pxc-0 1/1 Running 0 27h 10.36.2.5 gke-my-k8s-cluster-default-pool-b80902cd-gp09 <none> <none>
cluster1-pxc-1 1/1 Running 0 27h 10.36.1.10 gke-my-k8s-cluster-default-pool-b80902cd-rdv8 <none> <none>
cluster1-pxc-2 1/1 Running 0 27h 10.36.0.11 gke-my-k8s-cluster-default-pool-b80902cd-jdc3 <none> <none>
cluster1-pxc-3 1/1 Running 0 30m 10.36.7.2 gke-my-k8s-cluster-pool-1-ab14a45e-h1pf <none> <none>
cluster1-pxc-4 1/1 Running 0 13m 10.36.5.3 gke-my-k8s-cluster-pool-1-ab14a45e-01qn <none> <none>
2 Pod baru lainnya (cluster1-pxc-3 dan cluster1-pxc-4) telah dibuat pada 2 node Kubernetes baru lainnya (gke-my-k8s-cluster-pool-1-ab14a45e-h1pf dan gke-my-k8s-cluster-pool-1-ab14a45e-01qn). Untuk memperkecil, cukup ubah nilainya kembali ke 3 pada perintah patch di atas. Perhatikan bahwa Percona XtraDB Cluster harus dijalankan dengan jumlah node ganjil untuk mencegah split-brain.
Menyebarkan Aplikasi (WordPress)
Dalam contoh ini, kami akan menerapkan aplikasi WordPress di atas Percona XtraDB Cluster dan HAProxy kami. Mari kita siapkan dulu file definisi YAML seperti berikut ini:
$ cat wordpress-deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: cluster1-haproxy
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-cluster-secrets
key: root
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim
Perhatikan variabel lingkungan WORDPRESS_DB_HOST dan WORDPRESS_DB_PASSWORD. Variabel sebelumnya di mana kami mendefinisikan "cluster1-haproxy" sebagai host basis data, alih-alih node basis data individual dan untuk yang terakhir kami menentukan kata sandi root dengan menginstruksikan Kubernetes untuk membacanya dari objek my-cluster-secrets di bawah kunci "root", yang setara dengan "mypassword" (setelah nilai base64 diterjemahkan). Kami melewatkan mendefinisikan variabel lingkungan WORDPRESS_DB_USER karena nilai defaultnya adalah "root".
Sekarang kita dapat membuat aplikasi kita:
$ kubectl apply -f wordpress-deployment.yaml
Periksa layanan:
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster1-haproxy ClusterIP 10.40.9.177 <none> 3306/TCP,3309/TCP,33062/TCP 4h42m
cluster1-haproxy-replicas ClusterIP 10.40.0.236 <none> 3306/TCP 4h42m
cluster1-pxc ClusterIP None <none> 3306/TCP,33062/TCP 4h42m
cluster1-pxc-unready ClusterIP None <none> 3306/TCP,33062/TCP 4h42m
wordpress LoadBalancer 10.40.13.205 35.200.78.195 80:32087/TCP 4h39m
Pada titik ini, kita dapat terhubung ke aplikasi WordPress kita di http://35.200.78.195/ (alamat IP eksternal) dan mulai mengonfigurasi aplikasi WordPress. Pada titik ini, aplikasi WordPress kami terhubung ke salah satu Percona XtraDB Cluster (koneksi master tunggal) melalui salah satu pod HAProxy.
Itu saja untuk saat ini. Untuk informasi lebih lanjut, lihat Operator Percona Kubernetes untuk dokumentasi Percona XtraDB Cluster. Selamat berkemas!