docker容器命令与docker网络详解

使用 Docker 容器

容器就是对外提供服务的一个实例
容器启动的必要条件:容器内至少有一个进程运行在前台

创建容器

在 Docker 中,真正对外提供服务的还是容器,本小节咱们来创建一个容器。
创建容器的格式:docker run [option] image [cmd]
[root@alvin-test-os ~]# docker run -d --name nginx -p 80:80 nginx

Unable to find image 'nginx:latest' locally 
latest: Pulling from library/nginx 
852e50cd189d: Pull complete 
a29b129f4109: Pull complete 
b3ddf1fa5595: Pull complete 
c5df295936d3: Pull complete 
232bf38931fc: Pull complete 
Digest: sha256:c3a1592d2b6d275bef4087573355827b200b00ffc2d9849890a4f3aa2128c4ae Status: Downloaded newer image for nginx:latest 6381d29d6e0ec3f6b01cf1aabb58b799ee88acf1a722e251807c9cb44e73a3e0

补充:docker run 运行流程
1、检查本地是否用指定镜像,如果没有则去对应仓库下载镜像
2、启动容器,如果指定了命令则使用指定的命令,如果没有则使用默认的命令
3、返回容器ID

容器启动参数

#格式
docker run [参数] [镜像名称] [运行容器的启动命令]

参数

-d : 以守护进程的方式运行一个容器
docker run -d [镜像名称] [cmd]

–name : 指定容器的名称
docker run -d --name [容器名称] [镜像的名称] [cmd]

-p : 指定端口映射
docker run -d -p 宿主主机端口:容器内端口 [镜像名称] [cmd]

-P :随机端口映射
docker run -d -P [镜像名称] [cmd]

-i : 打开标准输出通常情况下与-t一起使用

-t : 创建一个伪终端
docker run -it [镜像名称] [cmd]

-v : 挂载目录到容器中
docker run -v 宿主主机目录:容器内目录 [镜像名称] [cmd]

–rm : 容器生命周期结束时立即删除
docker run --rm [镜像名称] [cmd]

-e : 在容器中创建一个环境变量
docker run -e NAME=Centos -d [镜像名称] [cmd]

–link : 连接上一个容器,实现网络互通
docker run --link 被连接的容器的名称:连接别名 [镜像名称] [cmd]

-h : 设置容器主机名
docker run -h “主机名” [镜像名称] [cmd]

-m 或 –memory:设置内存的运用限额
–memory-swap:设置 内存+swap 的运用限额。
格式是数字加单位,单位可以为 b,k,m,g。最小为 4M。 如果在发动容器时只指定 -m 而不指定 –memory-swap,那么 –memory-swap 默以为 -m 的两倍, 容器最多运用 200M 物理内存和 200M swap
docker run -m 200M –memory-swap=300M [镜像名称] [cmd]

补充:容器的生命周期
最初:docker run
随后:将启动命令运行完毕
最后:运行结束,生命周期结束

nginx前台启动:
nginx -g ‘daemon off;’

docker类似于一个小型的操作系统,但其本质就是一个进程

查看本机的容器列表

#格式
docker ps [参数]
docker ps # 查看当前系统中正在运行的容器列表

#参数
-a : 查看系统中所有的容器。
-q : 仅显示容器的ID

容器的具体释义:
在这里插入图片描述

停止容器

docker 终止容器是首先向容器发送 SIGTERM 信号,等待一段时间超时后(默认 10 秒),再发送 SIGKILL 信号 来终止容器。
格式:
#停止格式
docker stop [容器的ID|名称]
#启动(该容器必须是系统已经存在的容器)
docker start [容器的ID|名称]

[root@alvin-test-os ~]# docker ps 
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS 
NAMES 
6381d29d6e0e nginx 
"/docker-entrypoint.…" 26 minutes ago Up 25 minutes 0.0.0.0:80->80/tcp 
nginx
 820a17fe3935
 centos "/bin/bash" 4 hours ago Up 4 hours 
 happy_kare 
