Docker 网络模式

文章目录


一、Docker 网络实现原理

1、docker使用linux桥接,在宿主机虚拟一个docker容器网桥(docker0)

2、docker启动一个容器时会根据docker网桥的网段分配给容器一个IP地址,称为Container-IP

3、同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能通过容器的Container-IP直接通信。

Docker网桥是宿主机虚拟出来的,并不是真正存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主机**(端口映射)**,即docker run创建容器的时候,通过-p或者-P参数来启用。访问容器的时候,就通过【宿主机IP】:【容器端口】访问容器

1.容器的端口映射

端口映射,底层原理实际是做了一个DNAT转换。
方法一:随机映射端口(从32768开始) -P(大P)

sql 复制代码
docker run -itd  --name=为容器指定名称 -P 镜像名称
 
docker run -itd --name test1 -P nginx					#随机映射端口(从32768开始)

浏览器访问:http://192.168.40.104:32768

方法二:指定映射端口 -p(小p)

sql 复制代码
docker run -itd --name=为容器指定名称 -p 宿主机端口:容器端口 镜像名称
 
docker run -itd --name test2 -p 43000:80 nginx		#指定映射端口

浏览器访问:http://192.168.40.104:43000

二、Docker的网络模式

1、Host:容器不会虚拟出自己的网卡,配置主机的IP等,而是使用宿主机的IP和端口

2、Container:创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口的范围。

3、None:该模式关闭了容器的网络功能。

4、Briidge :默认为该模式,桥接,此模式会为每一个容器分配,设置IP等,并将容器连接到一个docker0的虚拟网桥,通过docker0 网桥以及iptables nat表配置与宿主机通信
5、自定义网络

1.Host模式

sql 复制代码
host容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口范围。

如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的
NetworkNamespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

使用host模式的容器可以直接使用宿主机的Ip地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是dockerhost 上已经使用的端口就不能再用了,网络的隔离性不好。

2.Container模式

1、container模式: 使用--net=contatiner:NAME_or_ID 指定

2、这个模式指定新创建的容器和已经存在的一个容器共享一个Network

Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP,端口范围等。可以在一定程度上节省网络资源,容器内部依然不会拥有所有端口。

3、同样,两个容器除了网络方面,其他的如文件系统,进程列表等还是隔离的。

4、两个容器的进程可以通过lo网卡设备通信

sql 复制代码
#基于镜像centos:7 创建一个名为test1的容器
[root@localhost ~]#: docker run -itd --name test3 centos:7 /bin/bash
5cde2ff96b6d706fb159b31f3e023cadefbdbd6c2c203a31163f9359f8363e61
 
#查看容器的pid号
[root@localhost ~]#: docker inspect -f '{{.State.Pid}}' test1
22955
 
#查看该容器的命名空间编号
[root@localhost ~]#: ls -l /proc/22955/ns
总用量 0
lrwxrwxrwx. 1 root root 0 8月  18 11:19 ipc -> ipc:[4026532751]
lrwxrwxrwx. 1 root root 0 8月  18 11:19 mnt -> mnt:[4026532749]
lrwxrwxrwx. 1 root root 0 8月  18 11:18 net -> net:[4026532754]
lrwxrwxrwx. 1 root root 0 8月  18 11:19 pid -> pid:[4026532752]
lrwxrwxrwx. 1 root root 0 8月  18 11:19 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 8月  18 11:19 uts -> uts:[4026532750]
 
#创建test2容器,使用container网络模式,和test1共享network Namespace
[root@localhost ~]#: docker run -itd --name test4 --net=container:test1 centos:7 /bin/bash
bb4ac525abc96725a8b8ef80c67b1e018ac3cb2b247041d7048cea2e9868f216
 
#查看test2容器的pid
[root@localhost ~]#: docker inspect -f '{{.State.Pid}}' test4
23046
 
#查看该容器的命名空间编号
[root@localhost ~]#: ls -l /proc/23046/ns
总用量 0
lrwxrwxrwx. 1 root root 0 8月  18 11:20 ipc -> ipc:[4026532826]
lrwxrwxrwx. 1 root root 0 8月  18 11:20 mnt -> mnt:[4026532824]
lrwxrwxrwx. 1 root root 0 8月  18 11:20 net -> net:[4026532754]
lrwxrwxrwx. 1 root root 0 8月  18 11:20 pid -> pid:[4026532827]
lrwxrwxrwx. 1 root root 0 8月  18 11:20 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 8月  18 11:20 uts -> uts:[4026532825]
 

