文章目录

  • 阿里云源安装 docker
  • 用户加入 docker 组,可以不用 sudo 执行命令。
  • docker 镜像加速
  • 私有仓库 https 白名单
  • Docker Network
  • Bridge
  • None
  • Host
  • MACVLAN
  • MACVLAN
  • Docker MACVLAN
  • 同主机多个 MACVLAN 类型的网络
  • IPVLAN
  • 常用命令
  • Docker DNS
  • 默认网络
  • 用户自定义网络
  • docker 端口映射
  • volume
  • 传递变量
  • 容器之间互联


阿里云源安装 docker

# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3: 更新并安装Docker-CE
sudo yum makecache fast
sudo yum -y install docker-ce
# Step 4: 开启Docker服务
sudo service docker start

用户加入 docker 组,可以不用 sudo 执行命令。

sudo groupadd docker
sudo usermod -aG docker ${USER}
sudo systemctl restart docker
# 重新登录/切换到该用户后生效

docker attach 之后,通过 ^p ^q 退出,使用 ^D 或者exit退出后,会处于Exited stop状态。

使用docker exec -it <name> <command>进入后,可以使用exit退出。

docker 镜像加速

# 到阿里云控制台申请,每个人地址不一样
# 通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://sj28ilnm.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

# 查看加速是否生效
docker info
 Registry Mirrors:
  https://sj28ilnm.mirror.aliyuncs.com/

私有仓库 https 白名单

# vim /etc/docker/daemon.json
{
    "insecure-registries": ["url"]
}

容器网络标准:

CNM(container network model)

CNI(container network interface)

Docker Network

Bridge 之间二层隔离,通过 iptables filter 表实现。

将 docker 的 namespace 挂载到系统目录下(可通过ip netns查看)

#! /bin/bash