[root@alvin-test-os ~]# docker stop nginx 
nginx 
[root@alvin-test-os ~]# docker ps 
CONTAINER ID IMAGE 
COMMAND CREATED STATUS PORTS 
NAMES 820a17fe3935 centos 
"/bin/bash" 4 hours ago Up 4 hours 
happy_kare

可见,NGINX 容器已经被我们终止了。这个时候我们也可以重新启动这个容器。

[root@alvin-test-os ~]# docker start nginx nginx 
[root@alvin-test-os ~]# docker ps 
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS 
NAMES 
6381d29d6e0e nginx 
"/docker-entrypoint.…" 34 minutes ago Up 1 second 0.0.0.0:80->80/tcp 
nginx
进入容器

在使用容器的过程中,我们难免需要进入容器进行排查问题。下面我们就来介绍进入容器的集中方式。
** attach**
attach在早期docker提供的进入容器的命令(缺点:当其结束时,容器也跟着结束了)
格式:docker attach [容器ID|名称]
[root@instance-gvpb80ao docs]# docker attach nginx
127.0.0.1 - “GET / HTTP/1.1” 308 171 “-” “curl/7.59.0” 0.000 - .

** exec**(官方推荐使用)
在容器外向容器内执行的一个命令
格式: docker exec [参数] [容器的名称|ID] [cmd]
内部原理:自己创建一个进程,操作docker
[root@instance-gvpb80ao docs]# docker exec -it nginx /bin/bash
nginx [ / ]$
nginx [ / ]$

** nsenter** (不属于docker,exec出现后很少使用)
建立一个管道连接上容器主ID需要配合 docker inspect 来使用(早期没有 exec 命令时,企业当中最长用的方式之一),Docker 是用 golang 语言开发,所以它也支持 go 语言的模版语法。
内部原理:
相当于在宿主主机上建立一个进程,通过自己的进程连接上容器的进程

[root@instance-gvpb80ao docs]# nsenter --target $( docker inspect -f {{.State.Pid}} 
nginxv1 ) --mount --uts --ipc --net --pid 
mesg: ttyname failed: No such device 
root@6f99ae8757f7:/#

** ssh**
通过ssh连接
在生产环境中排除了使用 docker attach 命令进入容器之后,相信大家第一个想到的就是 ssh。在镜像(或容器) 中安装 SSH Server,这样就能保证多人进入容器且相互之间不受干扰了,相信大家在当前的生产环境中(没有 使用 Docker 的情况)也是这样做的。但是使用了 Docker 容器之后不建议使用 ssh 进入到 Docker 容器内。
总结
进入 docker container 中一般情况下有 4 种方式,最常用的是 exec 和 nsenter 这两种。 Nsenter 和 exec 之间的区别?
Exec 是 docker 自带的命令,Nsenter 是 Linux 提供的命令
Exec 相当于在容器内执行一个命令,而 Nsenter 是仅仅进入容器之中而已。

删除容器
可以使用 docker rm 命令来删除处于终止或退出状态的容器,
命令格式为:docker rm [容器id|名称]。
[root@alvin-test-os ~]# docker rm nginx
强制删除
强制删除一个正在运行的容器。
[root@alvin-test-os ~]# docker rm -f nginx
nginx
导入与导出容器
某些时候,需要将容器从一个系统迁移到另外一个系统,此时可以使用 Docker 的导人和导出功能,这也 是 Docker 自身提供的一个重要特性。
导出容器
导出容器是指,导出一个已经创建的容器到一个文件,不管此时这个容器是否处于运行状态 可以使用 docker [container] export 令,该命令格式为:
[root@instance-gvpb80ao docs]# docker export daf9c3656be3 > nginx.tar
[root@instance-gvpb80ao docs]# ll | grep nginx.tar
导入容器
导出的文件又可以使用 docker [ container] import 命令导人变成镜像,该命令格式为:

[root@instance-gvpb80ao docs]# docker import nginx.tar test/nginx:v1 sha256:02107323de1b074c5d2034b01eff855fec5922b45776c2721882d100ba6dd15b [root@instance-gvpb80ao docs]# docker images | grep test 
test/nginx

实际上,既可以使用 docker load 命令来导入镜像存储文件到本地镜像库,也可以使 docker [container] import 命令来导入一个容器快照到本地镜像库 这两者的区别在于 容器快照文件将丢弃所有的历史记录和元数据信息 (即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积更大 此外,从容器快照文件导人时 可以重新指定标签等元数据信息

** 查看容器**
#格式
docker inspect [容器名称|ID]
#怎么监控docker运行状态?
docker inspect -f ‘{{.State.Running}}’ nginx

[root@alvin-test-os ~]# docker inspect k8s 
[ 
     { 
          "Id": "726b695a337c63b2ba617ed282171dff82a3d51cc0bdc43194ce63beaf656c38",                                                                    																 	 		 		 	 	 	 	 	 	 		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 
          "Created": "2020-11-16T04:05:53.271281122Z", 
          "Path": "docker-entrypoint.sh", 
          "Args": [ "./start" ], 
          ... 此处略去千百行
           } 
]
容器命令详解

** 复制命令**
复制命令类似于 Linux 系统中的 scp 命令,是将宿主主机上的内容上传到容器中,也可能是将容器中的文件 下载到宿主主机中。
1、复制到容器内
docker cp [宿主主机文件路径] 容器ID:容器内路径

2、复制到容器外
docker cp 容器ID:容器内路径 [宿主主机文件路径]

# 将容器中的内容复制到宿主主机 
[root@alvin-test-os ~]# docker cp 726b695a337c:/opt/start .
[root@alvin-test-os ~]# ls | grep start Start 
#将宿主主机中的文件复制到容器中 
[root@alvin-test-os ~]# docker cp start 726b695a337c:/root
[root@alvin-test-os ~]# docker exec 726b695a337c ls /root 
start

Docker 网络

Docker 本身的技术依赖于 Linux 内核虚拟化技术的发展。所以 Docker 对 Linux 内核的特性有很强的依赖。

网络基础

其中 Docker 使用到的与 Linux 网络有关的技术分别有:网络名称空间、Veth、Iptables、网桥、路由。

** 网络名称空间**
为了支持网络协议栈的多个实例,Linux 在网络协议栈中引入了网络名称空间(Network Namespace),这些 独立的协议栈被隔离到不同的命名空间中。处于不同的命名空间的网络协议栈是完全隔离的,彼此之间无法进行网络通信,就好像两个“平行宇宙”。通过这种对网络资源的隔离,就能在一个宿主机上虚拟多个不同的网络环 境,而 Docker 正是利用这种网络名称空间的特性,实现了不同容器之间的网络隔离。在 Linux 的网络命名空间 内可以有自己独立的 Iptables 来转发、NAT 及 IP 包过滤等功能。
Linux 的网络协议栈是十分复杂的,为了支持独立的协议栈,相关的这些全局变量都必须修改为协议栈私有。 最好的办法就是让这些全局变量成为一个 Net Namespace 变量的成员,然后为了协议栈的函数调用加入一个 Namespace 参数。这就是 Linux 网络名称空间的核心。所以的网络设备都只能属于一个网络名称空间。当然, 通常的物理网络设备只能关联到 root 这个命名空间中。虚拟网络设备则可以被创建并关联到一个给定的命名空 间中,而且可以在这些名称空间之间移动。
在这里插入图片描述
** 创建一个命名空间**

[root@alvin-test-os ~]# ip netns add test01 
[root@alvin-test-os ~]# ip netns add test02 
[root@alvin-test-os ~]# ip netns list 
test02 
test01

Veth 设备对
引入 Veth 设备对是为了在不同的网络名称空间之间进行通信,利用它可以直接将两个网络名称空间链接起 来。由于要连接的两个网络命名空间,所以 Veth 设备是成对出现的,很像一对以太网卡,并且中间有一根直连 的网线。既然是一对网卡,那么我们将其中一端称为另一端的 peer。在 Veth 设备的一端发送数据时,它会将数 据直接发送到另一端,并触发另一端的接收操作。
在这里插入图片描述

Veth 设备操作

创建 Veth 设备对

[root@alvin-test-os ~]# ip link add veth type veth peer name veth001 
[root@alvin-test-os ~]# ip link show 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 
link/ether 00:0c:29:e2:5b:2d brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default l
ink/ether 02:42:ad:75:28:7e brd ff:ff:ff:ff:ff:ff 
7: veth4cb1ab3@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
link/ether ce:90:13:71:7f:8f brd ff:ff:ff:ff:ff:ff link-netnsid 0 
9: vethbbf7148@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
link/ether 7e:6c:9f:d5:5b:26 brd ff:ff:ff:ff:ff:ff link-netnsid 1 
14: veth001@veth: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 
link/ether 96:f1:a2:1d:1d:10 brd ff:ff:ff:ff:ff:ff 
15: veth@veth001: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 
link/ether 66:af:ad:f0:5f:6d brd

生成了两个 veth 设备, 互为对方的 peer。

** 绑定命名空间**

[root@alvin-test-os ~]# ip link set veth001 netns test01 
[root@alvin-test-os ~]# ip link show | grep veth 
7: veth4cb1ab3@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
9: vethbbf7148@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
15: veth@if14: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000

已经查看不到 veth001,当我们进入 test01 命名空间之后,就可以查看到

root@alvin-test-os ~]# ip netns exec test01 bash 
[root@alvin-test-os ~]# ip link show 
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 14: veth001@if15: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 
link/ether 96:f1:a2:1d:1d:10 brd ff:ff:ff:ff:ff:ff link-netnsid 0

