Skip to content

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

shell
apt-get install bridge-utils

参考:自定义网桥 注意,自定义的 IP网段 不能和宿主机同网段,否则会冲突导致宿主机连接不上,如果想设置他同网段请看下面的。

  1. 修改 /etc/docker/deamon.json 文件,添加
json
"bip": "192.168.2.1/24"

除了默认的 docker0 网桥,用户也可以指定网桥来连接各个容器。

在启动 Docker 服务的时候,使用 -b BRIDGE或--bridge=BRIDGE 来指定使用的网桥。

如果服务已经运行,那需要先停止服务,并删除旧的网桥。

shell
sudo systemctl stop docker
sudo ip link set dev docker0 down
sudo brctl delbr docker0

然后创建一个网桥 bridge0。

shell
sudo brctl addbr bridge0
sudo ip addr add 192.168.1.0/24 dev bridge0
sudo ip link set dev bridge0 up

查看确认网桥创建并启动。

shell
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 默认桥接到创建的网桥上。

shell
{
"bridge": "bridge0",
}

启动 Docker 服务。 新建一个容器,可以看到它已经桥接到了 bridge0 上。 可以继续用 brctl show 命令查看桥接的信息。另外,在容器中可以使用 ip addr 和 ip route 命令来查看 IP 地址配置和路由信息。

使用 Macvlan 为 Docker 容器指定自定义网段的固定IP/静态IP地址

视频教程

确定网卡名称

shell
ifconfig

开启网卡混杂模式

shell
ip link set 网卡名 promisc on
ifconfig 网卡名 promisc

创建 Macvlan 网络

shell
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 网络

shell
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.10eth0
容器192.168.1.20macvlan

建立一个名为macvlan2的macvlan接口,并分配一个ip:

名字ip接口
macvlan2192.168.1.15macvlan

命令:

shell
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 :

shell
ip route add 192.168.1.20 dev macvlan2

宿主机 访问 容器的ip:192.168.1.20 容器 访问 宿主机ip:192.168.1.15

Docker 常用命令

shell
docker start [容器 ID]:启动一个或多个已经被停止的容器

docker stop [容器 ID]:停止一个运行中的容器

docker restart [容器 ID]:重启容器

docker rm -f [容器 ID] 删除容器

service docker restart 重启docker
service docker stop  停止docker

docker ps -a 查看所有容器
shell
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自启动

  1. 设置Docker开机自启
shell
systemctl enable docker
  1. 设置容器自动重启
    1. 创建容器时设置

      shell
      docker run -d --restart=always --name 设置容器名 使用的镜像
      (上面命令  --name后面两个参数根据实际情况自行修改)

      Docker 容器的重启策略如下:

      shell
          --restart具体参数值详细信息:
          no        // 默认策略,容器退出时不重启容器;
          on-failure    // 在容器非正常退出时(退出状态非0)才重新启动容器;
          on-failure:3    // 在容器非正常退出时重启容器,最多重启3次;
          always      // 无论退出状态是如何,都重启容器;
          unless-stopped  // 在容器退出时总是重启容器,但是不考虑在 Docker 守护进程启动时就已经停止了的容器。
    2. 修改已有容器,使用update,如果创建时未指定 --restart=always,可通过update 命令设置

      shell
      docker update --restart=always 容器ID(或者容器名)
      (容器ID或者容器名根据实际情况修改)

AdGuardHome 安装及部署

(1)Bridge 网络模式

shell
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 网络模式直接使用宿主机的网络,没有网络隔离,不需要考虑容器端口的映射,在容器启动后可以自由调整被占用的端口。适合在本机使用 (lo­cal­host),或者直通外网的设备对外开放服务,就比如 VPS 、主路由。

shell
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​ 的提示,需要手动处理,方法如下:

shell
#停止 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

在编辑器中粘贴以下内容:

shell
[Resolve]
DNS=127.0.0.1
DNSStubListener=no

保存后执行以下命令。

shell
#创建备份
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

Released under the MIT License.