第十三章 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"]
posted @ 2021-11-26 13:43  年少纵马且长歌  阅读(80)  评论(0编辑  收藏  举报