在kubernetes1.3的POD中,有两类容器,一类是系统容器(POD Container),一类是用户容器(User Container),在用户容器中,现在又分成两类容器,一类是初始化容器(Init Container),一类是应用容器(App Container),其中应用容器包含卷容器(Volume Container)。下面看看kubernetes1.3中同POD相关的各个实体信息:


在PodSpec中,可以看到有两个同容器相关的变量,分别是InitContainers和Containers,其中变量InitContainers代表初始化容器,变量Containers代表应用容器,这两个容器都对应相同的容器实体,如下图所示:


其中POD同容器的对应关系如下图所示,从图中可以看出来,POD同初始化容器之间的对应关系是从0到N,POD同应用容器之间的对应关系是从1到N。


初始化容器是kubernetes1.3的新特性,初始化容器适用下面几个使用场景:

一、如果容器中的应用使用到了一个外部服务,需要等这个外部服务可以访问之后才能启动容器中的应用。

我们可以通过下面的配置文件来简单实现:

pod:

  spec:

    initContainers:

    - name: wait

      image: centos:centos7

      command:["/bin/sh", "-c", "for i in {1..100}; do sleep 1; ifdig dnsservice; then exit 0; fi; exit 1"]

    containers:

    - name: run

      image: application-image

      command: ["/application_that_depends_on_dnsservice"]
在这个例子的POD中定义了一个初始化容器,名称是wait,这个初始化容器其实就是执行dig命令,Dig是一个在linux命令行模式下查询DNS包括NS记录,A记录,MX记录等相关信息的工具。这个初始化容器写的比较简单,就是等待100秒的时间,在这100秒的时间内,如果访问dnsservice成功,那么就退出。这个例子的POD中还定义了一个应用容器,名称是run,这个应用容器等待初始化容器执行成功,然后才运行应用“application_that_depends_on_dnsservice”。

这种场景适合两个POD协同工作,第一个POD负责dnsservice,第二个POD负责访问第一个POD,这两个POD中的应用容器启动有先后顺序,第二个POD中的应用容器必须要等第一个POD中的应用容器启动后才能启动。

二、我们知道kubernetes中POD是具有IP的,但是POD的IP是动态生成的,所以无法提前获取POD的IP。但是存在一个使用场景,要求POD中的应用容器访问外部服务,但是这个外部服务需要提前进行客户端IP和端口注册,之后才可以正常提供服务。

我们可以通过下面的配置文件来简单实现:

pod:

  spec:

    initContainers:

    - name: register

      image: centos:centos7

      command:["/bin/sh", "-c", "curl -X POST http://$SERVICE_HOST:$SERVICE_PORT/register-d 'instance=$(POD_NAME)&ip=$(POD_IP)'"]

      env:

      - name: POD_NAME

        valueFrom:

          field: metadata.name

      - name: POD_IP

        valueFrom:

          field: status.podIP

    containers:

    - name: run

      image: application-image

      command: ["/application_that_depends_on_service"]
在这个例子的POD中定义了一个初始化容器,名称是register,这个初始化容器会http访问主机SERVICE_HOST的register服务,并将POD注册上。在POD注册到了主机SERVICE_HOST后,应用容器run才开始运行应用“application_that_depends_on_service”。这种场景适合动态使用POD信息。

三、要求POD中的应用容器启动后等待一段时间在运行,但是不想在应用中通过sleep进行等待。

我们可以通过下面的配置文件来简单实现:

pod:

  spec:

    initContainers:

    - name: wait

      image: centos:centos7

      command:["/bin/sh", "-c", "sleep 60"]

    containers:

    - name: run

      image: application-image

      command: ["/application_without_sleep"]
在这个例子的POD中定义了一个初始化容器,名称是wait,这个初始化容器会sleep 60秒,之后应用容器run才开始运行应用“application_without_sleep”。

四、POD中的容器应用容器需要实现自动从代码仓库中获取代码,并进行操作。

我们可以通过下面的配置文件来简单实现:

