Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Menjalankan Galera Cluster di Kubernetes

Dalam beberapa blog terakhir, kami membahas cara menjalankan Galera Cluster di Docker, baik di Docker mandiri atau di multi-host Docker Swarm dengan jaringan overlay. Dalam posting blog ini, kita akan melihat cara menjalankan Galera Cluster di Kubernetes, alat orkestrasi untuk menjalankan container dalam skala besar. Beberapa bagian berbeda, seperti bagaimana aplikasi harus terhubung ke cluster, bagaimana Kubernetes menangani failover dan bagaimana load balancing bekerja di Kubernetes.

Kubernetes vs Docker Swarm

Target utama kami adalah memastikan Galera Cluster berjalan dengan andal di lingkungan container. Kami sebelumnya membahas Docker Swarm, dan ternyata menjalankan Galera Cluster di dalamnya memiliki sejumlah pemblokir, yang mencegahnya untuk siap produksi. Perjalanan kami sekarang berlanjut dengan Kubernetes, alat orkestrasi container tingkat produksi. Mari kita lihat tingkat "kesiapan produksi" mana yang dapat didukungnya saat menjalankan layanan stateful seperti Galera Cluster.

Sebelum kita melangkah lebih jauh, mari kita soroti beberapa perbedaan utama antara Kubernetes (1.6) dan Docker Swarm (17.03) saat menjalankan Galera Cluster pada container:

  • Kubernetes mendukung dua pemeriksaan kesehatan - keaktifan dan kesiapan. Hal ini penting ketika menjalankan Galera Cluster pada container, karena container Galera yang hidup tidak berarti siap untuk disajikan dan harus disertakan dalam set load balancing (pikirkan status joiner/donor). Docker Swarm hanya mendukung satu pemeriksaan pemeriksaan kesehatan yang mirip dengan keaktifan Kubernetes, sebuah wadah sehat dan terus berjalan atau tidak sehat dan dijadwalkan ulang. Baca di sini untuk detailnya.
  • Kubernetes memiliki dasbor UI yang dapat diakses melalui “kubectl proxy”.
  • Docker Swarm hanya mendukung load balancing round-robin (ingress), sedangkan Kubernetes menggunakan koneksi paling sedikit.
  • Docker Swarm mendukung mesh perutean untuk memublikasikan layanan ke jaringan eksternal, sementara Kubernetes mendukung sesuatu yang serupa yang disebut NodePort, serta penyeimbang beban eksternal (GCE GLB/AWS ELB) dan nama DNS eksternal (seperti untuk v1.7)

Menginstal Kubernetes Menggunakan Kubeadm

Kita akan menggunakan kubeadm untuk menginstal sebuah cluster Kubernetes 3-node pada CentOS 7. Ini terdiri dari 1 master dan 2 node (minion). Arsitektur fisik kami terlihat seperti ini:

1. Instal kubelet dan Docker di semua node:

$ ARCH=x86_64
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-${ARCH}
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
        https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
$ setenforce 0
$ yum install -y docker kubelet kubeadm kubectl kubernetes-cni
$ systemctl enable docker && systemctl start docker
$ systemctl enable kubelet && systemctl start kubelet

2. Pada master, inisialisasi master, salin file konfigurasi, atur jaringan Pod menggunakan Weave dan instal Dasbor Kubernetes:

$ kubeadm init
$ cp /etc/kubernetes/admin.conf $HOME/
$ export KUBECONFIG=$HOME/admin.conf
$ kubectl apply -f https://git.io/weave-kube-1.6
$ kubectl create -f https://git.io/kube-dashboard

3. Kemudian pada node lain yang tersisa:

$ kubeadm join --token 091d2a.e4862a6224454fd6 192.168.55.140:6443

4. Pastikan node sudah siap:

$ kubectl get nodes
NAME          STATUS    AGE       VERSION
kube1.local   Ready     1h        v1.6.3
kube2.local   Ready     1h        v1.6.3
kube3.local   Ready     1h        v1.6.3

Kami sekarang memiliki cluster Kubernetes untuk penerapan Galera Cluster.

Cluster Galera di Kubernetes

Dalam contoh ini, kita akan men-deploy MariaDB Galera Cluster 10.1 menggunakan image Docker yang diambil dari repositori DockerHub kita. File definisi YAML yang digunakan dalam penerapan ini dapat ditemukan di direktori example-kubernetes di repositori Github.

