StatefulSet

上一篇文章介绍了Deployment,在Deployment处理的编排问题中,有这样一个问题,在Deployment面前,所有的pod都是一样的,但是在实际的生产环境中,pod的启动顺序、作用等都是不一样的(主从关系、主备关系),因此,就需要StatefulSet(有状态
应用)

StatefulSet 的设计其实非常容易理解。它把真实世界里的应用状态,抽象为了两种情况:

  • 拓扑状态。这种情况意味着,应用的多个实例之间不是完全对等的关系。这些应用实例,必须按照某些顺序启动,比如应用的主节点 A 要先于从节点 B 启动。而如果你把 A 和 B 两个Pod 删除掉,它们再次被创建出来时也必须严格按照这个顺序才行。并且,新创建出来的Pod,必须和原来 Pod 的网络标识一样,这样原先的访问者才能使用同样的方法,访问到这个新 Pod。
  • 存储状态。这种情况意味着,应用的多个实例分别绑定了不同的存储数据。对于这些应用实例来说,Pod A 第一次读取到的数据,和隔了十分钟之后再次读取到的数据,应该是同一份,哪怕在此期间 Pod A 被重新创建过。这种情况最典型的例子,就是一个数据库应用的多个存储实例。

所以,StatefulSet 的核心功能,就是通过某种方式记录这些状态,然后在 Pod 被重新创建时,能够为新 Pod 恢复这些状态

Headless Service

Service 是 Kubernetes 项目中用来将一组 Pod 暴露给外界访问的一种机制(在我看来,把他当作为反向代理的架构更容易理解)

访问service的方式

  • 是以 Service 的 VIP(Virtual IP,即:虚拟 IP)方式。比如:当我访问 10.0.23.1,这个 Service 的 IP 地址时,10.0.23.1 其实就是一个 VIP,它会把请求转发到该 Service 所代理的某一个 Pod 上。
  • 是以 Service 的 DNS 方式。比如:这时候,只要我访问“my-svc.my�namespace.svc.cluster.local”这条 DNS 记录,就可以访问到名叫 my-svc 的 Service 所代理的某一个 Pod

而在Service DNS的方式下,还会有两种处理方式

  • Normal Service。这种情况下,你访问“my-svc.my�namespace.svc.cluster.local”解析到的,正是 my-svc 这个 Service 的 VIP,后面的流程就跟VIP 方式一致了。
  • Headless Service。这种情况下,你访问“my-svc.my�namespace.svc.cluster.local”解析到的,直接就是 my-svc 代理的某一个 Pod 的 IP 地址。可以看到,这里的区别在于,Headless Service 不需要分配一个 VIP,而是可以直接以 DNS 记录的方式解析出被代理 Pod 的 IP 地址

实例:

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

当你按照这样的方式创建了一个 Headless Service 之后,它所代理的所有 Pod 的 IP 地址,都
会被绑定一个这样格式的 DNS 记录

<pod-name>.<svc-name>.<namespace>.svc.cluster.loc
#这个 DNS 记录,正是 Kubernetes 项目为 Pod 分配的唯一的“可解析身份”
#查看创建的service的状态
[root@k8s-master pods]# kubectl get service nginx 
NAME    TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   None         <none>        80/TCP    26h

#查看创建的pods的状态
[root@k8s-master pods]# kubectl get statefulsets.apps web
NAME   READY   AGE
web    2/2     26h
#确定容器的主机名
[root@k8s-master pods]# kubectl exec web-0 -- sh -c 'hostname '
web-0
[root@k8s-master pods]# kubectl exec web-1 -- sh -c 'hostname '
web-1
#创建一个一次性容器(最新般的busybox会出现无法解析的问题)
kubectl run -i --tty --image busybox:1.28.4 dns-test --restart=Never --rm /bin/sh

/ # nslookup web-0.nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx
Address 1: 10.100.4.119 web-0.nginx.default.svc.cluster.local
#另启一个终端
[root@k8s-master pods]# kubectl  get pods -w -l app=nginx
#之前的终端,退出容器
kubectl delete pod -l app=nginx

#切换到新建的终端,观察输出:
[root@k8s-master pods]# kubectl  get pods -w -l app=nginx
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   1          25h
web-1   1/1     Running   1          25h
web-0   1/1     Terminating   1          26h
web-1   1/1     Terminating   1          26h
web-0   0/1     Terminating   1          26h
web-1   0/1     Terminating   1          26h
web-1   0/1     Terminating   1          26h
web-0   0/1     Terminating   1          26h
web-0   0/1     Terminating   1          26h
web-0   0/1     Terminating   1          26h
web-0   0/1     Pending       0          0s
web-0   0/1     Pending       0          0s
web-0   0/1     ContainerCreating   0          1s
web-0   0/1     ContainerCreating   0          2s
web-0   1/1     Running             0          3s
web-1   0/1     Terminating         1          26h
web-1   0/1     Terminating         1          26h
web-1   0/1     Pending             0          0s
web-1   0/1     Pending             0          0s
web-1   0/1     ContainerCreating   0          0s
web-1   0/1     ContainerCreating   0          1s
web-1   1/1     Running             0          2s

再次使用一次性容器,查看DNS解析的结果,发现没有变化

kubectl run -i --tty --image busybox:1.28.4 dns-test --restart=Never --rm /bin/sh

/ # nslookup web-0.nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx
Address 1: 10.100.4.119 web-0.nginx.default.svc.cluster.local

可以看到,当我们把这两个 Pod 删除之后,Kubernetes 会按照原先编号的顺序,创建出了两
个新的 Pod。并且,Kubernetes 依然为它们分配了与原来相同的“网络身份”:web-0.nginx
和 web-1.nginx。通过这种严格的对应规则,StatefulSet 就保证了 Pod 网络标识的稳定性。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339