Beim Ausführen von verteilten Datenbankclustern ist es üblich, ihnen Load Balancer voranzustellen. Die Vorteile liegen auf der Hand – Lastausgleich, Verbindungs-Failover und Entkopplung der Anwendungsebene von den zugrunde liegenden Datenbanktopologien. Für einen intelligenteren Lastenausgleich wäre ein datenbankfähiger Proxy wie ProxySQL oder MaxScale der richtige Weg. In unserem vorherigen Blog haben wir Ihnen gezeigt, wie Sie ProxySQL als Hilfscontainer in Kubernetes ausführen. In diesem Blogbeitrag zeigen wir Ihnen, wie Sie ProxySQL als Kubernetes-Dienst bereitstellen. Wir verwenden Wordpress als Beispielanwendung und das Datenbank-Backend läuft auf einer Zwei-Knoten-MySQL-Replikation, die mit ClusterControl bereitgestellt wird. Das folgende Diagramm veranschaulicht unsere Infrastruktur:
Da wir ein ähnliches Setup wie in diesem vorherigen Blog-Beitrag verwenden werden, erwarten Sie in einigen Teilen des Blog-Beitrags Duplikate, damit der Beitrag besser lesbar bleibt.
ProxySQL auf Kubernetes
Beginnen wir mit einer kleinen Zusammenfassung. Das Entwerfen einer ProxySQL-Architektur ist ein subjektives Thema und hängt stark von der Platzierung der Anwendung, den Datenbankcontainern sowie der Rolle von ProxySQL selbst ab. Im Idealfall können wir ProxySQL so konfigurieren, dass es von Kubernetes mit zwei Konfigurationen verwaltet wird:
- ProxySQL als Kubernetes-Dienst (zentralisierte Bereitstellung)
- ProxySQL als Hilfscontainer in einem Pod (verteilte Bereitstellung)
Beide Bereitstellungen können anhand des folgenden Diagramms leicht unterschieden werden:
Dieser Blogbeitrag behandelt die erste Konfiguration – das Ausführen von ProxySQL als Kubernetes-Dienst. Die zweite Konfiguration wird hier bereits behandelt. Im Gegensatz zum Helper-Container-Ansatz macht das Ausführen als Dienst ProxySQL-Pods unabhängig von den Anwendungen aktiv und kann mit Hilfe von Kubernetes ConfigMap einfach skaliert und geclustert werden. Dies ist definitiv ein anderer Clustering-Ansatz als die native ProxySQL-Clustering-Unterstützung, die auf Konfigurationsprüfsummen über ProxySQL-Instanzen (auch bekannt als Proxysql_server) angewiesen ist. Sehen Sie sich diesen Blogbeitrag an, wenn Sie mehr über ProxySQL-Clustering erfahren möchten, das mit ClusterControl leicht gemacht wurde.
In Kubernetes ermöglicht das mehrschichtige Konfigurationssystem von ProxySQL Pod-Clustering mit ConfigMap. Es gibt jedoch eine Reihe von Mängeln und Problemumgehungen, damit es reibungslos funktioniert, wie es die native Clustering-Funktion von ProxySQL tut. Im Moment ist die Signalisierung eines Pods bei einem ConfigMap-Update ein Feature in Arbeit. Wir werden dieses Thema in einem kommenden Blog-Beitrag ausführlicher behandeln.
Grundsätzlich müssen wir ProxySQL-Pods erstellen und einen Kubernetes-Dienst anhängen, auf den von den anderen Pods innerhalb des Kubernetes-Netzwerks oder extern zugegriffen werden kann. Anwendungen verbinden sich dann über das TCP/IP-Netzwerk an den konfigurierten Ports mit dem ProxySQL-Dienst. Der Standardwert ist 6033 für MySQL-Verbindungen mit Lastenausgleich und 6032 für die ProxySQL-Verwaltungskonsole. Bei mehr als einem Replikat werden die Verbindungen zum Pod automatisch durch die Kubernetes-kube-proxy-Komponente ausgeglichen, die auf jedem Kubernetes-Knoten ausgeführt wird.
ProxySQL als Kubernetes-Dienst
In diesem Setup führen wir sowohl ProxySQL als auch Wordpress als Pods und Dienste aus. Das folgende Diagramm veranschaulicht unsere High-Level-Architektur:
In diesem Setup werden wir zwei Pods und Dienste bereitstellen – „wordpress“ und „proxysql“. Wir werden Deployment und Service Declaration in einer YAML-Datei pro Anwendung zusammenführen und sie als eine Einheit verwalten. Um den Inhalt der Anwendungscontainer über mehrere Knoten hinweg persistent zu halten, müssen wir ein geclustertes oder entferntes Dateisystem verwenden, in diesem Fall NFS.
Das Bereitstellen von ProxySQL als Dienst bringt ein paar gute Dinge gegenüber dem Helfer-Container-Ansatz:
- Mithilfe des Kubernetes ConfigMap-Ansatzes kann ProxySQL mit unveränderlicher Konfiguration geclustert werden.
- Kubernetes übernimmt die ProxySQL-Wiederherstellung und gleicht die Verbindungen zu den Instanzen automatisch aus.
- Einzelner Endpunkt mit Implementierung der virtuellen IP-Adresse von Kubernetes namens ClusterIP.
- Zentralisierte Reverse-Proxy-Stufe mit Shared-Nothing-Architektur.
- Kann mit externen Anwendungen außerhalb von Kubernetes verwendet werden.
Wir beginnen mit der Bereitstellung als zwei Replikate für ProxySQL und drei für Wordpress, um die skalierbare Ausführung und die Lastausgleichsfunktionen zu demonstrieren, die Kubernetes bietet.
Datenbank vorbereiten
Erstellen Sie die WordPress-Datenbank und den Benutzer auf dem Master und weisen Sie sie mit der richtigen Berechtigung zu:
mysql-master> CREATE DATABASE wordpress;
mysql-master> CREATE USER [email protected]'%' IDENTIFIED BY 'passw0rd';
mysql-master> GRANT ALL PRIVILEGES ON wordpress.* TO [email protected]'%';
Erstellen Sie außerdem den ProxySQL-Überwachungsbenutzer:
mysql-master> CREATE USER [email protected]'%' IDENTIFIED BY 'proxysqlpassw0rd';
Laden Sie dann die Grant-Tabelle neu:
mysql-master> FLUSH PRIVILEGES;
ProxySQL-Pod und Dienstdefinition
Als nächstes bereiten wir unsere ProxySQL-Bereitstellung vor. Erstellen Sie eine Datei namens proxysql-rs-svc.yml und fügen Sie die folgenden Zeilen hinzu:
apiVersion: v1
kind: Deployment
metadata:
name: proxysql
labels:
app: proxysql
spec:
replicas: 2
selector:
matchLabels:
app: proxysql
tier: frontend
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: proxysql
tier: frontend
spec:
restartPolicy: Always
containers:
- image: severalnines/proxysql:1.4.12
name: proxysql
volumeMounts:
- name: proxysql-config
mountPath: /etc/proxysql.cnf
subPath: proxysql.cnf
ports:
- containerPort: 6033
name: proxysql-mysql
- containerPort: 6032
name: proxysql-admin
volumes:
- name: proxysql-config
configMap:
name: proxysql-configmap
---
apiVersion: v1
kind: Service
metadata:
name: proxysql
labels:
app: proxysql
tier: frontend
spec:
type: NodePort
ports:
- nodePort: 30033
port: 6033
name: proxysql-mysql
- nodePort: 30032
port: 6032
name: proxysql-admin
selector:
app: proxysql
tier: frontend
Mal sehen, worum es bei diesen Definitionen geht. Die YAML besteht aus zwei Ressourcen, die in einer Datei kombiniert und durch das Trennzeichen „---“ getrennt sind. Die erste Ressource ist das Deployment, das wir mit der folgenden Spezifikation definieren:
spec:
replicas: 2
selector:
matchLabels:
app: proxysql
tier: frontend
strategy:
type: RollingUpdate
Das Obige bedeutet, dass wir zwei ProxySQL-Pods als ReplicaSet bereitstellen möchten, das Containern entspricht, die mit „app=proxysql,tier=frontend“ gekennzeichnet sind. Die Bereitstellungsstrategie gibt die Strategie an, die verwendet wird, um alte Pods durch neue zu ersetzen. In dieser Bereitstellung haben wir RollingUpdate ausgewählt, was bedeutet, dass die Pods fortlaufend aktualisiert werden, ein Pod nach dem anderen.
Der nächste Teil ist die Vorlage des Containers:
- image: severalnines/proxysql:1.4.12
name: proxysql
volumeMounts:
- name: proxysql-config
mountPath: /etc/proxysql.cnf
subPath: proxysql.cnf
ports:
- containerPort: 6033
name: proxysql-mysql
- containerPort: 6032
name: proxysql-admin
volumes:
- name: proxysql-config
configMap:
name: proxysql-configmap
In den spec.templates.spec.containers.* Abschnitt weisen wir Kubernetes an, ProxySQL mit severalnines/proxysql bereitzustellen Bildversion 1.4.12. Wir möchten auch, dass Kubernetes unsere benutzerdefinierte, vorkonfigurierte Konfigurationsdatei einbindet und sie /etc/proxysql.cnf im Container zuordnet. Die laufenden Pods veröffentlichen zwei Ports – 6033 und 6032. Wir definieren auch den Abschnitt „Volumes“, in dem wir Kubernetes anweisen, die ConfigMap als Volume innerhalb der ProxySQL-Pods bereitzustellen, die von volumeMounts bereitgestellt werden.
Die zweite Ressource ist der Service. Ein Kubernetes-Dienst ist eine Abstraktionsschicht, die den logischen Satz von Pods und eine Richtlinie für den Zugriff auf sie definiert. In diesem Abschnitt definieren wir Folgendes:
apiVersion: v1
kind: Service
metadata:
name: proxysql
labels:
app: proxysql
tier: frontend
spec:
type: NodePort
ports:
- nodePort: 30033
port: 6033
name: proxysql-mysql
- nodePort: 30032
port: 6032
name: proxysql-admin
selector:
app: proxysql
tier: frontend
In diesem Fall möchten wir, dass auf unser ProxySQL vom externen Netzwerk aus zugegriffen wird, daher ist der NodePort-Typ der ausgewählte Typ. Dadurch wird der nodePort auf allen Kubernetes-Knoten im Cluster veröffentlicht. Der Bereich gültiger Ports für die NodePort-Ressource ist 30000-32767. Wir haben Port 30033 für MySQL-Load-Balancing-Verbindungen gewählt, der Port 6033 der ProxySQL-Pods zugeordnet ist, und Port 30032 für den Port 6032 der ProxySQL-Verwaltung.
Daher müssen wir basierend auf unserer obigen YAML-Definition die folgende Kubernetes-Ressource vorbereiten, bevor wir mit der Bereitstellung des „proxysql“-Pods beginnen können:
- ConfigMap – Zum Speichern der ProxySQL-Konfigurationsdatei als Volume, damit sie auf mehreren Pods gemountet und erneut gemountet werden kann, wenn der Pod auf dem anderen Kubernetes-Knoten neu geplant wird.
KonfigMap für ProxySQL vorbereiten
Ähnlich wie im vorherigen Blogbeitrag werden wir den ConfigMap-Ansatz verwenden, um die Konfigurationsdatei vom Container zu entkoppeln und auch für Skalierbarkeitszwecke. Beachten Sie, dass wir in diesem Setup davon ausgehen, dass unsere ProxySQL-Konfiguration unveränderlich ist.
Erstellen Sie zunächst die ProxySQL-Konfigurationsdatei proxysql.cnf und fügen Sie die folgenden Zeilen hinzu:
datadir="/var/lib/proxysql"
admin_variables=
{
admin_credentials="proxysql-admin:adminpassw0rd"
mysql_ifaces="0.0.0.0:6032"
refresh_interval=2000
}
mysql_variables=
{
threads=4
max_connections=2048
default_query_delay=0
default_query_timeout=36000000
have_compress=true
poll_timeout=2000
interfaces="0.0.0.0:6033;/tmp/proxysql.sock"
default_schema="information_schema"
stacksize=1048576
server_version="5.1.30"
connect_timeout_server=10000
monitor_history=60000
monitor_connect_interval=200000
monitor_ping_interval=200000
ping_interval_server_msec=10000
ping_timeout_server=200
commands_stats=true
sessions_sort=true
monitor_username="proxysql"
monitor_password="proxysqlpassw0rd"
}
mysql_replication_hostgroups =
(
{ writer_hostgroup=10, reader_hostgroup=20, comment="MySQL Replication 5.7" }
)
mysql_servers =
(
{ address="192.168.55.171" , port=3306 , hostgroup=10, max_connections=100 },
{ address="192.168.55.172" , port=3306 , hostgroup=10, max_connections=100 },
{ address="192.168.55.171" , port=3306 , hostgroup=20, max_connections=100 },
{ address="192.168.55.172" , port=3306 , hostgroup=20, max_connections=100 }
)
mysql_users =
(
{ username = "wordpress" , password = "passw0rd" , default_hostgroup = 10 , active = 1 }
)
mysql_query_rules =
(
{
rule_id=100
active=1
match_pattern="^SELECT .* FOR UPDATE"
destination_hostgroup=10
apply=1
},
{
rule_id=200
active=1
match_pattern="^SELECT .*"
destination_hostgroup=20
apply=1
},
{
rule_id=300
active=1
match_pattern=".*"
destination_hostgroup=10
apply=1
}
)
Achten Sie auf die admin_variables.admin_credentials Variable, bei der wir den nicht standardmäßigen Benutzer "proxysql-admin" verwendet haben. ProxySQL reserviert den Standardbenutzer „admin“ nur für die lokale Verbindung über localhost. Daher müssen wir andere Benutzer verwenden, um remote auf die ProxySQL-Instanz zuzugreifen. Andernfalls erhalten Sie die folgende Fehlermeldung:
ERROR 1040 (42000): User 'admin' can only connect locally
Unsere ProxySQL-Konfiguration basiert auf unseren beiden Datenbankservern, die in MySQL Replication ausgeführt werden, wie im folgenden Topologie-Screenshot von ClusterControl zusammengefasst:
Alle Schreibvorgänge sollten an den Master-Knoten gehen, während Lesevorgänge an Hostgruppe 20 weitergeleitet werden, wie im Abschnitt „mysql_query_rules“ definiert. Das ist die Grundlage des Read/Write-Splittings und wir wollen sie komplett nutzen.
Importieren Sie dann die Konfigurationsdatei in ConfigMap:
$ kubectl create configmap proxysql-configmap --from-file=proxysql.cnf
configmap/proxysql-configmap created
Überprüfen Sie, ob die ConfigMap in Kubernetes geladen ist:
$ kubectl get configmap
NAME DATA AGE
proxysql-configmap 1 45s
Wordpress-Pod und Dienstdefinition
Fügen Sie nun die folgenden Zeilen in eine Datei namens wordpress-rs-svc.yml ein auf dem Host, auf dem kubectl konfiguriert ist:
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
replicas: 3
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
restartPolicy: Always
containers:
- image: wordpress:4.9-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: proxysql:6033 # proxysql.default.svc.cluster.local:6033
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_DATABASE
value: wordpress
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 80
name: wordpress
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
tier: frontend
spec:
type: NodePort
ports:
- name: wordpress
nodePort: 30088
port: 80
selector:
app: wordpress
tier: frontend
Ähnlich wie bei unserer ProxySQL-Definition besteht die YAML aus zwei Ressourcen, getrennt durch „---“-Trennzeichen, die in einer Datei zusammengefasst sind. Die erste ist die Deployment-Ressource, die als ReplicaSet bereitgestellt wird, wie im Abschnitt „spec.*“ gezeigt:
spec:
replicas: 3
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: RollingUpdate
Dieser Abschnitt enthält die Bereitstellungsspezifikation – 3 zu startende Pods, die mit dem Label „app=wordpress,tier=backend“ übereinstimmen. Die Bereitstellungsstrategie ist RollingUpdate, was bedeutet, dass Kubernetes den Pod ersetzen wird, indem Rolling Update Mode verwendet wird, genau wie bei unserer ProxySQL-Bereitstellung.
Der nächste Teil ist der Abschnitt "spec.template.spec.*":
restartPolicy: Always
containers:
- image: wordpress:4.9-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: proxysql:6033
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
In diesem Abschnitt weisen wir Kubernetes an, Wordpress 4.9 mithilfe des Apache-Webservers bereitzustellen, und wir haben dem Container den Namen "wordpress" gegeben. Der Container wird unabhängig vom Status jedes Mal neu gestartet, wenn er heruntergefahren ist. Wir möchten auch, dass Kubernetes eine Reihe von Umgebungsvariablen übergibt:
- WORDPRESS_DB_HOST - Der MySQL-Datenbankhost. Da wir ProxySQL als Dienst verwenden, ist der Dienstname der Wert von metadata.name das ist "proxysql". ProxySQL lauscht auf Port 6033 auf MySQL-Load-Balancing-Verbindungen, während die ProxySQL-Verwaltungskonsole auf 6032 läuft.
- WORDPRESS_DB_USER - Geben Sie den WordPress-Datenbankbenutzer an, der im Abschnitt "Vorbereitung der Datenbank" erstellt wurde.
- WORDPRESS_DB_PASSWORD - Das Passwort für WORDPRESS_DB_USER . Da wir das Passwort in dieser Datei nicht preisgeben möchten, können wir es mithilfe von Kubernetes Secrets verbergen. Hier weisen wir Kubernetes an, stattdessen die geheime Ressource „mysql-pass“ zu lesen. Secrets müssen vor der Pod-Bereitstellung erstellt werden, wie weiter unten erklärt.
Wir wollen auch Port 80 des Pods für den Endbenutzer veröffentlichen. Der in /var/www/html im Container gespeicherte Wordpress-Inhalt wird in unseren persistenten Speicher gemountet, der auf NFS läuft. Wir werden die PersistentVolume- und PersistentVolumeClaim-Ressourcen für diesen Zweck verwenden, wie im Abschnitt „Persistent Storage für Wordpress vorbereiten“ gezeigt.
Nach der Bruchzeile „---“ definieren wir eine weitere Ressource namens Service:
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
tier: frontend
spec:
type: NodePort
ports:
- name: wordpress
nodePort: 30088
port: 80
selector:
app: wordpress
tier: frontend
In dieser Konfiguration möchten wir, dass Kubernetes einen Dienst namens „wordpress“ erstellt, Port 30088 auf allen Knoten (alias NodePort) auf das externe Netzwerk abhört und ihn an Port 80 auf allen Pods weiterleitet, die mit „app=wordpress,tier=Frontend".
Daher müssen wir basierend auf unserer obigen YAML-Definition eine Reihe von Kubernetes-Ressourcen vorbereiten, bevor wir mit der Bereitstellung des „wordpress“-Pods und -Dienstes beginnen können:
- PersistentVolume und PersistentVolumeClaim - Um die Webinhalte unserer Wordpress-Anwendung zu speichern, damit wir die letzten Änderungen nicht verlieren, wenn der Pod auf einen anderen Worker-Knoten verschoben wird.
- Geheimnisse - Um das Benutzerpasswort der Wordpress-Datenbank in der YAML-Datei zu verbergen.
Persistenten Speicher für Wordpress vorbereiten
Ein guter persistenter Speicher für Kubernetes sollte für alle Kubernetes-Knoten im Cluster zugänglich sein. Für diesen Blogbeitrag haben wir NFS als PersistentVolume (PV)-Anbieter verwendet, weil es einfach ist und standardmäßig unterstützt wird. Der NFS-Server befindet sich irgendwo außerhalb unseres Kubernetes-Netzwerks (wie im ersten Architekturdiagramm gezeigt) und wir haben ihn so konfiguriert, dass er alle Kubernetes-Knoten mit der folgenden Zeile in /etc/exports zulässt:
/nfs 192.168.55.*(rw,sync,no_root_squash,no_all_squash)
Beachten Sie, dass das NFS-Clientpaket auf allen Kubernetes-Knoten installiert sein muss. Andernfalls wäre Kubernetes nicht in der Lage, das NFS korrekt zu mounten. Auf allen Knoten:
$ sudo apt-install nfs-common #Ubuntu/Debian
$ yum install nfs-utils #RHEL/CentOS
Stellen Sie außerdem sicher, dass auf dem NFS-Server das Zielverzeichnis existiert:
(nfs-server)$ mkdir /nfs/kubernetes/wordpress
Erstellen Sie dann eine Datei namens wordpress-pv-pvc.yml und fügen Sie die folgenden Zeilen hinzu:
apiVersion: v1
kind: PersistentVolume
metadata:
name: wp-pv
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 3Gi
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /nfs/kubernetes/wordpress
server: 192.168.55.200
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: wp-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
selector:
matchLabels:
app: wordpress
tier: frontend
In der obigen Definition weisen wir Kubernetes an, 3 GB Volume-Speicherplatz auf dem NFS-Server für unseren Wordpress-Container zuzuweisen. Beachten Sie, dass NFS für die Produktionsnutzung mit automatischer Bereitstellung und Speicherklasse konfiguriert werden sollte.
Erstellen Sie die PV- und PVC-Ressourcen:
$ kubectl create -f wordpress-pv-pvc.yml
Überprüfen Sie, ob diese Ressourcen erstellt wurden und der Status „Gebunden“ lauten muss:
$ kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/wp-pv 3Gi RWO Recycle Bound default/wp-pvc 22h
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/wp-pvc Bound wp-pv 3Gi RWO 22h
Secrets für Wordpress vorbereiten
Erstellen Sie ein Geheimnis, das vom Wordpress-Container für WORDPRESS_DB_PASSWORD verwendet werden soll Umgebungsvariable. Der Grund liegt einfach darin, dass wir das Passwort nicht im Klartext in der YAML-Datei offenlegen möchten.
Erstellen Sie eine geheime Ressource namens mysql-pass und übergeben Sie das Passwort entsprechend:
$ kubectl create secret generic mysql-pass --from-literal=password=passw0rd
Überprüfen Sie, ob unser Geheimnis erstellt wurde:
$ kubectl get secrets mysql-pass
NAME TYPE DATA AGE
mysql-pass Opaque 1 7h12m
Bereitstellung von ProxySQL und Wordpress
Endlich können wir mit der Bereitstellung beginnen. Stellen Sie zuerst ProxySQL bereit, gefolgt von Wordpress:
$ kubectl create -f proxysql-rs-svc.yml
$ kubectl create -f wordpress-rs-svc.yml
Wir können dann alle Pods und Dienste auflisten, die unter der Ebene „Frontend“ erstellt wurden:
$ kubectl get pods,services -l tier=frontend -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
pod/proxysql-95b8d8446-qfbf2 1/1 Running 0 12m 10.36.0.2 kube2.local <none>
pod/proxysql-95b8d8446-vljlr 1/1 Running 0 12m 10.44.0.6 kube3.local <none>
pod/wordpress-59489d57b9-4dzvk 1/1 Running 0 37m 10.36.0.1 kube2.local <none>
pod/wordpress-59489d57b9-7d2jb 1/1 Running 0 30m 10.44.0.4 kube3.local <none>
pod/wordpress-59489d57b9-gw4p9 1/1 Running 0 30m 10.36.0.3 kube2.local <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/proxysql NodePort 10.108.195.54 <none> 6033:30033/TCP,6032:30032/TCP 10m app=proxysql,tier=frontend
service/wordpress NodePort 10.109.144.234 <none> 80:30088/TCP 37m app=wordpress,tier=frontend
kube2.local <none>
Die obige Ausgabe bestätigt unsere Bereitstellungsarchitektur, in der wir derzeit drei Wordpress-Pods haben, die öffentlich auf Port 30088 verfügbar gemacht werden, sowie unsere ProxySQL-Instanz, die extern auf Port 30033 und 30032 sowie intern auf Port 6033 und 6032 verfügbar gemacht wird.
An diesem Punkt sieht unsere Architektur in etwa so aus:
Der von den Wordpress-Pods veröffentlichte Port 80 wird jetzt über Port 30088 der Außenwelt zugeordnet. Wir können auf unseren Blog-Beitrag unter http://{any_kubernetes_host}:30088/ zugreifen und sollten auf die Wordpress-Installationsseite umgeleitet werden. Wenn wir mit der Installation fortfahren, wird der Teil der Datenbankverbindung übersprungen und direkt diese Seite angezeigt:
Es zeigt an, dass unsere MySQL- und ProxySQL-Konfiguration in der Datei wp-config.php korrekt konfiguriert ist. Andernfalls würden Sie zur Datenbankkonfigurationsseite weitergeleitet.
Unsere Bereitstellung ist jetzt abgeschlossen.
ProxySQL-Pods und Dienstverwaltung
Failover und Wiederherstellung werden voraussichtlich automatisch von Kubernetes gehandhabt. Wenn beispielsweise ein Kubernetes-Worker ausfällt, wird der Pod im nächsten verfügbaren Knoten nach --pod-eviction-timeout (standardmäßig 5 Minuten) neu erstellt. Wenn der Container abstürzt oder zerstört wird, ersetzt Kubernetes ihn fast sofort.
Einige gängige Verwaltungsaufgaben werden voraussichtlich anders sein, wenn sie in Kubernetes ausgeführt werden, wie in den nächsten Abschnitten gezeigt.
Verbinden mit ProxySQL
Während ProxySQL extern auf Port 30033 (MySQL) und 30032 (Admin) bereitgestellt wird, ist es auch intern über die veröffentlichten Ports 6033 bzw. 6032 zugänglich. Verwenden Sie daher für den Zugriff auf die ProxySQL-Instanzen im Kubernetes-Netzwerk die CLUSTER-IP oder den Dienstnamen „proxysql“ als Hostwert. Innerhalb des Wordpress-Pods können Sie beispielsweise mit dem folgenden Befehl auf die ProxySQL-Verwaltungskonsole zugreifen:
$ mysql -uproxysql-admin -p -hproxysql -P6032
Wenn Sie eine externe Verbindung herstellen möchten, verwenden Sie den Port, der unter nodePort-Wert des Dienstes YAML definiert ist, und wählen Sie einen der Kubernetes-Knoten als Hostwert aus:
$ mysql -uproxysql-admin -p -hkube3.local -P30032
Dasselbe gilt für die MySQL-Load-Balancing-Verbindung auf Port 30033 (extern) und 6033 (intern).
Hoch- und Runterskalieren
Das Hochskalieren ist mit Kubernetes einfach:
$ kubectl scale deployment proxysql --replicas=5
deployment.extensions/proxysql scaled
Überprüfen Sie den Rollout-Status:
$ kubectl rollout status deployment proxysql
deployment "proxysql" successfully rolled out
Auch das Herunterskalieren ist ähnlich. Hier wollen wir von 5 auf 2 Replikate zurückgehen:
$ kubectl scale deployment proxysql --replicas=2
deployment.extensions/proxysql scaled
Wir können uns auch die Bereitstellungsereignisse für ProxySQL ansehen, um uns ein besseres Bild davon zu machen, was bei dieser Bereitstellung passiert ist, indem wir die Option „Beschreiben“ verwenden:
$ kubectl describe deployment proxysql
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 20m deployment-controller Scaled up replica set proxysql-769895fbf7 to 1
Normal ScalingReplicaSet 20m deployment-controller Scaled down replica set proxysql-95b8d8446 to 1
Normal ScalingReplicaSet 20m deployment-controller Scaled up replica set proxysql-769895fbf7 to 2
Normal ScalingReplicaSet 20m deployment-controller Scaled down replica set proxysql-95b8d8446 to 0
Normal ScalingReplicaSet 7m10s deployment-controller Scaled up replica set proxysql-6c55f647cb to 1
Normal ScalingReplicaSet 7m deployment-controller Scaled down replica set proxysql-769895fbf7 to 1
Normal ScalingReplicaSet 7m deployment-controller Scaled up replica set proxysql-6c55f647cb to 2
Normal ScalingReplicaSet 6m53s deployment-controller Scaled down replica set proxysql-769895fbf7 to 0
Normal ScalingReplicaSet 54s deployment-controller Scaled up replica set proxysql-6c55f647cb to 5
Normal ScalingReplicaSet 21s deployment-controller Scaled down replica set proxysql-6c55f647cb to 2
Die Verbindungen zu den Pods werden automatisch von Kubernetes ausgeglichen.
Konfigurationsänderungen
Eine Möglichkeit, Konfigurationsänderungen an unseren ProxySQL-Pods vorzunehmen, besteht darin, unsere Konfiguration mit einem anderen ConfigMap-Namen zu versionieren. Ändern Sie zunächst unsere Konfigurationsdatei direkt über Ihren bevorzugten Texteditor:
$ vim /root/proxysql.cnf
Laden Sie es dann mit einem anderen Namen in Kubernetes ConfigMap hoch. In diesem Beispiel hängen wir "-v2" an den Ressourcennamen an:
$ kubectl create configmap proxysql-configmap-v2 --from-file=proxysql.cnf
Überprüfen Sie, ob die ConfigMap korrekt geladen wurde:
$ kubectl get configmap
NAME DATA AGE
proxysql-configmap 1 3d15h
proxysql-configmap-v2 1 19m
Öffnen Sie die ProxySQL-Bereitstellungsdatei proxysql-rs-svc.yml und ändern Sie die folgende Zeile im Abschnitt configMap auf die neue Version:
volumes:
- name: proxysql-config
configMap:
name: proxysql-configmap-v2 #change this line
Wenden Sie dann die Änderungen auf unsere ProxySQL-Bereitstellung an:
$ kubectl apply -f proxysql-rs-svc.yml
deployment.apps/proxysql configured
service/proxysql configured
Überprüfen Sie die Einführung, indem Sie sich das ReplicaSet-Ereignis mit dem Flag „describe“ ansehen:
$ kubectl describe proxysql
...
Pod Template:
Labels: app=proxysql
tier=frontend
Containers:
proxysql:
Image: severalnines/proxysql:1.4.12
Ports: 6033/TCP, 6032/TCP
Host Ports: 0/TCP, 0/TCP
Environment: <none>
Mounts:
/etc/proxysql.cnf from proxysql-config (rw)
Volumes:
proxysql-config:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: proxysql-configmap-v2
Optional: false
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: proxysql-769895fbf7 (2/2 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 53s deployment-controller Scaled up replica set proxysql-769895fbf7 to 1
Normal ScalingReplicaSet 46s deployment-controller Scaled down replica set proxysql-95b8d8446 to 1
Normal ScalingReplicaSet 46s deployment-controller Scaled up replica set proxysql-769895fbf7 to 2
Normal ScalingReplicaSet 41s deployment-controller Scaled down replica set proxysql-95b8d8446 to 0
Achten Sie auf den Abschnitt „Volumes“ mit dem neuen ConfigMap-Namen. Sie können auch die Bereitstellungsereignisse unten in der Ausgabe sehen. An diesem Punkt wurde unsere neue Konfiguration in alle ProxySQL-Pods geladen, wo Kubernetes das ProxySQL-ReplicaSet auf 0 herunterskaliert hat (unter Einhaltung der RollingUpdate-Strategie) und sie wieder auf den gewünschten Zustand von 2 Replikaten bringt.
Abschließende Gedanken
Bis zu diesem Punkt haben wir mögliche Bereitstellungsansätze für ProxySQL in Kubernetes behandelt. Das Ausführen von ProxySQL mit Hilfe von Kubernetes ConfigMap eröffnet eine neue Möglichkeit des ProxySQL-Clustering, wobei es sich etwas von der in ProxySQL integrierten nativen Clustering-Unterstützung unterscheidet.
Im kommenden Blogbeitrag werden wir uns mit ProxySQL-Clustering mit Kubernetes ConfigMap und der richtigen Vorgehensweise befassen. Bleiben Sie dran!