** 将 Veth 分配 IP**

# 设置 IP
[root@alvin-test-os ~]# ip netns exec test01 ip addr add 172.16.0.111/20 dev veth001 
# 绑定 
[root@alvin-test-os ~]# ip netns exec test01 ip link set dev veth001 up 
# 查看 
[root@alvin-test-os ~]# ip netns exec test01 ip a 
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 
14: veth001@if15: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000 
link/ether 96:f1:a2:1d:1d:10 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.16.0.111/20 scope global veth001 
valid_lft forever preferred_lft forever

这个时候双方就通了。

** 查看对端 Veth 设备**

[root@alvin-test-os ~]# ip netns exec test01 ethtool -S veth001 
NIC statistics: peer_ifindex: 15 
[root@alvin-test-os ~]# ip a | grep 15 
14: veth001@if15: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000

** 为对端 Veth 设备设置 IP**

[root@alvin-test-os ~]# ip addr add 172.16.0.112/20 dev veth 
[root@alvin-test-os ~]# ip link set dev veth down 
[root@alvin-test-os ~]# ip link set dev veth up
[root@alvin-test-os ~]# ping 172.16.0.111 
PING 172.16.0.111 (172.16.0.111) 56(84) bytes of data. 64 bytes from 172.16.0.111: icmp_seq=1 ttl=64 time=0.126 ms 64 bytes from 172.16.0.111: icmp_seq=2 ttl=64 time=0.081 ms ^C
--- 172.16.0.111 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.081/0.103/0.126/0.024 ms

