《每天5分钟,玩转Docker容器技术》笔记

文|Seraph

01 | 容器生态环境概览

容器生态环境

  1. 安装(Ubuntu)
  • 安装docker依赖包:apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
  • 添加docker的官方GPG秘钥:curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  • 将docker源(稳定版本)添加到/etc/apt/sources.llistadd-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  • 更新apt包引用:apt-get update
  • 安装Docker Engine-Community 和 containerd :apt-get install docker-ce docker-ce-cli containerd.io
  1. 由于Docker Hub在国外,下载镜像会比较慢,DaoCloud提供国内镜像服务。
    注册账户并登陆后,点击右上角的小火箭打开加速器
    加速器
    拷贝下面的链接在相应的系统下执行即可。
    加速指令
    然后使用systemctl restart docker.service重启Docker deamon。

  2. 基本docker命令

命令 含义
docker run 运行容器
docker pull 拉取镜像
docker images 查看镜像
docker commit 提交容器更新至新的镜像,添加--no-cache参数表示不是用缓存。
docker build 构建镜像
docker history 查看镜像构建历史
docker tag 给镜像打标签
docker login 登录docker hub
docker push 上传image至docker hub
docker search 搜索Docker Hub中的镜像
docker rmi 删除Docker Host上的镜像
docker rm 删除容器
docker ps 查询Docker Host上运行的容器,加上-a查询所有的容器(包含停止的)
docker stop 停止容器
docker attch 直接进入容器启动命令的终端,不会打开新的终端
docker exec 在容器打开新的终端
docker logs 查看容器输出
docker start 启动容器
docker restart 重启容器
docker kill 终止容器
docker pause 暂停容器
docker uppause 恢复暂停的容器
docker create 创建容器
docker info 查看docker相关信息
docker inspect 查看容器信息
docker volume 查看容器挂载信息
docker cp 容器与host数据拷贝
docker top 查询容器内运行进程情况
docker stats 监控容器资源使用情况
docker save/load 导出/导入镜像
docker export/import 导出/导入容器

02 | 容器技术

  1. 容器由共享主机的内核系统,这个是与虚拟机最本质的区别。
    容器一般由两部分组成:应用程序本身、依赖(库等)。
    所以容器可以看成一个个相互隔离的进程。占用的体积也小。
  2. 容器最关键的特性是:可移植性。解决了不同环境下部署难得问题。
  3. Docker核心组件
    Docker核心组件

查询docker运行状态:systemctl status docker.service

  1. 修改远程登陆功能(应用场景应该很低)
  • 修改/etc/systemd/system/multi-user.target.wants/docker.service文件,在ExecStart后面添加-H tcp://0.0.0.0
  • 重启Docker daemon
systemctl daemon-reload
systemctl restart docker.service
  1. Docker镜像
    以Dockerfile构建而来,Dockerfile构建过程中,又是利用docker commit进行构建。

  2. docker run命令 = docker pull + 启动

03 | Docker镜像

一、 Dockerfile
  1. 指令
指令 含义
FROM 指定基础镜像
MAINTAINER 设置镜像作者
CMD 容器启动时运行指定的命令,只有最有一个CMD会生效,同事CMD会被docker run 之后的参数替换
RUN 运行指定指令
COPY 从build context复制文件到容器中
ADD 与COPY类似,但是src文件为归档文件(tar\zip\tgz等),会被自动解压
ENV 设置环境变量,环境变量可被后面的指令使用
EXPOSE 指定容器中的进程监听某个端口
VOLUME 将文件或目录声明为volume
WORKDIR 设置工作目录
ENTRYPOINT 设置容器启动时运行的命令,只有最后一个会生效,且CMD或docker run值后的运行参数会被当作参数传递给ENTRYPOINT
  1. 两种运行格式Shell和Exec格式:
    Shell格式(默认调用/bin/sh -c):<instruction> <command>
    Exec格式:<instruction> ["executable", "param1", "param2", ...]

  2. 由于每一层都会创建镜像层,当有些由于不同时间执行可能受影响的指令,需要和其他执行搭配在一样进行执行。
    比如apt update,不能单独占一行,否则会使用之前的镜像层。

  3. 当CMD与ENTRYPOINT配合使用时,CMD提供参数,ENTRYPOINT必须使用Exec格式。

