zoukankan      html  css  js  c++  java
  • 深入理解Pod-初始化容器

    1、什么是Init Container?

    Init Container 就是⽤来做初始化⼯作的容器,可以是⼀个或者多个。如果有多个的话,这些容器会按定义的顺序依次执行,只有所有的 Init Container 执行完后,主容器才会被启动。我们知道⼀个 Pod ⾥⾯的所有容器是共享数据卷和网络命名空间的,所以 Init Container ⾥⾯产生的数据可以被主容器使⽤到的。

    其实, Init Container 和前面讲的钩⼦函数有点类似,只是钩子函数是在容器执⾏前来做⼀些⼯作。从直观的⻆度看上去的话,初始化容器的确有点像 PreStart ,但是钩⼦函数和我们的 Init Container 是处在不同的阶段的,我们可以通过下⾯的图来了解下:

    从上⾯这张图我们可以直观的看到 PostStart 和 PreStop 函数包括 liveness 和 readiness 探针是属于主容器生命周期范围内的,而 Init Container 是独⽴于主容器之外的,当然他们都属于 Pod 的⽣命周期范畴之内的,这就是 Init Container 和钩子函数之类的区别。

    从上面的图我们可以看到 Pod 右边还有⼀个 infra 的容器,这是⼀个什么容器呢?我们可以在集群环境中去查看下⼈任意⼀个 Pod 对应的运⾏的 Docker 容器,我们可以发现每⼀个 Pod 下⾯都包含了⼀个 pause-amd64 的镜像,这个就是我们的 infra 镜像,我们知道 Pod 下⾯的所有容器是共享同⼀个⽹络命名空间的,这个镜像就是来做这个事情的,所以每⼀个 Pod 当中都会包含⼀个这个镜像。

    注:很多同学最开始 Pod 启动不起来就是因为这个 infra 镜像没有被拉下来,因为默认该镜像是需要到⾕歌服务器上拉取的,所以需要提前拉取到节点上⾯

    2、Init Container应用场景

    Init Container 主要是来做初始化容器⼯作的,那么他有哪些应⽤场景呢?

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

    等待其他模块Ready

    我们还是通过示例的方式先来给⼤家演示下服务依赖的场景下初始化容器的使⽤方法,Pod 的定义方法如下:

    apiVersion: v1
    kind: Pod
    metadata:
      name: init-pod
      labels:
        app: init
    spec:
      containers:
      - name: main-container
        image: busybox
        command: ['sh', '-c', 'echo The app is running! && sleep 3600']
      initContainers:
      - name: init-myservice
        image: busybox
        command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
      - name: init-mydb
        image: busybox
        command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

    通过 kubectl get pods 我们可以看到 REDY 0/1 表示还有1个主容器没有准备好;Init:0/2 表示有两个初始化容器,都还没有准备好。

      查看带初始化容器的pod的详情,main-container里面还在waiting

    kubectl describe pod main-pod1

     通过yaml的方式启动myservice服务 和 mydb 服务,然后查看main-pod1的状态

    kind: Service
    apiVersion: v1
    metadata:
      name: myservice
    spec:
      ports:
      - protocol: TCP
        port: 80
        targetPort: 6376
    ---
    kind: Service
    apiVersion: v1
    metadata:
      name: mydb
    spec:
      ports:
      - protocol: TCP
        port: 80
        targetPort: 6377

    查看带初始化容器的pod的详

     跟上边的最初的init 0:2已经完全不一样

     通过初始化容器下载某个html到volumes上,然后在将volumes中的html挂载到主容器

    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://www.idig8.com
        volumeMounts:
        - name: workdir
          mountPath: "/work-dir"
      volumes:
      - name: workdir
        emptyDir: {}

    编译 yaml

     进入容器查看是否是init下载的html

    kubectl exec -it init-demo -- /bin/bash
    # 进入容器
    cd /usr/share/nginx/html
    cat html

    查看某一个init-container的日志

    kubectl logs main-pod1 -c init-myservice

    参考:

    https://blog.z0ukun.com/?p=1456

    https://cloud.tencent.com/developer/article/1491377

    https://kubernetes.io/zh/docs/concepts/workloads/pods/init-containers/

  • 相关阅读:
    面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?请根据自己的理解简明扼要的回答
    当下大部分互联网创业公司为什么都愿意采用增量模型来做开发?
    0
    计算机网络
    java基础
    java 多线程编程
    java类与对象,用程序解释
    修饰符的探讨
    java学习总结02
    java day1
  • 原文地址:https://www.cnblogs.com/fat-girl-spring/p/14886618.html
Copyright © 2011-2022 走看看