** 网桥**
Linux 可以支持多个不同的网络,它们之间能够相互通信,就需要一个网桥。 网桥是二层的虚拟网络设备, 它是把若干个网络接口“连接”起来,从而报文能够互相转发。网桥能够解析收发的报文,读取目标 MAC 地 址的信息,和自己记录的 MAC 表结合,来决定报文的转发目标网口。
网桥设备 brO 绑定了 eth0、 eth1 。对于网络协议械的上层来说,只看得到 brO 。因为桥接是在数据链 路层实现的 ,上层不需要关心桥接的细节,于是协议枝上层需要发送的报文被送到 brO ,网桥设备的处理代 码判断报文该被转发到 ethO 还是 ethl ,或者两者皆转发。反过来,从 ethO 或从 ethl 接收到的报文被提交 给网桥的处理代码,在这里会判断报文应该被转发、丢弃还是提交到协议枝上层。 而有时 ethl 也可能会作为 报文的源地址或目的地址 直接参与报文的发送与接收,从而绕过网桥
在这里插入图片描述
Iptables
我们知道, Linux 网络协议栈非常高效,同时比较复杂 如果我们希望在数据的处理过程中对关心的数据进行 一些操作该怎么做呢? Linux 提供了一套机制来为用户实现自定义的数据包处理过程。
在 Linux 网络协议棋中有一组回调函数挂接点,通过这些挂接点挂接的钩子函数可以在 Linux 网络棋处理数 据包的过程中对数据包进行 些操作,例如过滤、修改、丢弃等 整个挂接点技术叫作 Netfilter lptables
Netfilter 负责在内核中执行各种挂接的规则,运行在内核模式中:而 lptables 是在用户模式下运行的进程, 负责协助维护内核中 Netfilter 的各种规则表 通过 者的配合来实现整个 Linux 网络协议战中灵活的数据包处理 机制。
** 总结**

设备作用总结
network namespace主要提供了关于网络资源的隔离,包括网络设备、IPV4和ipv6协议栈、ip路由表、防火墙、/proc/net目录、/sys/class/net目录端口等
linux bridge功能相当于物理交换机,为连在其上的设备(容器)转发数据帧,如docker0网桥
iptables主要为容器提供NAT以及容器网络安全
veth pair两个虚拟网卡组成的数据通道,在docker中,用于连接docker容器和linuxbridge,一端在容器中作为eth0网卡,另一端在Linuxbridge中作为网桥的一个端口
Docker 网络模式

Docker 使用 Linux 桥接的方式,在宿主机虚拟一个 Docker 容器网桥(docker0),Docker 启动一个容器时会 根据 Docker 网桥的网段分配给容器一个 IP 地址,称为 Container-IP,同时 Docker 网桥是每个容器的默认网关。 因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。
Docker 网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接 Container-IP 访问到容器如果容器希望外部访问能够访问到,可以通过映射容器端口到 宿主主机(端口映射),即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主 机 IP]:[容器端口]访问容器。

docker网络模型配置说明
host模式–network=host容器和宿主机共享一个network namespace
containe模式–network=container:ID容器和另外一个容器共享network namespace kubernetes中的pod就是多个容器共享一个network namespace
none模式–network=none容器有独立的network namespace,但没有对其进行任何网络设置,如分配vethpair 和网桥连接,配置ip等
bridge模式–network=bridge当docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的docker容器会连接到这个虚拟网桥上,虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连接在一个二层的网络上(默认为该模式)

** HOST 模式**
如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用 host 模式的容器可以直接使用宿主机的 IP 地址与外界通信,容器内部的服务端口也可以使用宿主机的 端口,不需要进行 NAT,host 最大的优势就是网络性能比较好,但是 docker host 上已经使用的端口就不能再用了,网络的隔离性不好。

在这里插入图片描述