二、原理
  1. 容器维护的是rootfs(用户空间),内核空间都是使用主机的Kernel,所以在容器内查询Kernel,都和主机一样。
    所以当容器本身应用对内核版本有要求的时候,不建议使用容器,推荐使用虚拟机。
三、构建镜像
  1. 一般能用官方或者别人创建稳定的镜像,一定要先用。没有才考虑自己构建容器。
    推荐使用Dockerfile方式构建镜像,不推荐使用docker commit方式创建。
    由于不能复用,再者使用者也不知道是创建出来的,无法对镜像进行审计。

  2. 每执行一条指令,对容器修改后,都会使用类似docker commit操作,新建镜像层。这样的话,如果其中某个指令执行失败,也能得到前一个指令执行后构建出来的镜像。

  3. 镜像是分层结构的,同时我们在容器中的修改只会保存在容器层。
    Copy-on-Write
    添加文件:在容器中创建文件,新文件被添加到容器层。
    读取文件:从容器层往下,再到镜像层,查找文件。
    修改文件:先如读取文件时一样查找文件,然后将文件复制到容器层进行修改。
    删除文件:先如读取文件时一样查找文件,在容器层中记录此删除操作。(实际上不删除文件)

四、分发镜像
  1. 每个repository可以有多个tag,所以当发新版本的时候,可以使用tag管理版本关系。
    我们可以把tag看成linux下的链接,为了我们用通用的名字使用特定的版本。
    Image的ID是唯一,如果使用docker images查询ID相同,说明是同一份镜像,只不过tag不一样而已。

  2. 搭建本地Registry
    docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:2
    repository的完整格式是:[registry-host]:[post]/[username],只不过Docker Hub可以省略。
    私人库其实就是在我们机器上启动一个Registry容器,使用上仅是要加上repostitory完整格式指明是哪个私人库,其它和访问Docker Hub一样。

04 | 容器

一、Run容器
  1. 当进程退出时(或OOM),Docker会根据--restart策略判断是否要重启容器。
  • 当加--restart=always参数时,表示无论容器什么原因退出,都会重启容器。
  • 当加--restart==on-failure:3参数时,表示容器退出非0时,则重启容器。
  1. 内存限制
  • -m:内存限制
  • --memory-swap:设置内存+swap的使用限制
  • -vm:启动内存工作线程数
  • -vm-bytes:每个线程分配内存数
  1. CPU限制
  • -c:CPU优先级,数字越大,占比越高。
  • --cpu:CPU数量
  1. block IO带宽限额
  • --blkio-weight:block IO权重。
  • --device-read-bps:限制读某个设备的bps
  • --device-write-bps:限制写某个设备的bps
  • --device-read-iops:限制读某个设备的iops
  • --device-write-iops:限制写某个设备的iops
    其中bps表示每秒读取多少byte。
    iops表示每秒IO的次数。

测试例子:
<1> 创建限制写/dev/sda的速率30M/s:docker run -it --device-write-bps /dev/sda:30MB ubuntu
<2> 在容器中运行dd测试:time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
progrium/stress压力测试镜像。

二、删除容器
  1. 删除所有停止的容器docker rm -v $(docker ps -qf status=exited)
三、实现容器的底层技术
  1. cgroup实现资源限额。
    cgroup的主目录为:/sys/fs/cgroup
    按cpu、memory、blkio等区分的多个子目录:
    每个容器的限额会在相应的子目录下的docker目录下新建一个以容器ID为名的目录。其中保存着该容器的限额信息。

  2. namespace实现资源隔离。
    隔离的资源有:Mount、UTS(hostname)、IPC(共享内存和信号量)、PID、Network、User。

04 | Docker网络

Docker容器安装时会自动在host上新建三个网络,用docker network ls可以查询到。
docker网络run参数:--network

一、 none网络

