0x00 前言
Q:有Deployment不就够了吗?StatefulSet 又是什么?
A:Deployment: “无状态”应用√,主从 / 主备关系分布式应用x。
而StatefulSet专注“有状态”(Stateful Application)应用,其不外乎两类状态。
- 拓扑状态:应用的按序创建 / 启动。
- 存储状态:应用内多个实例,与不同存储的关系。
而过程就是:记录状态 —> 重建pod —> 恢复状态。
0x01 Headless Service
What
Q:什么是 Service ?
A:先上定义:
Service 是 Kubernetes 项目中用来将一组 Pod 暴露给外界访问的一种机制。比如,一个 Deployment 有 3 个 Pod,那么我就可以定义一个 Service。然后,用户只要能访问到这个 Service,它就能访问到某个具体的 Pod。
How
Q:如何访问 ?
A:Two ways
- 通过 Service 的 VIP
- 通过 Service 的 DNS 解析记录,有两种处理方法。
- Normal Service直接访问域名获得其 VIP,例如:my-svc.my-namespace.svc.cluster.local
- Headless Service直接查询不同域名获得具体Pod IP。
举个headless的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| $ cat >> svc.yml << EOF apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx EOF
$ kubectl apply -f svc.yml && kubectl get service nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx ClusterIP None <none> 80/TCP 104s
$ cat >> statefulset.yml << EOF apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.9.1 ports: - containerPort: 80 name: web
$ kubectl apply -f statefulset.yml && kubectl get pods -w -l app=nginx NAME READY STATUS RESTARTS AGE web-0 0/1 Pending 0 0s web-0 0/1 Pending 0 0s web-0 0/1 ContainerCreating 0 0s web-0 1/1 Running 0 19s web-1 0/1 Pending 0 0s web-1 0/1 Pending 0 0s web-1 0/1 ContainerCreating 0 0s web-1 1/1 Running 0 20s
$ kubectl get statefulset web NAME READY AGE web 2/2 9m18s
$ kubectl exec web-0 -- sh -c 'hostname' web-0 $ kubectl exec web-1 -- sh -c 'hostname' web-1
$ kubectl run -i --tty --image busybox:1.28.4 dns-test --restart=Never --rm /bin/sh / Server: 10.43.0.10 Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx Address 1: 10.42.3.239 web-0.nginx.default.svc.cluster.local / Server: 10.43.0.10 Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-1.nginx Address 1: 10.42.1.198 web-1.nginx.default.svc.cluster.local
|
Why
Q:有何用?
A:StatefulSet通过原先的顺序(web-0,web-1),名字,重新创造出它们,连解析记录都保持(而非IP结果)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| $ kubectl delete pod -l app=nginx pod "web-0" deleted pod "web-1" deleted
$ kubectl get pod -w -l app=nginx NAME READY STATUS RESTARTS AGE web-1 0/1 Terminating 0 139m web-0 1/1 Running 0 39s web-0 1/1 Terminating 0 42s web-0 0/1 Terminating 0 43s web-0 0/1 Terminating 0 43s web-0 0/1 Terminating 0 43s web-0 0/1 Pending 0 0s web-0 0/1 Pending 0 0s web-0 0/1 ContainerCreating 0 0s web-0 1/1 Running 0 1s web-1 0/1 Terminating 0 140m web-1 0/1 Terminating 0 140m web-1 0/1 Pending 0 0s web-1 0/1 Pending 0 0s web-1 0/1 ContainerCreating 0 0s web-1 1/1 Running 0 1s
If you don't see a command prompt, try pressing enter. / # nslookup web-0.nginx && nslookup web-1.nginx Server: 10.43.0.10 Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx Address 1: 10.42.3.244 web-0.nginx.default.svc.cluster.local Server: 10.43.0.10 Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-1.nginx Address 1: 10.42.1.199 web-1.nginx.default.svc.cluster.local
|
0x02 总结
本文阐述了,在headless Service的场景里,通过StatefulSet的配合,完成对有状态应用的创建,删除,自恢复。这种记录的保存,正是StatefulSet保存有拓扑状态的办法。