目录
Docker四种网络模式
HOST模式
与宿主机供共享网络名称空间/网络协议栈、IP共享、端口范围共享host容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是dockerhost上已经使用的端口就不能再用了。网终的隔离性不好
container模式
创建的容器不会创建自己的网卡、设置IP等,而是和一个指定地容器共享IP、端口范围
这个模式指定新创建的容器和已经存在的一个容器共享一个network namespace,而不是和宿主机共享,新创建的容器不会创建自己的网卡,配置自己的IlP,而是和一个指定地容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表还是隔离的。(两个容器的进程可以通过loo 网卡设备通信)
None
该模式关闭了容器的网络功能
这种网络模式下容器只有lo回环网口,没有其他的网卡。none模式可以在容器创建时通过-network=none参数指定
这种类型的网络无法联网,但是封闭的网络能很好的保证容器的安全性
Bridge:
此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker虚拟网桥,通过dockero 网桥及iptables.的nat表配置与宿主机通信
当Docker进程启动时,会在主机上创建一个名为dockero的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从dockerO子网中分配一个IP给容器使用,并设置docker0的地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair 设备,Docker将veth pair 设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过 brctl show命令查看。
bridge模式是docker的默认网络模式,不写-net参数,就是 bridge模式。使用docker run -p时, docker实际是在iptables 做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。
docker自定义网络
查看网络模式列表
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
ae257e2de599 bridge bridge local
7139a3eda38f host host local
2df381358ab3 none null local
查看容器信息(包含配置、环境、网关、挂载、cmd等等信息)
docker inspect容器ID
[root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8cf6de64a6b3 php:v1 "./sbin/php-fpm -c /…" 43 hours ago Up 43 hours 0.0.0.0:49153->9000/tcp, :::49153->9000/tcp funny_rosalind [root@localhost ~]# docker inspect 8cf6de64a6b3 [ { "Id": "8cf6de64a6b3dc5f1fd017d122da81fef48d445cc25f67a7a3534f243c1a6624", "Created": "2022-01-14T12:23:14.846582753Z", "Path": "./sbin/php-fpm", "Args": [ "-c", "/usr/local/php/etc/php-fpm.conf" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 32820, "ExitCode": 0, "Error": "", "StartedAt": "2022-01-14T12:23:15.17019772Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:7fa269790e889e2f1d0ae636b99a2f8840952eec09e329825b5033268ef7da3e", "ResolvConfPath": "/var/lib/docker/containers/8cf6de64a6b3dc5f1fd017d122da81fef48d445cc25f67a7a3534f243c1a6624/resolv.conf", "HostnamePath": "/var/lib/docker/containers/8cf6de64a6b3dc5f1fd017d122da81fef48d445cc25f67a7a3534f243c1a6624/hostname", "HostsPath": "/var/lib/docker/containers/8cf6de64a6b3dc5f1fd017d122da81fef48d445cc25f67a7a3534f243c1a6624/hosts", "LogPath": "/var/lib/docker/containers/8cf6de64a6b3dc5f1fd017d122da81fef48d445cc25f67a7a3534f243c1a6624/8cf6de64a6b3dc5f1fd017d122da81fef48d445cc25f67a7a3534f243c1a6624-json.log", "Name": "/funny_rosalind", "RestartCount": 0, "Driver": "overlay2", "Platform": "linux", "MountLabel": "", "ProcessLabel": "", "AppArmorProfile": "", "ExecIDs": null, "HostConfig": { "Binds": null, "ContainerIDFile": "", "LogConfig": { "Type": "json-file", "Config": {} }, "NetworkMode": "default", "PortBindings": {}, "RestartPolicy": { "Name": "no", "MaximumRetryCount": 0 }, "AutoRemove": false, "VolumeDriver": "", "VolumesFrom": null, "CapAdd": null, "CapDrop": null, "CgroupnsMode": "host", "Dns": [], "DnsOptions": [], "DnsSearch": [], "ExtraHosts": null, "GroupAdd": null, "IpcMode": "private", "Cgroup": "", "Links": null, "OomScoreAdj": 0, "PidMode": "", "Privileged": false, "PublishAllPorts": true, "ReadonlyRootfs": false, "SecurityOpt": null, "UTSMode": "", "UsernsMode": "", "ShmSize": 67108864, "Runtime": "runc", "ConsoleSize": [ 0, 0 ], "Isolation": "", "CpuShares": 0, "Memory": 0, "NanoCpus": 0, "CgroupParent": "", "BlkioWeight": 0, "BlkioWeightDevice": [], "BlkioDeviceReadBps": null, "BlkioDeviceWriteBps": null, "BlkioDeviceReadIOps": null, "BlkioDeviceWriteIOps": null, "CpuPeriod": 0, "CpuQuota": 0, "CpuRealtimePeriod": 0, "CpuRealtimeRuntime": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": [], "DeviceCgroupRules": null, "DeviceRequests": null, "KernelMemory": 0, "KernelMemoryTCP": 0, "MemoryReservation": 0, "MemorySwap": 0, "MemorySwappiness": null, "OomKillDisable": false, "PidsLimit": null, "Ulimits": null, "CpuCount": 0, "CpuPercent": 0, "IOMaximumIOps": 0, "IOMaximumBandwidth": 0, "MaskedPaths": [ "/proc/asound", "/proc/acpi", "/proc/kcore", "/proc/keys", "/proc/latency_stats", "/proc/timer_list", "/proc/timer_stats", "/proc/sched_debug", "/proc/scsi", "/sys/firmware" ], "ReadonlyPaths": [ "/proc/bus", "/proc/fs", "/proc/irq", "/proc/sys", "/proc/sysrq-trigger" ] }, "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/ab2ca8054c8b0d6561f7a9025bedf1b511be4e4e0bf681e98fb76fb2fb4e6e75-init/diff:/var/lib/docker/overlay2/97bc9178426c019232698efa14f23a6922b989af17b5957b064084ac14a6080a/diff:/var/lib/docker/overlay2/8a45ccd13ce9b7c1d1ff6306b7cd57116b9ebd7650adb111205c7b1dcba602f6/diff:/var/lib/docker/overlay2/56a412a6cb9dc1d51ed1fefe713414dbbcbf3812456db60ae42e3990c969f777/diff:/var/lib/docker/overlay2/0346a1489ea29c73cc823d868ca2ecf3d2eecba37e526d3be487962a31799d8b/diff:/var/lib/docker/overlay2/e5570432f6efca48c9349b39348e9d7270c0039825bc765661ebe3d642d0d881/diff", "MergedDir": "/var/lib/docker/overlay2/ab2ca8054c8b0d6561f7a9025bedf1b511be4e4e0bf681e98fb76fb2fb4e6e75/merged", "UpperDir": "/var/lib/docker/overlay2/ab2ca8054c8b0d6561f7a9025bedf1b511be4e4e0bf681e98fb76fb2fb4e6e75/diff", "WorkDir": "/var/lib/docker/overlay2/ab2ca8054c8b0d6561f7a9025bedf1b511be4e4e0bf681e98fb76fb2fb4e6e75/work" }, "Name": "overlay2" }, "Mounts": [], "Config": { "Hostname": "8cf6de64a6b3", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "9000/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "./sbin/php-fpm", "-c", "/usr/local/php/etc/php-fpm.conf" ], "Image": "php:v1", "Volumes": null, "WorkingDir": "/usr/local/php", "Entrypoint": null, "OnBuild": null, "Labels": { "org.label-schema.build-date": "20201113", "org.label-schema.license": "GPLv2", "org.label-schema.name": "CentOS Base Image", "org.label-schema.schema-version": "1.0", "org.label-schema.vendor": "CentOS", "org.opencontainers.image.created": "2020-11-13 00:00:00+00:00", "org.opencontainers.image.licenses": "GPL-2.0-only", "org.opencontainers.image.title": "CentOS Base Image", "org.opencontainers.image.vendor": "CentOS" } }, "NetworkSettings": { "Bridge": "", "SandboxID": "8489906f3513ae2b56f596af061a01e863a511854f4018dc53f6d78fe77bccce", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": { "9000/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "49153" }, { "HostIp": "::", "HostPort": "49153" } ] }, "SandboxKey": "/var/run/docker/netns/8489906f3513", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "21b59d7d982195c35a042e573ad32e97c4a816747cc3028517c69c54ed57b60a", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:02", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "ae257e2de59963aa1a52fbe90feef0ab8ce7523c36afe95f5c4bdd1dea6dee74", "EndpointID": "21b59d7d982195c35a042e573ad32e97c4a816747cc3028517c69c54ed57b60a", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } } } } ]
指定分配容器IP地址
docker run -itd --name test1 --network bridge --ip 172.17.0.10 centos:latest /bin/bash(会报错)
因为用户指定的IP地址只支持用户自定义网络。
[root@localhost ~]# docker run -itd --name test1 --network bridge --ip 172.17.0.10 centos:latest /bin/bash
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
e7ac622660ffdd8c0da45e1c147abc5d5360546dc7438a952cf8d2bda6c8e81d
docker: Error response from daemon: user specified IP address is supported on user defined networks only.
自定义网络固定IP
docker network create [--network bridge] --subnet=172.18.0.0/16 mynetwork
docker run -itd --name test2 --net mynetwork --ip 172.18.0.100 centos:latest /bin/bash
[root@localhost ~]# docker network create --subnet=172.18.0.0/16 mynetwork
73927b376e17d92af084b5d009434595bc85ccc10fd968a767a1cbd21fb7e114
[root@localhost ~]# docker run -itd --name test2 --net mynetwork --ip 172.18.0.100 centos:latest /bin/bash
14e3fe4f8984173f2f7ac8d8e7d2b651271cab092db4c95b87662a253a5a2e34
查看docker容器,此时不报错
端口映射
在启动容器的时候,如果不指定对应的端口,在容器外将无法通过网络来访问容器内的服务。Docker提供端口映射机制来将容器内的服务提供给外部网络访问,实质上就是将宿主机的端口映射到容器上,使得外部网络访问宿主机的端口便可以访问容器内的服务。
实现端口映射,需运行docker run 命令使用-p(小写)选项指定要映射的端口
使用-P(大写)选项实现随机映射,Docker会随机映射一个端口范围在49000-49900的端口到容器内不开放的网络端口。
-p自定义瑞口(宿主机端口:容器内端口)
-P随机端口(-P 49153起始49153到65535)
docker run -itd -p 333:80 nginx /bin/bash (docker 0)
docker run -itd -P nginx / bin/ bash
在宿主机环境执行容器内命令
docker exec -it容器ID /bin/bash -c ls
docker exec容器ID/容器name 执行的命令[root@localhost ~]# docker exec -it 57d0cb8e7608 /bin/bash -c ls bin docker-entrypoint.d home media proc sbin tmp boot docker-entrypoint.sh lib mnt root srv usr dev etc lib64 opt run sys var
Docker的数据管理
在Docker中,为了方便查看容器内产生的数据或者将多个容器中的数据实现共享,就涉及到容器的数据管理操作
管理Docker容器中数据主要有两种方式:数据卷(Data Volumes)和数据卷容器(Data Volunes Containers)。
数据卷
数据卷是一个供容器使用的特殊目录,位于容器中,可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立刻可见,并且更新数据不会影响镜像,从而实现数据在宿主机与容器之间的迁移。数据卷的使用类似于Linux下对目录进行的mount操作。
创建数据卷
在docker run 命令使用-v 选项可以在容器内创建数据卷。多次使用 -v 选项可创建多个数据卷。使用--name 选项可以给容器创建一个友好的自定义名称。
宿主机目录/var/ www挂载容器中的/data1
[root@localhost /data]# docker run -itd -v /var/www:/data1/ --name web1 centos /bin/bash
7ef37e79816ae729b22b7e5aa5920a10643346efa2518955b42e1fbdedbafccc
进入web1容器
[root@localhost /data]# docker exec -it web1 /bin/bash
[root@7ef37e79816a /]# ls
bin data1 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@7ef37e79816a /]# cd /var/
[root@7ef37e79816a var]# ls
adm cache crash db empty ftp games gopher kerberos lib local lock log mail nis opt preserve run spool tmp yp
[root@7ef37e79816a var]# cd /data1/
[root@7ef37e79816a data1]# ls
[root@7ef37e79816a data1]# touch test111
[root@7ef37e79816a data1]# touch index.html
[root@7ef37e79816a data1]# ls
index.html test111
[root@7ef37e79816a data1]# exit
exit
回到宿主机查看,可以看到创建的文件在宿主机上存在。
[root@localhost /data]# cd /var/
[root@localhost /var]# ls
account adm cache crash db empty games gopher kerberos lib local lock log mail nis opt preserve run spool target tmp www yp
[root@localhost /var]# cd www/
[root@localhost /var/www]# ls
index.html test111
数据卷容器
如果需要在容器之间共享一些数据,最简单的方法就是使用数据卷容器。它其实就是一个简单的容器,专门提供数据卷给其他容器挂载使用。使用方法就是,首先要创建一个容器作为数据卷容器,之后在其他容器创建时用--volume-from 挂载数据卷容器中的数据卷使用。
首先创建两个数据卷
[root@localhost /var/www]# docker run --name web100 -v /data3 -v /data4 -itd centos /bin/bash
ebe7ac343ee9b6f0af47f25922d317ee22cf968254163a06edb697b2339d6339
数据卷容器
[root@localhost /var/www]# docker run -itd --volumes-from web100 --name db1 centos /bin/bash
a27c0c385031e37147f4a5db913042ce1ebe56db8ef246985365e869734015ba
在db1容器中创建文件,在web100容器中查看
[root@localhost /var/www]# docker exec -it db1 /bin/bash
[root@a27c0c385031 /]# cd /data1
bash: cd: /data1: No such file or directory
[root@a27c0c385031 /]# cd /data3/
[root@a27c0c385031 data3]# ls
[root@a27c0c385031 data3]# touch file
[root@a27c0c385031 data3]# ls
file
[root@a27c0c385031 data3]# exit
exit
[root@localhost /var/www]# docker exec -it web100 /bin/bash
[root@ebe7ac343ee9 /]# ls
bin data3 data4 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@ebe7ac343ee9 /]# cd data3/
[root@ebe7ac343ee9 data3]# ls
file
原理:让两个容器实现数据共享
总结
1、Docker的四种网络模式,以及它是怎么工作的
2、容器中管理数据有数据卷和数据卷容器两种方式。
3、Docker可以使用映射容器端口到宿主机来实现网络访问