sql >> Databasteknik >  >> RDS >> Mysql

En översikt över Percona XtraDB Cluster Kubernetes Operator

Om du har funnits i containervärlden skulle du veta att det är ganska utmanande att införa en fullständig Kubernetes-automatisering för ett klustrade databassystem, vilket vanligtvis lägger till en nivå av komplexitet till det containerbaserade arkitektur för dessa statistiska tillämpningar. Det är där en Kubernetes-operatör kan hjälpa oss att lösa det här problemet. En Kubernetes Operator är en speciell typ av kontroller som introduceras för att förenkla komplexa distributioner som i princip utökar Kubernetes API med anpassade resurser. Den bygger på Kubernetes grundläggande resurs- och kontrollerkoncept men inkluderar domän- eller applikationsspecifik kunskap för att automatisera hela livscykeln för programvaran som den hanterar.

Percona XtraDB Cluster Operator är ett snyggt sätt att automatisera de specifika uppgifterna för Percona XtraDB Cluster som distribution, skalning, säkerhetskopiering och uppgraderingar inom Kubernetes, byggda och underhållna av Percona. Den distribuerar klustret i ett StatefulSet med en persistent volym, vilket gör att vi kan upprätthålla en konsekvent identitet för varje Pod i klustret och vår data som ska underhållas.

I det här blogginlägget kommer vi att testa implementeringen av Percona XtraDB Cluster 8.0 i en containermiljö, orkestrerad av Percona XtraDB Cluster Kubernetes Operator på Google Cloud Platform.

Skapa ett Kubernetes-kluster i Google Cloud

I den här genomgången kommer vi att använda Kubernetes-klustret på Google Cloud eftersom det är relativt enkelt och lätt att få igång Kubernetes. Logga in på din Google Cloud Platform-instrumentpanel -> Compute -> Kubernetes Engine -> Skapa kluster, så kommer du att presenteras med följande dialogruta:

Ange bara Kubernetes-klusternamnet, välj önskad zon och klicka på "SKAPA " (på botten av sidan). Om 5 minuter kommer ett Kubernetes-kluster med 3 noder att vara klart. Nu, på din arbetsstation, installera gcloud SDK som visas i den här guiden och dra sedan Kubernetes-konfigurationen till din arbetsstation:

$ gcloud container clusters get-credentials my-k8s-cluster --zone asia-northeast1-a --project s9s-qa
Fetching cluster endpoint and auth data.
kubeconfig entry generated for my-k8s-cluster.

Du bör kunna ansluta till Kubernetes-klustret vid det här laget. Kör följande kommando för att verifiera:

$ kubectl get nodes
NAME                                            STATUS   ROLES    AGE    VERSION
gke-my-k8s-cluster-default-pool-b80902cd-gp09   Ready    <none>   139m   v1.16.13-gke.401
gke-my-k8s-cluster-default-pool-b80902cd-jdc3   Ready    <none>   139m   v1.16.13-gke.401
gke-my-k8s-cluster-default-pool-b80902cd-rdv8   Ready    <none>   139m   v1.16.13-gke.401

Ovanstående utdata betyder att vi kan ansluta till Kubernetes-mastern och hämta Kubernetes-klusternoderna. Nu är vi redo att köra Kubernetes-arbetsbelastningarna.

Distribuera ett Percona XtraDB-kluster på Kubernetes

För arbetsbelastningsdistribution kommer vi att följa instruktionerna som anges i Percona XtraDB Cluster Operator-dokumentationen. I grund och botten kör vi följande kommando på vår arbetsstation för att skapa de anpassade resurserna, namnutrymmet, rollbaserad åtkomstkontroll och även Kubernetes-operatören själv:

$ git clone -b v1.6.0 https://github.com/percona/percona-xtradb-cluster-operator
$ cd percona-xtradb-cluster-operator/
$ kubectl apply -f deploy/crd.yaml
$ kubectl create namespace pxc
$ kubectl config set-context $(kubectl config current-context) --namespace=pxc
$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value core/account)
$ kubectl apply -f deploy/rbac.yaml
$ kubectl apply -f deploy/operator.yaml

