程式語言初學者 Docker 入門第七章 —— 連接埠對應與容器相連
需要多個服務元件之容器協作運作的情況。需要多個容器之間能夠彼此存取到對方的服務。
除了網路存取,服務連線基本需求還有:
- 允許度應容器內應用程式的監聽埠到本地端 Host 主機
- 戶連機制(link)實現多個容器間內過容器名稱來快速連接。
對應連接埠來存取容器
1. 從外部存取容器應用程式
啟動容器時如果不指定連接埠對應參數,在容器外部是無法透過網路來存取容器內的各項網路應用和服務
當容器內執行一些網路應用程式,要讓外部存取這些服務時,可以用 -P
或 -p
參數來指定連接埠對應
-
不加
-p
參數$ docker run -d training/webapp python app.py c1a2e0f91b6f593e13e05659dd927b391bac65711fcfd0bbac9443002763c648 $ docker run -d training/webapp python app.py de1cb4fbc539b07741821ffe3d72d7cd436fd8ed052f4d4b987e1750d46252b1 $ docker run -d training/webapp python app.py e252e4aab6b252398d7ccce756c7a020dccdf4bc1faf832e35b9c1bdf1145481 $ docker run -d training/webapp python app.py 1058336f9128a18c0663ba270550cd8102e23a4be208143de4bbb56cecf81364$ docker run -d training/webapp python app.py
可以連開好幾個都正常
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1058336f9128 training/webapp "python app.py" About a minute ago Up About a minute 5000/tcp nervous_haibt e252e4aab6b2 training/webapp "python app.py" About a minute ago Up About a minute 5000/tcp zealous_pike de1cb4fbc539 training/webapp "python app.py" About a minute ago Up About a minute 5000/tcp tender_einstein1 c1a2e0f91b6f training/webapp "python app.py" About a minute ago Up About a minute 5000/tcp lucid_banzai
ports 都是
5000/tpc
全部 container 都沒有遇到 port 衝突從這個實驗結果可以了解 container 具有隔離特性,也就是每個 container 都是獨立的個體,它們各自有屬於自己的
5000/tpc
可以用,因此才不會相衝。但這樣無法從外界存取 container,因此要做點手腳才行 port forwarding
Docker 使用
-p
選項設定 port forwarding -
-P
隨機對應一個 49000~49900 範圍的連接埠到容器內部有開放的連接埠:$ docker run -d -P training/webapp python app.py $ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 565d7910988d training/webapp "python app.py" About a minute ago Up About a minute 0.0.0.0:49153->5000/tcp, :::49153->5000/tcp cranky_ritchie
本機的 TCP:49153 port 被對應到容器的 TCP:5000 port
存取 Host 主機的 49153 連接埠,即可開啟容器內的 web 應用系統所提供的畫面
docker logs -f cranky_ritchie
查看容器內應用程式資訊$ docker logs -f cranky_ritchie * Running on <http://0.0.0.0:5000/> (Press CTRL+C to quit)
在網頁輸入
<http://0.0.0.0:49153/> <http://127.0.0.1:49153/> <http://10.1.113.39:49153/>
都可以 work
但是
log
會不一樣172.17.0.1 - - [21/Jun/2021 03:43:39] "GET / HTTP/1.1" 200 - 172.17.0.1 - - [21/Jun/2021 04:02:47] "GET / HTTP/1.1" 200 - 10.1.113.39 - - [21/Jun/2021 03:39:18] "GET / HTTP/1.1" 200 -
172.17.0.1 是 docker 的 IP
10.1.113.39 是本機的 IP
-
-p
可以指定要對應的連接埠,支援三種格式- IP:HostPort:ContainerPort
- IP::ContainerPort
- HostPort:ContainerPort
2. 對應所有界面位址的特定連接埠
使用 HostPort:ContainerPort 格式將本地的 5000 port 對應到容器的 5000 port
$ docker run -d -p 5000:5000 training/webapp python app.py
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
64a6944ba244 training/webapp "python app.py" 3 seconds ago Up 2 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp hopeful_rubin
$ docker port hopeful_rubin
5000/tcp -> 0.0.0.0:5000
5000/tcp -> :::5000
此時預設會榜定本機所有界面上的所有位址
多次使用 -p 可以榜定多個連接埠
$ docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7f16630b2e2 training/webapp "python app.py" 3 seconds ago Up 2 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp, 0.0.0.0:3000->80/tcp, :::3000->80/tcp naughty_montalcini
$ docker port naughty_montalcini
5000/tcp -> 0.0.0.0:5000
5000/tcp -> :::5000
80/tcp -> 0.0.0.0:3000
80/tcp -> :::3000
3. 對應到特定位址並指定連接埠
IP:HostPort:ContainerPort 指定對應使用一個特定位址
ex: localhost 位址 127.0.0.1:
$ docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9c93f7b657f6 training/webapp "python app.py" 2 seconds ago Up 2 seconds 127.0.0.1:5000->5000/tcp loving_bell
網頁輸入:
command line 輸入
curl 127.0.0.1:5000
curl 0.0.0.0:5000
4. 對應到特定位址的任意連接埠
IP::ContainerPort 榜定 localhost 的任意連接埠到容器的 5000 port,本地端主機會自動分配一個連接埠:
$ docker run -d -p 127.0.0.1::5000 training/webapp python app.py
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9441c69e82ce training/webapp "python app.py" 2 seconds ago Up 2 seconds 127.0.0.1:49153->5000/tcp sad_grothendieck
$ curl 127.0.0.1:49153
Hello world!
用 udp 參數 指定 udp port:
$ docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22f6fc5c70eb training/webapp "python app.py" 3 seconds ago Up 2 seconds 5000/tcp, 127.0.0.1:5000->5000/udp fervent_cartwright
5. 查看對應連接埠
docker port ContainerName ContainerPort
$ docker port sad_grothendieck
5000/tcp -> 127.0.0.1:49153
$ docker port fervent_cartwright
5000/udp -> 127.0.0.1:5000
容器有自己的內部網路和 IP 位址 docker inspect + 容器 ID 可以顯示容器內部資訊
小補充
$ docker run -d -p 8000:80 httpd
a029cadf17ce6fc837a4977cc4201b5028be4f32a9bd9fbf76c8981215d5f33b
$ curl localhost:8000
<html><body><h1>It works!</h1></body></html>
$ curl <http://localhost:8000>
<html><body><h1>It works!</h1></body></html>
使用 Port forwarding 開放服務 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
互連機制來實現快速存取
容器的互聯 linking 機制是一種讓多個容器內應用程式進行快速溝通的方式。
他會在來源與接收容器之間建立連接關係,接收容器可以透過容器名稱快速存取到來源容器,而不用指定具體的 IP 位址
1. 自訂容器命名
docker 互連機制依據容器的名稱來執行,好記的容器名字
-
--name
為容器命名docker run -d -P --name web training/webapp python app.py
-
docker ps -l
查看 latest containerdocker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES db9353d7441e training/webapp "python app.py" 2 minutes ago Up About a minute 0.0.0.0:55000->5000/tcp, :::55000->5000/tcp web
-
docker inspect
查看容器名稱docker inspect -f "{{ .Name}}" db93 /web
2. 容器間互連
使用 --link name:alias
<aside> 💡 name 連接的容器名稱 alias 讓要連接之容器來識別用的別名
</aside>
-
建立新的容器資料庫
docker run -d --name db training/postgres
-
刪除執行中的 web
$ docker rm -f web web
-
建立一個新的 web 容器並將它連接到 db 容器
docker run -d -P --name web --link db:db training/webapp python app.py
-
查看容器連接
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 295aa124ae15 training/webapp "python app.py" 6 seconds ago Up 4 seconds 0.0.0.0:55002->5000/tcp, :::55002->5000/tcp web fcb136e458a3 training/postgres "su postgres -c '/us…" 3 minutes ago Up 3 minutes 5432/tcp db
Docker 相當於在兩個互連的容器之間建立一個虛擬通道,而且不用對應他們的連接埠到 Host 主機上。在啟動 db 容器的時候並沒有使用 -p
/-P
標記,進而避免了暴露資料庫連接埠到外部網路上
Docker 透過兩種方式為容器公開連接資訊:
-
更新環境變數
使用
env
命令來查看 web 容器的環境變數$ docker run --rm --name web2 --link db:db training/webapp env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=73590563bb9b DB_PORT=tcp://172.17.0.2:5432 DB_PORT_5432_TCP=tcp://172.17.0.2:5432 DB_PORT_5432_TCP_ADDR=172.17.0.2 DB_PORT_5432_TCP_PORT=5432 DB_PORT_5432_TCP_PROTO=tcp DB_NAME=/web2/db DB_ENV_PG_VERSION=9.3 HOME=/root
<aside> 💡 DB_ 是提供 web 容器連接 db 容器使用的,前綴字採用大寫的連接之容器別名(db)
</aside>
-
更新 /etc/hosts 檔
連接 web 的 hosts 檔:
$ docker run -t -i --rm --link db:db training/webapp /bin/bash root@bc8513f69256:/opt/webapp# 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 db 98a6890f8cc4 172.17.0.5 bc8513f69256
此處有兩個 hosts 資訊:
-
web 容器:用自己的容器 ID 做為預設主機名稱
-
db 容器:IP 和主機名稱,可以在 web 容器中安裝 ping 指令來測試與 db 容器的網路是否相通:
root@5eca5dbf7b16:/opt/webapp# apt-get install -yqq inetutils-ping (Reading database ... 18233 files and directories currently installed.) Removing ubuntu-minimal (1.325) ... Removing iputils-ping (3:20121221-4ubuntu1.1) ... Selecting previously unselected package inetutils-ping. (Reading database ... 18221 files and directories currently installed.) Preparing to unpack .../inetutils-ping_2%3a1.9.2-1_amd64.deb ... Unpacking inetutils-ping (2:1.9.2-1) ... Setting up inetutils-ping (2:1.9.2-1) ... root@5eca5dbf7b16:/opt/webapp# ping db PING db (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=2.288 ms 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.263 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.626 ms 64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=1.207 ms 64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.261 ms 64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.333 ms 64 bytes from 172.17.0.2: icmp_seq=6 ttl=64 time=0.167 ms
用 ping 來測試 db 容器,他會解析成 172.17.0.2。使用者可也結合多個連接容器到來源容器,例如可以連接多個 web 容器到同一個 db 容器上
-
Comments
Post a Comment