sql >> Database teknologi >  >> RDS >> Mysql

Kører Galera Cluster på Kubernetes

I de sidste par blogs dækkede vi, hvordan man kører en Galera Cluster på Docker, uanset om det er på selvstændig Docker eller på multi-host Docker Swarm med overlejringsnetværk. I dette blogindlæg vil vi se på at køre Galera Cluster på Kubernetes, et orkestreringsværktøj til at køre containere i skala. Nogle dele er forskellige, såsom hvordan applikationen skal oprette forbindelse til klyngen, hvordan Kubernetes håndterer failover, og hvordan belastningsbalanceringen fungerer i Kubernetes.

Kubernetes vs Docker Swarm

Vores ultimative mål er at sikre, at Galera Cluster kører pålideligt i et containermiljø. Vi har tidligere dækket Docker Swarm, og det viste sig, at det at køre Galera Cluster på den har en række blokere, som forhindrer den i at være produktionsklar. Vores rejse fortsætter nu med Kubernetes, et containerorkestreringsværktøj i produktionskvalitet. Lad os se, hvilket niveau af "produktionsberedskab" det kan understøtte, når du kører en stateful service som Galera Cluster.

Inden vi går videre, lad os fremhæve nogle af de vigtigste forskelle mellem Kubernetes (1.6) og Docker Swarm (17.03), når vi kører Galera Cluster på containere:

  • Kubernetes understøtter to sundhedstjeksonder - livlighed og parathed. Dette er vigtigt, når du kører en Galera-klynge på containere, fordi en levende Galera-container ikke betyder, at den er klar til at betjene og bør inkluderes i belastningsbalanceringssættet (tænk på en joiner/donor-stat). Docker Swarm understøtter kun én sundhedstjeksonde, der ligner Kubernetes' livlighed, en container er enten sund og bliver ved med at køre eller usund og bliver omlagt. Læs her for detaljer.
  • Kubernetes har et UI-dashboard, der er tilgængeligt via "kubectl proxy".
  • Docker Swarm understøtter kun round-robin belastningsbalancering (ingress), mens Kubernetes bruger mindst forbindelse.
  • Docker Swarm understøtter routing mesh til at publicere en tjeneste til det eksterne netværk, mens Kubernetes understøtter noget lignende kaldet NodePort, såvel som eksterne belastningsbalancere (GCE GLB/AWS ELB) og eksterne DNS-navne (som for v1.7)

Installation af Kubernetes ved hjælp af Kubeadm

Vi skal bruge kubeadm til at installere en 3-node Kubernetes-klynge på CentOS 7. Den består af 1 master og 2 noder (minions). Vores fysiske arkitektur ser således ud:

1. Installer kubelet og Docker på alle noder:

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

2. På masteren skal du initialisere masteren, kopiere konfigurationsfilen, konfigurere Pod-netværket ved hjælp af Weave og installere Kubernetes Dashboard:

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

3. Derefter på de øvrige resterende noder:

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

4. Bekræft, at noderne er klar:

$ kubectl get nodesNAME STATUS ALDER VERSIONkube1.local Klar 1h v1.6.3kube2.local Klar 1t v1.6.3kube3.local Klar 1t v1.6.3 

Vi har nu en Kubernetes-klynge til Galera Cluster-implementering.

Galera Cluster på Kubernetes

I dette eksempel skal vi implementere en MariaDB Galera Cluster 10.1 ved hjælp af Docker-billede hentet fra vores DockerHub-lager. YAML-definitionsfilerne, der bruges i denne implementering, kan findes under eksempel-kubernetes-biblioteket i Github-lageret.

Kubernetes understøtter en række implementeringscontrollere. For at implementere en Galera Cluster kan man bruge:

  • Replikasæt
  • StatefulSet

Hver af dem har deres egne fordele og ulemper. Vi vil se nærmere på hver enkelt af dem og se, hvad der er forskellen.

Forudsætninger