Närnäst måste vi förbereda våra lösenord (det kallas Secrets in Kubernetes term) genom att uppdatera värdena inuti deploy/secrets.yaml i ett base64-kodat format. Du kan använda onlineverktyg som https://www.base64encode.org/ för att skapa ett eller använda ett kommandoradsverktyg som följande:

$ echo -n 'mypassword' | base64
bXlwYXNzd29yZA==

Uppdatera sedan deploy/secrets.yaml, som visas nedan:

apiVersion: v1
kind: Secret
metadata:
  name: my-cluster-secrets
type: Opaque
data:
  root: bXlwYXNzd29yZA==
  xtrabackup: bXlwYXNzd29yZA==
  monitor: bXlwYXNzd29yZA==
  clustercheck: bXlwYXNzd29yZA==
  proxyadmin: bXlwYXNzd29yZA==
  pmmserver: bXlwYXNzd29yZA==
  operator: bXlwYXNzd29yZA==

Ovanstående är en super förenkling av hemlig hantering, där vi ställer in alla lösenord för att vara lika för alla användare. I produktionen, använd ett mer komplext lösenord och ange ett annat lösenord för varje användare.

Nu kan vi skicka den hemliga konfigurationen till Kubernetes:

$ kubectl apply -f deploy/secrets.yaml

Innan vi går vidare för att distribuera ett Percona XtraDB-kluster måste vi se över standarddefinitionen för distribution i deploy/cr.yaml för klustret. Det finns många Kubernetes-objekt som är definierade här, men de flesta av dem kommenteras bort. För vår arbetsbörda skulle vi göra ändringen enligt nedan:

$ cat deploy/cr.yaml
apiVersion: pxc.percona.com/v1-6-0
kind: PerconaXtraDBCluster
metadata:
  name: cluster1
  finalizers:
    - delete-pxc-pods-in-order
spec:
  crVersion: 1.6.0
  secretsName: my-cluster-secrets
  vaultSecretName: keyring-secret-vault
  sslSecretName: my-cluster-ssl
  sslInternalSecretName: my-cluster-ssl-internal
  allowUnsafeConfigurations: false
  updateStrategy: SmartUpdate
  upgradeOptions:
    versionServiceEndpoint: https://check.percona.com
    apply: recommended
    schedule: "0 4 * * *"
  pxc:
    size: 3
    image: percona/percona-xtradb-cluster:8.0.20-11.1
    configuration: |
      [client]
      default-character-set=utf8

      [mysql]
      default-character-set=utf8

      [mysqld]
      collation-server = utf8_unicode_ci
      character-set-server = utf8
      default_authentication_plugin = mysql_native_password
    resources:
      requests:
        memory: 1G
    affinity:
      antiAffinityTopologyKey: "kubernetes.io/hostname"
    podDisruptionBudget:
      maxUnavailable: 1
    volumeSpec:
      persistentVolumeClaim:
        resources:
          requests:
            storage: 6Gi
    gracePeriod: 600
  haproxy:
    enabled: true
    size: 3
    image: percona/percona-xtradb-cluster-operator:1.6.0-haproxy
    resources:
      requests:
        memory: 1G
    affinity:
      antiAffinityTopologyKey: "kubernetes.io/hostname"
    podDisruptionBudget:
      maxUnavailable: 1
    gracePeriod: 30
  backup:
    image: percona/percona-xtradb-cluster-operator:1.6.0-pxc8.0-backup
    storages:
      fs-pvc:
        type: filesystem
        volume:
          persistentVolumeClaim:
            accessModes: [ "ReadWriteOnce" ]
            resources:
              requests:
                storage: 6Gi
    schedule:
      - name: "daily-backup"
        schedule: "0 0 * * *"
        keep: 5
        storageName: fs-pvc

