docker run的端口映射選項分為-p(小寫,全稱--publish),-P(大寫,全稱--publish-all),之前認為只有改變容器發布給宿主機的默認端口號才會進行-p的設置,而不改變默認端口號就無所謂設置與否。但當我在進行一個go連接容器redis的實驗時才發現這個問題,即使不改變默認端口號,也要進行設置,否則宿主機是訪問不到相應容器的。打鐵要趁熱,趁著這個機緣,和大家一起來學習端口映射的選項。
一、-p(小寫),--publish
英文對此選項的解釋為將容器的端口號發布給宿主機(Publish a container's port(s) to the host),我們總喜歡稱之為端口映射。我們怎么理解方便怎么來就好了,沒必要在這上面較真。下面是實操:
docker run -d --name myredis -p 26379:6379 redis
以上是使用docker run命令以后臺方式(-d)運行容器redis,將容器命名為myredis(--name myredis),將容器的端口號6379發布給宿主機的26379端口(-p 26379:6379)。這樣宿主機想訪問容器中的myredis容器,就可以通過127.0.0.1:26379來訪問了。
我們先用docker inspect myredis
來查看端口映射是否成功。可以看出執行命令后,在輸出的信息"HostConfig"中找到“PortBindings”,里面是我們-p進行的設置。
windows上我們打開Redis Insight進行測試,選擇Add Redis database后,輸入Host和Port后,點擊Test Connection按鈕,顯示Connection is successful,連接成功。
假如不進行-p指定,我們輸入
docker run -d --name myredis redis
結果顯示如下:
無法連接myredis容器。
二、-P(大寫),--publish-all
官網解釋此選項為將所有暴露的端口發布到隨機端口(Publish all exposed ports to random ports)。基于此,我們進行測試
docker run -d --name myredis -P redis
上述指令以后臺方式(-d)運行一個redis容器(docker run),將容器命名為myredis(--name myredis),并將暴露的端口發布到隨機端口(-P)。
我們使用docker ps查看此容器。顯示如下:
可以看到系統將myredis容器的6379端口隨機映射為32768端口。再來使用Redis Insight測試,結果成功。
備注:
docker ps顯示的PORTS列表項中的數據為0.0.0.0:32768->6379/tcp。其中0.0.0.0代表任意本地和遠端ip地址都可以訪問此容器的32768端口。若是出于安全考慮,應該指定特定的IP地址才可以訪問。
另外6379/tcp中的tcp,也可以指定為udp和sctp,根據需要進行改寫即可。
最后:
一開始我說過,為了進行go連接容器redis的實驗,才發現此-p的問題,現把go源碼發上來。
//RedisTest.go
package mainimport ("context""fmt""github.com/go-redis/redis/v8"
)func main() {rdb := redis.NewClient(&redis.Options{Addr: "localhost:26379",Password: "", // no password setDB: 0, // use default DB})ctx := context.Background()// 創建一個字節切片,包含單個字節 0xc0value := []byte{0xc0}// 使用 SET 命令將鍵 key 設置為這個字節切片err := rdb.Set(ctx, "key", value, 0).Err()if err != nil {fmt.Println("Error setting value in Redis:", err)return}// 獲取鍵 key 的值result, err := rdb.Get(ctx, "key").Bytes()if err != nil {fmt.Println("Error getting value from Redis:", err)return}// 輸出獲取到的值fmt.Printf("Value from Redis: %v\n", result)
}
使用go build RedisTest.go進行編譯,再執行編譯好的RedisTest.exe,結果如下:
go build RedisTest.go
.\RedisTest.exe
Error setting value in Redis: dial tcp [::1]:26379: connectex: No connection could be made because the target machine actively refused it.
發現報錯了,連不上。是因為上面通過-P已經將26379改成了32768端口,改過再來一遍,編譯運行結果如下:
結果正是我想要的。將0xc0代表的字節轉化成數字為192。