Giriş
operator'ün nasıl kullanılacağı
burada.
Toplamda 2 tane dosya gerekiyor. Bunlar
1. operator.yaml ve
2. 101_initial_cluster.yaml
dosyaları
Federation veya Multi Region
Ayrıca multi region kullanım için bir video
burada, videonun kaynak kodları da
burada. Şeklen şöyle. Burada etcd-global-1,etcd-global-2,etcd-global-3 sunucuları görülebilir.
- Google Cloud için bir kullanım
burada- Konuyu açıklayan
Vitess Operator Federation yazısına bakabilirsiniz. Açıklaması
şöyle. Yani federation için Global Vitess Lockserver gerekir. Bu işlevi de etcd cluster yapar.
Federation allows separate Vitess Operator instances, in separate Kubernetes clusters, to coordinate to deploy and manage a single Vitess Cluster that spans multiple Kubernetes clusters.
Note that this support consists of low-level capabilities that must be combined with additional Kubernetes plug-ins (like some form of cross-cluster LB) and other capabilities (like federated etcd) to assemble a federated system.
...
The basic principle of Vitess Operator federation is to write a set of VitessCluster object specifications that, when deployed in separate Kubernetes clusters, each bring up and manage the pieces of the Vitess cluster that live in that Kubernetes cluster. These pieces should then have some way to discover each other and connect up to form a single Vitess cluster.
Ordinarily, deploying several VitessCluster CRDs in several different Kubernetes clusters would result in completely independent Vitess clusters that don't know about each other. The key to federation is ensuring that all these Vitess components are pointed at a shared, global Vitess lockserver, which typically takes the form of an etcd cluster.
Once Vitess components are pointed at a shared, global topology service, they will use that to find each other's addresses to perform query routing and set up MySQL replication.
101_initial_cluster.yaml
Bu dosya tamamen Vitess Operator'a özel.İçinde iki tane bölüm var
1. kind : Secret
MySQL kurulumunda sonra çalıştırılacak SQL cümleleri vardır
2. kind: VitessCluster :
operator.yaml
Not : İlk kullandığım operator.yaml bir müddet sonra çalışmamaya başladı. Bu yüzden gidip yeni operator.yaml dosyasını indirmek gerekti. Linki
burada. Kullandığımız Vitess sürümüne uygun tag'lenmiş dosyayı indirmek gerekiyor. Örneğin
- main ile taglenmiş dosyada "image: planetscale/vitess-operator:latest" yazıyor.
- ancak "release 14" olarak taglenmiş dosyada "image: planetscale/vitess-operator:v2.7.3" yazıyor
Operator Çalışırken
Vitess Operator vitess kullanımı için gerekli her şeyi çalıştırır. Yani önce Vitess Operator'ün çalıştırılması gerekir. Eğer Vitess Operator düzgün başlamazsa, vtablet, vtgate gibi hiç bir şey de başlamaz. Çıktısı şöyle
>kubectl apply -f operator.yaml
customresourcedefinition.apiextensions.k8s.io/etcdlockservers.planetscale.com created
customresourcedefinition.apiextensions.k8s.io/vitessbackups.planetscale.com created
customresourcedefinition.apiextensions.k8s.io/vitessbackupstorages.planetscale.com created
customresourcedefinition.apiextensions.k8s.io/vitesscells.planetscale.com created
customresourcedefinition.apiextensions.k8s.io/vitessclusters.planetscale.com created
customresourcedefinition.apiextensions.k8s.io/vitesskeyspaces.planetscale.com created
customresourcedefinition.apiextensions.k8s.io/vitessshards.planetscale.com created
serviceaccount/vitess-operator created
role.rbac.authorization.k8s.io/vitess-operator created
rolebinding.rbac.authorization.k8s.io/vitess-operator created
deployment.apps/vitess-operator created
priorityclass.scheduling.k8s.io/vitess-operator-control-plane created
priorityclass.scheduling.k8s.io/vitess created
Örnek
Operator çalışırken podu şöyle görürüz. Yani ContainerCreating ve Running aşamalarından geçiyor.
default vitess-operator-7794c74b9b-5hcxn 0/1 ContainerCreating 0 8s
daha sonra
default vitess-operator-7794c74b9b-5hcxn 1/1 Running 0 97s
Operator çalıştıktan sonra şöyle
yaparız$ kubectl get pods
NAME READY STATUS RESTARTS AGE
...
vitess-operator-8454d86687-4wfnc 1/1 Running 0 2m29s
Minikube İle Kullanım
Talimatlar
burada. Eğer .sh dosyalarını hesaba katarsak bu örnek sadece Linux'ta çalışıyor. Katmazsak Windows'ta da çalışır.
Vitess örneğindeki "--kubernetes-version=v1.19.16" seçeneğini benim minikube kabul etmedi
minikube start --cpus=4 --memory=4000 --disk-size=32g
kubectl apply -f operator.yaml
Daha sonra cluster'ı başlatmak için şöyle
yaparız. Yani examples/operator altındaki dosyalar kullanılıyor. Bu dosyalar kubernetes dosyaları. examples/local dizinindeki gibi
"sh" dosyaları değil.
cd vitess/examples/operator
kubectl apply -f 101_initial_cluster.yaml
Bu işlemden sonra her şeyin çalışması için yaklaşık 7-8 dakika beklemek gerekiyor. Cluster'ın çalıştığını kontrol ederiz. İki tane tablet çalışması lazım. Çünkü yaml dosyası şöyle
tabletPools:
- cell: zone1
type: replica
replicas: 2Zaten pod çıktısında da bunu
görebiliriz. Her pod içinde 3 tane
container çalışıyor.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
example-etcd-faf13de3-1 1/1 Running 0 78s
example-etcd-faf13de3-2 1/1 Running 0 78s
example-etcd-faf13de3-3 1/1 Running 0 78s
example-vttablet-zone1-2469782763-bfadd780 3/3 Running 1 78s
example-vttablet-zone1-2548885007-46a852d0 3/3 Running 1 78s
example-zone1-vtctld-1d4dcad0-59d8498459-kwz6b 1/1 Running 2 78s
example-zone1-vtgate-bc6cde92-6bd99c6888-vwcj5 1/1 Running 2 78s
vitess-operator-8454d86687-4wfnc 1/1 Running 0 2m29s
Eğer 2 tane cell açarsak çıktı şöyle. Halen 3 tane etcd çalışıyor. Her cell için 2 tane yani toplam 4 tane vtctld çalışıyor
kubectl get pods
NAME READY STATUS RESTARTS AGE
adv-vitess-cluster-az1-vtctld-a22f4b1a-86f6d4b78c-ldz9h 1/1 Running 3 (2m6s ago) 10m
adv-vitess-cluster-az1-vtctld-a22f4b1a-86f6d4b78c-vwdhp 1/1 Running 4 (105s ago) 10m
adv-vitess-cluster-az1-vtgate-498e7697-5458d77dc8-mr6pn 1/1 Running 4 (2m3s ago) 10m
adv-vitess-cluster-az1-vtgate-498e7697-5458d77dc8-thgmg 1/1 Running 4 (102s ago) 10m
adv-vitess-cluster-az2-vtctld-d97301ea-764d4ddc6c-d7fpq 1/1 Running 3 (2m3s ago) 10m
adv-vitess-cluster-az2-vtctld-d97301ea-764d4ddc6c-jkmzd 1/1 Running 4 (104s ago) 10m
adv-vitess-cluster-az2-vtgate-9ea92c94-6cc44cd6b-5jcqm 1/1 Running 4 (113s ago) 10m
adv-vitess-cluster-az2-vtgate-9ea92c94-6cc44cd6b-pltm2 1/1 Running 4 (111s ago) 10m
adv-vitess-cluster-etcd-07a83994-1 1/1 Running 1 (116s ago) 10m
adv-vitess-cluster-etcd-07a83994-2 1/1 Running 1 (113s ago) 10m
adv-vitess-cluster-etcd-07a83994-3 1/1 Running 1 (110s ago) 10m
adv-vitess-cluster-vttablet-az1-1330809953-8066577e 3/3 Running 2 (2m ago) 10m
adv-vitess-cluster-vttablet-az1-3415112598-0c0e8ee0 3/3 Running 2 (119s ago) 10m
adv-vitess-cluster-vttablet-az1-4135592426-c2dc2c3d 3/3 Running 2 (112s ago) 10m
adv-vitess-cluster-vttablet-az2-0915606989-18937e48 3/3 Running 2 (117s ago) 10m
adv-vitess-cluster-vttablet-az2-1366268705-cdd98d67 3/3 Running 2 (114s ago) 10m
adv-vitess-cluster-vttablet-az2-4058700183-5f0ba1e4 3/3 Running 2 (115s ago) 10m
vitess-operator-7794c74b9b-s6gc8 1/1 Running 0 11m
Bunu görmek için şöyle yaparız. Bu container isimleri şöyle vttablet, mysqld, mysqld-exporter.
$ kubectl logs example-vttablet-zone1-2469782763-bfadd780
error: a container name must be specified
for pod example-vttablet-zone1-2469782763-bfadd780,
choose one of: [vttablet mysqld mysqld-exporter]
or one of the init containers: [init-vt-root init-mysql-socket]
$ kubectl get pods example-vttablet-zone1-2548885007-46a852d0 -o jsonpath={.spec.containers[*].name}
vttablet mysqld mysqld-exporterEğer bir container'ın loglarına bakmak istersek şöyle yaparız. Burada vtablet'in loglarına bakıyoruz
kubectl logs example-vttablet-zone1-2469782763-bfadd780 -c vttablet
Eğer bir pod'da problem varsa bakmak için şöyle yaparız
kubectl describe pods <podname>
Port Forward
Bu işlemi dışarıdan mysql client ile bağlanabilmek için yapmak gerekiyor. Şöyle
yaparız./pf.sh &
alias vtctlclient="vtctlclient -server=localhost:15999"
alias mysql="mysql -h 127.0.0.1 -P 15306 -u user"
pf.sh dosyasının içi şöyle
#!/bin/sh
kubectl port-forward --address localhost "$(kubectl get service --selector="planetscale.com/component=vtctld" -o name | head -n1)" 15000 15999 &
process_id1=$!
kubectl port-forward --address localhost "$(kubectl get service --selector="planetscale.com/component=vtgate,!planetscale.com/cell" -o name | head -n1)" 15306:3306 &
process_id2=$!
sleep 2
echo "You may point your browser to http://localhost:15000, use the following aliases as shortcuts:"
echo 'alias vtctlclient="vtctlclient -server=localhost:15999 -logtostderr"'
echo 'alias mysql="mysql -h 127.0.0.1 -P 15306 -u user"'
echo "Hit Ctrl-C to stop the port forwards"
wait $process_id1
wait $process_id2
VtGate için cluster içindeki 3306 MySQL portu dış dünyaya 15306 olarak açılıyor
Topology Server için cluster içindeki 15000 ve 15999 portları da dış dünyaya yine aynı numaralarla açılıyor. 15000 HTTP için 15999 ise gRPC için. Böylece dış dünyadan da vtctlclient kullanılabilir.
Topology Server
VTGate
İki cell ile şöyle görürüz. az1 içinde 3 tablet var. İki tanesi replica bir tanesi readonly. az2 içinde de 3 tablet var. Bir tanesi primary, bir tanesi replica ve 1 tanesi de readonly.
Çünkü bu pod şöyle çalıştırılıyor. Yani kendisi az1 içinde ama az2 içindeki tabletleri görüyor. Ayrıca "adv-vitess-cluster-etcd-07a83994-client" isimli ClusterIP servisi kullanarak global etcd sunucusuna da erişiyor. Gerçi parametrede fazladan ".default.svc:2379" var ama sebebini bilmiyorum. Ayrıca bir de "adv-vitess-cluster-etcd-07a83994-peer" isimli ClusterIP servisi var. Bunun da ne olduğunu bilmiyorum.
--buffer_max_failover_duration=10s
--buffer_min_time_between_failovers=20s
--buffer_size=1000
--cell=az1
--cells_to_watch=az1,az2
--enable_buffer=true
--grpc_max_message_size=67108864
--grpc_port=15999
--logtostderr=true
--mysql_auth_server_impl=static
--mysql_auth_server_static_file=/vt/secrets/vtgate-static-auth/users.json
--mysql_auth_static_reload_interval=30s
--mysql_server_port=3306
--mysql_server_version=8.0.13-Vitess
--port=15000
--service_map=grpc-vtgateservice
--tablet_types_to_wait=MASTER,REPLICA
--topo_global_root=/vitess/adv-vitess-cluster/global
--topo_global_server_address=adv-vitess-cluster-etcd-07a83994-client.default.svc:2379
--topo_implementation=etcd2
MySQL Sürümü
vitess/lite:latest MySQL 5.7 kullanıyor. Buradan
görülebilir. Dosyanın ilk hali şöyle
apiVersion: planetscale.com/v2
kind: VitessCluster
metadata:
name: example
spec:
images:
vtctld: vitess/lite:latest
vtgate: vitess/lite:latest
vttablet: vitess/lite:latest
vtbackup: vitess/lite:latest
mysqld:
mysql56Compatible: vitess/lite:latest
mysqldExporter: prom/mysqld-exporter:v0.11.0
cells:
- name: zone1
gateway:
authentication:
static:
secret:
name: example-cluster-config
key: users.json
replicas: 1
extraFlags:
mysql_server_version: "8.0.13-Vitess"
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 256Mi
MySQL 8 kullanmak için şöyle yaparız. Yani
- image olarak "vitess/lite:v12.0.0" veya "vitess/lite:mysql80" kullanıyoruz.
- mysql56Compatible satırını değiştiriyoruz
- extraFlags altına mysql_server_version alanını ekliyoruz.
apiVersion: planetscale.com/v2
kind: VitessCluster
metadata:
name: example
spec:
images:
vtctld: vitess/lite:mysql80
vtgate: vitess/lite:mysql80
vttablet: vitess/lite:mysql80
vtbackup: vitess/lite:mysql80
mysqld:
mysql80Compatible: vitess/lite:mysql80
mysqldExporter: prom/mysqld-exporter:v0.11.0
cells:
- name: zone1
gateway:
authentication:
static:
secret:
name: example-cluster-config
key: users.json
replicas: 1
extraFlags:
mysql_server_version: "8.0.13-Vitess"
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 256Mi
Bu durumda tablet'ler sağlıklı başlamadı. Çıktı şöyle. STATUS alanında Running görünüyor ancak READY sayısı 1/3. Yani STATUS ve READY farklı şeyler
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
example-etcd-faf13de3-1 1/1 Running 1 (10m ago) 17m
example-etcd-faf13de3-2 1/1 Running 1 (10m ago) 17m
example-etcd-faf13de3-3 1/1 Running 1 (10m ago) 17m
example-vttablet-zone1-1168688798-4251d3e4 1/3 Running 2 (10m ago) 17m
example-vttablet-zone1-1385747125-70285362 1/3 Running 2 (10m ago) 17m
example-vttablet-zone1-2469782763-bfadd780 1/3 Running 2 (10m ago) 17m
example-vttablet-zone1-2548885007-46a852d0 1/3 Running 2 (10m ago) 17m
example-vttablet-zone1-3798380744-870319fc 1/3 Running 2 (10m ago) 17m
example-zone1-vtctld-1d4dcad0-5d7ffbfc65-bqkkb 1/1 Running 3 (10m ago) 17m
example-zone1-vtgate-bc6cde92-6dd4b45794-5gqdh 1/1 Running 3 (10m ago) 17m
vitess-operator-5f47c6c45d-v7pn6 1/1 Running 0 18m
Hatanın ne olduğun bakmak için sanırım şöyle
yapılabilir. Pod'un neden schedule edilmediği görülebilir.
mysqld-exporter başladı ama vttablet, ve mysqld başlamadı. Hata şöyle
E0317 08:36:11.606146 1 srv_vschema.go:207] node doesn't exist: /vitess/example/global/cells/zone1/CellInfo: UpdateSrvVSchema(zone1) failed
F0317 08:36:11.606193 1 vttablet.go:109] failed to parse -tablet-path or initialize DB credentials: node doesn't exist: /vitess/example/global/cells/zone1/CellInfo
initeKeyspaceShardTopo: failed to RebuildSrvVSchema
mysqld'nin hatası şöyle
I0317 08:35:57.155966 1 mysqld.go:398] Mysqld.Start(1647506156) stderr: 2022-03-17T08:35:57.150820Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.23) starting as process 567
I0317 08:35:57.157253 1 mysqld.go:398] Mysqld.Start(1647506156) stderr: 2022-03-17T08:35:57.157109Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
I0317 08:35:57.682198 1 mysqld.go:398] Mysqld.Start(1647506156) stderr: Killed
I0317 08:35:57.685847 1 mysqld.go:404] Mysqld.Start(1647506156) stdout: 2022-03-17T08:35:57.685469Z mysqld_safe mysqld from pid file /vt/vtdataroot/vt_1168688798/mysql.pid ended
I0317 08:35:57.685880 1 mysqld.go:398] Mysqld.Start(1647506156) stderr: 2022-03-17T08:35:57.685469Z mysqld_safe mysqld from pid file /vt/vtdataroot/vt_1168688798/mysql.pid ended
I0317 08:35:57.686575 1 mysqld.go:417] Mysqld.Start(1647506156) exit: <nil>
Daha sonra şöyle
yaptım ama yine hatayı bulamadım
$ minikube ssh --user root
docker@minikube $ docker ps
docker@minikube $ sudo docker exec -it FQDN_CONTAINER bash
vitess@example-vttablet-zone1-1385747125-70285362:/$
/vt/bin/mysqlctld \
--db-config-dba-uname=vt_dba \
--db_charset=utf8mb4 \
--init_db_sql_file=/vt/secrets/db-init-script/init_db.sql \
--logtostderr=true \
--mysql_socket=/vt/socket/mysql.sock \
--socket_file=/vt/socket/mysqlctl.sock \
--tablet_uid=1385747125 \
--wait_time=2h0m0sVe en sonunda anladım ki bunların hiçbir şeyler alakası yok:) MySQL 8 için daha fazla bellek vermek gerekiyormuş. Son hali şöyle oldu
apiVersion: planetscale.com/v2
kind: VitessCluster
metadata:
name: example
spec:
images:
vtctld: vitess/lite:mysql80
vtgate: vitess/lite:mysql80
vttablet: vitess/lite:mysql80
vtbackup: vitess/lite:mysql80
mysqld:
mysql80Compatible: vitess/lite:mysql80
mysqldExporter: prom/mysqld-exporter:v0.11.0
cells:
- name: zone1
gateway:
authentication:
static:
secret:
name: example-cluster-config
key: users.json
replicas: 1
extraFlags:
mysql_server_version: "8.0.13-Vitess"
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 256Mi
vitessDashboard:
cells:
- zone1
extraFlags:
security_policy: read-only
replicas: 1
resources:
limits:
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
keyspaces:
- name: ADV
turndownPolicy: Immediate
partitionings:
- equal:
parts: 1
shardTemplate:
databaseInitScriptSecret:
name: example-cluster-config
key: init_db.sql
replication:
enforceSemiSync: false
tabletPools:
- cell: zone1
type: replica
replicas: 1
vttablet:
extraFlags:
db_charset: utf8mb4
resources:
limits:
memory: 256Mi
requests:
cpu: 100m
memory: 256Mi
mysqld:
resources:
limits:
memory: 1024Mi
requests:
cpu: 100m
memory: 512Mi
configOverrides: |
[mysqld]
lower_case_table_names = 1
dataVolumeClaimTemplate:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1GiEnforceSemiSync alanının açıklaması
şöyle. Yani eğer 3 tane replica varsa kullanılabilir. Asynchronous replication olmasına izin vermez.
EnforceSemiSync means Vitess will configure MySQL to require semi-sync acknowledgement of all transactions while forbidding fallback to asynchronous replication under any circumstance.
...
WARNING: Do not enable this if the shard has fewer than 3 master-eligible replicas, as that may lead to master unavailability during routine maintenance.
Örnek
Bir sefer de bir availability zone pod'ları kubernetes açılırken "Pending" olarak kaldı, çünkü Kubernetes cluster'da yeterli kaynak yoktu. Bu durumda da çalışan container sayısı 2/3 görünüyordu. Çalışan container sayısı her zaman 3/3 görünmeli. Her hangi bir tablette bile 2/3 görünse bir yerde mutlaka problem vardır. Read durumuna geçmeyen şey vttablet idi, çünkü sanırım operator cell 2'nin çalışmasını beklediği için vttablet'i de hazır duruma geçirmedi. Çıktı şöyle
$ oc -n rlwy03 get pods
NAME READY STATUS RESTARTS AGE
adv-vitess-cluster-az1-vtctld-a22f4b1a-6947f5bbb6-627hb 1/1 Running 0 3m40s
adv-vitess-cluster-az1-vtctld-a22f4b1a-6947f5bbb6-86t4t 1/1 Running 1 (3m16s ago) 3m40s
adv-vitess-cluster-az1-vtgate-498e7697-74c5dd4fdc-9rtr5 1/1 Running 2 (3m10s ago) 3m40s
adv-vitess-cluster-az1-vtgate-498e7697-74c5dd4fdc-hfhmc 1/1 Running 2 (3m8s ago) 3m40s
adv-vitess-cluster-az2-vtctld-d97301ea-6fcd788464-w4ppn 1/1 Running 2 (3m10s ago) 3m39s
adv-vitess-cluster-az2-vtctld-d97301ea-6fcd788464-z7bzq 1/1 Running 0 3m40s
adv-vitess-cluster-az2-vtgate-9ea92c94-85587bb7f7-cddb7 1/1 Running 0 3m40s
adv-vitess-cluster-az2-vtgate-9ea92c94-85587bb7f7-f66zb 1/1 Running 2 (3m8s ago) 3m40s
adv-vitess-cluster-etcd-07a83994-1 1/1 Running 0 3m40s
adv-vitess-cluster-etcd-07a83994-2 1/1 Running 0 3m40s
adv-vitess-cluster-etcd-07a83994-3 1/1 Running 0 3m40s
adv-vitess-cluster-vttablet-az1-1330809953-8066577e 2/3 Running 2 (3m8s ago) 3m40s
adv-vitess-cluster-vttablet-az1-3415112598-0c0e8ee0 2/3 Running 1 (2m45s ago) 3m40s
adv-vitess-cluster-vttablet-az1-4135592426-c2dc2c3d 0/3 Pending 0 3m40s
adv-vitess-cluster-vttablet-az2-0915606989-18937e48 2/3 Running 2 (3m11s ago) 3m40s
adv-vitess-cluster-vttablet-az2-1366268705-cdd98d67 0/3 Pending 0 3m40s
adv-vitess-cluster-vttablet-az2-4058700183-5f0ba1e4 2/3 Running 1 (3m ago) 3m40s
Failover
Açıklaması
şöyle. Yani master'a bir annotation veriyoruz. Yeni master seçildikten sonra üzerindeki annotation'ı kaldırmayı
unutmamak lazım
... let’s say we think our primary is not in good shape and we’d like to force a failover to the replica. We could use the drain feature of the operator to request a graceful failover to a replica. The operator will choose another suitable replica if one is available, healthy, and not itself drained.
Örnek
$ kubectl annotate pod <podname> drain.planetscale.com/started="Draining for blog"
pod/example-vttablet-zone1-2469782763-bfadd780 annotated
Master geçişi olduktan sonra şöyle
yaparız$ kubectl annotate pod -l planetscale.com/component=vttablet drain.planetscale.com/started-