docker容器網路配置

来源:https://www.cnblogs.com/tushanbu/archive/2022/08/10/16571987.html
-Advertisement-
Play Games

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選項的使用格式:

  1. containerPort: 將指定的容器埠映射至主機所有地址的一個動態埠
  2. hostPort:containerPort :將容器埠containerPort映射至指定的主機埠hostPort
  3. ip::containerPort :將指定的容器埠containerPort映射至主機指定ip的動態埠
  4. ip>:hostPort:containerPort: 將指定的容器埠containerPort映射至主機指定ip的埠hostPort
    動態埠指的是隨機埠,具體的映射結果可使用docker port命令查看。
  5. -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:把這個容器這個鏡像裡面所有的埠號指定出來,是隨機的

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 索引時資料庫提高數據查詢處理性能的一個非常關鍵的技術,索引的使用可以對性能產生上百倍甚至上千倍的影響。接下來,會介紹索引的基本原理、概念,並深入學習資料庫中所使用的索引結構和存儲方式,以及如何管理、維護索引等。 1.索引的基本概念 索引時用來快速查詢表記錄的一種存儲結構,一般使用索引有一下兩個方面: ...
  • 1.避免Scoped模式註冊的服務變成Singleton模式 當提供一個生命周期模式為Singleton的服務實例時,如果發現該服務中還依賴生命周期模式為Scoped的服務實例(Scoped服務實例將被一個Singleton服務實例所引用),那麼這個被依賴的Scoped服務實例最終會成為一個Sing ...
  • 一、JSON(JavaScript Object Notation)的簡介: ① JSON和XML類似,主要用於存儲和傳輸文本信息,但是和XML相比,JSON更小、更快、更易解析、更易編寫與閱讀。 ② C、Python、C++、Java、PHP、Go等編程語言都支持JSON。 二、JSON語法規則: ...
  • WPF 實現帶蒙版的 MessageBox 消息提示框 WPF 實現帶蒙版的 MessageBox 消息提示框 作者:WPFDevelopersOrg 原文鏈接: https://github.com/WPFDevelopersOrg/WPFDevelopers.Minimal 框架使用大於等於.N ...
  • 使用原因: 在我們服務端調用第三方介面時,如:支付寶,微信支付,我們服務端需要模擬http請求並加上一些自己的邏輯響應給前端最終達到我們想要的效果 1.使用WebClient 引用命名空間 using System.Net; using System.Collections.Specialized; ...
  • time.h 頭文件 是 C 語言中 有關 時間的函數所儲存的頭文件 #include <time.h> 在介紹時間函數用法之前,我們首先要瞭解在 time.h 頭文件中已經聲明瞭的一個結構: struct tm 該結構在time.h 頭文件內聲明如下: #ifndef _TM_DEFINED #d ...
  • GlueMotion是Mac上的縮時攝影軟體,gluemotion可以對圖片進行批量操作,包括編輯、去閃爍,並將圖像序列彙編成縮時影片等,GlueMotion還可以為攝影作品進行最佳效果矯正,是攝影師必備的一款軟體。 詳情:GlueMotion for Mac(縮時攝影製作工具) GlueMotio ...
  • Compressor for Mac是一款視頻轉碼工具,可以將媒體文件轉碼為各種格式的應用。您可以將 Compressor 用於:使用標準清晰度 (SD)、高清晰度 (HD) 和 4K 格式(包括 H.264 和 HEVC,也稱為 H.265)導出視頻以在 Apple 設備上觀看。此次更新新增了從“ ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...