Det billede, vi byggede, kræver en etcd (standalone eller cluster) til serviceopdagelse. For at køre en etcd-klynge kræver det, at hver etcd-instans kører med forskellige kommandoer, så vi vil bruge Pods-controller i stedet for Deployment og oprette en service kaldet "etcd-client" som slutpunkt til etcd Pods. Etcd-cluster.yaml definitionsfilen fortæller det hele.

For at implementere en 3-pod etcd-klynge skal du blot køre:

$ kubectl create -f etcd-cluster.yaml 

Bekræft, om etcd-klyngen er klar:

$ kubectl get po,svcNAME KLAR STATUS GENSTARTER AGEpo/etcd0 1/1 Kører 0 1dpo/etcd1 1/1 Kører 0 1dpo/etcd2 1/1 Kører 0 1d NAVN CLUSTER-IP EKSTERN-IP-PORT(S) ) AGEsvc/etcd-client 10.104.244.200  2379/TCP 1dsvc/etcd0 10.100.24.171  2379/TCP,2380/TCP 1dsvc/etcd1 .nsvc/etcd1 .n20.n20d1 3TCd1 .n20d1 120.2001 7TCd1.20d1 120.200. 10.101.9.115  2379/TCP,2380/TCP 1d 

Vores arkitektur ser nu nogenlunde sådan her ud:

Severalnines MySQL på Docker:Sådan Containerize Your DatabaseOpdag alt hvad du behøver at forstå, når du overvejer at køre en MySQL-tjeneste toppen af ​​Docker-containervirtualiseringDownload hvidbogen

Brug af ReplicaSet

Et ReplicaSet sikrer, at et specificeret antal pod-"replikaer" kører på ethvert givet tidspunkt. En Deployment er imidlertid et koncept på højere niveau, der administrerer ReplicaSets og giver deklarative opdateringer til pods sammen med en masse andre nyttige funktioner. Derfor anbefales det at bruge Deployments i stedet for direkte at bruge ReplicaSets, medmindre du har brug for tilpasset opdateringsorkestrering eller slet ikke kræver opdateringer. Når du bruger Deployments, behøver du ikke bekymre dig om at administrere de ReplicaSets, som de opretter. Implementeringer ejer og administrerer deres ReplicaSets.

I vores tilfælde vil vi bruge Deployment som workload-controller, som vist i denne YAML-definition. Vi kan oprette Galera Cluster ReplicaSet og Service direkte ved at køre følgende kommando:

$ kubectl create -f mariadb-rs.yml 

Bekræft, om klyngen er klar ved at se på ReplicaSet (rs), pods (po) og services (svc):

$ kubectl get rs,po,svcNAME ØNSKEDE AKTUELLE KLAR AGErs/galera-251551564 3 3 3 5h NAVN KLAR STATUS GENSTARTER AGEpo/etcd0 1/1 Kører 0 1dpo/etcd1 01/12d Kører /1 Kører 0 1dpo/galera-251551564-8c238 1/1 Kører 0 5hpo/galera-251551564-swjjl 1/1 Kører 1 5hpo/galera-251551564-z4sgx 1/5IP EXPORT 1/1h Kører S) AGEsvc/etcd-client 10.104.244.200  2379/TCP 1dsvc/etcd0 10.100.24.171  2379/TCP,2380/TCP 1dsvc/etcd08.7TCP/etcd1.3TCD1.70.20081.90.24.171 etcd2 10.101.9.115  2379/TCP,2380/TCP 1dsvc/galera-rs 10.107.89.109  3306:30000/TCP 5h svc/kubernetes 10.96.0.1  443/TCP 1d 

Fra outputtet ovenfor kan vi illustrere vores Pods og Service som nedenfor:

At køre Galera Cluster på ReplicaSet svarer til at behandle det som et statsløst program. Det orkestrerer pod-oprettelse, -sletning og -opdateringer og kan målrettes til Horisontal Pod Autoscales (HPA), dvs. et ReplicaSet kan automatisk skaleres, hvis det opfylder visse tærskler eller mål (CPU-brug, pakker-per-sekund, anmodning-per-sekund osv.).