Kubernetes mendukung sejumlah pengontrol penerapan. Untuk menyebarkan Cluster Galera, seseorang dapat menggunakan:

  • Set Replika
  • StatefulSet

Masing-masing dari mereka memiliki pro dan kontra sendiri. Kita akan melihat masing-masing dari mereka dan melihat apa perbedaannya.

Prasyarat

Gambar yang kami buat memerlukan etcd (standalone atau cluster) untuk penemuan layanan. Untuk menjalankan cluster etcd, setiap instance etcd harus dijalankan dengan perintah yang berbeda, jadi kita akan menggunakan pengontrol Pods alih-alih Deployment dan membuat layanan yang disebut "etcd-client" sebagai titik akhir untuk Pod etcd. File definisi etcd-cluster.yaml menjelaskan semuanya.

Untuk men-deploy cluster 3-pod etcd, cukup jalankan:

$ kubectl create -f etcd-cluster.yaml

Verifikasi apakah cluster etcd sudah siap:

$ kubectl get po,svc
NAME                        READY     STATUS    RESTARTS   AGE
po/etcd0                    1/1       Running   0          1d
po/etcd1                    1/1       Running   0          1d
po/etcd2                    1/1       Running   0          1d
 
NAME              CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
svc/etcd-client   10.104.244.200   <none>        2379/TCP            1d
svc/etcd0         10.100.24.171    <none>        2379/TCP,2380/TCP   1d
svc/etcd1         10.108.207.7     <none>        2379/TCP,2380/TCP   1d
svc/etcd2         10.101.9.115     <none>        2379/TCP,2380/TCP   1d

Arsitektur kami sekarang terlihat seperti ini:

Beberapa MySQL di Docker:Cara Menampung Basis Data AndaTemukan semua yang perlu Anda pahami saat mempertimbangkan untuk menjalankan layanan MySQL di atas virtualisasi wadah DockerUnduh White Paper

Menggunakan ReplicaSet

Sebuah ReplicaSet memastikan bahwa sejumlah pod "replika" tertentu berjalan pada waktu tertentu. Namun, Deployment adalah konsep tingkat tinggi yang mengelola ReplicaSet dan menyediakan pembaruan deklaratif untuk pod bersama dengan banyak fitur berguna lainnya. Oleh karena itu, disarankan untuk menggunakan Deployment daripada langsung menggunakan ReplicaSets, kecuali jika Anda memerlukan orkestrasi pembaruan khusus atau tidak memerlukan pembaruan sama sekali. Saat Anda menggunakan Deployments, Anda tidak perlu khawatir tentang mengelola ReplicaSet yang mereka buat. Deployments memiliki dan mengelola ReplicaSet mereka.

Dalam kasus kami, kami akan menggunakan Deployment sebagai pengontrol beban kerja, seperti yang ditunjukkan dalam definisi YAML ini. Kita bisa langsung membuat ReplicaSet dan Service Galera Cluster dengan menjalankan perintah berikut:

$ kubectl create -f mariadb-rs.yml

Verifikasi apakah cluster sudah siap dengan melihat ReplicaSet (rs), pod (po) dan services (svc):

$ kubectl get rs,po,svc
NAME                  DESIRED   CURRENT   READY     AGE
rs/galera-251551564   3         3         3         5h
 
NAME                        READY     STATUS    RESTARTS   AGE
po/etcd0                    1/1       Running   0          1d
po/etcd1                    1/1       Running   0          1d
po/etcd2                    1/1       Running   0          1d
po/galera-251551564-8c238   1/1       Running   0          5h
po/galera-251551564-swjjl   1/1       Running   1          5h
po/galera-251551564-z4sgx   1/1       Running   1          5h
 
NAME              CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
svc/etcd-client   10.104.244.200   <none>        2379/TCP            1d
svc/etcd0         10.100.24.171    <none>        2379/TCP,2380/TCP   1d
svc/etcd1         10.108.207.7     <none>        2379/TCP,2380/TCP   1d
svc/etcd2         10.101.9.115     <none>        2379/TCP,2380/TCP   1d
svc/galera-rs     10.107.89.109    <nodes>       3306:30000/TCP      5h
svc/kubernetes    10.96.0.1        <none>        443/TCP             1d

Dari output di atas, kita dapat menggambarkan Pod dan Service kita sebagai berikut:

