k8s 学习笔记 之 statefulset 应用 为何总是pending 状态
k8s pv 和 PVC 为何绑定不上
使用statefuset 部署有状态应用,应用总是处于pending 状态,在开始之前先介绍什么是statefuset, 在 k8s 中一般用 deployment 管理无状态应用,statefuset 用来管理有状态应用,如 redis 、mysql 、zookper 等分布式应用,这些应用的启动停止都会有严格的顺序
一、statefulset
headless (无头服务),没有cluserIP, 资源标识符,用于生成可解析的dns 记录
StatefulSet 用于pod 资源的管理
volumeClaimTemplates 提供存储
二、statefulset 部署
使用nfs 做网络存储
搭建nfs
配置共享存储目录
创建pv
编排 yaml
搭建nfs
yum install nfs-utils -y
mkdir -p /usr/local/k8s/redis/pv{7..12} # 创建挂载目录
cat /etc/exports /usr/local/k8s/redis/pv7 172.16.0.0/16(rw,sync,no_root_squash) /usr/local/k8s/redis/pv8 172.16.0.0/16(rw,sync,no_root_squash) /usr/local/k8s/redis/pv9 172.16.0.0/16(rw,sync,no_root_squash) /usr/local/k8s/redis/pv10 172.16.0.0/16(rw,sync,no_root_squash) /usr/local/k8s/redis/pv11 172.16.0.0/16(rw,sync,no_root_squash exportfs -avr
创建pv
cat nfs_pv2.yaml
apiVersion: v1kind: PersistentVolumemetadata: name: nfs-pv7spec: capacity: storage: 500M accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: slow nfs: server: 172.16.0.59 path: "/usr/local/k8s/redis/pv7"---apiVersion: v1kind: PersistentVolumemetadata: name: nfs-pv8spec: capacity: storage: 500M accessModes: - ReadWriteMany storageClassName: slow persistentVolumeReclaimPolicy: Retain nfs: server: 172.16.0.59 path: "/usr/local/k8s/redis/pv8"---apiVersion: v1kind: PersistentVolumemetadata: name: nfs-pv9spec: capacity: storage: 500M accessModes: - ReadWriteMany storageClassName: slow persistentVolumeReclaimPolicy: Retain nfs: server: 172.16.0.59 path: "/usr/local/k8s/redis/pv9"---apiVersion: v1kind: PersistentVolumemetadata: name: nfs-pv10spec: capacity: storage: 500M accessModes: - ReadWriteMany storageClassName: slow persistentVolumeReclaimPolicy: Retain nfs: server: 172.16.0.59 path: "/usr/local/k8s/redis/pv10"---apiVersion: v1kind: PersistentVolumemetadata: name: nfs-pv11spec: capacity: storage: 500M accessModes: - ReadWriteMany storageClassName: slow persistentVolumeReclaimPolicy: Retain nfs: server: 172.16.0.59 path: "/usr/local/k8s/redis/pv11"---apiVersion: v1kind: PersistentVolumemetadata: name: nfs-pv12spec: capacity: storage: 500M accessModes: - ReadWriteMany storageClassName: slow persistentVolumeReclaimPolicy: Retain nfs: server: 172.16.0.59 path: "/usr/local/k8s/redis/pv12"
kubectl apply -f nfs_pv2.yaml
查看 # 创建成功
编写yaml 编排应用
apiVersion: v1kind: Servicemetadata: name: myapp labels: app: myappspec: ports: - port: 80 name: web clusterIP: None selector: app: myapp-pod---apiVersion: apps/v1kind: StatefulSetmetadata: name: myappspec: serviceName: myapp replicas: 3 selector: matchLabels: app: myapp-pod template: metadata: labels: app: myapp-pod spec: containers: - name: myapp image: ikubernetes/myapp:v1 resources: requests: cpu: "500m" memory: "500Mi" ports: - containerPort: 80 name: web volumeMounts: - name: myappdata mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: myappdata spec: accessModes: ["ReadWriteOnce"] storageClassName: "slow" resources: requests: storage: 400Mi
kubectl create -f new-stateful.yaml
查看headless 创建成功
查看pod 是否创建成功
查看pvc 是否创建成功
pod 启动没有成功,依赖于pvc ,查看pvc 的日志,没有找到对应的pvc,明明写了啊
查看 关联信息,有下面这个属性
storageClassName: "slow"
三、statefulset 排障
pvc 无法创建,导致pod 无法正常启动,yaml 文件重新检查了几遍,
思考的方向:pvc 如何绑定pv ,通过storageClassName 去关联,pv 也创建成功了,也存在storageClassName: slow 这个属性,结果愣是找不到
。。。。
。。。。
后面检查pv 和pvc 的权限是否一直
发现pv 设置的权限
volumeClaimTemplates: 声明的pvc 权限
两边的权限不一致,
操作
删除 pvc kubectl delete pvc myappdata-myapp-0 -n daemon
删除 yaml 文件, kubectl delete -f new-stateful.yaml -n daemon
尝试修改 accessModes: ["ReadWriteMany"]
再次查看
提示:pv 和PVC 设定权限注
四、statefulset 测试,域名解析
kubectl exec -it myapp-0 sh -n daemon
nslookup myapp-0.myapp.daemon.svc.cluster.local
解析的规则 如下
myapp-0 myapp daemon
FQDN: $(podname).(headless server name).namespace.svc.cluster.local
容器里面如没有nsllokup ,需要安装对应的包,busybox 可以提供类似的功能
提供yaml 文件
apiVersion: v1kind: Podmetadata: name: busybox namespace: daemonspec: containers: - name: busybox image: busybox:1.28.4 command: - sleep - "7600" resources: requests: memory: "200Mi" cpu: "250m" imagePullPolicy: IfNotPresent restartPolicy: Never
五、statefulset 的扩缩容
扩容:
Statefulset 资源的扩缩容与Deployment 资源相似,即通过修改副本数,Statefulset 资源的拓展过程,与创建过程类似,应用名称的索引号,依次增加
可使用 kubectl scale
kubectl patch
实践:kubectl scale statefulset myapp --replicas=4
缩容:
缩容只需要将pod 副本数调小
kubectl patch statefulset myapp -p '{"spec":{"replicas":3}}' -n daemon
提示:资源扩缩容,需要动态创建pv 与pvc 的绑定关系,这里使用的是nfs 做持久化存储,pv 的多少是预先创建的
六、statefulset 的滚动更新
滚动更新
金丝雀发布
滚动更新
滚动更新 是从索引pod 号最大的开始的,终止完一个资源,在进行开始下一个pod ,滚动更新是 statefulset 默认的更新策略
kubectl set image statefulset/myapp myapp=ikubernetes/myapp:v2 -n daemon
升级过程
查看pod 状态
kubectl get pods -n daemon
查看升级后镜像是否更新
kubectl describe pod myapp-0 -n daemon