Hvis en af ​​Kubernetes-knuderne går ned, vil nye Pods blive planlagt på en tilgængelig node for at opfylde de ønskede replikaer. Bind, der er knyttet til Pod'en, vil blive slettet, hvis Pod'en slettes eller omlægges. Pod-værtsnavnet vil blive genereret tilfældigt, hvilket gør det sværere at spore, hvor containeren hører til ved blot at se på værtsnavnet.

Alt dette fungerer ret godt i test- og iscenesættelsesmiljøer, hvor du kan udføre en fuld containerlivscyklus som at implementere, skalere, opdatere og ødelægge uden nogen afhængigheder. Det er nemt at skalere op og ned ved at opdatere YAML-filen og sende den til Kubernetes-klyngen eller ved at bruge skaleringskommandoen:

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

Brug af StatefulSet

Kendt som PetSet på før 1.6 version, StatefulSet er den bedste måde at implementere Galera Cluster i produktionen, fordi:

  • Sletning og/eller nedskalering af et StatefulSet vil ikke slette de volumener, der er knyttet til StatefulSet. Dette gøres for at sikre datasikkerhed, hvilket generelt er mere værdifuldt end en automatisk udrensning af alle relaterede StatefulSet-ressourcer.
  • For et StatefulSet med N replikaer, når pods er ved at blive implementeret, oprettes de sekventielt i rækkefølge fra {0 .. N-1 }.
  • Når pods slettes, afsluttes de i omvendt rækkefølge fra {N-1 .. 0}.
  • Før en skaleringshandling anvendes på en pod, skal alle dens forgængere være kørende og klar.
  • Før en Pod afsluttes, skal alle dens efterfølgere lukkes fuldstændigt ned.

StatefulSet giver førsteklasses support til stateful containere. Det giver en implementerings- og skaleringsgaranti. Når en Galera-klynge med tre knudepunkter er oprettet, vil tre Pods blive implementeret i rækkefølgen db-0, db-1, db-2. db-1 vil ikke blive implementeret, før db-0 er "Running and Ready", og db-2 vil ikke blive implementeret, før db-1 er "Running and Ready". Hvis db-0 skulle fejle, efter db-1 er "Kører og klar", men før db-2 er lanceret, vil db-2 ikke blive lanceret, før db-0 er genstartet og bliver "Kører og klar".

Vi kommer til at bruge Kubernetes implementering af persistent storage kaldet PersistentVolume og PersistentVolumeClaim. Dette for at sikre datapersistens, hvis poden blev omlagt til den anden node. Selvom Galera Cluster leverer den nøjagtige kopi af data på hver replika, er det godt at have dataene vedvarende i hver pod til fejlfinding og gendannelsesformål.

For at skabe et vedvarende lager skal vi først oprette PersistentVolume for hver pod. PV'er er volumen-plugins som Volumes i Docker, men har en livscyklus uafhængig af enhver individuel pod, der bruger PV'en. Da vi skal implementere en 3-node Galera Cluster, skal vi oprette 3 PV'er:

apiVersion:v1kind:PersistentVolumemetadata:navn:datadir-galera-0 labels:app:galera-ss podindex:"0"spec:accessModes:- ReadWriteOnce kapacitet:lager:10Gi hostPath:sti:/data/pods /galera-0/datadir---apiVersion:v1kind:PersistentVolumemetadata:navn:datadir-galera-1 labels:app:galera-ss podindex:"1"spec:accessModes:- ReadWriteOnce kapacitet:lager:10Gi hostPath:sti:/ data/pods/galera-1/datadir---apiVersion:v1kind:PersistentVolumemetadata:navn:datadir-galera-2 labels:app:galera-ss podindex:"2"spec:accessModes:- ReadWriteOnce kapacitet:lager:10Gi hostPath:sti:/data/pods/galera-2/datadir 

Ovenstående definition viser, at vi vil skabe 3 PV, kortlagt til Kubernetes-knudernes fysiske sti med 10 GB lagerplads. Vi definerede ReadWriteOnce, hvilket betyder, at volumen kun kan monteres som read-write af en enkelt node. Gem ovenstående linjer i mariadb-pv.yml og send det til Kubernetes:

$ kubectl create -f mariadb-pv.ymlpersistentvolume "datadir-galera-0" oprettetpersistentvolumen "datadir-galera-1" oprettetpersistentvolumen "datadir-galera-2" oprettet 

Derefter skal du definere PersistentVolumeClaim-ressourcerne:

type:PersistentVolumeClaimapiVersion:v1metadata:navn:mysql-datadir-galera-ss-0spec:accessModes:- ReadWriteOnce-ressourcer:anmodninger:lagring:10Gi-vælger:matchLabels:app:galera-ss podindex:"0"- --kind:PersistentVolumeCaimapiVersion:v1metadata:navn:mysql-datadir-galera-ss-1spec:accessModes:- ReadWriteOnce-ressourcer:anmodninger:storage:10Gi-vælger:matchLabels:app:galera-ss podindex:"1"---kind:PersistentVolumeCaimapiVersion:v1metadata:navn:mysql-datadir-galera-ss-2spec:accessModes:- ReadWriteOnce-ressourcer:anmodninger:lagring:10Gi-vælger:matchLabels:app:galera-ss podindex:"2" 

Ovenstående definition viser, at vi gerne vil gøre krav på PV-ressourcerne og bruge spec.selector.matchLabels for at lede efter vores PV (metadata.labels.app:galera-ss ) baseret på det respektive pod-indeks (metadata.labels.podindex ) tildelt af Kubernetes. metadata.name ressource skal bruge formatet "{volumeMounts.name}-{pod}-{ordinal index}" defineret under spec.templates.containers så Kubernetes ved, hvilket monteringspunkt der skal tilknyttes kravet til poden.

Gem ovenstående linjer i mariadb-pvc.yml og send det til Kubernetes:

$ kubectl create -f mariadb-pvc.ymlpersistentvolumeclaim "mysql-datadir-galera-ss-0" createdpersistentvolumeclaim "mysql-datadir-galera-ss-1" createdpersistentvolumeclaim "mysql-datadir-galera-ss-2 " oprettet 

Vores vedvarende opbevaring er nu klar. Vi kan derefter starte Galera Cluster-implementeringen ved at oprette en StatefulSet-ressource sammen med Headless-serviceressource som vist i mariadb-ss.yml:

$ kubectl create -f mariadb-ss.ymlservice "galera-ss" oprettetstatefulset "galera-ss" oprettet 

Hent nu oversigten over vores StatefulSet-implementering:

$ kubectl get statefulsets,po,pv,pvc -o wideNAME ØNSKEDE AKTUELLE ALDERstatefulsets/galera-ss 3 3 1d galera fewernines/mariadb:10.1 app=galera-ss NAVN KLAR STATUS GENSTART ALDER IP NODEpo/etcd /1 Løb 0 7d 10.36.0.1 kube3.localpo/etcd1 1/1 Løb 0 7d 10.44.0.2 kube2.localpo/etcd2 1/1 Løb 0 7d 10.36.0.2 kube3.localpo/galera-01s Løb 0/s 1d 10.44.0.4 kube2.localpo/galera-ss-1 1/1 Løb 1 1d 10.36.0.5 kube3.localpo/galera-ss-2 1/1 Løb 0 1d 10.44.0.5 kube2.lokal NAVN LÆGELIGHED LÆGGELIGHED RÆSON ALDER pv/datadir-gale ra-0 10Gi RWO Retain Bound default/mysql-datadir-galera-ss-0 4dpv/datadir-galera-1 10Gi RWO Retain Bound default/mysql-datadir-galera-ss-1 4dpv/datadir-galera-2 10Gi RWO Retain Indbundet standard/mysql-datadir-galera-ss-2 4d NAVN STATUS VOLUME KAPACITET ADGANGSMODUS LAGERKLASSE ALDERpvc/mysql-datadir-galera-ss-0 Bundet datadir-galera-0 10Gi RWO 4dpvc/mysql-data-dir. datadir-galera-1 10Gi RWO 4dpvc/mysql-datadir-galera-ss-2 Indbundet datadir-galera-2 10Gi RWO 4d 

