Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | 51CTO学院 | CSDN程序员研修院 | OSChina 博客 | 腾讯云社区 | 阿里云栖社区 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏多维度架构

第 2 章 Docker

目录

2.1. 安装 Docker
2.1.1. Rocky Linux 9.0 / AlmiLinux 9.0 / CentOS 8 Stream
2.1.2. Ubuntu docker-ce
2.1.3. 测试 Docker
2.1.4. 重置 Docker
2.1.5. 早起版本
2.2. Portainer - Docker 图形管理界面
2.2.1. 安装
2.2.2. 配置 Portainer
2.2.3. 添加代理出错
2.3. 配置 Docker
2.3.1. 开启远程访问
2.3.2. 镜像配置
2.3.3. DNS
2.3.4. ulimit 资源
2.4. docker 命令
2.4.1. docker - A self-sufficient runtime for containers
2.4.2. docker-compose - Define and run multi-container applications with Docker.
2.4.3. Docker Scan
2.5. 镜像管理
2.5.1. 搜索镜像
2.5.2. 获取镜像
2.5.3. 列出本地镜像
2.5.4. tag
2.5.5. 保存和载入镜像
2.5.6. 删除本地镜像
2.5.7. history 镜像历史纪录
2.5.8. format 用法
2.5.9. inspect
2.5.10. 查看镜像内容
2.6. 容器管理
2.6.1. 查看容器
2.6.2. 启动与终止容器
2.6.3. 进入容器
2.6.4. 运行容器内的命令
2.6.5. 导出和导入容器
2.6.6. 停止所有容器
2.6.7. 删除容器
2.6.8. log-driver
2.6.9. 操作系统
2.6.10. 查看容器内运行的进程
2.6.11. 更新容器资源配置
2.6.12. 查看容器的退出状态
2.6.13. 暂停与恢复容器
2.6.14. 对比容器的变化
2.6.15. 查看容器状态
2.6.16. 重启容器
2.6.17. DNS
2.7. 卷管理
2.7.1. 列出卷
2.7.2. 创建卷
2.7.3. 挂在镜像
2.7.4. 检查卷
2.7.5. 删除卷
2.7.6. 销毁所有未使用的卷
2.7.7. 在多个容器间共享卷
2.7.8. 容器绑定本地文件系统
2.7.9. 只读权限
2.8. Docker 网络管理
2.8.1. docker0 IP地址
2.8.2. 容器指定固定IP地址
2.8.3. 创建子网
2.8.4. 创建 overlay 网络
2.8.5. 网络命令空间
2.8.6. flannel 网络配置
2.9. 日志管理
2.9.1. 查看默认驱动
2.9.2. Fluentd 配置
2.9.3. Docker 配置
2.9.4. docker-compose 编排
2.9.5. 将日志输出到 /dev/stdout 和 /dev/stderr
2.10. Dockerfile
2.10.1. 基于 Dockerfile 创建镜像
2.10.2. 基于 Alpine 制作镜像
2.10.3. Dockerfile 缺失的工具
2.10.4. Dockerfile 语法
2.11. 仓库
2.11.1. Docker 官方仓库
2.11.2. 私有仓库
2.11.3. Harbor
2.12. Swarms
2.12.1. 管理 Swarms
2.12.2. Stack
2.12.3. 服务
2.12.4. swarm 卷管理
2.13. docker-compose.yml 容器编排
2.13.1. 版本号
2.13.2. 镜像
2.13.3. 容器名称
2.13.4. 启动策略
2.13.5. 容器用户
2.13.6. 挂在卷
2.13.7. 映射端口的标签
2.13.8. 添加 hosts 文件
2.13.9. 网络配置
2.13.10. links 主机别名
2.13.11. 链接外部容器
2.13.12. 服务依赖
2.13.13. working_dir
2.13.14. 设置环境变量
2.13.15. 临时文件系统
2.13.16. 编译 Dockerfile
2.13.17. resources 硬件资源分配
2.14. Docker Example
2.14.1. registry
2.14.2. Example Java - Spring boot with Docker
2.14.3. Redis
2.14.4. Nginx
2.14.5. MySQL
2.14.6. MongoDB
2.14.7. Node
2.15. Docker FAQ
2.15.1. 通过 IP 找容器
2.15.2. 常用工具
2.15.3. 检查 Docker 是否可用
2.15.4. Bitnami

https://www.docker.com

2.1. 安装 Docker

2.1.1. Rocky Linux 9.0 / AlmiLinux 9.0 / CentOS 8 Stream

安装 Docker

		
[root@netkiller ~]# dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
Adding repo from: https://download.docker.com/linux/centos/docker-ce.repo

[root@netkiller ~]# dnf install -y docker-ce docker-compose-plugin

[root@netkiller ~]# systemctl enable docker
[root@netkiller ~]# systemctl start docker
		
		

		
[root@netkiller ~]# docker -v
Docker version 19.03.12, build 48a66213fe
		
		

