文章目录
阿里云源安装 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,而是直接写入这三个物理文件中。
用户自定义网络
- Docker 提供 DNS 服务,容器的
/etc/resolv.conf
由 docker 生成,指向 127.0.0.11 - 拦截目的地址为 127.0.0.11 端口是 53 的 tcp/udp 请求,转发到 docker 进程
- docker 知道所有容器的名字和地址,可以完成解析
- 如果 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 解析