使用Kubernetes StatefulSet来持久保存MySQL数据的指南

377 阅读1分钟

在Kubernetes中,如果你想为你的Pod提供持久性,你可以使用一个StatefulSet。与部署不同的是,StatefulSet可以保持其每个Pod的身份,这对于有状态的应用程序来说是非常理想的。StatefulSet需要一个无头服务来负责Pods的身份。

它倾向于用于单实例应用程序,因为底层的PersistentVolume只能被挂载到一个Pod。如果你不介意在开发、测试或QA等环境中的数据丢失,你可以使用它。避免在生产中使用它,因为它是有意义的。在生产环境中,应尽量选择基于云的存储。

配置

apiVersion: v1
kind: Namespace
metadata:
  name: storage

---

apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: storage
  labels:
    app: mysql
spec:
  clusterIP: None
  selector:
    app: mysql
  ports:
    - name: tcp
      protocol: TCP
      port: 3306

---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: storage
spec:
  replicas: 1
  serviceName: mysql
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: mysql
          image: mysql:5.6
          ports:
            - name: tpc
              protocol: TCP
              containerPort: 3306
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: password
          volumeMounts:
            - name: data
              mountPath: /var/lib/mysql
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        storageClassName: standard
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi

设置

运行$ kubectl apply -f mysql.yaml 命令来设置上述配置,结果应该如下:

$ kubectl -n storage get all
NAME          READY   STATUS    RESTARTS   AGE
pod/mysql-0   1/1     Running   0          11s

NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
service/mysql   ClusterIP   None                 3306/TCP   11s

NAME                     READY   AGE
statefulset.apps/mysql   1/1     11s

测试

运行$ kubectl -n storage port-forward service/mysql 3306:3306 命令,将MySQL服务暴露在本地环境中。我在MySQL中创建了一个数据库,并向其添加了三条记录。它看起来像下面这样:

$ kubectl -n storage exec -it pod/mysql-0 -c mysql bash

root@mysql-0:/# mysql -uroot -ppassword

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| inanzzz            |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)

mysql> USE inanzzz;
Database changed

mysql> SHOW TABLES;
+-------------------+
| Tables_in_inanzzz |
+-------------------+
| users             |
+-------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM users;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
+----+
3 rows in set (0.00 sec)

如果你删除了pod、service和statefulset,你的数据仍然会被保留。但是,如果你删除了命名空间,它就会消失。