2.1.1.1. 添加容器管理员

			
GID=$(egrep -o 'docker:x:([0-9]+)' /etc/group | egrep -o '([0-9]+)')
adduser -u ${GID} -g ${GID} -G wheel -c "Container Administrator" docker		
			
			
			
[root@netkiller ~]# id docker
uid=986(docker) gid=986(docker) groups=986(docker),10(wheel)		
			
			

配置 sudo 无需密码

			
cat > /etc/sudoers.d/docker <<-EOF
docker    ALL=(ALL)    NOPASSWD: ALL			
EOF
			
			

检查 sudo 是否工作正常

			
[root@netkiller ~]# su - docker
Last login: Mon Mar 21 15:43:39 CST 2022 on pts/3

[docker@netkiller ~]$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES				

[docker@iZt4nazp2u494r8p1dr1zdZ ~]$ sudo ls /sbin
			
			

2.1.1.2. docker-compose 2.x

正常情况使用 docker-compose-plugin 安装

			
[root@netkiller ~]# dnf install -y docker-compose-plugin
			
			

如需手工安装

			
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
			
			

使用 docker compose version 命令查看版本好,确认 docker compose 被成功安装

			
[root@netkiller ~]# docker compose version
Docker Compose version v2.6.0

[root@netkiller ~]# alias docker-compose='docker compose'
[root@netkiller ~]# docker-compose version
Docker Compose version v2.6.0
			
			

2.1.1.3. 切换镜像

			
[root@netkiller ~]# cat << EOF > /etc/docker/daemon.json
> 
> {
>   "registry-mirrors": [
>     "https://hub-mirror.c.163.com",
>     "https://mirror.baidubce.com",
>     "https://docker.mirrors.ustc.edu.cn/"
>   ]
> }
> 
> EOF

[root@netkiller ~]# cat /etc/docker/daemon.json 

{
  "registry-mirrors": [
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com",
    "https://docker.mirrors.ustc.edu.cn/"
  ]
}

[root@netkiller ~]# systemctl restart docker

[root@netkiller ~]# docker info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)
  scan: Docker Scan (Docker Inc., v0.8.0)

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 20.10.7
 Storage Driver: overlay2
  Backing Filesystem: xfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: e25210fe30a0a703442421b0f60afac609f950a3
 runc version: v1.0.1-0-g4144b63
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 4.18.0-326.el8.x86_64
 Operating System: CentOS Stream 8
 OSType: linux
 Architecture: x86_64
 CPUs: 4
 Total Memory: 7.514GiB
 Name: netkiller
 ID: 5GBU:CMWS:VIVP:TREZ:Y5AP:OGOW:EABK:NP4R:AWUA:S4J2:2YQ2:U7MT
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Registry Mirrors:
  https://hub-mirror.c.163.com/
  https://mirror.baidubce.com/
  https://docker.mirrors.ustc.edu.cn/
 Live Restore Enabled: false			
			
			

2.1.2. Ubuntu docker-ce

从官方网站获得最新社区版

		
#!/bin/bash

sudo apt update

sudo apt remove docker docker-engine docker.io containerd runc

sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
	
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null


<!-- sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable" -->
   
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

apt-cache madison docker-ce
		
		

查看 docker 运行状态

		
root@production:~# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2021-08-17 11:25:04 CST; 57s ago
     Docs: https://docs.docker.com
 Main PID: 7379 (dockerd)
   CGroup: /system.slice/docker.service
           └─7379 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Aug 17 11:25:04 production dockerd[7379]: time="2021-08-17T11:25:04.708262132+08:00" level=info msg="ClientConn switching balancer to \"pick_first\"" module=grpc
Aug 17 11:25:04 production dockerd[7379]: time="2021-08-17T11:25:04.742384618+08:00" level=warning msg="Your kernel does not support swap memory limit"
Aug 17 11:25:04 production dockerd[7379]: time="2021-08-17T11:25:04.742397707+08:00" level=warning msg="Your kernel does not support CPU realtime scheduler"
Aug 17 11:25:04 production dockerd[7379]: time="2021-08-17T11:25:04.742489785+08:00" level=info msg="Loading containers: start."
Aug 17 11:25:04 production dockerd[7379]: time="2021-08-17T11:25:04.811316570+08:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.18.0.0/16. Daemon option --bip can be used 
Aug 17 11:25:04 production dockerd[7379]: time="2021-08-17T11:25:04.836024290+08:00" level=info msg="Loading containers: done."
Aug 17 11:25:04 production dockerd[7379]: time="2021-08-17T11:25:04.858428922+08:00" level=info msg="Docker daemon" commit=b0f5bc3 graphdriver(s)=overlay2 version=20.10.7
Aug 17 11:25:04 production dockerd[7379]: time="2021-08-17T11:25:04.858470910+08:00" level=info msg="Daemon has completed initialization"
Aug 17 11:25:04 production systemd[1]: Started Docker Application Container Engine.
Aug 17 11:25:04 production dockerd[7379]: time="2021-08-17T11:25:04.875279830+08:00" level=info msg="API listen on /var/run/docker.sock"		
		
		