Menjalankan Galera Cluster di ReplicaSet mirip dengan memperlakukannya sebagai aplikasi stateless. Ini mengatur pembuatan, penghapusan, dan pembaruan pod dan dapat ditargetkan untuk Horizontal Pod Autoscales (HPA), yaitu ReplicaSet dapat diskalakan secara otomatis jika memenuhi ambang atau target tertentu (penggunaan CPU, paket per detik, permintaan per detik dll).

Jika salah satu node Kubernetes down, Pod baru akan dijadwalkan pada node yang tersedia untuk memenuhi replika yang diinginkan. Volume yang terkait dengan Pod akan dihapus, jika Pod dihapus atau dijadwalkan ulang. Nama host Pod akan dibuat secara acak, sehingga lebih sulit untuk melacak di mana wadah itu berada hanya dengan melihat nama hostnya.

Semua ini bekerja dengan cukup baik di lingkungan pengujian dan staging, di mana Anda dapat melakukan siklus hidup container penuh seperti penerapan, penskalaan, pembaruan, dan penghancuran tanpa ketergantungan apa pun. Penskalaan naik dan turun sangat mudah, dengan memperbarui file YAML dan mempostingnya ke cluster Kubernetes atau dengan menggunakan perintah skala:

$ kubectl scale replicaset galera-rs --replicas=5

Menggunakan StatefulSet

Dikenal sebagai PetSet pada versi pra 1.6, StatefulSet adalah cara terbaik untuk menyebarkan Galera Cluster dalam produksi, karena:

  • Menghapus dan/atau memperkecil StatefulSet tidak akan menghapus volume yang terkait dengan StatefulSet. Hal ini dilakukan untuk memastikan keamanan data, yang umumnya lebih berharga daripada pembersihan otomatis semua resource StatefulSet terkait.
  • Untuk StatefulSet dengan N replika, ketika Pod di-deploy, Pod akan dibuat secara berurutan, dari {0 .. N-1 }.
  • Saat Pod dihapus, Pod akan dihentikan dalam urutan terbalik, dari {N-1 .. 0}.
  • Sebelum operasi penskalaan diterapkan ke Pod, semua pendahulunya harus Berjalan dan Siap.
  • Sebelum sebuah Pod dihentikan, semua penerusnya harus dimatikan sepenuhnya.

StatefulSet menyediakan dukungan kelas satu untuk container stateful. Ini memberikan jaminan penyebaran dan penskalaan. Ketika Cluster Galera dengan tiga node dibuat, tiga Pod akan di-deploy dengan urutan db-0, db-1, db-2. db-1 tidak akan di-deploy sebelum db-0 "Berjalan dan Siap", dan db-2 tidak akan di-deploy hingga db-1 "Berjalan dan Siap". Jika db-0 gagal, setelah db-1 "Berjalan dan Siap", tetapi sebelum db-2 diluncurkan, db-2 tidak akan diluncurkan hingga db-0 berhasil diluncurkan kembali dan menjadi "Berjalan dan Siap".

Kita akan menggunakan implementasi Kubernetes dari penyimpanan persisten yang disebut PersistentVolume dan PersistentVolumeClaim. Ini untuk memastikan persistensi data jika pod dijadwal ulang ke node lain. Meskipun Galera Cluster menyediakan salinan data yang tepat pada setiap replika, memiliki data yang persisten di setiap pod bagus untuk tujuan pemecahan masalah dan pemulihan.

Untuk membuat penyimpanan persisten, pertama-tama kita harus membuat PersistentVolume untuk setiap pod. PV adalah plugin volume seperti Volume di Docker, tetapi memiliki siklus hidup yang independen dari setiap pod individu yang menggunakan PV. Karena kita akan men-deploy Cluster Galera 3-node, kita perlu membuat 3 PV:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: datadir-galera-0
  labels:
    app: galera-ss
    podindex: "0"
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Gi
  hostPath:
    path: /data/pods/galera-0/datadir
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: datadir-galera-1
  labels:
    app: galera-ss
    podindex: "1"
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Gi
  hostPath:
    path: /data/pods/galera-1/datadir
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: datadir-galera-2
  labels:
    app: galera-ss
    podindex: "2"
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Gi
  hostPath:
    path: /data/pods/galera-2/datadir

