sql >> Databáze >  >> RDS >> Mysql

Spuštění Galera Cluster na Kubernetes

V několika posledních blozích jsme se zabývali tím, jak spustit Galera Cluster na Dockeru, ať už na samostatném Dockeru nebo na multihostitelském Docker Swarm s překryvnou sítí. V tomto příspěvku na blogu se podíváme na spuštění Galera Cluster na Kubernetes, nástroj pro orchestraci pro spouštění kontejnerů ve velkém. Některé části se liší, například jak se má aplikace připojit ke clusteru, jak Kubernetes zpracovává převzetí služeb při selhání a jak funguje vyrovnávání zátěže v Kubernetes.

Kubernetes vs Docker Swarm

Naším konečným cílem je zajistit, aby Galera Cluster fungoval spolehlivě v prostředí kontejnerů. Dříve jsme se zabývali Docker Swarm a ukázalo se, že spuštění Galera Cluster na něm má řadu blokátorů, které brání tomu, aby byl připraven k produkci. Naše cesta nyní pokračuje s Kubernetes, nástrojem pro orchestraci kontejnerů na produkční úrovni. Podívejme se, jakou úroveň „produkční připravenosti“ může podporovat při spuštění stavové služby, jako je Galera Cluster.

Než se přesuneme dále, pojďme zdůraznit některé klíčové rozdíly mezi Kubernetes (1.6) a Docker Swarm (17.03) při spouštění Galera Cluster na kontejnerech:

  • Kubernetes podporuje dvě sondy pro kontrolu stavu – živost a připravenost. To je důležité při spouštění Galera Cluster na kontejnerech, protože živý kontejner Galera neznamená, že je připraven sloužit a měl by být zahrnut do sady pro vyrovnávání zátěže (přemýšlejte o stavu připojení/dárce). Docker Swarm podporuje pouze jednu sondu pro kontrolu stavu podobnou živosti Kubernetes, kontejner je buď zdravý a stále běží, nebo nezdravý a bude přeplánován. Podrobnosti naleznete zde.
  • Kubernetes má ovládací panel uživatelského rozhraní přístupný prostřednictvím „kubectl proxy“.
  • Docker Swarm podporuje pouze vyvažování zátěže typu round-robin (vstup), zatímco Kubernetes využívá nejméně připojení.
  • Docker Swarm podporuje směrovací síť pro publikování služby do externí sítě, zatímco Kubernetes podporuje něco podobného, ​​co se nazývá NodePort, stejně jako externí nástroje pro vyrovnávání zatížení (GCE GLB/AWS ELB) a externí názvy DNS (jako u verze 1.7)

Instalace Kubernetes pomocí Kubeadm

Budeme používat kubeadm k instalaci 3uzlového clusteru Kubernetes na CentOS 7. Skládá se z 1 hlavního a 2 uzlů (minionů). Naše fyzická architektura vypadá takto:

1. Nainstalujte kubelet a Docker na všechny uzly:

$ 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. Na masteru inicializujte master, zkopírujte konfigurační soubor, nastavte síť Pod pomocí Weave a nainstalujte Kubernetes Dashboard:

$ 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. Poté na ostatních zbývajících uzlech:

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

4. Ověřte, zda jsou uzly připraveny:

$ 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

Nyní máme cluster Kubernetes pro nasazení Galera Cluster.

Galera Cluster na Kubernetes

V tomto příkladu se chystáme nasadit MariaDB Galera Cluster 10.1 pomocí obrazu Docker staženého z našeho úložiště DockerHub. Definiční soubory YAML použité v tomto nasazení lze nalézt v adresáři example-kubernetes v úložišti Github.

Kubernetes podporuje řadu řadičů nasazení. K nasazení Galera Cluster lze použít:

  • ReplicaSet
  • StatefulSet

Každý z nich má své pro a proti. Podíváme se na každý z nich a uvidíme, jaký je rozdíl.

Předpoklady

Obraz, který jsme vytvořili, vyžaduje pro zjišťování služeb etcd (samostatný nebo cluster). Spuštění clusteru etcd vyžaduje, aby každá instance etcd běžela s různými příkazy, takže místo Deployment použijeme ovladač Pods a vytvoříme službu nazvanou „etcd-client“ jako koncový bod pro moduly etcd Pods. Definiční soubor etcd-cluster.yaml říká vše.

Chcete-li nasadit cluster se 3 moduly etcd, jednoduše spusťte:

$ kubectl create -f etcd-cluster.yaml

Ověřte, zda je cluster etcd připraven:

$ 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

Naše architektura nyní vypadá asi takto:

