docker容器網路配置 Docker在安裝後自動提供3種網路,可以使用docker network ls命令查看 [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE bca5c00311b4 bridge bridg ...
docker容器網路配置
目錄
Docker在安裝後自動提供3種網路,可以使用docker network ls命令查看
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
bca5c00311b4 bridge bridge local
53aa6b51eb52 host host local
d9b9ada86204 none null local
Docker使用Linux橋接,在宿主機虛擬一個Docker容器網橋(docker0),Docker啟動一個容器時會根據Docker網橋的網段分配給容器一個IP地址,稱為Container-IP,同時Docker網橋是每個容器的預設網關。因為在同一宿主機內的容器都接入同一個網橋,這樣容器之間就能夠通過容器的Container-IP直接通信。
docker的4種網路模式
網路模式 | 配置 | 說明 |
---|---|---|
host | --network host | 容器和宿主機共用Network namespace |
container | --network container:NAME_OR_ID | 容器和另外一個容器共用Network namespace |
none | --network none | 容器有獨立的Network namespace, 但並沒有對其進行任何網路設置, 如分配veth pair 和網橋連接,配置IP等 |
bridge | --network bridge | 預設模式 |
[root@localhost ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
5cc84ad355aa: Pull complete
Digest: sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
[root@localhost ~]# docker pull httpd
Using default tag: latest
latest: Pulling from library/httpd
a2abf6c4d29d: Pull complete
dcc4698797c8: Pull complete
41c22baa66ec: Pull complete
67283bbdd4a0: Pull complete
d982c879c57e: Pull complete
Digest: sha256:0954cc1af252d824860b2c5dc0a10720af2b7a3d3435581ca788dff8480c7b32
Status: Downloaded newer image for httpd:latest
docker.io/library/httpd:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest beae173ccac6 7 months ago 1.24MB
httpd latest dabbfbe0c57b 7 months ago 144MB
//拉取鏡像併列出查看
bridge模式
當Docker進程啟動時,會在主機上創建一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連接到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網路中。
從docker0子網中分配一個IP給容器使用,並設置docker0的IP地址為容器的預設網關。在主機上創建一對虛擬網卡veth pair設備,Docker將veth pair設備的一端放在新創建的容器中,並命名為eth0(容器的網卡),另一端放在主機中,以vethxxx這樣類似的名字命名,並將這個網路設備加入到docker0網橋中。可以通過brctl show命令查看。
bridge模式是docker的預設網路模式,不寫--network參數,就是bridge模式。使用docker run -p時,docker實際是在iptables做了DNAT規則,實現埠轉發功能。可以使用iptables -t nat -vnL查看。
bridge模式如下圖所示:
[root@localhost ~]# docker run -it --network bridge --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@localhost ~]# docker run -it --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
//創建容器時添加--network bridge與不添加的效果是一樣的
container模式
這個模式指定新創建的容器和已經存在的一個容器共用一個 Network Namespace,而不是和宿主機共用。新創建的容器不會創建自己的網卡,配置自己的 IP,而是和一個指定的容器共用 IP、埠範圍等。同樣,兩個容器除了網路方面,其他的如文件系統、進程列表等還是隔離的。兩個容器的進程可以通過 lo 網卡設備通信。
container模式如下圖所示:
[root@localhost ~]# docker run -it --name b1 --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
再開一個終端
[root@localhost ~]# docker run -it --name b2 --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
//新創建的容器和前一個創建的容器ip地址是一樣
host模式
如果啟動容器的時候使用host模式,那麼這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和埠。但是,容器的其他方面,如文件系統、進程列表等還是和宿主機隔離的。
使用host模式的容器可以直接使用宿主機的IP地址與外界通信,容器內部的服務埠也可以使用宿主機的埠,不需要進行NAT,host最大的優勢就是網路性能比較好,但是docker host上已經使用的埠就不能再用了,網路的隔離性不好。
Host模式如下圖所示:
[root@localhost ~]# docker run -it --name b1 --rm --network host busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel qlen 1000
link/ether 00:0c:29:05:f4:28 brd ff:ff:ff:ff:ff:ff
inet 192.168.222.250/24 brd 192.168.222.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe05:f428/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
link/ether 02:42:cf:39:fe:c4 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:cfff:fe39:fec4/64 scope link
valid_lft forever preferred_lft forever
none模式
使用none模式,Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網路配置。也就是說,這個Docker容器沒有網卡、IP、路由等信息。需要我們自己為Docker容器添加網卡、配置IP等。
這種網路模式下容器只有lo迴環網路,沒有其他網卡。none模式可以在容器創建時通過--network none來指定。這種類型的網路沒有辦法聯網,封閉的網路能很好的保證容器的安全性。
應用場景:
啟動一個容器處理數據,比如轉換數據格式
一些後臺的計算和處理任務
none模式如下圖所示:
[root@localhost ~]# docker run -it --name b1 --rm --network none busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
[root@localhost ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "bca5c00311b41e8db87bc37ef0657fbd36e446d51e55f77ab48223c3d0a7b305",
"Created": "2022-08-04T09:11:26.614207143+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
#查看bridge網路的詳細配置
Linux內核實現名稱空間的創建
ip netns命令
可以藉助ip netns命令來完成對 Network Namespace 的各種操作。ip netns命令來自於iproute安裝包,一般系統會預設安裝,如果沒有的話,請自行安裝。
註意:ip netns命令修改網路配置時需要 sudo 許可權。
可以通過ip netns命令完成對Network Namespace 的相關操作,可以通過ip netns help查看命令幫助信息:
[root@localhost ~]# ip netns help
Usage: ip netns list
ip netns add NAME
ip netns attach NAME PID
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 list-id [target-nsid POSITIVE-INT] [nsid POSITIVE-INT]
NETNSID := auto | POSITIVE-INT
預設情況下,Linux系統中是沒有任何 Network Namespace的,所以ip netns list命令不會返回任何信息。
創建Network Namespace
通過命令創建一個名為ns0的命名空間:
[root@localhost ~]# ip netns list
[root@localhost ~]# ip netns add ns0
[root@localhost ~]# ip netns list
ns0
新創建的 Network Namespace 會出現在/var/run/netns/目錄下。如果相同名字的 namespace 已經存在,命令會報Cannot create namespace file "/var/run/netns/ns0": File exists的錯誤。
[root@localhost ~]# ls /var/run/netns/
ns0
[root@localhost ~]# ip netns add ns0
Cannot create namespace file "/var/run/netns/ns0": File exists
對於每個 Network Namespace 來說,它會有自己獨立的網卡、路由表、ARP 表、iptables 等和網路相關的資源。
操作Network Namespace
ip命令提供了ip netns exec子命令可以在對應的 Network Namespace 中執行命令。
查看新創建 Network Namespace 的網卡信息
[root@localhost ~]# ip netns exec ns0 ip addr
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
可以看到,新創建的Network Namespace中會預設創建一個lo迴環網卡,此時網卡處於關閉狀態。此時,嘗試去 ping 該lo迴環網卡,會提示Network is unreachable
[root@localhost ~]# ip netns exec ns0 ping 127.0.0.1
connect: Network is unreachable
通過下麵的命令啟用lo迴環網卡:
[root@localhost ~]# ip netns exec ns0 ip link set lo up
[root@localhost ~]# ip netns exec ns0 ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.028 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.056 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.518 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.038 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.040 ms
^C
--- 127.0.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4110ms
rtt min/avg/max/mdev = 0.028/0.136/0.518/0.191 ms
轉移設備
我們可以在不同的 Network Namespace 之間轉移設備(如veth)。由於一個設備只能屬於一個 Network Namespace ,所以轉移後在這個 Network Namespace 內就看不到這個設備了。
其中,veth設備屬於可轉移設備,而很多其它設備(如lo、vxlan、ppp、bridge等)是不可以轉移的。
veth pair
veth pair 全稱是 Virtual Ethernet Pair,是一個成對的埠,所有從這對埠一 端進入的數據包都將從另一端出來,反之也是一樣。
引入veth pair是為了在不同的 Network Namespace 直接進行通信,利用它可以直接將兩個 Network Namespace 連接起來。
創建veth pair
[root@localhost ~]# ip link add type veth
[root@localhost ~]# 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:05:f4:28 brd ff:ff:ff:ff:ff:ff
inet 192.168.222.250/24 brd 192.168.222.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe05:f428/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:cf:39:fe:c4 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:cfff:fe39:fec4/64 scope link
valid_lft forever preferred_lft forever
12: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 16:4f:71:a9:27:41 brd ff:ff:ff:ff:ff:ff
13: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether fe:be:d8:2b:86:0c brd ff:ff:ff:ff:ff:ff
可以看到,此時系統中新增了一對veth pair,將veth0和veth1兩個虛擬網卡連接了起來,此時這對 veth pair 處於”未啟用“狀態。
實現Network Namespace間通信
下麵我們利用veth pair實現兩個不同的 Network Namespace 之間的通信。剛纔我們已經創建了一個名為ns0的 Network Namespace,下麵再創建一個信息Network Namespace,命名為ns1
[root@localhost ~]# ip netns add ns1
[root@localhost ~]# ip netns list
ns1
ns0
然後我們將veth0加入到ns0,將veth1加入到ns1
[root@localhost ~]# ip link set veth0 netns ns0
[root@localhost ~]# ip link set veth1 netns ns1
然後我們分別為這對veth pair配置上ip地址,並啟用它們
[root@localhost ~]# ip netns exec ns0 ip link set veth0 up
[root@localhost ~]# ip netns exec ns0 ip addr add 192.168.222.111/24 dev veth0
[root@localhost ~]# ip netns exec ns1 ip link set veth1 up
[root@localhost ~]# ip netns exec ns1 ip addr add 192.168.222.112/24 dev veth1
查看這對veth pair的狀態
[root@localhost ~]# ip netns exec ns0 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
12: veth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 16:4f:71:a9:27:41 brd ff:ff:ff:ff:ff:ff link-netns ns1
inet 192.168.222.111/24 scope global veth0
valid_lft forever preferred_lft forever
inet6 fe80::144f:71ff:fea9:2741/64 scope link
valid_lft forever preferred_lft forever
[root@localhost ~]# ip netns exec ns1 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
13: veth1@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether fe:be:d8:2b:86:0c brd ff:ff:ff:ff:ff:ff link-netns ns0
inet 192.168.222.112/24 scope global veth1
valid_lft forever preferred_lft forever
inet6 fe80::fcbe:d8ff:fe2b:860c/64 scope link
valid_lft forever preferred_lft forever
從上面可以看出,我們已經成功啟用了這個veth pair,併為每個veth設備分配了對應的ip地址。我們嘗試在ns1中訪問ns0中的ip地址:
[root@localhost ~]# ip netns exec ns1 ping 192.168.222.111
PING 192.168.222.111 (192.168.222.111) 56(84) bytes of data.
64 bytes from 192.168.222.111: icmp_seq=1 ttl=64 time=0.166 ms
64 bytes from 192.168.222.111: icmp_seq=2 ttl=64 time=0.081 ms
64 bytes from 192.168.222.111: icmp_seq=3 ttl=64 time=0.055 ms
64 bytes from 192.168.222.111: icmp_seq=4 ttl=64 time=0.075 ms
64 bytes from 192.168.222.111: icmp_seq=5 ttl=64 time=0.048 ms
64 bytes from 192.168.222.111: icmp_seq=6 ttl=64 time=0.059 ms
^C
--- 192.168.222.111 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5134ms
rtt min/avg/max/mdev = 0.048/0.080/0.166/0.041 ms
可以看到,veth pair成功實現了兩個不同Network Namespace之間的網路交互。
veth設備重命名
[root@localhost ~]# ip netns exec ns0 ip link set veth0 down
[root@localhost ~]# ip netns exec ns0 ip link set dev veth0 name eth0
[root@localhost ~]# ip netns exec ns0 ifconfig -a
eth0: flags=4098<BROADCAST,MULTICAST> mtu 1500
inet 192.168.222.111 netmask 255.255.255.0 broadcast 0.0.0.0
ether 16:4f:71:a9:27:41 txqueuelen 1000 (Ethernet)
RX packets 19 bytes 1538 (1.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 20 bytes 1608 (1.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 10 bytes 840 (840.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10 bytes 840 (840.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
容器的常用操作
查看容器的主機名
[root@localhost ~]# docker run -it --name b1 --network bridge --rm busybox
/ # hostname
0b0052dd49c5
在容器啟動時註入主機名
[root@localhost ~]# docker run -it --name b1 --network bridge --hostname tushanbu --rm busybox
/ # hostname
tushanbu
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 tushanbu //註入主機名時會自動創建主機名到IP的映射關係
/ # cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 192.168.222.2 //DNS也會自動配置為宿主機的DNS
/ # ping www.baidu.com //可以嘗試ping百度
PING www.baidu.com (182.61.200.6): 56 data bytes
64 bytes from 182.61.200.6: seq=0 ttl=127 time=24.784 ms
64 bytes from 182.61.200.6: seq=1 ttl=127 time=42.956 ms
64 bytes from 182.61.200.6: seq=2 ttl=127 time=57.581 ms
64 bytes from 182.61.200.6: seq=3 ttl=127 time=68.769 ms
^C
--- www.baidu.com ping statistics ---
18 packets transmitted, 18 packets received, 0% packet loss
round-trip min/avg/max = 22.958/47.448/75.551 ms
手動指定容器要使用的DNS
[root@localhost ~]# docker run -it --name b1 --network bridge --hostname tushanbu --dns 192.168.222.3 --rm busybox
/ # cat /etc/resolv.conf
nameserver 192.168.222.3
手動往/etc/hosts文件中註入主機名到IP地址的映射
[root@localhost ~]# docker run -it --name b1 --network bridge --hostname tushanbu --add-host www.a.com:1.1.1.1 --rm busybox
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
1.1.1.1 www.a.com
172.17.0.2 tushanbu
開放容器埠
執行docker run的時候有個-p選項,可以將容器中的應用埠映射到宿主機中,從而實現讓外部主機可以通過訪問宿主機的某埠來訪問容器內應用的目的。
-p選項能夠使用多次,其所能夠暴露的埠必須是容器確實在監聽的埠。
p選項的使用格式:
- containerPort: 將指定的容器埠映射至主機所有地址的一個動態埠
- hostPort:containerPort :將容器埠containerPort映射至指定的主機埠hostPort
- ip::containerPort :將指定的容器埠containerPort映射至主機指定ip的動態埠
- ip>:hostPort:containerPort: 將指定的容器埠containerPort映射至主機指定ip的埠hostPort
動態埠指的是隨機埠,具體的映射結果可使用docker port命令查看。 - -P:把這個容器這個鏡像(官方)裡面所有的埠號指定出來,是隨機的
[root@localhost ~]# docker run --name web --rm -p 80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
a2abf6c4d29d: Already exists
a9edb18cadd1: Pull complete
589b7251471a: Pull complete
186b1aaa4aa6: Pull complete
b4df32aa5a72: Pull complete
a0bcbecc962e: Pull complete
Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Status: Downloaded newer image for nginx:latest
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/08/10 04:26:58 [notice] 1#1: using the "epoll" event method
2022/08/10 04:26:58 [notice] 1#1: nginx/1.21.5
2022/08/10 04:26:58 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2022/08/10 04:26:58 [notice] 1#1: OS: Linux 4.18.0-257.el8.x86_64
2022/08/10 04:26:58 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/08/10 04:26:58 [notice] 1#1: start worker processes
2022/08/10 04:26:58 [notice] 1#1: start worker process 31
2022/08/10 04:26:58 [notice] 1#1: start worker process 32
2022/08/10 04:26:58 [notice] 1#1: start worker process 33
2022/08/10 04:26:58 [notice] 1#1: start worker process 34
以上命令執行後會一直占用著前端,我們新開一個終端連接來看一下容器的80埠被映射到了宿主機的什麼埠上
[root@localhost ~]# docker port web
80/tcp -> 0.0.0.0:49153
80/tcp -> :::49153
由此可見,容器的80埠被暴露到了宿主機的49153埠上,此時我們在宿主機上訪問一下這個埠看是否能訪問到容器內的站點
[root@localhost ~]# curl http://127.0.0.1:49153
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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>
iptables防火牆規則將隨容器的創建自動生成,隨容器的刪除自動刪除規則。
將容器埠映射到指定IP的隨機埠
[root@localhost ~]# docker run --name web --rm -p 192.168.222.250::80 nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/08/10 04:33:11 [notice] 1#1: using the "epoll" event method
2022/08/10 04:33:11 [notice] 1#1: nginx/1.21.5
2022/08/10 04:33:11 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2022/08/10 04:33:11 [notice] 1#1: OS: Linux 4.18.0-257.el8.x86_64
2022/08/10 04:33:11 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/08/10 04:33:11 [notice] 1#1: start worker processes
2022/08/10 04:33:11 [notice] 1#1: start worker process 31
2022/08/10 04:33:11 [notice] 1#1: start worker process 32
2022/08/10 04:33:11 [notice] 1#1: start worker process 33
2022/08/10 04:33:11 [notice] 1#1: start worker process 34
在另一個終端上查看埠映射情況
[root@localhost ~]# docker port web
80/tcp -> 192.168.222.250:49153
將容器埠映射到宿主機的指定埠
[root@localhost ~]# docker run --name web --rm -p 80:80 nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/08/10 04:35:18 [notice] 1#1: using the "epoll" event method
2022/08/10 04:35:18 [notice] 1#1: nginx/1.21.5
2022/08/10 04:35:18 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2022/08/10 04:35:18 [notice] 1#1: OS: Linux 4.18.0-257.el8.x86_64
2022/08/10 04:35:18 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/08/10 04:35:18 [notice] 1#1: start worker processes
2022/08/10 04:35:18 [notice] 1#1: start worker process 31
2022/08/10 04:35:18 [notice] 1#1: start worker process 32
2022/08/10 04:35:18 [notice] 1#1: start worker process 33
2022/08/10 04:35:18 [notice] 1#1: start worker process 34
在另一個終端上查看埠映射情況
[root@localhost ~]# docker port web
80/tcp -> 0.0.0.0:80
80/tcp -> :::80
使用-P來進行操作,只能指定官方的鏡像
[root@localhost ~]# docker run -d -P httpd
19d198a1746c7dddd44f5100285fc65db4e24e9eb5137d05c7207e9a83a4c207
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
19d198a1746c httpd "httpd-foreground" 2 minutes ago Up 2 minutes 0.0.0.0:49154->80/tcp, :::49154->80/tcp xenodochial_haibt
[root@localhost ~]# docker port 19d198a1746c
80/tcp -> 0.0.0.0:49154
80/tcp -> :::49154
//-P:把這個容器這個鏡像裡面所有的埠號指定出來,是隨機的