【docker基础知识】docker基础概念

1. docker 分层概念

    linux 操作系统由内核空间和用户空间组成。

  • 内核空间:kernel,Linux 刚启动时会加载 bootfs 文件系统,之后 bootfs 会被卸载
  • 用户空间:文件系统是 rootfs,包含 /dev, /proc, /bin 等

       对与基础镜像,底层直接使用 Host 的 kernel,而自己只需要提供 rootfs 。

     容器只能共用 Host kernel,不能修改。容器共用 host kernel,容器不能 kernel 升级。如果容器 kernel 版本有要求,这种更适合虚拟机。

 

  1.1 为什么镜像采用分层结构

     好处就是共享资源

【docker基础知识】docker基础概念_第1张图片      新镜像从 base 镜像一层一层叠加生成的。每RUN一次,就在现有镜像的基础上增加一层。

      只需在磁盘上保存一份 base 镜像;内存中也只需一份 base 镜像,就可以为所有容器使用。而且镜像的每一层都可以被共享

       当需要修改时才拷贝数据,这种称作 Copy-on-Write。

 

2 Dockerfile 指令

COPY
     将文件从 build context 复制到镜像。支持两种形式:

  • COPY src dest
  • COPY ["src", "dest"]

     注意:src 只能指定 build context 中的文件或目录

ADD
     从 build context 复制文件到镜像。不同的是,如果 src 是归档文件,文件会被自动解压到 dest。

ENV
     设置环境变量,环境变量可被后面的指令使用。

       WORKDIR
            为后面指令设置镜像中的当前工作目录。

CMD
      容器启动时运行指定的命令。
      Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 可以被 docker run 之后的参数替换

ENTRYPOINT
      设置容器启动时运行的命令。
      Dockerfile 中可以有多个 ENTRYPOINT,只有最后一个生效。CMD 或 docker run 之后的参数会被当做参数传递给 ENTRYPOINT。

 

3 Docker 命令

attach vs exec

  • attach 直接进入容器启动命令的终端,不会启动新的进程
  • exec 是在容器中打开新的终端,并且可以启动新的进程

      如果想直接在终端中查看启动命令的输出,用 attach;其他情况使用 exec。

stop start restart

       stop 命令向该进程发送一个 SIGTERM 信号。如果想快速停止容器,用 docker kill 命令,向容器进程发送 SIGKILL 信号,docker pause命令则不一样,它利用了cgroups的特性将运行中的进程空间暂停。

      容器可能会因某种错误而停止运行。对于服务类容器能够自动重启。启动容器时设置 --restart = always 就可以

rm

     批量删除所有已经退出的容器,可以执行如下命令:      

     docker rm $(docker ps -aq)

     docker rm -v $(docker ps -aq -f status=exited)

    build 命令根据 Dockerfile 文件中的 FROM 指令获取到镜像,然后重复地(create和start),修改,commit。在循环中的每一步都会生成一个新的层,因此许多新的层会被创建。

    docker exec 命令会在运行中的容器执行一个新进程。

    docker inspect命令会提取出容器或者镜像最顶层的元数据。 

     在 Docker 容器中的初始化进程(PID1 进程)在容器进程管理上具有特殊意义。它可以被 Dockerfile 中的 ENTRYPOINT 或 CMD 指令所指明;也可以被docker run 命令的启动参数所覆盖。

       

4 Docker 内存限额

      容器使用的内存包括两部分:物理内存和 swap。 Docker 两组参数来控制容器内存:

  • -m 或 --memory:内存的使用限额,例如 100M, 2G。
  • --memory-swap:内存+swap 的使用限额。

      例如运行命令如下:

      $ docker run --memory=100M --memory-swap=200M progrium/stress --vm 1 --vm-bytes 90M

      如果在启动容器时只指定 -m 而不指定 --memory-swap,那么 --memory-swap 默认为 -m 的两倍