启动参数配置 /etc/default/docker

		
neo@ubuntu:~$ cat /etc/default/docker
# Docker Upstart and SysVinit configuration file

#
# THIS FILE DOES NOT APPLY TO SYSTEMD
#
#   Please see the documentation for "systemd drop-ins":
#   https://docs.docker.com/engine/admin/systemd/
#

# Customize location of Docker binary (especially for development testing).
#DOCKERD="/usr/local/bin/dockerd"

# Use DOCKER_OPTS to modify the daemon startup options.
#DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"

# If you need Docker to use an HTTP proxy, it can also be specified here.
#export http_proxy="http://127.0.0.1:3128/"

# This is also a handy place to tweak where Docker's temporary files go.
#export DOCKER_TMPDIR="/mnt/bigdrive/docker-tmp"

		
		

启动脚本 /etc/init/docker.conf

		
neo@ubuntu:~$ sudo cat /etc/init/docker.conf
[sudo] password for neo: 
description "Docker daemon"

start on (filesystem and net-device-up IFACE!=lo)
stop on runlevel [!2345]

limit nofile 524288 1048576

# Having non-zero limits causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
limit nproc unlimited unlimited

respawn

kill timeout 20

pre-start script
	# see also https://github.com/tianon/cgroupfs-mount/blob/master/cgroupfs-mount
	if grep -v '^#' /etc/fstab | grep -q cgroup \
		|| [ ! -e /proc/cgroups ] \
		|| [ ! -d /sys/fs/cgroup ]; then
		exit 0
	fi
	if ! mountpoint -q /sys/fs/cgroup; then
		mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup
	fi
	(
		cd /sys/fs/cgroup
		for sys in $(awk '!/^#/ { if ($4 == 1) print $1 }' /proc/cgroups); do
			mkdir -p $sys
			if ! mountpoint -q $sys; then
				if ! mount -n -t cgroup -o $sys cgroup $sys; then
					rmdir $sys || true
				fi
			fi
		done
	)
end script

script
	# modify these in /etc/default/$UPSTART_JOB (/etc/default/docker)
	DOCKERD=/usr/bin/dockerd
	DOCKER_OPTS=
	if [ -f /etc/default/$UPSTART_JOB ]; then
		. /etc/default/$UPSTART_JOB
	fi
	exec "$DOCKERD" $DOCKER_OPTS --raw-logs
end script

# Don't emit "started" event until docker.sock is ready.
# See https://github.com/docker/docker/issues/6647
post-start script
	DOCKER_OPTS=
	DOCKER_SOCKET=
	if [ -f /etc/default/$UPSTART_JOB ]; then
		. /etc/default/$UPSTART_JOB
	fi

	if ! printf "%s" "$DOCKER_OPTS" | grep -qE -e '-H|--host'; then
		DOCKER_SOCKET=/var/run/docker.sock
	else
		DOCKER_SOCKET=$(printf "%s" "$DOCKER_OPTS" | grep -oP -e '(-H|--host)\W*unix://\K(\S+)' | sed 1q)
	fi

	if [ -n "$DOCKER_SOCKET" ]; then
		while ! [ -e "$DOCKER_SOCKET" ]; do
			initctl status $UPSTART_JOB | grep -qE "(stop|respawn)/" && exit 1
			echo "Waiting for $DOCKER_SOCKET"
			sleep 0.1
		done
		echo "$DOCKER_SOCKET is up"
	fi
end script
		
		
		

2.1.3. 测试 Docker

		
neo@MacBook-Pro ~ % docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete 
Digest: sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

neo@MacBook-Pro ~ % docker image ls 
REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
hello-world                                latest              fce289e99eb9        2 months ago        1.84kB

neo@MacBook-Pro ~ % docker container ls --all
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                          PORTS               NAMES
ea694b443e9e        hello-world         "/hello"            About a minute ago   Exited (0) About a minute ago                       dreamy_feistel
		
		

2.1.4. 重置 Docker

		
docker stop $(docker ps -a -q)
docker rm -f $(docker ps -a -q)
docker rmi -f $(docker images -q)
docker volume rm $(docker volume ls -q)	
		
		

2.1.5. 早起版本

2.1.5.1. CentOS 7 docker-ce

下载 containerd.io https://download.docker.com/linux/centos/7/x86_64/stable/Packages/

		
[root@netkiller ~]# yum install https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.2.el7.x86_64.rpm
		
			

从官方网站获得最新社区版

			
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum makecache fast
yum -y install docker-ce

systemctl start docker
			
			

测试安装是否成功

			
docker run hello-world
			
			

2.1.5.2. CentOS 6

			
yum install docker-io
service docker start
chkconfig docker on
docker pull centos:latest
docker images centos
			
			

test

			
docker run -i -t centos /bin/bash
			
			

2.1.5.3. Ubuntu

Ubuntu 默认版本

			
$ sudo apt update
$ sudo apt install docker.io
$ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
$ sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io
			
			
			
$ sudo docker run -i -t ubuntu /bin/bash