Definisi di atas menunjukkan bahwa kita akan membuat 3 PV, yang dipetakan ke jalur fisik node Kubernetes dengan ruang penyimpanan 10GB. Kami mendefinisikan ReadWriteOnce, yang berarti volume dapat dipasang sebagai baca-tulis hanya dengan satu node. Simpan baris di atas ke mariadb-pv.yml dan kirimkan ke Kubernetes:

$ kubectl create -f mariadb-pv.yml
persistentvolume "datadir-galera-0" created
persistentvolume "datadir-galera-1" created
persistentvolume "datadir-galera-2" created

Selanjutnya, tentukan sumber daya PersistentVolumeClaim:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mysql-datadir-galera-ss-0
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  selector:
    matchLabels:
      app: galera-ss
      podindex: "0"
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mysql-datadir-galera-ss-1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  selector:
    matchLabels:
      app: galera-ss
      podindex: "1"
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mysql-datadir-galera-ss-2
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  selector:
    matchLabels:
      app: galera-ss
      podindex: "2"

Definisi di atas menunjukkan bahwa kami ingin mengklaim sumber daya PV dan menggunakan spec.selector.matchLabels untuk mencari PV kami (metadata.labels.app:galera-ss ) berdasarkan indeks pod masing-masing (metadata.labels.podindex ) ditugaskan oleh Kubernetes. metadata.name resource harus menggunakan format “{volumeMounts.name}-{pod}-{ordinal index}” yang ditentukan di bawah spec.templates.containers jadi Kubernetes tahu titik mount mana yang akan memetakan klaim ke dalam pod.

Simpan baris di atas ke mariadb-pvc.yml dan kirimkan ke Kubernetes:

$ kubectl create -f mariadb-pvc.yml
persistentvolumeclaim "mysql-datadir-galera-ss-0" created
persistentvolumeclaim "mysql-datadir-galera-ss-1" created
persistentvolumeclaim "mysql-datadir-galera-ss-2" created

Penyimpanan persisten kami sekarang sudah siap. Kemudian kita dapat memulai penerapan Galera Cluster dengan membuat sumber daya StatefulSet bersama dengan sumber daya layanan Headless seperti yang ditunjukkan di mariadb-ss.yml:

$ kubectl create -f mariadb-ss.yml
service "galera-ss" created
statefulset "galera-ss" created

Sekarang, ambil ringkasan penerapan StatefulSet kami:

$ kubectl get statefulsets,po,pv,pvc -o wide
NAME                     DESIRED   CURRENT   AGE
statefulsets/galera-ss   3         3         1d        galera    severalnines/mariadb:10.1   app=galera-ss
 
NAME                        READY     STATUS    RESTARTS   AGE       IP          NODE
po/etcd0                    1/1       Running   0          7d        10.36.0.1   kube3.local
po/etcd1                    1/1       Running   0          7d        10.44.0.2   kube2.local
po/etcd2                    1/1       Running   0          7d        10.36.0.2   kube3.local
po/galera-ss-0              1/1       Running   0          1d        10.44.0.4   kube2.local
po/galera-ss-1              1/1       Running   1          1d        10.36.0.5   kube3.local
po/galera-ss-2              1/1       Running   0          1d        10.44.0.5   kube2.local
 
NAME                  CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS    CLAIM                               STORAGECLASS   REASON    AGE
pv/datadir-galera-0   10Gi       RWO           Retain          Bound     default/mysql-datadir-galera-ss-0                            4d
pv/datadir-galera-1   10Gi       RWO           Retain          Bound     default/mysql-datadir-galera-ss-1                            4d
pv/datadir-galera-2   10Gi       RWO           Retain          Bound     default/mysql-datadir-galera-ss-2                            4d
 
NAME                            STATUS    VOLUME             CAPACITY   ACCESSMODES   STORAGECLASS   AGE
pvc/mysql-datadir-galera-ss-0   Bound     datadir-galera-0   10Gi       RWO                          4d
pvc/mysql-datadir-galera-ss-1   Bound     datadir-galera-1   10Gi       RWO                          4d
pvc/mysql-datadir-galera-ss-2   Bound     datadir-galera-2   10Gi       RWO                          4d

Pada titik ini, Galera Cluster kami yang berjalan di StatefulSet dapat diilustrasikan seperti pada diagram berikut:

