美文网首页
Learning Docker Part 003 Dokcer容

Learning Docker Part 003 Dokcer容

作者: drfung | 来源:发表于2017-09-25 16:25 被阅读66次

    如何运行容器

    有三种方式可以指定容器启动时的命令

    1. CMD指令
    2. ENTRYPOINT 指令
    3. docker run命令行中指定
    root@fbo-virtual-machine:~# docker run ubuntu pwd
    /
    root@fbo-virtual-machine:~# docker ps -a
    CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                      PORTS                   NAMES
    9cad7521bf55        ubuntu              "pwd"                11 seconds ago      Exited (0) 10 seconds ago    
    root@fbo-virtual-machine:~# docker run --name "my_http_server" -d httpd
    231a01fe0dc5322836d25437f38ddd518814b70f4386b801cf6d256c5f72131d
    root@fbo-virtual-machine:~# docker ps
    CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
    231a01fe0dc5        httpd               "httpd-foreground"   6 seconds ago       Up 5 seconds        80/tcp              my_http_server
    

    如何进入容器

    有两种方式可以进入到docker容器中

    • docker attch
    • docker exec -it

    docker attach

    root@fbo-virtual-machine:~# docker run -d ubuntu /bin/bash -c "while true;do sleep 1;echo I_am_incontainer;done"
    51479e20192cf9765a954ea21a0e9c4b3015dc1c0e03e37458f6353d79b3fd24
    root@fbo-virtual-machine:~# docker ps 
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    51479e20192c        ubuntu              "/bin/bash -c 'whi..."   4 seconds ago       Up 3 seconds                            nervous_clarke
    231a01fe0dc5        httpd               "httpd-foreground"       5 minutes ago       Up 5 minutes        80/tcp              my_http_server
    root@fbo-virtual-machine:~# docker attach 51479
    I_am_incontainer
    I_am_incontainer
    I_am_incontainer
    I_am_incontainer
    

    docker exec

    root@fbo-virtual-machine:~# docker run -d ubuntu /bin/bash -c "while true;do sleep 1;echo I_am_incontainer;done"
    60db0f40851dfe5af74095724f917f231ccdc13d526cd5265d88c43a9156db42
    root@fbo-virtual-machine:~# docker exec -it 60db /bin/bash
    root@60db0f40851d:/# ps -aux
    USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root          1  0.0  0.0  18028  2836 ?        Ss   01:56   0:00 /bin/bash -c while true;do sleep 1;echo I_am_incontainer;
    root         45  0.2  0.0  18244  3208 pts/0    Ss   01:56   0:00 /bin/bash
    root         61  0.0  0.0   4380   796 ?        S    01:56   0:00 sleep 1
    root         62  0.0  0.0  34424  2784 pts/0    R+   01:56   0:00 ps -aux
    root@60db0f40851d:/# exit
    exit
    

    attach vs exec

    1. attach直接进入启动命令的终端
    2. exec在容器中打开新的进程
    3. attach会直接显示启动命令的输出,使用docker logs -f也可以查看启动命令的输出
    4. attach进入容器后退出会终止容器,exec则不会

    容器功能划分

    按照用途划分,容器分为:

    1. 服务类容器: 以deamon形式运行,外提供服务。比容 web server,数据等,通过-d以后台方式运行,要排查问题时,通过exec -it进入容器。
    2. 工具类容器: 能够给我们提供一个临时的工作环境,通常以run -it方式运行,工具类容器多用基础镜像,如busybox、ubuntu、debain等

    容器的常用操作

    start、stop、restart

    ## 1. 停止容器
    root@fbo-virtual-machine:~# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    a2cf56b541b9        ubuntu              "/bin/bash -c 'whi..."   38 seconds ago      Up 36 seconds                           romantic_curran
    root@fbo-virtual-machine:~# docker stop romantic_curran 
    romantic_curran
    root@fbo-virtual-machine:~# docker run -d --name http-kill httpd
    8db9c7bff6497a1f7701976fcde3fd27197e326e0ad8684269171bff13af9807
    ## 2. 杀掉容器
    root@fbo-virtual-machine:~# docker ps
    CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
    8db9c7bff649        httpd               "httpd-foreground"   8 seconds ago       Up 6 seconds        80/tcp              http-kill
    root@fbo-virtual-machine:~# docker kill http-kill
    http-kill
    root@fbo-virtual-machine:~# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    ## 3. 启动关闭的容器
    root@fbo-virtual-machine:~# docker ps -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS               NAMES
    8db9c7bff649        httpd               "httpd-foreground"       3 minutes ago       Exited (137) 2 minutes ago                       http-kill
    a2cf56b541b9        ubuntu              "/bin/bash -c 'whi..."   9 minutes ago       Exited (137) 8 minutes ago                       romantic_curran
    root@fbo-virtual-machine:~# docker start http-kill
    http-kill
    root@fbo-virtual-machine:~# docker ps
    CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
    8db9c7bff649        httpd               "httpd-foreground"   3 minutes ago       Up 2 seconds        80/tcp              http-kill
    ## 4. 重启容器
    root@fbo-virtual-machine:~# docker restart http-kill
    http-kill
    ## 5. 有时候容器会某种错误而终止,如果我们希望docker能够自动重启。在启动时设置--restart就可以达到这个效果 
    ##    --restart=always 意味着无论容器因何种原因退出(包括正常退出),就立即重启。该参数的形式还可以是 
    ##    --restart=on-failure:3,意思是如果启动进程退出代码非0,则重启容器,最多重启3次。
    root@fbo-virtual-machine:~# docker run -d --restart=always --name http-restart httpd
    3bf7b46f57f9f039409f9d4f29983c2af4e1379a80d42102226982be8cfaa949
    root@fbo-virtual-machine:~# docker ps 
    CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
    3bf7b46f57f9        httpd               "httpd-foreground"   2 seconds ago       Up 2 seconds        80/tcp              http-restart
    8db9c7bff649        httpd               "httpd-foreground"   18 minutes ago      Up 13 minutes       80/tcp              http-kill
    root@fbo-virtual-machine:~# docker exec -it http-restart /bin/bash
    root@3bf7b46f57f9:/usr/local/apache2# ps -aux | grep httpd | grep -v grep | awk '{print $2}' | xargs -I {} kill -9 {}
    root@3bf7b46f57f9:/usr/local/apache2# ps -aux
    USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root          1  0.0  0.1  77212  4436 ?        Ss   02:44   0:00 httpd -DFOREGROUND
    root         90  0.0  0.0  20252  3224 pts/0    Ss   02:45   0:00 /bin/bash
    daemon      208  0.0  0.1 366392  5472 ?        Sl   02:47   0:00 httpd -DFOREGROUND
    root        236  0.0  0.0  17500  2092 pts/0    R+   02:47   0:00 ps -aux
    root@3bf7b46f57f9:/usr/local/apache2# exit
    exit
    

    pause\unpause 容器

    root@fbo-virtual-machine:~# docker pause http-restart 
    http-restart
    root@fbo-virtual-machine:~# docker unpause http-restart
    http-restart
    root@fbo-virtual-machine:~# docker ps
    CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
    3bf7b46f57f9        httpd               "httpd-foreground"   21 minutes ago      Up 20 minutes       80/tcp              http-restart
    8db9c7bff649        httpd               "httpd-foreground"   40 minutes ago      Up 34 minutes       80/tcp              http-kill
    

    删除容器

    ## 删除多个容器
    root@fbo-virtual-machine:~# docker rm 8db9c a2cf56
    8db9c
    a2cf56
    ## 删除所有已经退出的容器
    root@fbo-virtual-machine:~# docker ps -aq -f status=exited | xargs docker rm
    a5c033c850c3
    8fb39e630f8f
    0635f8a0c056
    2b4b2f4ac0ed
    cec27c3847c8
    ccd36895e0e3
    79b85cdb3e9a
    e1fb45c8c949
    1cf4c2e2629c
    root@fbo-virtual-machine:~# for i in `seq 10`;do docker run busybox &> /dev/null;done 
    root@fbo-virtual-machine:~# docker ps -a
    CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                     PORTS               NAMES
    d02035d85b45        busybox             "sh"                 4 seconds ago       Exited (0) 3 seconds ago                       wizardly_swartz
    d528c3af182f        busybox             "sh"                 5 seconds ago       Exited (0) 4 seconds ago                       stupefied_boyd
    63ceda326bf5        busybox             "sh"                 6 seconds ago       Exited (0) 5 seconds ago                       jovial_ramanujan
    ab0e240a435a        busybox             "sh"                 6 seconds ago       Exited (0) 5 seconds ago                       nifty_mayer
    6cc0355813f4        busybox             "sh"                 7 seconds ago       Exited (0) 6 seconds ago                       agitated_bhaskara
    15b4bd171497        busybox             "sh"                 7 seconds ago       Exited (0) 6 seconds ago                       hardcore_allen
    3be63fb9598a        busybox             "sh"                 8 seconds ago       Exited (0) 7 seconds ago                       quizzical_wozniak
    6c9152cee5e2        busybox             "sh"                 8 seconds ago       Exited (0) 7 seconds ago                       sleepy_raman
    7649ac28a45f        busybox             "sh"                 9 seconds ago       Exited (0) 8 seconds ago                       keen_pare
    30d36cf4044c        busybox             "sh"                 9 seconds ago       Exited (0) 8 seconds ago                       kind_bardeen
    3bf7b46f57f9        httpd               "httpd-foreground"   32 minutes ago      Up 31 minutes              80/tcp              http-restart
    root@fbo-virtual-machine:~# docker rm -v $(docker ps -aq -f status=exited)
    d02035d85b45
    d528c3af182f
    63ceda326bf5
    ab0e240a435a
    6cc0355813f4
    15b4bd171497
    3be63fb9598a
    6c9152cee5e2
    7649ac28a45f
    30d36cf4044c
    

    容器的生命周期

    容器生命周期

    限制容器对资源的使用

    一个docker host上会运行若干个容器,每个容器都要消耗cpu、内存以及磁盘IO资源,为避免某个容器因为占中过多资源而影响其他容器乃至整个host的性能,我们必须要对容器资源使用进行限制。

    内存限额

    容器的内存包括两部分:物理内容和swap内存

    1. -m或者--memory:设置内存的使用限额,如100M、2G;
    2. --memory-swap: 设置内存+swap的使用限额
    ## 1. 指定内存限额启动ubuntu
    root@fbo-virtual-machine:~# docker run -m 200M --memory-swap 300M ubuntu
    root@fbo-virtual-machine:~# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    root@fbo-virtual-machine:~# docker ps -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
    38f99d7e9cc5        ubuntu              "/bin/bash"         5 seconds ago       Exited (0) 4 seconds ago                       objective_khorana
    ## 2. 通过progrium/stress镜像来看容器的内存如何分配。该镜像可以用来对容
    ##    器执行压力测试。
    ##    --vm 1 : 启动一个内存工作线程
    ##    --vm-bytes 280M :每个线程分配280M 
    root@fbo-virtual-machine:~# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
    stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
    stress: dbug: [1] using backoff sleep of 3000us
    stress: dbug: [1] --> hogvm worker 1 [5] forked
    stress: dbug: [5] allocating 293601280 bytes ...
    stress: dbug: [5] touching bytes in strides of 4096 bytes ...
    stress: dbug: [5] freed 293601280 bytes
    stress: dbug: [5] allocating 293601280 bytes ...
    stress: dbug: [5] touching bytes in strides of 4096 bytes ...
    stress: dbug: [5] freed 293601280 bytes
    stress: dbug: [5] allocating 293601280 bytes ...
    stress: dbug: [5] touching bytes in strides of 4096 bytes ...
    ## 3. 让线程分配内存超过容器的配额,容器将会退出
    root@fbo-virtual-machine:~# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M
    stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
    stress: dbug: [1] using backoff sleep of 3000us
    stress: dbug: [1] --> hogvm worker 1 [5] forked
    stress: dbug: [5] allocating 325058560 bytes ...
    stress: dbug: [5] touching bytes in strides of 4096 bytes ...
    stress: FAIL: [1] (416) <-- worker 5 got signal 9
    stress: WARN: [1] (418) now reaping child worker processes
    stress: FAIL: [1] (422) kill error: No such process
    stress: FAIL: [1] (452) failed run completed in 2s
    

    CPU权重

    默认情况下,容器对cpu的使用没有限制,可以使用-c或者--cpu-shares设置容器使用CPU的权重,如果不指定,默认权重为1024.

    ## 1. 启动container-a,cpu权重1024
    root@fbo-virtual-machine:~# docker run -it --name container-a -c 1024 progrium/stress --cpu 1
    stress: info: [1] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
    stress: dbug: [1] using backoff sleep of 3000us
    stress: dbug: [1] --> hogcpu worker 1 [5] forked
    ## 2. 启动container-b,cpu权重512
    root@fbo-virtual-machine:~# docker run -it --name container-b -c 512 progrium/stress --cpu 1
    stress: info: [1] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
    stress: dbug: [1] using backoff sleep of 3000us
    stress: dbug: [1] --> hogcpu worker 1 [5] forked
    ## 3. 在host使用top观察cpu消耗情况,container-a恰好是container-b的两倍
    fbo@fbo-virtual-machine:~$ top
    top - 14:34:18 up 43 min,  3 users,  load average: 1.96, 0.96, 0.38
    Tasks: 214 total,   3 running, 211 sleeping,   0 stopped,   0 zombie
    %Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem :  4025468 total,  3194544 free,   379596 used,   451328 buff/cache
    KiB Swap:  4191228 total,  4149236 free,    41992 used.  3343756 avail Mem 
    
       PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                
      3888 root      20   0    7312    100      0 R 66.4  0.0   2:52.13 stress                                                                                                 
      4008 root      20   0    7312     96      0 R 33.2  0.0   0:48.75 stress
    ## 4. 停掉container-a后container-b将会抢占cpu
    fbo@fbo-virtual-machine:~$ sudo docker stop container-a
    container-a
    fbo@fbo-virtual-machine:~$ top
    top - 14:40:27 up 50 min,  3 users,  load average: 1.72, 1.65, 0.91
    Tasks: 212 total,   2 running, 210 sleeping,   0 stopped,   0 zombie
    %Cpu(s): 20.3 us,  0.8 sy,  0.0 ni, 76.7 id,  2.1 wa,  0.0 hi,  0.1 si,  0.0 st
    KiB Mem :  4025468 total,  3203672 free,   370764 used,   451032 buff/cache
    KiB Swap:  4191228 total,  4149236 free,    41992 used.  3352948 avail Mem 
    
       PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                
      4008 root      20   0    7312     96      0 R 93.8  0.0   3:04.58 stress    
    

    容器IO限制

    docker可以通过设置block IO权重、限制bqs和iops的方式控制容器读写磁盘的带宽。

    block IO 权重

    默认情况下所有容器能够平等地读写磁盘,可以通过--blkio-weight参数来改变block IO的优先级。

    ## 启动container-a和container-b,同时写入磁盘,由于container-a的权重大于
    ## container-b,测试发现container-a的IO资源要优先于container-b  
    root@fbo-virtual-machine:~# docker run -it --name container-a --blkio-weight 600 ubuntu
    root@ca7eb3cf1b3f:/# time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
    800+0 records in
    800+0 records out
    838860800 bytes (839 MB, 800 MiB) copied, 15.1962 s, 55.2 MB/s
    
    real    0m15.832s
    user    0m0.012s
    sys 0m1.428s
    root@fbo-virtual-machine:~# docker run -it --name container-b --blkio-weight 300 ubuntu
    root@b6d222694ca5:/# time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
    800+0 records in
    800+0 records out
    838860800 bytes (839 MB, 800 MiB) copied, 18.8524 s, 44.5 MB/s
    
    real    0m19.487s
    user    0m0.004s
    sys 0m1.348s
    

    限制bqs和iops

    bps是bytes per second,每秒读写的数据量
    iops是io per second,每秒IO次数

    可以通过下列参数来控制bqs和iops
    --device-read-bqs,限制读某个设备的bps
    --device-write-bqs,限制写某个设备的bps
    --device-read-iops,限制读某个设备的iops
    --device-write-iops,限制写某个设备的iops

    ## 指定限制bps后,写速率不会超过限定值
    root@fbo-virtual-machine:~# docker run -it --device-write-bps /dev/sda:30MB ubuntu
    root@9e5f5ecfe864:/# time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct 
    800+0 records in
    800+0 records out
    838860800 bytes (839 MB, 800 MiB) copied, 40.8922 s, 20.5 MB/s
    
    real    0m40.894s
    user    0m0.000s
    sys 0m0.940s
    ## 我们来测试下本机的bps
    root@fbo-virtual-machine:~# time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
    800+0 records in
    800+0 records out
    838860800 bytes (839 MB, 800 MiB) copied, 0.328587 s, 2.6 GB/s
    
    real    0m0.759s
    user    0m0.004s
    sys 0m0.212s
    

    容器配额的底层实现

    cgroup实现资源配额,namespace实现资源隔离

    cgroup

    cgroup全称controller Group。linux操作系统通过cgroup可以设置进程使用CPU、内存和IO资源的限额。

    ## 1. 启动一个限定了cpu权重的容器
    root@fbo-virtual-machine:~# docker run -it --cpu-shares 512 progrium/stress -c 1
    stress: info: [1] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
    stress: dbug: [1] using backoff sleep of 3000us
    stress: dbug: [1] --> hogcpu worker 1 [5] forked
    ## 2. 找到容器的id
    root@fbo-virtual-machine:~# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    2a3aabf1e540        progrium/stress     "/usr/bin/stress -..."   12 seconds ago      Up 11 seconds                           epic_elion
    ## 3. 找到cgroup的配置文件
    root@fbo-virtual-machine:~# cat /sys/fs/cgroup/cpu/docker/2a3aabf1e54019501932410bda550f1cf38393f9313a800a58d4b581878f680a/cpu.shares 
    512
    

    namespace

    namespace 管理着 host 中全局唯一的资源,并可以让每个容器都觉得只有自己在使用它。换句话说,namespace 实现了容器间资源的隔离。

    Linux 使用了六种 namespace,分别对应六种资源:Mount、UTS、IPC、PID、Network 和 User:

    • Mount namespace - 让容器看上去拥有整个文件系统,容器有自己的根目录,不会影响到host和其他容器
    • UTS namespace - 让容器有自己的hostname。
    • IPC namespace - 让容器拥有自己的共享内存和信号量(semaphore)来实现进程间通信,而不会与 host 和其他容器的 IPC 混在一起。
    • PID namespace - 容器拥有自己独立的一套 PID。
    • Network namespace - 让容器拥有自己独立的网卡、IP、路由等资源。
    • User namespace - 让容器能够管理自己的用户,host 不能看到容器中创建的用户。

    使用--memory-swap限制内置配额时报错:
    Your kernel does not support cgroup swap limit.
    解决方法:
    https://docs.docker.com/installation/ubuntulinux/

    Edit the /etc/default/grub file.
    Set the GRUB_CMDLINE_LINUX value as follows:
    GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
    Save and close the file.
    Update GRUB.
    $ sudo update-grub
    Reboot your system.

    相关文章

      网友评论

          本文标题:Learning Docker Part 003 Dokcer容

          本文链接:https://www.haomeiwen.com/subject/jfddextx.html