1 数据管理
1.1 数据卷
数据卷
是一个可供一个或多个容器使用的特殊目录
数据卷
绕过了 UnionFS,可以在容器之间共享和重用- 对
数据卷
的修改会立马生效;对数据卷
的更新,不会影响镜像 数据卷
默认会一直存在,即使容器被删除(类似于mount
命令)
数据卷的常见操作:
docker volume create my-vol # 创建一个数据卷
docker volume ls # 查看所有的数据卷
docker volume inspect my-vol # 查看指定数据卷的信息
# 创建一个名为`web`的容器,并加载`数据卷`到容器的`/usr/share/nginx/html`目录
docker run -d -P \
--name web \
# -v my-vol:/usr/share/nginx/html \
--mount source=my-vol,target=/usr/share/nginx/html \
nginx:alpine
docker volume rm my-vol # 删除一个数据卷
docker volume prune # 批量清理无主的数据卷
1.2 挂载主机目录
挂载一个主机目录:
docker run -d -P \
--name web \
# -v /src/webapp:/usr/share/nginx/html \
--mount type=bind,source=/src/webapp,target=/usr/share/nginx/html \
nginx:alpine
- 本地目录的路径必须是绝对路径,本地目录不存在时以上命令会报错
- 挂载目录的默认权限是
读写
,用户可以通过参数readonly
指定为只读
- 使用
docker inspect
命令可以查看容器的挂载目录(”Mounts“下的内容)
--mount
命令也支持挂载单个文件到容器中:
docker run --rm -it \
# -v $HOME/.bash_history:/root/.bash_history \
--mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history \
ubuntu:18.04 \
bash
root@2affd44b4667:/# history
1 ls
2 diskutil list
2 使用网络
Docker 允许通过外部访问容器或容器互联的方式来提供网络服务
2.1 容器端口映射
容器通过 -P
或 -p
参数来指定端口映射,以方便从外部访问应用
常见端口映射命令:
docker run -d -p 80:80 nginx:alpine # 端口映射80:80
docker run -d -p 127.0.0.1:80:80 nginx:alpine # 端口映射指定ip
docker run -d -p 127.0.0.1::80 nginx:alpine # 自动分配外部端口
docker run -d -p 127.0.0.1:80:80/udp nginx:alpine # 指定udp端口
docker port fa 80 # 查看当前映射的端口配置
docker run -d -p 80:80 -p 443:443 nginx:alpine # 绑定多个端口
2.2 容器互联
使用 --link
参数可以实现容器互联,但现在更建议荐通过 Docker 网络来连接多个容器
通过自定义的 Docker 网络实现容器互联:
docker network create -d bridge my-net # 创建一个新的Docker网络
# 运行两个容器并同时连接到新建的 `my-net` 网络
docker run -it --rm --name busybox1 --network my-net busybox sh
docker run -it --rm --name busybox2 --network my-net busybox sh
# 在 `busybox1` 容器输入以下命令来证明容器实现了互联
ping busybox2
# 同理在 `busybox2` 容器执行 `ping busybox1`,也会成功连接到
# 这样 `busybox1` 容器和 `busybox2` 容器建立了互联关系
-d
参数指定 Docker 网络类型,比如bridge
overlay
;- 其中
overlay
网络类型用于 Swarm mode - 多个容器之间需要互相连接,推荐使用 Docker Compose
2.3 配置DNS
在容器中使用 mount
命令可以看到挂载信息:
$ mount
/dev/disk/by-uuid/1fec...ebdf on /etc/hostname type ext4 ...
/dev/disk/by-uuid/1fec...ebdf on /etc/hosts type ext4 ...
tmpfs on /etc/resolv.conf type tmpfs ...
- 以上三个配置文件的挂载,使得宿主 DNS 信息更新后,容器的 DNS 配置可以直接通过
/etc/resolv.conf
文件立刻得到更新
更新 /etc/docker/daemon.json
文件,可以实现全部容器的DNS配置:
{
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
}
使用以下命令验证 DNS 配置是否生效:
docker run -it --rm ubuntu:18.04 cat etc/resolv.conf
单独容器的 DNS 相关配置:
- 通过参数
-h
或--hostname
配置单独容器的主机名(该主机名仅在容器内部生效) - 通过参数
--dns
来单独添加 DNS 服务器,解析不在/etc/hosts
中的主机名 - 通过参数
--dns-search
设定搜索域;当设定搜索域为.example.com
并搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索host.example.com
3 高级网络配置
3.1 配置网桥
Docker 服务默认会创建一个 docker0
网桥(其上有一个 docker0
内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络
- 参数
--bip=CIDR
设定 docker0 的掩码,例如 192.168.1.5/24 - 参数
--mtu=BYTES
设定容器网络中的 MTU(接口允许接收的最大传输单元) - Docker 网桥作为一种 Linux 网桥,可以使用
brctl show
来查看网桥和端口信息 - 本地主机上
docker0
接口的 IP ,会作为所有容器的默认网关
除了默认网桥,还可用-b BRIDGE
或 --bridge=BRIDGE
指定容器挂载的网桥:
sudo systemctl stop docker # 停止docker访问
sudo ip link set dev docker0 down # 停止网桥
sudo brctl delbr docker0 # 删除旧的网桥
# 创建一个网桥 `bridge0`
sudo brctl addbr bridge0
sudo ip addr add 192.168.5.1/24 dev bridge0
sudo ip link set dev bridge0 up
ip addr show bridge0 # 查看确认
将新创建的网桥配置docker的默认网桥:
# 在配置文件 `/etc/docker/daemon.json` 中添加如下内容
{
"bridge": "bridge0",
}
3.2 容器访问控制
容器的访问控制,主要通过 Linux 上的 iptables
防火墙来进行管理和实现
容器要想访问外部网络,需要本地系统的转发支持:
sysctl net.ipv4.ip_forward
查看转发设置(0表示关闭转发)sysctl -w net.ipv4.ip_forward=1
手动开启转发- 启动 Docker 服务时设定
--ip-forward=true
,实现自动开启转发
容器间相互访问的两个条件:网络互通+ iptables
防火墙允许
- 默认情况下,同容器之间是允许网络互通的(
icc=true
) - 在Docker 访问启动时,可以手动关闭网络访问:
--icc=false
- 也可以在
/etc/docker/daemon.json
文件中配置{"icc": false}
来关闭 - 如果手动指定
--iptables=false
则不会添加iptables
规则 - 同时使用
icc=false --iptables=true
参数来实现网络访问的控制 - 关闭网络访问后,还可以通过
--link
选项来访问容器的开放端口
3.3 配置网络代理
配置网络代理的3个常见场景:
- 为 Docker 服务配置网络代理:在配置文件中添加相关环境变量后重启 Docker 服务
# 编辑/etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:8080/"
Environment="HTTPS_PROXY=http://proxy.example.com:8080/"
Environment="NO_PROXY=localhost,127.0.0.1,.example.com"
# 重启 Docker 服务
sudo systemctl daemon-reload
sudo systemctl restart docker
- 为 Docker 容器配置网络代理:更改 docker 客户端配置,或者指定环境变量(--env)
# ~/.docker/config.json
{
"proxies":
{
"default":
{
"httpProxy": "http://proxy.example.com:8080/",
"httpsProxy": "http://proxy.example.com:8080/",
"noProxy": "localhost,127.0.0.1,.example.com"
}
}
}
# 运行 "docker run" 命令时,指定相关环境变量
docker run --env HTTP_PROXY="http://proxy.example.com:8080/"
- 为 docker build 过程设置网络代理:在
docker build
或Dockerfile
中指定环境变量
# 使用 "--build-arg" 指定 "docker build" 的相关环境变量
docker build \
--build-arg "HTTP_PROXY=http://proxy.example.com:8080/" \
--build-arg "HTTPS_PROXY=http://proxy.example.com:8080/" \
--build-arg "NO_PROXY=localhost,127.0.0.1,.example.com" .
# 在 Dockerfile 中指定相关环境变量
ENV HTTP_PROXY="http://proxy.example.com:8080/"
3.4 其他网络配置
容器的临时网络配置:
- Docker 1.2.0 开始支持在运行中的容器里编辑配置文件
- 配置文件主要包括
/etc/hosts
,/etc/hostname
和/etc/resolv.conf
- 这些修改是临时的,只在运行的容器中保留,也不会被
docker commit
提交