Vi har gjort några ändringar av den medföljande cr.yaml för att få den att fungera med vår applikation, som visas ovan. Först och främst måste vi kommentera (eller ta bort) alla CPU-relaterade rader, till exempel [*].resources.requests.cpu:600m, för att se till att Kubernetes kan schemalägga podden korrekt på noder med begränsad CPU. Sedan måste vi lägga till några kompatibilitetsalternativ för Percona XtraDB Cluster 8.0 som är baserad på MySQL 8.0, för att fungera smidigt med vår WordPress-applikation som vi kommer att distribuera senare, som visas i följande utdrag:

   configuration: |
      [client]
      default-character-set=utf8

      [mysql]
      default-character-set=utf8

      [mysqld]
      collation-server = utf8_unicode_ci
      character-set-server = utf8
      default_authentication_plugin = mysql_native_password

Ovanstående kommer att matcha MySQL-serverns standardteckenuppsättning med MySQLi PHP-drivrutinen i vår WordPress-behållare. Nästa avsnitt är HAProxy-distributionen där den är inställd på "enabled:true". Det finns också en ProxySQL-sektion med "enabled:false" - vanligtvis skulle man välja någon av de omvända proxyerna för varje kluster. Det sista avsnittet är säkerhetskopieringskonfigurationen, där vi skulle vilja ha en daglig säkerhetskopiering schemalagd klockan 12:00 varje dag och behålla de sista 5 säkerhetskopiorna.

Vi kan nu börja distribuera vårt Percona XtraDB-kluster med 3 noder:

$ kubectl apply -f deploy/cr.yaml

Skapandet kommer att ta lite tid. Operatören kommer att distribuera Percona XtraDB Cluster-poddarna som en Stateful Set, vilket innebär att skapa en pod åt gången och varje Pod i StatefulSet kommer att tilldelas en heltalsordning, från 0 upp till N-1, som är unik över setet. Processen är över när både operatören och poddarna har nått sin körstatus:

$ kubectl get pods
NAME                                               READY   STATUS    RESTARTS   AGE
cluster1-haproxy-0                                 2/2     Running   0          71m
cluster1-haproxy-1                                 2/2     Running   0          70m
cluster1-haproxy-2                                 2/2     Running   0          70m
cluster1-pxc-0                                     1/1     Running   0          71m
cluster1-pxc-1                                     1/1     Running   0          70m
cluster1-pxc-2                                     1/1     Running   0          69m
percona-xtradb-cluster-operator-79d786dcfb-6clld   1/1     Running   0          121m

Eftersom den här operatören är en anpassad resurs kan vi manipulera perconaxtradbcluster-resursen så att den liknar standard Kubernetes-resursen:

$ kubectl get perconaxtradbcluster
NAME       ENDPOINT               STATUS   PXC   PROXYSQL   HAPROXY   AGE
cluster1   cluster1-haproxy.pxc   ready    3                3         27h

Du kan också använda det kortare resursnamnet, "pxc", och prova med följande kommandon:

$ kubectl describe pxc
$ kubectl edit pxc

När vi tittar på arbetsbelastningsuppsättningen kan vi se att operatören har skapat två StatefulSets:

$ kubectl get statefulsets -o wide
NAME               READY   AGE   CONTAINERS          IMAGES
cluster1-haproxy   3/3     26h   haproxy,pxc-monit   percona/percona-xtradb-cluster-operator:1.6.0-haproxy,percona/percona-xtradb-cluster-operator:1.6.0-haproxy
cluster1-pxc       3/3     26h   pxc                 percona/percona-xtradb-cluster:8.0.20-11.2

Operatören kommer också att skapa motsvarande tjänster som kommer att lastbalanserade anslutningar till respektive poddar:

$ kubectl get service
NAME                        TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                       AGE
cluster1-haproxy            ClusterIP      10.40.9.177    <none>          3306/TCP,3309/TCP,33062/TCP   3h27m
cluster1-haproxy-replicas   ClusterIP      10.40.0.236    <none>          3306/TCP                      3h27m
cluster1-pxc                ClusterIP      None           <none>          3306/TCP,33062/TCP            3h27m
cluster1-pxc-unready        ClusterIP      None           <none>          3306/TCP,33062/TCP            3h27m