Berjalan di StatefulSet menjamin pengidentifikasi yang konsisten seperti nama host, alamat IP, ID jaringan, domain cluster, DNS Pod, dan penyimpanan. Hal ini memungkinkan Pod untuk dengan mudah membedakan dirinya dari yang lain dalam kelompok Pod. Volume akan disimpan di host dan tidak akan dihapus jika Pod dihapus atau dijadwal ulang ke node lain. Hal ini memungkinkan pemulihan data dan mengurangi risiko kehilangan data total.

Sisi negatifnya, waktu penerapan adalah N-1 kali (N =replika) lebih lama karena Kubernetes akan mematuhi urutan ordinal saat menerapkan, menjadwal ulang, atau menghapus sumber daya. Akan sedikit merepotkan untuk menyiapkan PV dan klaim sebelum berpikir untuk menskalakan klaster Anda. Perhatikan bahwa memperbarui StatefulSet yang ada saat ini merupakan proses manual, di mana Anda hanya dapat memperbarui spec.replicas saat ini.

Menghubungkan ke Layanan dan Pod Galera Cluster

Ada beberapa cara Anda dapat terhubung ke cluster database. Anda dapat terhubung langsung ke port. Dalam contoh layanan "galera-rs", kami menggunakan NodePort, mengekspos layanan pada setiap IP Node di port statis (NodePort). Layanan ClusterIP, yang akan dirutekan oleh layanan NodePort, dibuat secara otomatis. Anda dapat menghubungi layanan NodePort, dari luar cluster, dengan meminta {NodeIP}:{NodePort} .

Contoh untuk terhubung ke Galera Cluster secara eksternal:

(external)$ mysql -udb_user -ppassword -h192.168.55.141 -P30000
(external)$ mysql -udb_user -ppassword -h192.168.55.142 -P30000
(external)$ mysql -udb_user -ppassword -h192.168.55.143 -P30000

Dalam ruang jaringan Kubernetes, Pod dapat terhubung melalui IP cluster atau nama layanan secara internal yang dapat diambil dengan menggunakan perintah berikut:

$ kubectl get services -o wide
NAME          CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE       SELECTOR
etcd-client   10.104.244.200   <none>        2379/TCP            1d        app=etcd
etcd0         10.100.24.171    <none>        2379/TCP,2380/TCP   1d        etcd_node=etcd0
etcd1         10.108.207.7     <none>        2379/TCP,2380/TCP   1d        etcd_node=etcd1
etcd2         10.101.9.115     <none>        2379/TCP,2380/TCP   1d        etcd_node=etcd2
galera-rs     10.107.89.109    <nodes>       3306:30000/TCP      4h        app=galera-rs
galera-ss     None             <none>        3306/TCP            3m        app=galera-ss
kubernetes    10.96.0.1        <none>        443/TCP             1d        <none>

Dari daftar layanan, kita dapat melihat bahwa Galera Cluster ReplicaSet Cluster-IP adalah 10.107.89.109. Secara internal, pod lain dapat mengakses database melalui alamat IP atau nama layanan ini menggunakan port yang terbuka, 3306:

(etcd0 pod)$ mysql -udb_user -ppassword -hgalera-rs -P3306 -e 'select @@hostname'
+------------------------+
| @@hostname             |
+------------------------+
| galera-251551564-z4sgx |
+------------------------+

Anda juga dapat terhubung ke NodePort eksternal dari dalam pod mana pun di port 30000:

(etcd0 pod)$ mysql -udb_user -ppassword -h192.168.55.143 -P30000 -e 'select @@hostname'
+------------------------+
| @@hostname             |
+------------------------+
| galera-251551564-z4sgx |
+------------------------+

Koneksi ke Pod backend akan seimbang bebannya berdasarkan algoritma koneksi terkecil.

Ringkasan

Pada titik ini, menjalankan Galera Cluster di Kubernetes dalam produksi tampaknya jauh lebih menjanjikan dibandingkan dengan Docker Swarm. Seperti yang dibahas dalam posting blog terakhir, masalah yang diangkat ditangani secara berbeda dengan cara Kubernetes mengatur container di StatefulSet, (walaupun masih fitur beta di v1.6). Kami berharap pendekatan yang disarankan akan membantu menjalankan Galera Cluster pada container dalam skala besar dalam produksi.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. LINQ ke SQL beberapa tabel kiri luar bergabung

  2. Cara membuat MySQL menangani UTF-8 dengan benar

  3. 8 Database Paling Populer

  4. Menyetel ulang kata sandi ROOT di MySQL 5.6

  5. Beberapa Peringkat dalam satu tabel