pod:

 spec:

   initContainers:

    -name: download

     image: image-with-git

     command: ["git", "clone","https://github.com/myrepo/myrepo.git", "/var/lib/data"]

     volumeMounts:

     - mountPath: /var/lib/data

       volumeName: git

   containers:

    -name: run

     image: centos:centos7

     command: ["/var/lib/data/exec"]

     volumeMounts:

     - mountPath: /var/lib/data

       volumeName: git

   volumes:

    -emptyDir: {}

     name: git
在这个例子的POD中定义了一个初始化容器,名称是download,这个初始化容器会挂载宿主机上的存储目录"/var/lib/data",从代码仓库https://github.com/myrepo/myrepo.git克隆一份到"/var/lib/data"上。应用容器run接着会挂载宿主机上的存储目录"/var/lib/data",然后执行“exec”命令。

以此类推,初始化容器可以应用到很多场景中。

对于具有初始化容器的POD来说,对POD的资源配额限制按照如下规则:

1、  查找初始化容器request/limit的最大值;

2、  计算应用容器request/limit的汇总;

3、  将应用容器request/limit的汇总值同初始化容器request/limit的最大值进行比较,按照最大值来作为POD的资源配额限制。

我们来看下面具有初始化容器的POD资源配额限制的例子:

pod:

  spec:

    initContainers:

    - limits:

        cpu: 100m

        memory: 1GiB

    - limits:

        cpu: 50m

        memory: 2GiB

    containers:

    - limits:

        cpu: 10m

        memory: 1100MiB

    - limits:

        cpu: 10m

        memory: 1100MiB
在这个例子中,POD中limit的资源限制是:CPU: 100m, 内存: 2200MiB。计算方法如下:

1、  初始化容器limit的CPU最大值是100m,内存最大值是2GiB;

2、  应用容器limit的汇总CPU是20m,内存是2200MiB;

3、  将上面1和2的数值进行比较,取最大值,CPU是100m,内存是2200MiB。

我们来看下面具有初始化容器的POD资源配额限制的例子:

pod:

  spec:

    initContainers:

    - limits:

        cpu: 100m

        memory: 1GiB

    containers:

    - request:

        cpu: 10m

        memory: 1100MiB
在这个例子中,POD中request的资源限制是:CPU:10m,内存1100MiB;POD中limit的资源限制是:CPU:100m,内存1GiB。计算方法同上。

在Kubernetes中,POD的QoS服务质量一共有三个级别,如下图所示:


这三个QoS级别介绍,可以看下面表格:

QoS级别

QoS介绍

BestEffort

POD中的所有容器都没有指定CPU和内存的requests和limits,那么这个POD的QoS就是BestEffort级别

Burstable

POD中只要有一个容器,这个容器requests和limits的设置同其他容器设置的不一致,那么这个POD的QoS就是Burstable级别

Guaranteed

POD中所有容器都必须统一设置了limits,并且设置参数都一致,如果有一个容器要设置requests,那么所有容器都要设置,并设置参数同limits一致,那么这个POD的QoS就是Guaranteed级别

 

对于具有初始化容器的POD来说,对POD的QoS服务质量限制按照如下规则:

1、  查找初始化容器的最高QoS;

2、  查找应用容器的最高QoS;

3、  将初始化容器的最高QoS同应用容器的最高QoS进行比较,按照高的QoS服务质量作为POD的QoS服务质量限制。

我们来看下面具有初始化容器POD的QoS服务质量的例子:

pod:

 spec:

   initContainers:

    -request:

       cpu: 10m

       memory: 1GiB

    -limits:

       cpu: 100m

       memory: 1100MiB

   containers:

    -request:

       cpu: 10m

       memory: 1GiB

    -limits:

       cpu: 100m

       memory: 1100MiB
在这个例子中,POD的QoS服务质量是Burstable,计算方法如下:

1、  初始化容器的QoS是Burstable;

2、  应用容器的QoS是Burstable;

3、  将1和2的QoS服务质量进行比较,取高的QoS,因为1和2相同,所以POD的QoS服务质量是Burstable。

综上所述,介绍了kubernetes1.3中POD的初始化容器相关结构体、适用场景、资源配额和QoS服务质量,在kubernetes1.3中初始化容器还是阿尔法特性,也就是还处在研发开发阶段,但是我们可以发现通过初始化容器可以解决现实生产环境中的很多问题,对初始化容器这个新特性,我还是充满了期待的。


Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