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。