[root@instance-gvpb80ao ~]# docker run -d --name my-web --network host nginx 
Unable to find image 'nginx:latest' locally 
latest: Pulling from library/nginx 
d121f8d1c412: Pull complete 
ebd81fc8c071: Pull complete 
655316c160af: Pull complete 
d15953c0e0f8: Pull complete 
2ee525c5c3cc: Pull complete 
Digest: sha256:c628b67d21744fce822d22fdcc0389f6bd763daac23a6b77147d0712ea7102d0 Status: Downloaded newer image for nginx:latest 06941559a3f7e0c53cf228302dedc2040c10f2eb0b6e3d0f962c065b0e0419ce 
[root@instance-gvpb80ao ~]# docker ps 
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 06941559a3f7 nginx "/docker-entrypoint.…" 6 minutes ago Up 6 minutes my-web 
[root@instance-gvpb80ao ~]# curl 127.0.0.1:80
 <!DOCTYPE html>
  <html> 
  <head>
   <title>Welcome to nginx!</title> 
   <style> 
   body { width: 35em;
   margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } 
   </style> 
   </head> 
   <body> 
   <h1>Welcome to nginx!</h1> 
   <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> 
<p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>

** Containe 模式**
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。 新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个 容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。一系列相关的容器端口不能重复,否则容器起不来
在这里插入图片描述
[root@instance-gvpb80ao ~]# docker run -itd --name test01 busybox
Unable to find image ‘busybox:latest’ locally
latest: Pulling from library/busybox
df8698476c65: Pull complete
Digest: sha256:d366a4665ab44f0648d7a00ae3fae139d55e32f9712c67accd604bb55df9d05a Status: Downloaded newer image for busybox:latest dd99687d303d61d649364084ad353ec38b4e07149b0328301ec9691f18669951 [root@instance-gvpb80ao ~]# docker run -itd --name test02 --network “container:test01” busybox
72adb0dcdb93b6adc7a62e1ad1ac274f64b8cec941d5f89da43fcd0757f99fa3
[root@instance-gvpb80ao ~]# docker exec -it test02 sh
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:28 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:2423 (2.3 KiB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ # exit
[root@instance-gvpb80ao ~]# docker exec -it test01 sh
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:29 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:2493 (2.4 KiB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ #
** none 模式**
使用 none 模式,Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker 容器进行任何网络 配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置 IP 等。
这种网络模式下容器只有 lo 回环网络,没有其他网卡。none 模式可以在容器创建时通过–network=none 来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
在这里插入图片描述
[root@instance-gvpb80ao ~]# docker run -itd --name test03 --network none busybox b9dde79754bc110314be4aecde1251dcdd6ce28fdf43102ae184b79c6e7414bc [root@instance-gvpb80ao ~]# docker exec -it test03 sh
/ # ifconfig
lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

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

从 docker0 子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关。在主机上创建 一对虚拟网卡 veth pair 设备,Docker 将 veth pair 设备的一端放在新创建的容器中,并命名为 eth0(容器的网 卡),另一端放在主机中,以 vethxxx 这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中。可以 通过 brctl show 命令查看。

bridge 模式是 docker 的默认网络模式,不写–net 参数,就是 bridge 模式。使用 docker run -p 时,docker 实际是在 iptables 做了 DNAT 规则,实现端口转发功能。可以使用 iptables -t nat -vnL 查看。
在这里插入图片描述
[root@instance-gvpb80ao ~]# docker run -itd --name test04 busybox dd17d863b2957a29df44b2552365eb0cfc01552fd4ec6b8b63e28dfd0d61472e
[root@instance-gvpb80ao ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether fa:16:3e:4a:9c:c7 brd ff:ff:ff:ff:ff:ff inet 172.16.0.4/20 brd 172.16.15.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fe4a:9cc7/64 scope link noprefixroute valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group
default
link/ether 02:42🆎42:6a:8a brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:abff:fe42:6a8a/64 scope link
valid_lft forever preferred_lft forever
5: veth870d996@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether ae:36:24:dc:11:6d brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::ac36:24ff:fedc:116d/64 scope link valid_lft forever preferred_lft forever
7: veth6acb18a@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 4e:03:b1:5e:40:91 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::4c03:b1ff:fe5e:4091/64 scope link valid_lft forever preferred_lft forever [root@instance-gvpb80ao ~]# docker exec -it test04 bash
/ # ping 172.16.0.4 PING 172.16.0.4 (172.16.0.4): 56 data bytes 64 bytes from 172.16.0.4: seq=0 ttl=64 time=0.113 ms 64 bytes from 172.16.0.4: seq=1 ttl=64 time=0.101 ms ^C
— 172.16.0.4 ping statistics —
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.101/0.107/0.113 ms

创建自己的网桥

#创建网桥
[root@docker1 ~]# docker network create yzl
1ff65336a2acff7c1eaf1f218a1523d70a74027244662a0a6992b7d5b8b36919

#查看创建的网桥
[root@docker1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
6db861e6fa5c bridge bridge local
53994c006463 host host local
5983e3ca3d0d lnmp bridge local
413c0d77b5d2 none null local
1ff65336a2ac yzl bridge local

docker network命令

语法:docker network [command]

command:

connect 网桥连接容器
create 创建网桥
disconnect 断开连接
inspect 展示network的详细信息
ls 展示network列表
prune 清理没有被使用到的network(除了自带的三个网络如:none bridge host)
rm 删除一个或多个network(除了自带的三个网络如:none bridge host)

总结

1、host模式
容器使用宿主主机的网卡,不能跟宿主主机之间的端口冲突。

2、Container模式
一个容器使用另一个容器的网卡。一系列相关的容器端口不能重复,否则会因为端口被占用而起不来

3、none模式
没有外网,只有物理回环网络,绝对安全,但无法与外界通信

4、bridge模式
从 docker0 子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关

作业:网桥搭建wordpress

数据库

[root@docker1 php]# docker run -d -e MYSQL_ROOT_PASSWORD=123 --network=lnmp --name mysql mysql:5.7
a10b78635ea9adc887bf52b9e2ce42d8c6caf96fbb694f63f5751d5d0daef102
[root@docker1 php]#  docker exec -it mysql bash
root@a10b78635ea9:/# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.35 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database wordpress;
Query OK, 1 row affected (0.00 sec)

PHP

#配置文件
[root@docker1 php]# cat Dockerfile 
FROM centos:7
ADD www.conf /etc/php-fpm.d/www.conf
ADD php.repo /etc/yum.repos.d/php.repo
RUN useradd www
RUN yum install -y php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongodb php71w-bcmath --skip-broken
EXPOSE 9000
CMD ["php-fpm,"-F""]

[root@docker1 php]# cat php.repo 
[php-webtatic]
name = PHP Repo
baseurl = http://us-east.repo.webtatic.com/yum/el7/x86_64/
gpgcheck = 0
enable = 1

[root@docker1 php]# cat www.conf 
[www]
user = www
group = www
listen = 9000
request_terminate_timeout = 0
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path]    = /var/lib/php/session
php_value[soap.wsdl_cache_dir]  = /var/lib/php/wsdlcache

#构建镜像
[root@docker1 php]# docker build -t php:v1 .


#此处的PHP镜像为自构建镜像
[root@docker1 php]# docker run -it --name php --network=lnmp -v /opt/wordpress/:/usr/share/nginx/html php:v1 bash
[root@336b4563608a /]# php-fpm -F
[28-Jul-2021 09:35:33] NOTICE: fpm is running, pid 16
[28-Jul-2021 09:35:33] NOTICE: ready to handle connections
[28-Jul-2021 09:35:33] NOTICE: systemd monitor interval set to 10000ms

nginx

[root@docker1 nginx]# docker run -d --name nginx -p 80:80 --network=lnmp -v /opt/wordpress/:/usr/share/nginx/html nginx

[root@docker1 nginx]# docker exec -it nginx bash

root@33c253b8d18d:/# useradd www

[root@docker1 ~]# cd nginx/

[root@docker1 nginx]# docker cp default.conf 
nginx:/etc/nginx/conf.d/

[root@docker1 nginx]# docker cp nginx.conf nginx:/etc/nginx/

[root@docker1 nginx]# docker restart nginx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值