深入剖析Kubernetes
张磊
Kubernetes社区资深成员与项目维护者
立即订阅
22715 人已学习
课程目录
已完结 56 讲
0/4登录后,你可以任选4讲全文学习。
课前必读 (5讲)
开篇词 | 打通“容器技术”的任督二脉
免费
01 | 预习篇 · 小鲸鱼大事记(一):初出茅庐
02 | 预习篇 · 小鲸鱼大事记(二):崭露头角
03 | 预习篇 · 小鲸鱼大事记(三):群雄并起
04 | 预习篇 · 小鲸鱼大事记(四):尘埃落定
容器技术概念入门篇 (5讲)
05 | 白话容器基础(一):从进程说开去
06 | 白话容器基础(二):隔离与限制
07 | 白话容器基础(三):深入理解容器镜像
08 | 白话容器基础(四):重新认识Docker容器
09 | 从容器到容器云:谈谈Kubernetes的本质
Kubernetes集群搭建与实践 (3讲)
10 | Kubernetes一键部署利器:kubeadm
11 | 从0到1:搭建一个完整的Kubernetes集群
12 | 牛刀小试:我的第一个容器化应用
容器编排与Kubernetes作业管理 (15讲)
13 | 为什么我们需要Pod?
14 | 深入解析Pod对象(一):基本概念
15 | 深入解析Pod对象(二):使用进阶
16 | 编排其实很简单:谈谈“控制器”模型
17 | 经典PaaS的记忆:作业副本与水平扩展
18 | 深入理解StatefulSet(一):拓扑状态
19 | 深入理解StatefulSet(二):存储状态
20 | 深入理解StatefulSet(三):有状态应用实践
21 | 容器化守护进程的意义:DaemonSet
22 | 撬动离线业务:Job与CronJob
23 | 声明式API与Kubernetes编程范式
24 | 深入解析声明式API(一):API对象的奥秘
25 | 深入解析声明式API(二):编写自定义控制器
26 | 基于角色的权限控制:RBAC
27 | 聪明的微创新:Operator工作原理解读
Kubernetes容器持久化存储 (4讲)
28 | PV、PVC、StorageClass,这些到底在说啥?
29 | PV、PVC体系是不是多此一举?从本地持久化卷谈起
30 | 编写自己的存储插件:FlexVolume与CSI
31 | 容器存储实践:CSI插件编写指南
Kubernetes容器网络 (8讲)
32 | 浅谈容器网络
33 | 深入解析容器跨主机网络
34 | Kubernetes网络模型与CNI网络插件
35 | 解读Kubernetes三层网络方案
36 | 为什么说Kubernetes只有soft multi-tenancy?
37 | 找到容器不容易:Service、DNS与服务发现
38 | 从外界连通Service与Service调试“三板斧”
39 | 谈谈Service与Ingress
Kubernetes作业调度与资源管理 (5讲)
40 | Kubernetes的资源模型与资源管理
41 | 十字路口上的Kubernetes默认调度器
42 | Kubernetes默认调度器调度策略解析
43 | Kubernetes默认调度器的优先级与抢占机制
44 | Kubernetes GPU管理与Device Plugin机制
Kubernetes容器运行时 (3讲)
45 | 幕后英雄:SIG-Node与CRI
46 | 解读 CRI 与 容器运行时
47 | 绝不仅仅是安全:Kata Containers 与 gVisor
Kubernetes容器监控与日志 (3讲)
48 | Prometheus、Metrics Server与Kubernetes监控体系
49 | Custom Metrics: 让Auto Scaling不再“食之无味”
50 | 让日志无处可逃:容器日志收集与管理
再谈开源与社区 (1讲)
51 | 谈谈Kubernetes开源社区和未来走向
答疑文章 (1讲)
52 | 答疑:在问题中解决问题,在思考中产生思考
特别放送 (1讲)
特别放送 | 2019 年,容器技术生态会发生些什么?
结束语 (1讲)
结束语 | Kubernetes:赢开发者赢天下
特别放送 | 云原生应用管理系列 (1讲)
基于 Kubernetes 的云原生应用管理,到底应该怎么做?
深入剖析Kubernetes
登录|注册

18 | 深入理解StatefulSet(一):拓扑状态