5 Docker CPU 限额  

        通过 -c 或 --cpu-shares 设置容器使用 CPU 的权重。如果不指定,默认值为 1024。

        容器能分配到的 CPU 资源取决于它的 cpu share 占所有容器 cpu share 总和的比例。换句话说:通过 cpu share 可以设置容器使用 CPU 的优先级。

  

6 Docker Block IO 限额  

       Block IO:指的是磁盘的读写,docker 可以通过设置权重,限制bpsiops的方式控制容器读写磁盘的带宽

      注:目前block IO限额只对direct IO不使用文件缓存)有效。

   Block IO权重:--blkio-weight,这个--blkio-weight的权重值在  10~1000之间

      和容器cpu的使用机制是一致的,所有容器都可以平等的读写磁盘,可以通过--blkio-weight参数来改变容器的优先级

     --blkio-weight和-c类似,设置的都是资源使用的权重,都是在资源紧张的情况下才会起到权重的作用,正常情况下,都是平等的

  • bps:byte per second ,每秒读写的数据量
  • iops:io per second ,每秒IO次数

  可以通过以下参数来控制容器的bps 和iops:

  • --device-read-bps:限制读某个设备的bps(数据量)   例:docker run -d  --device-read-bps /dev/sdb:30M  httpd
  • --device-write-bps : 限制写入某个设备的bps(数据量) 例:docker run -d --device-write-bps dev/sdb:30M httpd
  • --device-read-iops :限制读某个设备的iops(次数) 例:docker run -d --device-read-iops /dev/sdb
  • --device-write-iops :限制写入某个设备的iops(次数)

 

7 Docker 网络

Docker 安装会在 host 上创建三个网络,docker network ls 命令查看:

【docker基础知识】docker基础概念_第2张图片none

       这个网络下的容器除了 lo,没有其他任何网卡。容器创建时,--network=none 使用 none 网络  

host

       容器共享 host 的网络栈,容器的网络配置与 host 完全一样。--network=host 使用 host 网络。

        最大的好处就是性能,适用的情况容器对网络传输效率有较高要求

 

7.1 创建网络

 

       网络驱动:bridge, overlay 和 macvlan。overlay 和 macvlan 用于创建跨主机的网络

       docker network create --driver bridge --subnet 172.200.200.0/24 --gateway 172.200.200.1 bridge_ne

 

       可以使用新创建的网络如下所示:

       docker run --network bridge_net

       静态IP 分配 --ip 

       容器添加网卡:

       docker network connect $network $docker_id

 

7.2 网络基础

  1. 网络命名空间
  2. veth 设备对
  3. Iptables / Netfilter
  4. 网桥
  5. 路由

Docker 容器中的各类网络栈设备都是 Docker Daemon 在启动时自动创建和配置的

网络命名空间代表的是一个堵路的协议栈,彼此之间相互隔离,无法通信:Veth 设备对就是打通互相看不到的协议栈 (不同命名空间进行通信)【docker基础知识】docker基础概念_第3张图片

 

