Kubernetes-Init容器与静态Pod

Init容器

在Pod的生命周期中,可以执行多种操作如下图:

什么是Init容器?

Init容器也就是我们平时常说的初始化容器。Init Container就是用来做初始化工作的容器,可以是一个或者多个,如果有多个的话,这些容器会按定义的顺序依次执行。我们知道一个 Pod 里面的所有容器是共享数据卷和 Network Namespace 的,所以 Init Container 里面产生的数据可以被主容器使用到。从上面的 Pod 生命周期的图中可以看出初始化容器是独立与主容器之外的,只有所有的`初始化容器执行完之后,主容器才会被启动。那么初始化容器有哪些应用场景呢:

  • 等待其他模块 Ready:这个可以用来解决服务之间的依赖问题,比如我们有一个 Web 服务,该服务又依赖于另外一个数据库服务,但是在我们启动这个 Web 服务的时候我们并不能保证依赖的这个数据库服务就已经启动起来了,所以可能会出现一段时间内 Web 服务连接数据库异常。要解决这个问题的话我们就可以在 Web 服务的 Pod 中使用一个 InitContainer,在这个初始化容器中去检查数据库是否已经准备好了,准备好了过后初始化容器就结束退出,然后我们主容器的 Web 服务才被启动起来,这个时候去连接数据库就不会有问题了。
  • 做初始化配置:比如集群里检测所有已经存在的成员节点,为主容器准备好集群的配置信息,这样主容器起来后就能用这个配置信息加入集群。
  • 其它场景:如将 Pod 注册到一个中央数据库、配置中心等。

示例如下:

apiVersion: v1
kind: Pod
metadata:
  name: init-demo
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: workdir
      mountPath: /usr/share/nginx/html
  initContainers:
  - name: install
    image: busybox
    command:
    - wget
    - "-O"
    - "/work-dir/index.html"
    - http://kubernetes.io
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  dnsPolicy: Default
  volumes:
  - name: workdir
    emptyDir: {}

理解init容器

  1. 它们总是运行到完成。
  2. 每个都必须在下一个启动之前成功完成。
  3. 如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 restartPolicy 为 Never,它不会重新启动。
  4. Init 容器支持应用容器的全部字段和特性,但不支持 Readiness Probe,因为它们必须在 Pod 就绪之前运行完成。
  5. 如果为一个 Pod 指定了多个 Init 容器,那些容器会按顺序一次运行一个。 每个 Init 容器必须运行成功,下一个才能够运行。
  6. 因为 Init 容器可能会被重启、重试或者重新执行,所以 Init 容器的代码应该是幂等的。 特别地,被写到 EmptyDirs 中文件的代码,应该对输出文件可能已经存在做好准备。
  7. 在 Pod 上使用 activeDeadlineSeconds,在容器上使用 livenessProbe,这样能够避免 Init 容器一直失败。 这就为 Init 容器活跃设置了一个期限。
  8. 在 Pod 中的每个 app 和 Init 容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误。
  9. 对 Init 容器 spec 的修改,被限制在容器 image 字段中。 更改 Init 容器的 image 字段,等价于重启该 Pod。

如果Pod的Init容器失败,Kubernetes会不断地重启该Pod,直到Init容器成功为止。然而如果Pod对应的restartPolicy为Never,则它不会重新启动。所以在Pod上使用activeDeadlineSeconds,在容器上使用livenessProbe,相当于为Init容器活跃设置了一个期限,能够避免Init容器一直失败。

Init容器与普通容器的不同之处

Init 容器与普通的容器非常像,除了如下两点:

  • Init 容器总是运行到成功完成为止。
  • 每个 Init 容器都必须在下一个 Init 容器启动之前成功完成。

静态Pod

静态Pod是由kubelet进行管理,仅存在于特定Node上的Pod。它们不能通过API Server进行管理,无法与ReplicationController、Deployment或DaemonSet进行关联,并且kubelet也无法对其健康检查。静态Pod总是由kubelet创建,并且总在kubelet所在的Node上运行。创建静态Pod的方式:使用配置文件方式 或** HTTP方式**。一般常使用的是配置文件方式。

通过配置文件创建

配置文件只是特定目录中json或yaml格式的标准pod定义。它通过在kubelet守护进程中添加配置参数--pod-manifest-path= 来运行静态Pod,kubelet经常会它定期扫描目录,我们可以查看kubelet的pod-manifest-path参数,可以看到默认指定的是/etc/kubernetes/manifests目录
image.png
那么,如何将一个简单web服务作为静态pod启动?
我们只需要在该目录下面创建一个标准的 Pod 的 JSON 或者YAML文件即可
注意:选择运行静态pod的节点服务器,不一定是node节点,只要有kubelet进程所在的节点都可以运行静态pod。

cat <<EOF >/etc/kubernetes/manifests/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    app: static
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
EOF

前面说了,当kubelet启动时,它会自动启动在指定的目录–pod-manifest-path和- manifest-url参数中定义的所有pod ,即我们的static-web。接着在该节点上检查是否创建成功:

[root@master01 podselector]# kubectl get  pods | grep static
static-web-master01            1/1     Running   0              100s
[root@master01 podselector]# 

上面也提到了,它不归任何部署方式来管理,即使我们尝试命令去删除

[root@master01 podselector]# kubectl delete pods static-web-master01 
pod "static-web-master01" deleted
[root@master01 podselector]# kubectl get  pods | grep static
static-web-master01            1/1     Running   0              16s

可以看出静态pod通过这种方式是没法删除的
那我如何去删除或者说是动态的添加一个pod呢?这种机制已经知道,kubelet进程会定期扫描配置的目录(/etc/kubernetes/manifests)以进行更改,并在文件出现/消失在此目录中时添加/删除pod。

[root@master01 podselector]# rm -f /etc/kubernetes/manifests/static-web.yaml 
[root@master01 podselector]# kubectl get  pods | grep static
static-web-master01            0/1     Completed   0              4m53s
[root@master01 podselector]# kubectl get  pods | grep static
[root@master01 podselector]# 
posted @ 2024-08-11 16:36  &UnstopPable  阅读(4)  评论(0编辑  收藏  举报