zoukankan      html  css  js  c++  java
  • 深入剖析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

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

  • 相关阅读:
    Windows Server 2012配置开机启动项
    Windows Server 2019 SSH Server
    NOIP2017 senior A 模拟赛 7.7 T1 棋盘
    Noip 2015 senior 复赛 Day2 子串
    Noip 2015 senior复赛 题解
    Noip 2014 senior Day2 解方程(equation)
    Noip 2014 senior Day2 寻找道路(road)
    Noip 2014 senior Day2 无线网络发射器选址(wireless)
    Noip2014senior复赛 飞扬的小鸟
    Noip 2014 senior 复赛 联合权值(link)
  • 原文地址:https://www.cnblogs.com/luoahong/p/12421443.html
Copyright © 2011-2022 走看看