Ovanstående utdata visar att operatören har skapat fyra tjänster:

  • kluster1-haproxy - Tjänsten för en lastbalanserad MySQL single-master (3306), Proxy-protokoll (3309) och MySQL Admin (33062) - En ny administrativ port introducerad i MySQL 8.0.14 och senare. Detta är tjänstens namn eller kluster-IP-adress som applikationerna behöver ansluta för att ha en enkelmasteranslutning till Galera-klustret.
  • kluster1-haproxy-repliker - Tjänsten för en lastbalanserad MySQL multi-master (3306). Detta är tjänstens namn eller kluster-IP-adress som applikationerna behöver ansluta för att ha en multimasteranslutning till Galera-klustret med round-robin-balanseringsalgoritm.
  • cluster1-pxc - Tjänsten för belastningsbalanserade PXC-poddar, som går förbi HAProxy. Genom att ansluta direkt till den här tjänsten kommer Kubernetes att dirigera anslutningen i round-robin-form till alla PXC-poddar, liknande vad kluster-haproxy-replikas tillhandahåller. Tjänsten har ingen offentlig IP-adress tilldelad och är inte tillgänglig utanför klustret.
  • cluster1-pxc-unready - Tjänsten "oklar" behövs för att hitta podadress under applikationsstarten oavsett Pod-tillstånd. Proxysql- och pxc-pods bör känna till varandra innan databasen blir fullt funktionsduglig. Den oklara tjänsten har ingen offentlig IP-adress tilldelad och är inte tillgänglig utanför klustret.

För att ansluta via en MySQL-klient, kör helt enkelt följande kommando:

$ kubectl run -i --rm --tty percona-client --image=percona:8.0 --restart=Never -- bash -il

Detta skapar en övergående Pod och går omedelbart in i containermiljön. Kör sedan standardkommandot mysql-klient med en korrekt referens:

bash-4.2$ mysql -uroot -pmypassword -h cluster1-haproxy -P3306 -e 'SELECT @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------+
| @@hostname     |
+----------------+
| cluster1-pxc-0 |
+----------------+

När vi tittar på Pod-placeringen är alla Percona XtraDB Cluster-poddar placerade på en annan Kubernetes-värd:

$ kubectl get pods -o wide --selector=app.kubernetes.io/component=pxc
NAME             READY   STATUS    RESTARTS   AGE   IP           NODE                                            NOMINATED NODE   READINESS GATES
cluster1-pxc-0   1/1     Running   0          67m   10.36.2.5    gke-my-k8s-cluster-default-pool-b80902cd-gp09   <none>           <none>
cluster1-pxc-1   1/1     Running   0          66m   10.36.1.10   gke-my-k8s-cluster-default-pool-b80902cd-rdv8   <none>           <none>
cluster1-pxc-2   1/1     Running   0          65m   10.36.0.11   gke-my-k8s-cluster-default-pool-b80902cd-jdc3   <none>           <none>

Detta kommer definitivt att förbättra tillgängligheten för tjänsten, om någon av Kubernetes-värdarna går ner.

För att skala upp till 5 poddar måste vi förbereda ytterligare två nya Kubernetes-noder i förväg för att respektera podaffinitetskonfigurationen (standard till affinity.antiAffinityTopologyKey.topologyKey="kubernetes.io/hostname"). Kör sedan följande patchkommando för att skala Percona XtraDB-klustret till 5 noder:

$ kubectl patch pxc cluster1 \
--type='json' -p='[{"op": "replace", "path": "/spec/pxc/size", "value": 5 }]'

Övervaka skapandet av podden genom att använda kommandot kubectl get pods:

$ kubectl get pods -o wide
NAME               READY   STATUS      RESTARTS   AGE   IP           NODE                                            NOMINATED NODE   READINESS GATES
cluster1-pxc-0     1/1     Running     0          27h   10.36.2.5    gke-my-k8s-cluster-default-pool-b80902cd-gp09   <none>           <none>
cluster1-pxc-1     1/1     Running     0          27h   10.36.1.10   gke-my-k8s-cluster-default-pool-b80902cd-rdv8   <none>           <none>
cluster1-pxc-2     1/1     Running     0          27h   10.36.0.11   gke-my-k8s-cluster-default-pool-b80902cd-jdc3   <none>           <none>
cluster1-pxc-3     1/1     Running     0          30m   10.36.7.2    gke-my-k8s-cluster-pool-1-ab14a45e-h1pf         <none>           <none>
cluster1-pxc-4     1/1     Running     0          13m   10.36.5.3    gke-my-k8s-cluster-pool-1-ab14a45e-01qn         <none>           <none>

Ytterligare 2 nya Pods (cluster1-pxc-3 och cluster1-pxc-4) har skapats på ytterligare 2 nya Kubernetes-noder (gke-my-k8s-cluster-pool-1-ab14a45e-h1pf och gke-my-k8s-cluster-pool-1-ab14a45e-01qn). För att skala ner, ändra helt enkelt tillbaka värdet till 3 i patchkommandot ovan. Observera att Percona XtraDB Cluster bör köras med ett udda antal noder för att förhindra split-brain.

Distribuera ett program (WordPress)

I det här exemplet kommer vi att distribuera en WordPress-applikation ovanpå vårt Percona XtraDB-kluster och HAProxy. Låt oss först förbereda YAML-definitionsfilen enligt följande:

$ cat wordpress-deployment.yaml
apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: frontend
  type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:4.8-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: cluster1-haproxy
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: my-cluster-secrets
              key: root
        ports:
        - containerPort: 80
          name: wordpress
        volumeMounts:
        - name: wordpress-persistent-storage
          mountPath: /var/www/html
      volumes:
      - name: wordpress-persistent-storage
        persistentVolumeClaim:
          claimName: wp-pv-claim

Var uppmärksam på miljövariablerna WORDPRESS_DB_HOST och WORDPRESS_DB_PASSWORD. Den förra variabeln där vi definierade "cluster1-haproxy" som databasvärd, istället för en individuell databasnod och för den senare angav vi root-lösenordet genom att instruera Kubernetes att läsa det från my-cluster-secrets-objektet under nyckeln "root", vilket motsvarar "mypassword" (efter att base64-värdet avkodats). Vi hoppar över att definiera miljövariabeln WORDPRESS_DB_USER eftersom standardvärdet är "root".

Nu kan vi skapa vår applikation:

$ kubectl apply -f wordpress-deployment.yaml

Kontrollera tjänsten:

$ kubectl get service
NAME                        TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                       AGE
cluster1-haproxy            ClusterIP      10.40.9.177    <none>          3306/TCP,3309/TCP,33062/TCP   4h42m
cluster1-haproxy-replicas   ClusterIP      10.40.0.236    <none>          3306/TCP                      4h42m
cluster1-pxc                ClusterIP      None           <none>          3306/TCP,33062/TCP            4h42m
cluster1-pxc-unready        ClusterIP      None           <none>          3306/TCP,33062/TCP            4h42m
wordpress                   LoadBalancer   10.40.13.205   35.200.78.195   80:32087/TCP                  4h39m

Vid denna tidpunkt kan vi ansluta till vår WordPress-applikation på http://35.200.78.195/ (den externa IP-adressen) och börja konfigurera WordPress-applikationen. Vid det här laget är vår WordPress-applikation ansluten till ett av Percona XtraDB-klustret (single-master-anslutning) via en av HAProxy-podarna.

Det var allt för nu. För mer information, kolla in dokumentationen för Percona Kubernetes Operator for Percona XtraDB Cluster. Lycka till med containersändningen!


  1. Utländsk nyckel till flera bord

  2. Vad är DATALENGTH()-ekvivalenten i MySQL?

  3. pgmemcache Installation och användning

  4. Fel vid Update Join