Menjalankan MySQL di Kubernetes
Persyaratan
- Terminal Bash dengan kubectl yang sudah ter-install,
- Kubernetes cluster [Google Kubernetes Engine].
Membuat Namespace untuk MySQL
Namespace dibuat untuk digunakan di environment dengan banyak pengguna yang berada di dalam beberapa tim ataupun proyek. Untuk sebuah cluster dengan beberapa pengguna saja, kamu tidak harus membuat ataupun memikirkan tentang namespace. Mulai gunakan namespace saat kamu membutuhkan fitur dari namespace itu sendiri.
Membuat Namespace Baru
Buat satu file YML dengan nama namespace.yml.
apiVersion: v1
kind: Namespace
metadata:
name: medium-demo
labels:
name : development
Lalu, apply file di atas ke dalam cluster kita.
kubectl apply -f namespace.yml
Pastikan bahwa namespace sudah aktif.
amka@Abduls-MacBook-Pro:~$ kubectl get namespaceNAME STATUS AGE
default Active 17d
medium-demo Active 20s
Membuat PersistentVolumeClaims untuk menyimpan data MySQL
Selanjutnya, kita perlu membuat 1 PVC untuk menyimpan data di dalam direktori /var/lib/mysql.
PVC untuk MySQL
Buat satu file YML dengan nama mysql-vc.yml dengan isinya.
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mysql-volumeclaim
namespace: medium-demo
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
Lalu, apply file mysql-vc.yml ke dalam cluster kita.
amka@Abduls-MacBook-Pro:~$ kubectl apply -f mysql-vc.ymlpersistentvolumeclaim/mysql-volumeclaim created
Pastikan PVC sudah berhasil dibuat dengan namespace.
amka@Abduls-MacBook-Pro:~$ kubectl get pvc -n medium-demo
- -n adalah singkatan dari namespace, karena semua services MySQL di-deploy dalam namespace medium-demo.
Membuat Secret untuk Menyimpan MySQL Password
Kita perlu membuat 2 Secret, Karena MySQL memerlukan root password dan user
Secret MySQL untuk Root Password
secret-mysql-password.ymlapiVersion: v1
kind: Secret
metadata:
name: mysql-root-password
namespace: medium-demo
type: Opaque
stringData:
password: KuB3D3m0db
Secret MySQL untuk User
secret-mysql-user.ymlapiVersion: v1
kind: Secret
metadata:
name: mysql-user-creds
namespace: medium-demo
type: Opaque
stringData:
MYSQL_USER: user
MYSQL_ROOT_PASSWORD: KuB3D3m0db
MYSQL_PASSWORD: mediumdemomysql
Apply file Secret.
kubectl apply -f secret-mysql-password.ymlkubectl apply -f secret-mysql-user.yml
Pastikan Secret yang sudah dibuat masuk ke dalam namespace medium-demo.
amka@Abduls-MacBook-Pro:~$ kubectl get secret -n medium-demo
NAME TYPE DATA AGE
mysql-root-password Opaque 1 2m13s
mysql-user-creds Opaque 3 2m45s
Membuat ConfigMap untuk Menyimpan Konfigurasi MySQL
Kita perlu membuat direktori dengan nama mysql-config untuk konfigurasi MySQL yang akan di-mount ke direktori /etc/mysql/conf.d.
Setelah masuk ke dalam direktori, tahap selanjutnya adalah pembuatan file konfigurasi MySQL dengan nama max_allowed_packet.cnf.
[mysqld]max_allo
wed_packet = 64M
Membuat ConfigMap
Siapkan mysql-conf.yml.
mysql-conf.ymlapiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
namespace: medium-demo
data:
max_allowed_packet.cnf: |
[mysqld]
max_allowed_packet = 32M
Apply file ConfigMap.
kubectl apply -f mysql-conf.yml
Pastikan ConfigMap sudah masuk ke dalam namespace.
amka@Abduls-MacBook-Pro:~$ kubectl get configmap -n medium-demoNAME DATA AGE
mysql-config 1 10s
Membuat Deployment MySQL
Setelah PVC, Secret, dan ConfigMap, kita siap untuk menggunakan file YML berikut.
Pertama, siapkan mysql-cluster.yml.
Sebagai referensi, berikut adalah isi file mysql-cluster.yml yang menggunakan private registry.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mysql-db
name: mysql-db
namespace: medium-demo
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 25%
selector:
matchLabels:
app: mysql-db
template:
metadata:
annotations:
sidecar.istio.io/inject: "false"
labels:
app: mysql-db
spec:
terminationGracePeriodSeconds: 30
containers:
- name: mysql-db
image: asia.gcr.io/[Nama Projek]/[Nama direktori]/[image]
imagePullPolicy: Always
env:
- name: RELEASE_DATE
value: '30MEI2020'
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-root-password
key: password
- name: MYSQL_USER
value: user
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-user-creds
key: MYSQL_PASSWORD
- name: MYSQL_DATABASE
value: mysql
ports:
- containerPort: 3306
protocol: TCP
volumeMounts:
- mountPath: /var/lib/mysql
subPath: "mysql"
name: mysql-presistent-storage
- mountPath: /etc/mysql/conf.d
name: mysql-config
imagePullSecrets:
- name: gcr-registry-json
volumes:
- name: mysql-presistent-storage
persistentVolumeClaim:
claimName: mysql-volumeclaim
- name: mysql-config
configMap:
name: mysql-config
items:
- key: max_allowed_packet.cnf
path: max_allowed_packet.cnf
Untuk yang tidak menggunakan private registry, bisa menggunakan isi di bawah ini.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mysql-db
name: mysql-db
namespace: medium-demo
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 25%
selector:
matchLabels:
app: mysql-db
template:
metadata:
annotations:
sidecar.istio.io/inject: "false"
labels:
app: mysql-db
spec:
terminationGracePeriodSeconds: 30
containers:
- name: mysql-db
image: mysql:5.7
imagePullPolicy: Always
env:
- name: RELEASE_DATE
value: '30MEI2020'
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-root-password
key: password
- name: MYSQL_USER
value: user
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-user-creds
key: MYSQL_PASSWORD
- name: MYSQL_DATABASE
value: mysql
ports:
- containerPort: 3306
protocol: TCP
volumeMounts:
- mountPath: /var/lib/mysql
subPath: "mysql"
name: mysql-presistent-storage
- mountPath: /etc/mysql/conf.d
name: mysql-config
volumes:
- name: mysql-presistent-storage
persistentVolumeClaim:
claimName: mysql-volumeclaim
- name: mysql-config
configMap:
name: mysql-config
items:
- key: max_allowed_packet.cnf
path: max_allowed_packet.cnf
Beberapa komentar tentang YAML,
- Menggunakan MySQL versi 5.7 untuk menyamakan dengan versi MySQL di CloudSQL,
- Menggunakan variabel untuk mengambil root password yang ada pada Secret,
- Jika menggunakan private registry, tambahkan,
imagePullSecrets:
— name: gcr-registry-json
amka@Abduls-MacBook-Pro:~$ kubectl apply -f mysql-cluster.yml
deployment.extensions/mysql-db createdamka@Abduls-MacBook-Pro:~$ kubectl get pods -n medium-demoNAME READY STATUS RESTARTS AGE
mysql-db-5695d96446-rqxz6 1/1 Running 0 5m
Selanjutnya, kita dapat memeriksa log dari pod MySQL untuk menentukan apakah layanan sudah berjalan.
amka@Abduls-MacBook-Pro:~$ kubectl logs -f mysql-db-5695d96446-rqxz6 -n medium-demo2020-05-30 13:11:04+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.30-1debian10 started.
2020-05-30 13:11:05+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2020-05-30 13:11:05+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.30-1debian10 started.
2020-05-30T13:11:06.257500Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2020-05-30T13:11:06.295230Z 0 [Note] mysqld (mysqld 5.7.30) starting as process 1 ...
2020-05-30T13:11:06.300079Z 0 [Warning] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
2020-05-30T13:11:06.303065Z 0 [Note] InnoDB: PUNCH HOLE support available
2020-05-30T13:11:06.303119Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2020-05-30T13:11:06.303137Z 0 [Note] InnoDB: Uses event mutexes
2020-05-30T13:11:06.303154Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
Publish MySQL via Kubernetes Service
Setelah MySQL aktif dan berjalan, kita perlu membuat endpoint publik untuk mengakses MySQL.
Dimulai dengan membuat 2 file YML dengan nama mysql-service-lb.yml dan mysql-service.yml.
mysql-service-lb.ymlapiVersion: v1
kind: Service
metadata:
name: mysql-cluster-lb
namespace: medium-demo
spec:
type: LoadBalancer
ports:
- port: 3306
name: mysql-cluster
selector:
app: mysql-db
File mysql-service.yml untuk mendapatkan ClusterIP local dari MySQL.
mysql-service.ymlapiVersion: v1
kind: Service
metadata:
name: mysql
namespace: medium-demo
spec:
ports:
- port: 3306
name: mysql-cluster
clusterIP: None
selector:
app: mysql-db
Apply file mysql-service-lb.yml dan mysql-service.yml untuk membuat Service dan pastikan Service tersebut sudah ter-deploy di dalam namespace medium-demo.
amka@Abduls-MacBook-Pro:~$ kubectl apply -f mysql-service-lb.yml
service/mysql-cluster-lb createdamka@Abduls-MacBook-Pro:~$ kubectl apply -f mysql-service.yml
service/mysql createdamka@Abduls-MacBook-Pro:~$ kubectl get svc -n medium-demoNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEmysql-cluster-lb LoadBalancer 10.125.6.143 35.225.133.182 3306:31496/TCP 16d
mysql ClusterIP None <none> 3306/TCP 16d
Lalu, gunakan ClusterIP untuk mengakses MySQL melalui CLI.
amka@Abduls-MacBook-Pro:~$ kubectl exec -ti mysql-db-5695d96446-rqxz6 -n medium-demo bashroot@mysql-db-5695d96446-rqxz6:/# mysql -u root -p
Enter password:Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 47302
Server version: 5.7.30 MySQL Community Server (GPL)Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>
Setelah mencoba mengakses melalui CLI, kita dapat pula menggunakan endpoint publik EXTERNAL-IP untuk mengakses MySQL dari database client.
Itu dia! Setelah mengikuti tahapan tersebut, kita memiliki MySQL yang berjalan di Kubernetes. Jika salah satu node gagal, pod akan secara otomatis dipindahtugaskan ke node yang sehat.
Di Warung Pintar, kami selalu berupaya untuk merevolusi warung di seluruh Indonesia mengingat masih banyak orang yang berdagang dengan cara yang sama seperti 50 tahun lalu. Banyak hal yang perlu kita benahi, banyak masalah pula yang masih harus kita selesaikan. Untuk itu, bagi kalian yang tertarik untuk memajukan warung di seluruh Indonesia dengan teknologi,
mari bergabung bersama kami di https://warungpintar.co.id/karir!