8 Docker 信号处理

     执行 docker stop 命令,docker 首先向容器的 PID1 进程发送一个SIGTERM信号,用于容器内程序的退出。如果容器在收到 SIGTERM 后没有结束, 那么 Docker Daemon 会在等待一段时间(默认是10s)后,再向容器发送 SIGKILL 信号,将容器杀死变为退出状态。这种方式给 Docker 应用提供了退出(graceful stop)机制,允许应用在收到 stop 命令时清理和释放使用中的资源。而 docker kill 可以向容器内 PID1 进程发送任何信号,缺省是发送 SIGKILL 信号来强制退出应用。

    由于 PID1 进程的特殊性,Linux 内核做了特殊处理。如果它没有提供某个信号的处理逻辑,那么与其在同一个PID 名空间下的进程发送给它的该信号都会被屏蔽。主要是防止 init 进程被误杀。

  8.1 孤儿进程

     当一个子进程终止后,首先会变成一个失效(defunct)的进程,也称为僵尸 zombie 进程,等待父进程或系统收回。在 Linux 内核中维护了关于僵尸进程的信息(PID,终止状态,资源使用信息),从而允许父进程能够获取子进程的信息。如果不能正确回收僵尸进程,那么他们的进程描述符仍然保存在系统中,系统资源会缓慢泄露。

    执行 docker stop 命令,docker 首先向容器的 PID1 进程发送一个SIGTERM信号,用于容器内程序的退出。如果容器在收到 SIGTERM 后没有结束, 那么 Docker Daemon 会在等待一段时间(默认是10s)后,再向容器发送 SIGKILL 信号,将容器杀死变为退出状态。这种方式给 Docker 应用提供了退出(graceful stop)机制,允许应用在收到 stop 命令时清理和释放使用中的资源。而 docker kill 可以向容器内 PID1 进程发送任何信号,缺省是发送 SIGKILL 信号来强制退出应用。

  8.2 信号与init进程

    当容器内的init进程可以对信号进行捕获,当SIGTERM或SIGINT等信号,对其子进程做信息保存,资源回收等处理。    

 

9. docker run参数

docker version:  17.12.1-ce

Usage:    docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

      Run a command in a new container

