为了管理有状态的服务而存在(有顺序号的Pod)
有状态服务StatefulSet是有状态的集合,管理有状态的服务,它所管理的Pod的名称不能随意变化。数据持久化的目录也是不一样,每一个Pod都有自己独有的数据持久化存储目录。比如MySQL主从、redis集群等。
无状态服务RC、Deployment、DaemonSet都是管理无状态的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的。个体对整体无影响,所有pod都是共用一个数据卷的,部署的tomcat就是无状态的服务,tomcat被删除,在启动一个新的tomcat,加入到集群即可,跟tomcat的名字无关。
Headless Service用来定义pod网路标识,生成可解析的DNS记录。
在用statefulset管理pod时要求pod名称必须是有序的 ,每一个pod不能被随意取代,pod重建后pod名称还是一样的。
因为pod IP是变化的,所以要用Pod名称来识别,pod名称是pod唯一性的标识符,必须持久稳定有效。这时候要用到无头服务,它可以给每个Pod一个唯一的名称。
Headless service不分配clusterIP,headless service可以通过解析service的DNS,返回所有Pod的dns和ip地址 (statefulSet部署的Pod才有DNS),普通的service,只能通过解析service的DNS返回service的ClusterIP。
# 1.headless service会为service分配一个域名.$ .svc.cluster.local # 2.StatefulSet会为关联的Pod保持一个不变的Pod Name Pod的名字格式为$(StatefulSet name)-$(pod序号) # 3.StatefulSet会为关联的Pod分配一个dnsName $ .$ .$ .svc.cluster.local
## 【扩展】全质量域名:FQDN Fully Qualified Domain Name 即全限定域名:同时带有主机名和域名的名称 FQDN = Hostname + DomainName 如 主机名是 master 域名是 baidu.com FQDN= master.baidu.com ## K8s中资源的全局FQDN格式: Service_NAME.NameSpace_NAME.Domain.LTD. Domain.LTD.=svc.cluster.localVolumeClaimTemplate
有状态应用的持久化存储模板,有状态应用要求主从机器的持久化存储卷不能够是共享的(独立存储空间)。
statefulset定义中的每一个pod都不能使用同一个存储卷,这就需要使用volumeClainTemplate,当在使用statefulset创建pod时,volumeClainTemplate会自动生成一个PVC,从而请求绑定一个PV,每一个pod都有自己专用的存储卷。
资源清单解释# kubectl explain statefulset.spec podManagementPolicy示例#pod管理策略 replicas #副本数 revisionHistoryLimit #保留的历史版本 selector
# 【1】创建存储类 vim statefulset-class.yaml kubectl apply -f statefulset-class.yaml kubectl get sc # 【2】创建service和deploy vim statefulset-test-myapp.yaml kubectl apply -f statefulset-test-myapp.yaml ## 查看结果 # kubectl get statefulset NAME READY AGE web 0/2 105s # kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1443/TCP 4d4h nginx ClusterIP None 80/TCP 2m12s # kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-0 1/1 Running 0 12m 10.244.30.104 worker02 web-1 1/1 Running 0 12m 10.244.30.105 worker02 # kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE www-web-0 Bound pvc-2c9fe659-2b05-45ab-ae04-d438b0fc8579 50M RWO nfs-web 29s # kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-2c9fe659-2b05-45ab-ae04-d438b0fc8579 50M RWO Delete Bound default/www-web-0 nfs-web 27s #查看pod主机名 for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname';done
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-web provisioner: example.com/nfs
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
## 通过对pod主机名执行nslookup,可以检查它们在集群内部的DNS地址 kubectl exec -it web-1 -- /bin/bash apt-get update apt-get install dnsutils -y ## 解析Pod的IP (展示Pod的IP) nslookup web-0.nginx.default.svc.cluster.local Server: 10.96.0.10 Address: 10.96.0.10#53 Name: web-0.nginx.default.svc.cluster.local Address: 10.244.30.104 ## 解析Service的IP(会把绑定的Pod的IP解析出来) nslookup nginx.default.svc.cluster.local Server: 10.96.0.10 Address: 10.96.0.10#53 Name: nginx.default.svc.cluster.local Address: 10.244.30.105 Name: nginx.default.svc.cluster.local Address: 10.244.30.104 ## 查看详细信息 dig -t A nginx.default.svc.cluster.local @10.96.0.10
## 【扩展-1】dig的使用 dig -t A nginx.default.svc.cluster.local @10.96.0.10 格式如下: @来指定域名服务器 A 为解析类型 ,A记录 -t 指定要解析的类型 A记录: A记录是解析域名到IP
## 【扩展-2】service 和headless service区别 vim deploy-service.yaml kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE springboot NodePort 10.111.145.2118081:31180/TCP 3d5h # 进入到web-1的pod kubectl exec -it web-1 -- /bin/bash # 解析的是service的ip地址 nslookup my-nginx.default.svc.cluster.local Name: springboot.default.svc.cluster.local Address 1: 10.111.145.211 springboot.default.svc.cluster.local
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
type: ClusterIP
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: busybox
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
command:
- sleep
- "3600"
字段详述
apiVersion: v1 #定义api版本
kind: Service #定义要创建的资源:service
metadata:
name: nginx #定义service的名字
labels:
app: nginx #service的标签
spec:
ports:
- port: 80
name: web
clusterIP: None #创建一个没有ip的service
selector:
app: nginx #选择拥有app=nginx标签的pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx" #headless service的名字
replicas: 2 #副本数
template: #定义pod的模板
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates: #存储卷申请模板
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "nfs-web" #指定从哪个存储类申请pv
resources:
requests:
storage: 1Gi #需要1G的pvc,会自动跟符合条件的pv绑定
动态扩缩容、滚动更新
基本同deployment一致
### 修改replicas 和 image字段 ## 方式一:编辑本地的yaml文件 vimkubectl apply -f ## 方式二:直接编辑statefulset资源 kubectl edit sts ## 查看 kubectl get pods -o wide kubectl describe pods web-0