张磊 2018-10-03
你好,我是张磊。今天我和你分享的主题是:深入理解 StatefulSet 之拓扑状态。
在上一篇文章中,我在结尾处讨论到了 Deployment 实际上并不足以覆盖所有的应用编排问题。
造成这个问题的根本原因,在于 Deployment 对应用做了一个简单化假设。
它认为,一个应用的所有 Pod,是完全一样的。所以,它们互相之间没有顺序,也无所谓运行在哪台宿主机上。需要的时候,Deployment 就可以通过 Pod 模板创建新的 Pod;不需要的时候,Deployment 就可以“杀掉”任意一个 Pod。
但是,在实际的场景中,并不是所有的应用都可以满足这样的要求。
尤其是分布式应用,它的多个实例之间,往往有依赖关系,比如:主从关系、主备关系。
还有就是数据存储类应用,它的多个实例,往往都会在本地磁盘上保存一份数据。而这些实例一旦被杀掉,即便重建出来,实例与数据之间的对应关系也已经丢失,从而导致应用失败。
所以,这种实例之间有不对等关系,以及实例对外部数据有依赖关系的应用,就被称为“有状态应用”(Stateful Application)。
容器技术诞生后,大家很快发现,它用来封装“无状态应用”(Stateless Application),尤其是 Web 服务,非常好用。但是,一旦你想要用容器运行“有状态应用”,其困难程度就会直线上升。而且,这个问题解决起来,单纯依靠容器技术本身已经无能为力,这也就导致了很长一段时间内,“有状态应用”几乎成了容器技术圈子的“忌讳”,大家一听到这个词,就纷纷摇头。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入剖析Kubernetes》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(66)

  • 我来也
    今天按文章中的内容来, 确实也遇到了nslookup 反馈失败的状况.
    ** server can't find web-0.nginx: NXDOMAIN
    *** Can't find web-0.nginx: No answer
    但是直接ping web-0.nginx 是可以获取真实ip地址的.
    确实是如楼下的同学所说, 需要用 busybox:1.28.4 的镜像. 这个是最新版busybox的问题.
    kubectl run -i --tty --image busybox:1.28.4 dns-test --restart=Never --rm /bin/sh
    这样就可获得期待的结果了.
    我也是google到了 https://github.com/kubernetes/kubernetes/issues/66924 才知道的.
    再看楼下的评论,才发现有其他同学也遇到了,且在几天前已经给出了解决方案. 👍
    新技术确实变化太快了,作者在写文章时用的没问题,也许隔一天因为某个默认镜像修改了,就会出现新的状况.

    作者回复: 看来这个镜像确实有问题

    2018-10-13
    51
  • 千寻
    说dns访问不到那个童鞋,不要用latest标签的busybox,用busybox:1.28.4这个tag的就可以了,我也是这样。

    作者回复: 这咋还跟镜像有关系呢?

    2018-10-09
    19
  • along2018
    创建statefulset必须要先创建一个headless的service?分两步操作?

    作者回复: 对的

    2018-10-08
    1
    12
  • Dillion
    在上面的例子中,web-0、web-1启动后,此时如果web-0挂了,那在创建web-0的过程中,web-1也会被重新创建一次么???也就是如果一个StatefulSet中只有某个Pod挂了,在重启它的时候,如何确保文中说的Pod启动顺序呢??

    作者回复: 任何一次pod的更新都会触发statefulset 滚动更新,更新一定会按编号顺序。但如果只是删除那就直接重建当前pod就够了,这并不破坏拓扑状态。当然,必要的时候,你的pod启动命令要能够区分第一次启动和重启,见下一节。

    2018-10-03
    9
  • 巩夫建
    Headless Service中不通过vip,外部访问的时候,是轮询还是随机还是热备的方式访问到web-0和web-1,dns解析好像没有轮询随机概念吧。

    作者回复: 只能访问到固定的一个pod。所以说headless service不能替代normal service

    2018-10-06
    8
  • 刘欣洲
    访问不到啊
    / # nslookup web-0.nginx
    Server: 10.96.0.10
    Address: 10.96.0.10:53

    ** server can't find web-0.nginx: NXDOMAIN

    *** Can't find web-0.nginx: No answer

    是不是需要DNS插件啊, 该如何启动呢?

    作者回复: dns是默认插件。你按我前面的部署流程、也就是官方的部署流程,是必然有dns的。看看pod列表debug一下吧。

    2018-10-04
    1
    7
  • Lukri
    加上namespace就可以了。
    / # ping web-0.nginx.default.svc.cluster.local
    PING web-0.nginx.default.svc.cluster.local (10.44.0.2): 56 data bytes
    64 bytes from 10.44.0.2: seq=0 ttl=64 time=0.138 ms
    64 bytes from 10.44.0.2: seq=1 ttl=64 time=0.089 ms
    64 bytes from 10.44.0.2: seq=2 ttl=64 time=0.091 ms
    64 bytes from 10.44.0.2: seq=3 ttl=64 time=0.090 ms
    64 bytes from 10.44.0.2: seq=4 ttl=64 time=0.093 ms
    64 bytes from 10.44.0.2: seq=5 ttl=64 time=0.128 ms
    64 bytes from 10.44.0.2: seq=6 ttl=64 time=0.093 ms
    64 bytes from 10.44.0.2: seq=7 ttl=64 time=0.091 ms
    ^C
    --- web-0.nginx.default.svc.cluster.local ping statistics ---
    8 packets transmitted, 8 packets received, 0% packet loss
    round-trip min/avg/max = 0.089/0.101/0.138 ms
    / # nslookup web-0.nginx.default.svc.cluster.local
    Server: 10.96.0.10
    Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

    Name: web-0.nginx.default.svc.cluster.local
    Address 1: 10.44.0.2 web-0.nginx.default.svc.cluster.local
    2018-11-29
    1
    6
  • A-
    service里的dns信息是存在etcd里的嘛?有些应用的pod的域名是自己定义的。而不是k8s创建出来的带有local的域名。我可以更改service里的dns信息嘛?

    作者回复: kubernetes 当然允许你自定义域名了

    2018-10-04
    4
  • fldhmily63319
    我也想问, "Normal Service"和"Headless Service“的应用场景是什么?

    根据文章所说的,”Headless Service不需要分配一个 VIP,而是可以直接以 DNS 记录的方式解析出被代理 Pod 的 IP 地址“,同时由于其编号的严格规定,会按照编号顺序完成创建工作。

    这样是不是说,如果在部署StatefulSet的时候,大部分是推荐使用"Headless Service" ,而不是"Normal Service”呢?

    作者回复: 是,必须用headless service

    2018-10-03
    4
  • Plantegg
    首先busybox镜像的/bin/ 下几百个可执行命令的md5签名都是一样的。不能按照正常的ping、nslookup逻辑来理解了。 也就是md5sum /bin/ping 和 md5sum /bin/nslookup 签名一样,我猜测这个可执行命令都是空架子,会被拦截下来。
    另外就是1.28.4和1.29.3(latest) 的 nslookup 签名也不一样了

    作者回复: busybox就是这么做出来的,正常

    2018-10-18
    3
  • Tim Zhang
    statefulset通过dns访问pod 是否必须要启动dns插件?

    作者回复: kubernetes的dns早就已经是默认安装的了

    2018-10-03
    3
  • bat2man
    说一个我的经验哈:

    环境(一个master, 一个node, coredns)
    1. busybox的版本要控制在1.28.4以下
     kubectl run -i --tty --image busybox:1.28.4 dns-test --restart=Never --rm /bin/sh
    2. 主从节点时间要一致
    3. 从节点拷贝主节点的admin.conf文件到从节点
    4. 重启kubelet docker
    完了之后发现 两天解析不到的dns 竟然成功了 ????
    2019-01-05
    1
    2
  • jssfy
    通过这种方法,Kubernetes 就成功地将 Pod 的拓扑状态(比如:哪个节点先启动,哪个节点后启动),按照 Pod 的“名字 + 编号”的方式固定了下来。
    如上所述,
    1. 是否可以这样理解:sts在这里只是保留了“名字 + 编号”这种网络身份,而不同网络身份对应的pod其实本质上是一样的,都是同一个模板replicate出来的?
    2. 这里sts的主要意义是什么呢:仅仅是保证不同网络身份的启动顺序?

    作者回复: pod镜像是一样,但启动pod的命令和初始化流程可以完全不一样啊。可以参考后面的完整案例

    2018-11-04
    2
  • Tim Zhang
    既然默认有安装dns 为啥还要开启dns插件呢

    作者回复: 因为有太多人是自己拿二进制文件DIY部署的,不按kubeadm的流程来

    2018-10-04
    2
  • Rodinian
    一直很好奇,normal service和headless service都可以指定DNS name。那两者的区别是什么?

    作者回复: service部分会讲解

    2019-05-16
    1
  • Leon📷
    老师,我在busybox查看statefulset的两个容器web-0, web-1,的地址解析
    / # nslookup web-0.nginx.test.svc.cluster.local
    Server: 10.62.45.10
    Address: 10.62.45.10:53

    Name: web-0.nginx.test.svc.cluster.local
    Address: 10.128.31.25

    *** Can't find web-0.nginx.test.svc.cluster.local: No answer

    / # ^C
    / # nslookup web-1.nginx.test.svc.cluster.local
    Server: 10.62.45.10
    Address: 10.62.45.10:53

    Name: web-1.nginx.test.svc.cluster.local
    Address: 10.128.177.140

    *** Can't find web-1.nginx.test.svc.cluster.local: No answer
    这个是到底是解析出来了还是没解析出来啊
    2019-01-24
    1
  • Geek_6bab38
    教程中两个nginx是一块启动:
    如果是有顺序的,比如redis先启动,然后启动在启动nginx这样子,需要怎样设置呢
    2018-12-18
    1
  • Adam
    busybox latest的这个标签确实不能正常解析,改成1.28.4就可以正常解析。怪了。
    2018-12-05
    1
  • IOVE.-Minn
    请问,“有状态的是pv,不是副本控制器,statefulset不用pv创建的pod是无状态”这句话是对的么? 是不是其实statefulset是无状态的,其实是给有状态的服务扩容和伸缩? 那么initcontainer其实只是维护了有状态服务的拓扑状态?

    作者回复: statefulset 还给pod编号了,这就是拓扑状态啊

    2018-10-10
    1
  • huan
    关于nslookup无法解析的问题,debug了下dnspod的log。使用命令 `kubectl logs -f kube-dns-86f4d74b45-28xdg kubedns -n kube-system` 来监视dns pod的log。
    当 `kubectl delete -f svc.yaml` 的时候,会有一个log出现:
    `I1007 14:12:32.818523 1 dns.go:555] Could not find endpoints for service "nginx" in namespace "default". DNS records will be created once endpoints show up.`
    期待这个问题会随着k8s的学习深入得到解决。

    作者回复: service部分讲解可以关注一下

    2018-10-07
    1
收起评论
66
返回
顶部