kubernetes 配置示例 - StatefulSet

Deployment 应用于无状态的应用,即它认为所有 Pod 是完全一样的。所以它们之间没有顺序。但对于一些应用,尤其是分布式应用, 它的多个实例之间有依赖关系。比如:主从关系。这种实例之间有不对等关系(拓扑状态),以及实例对外部数据有依赖关系(存储状态)的应用,就称为有状态的应用。

Service 是 Kubernetes 项目中用来将一组 Pod 暴露给外界访问的一种机制。这个 Service 的访问方式有以下3种:

(1) 虚拟IP(VIP)的方式。

(2)NDS 方式。比如: 只要访问 my-svc.my-namespace.svc.cluster.local 就可以访问名叫 my-svc 所代理的某一个 pod。具体又分为两种处理方法

     (a) Normal Service 。 此种方式,当访问 my-svc.my-namespace.svc.cluster.local 时,其实就是访问 my-svc 这个 service 的 VIP。

     (b) Headless Service。 当访问 my-svc.my-namespace.svc.cluster.local 时,解析到的直接就是 my-svc 某一个 Pod 的 IP 地址。区别在于,Headless Service 不需要分配一个 VIP,而是可以直接以 DNS 记录的方式解析出被代理 Pod 的 IP 地址。

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None  # 表明是 headless Service
  selector:
    app: nginx

 

StatefulSet 的 yaml 文件

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
          

这里的 serviceName=nginx 的作用就是告诉 StatefulSet 控制器,在执行控制循环时请使用 Nginx 这个 Headless Service 来保证 Pod 可解析。先创建上面的 headless service,然后再创建 statefulSet。运行如下的命令:

kubectl get pods -w -l app=nginx

上面的命令输入够快的话,可以看到 web-0 的容器变为 ready 之前, web-1 会一直处于 Pending 状态(有些版本可能都看不到 web-1)。我们进入容器,可以看到 pod 的 hostname 就是 pod 的名字

kubectl exec web-0 -- sh -c 'hostname'

我们用下面的命令把这两个 Pod 删除后,kubernetes 会按照原先的编号的顺序重新创建出两个 Pod,并且分配了与原来相同的网络身份。

kubectl delete pod -l app=nginx

这种严格的对应规则,StatefulSet 就保证了 Pod 网络标识的稳定性。

posted @ 2022-01-19 09:08  一剑侵心  阅读(82)  评论(0编辑  收藏  举报