文章目录
Docker 服务器 Docker 镜像 Docker 容器 本地 Registry RUN vs CMD vs ENTRYPOINT
限制容器对内存、CPU 和 IO 资源的使用
cgroup 和 namespace cgroup namespac Mount namespace UTS namespace IPC namespace PID namespace Network namespace User namespace
Docker 服务器
systemctl status docker.service:查看 Docker daemon 服务状态 vim /etc/systemd/system/multi-user.target.wants/docker.service:修改 docker.service 配置 systemctl daemon-reload:重新加载 Docker daemon 配置 systemctl restart docker.service:重启 Docker daemon 服务 docker -H 192.168.138.132 info:通过命令行与 Docker daemon 通信,查看 Docker 服务器的信息
Docker 镜像
docker pull httpd:从 Registry 下载镜像 docker inspect xxxxx:用于查看容器、镜像、网络或数据卷的详细信息 dcoker run hello-world
docker run -d -p 8080:80 httpd:先下载镜像(如果本地没有),然后再启动容器。 docker run -it 镜像名:以交互模式进入容器,并打开终端 docker images [centos][-a]:查看镜像,-a 会显示所有中间镜像 Docker 容器的 ubuntu 镜像配置 apt 国内源
sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
sed -i s@/security.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
apt-get clean
apt-get update
apt-get install -y vim:安装 vim,并跳过安装提示 docker commit wonderful_sa ubuntu_with_vi:将容器保存为镜像 docker rmi [-f] 容器id:删除镜像(先停止容器才能删除)。如果一个镜像对应了多个 tag,只有当最后一个 tag 被删除时,镜像才被真正删除。 touch Dockerfile:创建Dockerfile文件 docker build -t ubuntu-with-vi-dockerfile . :运行 docker build 命令,-t 将新镜像命名为 ubuntu-with-vi-dockerfile,命令末尾的 . 指明 build context 为当前目录。Docker 默认会从 build context 中查找 Dockerfile 文件,我们也可以通过 -f 参数指定 Dockerfile 的位置。 docker history ubuntu-with-vi-dockerfile:显示镜像的构建历史 docker build -t --no-cache ubuntu-with-vi-dockerfile-2 . 根据当前目录下的 dockerfile 构建镜像,不使用缓存 docker tag aaa:latest bbb:1:修改镜像的REPOSITORY和TAG docker search httpd:搜索 Docker Hub 中的镜像。
Docker 容器
docker attach:进入容器的启动命令终端,不会启动新的进程。如果想直接在终端中查看启动命令的输出,用 attach;其他情况使用 exec。 docker exec -it container bash :在容器中打开新的终端,并且可以启动新的进程。 docker logs -f container:如果只是为了查看启动命令的输出,可以使用 docker logs 命令。-f 的作用与 tail -f 类似,能够持续打印输出。 docker ps -a/ docker container ls -a:查看正在运行的容器,-a 会显示所有状态的容器。 ctrl + p + q :退出容器 docker run hello-world
docker run -d -p 8080:80 httpd:先下载镜像(如果本地没有),然后再启动容器。服务类容器通过 -d 以后台方式启动是非常合适的。 docker run -it 镜像名:以交互模式进入容器,并打开终端。退出 Shell(输入 exit 或 Ctrl+D):主进程(bash)终止 → 容器停止。若你不退出 Shell:容器会保持运行(因为主进程未终止)。工具类容器通常给能我们提供一个临时的工作环境,通常以 run -it 方式运行。工具类容器多使用基础镜像,例如 busybox、debian、ubuntu 等。 docker run --name my_nginx_container nginx:–name 参数显示地为容器命名,如果不指定,docker 会自动为容器分配名字。 docker run -d \ –name mysql-container \ -e MYSQL_ROOT_PASSWORD=my-secret-pw \ -p 3306:3306 \ -v /path/on/host:/var/lib/mysql \ mysql:latest docker run -d --restart=always httpd:无论容器因何种原因退出(包括正常退出),就立即重启。 只有当容器的启动进程退出时,–restart 才生效。 如果容器是因为执行 docker stop 或docker kill 退出,则不会自动重启。 docker stop/kill 镜像名:停止容器。kill 会快速停止容器。 docker create mysql-container:创建的容器处于 Created 状态。docker run 命令实际上是 docker create 和 docker start 的组合。 docker start/restart mysql-container:重新启动容器。 docker pause/unpause mysql-container:暂停容器/恢复运行容器。 docker rm container1 container2 container3:删除容器。
docker rm -v $(docker ps -aq -f status=exited):批量删除所有已经退出的容器。
本地 Registry
docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:2:-d 是后台启动容器。-p 将容器的 5000 端口映射到 Host 的 5000 端口。5000 是 registry 服务端口。-v 将容器 /var/lib/registry 目录映射到 Host 的 /myregistry,用于存放镜像数据。 docker tag hanfei/httpd:1 ubuntu:5000/hanfei/httpd:1:repository 的完整格式为:[registry-host]:[port]/[username]/xxx。只有 Docker Hub 上的镜像可以省略 [registry-host]:[port] 。在 Docker 主机上,可以使用 hostname 命令查看主机的名称。
RUN vs CMD vs ENTRYPOINT
RUN
RUN 指令通常用于安装应用和软件包,构建镜像 。RUN 有两种格式:
(1)Shell 格式:
RUN [ "apt-get" , "install" , "python3" ]
(2)Exec 格式:
RUN apt-get install python3
RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion
CMD
CMD 指令通常用于设置容器启动后默认执行的命令及其参数。 CMD 能够被 docker run 后面跟的命令行参数替换。如果 Dockerfile 中有多个 CMD 指令,只有最后一个 CMD 有效。 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。
(1)Exec 格式:
CMD [ "executable" ,"param1" ,"param2" ]
(2)CMD [ "param1" ,"param2" ] 为 ENTRYPOINT 提供额外的参数,此时 ENTRYPOINT 必须使用 Exec 格式。
CMD [ "world" ]
(3)Shell 格式(不推荐)
ENTRYPOINT
ENTRYPOINT 配置容器启动时运行的命令。让容器以应用程序或者服务的形式运行。 ENTRYPOINT 看上去与 CMD 很像,它们都可以指定要执行的命令及其参数。不同的地方在于 ENTRYPOINT 不会被忽略,一定会被执行,即使运行 docker run 时指定了其他命令。 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。
(1)使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。
ENTRYPOINT [ "/bin/echo" , "Hello" ]
CMD [ "world" ]
(2)Shell 格式(不推荐)
ENTRYPOINT 的 Shell 格式会忽略任何 CMD 或 docker run 提供的参数。
限制容器对内存、CPU 和 IO 资源的使用
内存
docker run -m 200M --memory-swap= 300M ubuntu
docker run -it -m 200M --memory-swap= 300M progrium/stress --vm 1 --vm-bytes 280M
CPU
通过 -c 或 --cpu-shares 设置容器使用 CPU 的权重。如果不指定,默认值为 1024。 通过 -c 设置的 cpu share 并不是 CPU 资源的绝对数量,而是一个相对的权重值。某个容器最终能分配到的 CPU 资源取决于它的 cpu share 占所有容器 cpu share 总和的比例。换句话说:通过 cpu share 可以设置容器使用 CPU 的优先级。 权重分配 CPU 只会发生在 CPU 资源紧张的情况下。如果 container_A 处于空闲状态,这时,为了充分利用 CPU 资源,container_B 也可以分配到全部可用的 CPU。
docker run --name "container_A" -c 1024 ubuntu
docker run --name "container_B" -c 512 ubuntu
Block IO
Block IO 指的是磁盘的读写,docker 可通过设置权重、限制 bps 和 iops 的方式控制容器读写磁盘的带宽。目前 Block IO 限额只对 direct IO(不使用文件缓存)有效。
设置权重
默认情况下,所有容器能平等地读写磁盘,可以通过设置 --blkio-weight 参数来改变容器 block IO 的优先级,设置的是相对权重值,默认为 500。
docker run -it --name container_A --blkio-weight 600 ubuntu
docker run -it --name container_B --blkio-weight 300 ubuntu
bps 和 iops
bps 是 byte per second,每秒读写的数据量。 iops 是 io per second,每秒 IO 的次数。
–device-read-bps,限制读某个设备的 bps。 –device-write-bps,限制写某个设备的 bps。 –device-read-iops,限制读某个设备的 iops。 –device-write-iops,限制写某个设备的 iops。
docker run -it --device-write-bps /dev/sda:30MB ubuntu
time dd if = /dev/zero of = test.out bs = 1M count = 800 oflag = direct
cgroup 和 namespace
cgroup 实现资源限额, namespace 实现资源隔离。
cgroup
cgroup 全称 Control Group。Linux 操作系统通过 cgroup 可以设置进程使用 CPU、内存 和 IO 资源的限额。–cpu-shares、-m、–device-write-bps 实际上就是在配置 cgroup。
/sys/fs/cgroup/cpu/docker/容器长ID:目录中包含所有与 cpu 相关的 cgroup 配置。 /sys/fs/cgroup/memory/docker/容器长ID:目录中包含所有与 memory 相关的 cgroup 配置。 /sys/fs/cgroup/blkio/docker/容器长ID:目录中包含所有与 blkio 相关的 cgroup 配置。
namespac
在每个容器中,我们都可以看到文件系统,网卡等资源,这些资源看上去是容器自己的。拿网卡来说,每个容器都会认为自己有一块独立的网卡,即使 host 上只有一块物理网卡。这种方式非常好,它使得容器更像一个独立的计算机。Linux 实现这种方式的技术是 namespace。namespace 管理着 host 中全局唯一的资源,并可以让每个容器都觉得只有自己在使用它。换句话说,namespace 实现了容器间资源的隔离。Linux 使用了六种 namespace,分别对应六种资源:Mount、UTS、IPC、PID、Network 和 User。
Mount namespace
容器有自己的 / 目录,可以执行 mount 和 umount 命令。当然我们知道这些操作只在当前容器中生效,不会影响到 host 和其他容器。
1 .你插入了一个 U 盘,系统识别它为 /dev/sdb1。
2 .你执行命令:
mount /dev/sdb1 /mnt
3 .现在,你可以通过 /mnt 访问 U 盘里的文件了:
ls /mnt
4 .当你用完 U 盘后,可以卸载它。这样,U 盘就“关门”了,/mnt 目录下不再显示 U 盘的内容:
umount /mnt
UTS namespace
让容器有自己的 hostname。 UTS namespace 为每个Docker容器设置了一个独立的主机名和域名。这使得每个容器都能够被视为网络上的一个独立节点,从而简化了应用的访问和管理,并增强了应用之间的隔离性和安全性。
docker run -h/--hostname myhost -it ubuntu
IPC namespace
IPC namespace 让容器拥有自己的共享内存和信号量(semaphore)来实现进程间通信,而不会与 host 和其他容器的 IPC 混在一起。
PID namespace
容器在 host 中以进程的形式运行。 容器中进程的 PID 不同于 host 中对应进程的 PID,容器中 PID=1 的进程当然也不是 host 的 init 进程。也就是说:容器拥有自己独立的一套 PID,这就是 PID namespace 提供的功能。
ps axf
docker exec -it container bash
Network namespace
User namespace
让容器能够管理自己的用户,host 不能看到容器中创建的用户。