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
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于