• 深入剖析Kubernetes学习笔记:StatefulSet(18)


    一、StatefulSet

    1、什么是StatefulSet?

    2、StatefulSet设计

    1、拓扑状态

    2、存储状态

    3、StatefulSet 的核心功能

     

    二、Headless Service

    1、什么是Headless Service?

    2、Headless Service如何被访问?

    1、以 Service 的 VIP方式

    2、以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 地址。

    3、两种访问方式的区别

     

    4、那么,这样的设计又有什么作用呢?

    想要回答这个问题,我们需要从 Headless Service 的定义方式看起。

    下面是一个标准的 Headless Service 对应的 YAML 文件:

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      ports:
      - port: 80
        name: web
      clusterIP: None
      selector:
        app: nginx
    

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

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

    这个 DNS 记录,正是 Kubernetes 项目为 Pod 分配的唯一的“可解析身份”(Resolvable Identity)。

    有了这个“可解析身份”,只要你知道了一个 Pod 的名字,以及它对应的 Service 的名字,你就可以非常确定地通过这条 DNS 记录访问到 Pod 的 IP 地址。

    三、StatefulSet 又是如何使用这个 DNS 记录来维持 Pod 的拓扑状态的呢?

    1、可解析身份

    为了回答这个问题,现在我们就来编写一个 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
    

     注意事项

    $ kubectl create -f svc.yaml
    $ kubectl get service nginx
    NAME      TYPE         CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    nginx     ClusterIP    None         <none>        80/TCP    10s
     
    $ kubectl create -f statefulset.yaml
    $ kubectl get statefulset web
    NAME      DESIRED   CURRENT   AGE
    web       2         1         19s
    

    备注:如果手不够快的话,Pod 很快就创建完了。不过,你依然可以通过这个 StatefulSet 的 Events 看到这些信息。

    $ 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

    四、编号规则

    1、编码规则是

    通过上面这个 Pod 的创建过程,我们不难看到,StatefulSet 给它所管理的所有 Pod 的名字,进行了编号,编号规则是:-。

     比如

    我们使用 kubectl exec 命令进入到容器中查看它们的 hostname:

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

    2、以 DNS 的方式,访问一下这个 Headless Service:

    可以看到,这两个 Pod 的 hostname 与 Pod 名字是一致的,都被分配了对应的编号。接下来,我们再试着以 DNS 的方式,访问一下这个 Headless Service:

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

    $ kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
    $ nslookup web-0.nginx
    Server:    10.0.0.10
    Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
     
    Name:      web-0.nginx
    Address 1: 10.244.1.7
     
    $ nslookup web-1.nginx
    Server:    10.0.0.10
    Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
     
    Name:      web-1.nginx
    Address 1: 10.244.2.7
    

    nslookup 输出结果

    这时候,如果你在另外一个 Terminal 里把这两个“有状态应用”的 Pod 删掉

    $ kubectl delete pod -l app=nginx
    pod "web-0" deleted
    pod "web-1" deleted
    

    3、会发现一个有趣的现象:

    然后,再在当前 Terminal 里 Watch 一下这两个 Pod 的状态变化,就会发现一个有趣的现象:

    $ kubectl get pod -w -l app=nginx
    NAME      READY     STATUS              RESTARTS   AGE
    web-0     0/1       ContainerCreating   0          0s
    NAME      READY     STATUS    RESTARTS   AGE
    web-0     1/1       Running   0          2s
    web-1     0/1       Pending   0         0s
    web-1     0/1       ContainerCreating   0         0s
    web-1     1/1       Running   0         32s

    可以看到 

    4、StatefulSet 如何保证 Pod 网络标识的稳定性

     所以,如果我们再用 nslookup 命令,查看一下这个新 Pod 对应的 Headless Service 的话:

    $ kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh 
    $ nslookup web-0.nginx
    Server:    10.0.0.10
    Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
     
    Name:      web-0.nginx
    Address 1: 10.244.1.8
     
    $ nslookup web-1.nginx
    Server:    10.0.0.10
    Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
     
    Name:      web-1.nginx
    Address 1: 10.244.2.8
    

    1、按照 Pod 的“名字 + 编号”的方式固定了下来

     2、固定并且唯一的访问入口

     3、“有状态应用”实例的访问

    五、小结

    1、用一句话总结

    2、Headless Service

    实际上,在部署“有状态应用”的时候,应用的每个实例拥有唯一并且稳定的“网络标识”,是一个非常重要的假设。

  • 相关阅读:
    Excel 相对引用与绝对引用
    SQL Update 巧用
    Delphi 多步操作产生错误,请检查每一步的状态值
    cxGrid 增加序号 (非数据库绑定模式) (测试通过)
    delphi cxgrid 使用方法
    如何使满足条件的数据显示不同的颜色
    Delphi中Format与FormatDateTime函数详解
    常用的日期时间函数
    100m和1000m网线的常见制作方法
    基于请求的分布式互斥算法
  • 原文地址:https://www.cnblogs.com/luoahong/p/12421443.html
Copyright © 2020-2023  润新知