Options:
      --add-host list                        为容器添加host与ip的映射关系
  -a, --attach list                           容器的用户
      --blkio-weight uint16            限制容器读写权重,权重值在10~1000之间,0为关闭权重(该参数默认为0)                                                                                            默认,所有的容器对于 IO 操作都拥有相同优先级。
      --blkio-weight-device list     设置设备的权重,权重值在10~1000之间,且优先级高于blkio.weigh (docker run --blkio-weight-device "/dev/sda:100" )
      --cap-add list      添加权限 http://linux.die.net/man/7/capabilities  (在docker容器内限制了大部分的linux权限,在之前,需要开启这些功能需要结合--privileged开启特权模式才能使用这些参数,考虑到安全性,可以通过该参数来开启指定的linux功能,若参数为all则默认开启所有linux权限)
      --cap-drop list     删除权限 http://linux.die.net/man/7/capabilities  
      --cgroup-parent string        配置容器的控制组,继承该控制组的资源限制模式
      --cidfile string                       运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法(若该文件存在,则会返回一个错误)           
      --cpu-period int                   与参数--cpu-quota配合使用,设定cpu从新分配资源的时间周期,时间周期结束后,会对cpu进行重新分配。
      --cpu-quota int                    与参数--cpu-period配合使用,设定容器在资源分配周期内占用cpu的时间,若容器设定--cpu-quota=1000000 --cpu-period=500000,则该容器在这个时间周期内权重为50%,容器的权重比,用来解决宿主机内若干容器的资源抢占导致重要容器cpu性能不足的场景(Linux 的CFS模式)
      --cpu-rt-period int              为--cpu-period量级微妙
      --cpu-rt-runtime int            在一个cpu资源分配周期内,优先保证某容器的cpu使用的最大微秒数。例如,默认周期为 1000000 微秒(1秒),设置 --cpu-rt-runtime=800000 可确保使用实时调度程序的容器每 1000000 微秒可运行 800000 微秒,并保留至少 200000 微秒用于非实时任务
  -c, --cpu-shares int                设置容器CPU权重,在CPU共享场景使用
      --cpus decimal                   设置容器使用cpu的数量,该参数为1.3新增参数用于快速设置容器对于cpu的占用
      --cpuset-cpus string          设置容器可以使用哪些CPU,此参数可以用来容器独占CPU  
      --cpuset-mems string        同参数--cpuset-cpus,但该参数是作用于NUMA 架构的 CPU
  -d, --detach                             容器运行于前台还是后台默认为false   
      --detach-keys string          设置容器的键盘映射键位,在容器被链接到前台时,若宿主机的键盘键位与容器键位冲突,可以使用该指令对容器的键位进行重新映射
      --device list                           添加主机设备给容器,相当于设备直通,将宿主机的设备映射至容器
      --device-cgroup-rule list    将宿主机的设备添加到cgroup规则列表中
      --device-read-bps list         以字节数/每秒的形式限制设备的读取速率 (docker run --device-read-bps /dev/sda:100KB)
      --device-read-iops list        以每秒所执行IO操作的次数的形式限制设备的读取速率
      --device-write-bps list         以字节数/每秒的形式限制设备的写入速率
      --device-write-iops list        以每秒所执行IO操作的次数的形式限制设备的写入速率
      --disable-content-trust        忽略镜像的校验 (default true)
      --dns list                                指定容器的dns服务器,默认和宿主一致
      --dns-option list                   设置DNS选项,同修改/etc/resolv.conf文件
      --dns-search list                 指定容器的dns搜索域名,默认和宿主一致,写入到容器的/etc/resolv.conf文件  
      --entrypoint string               覆盖image的入口点  
  -e, --env list                                       环境变量
      --env-file list                                  指定环境变量文件,文件格式为每行一个环境变量
      --expose list                                   指定容器暴露的端口,即修改镜像的暴露端口  
      --group-add list                             为容器添加用户组
      --health-cmd string                       执行一个健康检查命令
      --health-interval duration            设置健康检查的执行的间隔时间 (ms|s|m|h) (default 0s)
      --health-retries int                         健康检查命令失败重试的次数
      --health-start-period duration   Start period for the container to initialize before starting health-retries
                                       countdown (ms|s|m|h) (default 0s)
      --health-timeout duration            设置健康检查命令超时时间 (ms|s|m|h) (default 0s)
      --help                           Print usage
  -h, --hostname string            容器的主机名
      --init                                     使用init在容器中新增一个守护进程,来预防该容器出现僵尸进程的可能性
  -i, --interactive                       打开STDIN,用于控制台交互  
      --ip string                            IPv4 address (e.g., 172.30.100.104)
      --ip6 string                          IPv6 address (e.g., 2001:db8::33)
      --ipc string                          启用ipc命名空间。容器中进程交互采用了Linux进程间交互方法(interprocess communication - IPC), 包括信号量、消息队列和共享内存等。容器的进程间交互实际上还是host上具有相同pid命名空间中的进程间交互,因此需要在IPC资源申请时加入命名空间信息,每个IPC资源有一个唯一的32位id。

      --isolation string               使用容器隔离
                                                       default 与使用dockerd --exec-opt的参数默认效果相同
                                                       process 使用linux内核命名空间进行隔离,该参数不支持windows环境。
      --kernel-memory bytes   限制该容器内核的内存使用
  -l, --label list                          设置该容器的元数据
      --label-file list                    通过本地文件导入元数据至该容器
      --link list                              指定容器间的关联,使用其他容器的IP、env等信息
      --link-local-ip list               设置本地链路地址(link-local address)ip
      --log-driver string             设置一个指定日志接受工具,用于动态收集日志。扩展阅读日志处理与log-driver实现
      --log-opt list                       用于设置日志输出参数
      --mac-address string       设置该容器mac地址
  -m, --memory bytes                         容器的内存上限  
      --memory-reservation bytes      软限制该容器的内存使用,当宿主机内存空闲时,该容器的内存使用可以一定比例超出限制,但当宿主机内存紧张时,会强制该容器内存使用限制在该参数之内
      --memory-swap bytes                内存交换分区大小限制。配合参数--memory使用,且最小内存交换限制应该大于内存限制。该参数有4种情况:(1)不设置--memory与该参数:则该容器默认可以用完宿舍机的所有内存和 宿主机 swap 分区。

  • (2)设置--memory 50MB 不设置--memory-swap(默认为0):则--memory-swap值等于限制内存大小,即该容器能够申请的最大内存为100MB。
  • (3)设置--memory 50MB --memory-swap为-1:则该容器最大可以申请的内存为50MB+宿主机swap分区大小
  • (4)设置--memory 50MB --memory-swap 100MB:则该容器可以申请的最大内存为100MB-50MB=50MB


      --memory-swappiness int         用于调整虚拟内存的控制行为,为0~100之间的整数。在linux内存管理中,将内存中不活跃的页交换至硬盘中,以缓解内存紧张,该参数设置为0则认定该容器所有内存中的内容均不允许交换至硬盘,用以保障最大性能,若设置为100,则认为该容器所有内存中的数据均可以交换至硬盘。扩展阅读Linux内存管理

      --mount mount                    将文件系统挂载附加到容器
      --name string                      指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字  
      --network string                  容器网络设置:
                                                                  bridge 使用docker daemon指定的网桥     
                                                                  host     //容器使用主机的网络  
                                                                  container:NAME_or_ID  >//使用其他容器的网路,共享IP和PORT等网络资源  
                                                                  none 容器使用自己的网络(类似--net=bridge),但是不进行配置 
      
      --network-alias list            设置该容器在网络上的别名
      --no-healthcheck              禁止一切健康检查行为
      --oom-kill-disable             设置是否禁止oom kill行为,若该容器因为需要大量请求内存,导致宿主机内存不足或触发到内存限制,导致杀死该容器进程,若设置该参数为true则会关闭这个检查
      --oom-score-adj int          调整主机的OOM首选项(从-1000到1000)不建议用户修改--oom-score-adj--oom-kill-disable
      --pid string                    自定义设置该容器的pid namespace
      --pids-limit int               该参数值为整数,为限制该容器所能创建的最大进程数。
      --privileged                   指定容器是否为特权容器,特权容器拥有所有的capabilities  
  -p, --publish list        容器暴露的端口 
  -P, --publish-all         容器暴露所有端口到宿主机随机端口 
      --read-only            设置该容器只读
      --restart string       指定容器停止后的重启策略:
                                            no:容器退出时不重启  
                                            on-failure:容器故障退出(返回值非零)时重启 
                                            always:容器退出时总是重启  
      --rm                                指定容器停止后自动删除容器(不支持以docker run -d启动的容器)  
      --runtime string            指定该容器关联一个runtime的容器
      --shm-size bytes          设置/dev/shm/目录的大小
      --sig-proxy                    设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理
      --stop-signal string      停止带有信号的容器,在linux环境下输入kill -l,就可以看到所有信号名称,可以指定容器发出某种信号时停止该容器,譬如SIGKILL (default "SIGTERM")
      --stop-timeout int          设置容器调用命令超时后自动退出。该参数可以设置容器在调用命令时导致超时后多少秒退出,0为永远不退出,该参数单位为秒
      --storage-opt list            设定该容器的存储空间,可以分别指定dm.basesize、dm.loopdatasize、dm.loopmetadatasize等项,指定单个容器可用数据空间、元数据可用数据空间。
      --sysctl map                    修改内核参数,对应修改容器中的/etc/sysctl.conf文件
      --tmpfs list                    指定挂载一个tmpfs目录,tmpfs是一种虚拟内存文件系统。可以不经由镜像直接创建一个容器
  -t, --tty                                         分配tty设备,持终端登录默认为false  
      --ulimit ulimit               设置容器的ulimit选项
  -u, --user string               该容器下添加新用户 (format: [:])
      --userns string             指定该容器运行在指定user namespace中
      --uts string                    使用uts命名空间
  -v, --volume list                    容器挂载存储卷,挂载到容器的某个目录  
      --volume-driver string     默认 volume loclal,主机上的一个目录 mount 到容器内的一个目录,不具备可移植性
      --volumes-from list          给容器挂载其他容器上的卷,挂载到容器的某个目录
  -w, --workdir string              容器的工作目录 

 

你可能感兴趣的:(Docker)