1.1 Statefulset 控制器:概念、原理解读
StatefulSet 是为了管理有状态服务的问题而设计的
扩展:
有状态服务?
StatefulSet 是有状态的集合,管理有状态的服务,它所管理的 Pod 的名称不能随意变化。数据
持久化的目录也是不一样,每一个 Pod 都有自己独有的数据持久化存储目录。比如 MySQL 主从、redis 集群等。
无状态服务?
RC、Deployment、DaemonSet 都是管理无状态的服务,它们所管理的 Pod 的 IP、名字,启
停顺序等都是随机的。个体对整体无影响,所有 pod 都是共用一个数据卷的,部署的 tomcat 就
是无状态的服务,tomcat 被删除,在启动一个新的 tomcat,加入到集群即可,跟 tomcat 的名字无关。
StatefulSet 由以下几个部分组成:
1. Headless Service:用来定义 pod 网路标识,生成可解析的 DNS 记录
2. volumeClaimTemplates:存储卷申请模板,创建 pvc,指定 pvc 名称大小,自动创建pvc,且 pvc 由存储类供应。
3. StatefulSet:管理 pod 的
扩展:什么是 Headless service?
Headless service 不分配 clusterIP,headless service 可以通过解析 service 的 DNS,返回所
有 Pod 的 dns 和 ip 地址 (statefulSet 部署的 Pod 才有 DNS),普通的 service,只能通过解析
service 的 DNS 返回 service 的 ClusterIP。
为什么要用 headless service(没有 service ip 的 service)?
在使用 Deployment 时,创建的 Pod 名称是没有顺序的,是随机字符串,在用 statefulset 管理
pod 时要求 pod 名称必须是有序的 ,每一个 pod 不能被随意取代,pod 重建后 pod 名称还是
一样的。因为 pod IP 是变化的,所以要用 Pod 名称来识别。pod 名称是 pod 唯一性的标识符,
必须持久稳定有效。这时候要用到无头服务,它可以给每个 Pod 一个唯一的名称。
1.headless service 会为 service 分配一个域名
<service name>.$<namespace name>.svc.cluster.local
K8s 中资源的全局 FQDN 格式:
Service_NAME.NameSpace_NAME.Domain.LTD.
Domain.LTD.=svc.cluster.local. #这是默认 k8s 集群的域名。
FQDN 全称 Fully Qualified Domain Name
即全限定域名:同时带有主机名和域名的名称
FQDN = Hostname + DomainName
如 主机名是 xks
域名是 baidu.com
FQDN= xks.baidu.com
2.StatefulSet 会为关联的 Pod 保持一个不变的 Pod Name
statefulset 中 Pod 的名字格式为$(StatefulSet name)-$(pod 序号)
3.StatefulSet 会为关联的 Pod 分配一个 dnsName
$<Pod Name>.$<service name>.$<namespace name>.svc.cluster.local
Statefulset 使用案例:部署 web 站点
#创建存储类
[root@xksmaster1~]# cat class-web.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-web
provisioner: example.com/nfs
#更新资源清单文件
[root@xksmaster1~]# kubectl apply -f class-web.yaml
[root@xksmaster1 07_Statefulset]# cat statefulset.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "nfs-web"
resources:
requests:
storage: 1Gi
[root@xksmaster1 07_Statefulset]# kubectl apply -f statefulset.yaml
service/nginx unchanged
statefulset.apps/web configured
[root@xksmaster1 07_Statefulset]# kubectl get statefulset
NAME READY AGE
web 2/2 8m58s
[root@xksmaster1 07_Statefulset]# kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 9m5s
web-1 1/1 Running 0 6m
You have new mail in /var/spool/mail/root
[root@xksmaster1 07_Statefulset]# # kubectl get svc -l app=nginx
[root@xksmaster1 07_Statefulset]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound pvc-77c56220-a0c6-4501-9684-e9bca1499c6d 1Gi RWO nfs-web 18m
www-web-1 Bound pvc-6018ee74-bf44-450e-b3d2-7683f58a6932 1Gi RWO nfs-web 7m3s
You have new mail in /var/spool/mail/root
[root@xksmaster1 07_Statefulset]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-6018ee74-bf44-450e-b3d2-7683f58a6932 1Gi RWO Delete Bound default/www-web-1 nfs-web 7m10s
pvc-77c56220-a0c6-4501-9684-e9bca1499c6d 1Gi RWO Delete Bound default/www-web-0 nfs-web 10m
[root@xksmaster1 07_Statefulset]#
[root@xksmaster1 07_Statefulset]# for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname';done
web-0
web-1
[root@xksmaster1 07_Statefulset]# kubectl exec -it web-1 -- /bin/bash