Docker
挺好的教程 Docker--从入门到实践
docker run 和 start 的区别
docker run
docker run 只在第一次运行时使用,将镜像放到容器中,以后再次启动这个容器时,只需要使用命令docker start 即可。 docker run相当于执行了两步操作:将镜像放入容器中(docker create),然后将容器启动,使之变成运行时容器(docker start)。
docker start
docker start的作用是,重新启动已存在的镜像。也就是说,如果使用这个命令,我们必须事先知道这个容器的ID,或者这个容器的名字,我们可以使用docker ps找到这个容器的信息。
Docker 自定义网桥
需要先安装 brctl
apt-get install bridge-utils
参考:自定义网桥 注意,自定义的 IP网段 不能和宿主机同网段,否则会冲突导致宿主机连接不上,如果想设置他同网段请看下面的。
- 修改
/etc/docker/deamon.json
文件,添加
"bip": "192.168.2.1/24"
除了默认的 docker0 网桥,用户也可以指定网桥来连接各个容器。
在启动 Docker 服务的时候,使用 -b BRIDGE或--bridge=BRIDGE 来指定使用的网桥。
如果服务已经运行,那需要先停止服务,并删除旧的网桥。
sudo systemctl stop docker
sudo ip link set dev docker0 down
sudo brctl delbr docker0
然后创建一个网桥 bridge0。
sudo brctl addbr bridge0
sudo ip addr add 192.168.1.0/24 dev bridge0
sudo ip link set dev bridge0 up
查看确认网桥创建并启动。
ip addr show bridge0
4: bridge0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state UP group default
link/ether 66:38:d0:0d:76:18 brd ff:ff:ff:ff:ff:ff
inet 192.168.5.1/24 scope global bridge0
valid_lft forever preferred_lft forever
在 Docker 配置文件 /etc/docker/daemon.json 中添加如下内容,即可将 Docker 默认桥接到创建的网桥上。
{
"bridge": "bridge0",
}
启动 Docker 服务。 新建一个容器,可以看到它已经桥接到了 bridge0 上。 可以继续用 brctl show 命令查看桥接的信息。另外,在容器中可以使用 ip addr 和 ip route 命令来查看 IP 地址配置和路由信息。
使用 Macvlan 为 Docker 容器指定自定义网段的固定IP/静态IP地址
确定网卡名称
ifconfig
开启网卡混杂模式
ip link set 网卡名 promisc on
ifconfig 网卡名 promisc
创建 Macvlan 网络
docker network create -d macvlan --subnet=192.168.1.0/24 --ip-range=192.168.1.0/24 --gateway=192.168.1.1 -o parent=网卡名 -o macvlan_mode=bridge 自定义网络名称
参数解析:
-d macvlan 加载kernel的模块名
--subnet 宿主机所在网段
--ip-range 地址范围
--gateway 宿主机所在网段网关
--o parent 继承指定网段的网卡
加入 Macvlan 网络
docker run -itd --name tomcat --ip=192.168.1.2 --network pub_net tomcat
参数解析:
--ip 指定容器的IP
--network 加入的Macvlan网络
这样会使Docker启动时的
-p
参数无效。因为 Docker 不会为 macvlan 做端口映射。Macvlan 将容器放在主机的网络上,使端口转发变得多余。除此之外,由于 macvlan 的工作原理,默认无法从主机访问 macvlan ip。
Macvlan网络模式下容器与宿主机互通
假设现有网段为 192.168.1.0/24
的网络:
名字 | ip | 接口 |
---|---|---|
宿主机 | 192.168.1.10 | eth0 |
容器 | 192.168.1.20 | macvlan |
建立一个名为macvlan2的macvlan接口,并分配一个ip:
名字 | ip | 接口 |
---|---|---|
macvlan2 | 192.168.1.15 | macvlan |
命令:
ip link add macvlan2 link eth0 type macvlan mode bridge
ip addr add 192.168.1.15 dev macvlan2
ip link set macvlan2 up
修改路由,让宿主机到容器 192.168.1.20
的数据经过 macvlan2
:
ip route add 192.168.1.20 dev macvlan2
宿主机 访问 容器的ip:192.168.1.20 容器 访问 宿主机ip:192.168.1.15
Docker 常用命令
docker start [容器 ID]:启动一个或多个已经被停止的容器
docker stop [容器 ID]:停止一个运行中的容器
docker restart [容器 ID]:重启容器
docker rm -f [容器 ID] 删除容器
service docker restart 重启docker
service docker stop 停止docker
docker ps -a 查看所有容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS说明:
-a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
-d: 后台运行容器,并返回容器ID;
-i: 以交互模式运行容器,通常与 -t 同时使用;
-P: 随机端口映射,容器内部端口随机映射到主机的端口
-p: 指定端口映射,格式为:主机(宿主)端口:容器端口
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
--name="nginx-lb": 为容器指定一个名称;
--dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
--dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
-h "mars": 指定容器的hostname;
-e username="ritchie": 设置环境变量;
--env-file=[]: 从指定文件读入环境变量;
--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;
-m :设置容器使用内存最大值;
--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
--link=[]: 添加链接到另一个容器;
--expose=[]: 开放一个端口或一组端口;
--volume , -v: 绑定一个卷
Docker启动报错
报错内容
Job for docker. service failed because the control process exited with error code
解决方法 ,检测 /etc/docker/daemon.json
文件格式是否正确
Docker自启动
- 设置Docker开机自启
systemctl enable docker
- 设置容器自动重启
创建容器时设置
shelldocker run -d --restart=always --name 设置容器名 使用的镜像 (上面命令 --name后面两个参数根据实际情况自行修改)
Docker 容器的重启策略如下:
shell--restart具体参数值详细信息: no // 默认策略,容器退出时不重启容器; on-failure // 在容器非正常退出时(退出状态非0)才重新启动容器; on-failure:3 // 在容器非正常退出时重启容器,最多重启3次; always // 无论退出状态是如何,都重启容器; unless-stopped // 在容器退出时总是重启容器,但是不考虑在 Docker 守护进程启动时就已经停止了的容器。
修改已有容器,使用update,如果创建时未指定 --restart=always,可通过update 命令设置
shelldocker update --restart=always 容器ID(或者容器名) (容器ID或者容器名根据实际情况修改)
AdGuardHome 安装及部署
(1)Bridge 网络模式
docker run -d \
--name adguardhome \
-v $PWD/adguardhome/work:/opt/adguardhome/work \
-v $PWD/adguardhome/conf:/opt/adguardhome/conf \
-p 53:53/tcp \
-p 53:53/udp \
-p 3000:3000/tcp \
adguard/adguardhome
(2)Host 网络模式
Host 网络模式直接使用宿主机的网络,没有网络隔离,不需要考虑容器端口的映射,在容器启动后可以自由调整被占用的端口。适合在本机使用 (localhost),或者直通外网的设备对外开放服务,就比如 VPS 、主路由。
docker run -d \
--name adguardhome \
--restart unless-stopped \
--log-opt max-size=1m \
--network host \
-v $PWD/adguardhome/work:/opt/adguardhome/work \
-v $PWD/adguardhome/conf:/opt/adguardhome/conf \
adguard/adguardhome
出现过的问题
端口冲突
在 Linux 设备上运行 AdGuard Home,通常会出现 53(本地 DNS 服务器)、68(DHCP 客户端)、80(Http)、443(Https) 端口冲突的问题,可以通过netstat -tunlp | grep
端口号 查询占用进程。有两种解决方案:使用不同端口、停用冲突进程。 如果是通过 Docker 方式运行 AdGuard Home,
出现 listen udp 0.0.0.0:53 bind: address already in use 的提示,需要手动处理,方法如下:
#停止 DNSStubListener
systemctl stop systemd-resolved
#创建文件夹(如果不存在)
mkdir /etc/systemd/resolved.conf.d/
#使用 Nano 创建配置文件2021-04-29 16:16:00 星期四
nano /etc/systemd/resolved.conf.d/adguardhome.conf
在编辑器中粘贴以下内容:
[Resolve]
DNS=127.0.0.1
DNSStubListener=no
保存后执行以下命令。
#创建备份
sudo mv /etc/resolv.conf /etc/resolv.conf.backup
#将 /etc/resolv.conf 链接至 /run/systemd/resolve/resolv.conf
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
#重启 DNSStubListener
systemctl restart systemd-resolved
完成后使用 netstat -tunlp | grep 53
命令检查是否依旧有进程占用 53 端口,如无冲突,重启 AdGuard Home 容器即可。
Docker容器修改dns
设置docker的dns 编辑 /etc/docker/daemmon.json
报错
Job for docker.service failed because the control process exited with error code.
See "systemctl status docker.service" and "journalctl -xe" for details.
是因为/etc/docker/daemon.json 填写出错
启动一个挂载数据卷的容器
在用 docker run
命令的时候,使用 --mount
标记来将 数据卷
挂载到容器里。在一次 docker run
中可以挂载多个 数据卷
。
下面创建一个名为 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