zoukankan      html  css  js  c++  java
  • 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重启的实现,实现把容器当作虚拟机来使用的需求。

  • 相关阅读:
    桟错误分析方法
    gstreamer调试命令
    sqlite的事务和锁,很透彻的讲解 【转】
    严重: Exception starting filter struts2 java.lang.NullPointerException (转载)
    eclipse 快捷键
    POJ 1099 Square Ice
    HDU 1013 Digital Roots
    HDU 1087 Super Jumping! Jumping! Jumping!(动态规划)
    HDU 1159 Common Subsequence
    HDU 1069 Monkey and Banana(动态规划)
  • 原文地址:https://www.cnblogs.com/hehe520/p/6147718.html
Copyright © 2011-2022 走看看