På dette tidspunkt kan vores Galera Cluster, der kører på StatefulSet, illustreres som i følgende diagram:

Kørsel på StatefulSet garanterer ensartede identifikatorer som værtsnavn, IP-adresse, netværks-id, klyngedomæne, Pod DNS og storage. Dette giver Pod'en mulighed for nemt at adskille sig fra andre i en gruppe af Pods. Lydstyrken bevares på værten og slettes ikke, hvis Pod'en slettes eller flyttes til en anden node. Dette giver mulighed for datagendannelse og reducerer risikoen for totalt datatab.

På den negative side vil implementeringstiden være N-1 gange (N =replikaer) længere, fordi Kubernetes vil adlyde ordensrækkefølgen, når ressourcerne implementeres, omplanlægges eller slettes. Det ville være lidt besværligt at forberede PV'en og påstandene, før du tænker på at skalere din klynge. Bemærk, at opdatering af et eksisterende StatefulSet i øjeblikket er en manuel proces, hvor du kun kan opdatere spec.replicas i øjeblikket.

Opretter forbindelse til Galera Cluster Service og Pods

Der er et par måder, du kan oprette forbindelse til databaseklyngen på. Du kan tilslutte direkte til porten. I "galera-rs"-tjenesteeksemplet bruger vi NodePort, der eksponerer tjenesten på hver Nodes IP ved en statisk port (NodePort). En ClusterIP-tjeneste, som NodePort-tjenesten ruter til, oprettes automatisk. Du vil være i stand til at kontakte NodePort-tjenesten uden for klyngen ved at anmode om {NodeIP}:{NodePort} .

Eksempel på ekstern tilslutning til Galera Cluster:

(ekstern)$ mysql -udb_bruger -ppassword -h192.168.55.141 -P30000(ekstern)$ mysql -udb_bruger -ppassword -h192.168.55.142 -P30000 -P30000_external)pudb mysword h192.168.55.143 -P30000

Inden for Kubernetes-netværksområdet kan Pods oprette forbindelse via klynge-IP eller tjenestenavn internt, som kan hentes ved at bruge følgende kommando:

$ kubectl get services -o wideNAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTORetcd-client 10.104.244.200  2379/TCP 1d app=etcdetcd0 10.100.24.171  3306/TCP 3m app=galera-sskubernetes 10.96.0.1  443/TCP 1d  

Fra tjenestelisten kan vi se, at Galera Cluster ReplicaSet Cluster-IP er 10.107.89.109. Internt kan en anden pod få adgang til databasen via denne IP-adresse eller tjenestenavn ved hjælp af den udsatte port, 3306:

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

Du kan også oprette forbindelse til den eksterne NodePort inde fra enhver pod på port 30000:

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

Forbindelse til backend Pods vil være belastningsbalanceret i overensstemmelse hermed baseret på mindste forbindelsesalgoritme.

Oversigt

På dette tidspunkt virker det meget mere lovende at køre Galera Cluster på Kubernetes i produktion sammenlignet med Docker Swarm. Som diskuteret i det sidste blogindlæg tackles de rejste bekymringer forskelligt med den måde Kubernetes orkestrerer containere i StatefulSet, (selvom det stadig er en betafunktion i v1.6). Vi håber, at den foreslåede tilgang vil hjælpe med at køre Galera Cluster på containere i stor skala i produktionen.


  1. Opdater SQL Server-statistikker ved hjælp af en databasevedligeholdelsesplan

  2. Opgradering af Slony-I 2.0.x til seneste version 2.1.x

  3. Frisørsalonens databaseprojekt

  4. På opgraderingsmetoden bliver ikke kaldt i android sqlite