Několik řádků MySQL na Docker:Jak kontejnerizovat databáziZjistěte vše, co potřebujete pochopit, když zvažujete spuštění služby MySQL na horní část virtualizace kontejneru DockerStáhněte si bílou knihu

Použití ReplicaSet

Sada ReplicaSet zajišťuje, že v daný čas běží určený počet „replik“ pod. Deployment je však koncept vyšší úrovně, který spravuje sady ReplicaSets a poskytuje deklarativní aktualizace modulů spolu se spoustou dalších užitečných funkcí. Proto se doporučuje používat Deployments namísto přímého používání ReplicaSets, pokud nevyžadujete vlastní orchestraci aktualizací nebo nevyžadujete aktualizace vůbec. Když používáte Deployments, nemusíte se starat o správu ReplicaSets, které vytvoří. Implementace vlastní a spravují své ReplicaSets.

V našem případě budeme používat Deployment jako řadič pracovní zátěže, jak je znázorněno v této definici YAML. Můžeme přímo vytvořit Galera Cluster ReplicaSet and Service spuštěním následujícího příkazu:

$ kubectl create -f mariadb-rs.yml

Ověřte, zda je cluster připraven, pohledem na ReplicaSet (rs), pody (po) a služby (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

Z výše uvedeného výstupu můžeme ilustrovat naše moduly a službu takto:

Spuštění Galera Cluster na ReplicaSet je podobné jako s ním zacházet jako s bezstavovou aplikací. Organizuje vytváření, mazání a aktualizace podů a může být zaměřeno na automatické škálování horizontálních podů (HPA), tj. sadu ReplicaSet lze automaticky škálovat, pokud splňuje určité prahové hodnoty nebo cíle (využití CPU, pakety za sekundu, požadavek za sekundu atd).

Pokud dojde k výpadku jednoho z uzlů Kubernetes, budou na dostupném uzlu naplánovány nové moduly, aby splnily požadované repliky. Svazky přidružené k modulu budou odstraněny, pokud je modul smazán nebo přeplánován. Název hostitele pod bude vygenerován náhodně, takže bude obtížnější sledovat, kam kontejner patří, pouhým pohledem na název hostitele.

To vše funguje docela dobře v testovacích a přípravných prostředích, kde můžete provádět celý životní cyklus kontejneru, jako je nasazení, škálování, aktualizace a zničení bez jakýchkoli závislostí. Změna měřítka nahoru a dolů je přímočará aktualizací souboru YAML a jeho odesláním do clusteru Kubernetes nebo pomocí příkazu scale:

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

Použití StatefulSet

StatefulSet, známý jako PetSet ve verzi starší než 1.6, je nejlepší způsob, jak nasadit Galera Cluster v produkci, protože:

  • Odstraněním a/nebo zmenšením StatefulSet nedojde k odstranění svazků přidružených k StatefulSet. To se provádí za účelem zajištění bezpečnosti dat, která je obecně cennější než automatické čištění všech souvisejících zdrojů StatefulSet.
  • U StatefulSet s N replikami se moduly při nasazování modulů vytvářejí postupně v pořadí od {0 .. N-1 }.
  • Když jsou moduly mazány, jsou ukončeny v opačném pořadí, od {N-1 .. 0}.
  • Před použitím operace změny velikosti na podu musí být všechny jeho předchůdce spuštěné a připravené.
  • Před ukončením podu musí být všechny jeho nástupce zcela vypnuty.

StatefulSet poskytuje prvotřídní podporu pro stavové kontejnery. Poskytuje záruku nasazení a škálování. Když je vytvořen tříuzlový Galera Cluster, budou nasazeny tři moduly v pořadí db-0, db-1, db-2. db-1 nebude nasazen, dokud nebude db-0 „Spuštěno a připraveno“ a db-2 nebude nasazeno, dokud nebude db-1 „Spuštěno a připraveno“. Pokud by db-0 selhal, poté, co je db-1 „Běžící a připravený“, ale před spuštěním db-2, nebude db-2 spuštěn, dokud nebude db-0 úspěšně znovu spuštěn a nestane se „Spuštěný a připravený“.

Budeme používat Kubernetes implementaci trvalého úložiště s názvem PersistentVolume a PersistentVolumeClaim. Tím se zajistí perzistence dat, pokud bude modul přeplánován na jiný uzel. Přestože Galera Cluster poskytuje přesnou kopii dat na každé replice, trvalé uložení dat v každém modulu je dobré pro účely odstraňování problémů a obnovy.

Abychom vytvořili trvalé úložiště, musíme nejprve vytvořit PersistentVolume pro každý modul. PV jsou moduly pro objemy jako Volumes v Dockeru, ale mají životní cyklus nezávislý na jakémkoli jednotlivém modulu, který používá PV. Protože se chystáme nasadit 3-uzlový Galera Cluster, musíme vytvořit 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

Výše uvedená definice ukazuje, že vytvoříme 3 PV, mapované na fyzickou cestu uzlů Kubernetes s 10 GB úložného prostoru. Definovali jsme ReadWriteOnce, což znamená, že svazek může být připojen jako čtení a zápis pouze jedním uzlem. Uložte výše uvedené řádky do mariadb-pv.yml a odešlete je do Kubernetes:

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

Dále definujte prostředky 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"

Výše uvedená definice ukazuje, že bychom chtěli nárokovat PV zdroje a používat spec.selector.matchLabels hledat naše PV (metadata.labels.app:galera-ss ) na základě příslušného indexu pod (metadata.labels.podindex). ) přidělený Kubernetes. metadata.name zdroj musí používat formát „{volumeMounts.name}-{pod}-{ordinální index}“ definovaný v spec.templates.containers takže Kubernetes ví, který přípojný bod má mapovat nárok do podu.

