1.StatefulSet
1.1 概述:
StatefulSet:
- 部署有状态应用
- 解决 Pod 独立生命周期,保持 Pod 启动顺序和唯一性
-- 稳定,唯一的网络标识符,持久存储
-- 有序,优雅的部署和扩展、删除和终止
-- 有序,滚动更新
应用场景:数据库
1.2 稳定的网络 ID
Headless Service
也是一种 service,但不同在于 spec.clusterIP
定义为 None
,也就是不需要 ClusterIP
对比
示例程序
headless.yaml
:
apiVersion: v1 kind: Service metadata: labels: app: web name: hd-service spec: clusterIP: None ports: - port: 80 protocol: TCP targetPort: 80 selector: app: web project: blog
web-dp.yaml
apiVersion: apps/v1 kind: StatefulSet metadata: labels: app: web name: web spec: serviceName: hd-service replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web project: blog spec: containers: - image: nginx name: nginx resources: {}
应用之后发现,程序并非像之前那样并行的去创建 pod,而是顺序创建 pod
测试 dns:
kubectl run -it --rm --image=busybox:1.28.4 sh
在控制台输入 nslookup hd-service
之后会响应三个 pod 的 ip,headless 不需要分配 clusterIP,它是为每个 pod 分配了一个固定的 dns 名称,ping 一下这个 dns 就会访问具体的 pod 的 IP
dns 名称规律
- ClusterIP A 记录格式:
<service-name>.<namespace-name>.svc.cluster.local
- ClusterIP=None A 记录格式:
<statefulsetName-index>.<service-name> .<namespace-name>.svc.cluster.local
示例:web-0.nginx.default.svc.cluster.local
1.3 稳定的存储
StatefulSet
的存储卷使用 VolumeClaimTemplate
创建,
称为卷申请模板,当 StatefulSet
使用 VolumeClaimTemplate
创建一个 PersistentVolume
时,同样也会为每个 Pod 分配并创建一个编号的 PVC。
示例程序:
apiVersion: apps/v1 kind: StatefulSet metadata: labels: app: web name: web spec: serviceName: hd-service replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web project: blog spec: containers: - image: nginx name: nginx volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "managed-nfs-storage" resources: requests: storage: 1Gi
参数解释:
ReadWriteOnce
:单节点读写,因为非数据共享,一个 pod 对应一个 pv
这样就可以保证每个 pod 存储数据的唯一性了
1.4 小结
StatefulSet 与 Deployment 区别:有身份的!
身份三要素:
- 域名
- 主机名
- 存储(PVC)
2.ConfigMap
数据存储在 Etcd 中,让 Pod 中容器以 Volume 或者变量方式访问。
应用场景:应用程序配置
Pod 使用 configmap 两种方式:
- 变量注入——主要适用少的数据,以键值存储
- 数据卷挂载——适用于配置文件
2.1 变量注入
创建一个 configmap
apiVersion: v1 kind: ConfigMap metadata: name: myconfig namespace: default data: special.level: info special.type: hello
创建一个 pod:
apiVersion: v1 kind: Pod metadata: name: mypod-cm spec: containers: - name: busybox image: busybox command: [ "/bin/sh", "-c", "echo $(LEVEL) $(TYPE) $(ABC) $TYPE" ] env: - name: ABC value: "1234567" - name: LEVEL valueFrom: configMapKeyRef: name: myconfig key: special.level - name: TYPE valueFrom: configMapKeyRef: name: myconfig key: special.type restartPolicy: Never
参数解释:
env
:变量,参考
2.2 数据卷挂载
创建一个 redis 的 configmap:
apiVersion: v1 kind: ConfigMap metadata: name: redis-config data: redis.properties: | redis.host=127.0.0.1 redis.port=6379 redis.password=123456
参数解释:
- redis.properties:相当于 redis 的配置文件名称
- |:特殊字符,代表下面的内容为多行数据,作为整体处理
创建 pod 去引用 redis 的 configmap:
apiVersion: v1 kind: Pod metadata: name: mypod-redis spec: containers: - name: nginx image: nginx volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: redis-config restartPolicy: Never
3.Secret
与 ConfigMap 类似,区别在于 Secret 主要存储敏感数据,所有的数据要经过编码。
应用场景:凭据
secret 应用场景:
- docker-registry docker 镜像仓库认证信息
- generic 通用的数据存储
- tls https 证书
3.1 拿 generic
举例,将用户名和密码保存在 k8s 中:
先给用户名和密码进行编码:
echo -n 'admin' | base64 YWRtaW4= echo -n '1f2d1e2e67df' | base64 MWYyZDFlMmU2N2Rm
创建 secret:
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: MWYyZDFlMmU2N2Rm
注意:用户名和密码需要经过 base64 位编码提高安全性。如
echo "123456" | base64
创建 pod:
apiVersion: v1 kind: Pod metadata: name: mypod-secret spec: containers: - name: nginx image: nginx env: - name: SECRET_USERNAME valueFrom: secretKeyRef: name: mysecret key: username - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password # echo $SECRET_USERNAME # echo $SECRET_PASSWORD
参数说明:
env.name
:变量名
编码过后的用户名和密码在注入到 pod 中后会解码
secret 解决了 pod 镜像中的敏感信息问题,将信息放在 secret 中,通过动态的往 pod 中注入的方式提高 pod 的安全性。
数据卷挂载方式
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: nginx image: nginx volumeMounts: - name: foo mountPath: "/etc/foo" readOnly: true volumes: - name: foo secret: secretName: mysecret # cat /etc/foo/username # cat /etc/foo/password
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于