• kubernetes1.4新特性:支持Docker新特性


    (一)背景资料

    • 在Kubernetes1.2中这个第三方组件就是go-dockerclient,这是一个GO语言写的docker客户端,支持Dockerremote API,这个项目在https://github.com/fsouza/go-dockerclient中。
    • 在Kubernetes1.3中直接使用docker公司提供的client来实现,通过这个client可以实现同DockerDeamon之间的通讯,这个客户端项目在https://github.com/docker/engine-api/中,感兴趣的话可以去看看。
    • 在Kubernetes1.4中延用了1.3中的方式,直接使用docker公司提供的client来实现。

    (二)支持Docker版本

    • 对于Kubernetes1.4需要使用Docker版本至少是1.9.x,Docker1.9.x对应的API版本是1.21。
    • 下面是Docker版本同API版本对应关系,其中红色字体的部分是Kubernetes1.4不支持的。

    Docker版本

    API版本

    1.12x

    1.24

    1.11.x

    1.23

    1.10.x

    1.22

    1.9.x

    1.21

    1.8.x

    1.20

    1.7.x

    1.19

    1.6.x

    1.18

    1.5.x

    1.17

    1.4.x

    1.16

    1.3.x

    1.15

    1.2.x

    1.14

    (三)调用Docker API

    下面表格展现了Docker最新版本所有的API列表,同时也展现了Kubernetes1.4版本和1.3版本都使用了哪些API。

    • 第一列是Docker 1.24版本API列表
    • 第二列是这些API使用方式
    • 第三列是Kubernetes1.4中使用到的API
    • 第四列是Kubernetes1.3中使用到的API
    • 红色字体部分为1.4版本比1.3版本增加的调用API,也就是说1.4版本比1.3版本增加的操作Docker的功能

    Docker API 1.24

    使用方式

    Kubernetes1.4

    Kubernetes1.3

    Get container stats based on resource usage

    GET /containers/(id)/stats

     

     

    Update a container

    POST /containers/(id)/update

     

     

    Rename a container

    POST /containers/(id)/rename

     

     

    Retrieving information about files and folders in a container

    HEAD /containers/(id)/archive

     

     

    List containers

    GET /containers/json

    Inspect a container

    GET /containers/(id)/json

    Inspect changes on a container’s filesystem

    GET /containers/(id)/changes

    Create a container

    POST /containers/create

    Start a container

    POST /containers/(id)/start

    Stop a container

    POST /containers/(id)/stop

    Restart a container

    POST /containers/(id)/restart

     

     

    Pause a container

    POST /containers/(id)/pause

     

     

    Unpause a container

    POST /containers/(id)/unpause

     

     

    List processes running inside a container

    GET /containers/(id)/top

     

     

    Kill a container

    POST /containers/(id)/kill

    Remove a container

    DELETE /containers/(id)

    Get an archive of a filesystem resource in a container

    GET /containers/(id)/archive

     

     

    Extract an archive of files or folders to a directory in a container

    PUT /containers/(id)/archive

     

     

    Copy files or folders from a container

    POST /containers/(id)/copy,以后会被删除掉,使用archive代替

     

     

    Wait a container

    POST /containers/(id)/wait

     

     

    Create a new image from a container’s changes

    POST /commit

     

     

    Attach to a container

    POST /containers/(id)/attach

    Attach to a container (websocket)

    GET /containers/(id or name)/attach/ws

     

     

    Get container logs

    GET /containers/(id)/logs

    Resize a container TTY

    POST /containers/(id)/resize

     

    Export a container

    GET /containers/(id)/export

     

     

    List Images

    GET /images/json

    Inspect an image

    GET /images/(name)/json

    Get the history of an image

    GET /images/(name)/history

    Push an image on the registry

    POST /images/(name)/push

     

     

    Build image from a Dockerfile

    POST /build

     

     

    Create an image

    POST /images/create

    Load a tarball with a set of images and tags into docker

    POST /images/load

     

     

    Get a tarball containing all images in a repository

    GET /images/(name)/get

     

     

    Get a tarball containing all images

    GET /images/get

     

     

    Tag an image into a repository

    POST /images/(name)/tag

     

     

    Remove an image

    DELETE /images/(name)

    Search images

    GET /images/search

     

     

    Monitor Docker’s events

    GET /events

     

     

    Show the docker version information

    GET /version

    Display system-wide information

    GET /info

    Ping the docker server

    GET /_ping

     

     

    List volumes

    GET /volumes

     

     

    Create a volume

    POST /volumes/create

     

     

    Inspect a volume

    GET /volumes/(name)

     

     

    Remove a volume

    DELETE /volumes/(name)

     

     

    List networks

    GET /networks

     

     

    Inspect network

    GET /networks/<network-id>

     

     

    Create a network

    POST /networks/create

     

     

    Remove a network

    DELETE /networks/(id)

     

     

    Connect a container to a network

    POST /networks/(id)/connect

     

     

    Disconnect a container from a network

    POST /networks/(id)/disconnect

     

     

    Check auth configuration

    POST /auth

     

     

    Exec Create

    POST /containers/(id)/exec

    Exec Start

    POST /exec/(id)/start

    Exec Resize

    POST /exec/(id)/resize

     

    Exec Inspect

    GET /exec/(id)/json

    List plugins

    GET /plugins

     

     

    Install a plugin

    POST /plugins/pull?name=<plugin name>

     

     

    Inspect a plugin

    GET /plugins/(plugin name)

     

     

    Enable a plugin

    POST /plugins/(plugin name)/enable

     

     

    Disable a plugin

    POST /plugins/(plugin name)/disable

     

     

    Remove a plugin

    DELETE /plugins/(plugin name)

     

     

    List nodes

    GET /nodes

     

     

    Inspect a node

    GET /nodes/<id>

     

     

    Remove a node

    DELETE /nodes/<id>

     

     

    Update a node

    POST /nodes/<id>/update

     

     

    Inspect swarm

    GET /swarm

     

     

    Initialize a new swarm

    POST /swarm/init

     

     

    Join an existing swarm

    POST /swarm/join

     

     

    Leave a swarm

    POST /swarm/leave

     

     

    Update a swarm

    POST /swarm/update

     

     

    List services

    GET /services

     

     

    Create a service

    POST /services/create

     

     

    Remove a service

    DELETE /services/(id or name)

     

     

    Inspect one or more services

    GET /services/(id or name)

     

     

    Update a service

    POST /services/(id or name)/update

     

     

    List tasks

    GET /tasks

     

     

    Inspect a task

    GET /tasks/(task id)

     

     

    1)       从表格中可以看到,Kubernetes1.4中调用了Docker的Resize a container TTY接口,用来配置Docker容器的虚拟终端(TTY),重新设置Docker容器的虚拟终端之后,需要重新启动容器才能生效。

    HTTP请求例子:

     POST/containers/4fa6e0f0c678/resize?h=40&w=80 HTTP/1.1

    返回响应例子:

     HTTP/1.1 200 OK
     Content-Length: 0
     Content-Type: text/plain; charset=utf-8

    请求参数:

    h – 虚拟终端高度

    w – 虚拟终端宽度

    HTTP返回响应状态值:

    200 – 设置成功

    404 – 没有找到指定Docker容器

    500 – 不能够重新设置虚拟终端参数

    2)       从表格中还可以看到,Kubernetes1.4中调用了Docker的Exec Resize接口,如果在Docker容器中执行exec命令时指定了虚拟终端(tty),那么通过这个API接口就可以重新设置虚拟终端(tty)。

    HTTP请求例子:

      POST/exec/e90e34656806/resize?h=40&w=80 HTTP/1.1
      Content-Type: text/plain

    返回响应例子:

      HTTP/1.1201 Created
      Content-Type: text/plain


    请求参数:

    h –虚拟终端高度

    w –虚拟终端宽度

    HTTP返回响应状态值:

    201 –设置成功

    404 –没有找到指定exec实例

    3)       Kubernetes1.4新增加了上面两个接口调用,可以看看这两个接口调用在源代码中的位置:

    func AttachContainer(client DockerInterface,containerID kubecontainer.ContainerID, stdin io.Reader, stdout, stderrio.WriteCloser, tty bool, resize <-chan term.Size) error {
    
          <span style="color:#FF0000;"> kubecontainer.HandleResizing(resize, func(size term.Size) {
    
                  client.ResizeContainerTTY(containerID.ID,int(size.Height), int(size.Width))
    
           })</span>
    
           opts:= dockertypes.ContainerAttachOptions{
    
                  Stream:true,
    
                  Stdin:  stdin != nil,
    
                  Stdout:stdout != nil,
    
                  Stderr:stderr != nil,
    
           }
    
           ……
    
    }
     
    func (*NativeExecHandler)ExecInContainer(client DockerInterface, container *dockertypes.ContainerJSON,cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize<-chan term.Size) error {
    
           ……
    
          <span style="color:#FF0000;"> kubecontainer.HandleResizing(resize, func(size term.Size) {
    
                  client.ResizeExecTTY(execObj.ID, int(size.Height),int(size.Width))
    
           })</span>
    
           startOpts:= dockertypes.ExecStartCheck{Detach: false, Tty: tty}
    
           streamOpts:= StreamOptions{
    
                  InputStream:  stdin,
    
                  OutputStream:stdout,
    
                  ErrorStream:  stderr,
    
                  RawTerminal:  tty,
    
           }
    
           err= client.StartExec(execObj.ID, startOpts, streamOpts)
    
           iferr != nil {
    
                  returnerr
    
           }
    
    ……
    
    }


    这两处开发开发人员的注释如下:

    Have to start this before the call toclient.AttachToContainer because client.AttachToContainer is a blocking call:-( Otherwise, resize events don't get processed and the terminal neverresizes. 

    Have to start this before the call toclient.StartExec because client.StartExec is a blocking call :-( Otherwise,resize events don't get processed and the terminal never resizes.

     通过注释可以发现,因为attach和start exec两个接口都是可以阻塞的,所以通过增加设置虚拟终端(tty)来判断向attach和start exec两个接口发送的请求是否阻塞。

    4)       从表格中还可以看到,Kubernetes没有使用到Docker的网络接口,也没有使用到Docker的卷接口,原因是Kubernetes自己定义了Service和POD,自己实现了POD之间的网络和挂载到POD上的卷。

    5)       从表格中也可以看到,Kubernetes对Docker容器的管理只有很少的功能,甚至都没有使用到Docker的重启接口,还是因为Kubernetes自己定义的POD,Kubernetes以POD为基本操作单元,而且是Kubernetes从容器集群管理角度设计的,所以不存在对POD里面单个Docker容器的重启操作。

    (四)对Docker其他操作

    1)       Linux ext4文件系统要求文件名字符个数不能超过255,在Kubernetes1.4中进行了控制。

    2)       由于Docker1.12支持了通过—sysctl参数来设置内核参数,所以在Kubernetes1.4可以将安全的sysctl命令放入白名单列表中,这样就可以对容器内核参数进行配置操作,下面是Kubernetes1.4对内核参数的默认设置:

    •       sysctl -wvm.overcommit_memory=1

    表示节点上有多少物理内存就用多少,不进行内存超分配

    •       sysctl -w vm.panic_on_oom=0

    表示当节点上物理内存耗尽时,内核触发OOM killer杀掉最耗内存的进程

    •       sysctl -w kernel/panic=10

    表示当内核panic时,等待10秒后在重启

    •       sysctl -wkernel/panic_on_oops=1

    设置当内核oops发生时,采用panic方式处理。不同于panic会导致OS重启,设备驱动引发的oops通常不会导致OS重启,但是可以通过设置这个参数来指定oops发生时进行OS重启

    (五)K8S操作Docker的网络实现

    我们可以用下面这张图来把POD和容器之间的关系形象化,此图仅供说明问题时的参考,并无实际意义。


    我们可以把POD看作是机器里面的操作系统,把容器看作是里面的进程,在操作系统内部进程间是可以通过IPC(Inter-Process Communication)进行通讯的,不同操作系统之间的进程是通过操作系统IP和端口进行通讯的,那么对应到POD和容器,就变成了POD内部容器间事可以通过IPC(Inter-Process Communication)进行通讯的,不同POD之间的容器是通过POD IP和端口进行通讯的。从集群的角度来考虑问题,Kubernetes基本操作单元是POD,不需要关注到POD中的容器,那么我们可以想象一下,如果我们要按照虚拟机的使用方式来使用容器,那样的话应该如何使用Kubernetes呢?可以看下面的图:


    这样我们就实现了像虚拟机那样使用容器,我们可以认为POD就是一个虚拟机,只不过在这个虚拟机中只有一个容器。但是如果要对这个虚拟机进行操作的时候我们发现问题来了,从前面的表格中可以看到,Kubernetes对Docker容器的管理只有很少的功能,没有使用到Docker的重启接口,但是如果把容器当作虚拟机用,必然要使用重启功能,抛开Kubernetes的设计理念,我们自己可以扩展Kubernetes对POD重启的实现,实现把容器当作虚拟机来使用的需求。

  • 相关阅读:
    u-boot 用哪个lds链接脚本
    u-boot-2019.07 移植步骤
    u-boot-2016.09 make编译过程分析(二)
    grep 命令搜索 带空格的字符
    uboot if_changed函数
    2019保险规划 待完善
    MongoDB Capped集合
    并发编程——详解 AQS CLH 锁
    Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
    观察者模式
  • 原文地址:https://www.cnblogs.com/hehe520/p/6147718.html
Copyright © 2020-2023  润新知