none网络表示在这个网络下的容器除了lo外,没有其他任何网卡。适用于需要网络隔离的场景

二、host 网络

host网络表示共享Docker host的网络栈。
使用host网络的有点是网络性能最好。但因为是和host共享网络栈,所以需要避免端口冲突。

三、bridge网络

Docker安装时会创建一个命名为docker0的linux bridge。我们新建的容器默认网络模式为bridge,所以会挂载到docker0上。不过虚拟网卡是成对的,一个在host上,与docker0连接;一个在容器内。

  1. 通过docker network inspect bridge命令可以查看网桥设置。
  2. brctl show查看网桥信息。
四、user-defined网络
  1. 可以使用docker network create创建网络
  • --driver:网络驱动,bridge、overlay和macvlan。
  • --subnet:指定子网。
  • --gateway:指定网关。
  • --ip:指定ip(前提已经使用–subnet指定了子网)
    eg. docker network create --driver bridge --subnet 172.22.16.0/24 --gatway 172.22.16.1 my_net2
  1. 使用docker network connect可以给容器添加网络。
    建立在同一个网络上的容器才能IP通信,所以当两个容器需要IP通信时,可以让其中一个容器添加另一个容器的网络即可。
五、容器间通信

容器间可通过IP、Docker DNS Server或joined容器三种方式通信。

  1. 建立在同一个网络上的容器即能IP通信。但是仅能通过静态IP。
  2. Docker DNS Server通信,可以给容器主机命名,通过对方的主机名与在一个user-defined网络(其它网络不行)上进行通信。
  3. joined容器,我们可以通过joined容器的形式与容器共享网络栈:docker run -it --network=container:容器名
六、与外部网络连接
  1. 我们默认以bridge模式建立的容器是能与外部网络连接的。其主要是docker0通过NAT方式与外部连接。
  2. 外部网络访问容器,通常是根据容器映射到host上的端口。
    每一个映射的端口,host都会启动一个docker-proxy进程来处理。

06 | Docker 存储

一、storage driver
  1. storage driver实现了多层数据的堆叠。docker支持多种storage driver实现,优先使用系统本身默认的storage driver,这个样稳定性更好。
二、Data Volume

对于需要持久化的数据(即使容器删除,数据也保留),需要使用Data Volume来处理。
有两种方式:bind mount、docker managed volume。

  1. bind mount
  • 使用方式:在docker run加入-v <host path>:<container path>[:读写属性]即可。
    其实就是目录映射。
  • Data Volume默认是可读可写,可以指定添加:ro只读
  • 缺点:需要指定目录,移植后如发现host没有指定目录会出错。
  1. docker managed volume
  • 使用方式:在docker run加入-v <container path>即可。docker会为容器自动生成host共享目录。
  • 当移植时,不会自动打包数据,只会生成相应的挂载目录。
  1. 另一种数据共享方式:volume container
    volume container的意识是专门为其它容器提供volume,其容器只需被create就行,不用run。
  • 新建volume容器示例:docker create --name vc_data -v ~/htdocs:/usr/local/apache2/htdocs -v /other/useful/tools busybox
  • 其它容器使用volume容器示例:docker run --name web1 -d -p 80 --volumes-from vc_data httpd
  1. 在Dockerfile文件中使用VOLUME、ADD添加共享文件或volume。(自包含的)
  2. volume删除
  • 删除容器是加上-v参数可以将容器使用到的volume也删除,但前提是没有其它容器也使用了。
  • 可以使用docker volume ls查询volume的情况。如果删除容器时,没有加-v参数,docker volume ls还是能查找volume存在的。
    如要继续删除,可以使用docker volume rm
  • 删除所有孤儿volume指令:docker volume rm $(docker volume ls -1)

07 | 多主机管理

docker machine,目前没有实际环境,后面再试。

99 | 问题解决
  1. 在ubuntu下使用--memory-swap会弹出Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.
    解决:尝试在aliyun服务器改动过配置文件,然后服务器就起不来了。。。。

猜你喜欢

转载自blog.csdn.net/pengshuyes/article/details/103531595