容器虚拟化网络和Docker容器网络(转载)
容器虚拟化网络和Docker容器网络
docker 6种名称空间
UTS namespace 主机名与域名
Mount namespace 挂载点
IPC namespace 信号量、消息队列和共享内存
PID namespace 进程号
User namespace 用户和组
Network namespace 网络设备、网络栈、端口等
Linux系统虚拟交换机
OVS: Open VSwitch, 开源虚拟交换机
软件功能实现交换机技术,模拟实现三层网络技术,vlan,流控,SDN
网络名称空间
网络名称命令
ip netns 命令
# ip netns help
Usage: ip netns list
ip netns add NAME
ip netns set NAME NETNSID
ip [-all] netns delete [NAME]
ip netns identify [PID]
ip netns pids NAME
ip [-all] netns exec [NAME] cmd ...
ip netns monitor
创建网络名称空间
# ip netns add r1
# ip netns add r2
## 查看名称空间网卡
# ip netns exec r1 ifconfig
# ip netns exec r1 ifconfig -a
创建虚拟网卡对
# ip link help
## 创建一堆网卡
# ip link add name veth1.1 type veth peer name veth1.2
## 移动一个网卡到r1
# ip link set dev veth1.2 netns r1
# ip netns exec r1 ifconfig -a
## 修改r1中veth1.2名字为eth0、
# ip netns exec r1 ip link set dev veth1.2 name eth0
# ip netns exec r1 ifconfig -a
## 激活网卡即可通信
# ifconfig veth1.1 10.1.0.1/24 up
# ip netns exec r1 ifconfig eth0 10.1.0.2/24 up
# ping 10.1.0.2
## r1和r2进行通信
# ip link set dev veth1.1 netns r2
# ip netns exec r2 ifconfig -a
# ip netns exec r2 ping 10.1.0.2
测试网络通信模型时使用,轻量级,模拟bridge,none,host模式
docker网络
- 查看网络
# docker network ls
# docker network inspect bridge
创建容器时,可为 docker run 命令使用 --network选项指定要加入的网络
bridge桥接
容器启动,创建一对网卡,一半在容器,一半在docker0
桥接式容器一般拥有两个接口:一个环回接口和一个连接至主机上某桥设备的以太网接口
docker daemon 启动时默认会创建一个名为 docker0的网络桥,并且创建的容器为桥接式容器,其以太网接口桥接至 docker0
--net bridge 即为将容器接口添加至 docker0
docker0 桥为 NAT桥,因此,桥接式容器可通过此桥接口访问外部网络,但防火墙规则阻止了一切从外部网络访问桥接式容器的请求
- 查看桥接信息
# yum install -y bridge-utils
# brctl show
# ip link show
# iptables -t nat -vnL
- 启动命令1
# docker run --name t1 -it --rm busybox:latest
- 启动命令2 bridge桥接
# docker run --name t1 -it --network bridge --rm busybox:latest
- 启动docker时注入参数
# docker run --name t1 -it -h evescn --rm busybox:latest
-h 注入主机名
# docker run --name t1 -it -h evescn --dns 114.114.114.114 --dns-search ilinux.io --rm busybox:latest
-h 注入主机名
--dns 注入dns IP
--dns-search 注入dns解析搜索域
# docker run --name t1 --rm --add-host "my.docker.com:172.16.0.100" busybox nslookup docker.com
--add-host HOSTNAME:IP 选项能够为容器指定本地主机名解析项
docker容器端口暴露
Docker0 为 NAT 桥,因此容器一般获得的是私有网络地址
可以把容器想像为宿主机 NAT 服务背后的主机
如果开放容器或其上的服务为外部网络访问,需要在宿主机上为其定义 DNAT 规则,例如
对宿主机某 IP 地址的访问全部映射给某容器地址
主机 IP 容器 IP
-A PREROUTING -d 主机 IP -j DNAT --to-destination 容器 IP
对宿主机某 IP 地址的某端口的访问映射给某容器地址的某端口
主机 IP:PORT 容器 IP:PORT
-A PREROUTING -d 主机 IP -p {tcp|udp} --dport 主机端口 -j DNAT --to-destination 容器 IP: 容器端口
为 docker run 命令使用 -p选项即可实现端口映射,无须手动添加规则
- -p 参数
-p选项的使用格式
-p <containerPort>
将指定的容器端口映射至主机所有地址的一个动态端口
-p <hostPort>:<containerPort>
将容器端口<containerPort>映射至指定的主机端口<hostPort>
-p <ip>::<containerPort>
将指定的容器端口<containerPort>映射至主机指定<ip>的动态端口
-p <ip>:<hostPort>:<containerPort>
将指定的容器端口<containerPort>映射至主机指定<ip>的端口<hostPort>
“动态端口”指随机端口,具体的映射结果可使用docker port命令查看
--------------------------------------------
"-P" 选项或 "--publish-all" 将容器的所有计划要暴露端口全部映射至主机端口
-P 暴露所有Dockerfile中定义好的端口暴露
计划要暴露的端口使用使用 --expose 选项指定
例如
# docker run -d -P --expose 2222 --expose 3333 --name web busybox:latest /bin/httpd -p 2222 -f
查看映射结果,查看容器暴露端口
# docker port myweb
如果不想使用默认的 docker0桥接口,或者需要修改此桥接口的网络属性,可通过为 docker daemon 命令使用 -b 、 --bip 、 --fixed-cidr 、 --default-gateway 、 --dns 以及 --mtu等选项进行设定
none
不参与网络通信,运行于此类容器中的进程仅能访问本地环回接口
仅适用于进程无须网络通信的场景中,例如备份、进程诊断及各种离线任务等
空共享,不设置网络,只要lo接口,没有网卡
- 启动命令
# docker run --name t1 -it --network none --rm busybox:latest
联盟式网络
联盟式容器是指使用某个已存在容器的网络接口的容器,接口被联盟内的各容器共享使用;因此,联盟式容器彼此间完全无隔离
联盟式容器彼此间虽然共享同一个网络名称空间,但其它名称空间如 User 、 Mount等还是隔离的
联盟式容器彼此间存在端口冲突的可能性,因此,通常只会在多个容器上的程序需要程序 loopback接口互相通信、或对某已存的容器的网络属性进行监控时才使用此种模式的网络模型
## 类似host模式
2个或多个容器共享网络名称空间
共享:UTS,Net,IPC
不共享:User,Mount,Pid
# docker run --name t1 -it --rm busybox:latest
# docker run --name t2 --network container:b1 -it --rm busybox:latest
主机模式
开放式容器共享主机网络名称空间的容器,它们对主机的网络名称空间拥有全部的访问权限,包括访问那些关键性服务,这对宿主机安全性有很大潜在威胁
容器共享物理机网络名称空间
共享:UTS,Net,IPC
不共享:User,Mount,Pid
# docker run --name t1 -it --network host --rm busybox:latest
修改docker0的网络ip地址
自定义docker0桥的网络属性信息:/etc/docker/daemon.json文件
{
"bip": "10.20.0.1/16",
"fixed-cidr": "10.20.0.0/16",
"fixed-cidr-v6": "2001:db8::/64",
"mtu": 1500,
"default-gateway": "10.20.1.1",
"default-gateway-v6": "2001:db8:abcd::89",
"dns": ["10.20.1.2","10.20.1.3"]
}
docker服务器开启远程操作
## dockerd守护进程的 C/S,其默认仅监听 Unix SOcket格式的地址,/var/run/docker.sock;如果使用TCP套接字,
# vim /etc/docker/daemon.json
"hosts": ["tcp://0.0.0.0:2375", unix:///var/run/docker.sock"]
## 远程主机向dockerd直接传递“-H|--host”选项;
# docker -H IP ps -a
创建自定义桥
## 创建桥
# docker network --help
# docker network create --help
# docker network create -d bridge --subnet "172.26.0.0/16" --gateway "172.26.0.1" mybr0
# docker network ls
## 重命名桥
# ip link set dev xxxx name docker1
## 启动容器,使其使用新桥
# docker run --name t1 -it --net mybr0 busybox