3.none模式

1、none模式:使用 --net=none指定

2、使用none 模式,docker 容器有自己的network Namespace ,但是并不为3、Docker 容器进行任何网络配置。也就是说,这个Docker 容器没有网卡,ip, 路由等信息。

3、这种网络模式下,容器只有lo 回环网络,没有其他网卡。

4、这种类型没有办法联网,但是封闭的网络能很好的保证容器的安全性

5、该容器将完全独立于网络,用户可以根据需要为容器添加网卡。此模式拥有所有端口。(none网络模式配置网络)

6、特殊情况下才会用到,一般不用

4.bridge模式

bridge模式是docker的默认网络模式,不用--net参数, 就是bridge模式。

相当于Vmware中的nat模式,容器使用独立network Namespace, 并连接到docker0虚拟网卡I通过docker0网桥以及iptables nat表配置与宿主机通信,此模式会为每. 个容器分配Network Namespace、 设置IP等,并将一一个 主机上的Docker 容器连接到一个虚拟网桥上。

(1)当Docker进程启动时,会在主机上创建一个名为docker0的虛拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一"个二层网络中。

(2)从docker0子网中分配一个IP给容器使用(分配一个和网桥相同网段内的IP,网桥作为网关),并设置docker0的IP地址为容器的默认网关。在主机上创建一对虛拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。

(3)Docker将 veth pair设备的一端放在新创建的容器中,并命名为eth0 (容器的网卡),另一端放在主机中,以veth*这样类似的名字命名,并将这个网络设备加入到docker0 网桥中。可以通过brctl show命令查看。

(4)使用docker run -P 时,docker实际 是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。每个容器有自己独立的命名空间。容器之间通过网桥转发进行通信,成对的网络设备veth pair。

三、自定义网络

1、查看网络模式列表

clike 复制代码
[root@localhost opt]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
b87dc8ba51a3   bridge    bridge    local
d218e0246c94   host      host      local
da14a0020e59   none      null      local
[root@localhost opt]# 

2、查看容器信息(包含配置、环境、网关、挂载、cmd等等信息)

clike 复制代码
docker inspect  容器ID
例:
[root@localhost opt]# docker images 
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
centos       7         eeb6ee3f44bd   23 months ago   204MB
[root@localhost opt]# docker inspect eeb6ee3f44bd

3、指定分配容器IP地址

clike 复制代码
[root@localhost opt]# docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork

[root@localhost opt]# docker run -itd --name test1 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash

面试题

clike 复制代码
怎么把宿主机的文件传入到容器内部
1、linux 怎么复制
cp 原文件路径 目标文件路径
docker cp /opt/abc 容器id:/opt/abc 

#======复制到容器中
echo abc123 > ~/test.txt
docker cp ~/test.txt 2592d3fad0fb:/opt/

#从容器复制文件到主机
docker cp 2592d3fad0fb:/opt/test.txt ~/abc123.txt
相关推荐
似水流年 光阴已逝21 小时前
Kubernetes Pod 基本原理:全面详解
云原生·容器·kubernetes·pod
PKNLP21 小时前
07.docker介绍与常用命令
运维·docker·容器
阿里云云原生21 小时前
评估工程正成为下一轮 Agent 演进的重点
云原生
人工智能训练1 天前
在ubuntu系统中如何将docker安装在指定目录
linux·运维·服务器·人工智能·ubuntu·docker·ai编程
爱宇阳1 天前
Java Spring Boot 项目 Docker 容器化部署教程
java·spring boot·docker
掘根1 天前
【Docker】网络
网络·docker·容器
爱宇阳1 天前
从容器化到自动化:Vue3 项目 Docker 部署与 GitLab CI/CD 集成 Harbor 全流程
docker·自动化·gitlab
高旭博1 天前
10. kubernetes资源——statefulset有状态负载
云原生·容器·kubernetes
马达加斯加D1 天前
k8s --- resource: Pod, ReplicaSet and Deployment
云原生·容器·kubernetes
ejinxian1 天前
Linux 虚拟化技术 KVM/ESXI/Docker
linux·运维·docker·qemu·openvz