前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >有状态的节点控制器 -- StatefulSet 及其网络状态

有状态的节点控制器 -- StatefulSet 及其网络状态

作者头像
用户3147702
发布2022-06-27 17:05:23
8880
发布2022-06-27 17:05:23
举报
文章被收录于专栏:小脑斧科技博客

1. 引言

上一篇文章中,我们详细介绍了 Kubernetes 中的作业副本控制器 Deployment:

详解 K8s 作业副本控制器 Deployment

对于 Deployment 来说,每一种 Pod 都是完全一样的,因此,Deployment 可以按照配置任意增删任何一个 Pod,但在我们的实际场景中,情况并非总是如此,多个实例之间往往会有着复杂的依赖关系,比如主从、主备关系等等。这些情况下,实例之间的地位是不对等的,这样的应用就被称为“有状态应用”。

容器的解决方案是针对无状态应用场景的最佳实践,但对于有状态应用来说,就并非如此了。Kubernetes 用 StatefulSet 解决了有状态应用编排的问题,本文我们就来初步认识一下 StatefulSet。

2. 应用组织的两种状态

StatefulSet 将应用设计抽象为了两种状态:

2.1 拓扑状态

应用存在多个实例,但多个实例地位并不完全对等。

应用的多个实例必须按照某种顺序启动,并且必须成组存在,例如一个应用中必须存在一个 A Pod 和两个 B Pod,且 A Pod 必须先于 B Pod 启动的场景。

2.2 存储状态

应用存在多个实例,但每个实例绑定的存储数据不同,那么对于一个 Pod 来说,无论它是否被重新创建,它读到的数据状态应该是一致的。

3. 实战拓扑状态下的 StatefulSet

一个最简单的场景,我们用一个 nginx Headless Service 反向代理 Kubernetes 中的两个 Pod,并且这两个 Pod 具有不完全对等的网络身份,这个情况下,就是典型的拓扑状态下的 StatefulSet 的使用场景。

3.1 初识 Kubernetes Service

1. 两种访问方式

Kubernetes 的 Service 就是对外提供的可访问服务,它有两种访问方式:

  1. VIP 方式:它是 Virtual IP 的缩写,通过将服务绑定到 Kubernetes 虚拟的 IP 地址,提供给外部调用,通过虚拟 IP 地址隐藏了服务的具体实现与地址。
  2. DNS 方式:与虚拟 IP 地址类似,外部通过访问 DNS 记录的方式实现对具体 Service 的转发。

2. DNS 的两种处理方式

  1. Normal Service:将 DNS 地址绑定到虚拟 IP 地址,从而复用虚拟 IP 地址的设计和逻辑;
  2. Headless Service:将 DNS 地址直接代理到 Pod。

3.2 配置一个 Headless nginx Service

下面的配置文件配置了一个 Headless 方式启动的 nginx Service:

代码语言:javascript
复制
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

这个配置中,clusterIP 设置为了 None,表示不为这个 Service 分配 VIP,而是通过 Headless DNS 的方式来处理该 Service 的调用。

具体的 DNS 地址是这样的:

<pod-name>.<svc-name>.<namespace>.svc.cluster.local

这个 DNS 就是 Kubernetes 为 Pod 分配的唯一可解析身份,这样一来,只要有了 Pod 的名字和 Service 的名字,我们就能唯一确定一个能够访问这个 Pod 的 DNS 地址了。

3.3 配置 StatefulSet

下面,我们就来配置一个使用上述 nginx Service 的 StatefulSet:

代码语言:javascript
复制
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

这个 yaml 与 Deployment 的配置的唯一区别就是多了一个 ServiceName=nginx 的配置,它意味着 StatefulSet 控制器必须在执行控制循环时使用 nginx 这个 Service 来保证每一个 Pod 可解析。

通过 kubectl get 命令就可以查看 pod 的启动:

$ kubectl get statefulset web

通过命令 kubectl get pods -w -l app=nginx 可以看到这些 pod 的启动顺序,每一个 pod 都被命名为了 web-<编号>,比如 web-0 与 web-1,他们是严格按照编号顺次启动的。

如果我们通过 kubectl delete pod -l app=nginx,再通过 kubectl get 观察,就可以看到两个 Pod 删除后,Kubernetes 会按照原先的编号和顺序再次启动一组新的 pod,并且他们各自的网络身份与原 Pod 是一一对应的。

4. 结论

通过上述实践,我们看到,只要我们使用 DNS 记录来访问 StatefulSet 控制器控制下的 Pod,即使 Pod 发生了宕机和重启,DNS 记录对应的 nginx 记录本身是不会发生变化的,同一个“名字-编号”组合的 Pod 在 StatefulSet 中总是稳定地对外提供服务的,进而实现了整个“网络状态”的稳定。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小脑斧科技博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 引言
  • 2. 应用组织的两种状态
    • 2.1 拓扑状态
      • 2.2 存储状态
      • 3. 实战拓扑状态下的 StatefulSet
        • 3.1 初识 Kubernetes Service
          • 1. 两种访问方式
          • 2. DNS 的两种处理方式
        • 3.2 配置一个 Headless nginx Service
          • 3.3 配置 StatefulSet
          • 4. 结论
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档