statefulset控制器
前言
statefulset控制器用于部署无状态应用,所谓无状态应用简单理解就是各个节点存在主从关系,如ZK集群存在leader、fllower,mysql集群的master和slave,他们各个独立有序运行,有单独的存储,这里存储就要用到前面咱们学习的PV/PVC。
一、statefulset控制器
特点:
- 部署有状态应用(deployment部署都是无状态应用)
- 解决Pod独立生命周期,保持Pod启动顺序和唯一性
- 稳定,唯一的网络标识符,持久存储
- 有序,优雅的部署和扩展、删除和终止
- 有序,滚动更新
应用场景:分布式应用、数据库集群
K8s中实现statefulset控制器两个必备条件,网络和存储
-
稳定的网络ID
使用Headless Service(相比普通Service只是将spec.clusterIP定义为None)来维护Pod网络身份。
并且添加serviceName: "nginx"字段指定StatefulSet控制器要使用这个Headless Service。
DNS解析名称:...svc.cluster.local -
稳定的存储
StatefulSet的存储卷使用VolumeClaimTemplate创建,称为卷申请模板,当StatefulSet使用
VolumeClaimTemplate创建一个PersistentVolume时,同样也会为每个Pod分配并创建一个编号的PVC。
二、示例
# cat statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-statefulset
spec:
selector:
matchLabels:
app: nginx1 # has to match .spec.template.metadata.labels
serviceName: "nginx-svc" # match service
replicas: 2 # by default is 1
template:
metadata:
labels:
app: nginx1 # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www-volume
mountPath: /usr/share/nginx/html
volumeClaimTemplates: # auto pvc
- metadata:
name: www-volume
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "managed-nfs-storage"
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx-svc
spec:
ports:
- port: 80
clusterIP: None # Headless Service
selector:
app: nginx1
# kubectl get pods -w
web-statefulset-0 0/1 ContainerCreating 0 5s
web-statefulset-0 0/1 ContainerCreating 0 10s
web-statefulset-0 1/1 Running 0 12s
web-statefulset-1 0/1 Pending 0 0s
web-statefulset-1 0/1 Pending 0 3s
web-statefulset-1 0/1 ContainerCreating 0 3s
web-statefulset-1 0/1 ContainerCreating 0 4s
web-statefulset-1 1/1 Running 0 6s
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
my-pv 5Gi RWX Retain Bound default/my-pvc 3h44m
pvc-05d4fed1-8b2d-4352-bf62-dc3e26211c24 1Gi RWO Delete Bound default/www-volume-web-statefulset-1 managed-nfs-storage 33s
pvc-968e4f9f-f347-419a-a6c4-292a1871f69a 1Gi RWO Delete Bound default/www-volume-web-statefulset-0 managed-nfs-storage 45s
pvc-b5b27e9a-8741-497f-a1a0-cda57de73421 30Gi RWX Delete Bound default/my-autopvc managed-nfs-storage 172m
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-autopvc Bound pvc-b5b27e9a-8741-497f-a1a0-cda57de73421 30Gi RWX managed-nfs-storage 172m
my-pvc Bound my-pv 5Gi RWX 5h50m
www-volume-web-statefulset-0 Bound pvc-968e4f9f-f347-419a-a6c4-292a1871f69a 1Gi RWO managed-nfs-storage 47s
www-volume-web-statefulset-1 Bound pvc-05d4fed1-8b2d-4352-bf62-dc3e26211c24 1Gi RWO managed-nfs-storage 35s
可以看到,statefulset启动pod会有先后顺序,逐个去启动。
statefuleset不用单独创建pvc,使用"volumeClaimTemplates"
使用nslookup分别对deployment svc以及statefulset svc进行解析,deployment只可以解析到CLUSTER-IP,statefulset可以解析到所有pod
每个pod命名格式为"<statefulsetName-index>.<serviceName>.<namespace>.svc.cluster.local
",这是一个固定名称,所有的连接均可使用该命令。
# nslookup web-service
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-service
Address 1: 10.109.33.190 web-service.default.svc.cluster.local
# nslookup nginx-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-svc
Address 1: 10.244.36.123 web-statefulset-1.nginx-svc.default.svc.cluster.local
Address 2: 10.244.169.180 web-statefulset-0.nginx-svc.default.svc.cluster.local
总结:
StatefulSet与Deployment区别:有身份
身份三要素:
- 域名
- 主机名
- 存储(PVC)
三、示例:consul statefulset
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: consul
spec:
serviceName: consul
replicas: 3
selector:
matchLabels:
k8s-app: consul
template:
metadata:
labels:
k8s-app: consul
spec:
containers:
- name: consul
image: consul:latest
args:
- "agent"
- "-server"
- "-bootstrap-expect=3"
- "-ui"
- "-config-file=/consul/config"
- "-data-dir=/consul/data"
- "-log-file=/consul/log"
- "-bind=0.0.0.0"
- "-client=0.0.0.0"
- "-advertise=$(PODIP)"
- "-retry-join=consul-0.consul.$(NAMESPACE).svc.cluster.local"
- "-retry-join=consul-1.consul.$(NAMESPACE).svc.cluster.local"
- "-retry-join=consul-2.consul.$(NAMESPACE).svc.cluster.local"
- "-domain=cluster.local"
- "-disable-host-node-id"
volumeMounts:
- name: nfs
mountPath: /consul/data
subPathExpr: data/$(PODNAME)
- name: nfs
mountPath: /consul/config
subPathExpr: config/$(PODNAME)
env:
- name: PODIP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: PODNAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- containerPort: 8500
name: ui-port
- containerPort: 8400
name: alt-port
- containerPort: 53
name: udp-port
- containerPort: 8443
name: https-port
- containerPort: 8080
name: http-port
- containerPort: 8301
name: serflan
- containerPort: 8302
name: serfwan
- containerPort: 8600
name: consuldns
- containerPort: 8300
name: server
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfs