# docker入门

参考资料:

# 常规操作

# 导出导入镜像

有时候服务器不联网,这个时候部署docker就很费劲,此时需要把一台电脑的docker镜像复制到其他电脑上:

  1. 导出已部署好的服务器所有docker镜像:

    sudo docker save -o images.tar $(sudo docker images | sed '1d' | awk '{print $1":"$2}')
    docker save -o <tar包名>.tar <镜像名1>:<tag1> <镜像名2>:<tag2>

  2. 将镜像拷贝到目标服务器:

    sudo scp images.tar user@ip:/home/rootuser/images.tar

  3. 将镜像备份文件还原到目标服务器:

    docker load -i images.tar

# 其他命令

  1. 删除所有镜像:

    docker rmi -f $(docker images -qa)

# Docker网络

安装Docker时,它会自动创建三个网络:

  • bridge(创建容器默认连接到此网络)
  • none
  • host

使用docker run创建容器时,可使用--net指定容器的网络模式:

host模式:使用 --net=host 指定。
none模式:使用 --net=none 指定。
bridge模式:使用 --net=bridge 指定,默认设置。
container模式:使用 --net=container:NAME_or_ID 指定
1
2
3
4

下面详细介绍这几种模式

# host模式

默认docker容器运行会被分配独立的network namespace隔离子系统,基于host模式,容器将不会获得一个独立的network namespace,而是和宿主机共用一个network namespace,容器将不会虚拟出自己的网卡,而是使用宿主机的IP和端口。

# container模式

这个模式就是容器间共享一个network namespace,并不是容器和宿主机共享,这样新创建的容器不会创建自己的网卡,配置自己的ip,而是和一个指定的容器共享网络环境,但是他们的文件系统,进程列表还是隔离的。

# none模式

这种模式下docker容器会拥有自己独立的network namespace,但是并不会为docker容器进行任何网络配置,也就是该docker容器没有网络信息,需要手动自定义,此时可以借助pipwork工具为docker容器指定ip信息。

# bridge桥接模式

该模式是docker默认的网络模式,该模式下宿主机会为每一个容器自动分配一个network namespace,默认会将docker容器连接到一个虚拟网桥交换机docker0上。

docker_bridge

下面是桥接模式的创建过程:

  1. 首先宿主机上创建一对虚拟网卡veth pair设备,veth设备总是成对出现的,形成一个通信通道,数据传输就是基于这个链路的,veth设备常用来连接两个网络设备。
  2. Docker将veth pair设备的一端放在容器中,并命名为eth0,然后将另一端加入docker0网桥中,可以通过brctl show命令查看。
  3. 从docker0的网卡中分配一个IP到给容器使用,并设置docker0的IP地址为容器默认网关。
  4. 此时容器IP与宿主机是可以通信的,宿主机也可以访问容器中的ip地址,在桥接模式下连接同一网桥的容器之间可以相互通信,同时容器可以访问外网,但是其他物理机不能访问docker容器IP,需爱通过NAT将容器的IP的port映射为宿主机的IP和port。

# docker网络命令

下面是docker网络方面的常见命令:

# 显示完整的网络ID
docker network ls --no-trunc
# 显示桥接的网络
docker network ls --filter driver=bridge
# 以固定格式显示
docker network ls --format "{{.ID}}: {{.Driver}}"

# 创建网络,默认为桥接模式
docker network create van
# 删除网络
docker network rm van
# 删除所有无用网络
docker network prune
1
2
3
4
5
6
7
8
9
10
11
12
13

下面是将容器连接到网络,可以按名称连接容器,一旦连接,容器可以与同一网络中的其他容器通信。

# 将正在运行的容器连接到网络
docker network connect 网络名 正在运行的容器
# 启动时将容器连接到网络 
docker run -itd --network=网络名 即将启动的容器
# 指定容器的IP地址
docker network connect --ip 10.10.10.10 网络名 容器

# 断开网络连接
docker network disconnect 网络名 容器
1
2
3
4
5
6
7
8
9

# 国内镜像

# CentOS安装镜像

大部分都是按照官网 (opens new window)步骤来做,不过如果网速不好,可以使用国内docker安装镜像地址:

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# Debian安装镜像

使用Docker的官方安装步骤来使用阿里的镜像:

install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  tee /etc/apt/sources.list.d/docker.list > /dev/null