if [ $# -ne 1 ]; then
  echo -e "Specify container name by ./link_docker_ns.sh <container_name> \n\n\n"
  exit 1
else
  container_name=$1
fi

sudo mkdir -p /var/run/netns/

pid=`docker inspect -f '{{.State.Pid}}' $container_name`
sudo ln -sfT /proc/$pid/ns/net /var/run/netns/$container_name

映射端口(publish list):通过 iptables nat 表实现

# 不指定主机端口,会随机分配(大于30000)
docker run -itd -p 80 nginx
# 指定主机端口,将主机的 8080 映射到容器的 80 端口
docker run -itd -p 8080:80 nginx
# 映射 udp 端口(默认是 tcp)
docker run -itd -p 80/udp nginx

网络类型:Bridge、None、Host、MACVLAN

查看网络:docker network ls

Bridge

工作方式和一般的Linux bridge 一样,可以通过 brctl 工具来查看。
支持 stp、flood-learn 等

None

不连接网络:用于进行一些计算之类的,不需要网络
不使用docker提供的网络:使用其他 network plugin 如 weave、calico等

Host

直接使用主机网络,网络不隔离。适用情况:例如直接将主机的服务迁移到容器里,网络地址空间不变。

MACVLAN

容器跨主机通信

MACVLAN

通过子接口的方式实现

  • sub-interface
  • 在 netdev 设备上挂载虚拟的子接口
  • 虚拟子接口的流量最终从 netdev 设备转发出去
  • MACVLAN
  • 每个MACVLAN子接口都有独立的 IP 和 MAC,通过挂载的物理网卡直接连接到物理网卡
  • 使用的是物理网络的地址空间,增加了物理网络的负担(MAC表,ARP表)
  • 需要物理网络设备打开混杂模式(promiscuous mode)(ip link set eth0 promisc on)
  • Kernel v3.9-3.19,v4.0+

四种工作方式

  • private:容器之间不能通信
  • VEPA(Virtual Ethernet Port Aggregator):依赖物理网络
  • bridge:容器通过桥直接通信
  • Passthru:直通

Docker MACVLAN

-o macvlan_mode=bridge 来指定 MACVLAN 的模式

docker network create --driver macvlan  \
--subnet=10.1.1.0/24  \
--ip-range=10.1.1.0/26  \
--gateway=10.1.1.1  \
-o parent=ens33 macvlan_demo

同主机多个 MACVLAN 类型的网络

通过 VLAN 子接口来实现,在一个主机同时创建多个 MACVLAN 网络时,指定 VLAN 子接口名字作为 MACVLAN 的挂载网卡,docker会自动创建 VLAN 子接口,物理主机要与物理网络使用 Trunk 模式

docker network create --driver macvlan  \
--subnet=10.1.1.0/24  \
--ip-range=10.1.1.0/26  \
--gateway=10.1.1.1  \
-o parent=ens33.100 macvlan_demo

IPVLAN

每个 IPVLAN 子接口,IP 地址不一样,MAC 地址与挂载的网卡一样。
物理交换机不支持混杂模式时使用(作为 MACVLAN 的补充方案)

查看 macvlan 类型:将容器的 netns 映射到主机中,登录到该 netns 中,ip link show type macvlan

常用命令

Usage:	docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

# 查看容器详细信息
Usage:	docker inspect [OPTIONS] NAME|ID [NAME|ID...]

Return low-level information on Docker objects

Options:
  -f, --format string   Format the output using the given Go template
  -s, --size            Display total file sizes if the type is container
      --type string     Return JSON for specified type

# 查看容器主进程的日志,输出到控制台,-f follow,持续观察
docker logs -f <容器名>

Docker DNS

默认网络

docker 默认情况下通过拷贝主机的/etc/resolv.conf文件来使用主机的 DNS 服务。

# 指定容器的hostname(相当于修改 /etc/hostname)
--hostname
# 指定静态 DNS 记录(相当于修改 /etc/hosts)
--link
# 指定 DNS 配置,不使用主机的 DNS 配置
--dns
--dns-search
--dns-opt

./etc/hosts /etc/resolv.conf /etc/hostname,容器中的这三个文件不存在于镜像,而是存在于 /var/lib/docker/containers/{container_id}/hosts,在启动容器的时候,通过 mount 的形式将这些文件挂载到容器内部。因此,如果在容器中修改这些文件的话,修改部分不会存在于容器的 top layer,而是直接写入这三个物理文件中。

用户自定义网络

  1. Docker 提供 DNS 服务,容器的 /etc/resolv.conf由 docker 生成,指向 127.0.0.11
  2. 拦截目的地址为 127.0.0.11 端口是 53 的 tcp/udp 请求,转发到 docker 进程
  3. docker 知道所有容器的名字和地址,可以完成解析
  4. 如果 docker 不能解析,会 fallback 到主机配置的 DNS Server 来完成域名解析请求

docker 端口映射

-p 参数:
-p hostPort:containerPort
-p ip:hostPort:containPort # 不同容器使用宿主机不同ip的同一端口
-p ip::containerPort # 随机端口
-p hostPort:containerPort:udp # 默认为tcp端口,加udp指定
-p 80:80 -p 443:443 # 多个端口需要指定多个 -p

随机端口的范围由内核参数决定,默认时 32768-60999,参数sysctl -n net.ipv4.ip_local_port_range

volume

-v 参数
# 挂载系统目录,-v hostDir:containerDir,如果主机没有目录,会新建
docker run -itd -v /var/www/html/:/usr/local/apache2/htdocs/

挂载卷,如果没有指定目录,会新建一个 volume,持久化存储,如果容器删除,卷不会被删除(docker rm -f -v 会同时删除卷),卷也可以多次挂载

docker run -itd -v test:/usr/local/apache2/htdocs httpd
docker volume ls # 会看到一个test的卷
docker volume inspect test # 查看卷的信息,挂载点
[
    {
        "CreatedAt": "2020-09-05T22:30:38+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/test/_data",
        "Name": "test",
        "Options": null,
        "Scope": "local"
    }
]

传递变量

-e , --env
在容器内服务运行的时候需要传递参数,使用 -e ,如指定 ssh 密码

docker run -itd -e "ROOT_PWD=123" centos:7 /bin/bash /init.sh
# 容器内的文件 cat init.sh
if [ -z $ROOT_PWD ];then
    ROOT_PWD=123456
fi
echo "$ROOT_PWD" | passwd --stdin root
service sshd restart

这样容器运行的时候如果不指定密码,就使用默认密码,指定密码后会修改密码

容器之间互联

–link,单向连接

docker run --link <容器名>:<别名>

本质是加了一个 host 解析