• 第十三章 kubernetes 核心技术Namespace和服务探针


    一、Namespace 概述

    Namespace 在很多情况下用于实现多用户的资源隔离,通过将集群内部的资源对象分配到不同的 Namespace 中, 形成逻辑上的分组,便于不同的分组在共享使用整个集群的资源同时还能被分别管理。Kubernetes 集群在启动后,会创建一个名为"default"的 Namespace, 如果不特别指明 Namespace,则用户创建的 Pod,RC,Service 都将 被系统 创建到这个默认的名为 default 的 Namespace 中。
    
    大多数的Kubernetes中的集群默认会有一个叫default的namespace。实际上,应该是3个:
    
    default:你的service和app默认被创建于此。
    kube-system:kubernetes系统组件使用。
    kube-public:公共资源使用。但实际上现在并不常用。
    
    这个默认(default)的namespace并没什么特别,但你不能删除它。这很适合刚刚开始使用kubernetes和一些小的产品系统。但不建议应用于大型生产系统。因为,这种复杂系统中,团队会非常容易意外地或者无意识地重写或者中断其他服务service。相反,请创建多个命名空间来把你的服务service分割成更容易管理的块。
    

    二、创建Namespace

    #1.创建名称空间development的yaml文件
    [root@kubernetes-master-001 ~]# vi nsdemo.yaml 
    apiVersion: v1
    kind: Namespace
    metadata:
      name: development
    
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
      namespace: development
    spec:
      containers:
      - name: mypod
        image: nginx
      
    #2.创建名称空间development
    [root@kubernetes-master-001 ~]# kubectl  apply  -f nsdemo.yaml 
    namespace/development created
    pod/mypod created
    
    #3.查询验证
    [root@kubernetes-master-001 ~]# kubectl  get  pods -n development 
    NAME    READY   STATUS    RESTARTS   AGE
    mypod   1/1     Running   0          59s
    

    三、服务探针概述

    对线上业务来说,保证服务的正常稳定是重中之重,对故障服务的及时处理避免影响业务以及快速恢复一直是开发运维的难点。Kubernetes提供了健康检查服务,对于检测到故障服务会被及时自动下线,以及通过重启服务的方式使服务自动恢复。
    
    K8s 中存在两种类型的探针:liveness probe 和 readiness probe。
    

    四、服务探针作用

    #1.保证pod中的容器正常启动
    
    #2.保证pod中容器能够正常对外提供服务
    
    综合下来就一句话:只有容器启动了并且能够正常对外提供服务了,才能放到负载均衡上供给用户访问
    

    1.每类探针都支持三种探测方法

    #1.exec:通过执行命令来检查服务是否正常,针对复杂检测或无 HTTP 接口的服务,命令返回值为 0 则表示容器健康。
    #2.httpGet:通过发送 http 请求检查服务是否正常,返回 200-399 状态码则表明容器健康。
    #3.tcpSocket:通过容器的 IP 和 Port 执行 TCP 检查,如果能够建立 TCP 连接,则表明容器健康。
    

    2.探针探测的结果

    #1.Success:Container 通过了检查。
    #2.Failure:Container 未通过检查。
    #3.Unknown:未能执行检查,因此不采取任何措施。
    

    3.Pod 重启策略

    #1.Always: 总是重启
    #2.OnFailure: 如果失败就重启
    #3.Never: 永远不重启
    

    4.探针参数详解

    apiVersion: v1 
    kind: Pod
    metadata:
      name: goproxy labels:
      app: goproxy
    spec:
      containers:
      - name: goproxy
        image: k8s.gcr.io/goproxy:0.1
        ports:
        - containerPort: 8080
        readinessProbe:
          tcpSocket:
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 20
          
    探针(Probe)有许多可选字段,可以用来更加精确的控制 Liveness 和 Readiness 两种探针的行为。这些参数包括:
    initialDelaySeconds:容器启动后第一次执行探测是需要等待多少秒。
    periodSeconds:执行探测的频率。默认是 10 秒,最小 1 秒。
    timeoutSeconds:探测超时时间。默认 1 秒,最小 1 秒。
    successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1。对于 liveness 必须是 1。最小值是 1。
    failureThreshold:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3。最小值是 1。
    

    五、存活性探测Liveness Probe

    用于判断容器是否存活,即 Pod 是否为 running 状态,如果 LivenessProbe 探针探测到容器不健康,则 kubelet 将 kill 掉容器,并根据容器的重启策略是否重启。如果一个容器不包含 LivenessProbe 探针,则 Kubelet 认为容器的 LivenessProbe 探针的返回值永远成功。有时应用程序可能因为某些原因(后端服务故障等)导致暂时无法对外提供服务,但应用 软件没有终止,导致 K8S 无法隔离有故障的 pod,调用者可能会访问到有故障的 pod,导致业务不稳定。K8S 提供 livenessProbe 来检测应用程序是否正常运行,并且对相应状况进 行相应的补救措施。存活性探测支持的方法有三种:ExecAction,TCPSocketAction,HTTPGetAction。
    

    1.Exec

    [root@kubernetes-master-001 ~]# vi live-exec.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: probe-exec
      namespace: default
    spec:
      containers:
        - name: nginx
          image: nginx
          livenessProbe:
            exec:
              command:
                - cat
                - /tmp/health    
            initialDelaySeconds: 5
            timeoutSeconds: 1
    
    [root@kubernetes-master-001 ~]# kubectl apply -f live-exec.yaml
    pod/probe-exec created
    [root@kubernetes-master-001 ~]# kubectl  get pods -o wide -w
    NAME                                            READY   STATUS    RESTARTS   AGE     IP               NODE                    NOMINATED NODE   READINESS GATES
    probe-exec                                      1/1     Running   0          46s     10.244.1.103     kubernetes-node-002     <none>           <none>
    

    2.TCPSocket

    [root@kubernetes-master-001 ~]# vi live-tcp.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: probe-tcp
      namespace: default
    spec:
      containers:
      - name: nginx
        image: nginx
        livenessProbe:
          initialDelaySeconds: 5
          timeoutSeconds: 1
          tcpSocket:
            port: 80
    
    [root@kubernetes-master-001 ~]# kubectl apply -f live-exec.yaml
    pod/probe-tcp created
    [root@kubernetes-master-001 ~]# kubectl  get pods -o wide -w
    NAME                                            READY   STATUS              RESTARTS   AGE     IP               NODE                    NOMINATED NODE   READINESS GATES
    probe-tcp                                       0/1     ContainerCreating   0          3s      <none>           kubernetes-node-002     <none>           <none>
    probe-tcp                                       1/1     Running             0          18s     10.244.1.104     kubernetes-node-002     <none>           <none>
    

    3.HTTPGet

    [root@kubernetes-master-001 ~]# vi live-http.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: probe-http
      namespace: default
    spec:
      containers:
      - name: nginx
        image: nginx
        livenessProbe:
          httpGet:
            path: /
            port: 80
            host: 127.0.0.1
            scheme: HTTP   
          initialDelaySeconds: 5
          timeoutSeconds: 1
    
    [root@kubernetes-master-001 ~]# kubectl  apply  -f live-http.yaml 
    pod/probe-http created
    [root@kubernetes-master-001 ~]# kubectl  get pods -o wide -w
    NAME                                            READY   STATUS              RESTARTS   AGE     IP               NODE                    NOMINATED NODE   READINESS GATES
    probe-http                                      0/1     ContainerCreating   0          4s      <none>           kubernetes-node-002     <none>           <none>
    probe-http                                      1/1     Running             0          30s     10.244.1.105     kubernetes-node-002     <none>           <none>
    

    六、就绪性探测Readiness Probe

    用于判断容器是否启动完成,即容器的 Ready 是否为 True,可以接收请求,如果ReadinessProbe 探测失败,则容器的 Ready 将为 False,控制器将此 Pod 的Endpoint 从对应的 service 的 Endpoint 列表中移除,从此不再将任何请求调度此 Pod 上,直到下次探测成功。通过使用 Readiness 探针,Kubernetes 能够等待应用程序完全启动,然后才允许服务将流量发送到新副本。比如使用 tomcat 的应用程序来说,并不是简单地说 tomcat 启动成功就可以对外提供服务的,还需要等待 spring 容器初始化,数据库连接没连上等等。对于 springboot 应用,默认的 actuator 带有/health 接口,可以用来进行启动成功的判断。
    

    1.Exec

    通过执行一条命令,探测服务是否可以正常对外提供服务。
    [root@kubernetes-master-001 ~]# vi read-exec.yaml
    kind: Pod
    apiVersion: v1
    metadata:
      name: readexec-pod
    spec:
      containers:
        - name: nginx
          imagePullPolicy: IfNotPresent
          image: nginx
          readinessProbe:
            exec:
              command:
                - cat
                - /usr/share/nginx/html/index.html
    
    [root@kubernetes-master-001 ~]# kubectl  apply  -f read-exec.yaml 
    pod/readexec-pod created
    

    2.TCPSocket

    通过ping某个端口的方式,探测服务是否可以正常对外提供服务。
    [root@kubernetes-master-001 ~]# vi read-tcp.yaml 
    kind: Pod
    apiVersion: v1
    metadata:
      name: readtcp-pod
    spec:
      containers:
        - name: nginx
          imagePullPolicy: IfNotPresent
          image: nginx
          readinessProbe:
            tcpSocket:
              port: 80
    
    [root@kubernetes-master-001 ~]# kubectl apply -f read-tcp.yaml 
    pod/readtcp-pod created
    

    3.HTTPGet

    通过访问某个URL的方式探测当前POD是否可以正常对外提供服务。
    [root@kubernetes-master-001 ~]# vi readhttp.yaml
    kind: Pod
    apiVersion: v1
    metadata:
      name: readinessprobe-nginx
      namespace: default
      labels:
        provider: aliyun
        business: pms
        environmental: dev
    spec:
      containers:
        - name: readinessprobe-nginx
          image: nginx
          imagePullPolicy: Always
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
            - containerPort: 443
              name: https
              protocol: TCP
          readinessProbe:
            httpGet:
              port: 80
              path: /demo.html
    
    [root@kubernetes-master-001 ~]# kubectl  apply  -f  readhttp.yaml 
    pod/readinessprobe-nginx created
    

    七、回调HOOK

    实际上 Kubernetes 为我们的容器提供了生命周期钩子的,就是我们说的Pod Hook,Pod Hook 是由 kubelet 发起的,当容器中的进程启动前或者容器中的进程终止之前运行,这是包含在容器的生命周期之中。我们可以同时为 Pod 中的所有容器都配置 hook。
    
    Kubernetes 为我们提供了两种钩子函数:
    1)PostStart:这个钩子在容器创建后立即执行。但是,并不能保证钩子将在容器ENTRYPOINT之前运行,因为没有参数传递给处理程序。主要用于资源部署、环境准备等。不过需要注意的是如果钩子花费太长时间以至于不能运行或者挂起, 容器将不能达到running状态。
    
    2)PreStop:这个钩子在容器终止之前立即被调用。它是阻塞的,意味着它是同步的, 所以它必须在删除容器的调用发出之前完成。主要用于优雅关闭应用程序、通知其他系统等。如果钩子在执行期间挂起, Pod阶段将停留在running状态并且永不会达到failed状态。
    
    如果PostStart或者PreStop钩子失败, 它会杀死容器。所以我们应该让钩子函数尽可能的轻量。当然有些情况下,长时间运行命令是合理的, 比如在停止容器之前预先保存状态。
    
    apiVersion: v1
    kind: Pod
    metadata:
      name: hook-demo1
    spec:
      containers:
        - name: hook-demo1
          image: nginx
          lifecycle:
            postStart:
              exec:
                command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
    
  • 相关阅读:
    人月神话读书笔记
    读人月神话有感
    Codeforces 137D
    Codeforces 1138B
    <WFU暑假训练一> 解题报告
    Codeforces 1250B
    Codeforces 1038D
    Codeforces 1202D
    Codeforces 87B
    Codeforces 208C
  • 原文地址:https://www.cnblogs.com/jhno1/p/15607435.html
Copyright © 2020-2023  润新知