Dokumen ini ditujukan untuk administrator database, arsitek cloud, dan profesional operasi yang tertarik untuk men-deploy topologi MySQL yang sangat tersedia di Google Kubernetes Engine.
Ikuti tutorial ini untuk mempelajari cara men-deploy Cluster InnoDB MySQL dan MySQL InnoDB ClusterSet, selain middleware MySQL Router di cluster GKE Anda, dan cara melakukan upgrade.
Tujuan
Dalam tutorial ini, Anda akan mempelajari cara:- Membuat dan men-deploy layanan Kubernetes stateful.
- Men-deploy Cluster InnoDB MySQL untuk ketersediaan tinggi.
- Men-deploy middleware Router untuk perutean operasi database.
- Men-deploy ClusterSet InnoDB MySQL untuk toleransi bencana.
- Menyimulasikan failover cluster MySQL.
- Melakukan upgrade versi MySQL.
Bagian berikut menjelaskan arsitektur solusi yang akan Anda buat dalam tutorial ini.
Cluster InnoDB MySQL
Di cluster GKE regional, dengan menggunakan StatefulSet, Anda men-deploy instance database MySQL dengan penamaan dan konfigurasi yang diperlukan untuk membuat Cluster InnoDB MySQL. Untuk memberikan fault tolerance dan ketersediaan tinggi, Anda harus men-deploy tiga Pod instance database. Hal ini memastikan sebagian besar Pod di zona yang berbeda tersedia pada waktu tertentu untuk pemilu primer yang sukses menggunakan protokol konsensus, dan membuat Cluster MySQL InnoDB Anda toleran terhadap kegagalan zona tunggal.
Setelah di-deploy, Anda menetapkan satu Pod sebagai instance utama untuk menyalurkan operasi baca dan tulis. Dua Pod lainnya adalah replika sekunder hanya baca. Jika instance utama mengalami kegagalan infrastruktur, Anda dapat mempromosikan salah satu dari dua Pod replika ini untuk menjadi yang utama.
Dalam namespace terpisah, Anda men-deploy tiga Pod Router MySQL untuk memberikan perutean koneksi guna meningkatkan ketahanan. Alih-alih terhubung langsung ke layanan database, aplikasi Anda terhubung ke Pod Router MySQL. Setiap Pod Router mengetahui status dan tujuan setiap Pod Cluster InnoDB MySQL, dan merutekan operasi aplikasi ke masing-masing Pod yang responsif. Status perutean disimpan dalam cache di Pod Router dan diperbarui dari metadata cluster yang disimpan di setiap node Cluster InnoDB MySQL. Jika terjadi kegagalan instance, Router akan menyesuaikan pemilihan rute koneksi ke instance langsung.
ClusterSet InnoDB MySQL
Anda dapat membuat ClusterSet InnoDB MySQL dari Cluster InnoDB MySQL awal. Dengan demikian, Anda dapat meningkatkan toleransi bencana jika cluster utama tidak lagi tersedia.
Jika instance utama Cluster InnoDB MySQL tidak lagi tersedia, Anda dapat mempromosikan cluster replika di ClusterSet menjadi utama. Saat menggunakan middleware Router MySQL, aplikasi Anda tidak perlu melacak kondisi instance database utama. Pemilihan rute disesuaikan untuk mengirim koneksi ke cluster primer baru setelah pemilihan dilakukan. Namun, Anda bertanggung jawab untuk memastikan bahwa aplikasi yang terhubung ke middleware Router MySQL Anda mengikuti praktik terbaik untuk ketahanan, sehingga koneksi akan dicoba ulang jika terjadi error selama failover cluster.
Biaya
Dalam dokumen ini, Anda menggunakan komponen Google Cloud yang dapat ditagih berikut:
Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda,
gunakan kalkulator harga.
Setelah menyelesaikan tugas yang dijelaskan dalam dokumen ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk mengetahui informasi selengkapnya, lihat Pembersihan.
Sebelum memulai
Menyiapkan project
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
Di konsol Google Cloud, pada halaman pemilih project, klik Buat project untuk mulai membuat project Google Cloud baru.
-
Make sure that billing is enabled for your Google Cloud project.
-
Aktifkan API GKE.
-
Di konsol Google Cloud, pada halaman pemilih project, klik Buat project untuk mulai membuat project Google Cloud baru.
-
Make sure that billing is enabled for your Google Cloud project.
-
Aktifkan API GKE.
Menyiapkan peran
-
Grant roles to your user account. Run the following command once for each of the following IAM roles:
role/storage.objectViewer, role/logging.logWriter, role/artifactregistry.Admin, roles/container.clusterAdmin, role/container.serviceAgent, roles/serviceusage.serviceUsageAdmin, roles/iam.serviceAccountAdmin
gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
- Replace
PROJECT_ID
with your project ID. -
Replace
USER_IDENTIFIER
with the identifier for your user account. For example,user:myemail@example.com
. - Replace
ROLE
with each individual role.
- Replace
Menyiapkan lingkungan Anda
Dalam tutorial ini, Anda akan menggunakan Cloud Shell untuk mengelola resource yang dihosting di Google Cloud. Cloud Shell dilengkapi dengan Docker, kubectl
, dan gcloud CLI.
Untuk menggunakan Cloud Shell guna menyiapkan lingkungan Anda:
Menetapkan variabel lingkungan.
export PROJECT_ID=PROJECT_ID export CLUSTER_NAME=gkemulti-west export REGION=COMPUTE_REGION
Ganti nilai berikut:
- PROJECT_ID: project ID Google Cloud Anda.
- COMPUTE_REGION: region Compute Engine Anda.
Untuk tutorial ini, region-nya adalah
us-west1
. Biasanya, Anda menginginkan wilayah yang dekat dengan Anda.
Tetapkan variabel lingkungan default.
gcloud config set project PROJECT_ID gcloud config set compute/region COMPUTE_REGION
Buat clone repositori kode.
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Ubah ke direktori kerja.
cd kubernetes-engine-samples/databases/gke-stateful-mysql/kubernetes
Membuat cluster GKE
Di bagian ini, Anda akan membuat cluster GKE regional. Tidak seperti cluster zona, bidang kontrol cluster regional direplikasi ke beberapa zona, sehingga pemadaman layanan di satu zona tidak membuat bidang kontrol tidak tersedia.
Untuk membuat cluster GKE, ikuti langkah-langkah berikut:
Autopilot
Di Cloud Shell, buat cluster GKE Autopilot di region
us-west1
.gcloud container clusters create-auto $CLUSTER_NAME \ --region=$REGION
Dapatkan kredensial cluster GKE.
gcloud container clusters get-credentials $CLUSTER_NAME \ --region=$REGION
Deploy Layanan di tiga zona.
kubectl apply -f prepare-for-ha.yaml
Secara default, Autopilot menyediakan sumber daya di dua zona. Deployment yang ditentukan dalam
prepare-for-ha.yaml
memastikan bahwa Autopilot menyediakan node di tiga zona dalam cluster Anda, dengan menetapkanreplicas:3
,podAntiAffinity
denganrequiredDuringSchedulingIgnoredDuringExecution
, dantopologyKey: "topology.kubernetes.io/zone"
.Periksa status Deployment.
kubectl get deployment prepare-three-zone-ha --watch
Jika Anda melihat tiga Pod dalam status siap, batalkan perintah ini dengan
CTRL+C
. Outputnya mirip dengan hal berikut ini:NAME READY UP-TO-DATE AVAILABLE AGE prepare-three-zone-ha 0/3 3 0 9s prepare-three-zone-ha 1/3 3 1 116s prepare-three-zone-ha 2/3 3 2 119s prepare-three-zone-ha 3/3 3 3 2m16s
Jalankan skrip ini untuk memvalidasi bahwa Pod Anda telah di-deploy di tiga zona.
bash ../scripts/inspect_pod_node.sh default
Setiap baris output sesuai dengan Pod, dan kolom kedua menunjukkan zona cloud. Outputnya mirip dengan hal berikut ini:
gk3-gkemulti-west1-default-pool-eb354e2d-z6mv us-west1-b prepare-three-zone-ha-7885d77d9c-8f7qb gk3-gkemulti-west1-nap-25b73chq-739a9d40-4csr us-west1-c prepare-three-zone-ha-7885d77d9c-98fpn gk3-gkemulti-west1-default-pool-160c3578-bmm2 us-west1-a prepare-three-zone-ha-7885d77d9c-phmhj
Standar
Di Cloud Shell, buat cluster GKE Standard di region
us-west1
.gcloud container clusters create $CLUSTER_NAME \ --region=$REGION \ --machine-type="e2-standard-2" \ --disk-type="pd-standard" \ --num-nodes="5"
Dapatkan kredensial cluster GKE.
gcloud container clusters get-credentials $CLUSTER_NAME \ --region=$REGION
Men-deploy StatefulSets MySQL
Di bagian ini, Anda akan men-deploy satu StatefulSet MySQL. Setiap StatefulSet terdiri dari tiga replika MySQL.
Untuk men-deploy StatefulSet MySQL, ikuti langkah-langkah berikut:
Membuat namespace untuk StatefulSet.
kubectl create namespace mysql1
Membuat secret MySQL.
kubectl apply -n mysql1 -f secret.yaml
Sandi di-deploy dengan setiap Pod, dan digunakan oleh skrip dan perintah pengelolaan untuk Cluster InnoDB MySQL dan deployment ClusterSet dalam tutorial ini.
Membuat StorageClass.
kubectl apply -n mysql1 -f storageclass.yaml
Kelas penyimpanan ini menggunakan jenis Persistent Disk
pd-balanced
yang menyeimbangkan performa dan biaya. KolomvolumeBindingMode
disetel keWaitForFirstConsumer
yang berarti GKE menunda penyediaan PersistentVolume hingga Pod dibuat. Setelan ini memastikan bahwa disk disediakan di zona yang sama dengan tempat Pod dijadwalkan.Men-deploy StatefulSet Pod instance MySQL.
kubectl apply -n mysql1 -f c1-mysql.yaml
Perintah ini men-deploy StatefulSet yang terdiri dari tiga replika. Dalam tutorial ini, cluster MySQL utama di-deploy di tiga zona pada
us-west1
. Outputnya mirip dengan hal berikut ini:service/mysql created statefulset.apps/dbc1 created
Dalam tutorial ini, batas dan permintaan resource ditetapkan ke nilai minimum untuk menghemat biaya. Saat merencanakan beban kerja produksi, pastikan untuk menetapkan nilai ini dengan tepat sesuai kebutuhan organisasi Anda.
Pastikan StatefulSet berhasil dibuat.
kubectl get statefulset -n mysql1 --watch
Perlu waktu sekitar 10 menit hingga StatefulSet siap.
Jika ketiga pod dalam status siap, keluar dari perintah menggunakan
Ctrl+C
. Jika Anda melihat errorPodUnscheduleable
karena CPU atau memori tidak mencukupi, tunggu beberapa menit agar ukuran bidang kontrol diubah untuk mengakomodasi beban kerja yang besar.Outputnya mirip dengan hal berikut ini:
NAME READY AGE dbc1 1/3 39s dbc1 2/3 50s dbc1 3/3 73s
Untuk memeriksa penempatan Pod di node cluster GKE, jalankan skrip ini:
bash ../scripts/inspect_pod_node.sh mysql1 mysql
Output menunjukkan nama Pod, nama node GKE, dan zona tempat node disediakan, dan terlihat mirip dengan contoh berikut:
gke-gkemulti-west-5-default-pool-4bcaca65-jch0 us-west1-b dbc1-0 gke-gkemulti-west-5-default-pool-1ac6e8b5-ddjx us-west1-c dbc1-1 gke-gkemulti-west-5-default-pool-1f5baa66-bf8t us-west1-a dbc1-2
Kolom dalam output masing-masing mewakili nama host, zona cloud, dan nama Pod.
Kebijakan
topologySpreadConstraints
dalam spesifikasi StatefulSet (c1-mysql.yaml
) mengarahkan penjadwal untuk menempatkan Pod secara merata di seluruh domain gagal (topology.kubernetes.io/zone
).Kebijakan
podAntiAffinity
menerapkan batasan yang mengharuskan Pod agar tidak ditempatkan pada node cluster GKE yang sama (kubernetes.io/hostname
). Untuk Pod instance MySQL, kebijakan ini menyebabkan Pod di-deploy secara merata di ketiga zona dalam region Google Cloud. Penempatan ini memungkinkan ketersediaan tinggi Cluster InnoDB MySQL dengan menempatkan setiap instance database di domain kegagalan yang terpisah.
Menyiapkan Cluster InnoDB MySQL utama
Untuk mengonfigurasi Cluster InnoDB MySQL, ikuti langkah-langkah berikut:
Di terminal Cloud Shell, tetapkan konfigurasi replikasi grup untuk instance MySQL yang akan ditambahkan ke cluster Anda.
bash ../scripts/c1-clustersetup.sh
Skrip ini akan terhubung dari jarak jauh ke masing-masing dari tiga instance MySQL untuk menetapkan dan mempertahankan variabel lingkungan berikut:
group_replication_ip_allowlist
: memungkinkan instance dalam cluster terhubung ke instance mana pun dalam grup.binlog_transaction_dependency_tracking='WRITESET'
: memungkinkan transaksi paralel yang tidak akan bertentangan.
Di MySQL versi yang lebih lama dari 8.0.22, gunakan
group_replication_ip_whitelist
, bukangroup_replication_ip_allowlist
.Buka terminal kedua agar Anda tidak perlu membuat shell untuk setiap Pod.
Menghubungkan ke MySQL Shell di Pod
dbc1-0
.kubectl -n mysql1 exec -it dbc1-0 -- \ /bin/bash \ -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql.mysql1.svc.cluster.local"'
Memverifikasi daftar replikasi grup MySQL yang diizinkan untuk terhubung ke instance lain.
\sql SELECT @@group_replication_ip_allowlist;
Outputnya mirip dengan hal berikut ini:
+----------------------------------+ | @@group_replication_ip_allowlist | +----------------------------------+ | mysql.mysql1.svc.cluster.local | +----------------------------------+
Pastikan bahwa
server-id
bersifat unik pada setiap instance.\sql SELECT @@server_id;
Outputnya mirip dengan hal berikut ini:
+-------------+ | @@server_id | +-------------+ | 21 | +-------------+
Konfigurasikan setiap instance untuk penggunaan Cluster InnoDB MySQL dan buat akun administrator di setiap instance.
\js dba.configureInstance('root@dbc1-0.mysql.mysql1.svc.cluster.local', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")}); dba.configureInstance('root@dbc1-1.mysql.mysql1.svc.cluster.local', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")}); dba.configureInstance('root@dbc1-2.mysql.mysql1.svc.cluster.local', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
Semua instance harus memiliki nama pengguna dan sandi yang sama agar Cluster InnoDB MySQL dapat berfungsi dengan baik. Setiap perintah menghasilkan output yang mirip dengan berikut ini:
... The instance 'dbc1-2.mysql:3306' is valid to be used in an InnoDB cluster. Cluster admin user 'icadmin'@'%' created. The instance 'dbc1-2.mysql.mysql1.svc.cluster.local:3306' is already ready to be used in an InnoDB cluster. Successfully enabled parallel appliers.
Verifikasi bahwa instance siap digunakan di Cluster InnoDB MySQL.
dba.checkInstanceConfiguration()
Outputnya mirip dengan hal berikut ini:
... The instance 'dbc1-0.mysql.mysql1.svc.cluster.local:3306' is valid to be used in an InnoDB cluster. { "status": "ok" }
Atau, Anda dapat terhubung ke setiap instance MySQL dan mengulangi perintah ini. Misalnya, jalankan perintah ini untuk memeriksa status pada instance
dbc1-1
:kubectl -n mysql1 exec -it dbc1-0 -- \ /bin/bash \ -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-1.mysql.mysql1.svc.cluster.local" \ --js --execute "dba.checkInstanceConfiguration()"'
Membuat Cluster InnoDB MySQL utama
Selanjutnya, buat Cluster InnoDB MySQL menggunakan perintah createCluster
Admin MySQL. Mulai dengan instance dbc1-0
, yang akan menjadi
instance utama untuk cluster, lalu tambahkan dua replika tambahan ke
cluster tersebut.
Untuk melakukan inisialisasi Cluster InnoDB MySQL, ikuti langkah-langkah berikut:
Membuat Cluster InnoDB MySQL.
var cluster=dba.createCluster('mycluster');
Menjalankan perintah
createCluster
akan memicu operasi berikut:- Deploy skema metadata.
- Pastikan konfigurasi sudah benar untuk Replikasi Grup.
- Daftarkan sebagai instance seed dari cluster baru.
- Buat akun internal yang diperlukan, seperti akun pengguna replikasi.
- Mulai Replikasi Grup.
Perintah ini menginisialisasi Cluster InnoDB MySQL dengan
dbc1-0
host sebagai utama. Referensi cluster disimpan dalam variabel cluster.Outputnya terlihat mirip dengan ini:
A new InnoDB cluster will be created on instance 'dbc1-0.mysql:3306'. Validating instance configuration at dbc1-0.mysql:3306... This instance reports its own address as dbc1-0.mysql.mysql1.svc.cluster.local:3306 Instance configuration is suitable. NOTE: Group Replication will communicate with other instances using 'dbc1-0.mysql:33061'. Use the localAddress option to override. Creating InnoDB cluster 'mycluster' on 'dbc1-0.mysql.mysql1.svc.cluster.local:3306'... Adding Seed Instance... Cluster successfully created. Use Cluster.addInstance() to add MySQL instances. At least 3 instances are needed for the cluster to be able to withstand up to one server failure.
Tambahkan instance kedua ke cluster.
cluster.addInstance('icadmin@dbc1-1.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
Tambahkan instance yang tersisa ke cluster.
cluster.addInstance('icadmin@dbc1-2.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
Outputnya mirip dengan hal berikut ini:
... The instance 'dbc1-2.mysql:3306' was successfully added to the cluster.
Verifikasi status cluster.
cluster.status()
Perintah ini akan menampilkan status cluster. Topologinya terdiri dari tiga host, satu instance primer dan dua instance sekunder. Jika ingin, Anda dapat memanggil
cluster.status({extended:1})
.Outputnya mirip dengan hal berikut ini:
{ "clusterName": "mysql1", "defaultReplicaSet": { "name": "default", "primary": "dbc1-0.mysql:3306", "ssl": "REQUIRED", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": { "dbc1-0.mysql:3306": { "address": "dbc1-0.mysql:3306", "memberRole": "PRIMARY", "mode": "R/W", "readReplicas": {}, "replicationLag": null, "role": "HA", "status": "ONLINE", "version": "8.0.28" }, "dbc1-1.mysql:3306": { "address": "dbc1-1.mysql:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": null, "role": "HA", "status": "ONLINE", "version": "8.0.28" }, "dbc1-2.mysql:3306": { "address": "dbc1-2.mysql:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": null, "role": "HA", "status": "ONLINE", "version": "8.0.28" } }, "topologyMode": "Single-Primary" }, "groupInformationSourceMember": "dbc1-0.mysql:3306" }
Jika ingin, Anda dapat memanggil
cluster.status({extended:1})
untuk mendapatkan detail status tambahan.
Membuat contoh database
Untuk membuat contoh database, ikuti langkah-langkah berikut:
Membuat database dan memuat data ke dalam database.
\sql create database loanapplication; use loanapplication CREATE TABLE loan (loan_id INT unsigned AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30) NOT NULL , status VARCHAR(30) );
Memasukkan data sampel ke dalam database. Untuk menyisipkan data, Anda harus terhubung ke instance utama cluster.
INSERT INTO loan (firstname, lastname, status) VALUES ( 'Fred','Flintstone','pending'); INSERT INTO loan (firstname, lastname, status) VALUES ( 'Betty','Rubble','approved');
Pastikan tabel berisi tiga baris yang disisipkan pada langkah sebelumnya.
SELECT * FROM loan;
Outputnya mirip dengan hal berikut ini:
+---------+-----------+------------+----------+ | loan_id | firstname | lastname | status | +---------+-----------+------------+----------+ | 1 | Fred | Flintstone | pending | | 2 | Betty | Rubble | approved | +---------+-----------+------------+----------+ 2 rows in set (0.0010 sec)
Membuat ClusterSet InnoDB MySQL
Anda dapat membuat InnoDB ClusterSet MySQL untuk mengelola replikasi dari cluster utama ke cluster replika, menggunakan saluran replikasi ClusterSet khusus.
ClusterSet InnoDB MySQL memberikan toleransi bencana untuk deployment Cluster InnoDB MySQL dengan menautkan Cluster InnoDB MySQL utama dengan satu atau beberapa replikanya sendiri di lokasi alternatif, seperti beberapa zona dan beberapa region.
Jika Anda menutup MySQL Shell, buat shell baru dengan menjalankan perintah ini di terminal Cloud Shell baru:
kubectl -n mysql1 exec -it dbc1-0 -- \
/bin/bash -c 'mysqlsh \
--uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql.mysql1.svc.cluster.local"'
Untuk membuat ClusterSet InnoDB MySQL, ikuti langkah-langkah berikut:
Di terminal MySQL Shell Anda, dapatkan objek cluster.
\js cluster=dba.getCluster()
Outputnya mirip dengan hal berikut ini:
<Cluster:mycluster>
Lakukan inisialisasi ClusterSet InnoDB MySQL dengan Cluster InnoDB MySQL yang ada dan tersimpan di objek cluster sebagai cluster utama.
clusterset=cluster.createClusterSet('clusterset')
Outputnya mirip dengan hal berikut ini:
A new ClusterSet will be created based on the Cluster 'mycluster'. * Validating Cluster 'mycluster' for ClusterSet compliance. * Creating InnoDB ClusterSet 'clusterset' on 'mycluster'... * Updating metadata... ClusterSet successfully created. Use ClusterSet.createReplicaCluster() to add Replica Clusters to it. <ClusterSet:clusterset>
Periksa status ClusterSet InnoDB MySQL Anda.
clusterset.status()
Outputnya mirip dengan hal berikut ini:
{ "clusters": { "mycluster": { "clusterRole": "PRIMARY", "globalStatus": "OK", "primary": "dbc1-0.mysql:3306" } }, "domainName": "clusterset", "globalPrimaryInstance": "dbc1-0.mysql:3306", "primaryCluster": "mycluster", "status": "HEALTHY", "statusText": "All Clusters available." }
Secara opsional, Anda dapat memanggil
clusterset.status({extended:1})
untuk mendapatkan detail status tambahan, termasuk informasi tentang cluster.Keluar dari MySQL Shell.
\q
Men-deploy Router MySQL
Anda dapat men-deploy Router MySQL untuk mengarahkan traffic aplikasi klien ke cluster yang tepat. Pemilihan rute didasarkan pada port koneksi aplikasi yang mengeluarkan operasi database:
- Operasi tulis dirutekan ke instance Cluster utama di ClusterSet utama.
- Operasi baca dapat dirutekan ke instance mana pun di Cluster utama.
Saat Anda memulai Router MySQL, Router tersebut akan di-bootstrap terhadap deployment ClusterSet InnoDB MySQL. Instance Router MySQL yang terhubung dengan ClusterSet InnoDB MySQL mengetahui adanya peralihan terkontrol atau failover darurat dan mengarahkan traffic ke cluster utama yang baru.
Untuk men-deploy Router MySQL, ikuti langkah-langkah berikut:
Di terminal Cloud Shell, deploy Router MySQL.
kubectl apply -n mysql1 -f c1-router.yaml
Outputnya mirip dengan hal berikut ini:
configmap/mysql-router-config created service/mysql-router created deployment.apps/mysql-router created
Periksa kesiapan deployment Router MySQL.
kubectl -n mysql1 get deployment mysql-router --watch
Jika ketiga Pod sudah siap, outputnya akan mirip dengan berikut ini:
NAME READY UP-TO-DATE AVAILABLE AGE mysql-router 3/3 3 0 3m36s
Jika Anda melihat error
PodUnschedulable
di konsol, tunggu satu atau dua menit selagi GKE menyediakan lebih banyak node. Muat ulang, dan Anda akan melihat3/3 OK
.Mulai MySQL Shell pada anggota cluster yang ada.
kubectl -n mysql1 exec -it dbc1-0 -- \ /bin/bash -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql"'
Perintah ini terhubung ke Pod
dbc1-0
, lalu memulai shell yang terhubung ke instance MySQLdbc1-0
.Verifikasi konfigurasi router.
clusterset=dba.getClusterSet() clusterset.listRouters()
Outputnya mirip dengan hal berikut ini:
{ "domainName": "clusterset", "routers": { "mysql-router-7cd8585fbc-74pkm::": { "hostname": "mysql-router-7cd8585fbc-74pkm", "lastCheckIn": "2022-09-22 23:26:26", "roPort": 6447, "roXPort": 6449, "rwPort": 6446, "rwXPort": 6448, "targetCluster": null, "version": "8.0.27" }, "mysql-router-7cd8585fbc-824d4::": { ... }, "mysql-router-7cd8585fbc-v2qxz::": { ... } } }
Keluar dari MySQL Shell.
\q
Jalankan skrip ini untuk memeriksa penempatan Pod Router MySQL.
bash ../scripts/inspect_pod_node.sh mysql1 | sort
Skrip ini menunjukkan penempatan node dan Zona Cloud dari semua Pod di namespace
mysql1
, dengan output yang mirip dengan berikut ini:gke-gkemulti-west-5-default-pool-1ac6e8b5-0h9v us-west1-c mysql-router-6654f985f5-df97q gke-gkemulti-west-5-default-pool-1ac6e8b5-ddjx us-west1-c dbc1-1 gke-gkemulti-west-5-default-pool-1f5baa66-bf8t us-west1-a dbc1-2 gke-gkemulti-west-5-default-pool-1f5baa66-kt03 us-west1-a mysql-router-6654f985f5-qlfj9 gke-gkemulti-west-5-default-pool-4bcaca65-2l6s us-west1-b mysql-router-6654f985f5-5967d gke-gkemulti-west-5-default-pool-4bcaca65-jch0 us-west1-b dbc1-0
Anda dapat mengamati bahwa Pod Router MySQL didistribusikan secara merata di seluruh zona; yaitu, tidak ditempatkan pada node yang sama dengan Pod MySQL, atau di node yang sama dengan Pod Router MySQL lainnya.
Mengelola upgrade Cluster InnoDB GKE dan MySQL
Update untuk MySQL dan Kubernetes dirilis secara rutin. Ikuti praktik terbaik operasional untuk mengupdate lingkungan software Anda secara rutin. Secara default, GKE mengelola upgrade cluster dan kumpulan node untuk Anda. Kubernetes dan GKE juga menyediakan fitur tambahan untuk memfasilitasi upgrade software MySQL.
Merencanakan upgrade GKE
Anda dapat mengambil langkah-langkah proaktif dan menetapkan konfigurasi untuk memitigasi risiko serta memfasilitasi upgrade cluster yang lebih lancar saat menjalankan layanan stateful, termasuk:
Cluster standar: Ikuti praktik terbaik GKE untuk mengupgrade cluster. Pilih strategi upgrade yang sesuai untuk memastikan upgrade terjadi selama periode masa pemeliharaan:
- Pilih upgrade lonjakan jika pengoptimalan biaya penting dan jika beban kerja Anda dapat menoleransi penonaktifan tuntas dalam waktu kurang dari 60 menit.
- Pilih upgrade blue-green jika beban kerja Anda tidak terlalu toleran terhadap gangguan, dan kenaikan biaya sementara karena penggunaan resource yang lebih tinggi dapat diterima.
Untuk mempelajari lebih lanjut, lihat Mengupgrade cluster yang menjalankan beban kerja stateful. Cluster Autopilot diupgrade secara otomatis, berdasarkan saluran rilis yang Anda pilih.
Gunakan periode pemeliharaan untuk memastikan upgrade terjadi saat Anda menginginkannya. Sebelum masa pemeliharaan, pastikan pencadangan database Anda berhasil.
Sebelum mengizinkan traffic ke node MySQL yang telah diupgrade, gunakan Pemeriksaan Kesiapan dan Pemeriksaan Keaktifan untuk memastikan keduanya siap menerima traffic.
Buat Pemeriksaan yang menilai apakah replikasi sinkron sebelum menerima traffic. Hal ini dapat dilakukan melalui skrip kustom, bergantung pada kompleksitas dan skala database Anda.
Menetapkan kebijakan Anggaran Gangguan Pod (PDB)
Saat Cluster InnoDB MySQL berjalan di GKE, harus ada cukup instance yang berjalan kapan saja untuk memenuhi persyaratan kuorum.
Dalam tutorial ini, dengan mempertimbangkan cluster MySQL yang terdiri dari tiga instance, dua instance harus tersedia untuk membentuk kuorum. Kebijakan PodDisruptionBudget
memungkinkan Anda
membatasi jumlah Pod yang dapat dihentikan pada waktu tertentu. Hal ini
berguna untuk operasi status stabil layanan stateful dan untuk
upgrade cluster.
Untuk memastikan bahwa sejumlah kecil Pod terganggu secara bersamaan, tetapkan
PDB untuk workload ke maxUnavailable: 1
. Hal ini memastikan bahwa dalam operasi layanan, hanya boleh ada satu Pod yang berjalan.
Manifes kebijakan PodDisruptionBudget
berikut menetapkan jumlah maksimum Pod yang tidak tersedia ke satu untuk aplikasi MySQL Anda.
Untuk menerapkan kebijakan PDB ke cluster Anda, ikuti langkah-langkah berikut:
Terapkan kebijakan PDB menggunakan
kubectl
.kubectl apply -n mysql1 -f mysql-pdb-maxunavailable.yaml
Lihat status PDB.
kubectl get poddisruptionbudgets -n mysql1 mysql-pdb -o yaml
Di bagian
status
output, lihat jumlah PodcurrentHealthy
dandesiredHealthy
. Outputnya mirip dengan hal berikut ini:status: ... currentHealthy: 3 desiredHealthy: 2 disruptionsAllowed: 1 expectedPods: 3 ...
Rencana untuk upgrade biner MySQL
Kubernetes dan GKE menyediakan fitur untuk memfasilitasi upgrade bagi biner MySQL. Namun, Anda perlu melakukan beberapa operasi untuk mempersiapkan upgrade.
Ingatlah selalu hal-hal berikut sebelum Anda memulai proses upgrade:
- Upgrade harus dilakukan terlebih dahulu di lingkungan pengujian. Untuk sistem produksi, Anda harus melakukan pengujian lebih lanjut di lingkungan praproduksi.
- Untuk beberapa rilis biner, Anda tidak dapat mendowngrade versi setelah upgrade dilakukan. Luangkan waktu untuk memahami implikasi upgrade.
- Sumber replikasi dapat mereplikasi ke versi yang lebih baru. Namun, menyalin dari versi yang lebih baru ke versi yang lebih lama biasanya tidak didukung.
- Pastikan Anda memiliki cadangan database yang lengkap sebelum men-deploy versi yang telah diupgrade.
- Perlu diingat bahwa Pod Kubernetes bersifat sementara. Status konfigurasi apa pun yang disimpan oleh Pod yang tidak berada dalam volume persisten akan hilang saat Pod di-deploy ulang.
- Untuk upgrade biner MySQL, gunakan PDB, strategi update node pool, dan Probe yang sama seperti yang dijelaskan sebelumnya.
Dalam lingkungan produksi, Anda harus mengikuti praktik terbaik berikut:
- Membuat image container dengan MySQL versi baru.
- Mempertahankan petunjuk build gambar di repositori kontrol sumber.
- Gunakan build image dan pipeline pengujian otomatis seperti Cloud Build, dan simpan biner image di registry image seperti Artifact Registry.
Agar tutorial ini tetap sederhana, Anda tidak akan membangun dan mempertahankan image container. Sebagai gantinya, Anda akan menggunakan image MySQL publik.
Men-deploy biner MySQL yang telah diupgrade
Untuk melakukan upgrade biner MySQL, Anda harus mengeluarkan perintah deklaratif yang mengubah versi image resource StatefulSet. GKE melakukan langkah-langkah yang diperlukan untuk menghentikan Pod saat ini, men-deploy Pod baru dengan biner yang diupgrade, dan memasang persistent disk ke Pod baru.
Verifikasi bahwa PDB telah dibuat.
kubectl get poddisruptionbudgets -n mysql1
Dapatkan daftar kumpulan stateful.
kubectl get statefulsets -n mysql1
Dapatkan daftar Pod yang berjalan menggunakan label
app
.kubectl get pods --selector=app=mysql -n mysql1
Update image MySQL dalam kumpulan stateful.
kubectl -n mysql1 \ set image statefulset/dbc1 \ mysql=mysql/mysql-server:8.0.30
Outputnya mirip dengan hal berikut ini:
statefulset.apps/mysql image updated
Memeriksa status Pod baru dan Pod baru yang berhenti.
kubectl get pods --selector=app=mysql -n mysql1
Memvalidasi upgrade biner MySQL
Selama upgrade, Anda dapat memverifikasi status peluncuran, Pod baru, dan Layanan yang ada.
Konfirmasi upgrade dengan menjalankan perintah
rollout status
.kubectl rollout status statefulset/dbc1 -n mysql1
Outputnya mirip dengan hal berikut ini:
partitioned roll out complete: 3 new pods have been updated...
Konfirmasi versi image dengan memeriksa kumpulan stateful.
kubectl get statefulsets -o wide -n mysql1
Outputnya mirip dengan hal berikut ini:
NAME READY AGE CONTAINERS IMAGES dbc1 3/3 37m mysql mysql/mysql-server:8.0.30
Periksa status cluster.
kubectl -n mysql1 \ exec -it dbc1-0 -- \ /bin/bash \ -c 'mysqlsh \ --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-1.mysql.mysql1.svc.cluster.local" \ --js \ --execute "print(dba.getClusterSet().status({extended:1})); print(\"\\n\")"'
Untuk setiap instance cluster, cari nilai status dan versi dalam output. Outputnya mirip dengan hal berikut ini:
... "status": "ONLINE", "version": "8.0.30" ...
Rollback peluncuran deployment aplikasi terakhir
Saat Anda mengembalikan deployment versi biner yang diupgrade, proses peluncuran akan dibalik dan kumpulan Pod baru di-deploy dengan versi image sebelumnya.
Untuk mengembalikan deployment ke versi kerja sebelumnya, gunakan perintah rollout undo
:
kubectl rollout undo statefulset/dbc1 -n mysql1
Outputnya mirip dengan hal berikut ini:
statefulset.apps/dbc1 rolled back
Menskalakan cluster database secara horizontal
Untuk menskalakan Cluster InnoDB MySQL secara horizontal, tambahkan node tambahan ke node pool cluster GKE (hanya diperlukan jika Anda menggunakan Standard), deploy instance MySQL tambahan, lalu tambahkan setiap instance ke MySQL yang ada Cluster InnoDB.
Menambahkan node ke cluster Standard
Operasi ini tidak diperlukan jika Anda menggunakan cluster Autopilot.
Untuk menambahkan node ke cluster Standard, ikuti petunjuk di bawah untuk Cloud Shell atau konsol Google Cloud. Untuk mengetahui langkah-langkah detailnya, lihat Mengubah ukuran node pool
gcloud
Di Cloud Shell, ubah ukuran node pool default menjadi delapan instance untuk setiap grup instance terkelola.
gcloud container clusters resize ${CLUSTER_NAME} \
--node-pool default-pool \
--num-nodes=8
Konsol
Untuk menambahkan node ke cluster Standard:
- Buka halaman Cluster
gkemulti-west1
di Konsol Google Cloud. - Pilih Nodes, lalu klik default pool.
- Scroll ke bawah ke bagian Grup instance.
- Untuk setiap grup instance, ubah ukuran nilai
Number of nodes
dari 5 menjadi 8 node.
Menambahkan Pod MySQL ke cluster utama
Untuk men-deploy Pod MySQL tambahan guna menskalakan cluster secara horizontal, ikuti langkah-langkah berikut:
Di Cloud Shell, perbarui jumlah replika dalam deployment MySQL dari tiga replika menjadi lima replika.
kubectl scale -n mysql1 --replicas=5 -f c1-mysql.yaml
Memverifikasi progres deployment.
kubectl -n mysql1 get pods --selector=app=mysql -o wide
Untuk menentukan apakah Pod sudah siap, gunakan flag
--watch
untuk menonton deployment. Jika Anda menggunakan cluster Autopilot dan melihat errorPod Unschedulable
, ini mungkin mengindikasikan bahwa GKE menyediakan node untuk mengakomodasi Pod tambahan.Konfigurasikan setelan replikasi grup untuk instance MySQL baru yang akan ditambahkan ke cluster
bash ../scripts/c1-clustersetup.sh 3 4
Skrip ini mengirimkan perintah ke instance yang berjalan di Pod dengan ordinal 3 sampai 4.
Buka MySQL Shell.
kubectl -n mysql1 \ exec -it dbc1-0 -- \ /bin/bash \ -c 'mysqlsh \ --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql"'
Konfigurasi dua instance MySQL baru.
dba.configureInstance('root:$MYSQL_ROOT_PASSWORD@dbc1-3.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")}); dba.configureInstance('root:$MYSQL_ROOT_PASSWORD@dbc1-4.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
Perintah ini memeriksa apakah instance dikonfigurasi dengan benar untuk penggunaan Cluster InnoDB MySQL dan melakukan perubahan konfigurasi yang diperlukan.
Tambahkan salah satu instance baru ke cluster utama.
cluster = dba.getCluster() cluster.addInstance('icadmin@dbc1-3.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
Tambahkan instance baru kedua ke cluster utama.
cluster.addInstance('icadmin@dbc1-4.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
Dapatkan status ClusterSet, yang juga mencakup status Cluster.
clusterset = dba.getClusterSet() clusterset.status({extended: 1})
Outputnya mirip dengan hal berikut ini:
"domainName": "clusterset", "globalPrimaryInstance": "dbc1-0.mysql:3306", "metadataServer": "dbc1-0.mysql:3306", "primaryCluster": "mycluster", "status": "HEALTHY", "statusText": "All Clusters available."
Keluar dari MySQL Shell.
\q
Pembersihan
Agar tidak perlu membayar biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.
Menghapus project
Cara termudah untuk menghindari penagihan adalah dengan menghapus project yang Anda buat untuk tutorial.
Menghapus project Google Cloud:
gcloud projects delete PROJECT_ID
Langkah selanjutnya
- Pelajari lebih lanjut cara integrasi MySQL Google Cloud Observability mengumpulkan metrik performa yang terkait dengan InnoDB.
- Pelajari lebih lanjut pencadangan untuk GKE, sebuah layanan untuk mencadangkan dan memulihkan workload di GKE.
- Pelajari Volume Persisten secara lebih mendetail.