在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,你的数据仍然会被保留。但是,如果你删除了命名空间,它就会消失。