apt update
1
2
3
4
5
6
7
8
9
10

# 国内镜像源

方法一(适用于群辉):

  1. 更改文件:

    /var/packages/Docker/etc/dockerd.json

  2. 在registry-mirrors中添加镜像源

    https://5yzx6sxk.mirror.aliyuncs.com

方法二:

  1. 更改文件:

    /etc/docker/daemon.json

  2. 在配置文件中:

    {
    
    "registry-mirrors": ["https://5yzx6sxk.mirror.aliyuncs.com"]
    
    }
    
    1
    2
    3
    4
    5
  3. 热更新配置文件,不重启镜像

    kill -SIGHUP $(pidof dockerd)
    docker info
    
    1
    2

# 其他问题

# 查看占用硬盘空间

有时候我们需要知道哪个容器占用硬盘空间最大,这个时候需要查找一下:

# 直接查看docker总体硬盘占用空间
docker system df
# 进入容器空间
cd /var/lib/docker/overlay2/
# 统计前10的目录
du -cks * | sort -rn | head -n 10
# 查找到对应的容器id
for i in $(docker ps -q );do echo echo $i ; docker inspect $i|grep 00bf345c0b67c9c05c69b8 ; done
1
2
3
4
5
6
7
8

# firewalld和docker冲突

参考资料:Centos7/8 firewall 和 docker 冲突解决 (opens new window)

centos7/8 自带防火墙是firewalld。firewall的底层是使用iptables进行数据过滤,建立在iptables之上,这可能会与 Docker 产生冲突。当 firewalld 启动或者重启的时候,将会从 iptables 中移除 DOCKER 的规则,从而影响了 Docker 的正常工作。当你使用的是 Systemd 的时候, firewalld 会在 Docker 之前启动,但是如果你在 Docker 启动之后再启动 或者重启 firewalld ,你就需要重启 Docker 进程了。

解决办法是将firewalld换成iptables:

#查看firewalld是否启用
systemctl status firewalld
#停止firewalld
systemctl stop firewalld
#禁用firewalld(否则重启系统后会再次启动)
systemctl disable firewalld
systemctl disable firewalld.service
#如果要是开启需要使用如下命令
systemctl enable firewalld
#屏蔽firewalld
systemctl mask firewalld
#取消屏蔽
systemctl unmask firewalld
#查看是否安装iptables
yum list installed | grep iptables-services
#如果没安装则安装下
yum install iptables-services -y
#重启iptables
systemctl restart iptables
#设置开机自启
systemctl enable iptables
#重启docker
systemctl restart docker
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

注意:

  • systemctl disable是在/etc/systemd/system/目录下删除相应的符号链接(链接的是/usr/lib/systemd/system/这个目录中的文件)。
  • systemctl mask 同上面不同的是前者只是删除符号链接,mask则会建立一个指向/dev/null的符号链接。

# CentOS6容器崩溃

以Centos6为基础构建的容器有可能会直接139退出:

vi /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet vsyscall=emulate"
update-grub
1
2
3

如果是systemd-boot启动,可以如下改动:

vi /boot/loader/entries

title Arch Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
options *EXISTINGPARAMS* vsyscall=emulate
1
2
3
4
5
6

# 更改存储位置

下面是更改docker存储的位置,包括镜像容器等东西:

{
    "data-root": "/root/maindata/dockerData",
    "registry-mirrors": ["http://hub-mirror.c.163.com"]
}
1
2
3
4

# 拉取ARM镜像

ARM镜像是个有意思的问题,下面是参考文档:

  1. 开启experiment特性:

    vi /etc/docker/daemon.json
    
    {
    "experimental": true
    }
    
    systemctl daemon-reload
    systemctl restart docker
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  2. 拉取特定架构镜像:

    docker pull --platform linux/arm64 openjdk
    # 查看已下载的镜像的架构
    docker image inspect openjdk | grep Architecture
    # 查看某个仓库都包含的架构
    docker manifest inspect --insecure nginx
    # 如果要拉取某个架构的可以使用digest
    docker pull nginx@digest
    
    1
    2
    3
    4
    5
    6
    7

# 群辉docker

# 常用命令

  1. 群辉重启docker:

    synoservice --restart pkgctl-Docker

  2. 新版群辉可能弃用synoservice了:

    systemctl restart sshd

  3. 设置root密码:

    synouser --setpw root 密码