Uložte výše uvedené řádky do mariadb-pvc.yml a odešlete je do 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

Naše trvalé úložiště je nyní připraveno. Poté můžeme zahájit nasazení Galera Cluster vytvořením prostředku StatefulSet společně se zdrojem služby Headless, jak je znázorněno v mariadb-ss.yml:

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

Nyní si načtěte souhrn našeho nasazení StatefulSet:

$ 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

V tomto okamžiku lze náš Galera Cluster běžící na StatefulSet znázornit jako na následujícím diagramu:

Běh na StatefulSet zaručuje konzistentní identifikátory, jako je název hostitele, IP adresa, ID sítě, doména clusteru, pod DNS a úložiště. To umožňuje, aby se modul snadno odlišil od ostatních ve skupině modulů. Svazek bude uchován na hostiteli a nebude odstraněn, pokud je modul smazán nebo přeplánován na jiný uzel. To umožňuje obnovu dat a snižuje riziko úplné ztráty dat.

Na druhou stranu bude doba nasazení N-1 krát (N =repliky) déle, protože Kubernetes se bude při nasazování, přeplánování nebo mazání prostředků řídit pořadovým pořadím. Bylo by trochu obtížné připravit PV a nároky, než začnete přemýšlet o škálování vašeho clusteru. Upozorňujeme, že aktualizace existující sady StatefulSet je v současné době ruční proces, kdy můžete pouze aktualizovat spec.replicas v tuto chvíli.

Připojování ke Galera Cluster Service a modulům

Existuje několik způsobů, jak se připojit k databázovému clusteru. Můžete se připojit přímo k portu. V příkladu služby „galera-rs“ používáme NodePort, vystavujeme službu na IP každého uzlu na statickém portu (NodePort). Automaticky se vytvoří služba ClusterIP, na kterou bude služba NodePort směrovat. Službu NodePort budete moci kontaktovat z místa mimo klastr vyžádáním {NodeIP}:{NodePort} .

Příklad externího připojení ke Galera Cluster:

(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

V rámci síťového prostoru Kubernetes se mohou Pods připojit přes IP clusteru nebo název služby interně, který lze získat pomocí následujícího příkazu:

$ 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>

Ze seznamu služeb vidíme, že Galera Cluster ReplicaSet Cluster-IP je 10.107.89.109. Interně může další modul přistupovat k databázi prostřednictvím této IP adresy nebo názvu služby pomocí vystaveného portu 3306:

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

Můžete se také připojit k externímu NodePort z libovolného modulu na portu 30000:

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

Připojení k backendovým modulům bude odpovídajícím způsobem vyváženo na základě algoritmu nejmenšího připojení.

Shrnutí

V tuto chvíli se spuštění Galera Cluster na Kubernetes ve výrobě zdá mnohem slibnější ve srovnání s Docker Swarm. Jak bylo uvedeno v posledním příspěvku na blogu, vznesené obavy se řeší odlišně způsobem, jakým Kubernetes organizuje kontejnery ve StatefulSet (ačkoli je to stále beta funkce ve verzi 1.6). Doufáme, že navrhovaný přístup pomůže spustit Galera Cluster na kontejnerech ve velkém měřítku ve výrobě.


  1. Jak vybrat a seřadit podle sloupců, které nejsou v SQL příkazu Groupy By - Oracle

  2. Pandas:Jak číst a zapisovat soubory

  3. Je do MySQL vloženo nesprávné celé číslo (2147483647)?

  4. Jak provádět změny schématu v MySQL a MariaDB bezpečným způsobem