【Docker学习】docker run的端口映射-p和-P选项

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 main

import (
	"context"
	"fmt"

	"github.com/go-redis/redis/v8"
)

func main() {
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:26379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})

	ctx := context.Background()

	// 创建一个字节切片,包含单个字节 0xc0
	value := []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。

相关推荐
Three~stone9 分钟前
MySQL学习集--DDL
数据库·sql·学习
Zero_to_zero123413 分钟前
解决docker的ubuntu系统中文乱码问题
ubuntu·docker·容器
@郭小茶13 分钟前
docker-compose方式部署docker项目
运维·docker·容器
齐尹秦20 分钟前
HTML 音频(Audio)学习笔记
学习
自由鬼25 分钟前
开源虚拟化管理平台Proxmox VE部署超融合
linux·运维·服务器·开源·虚拟化·pve
瞌睡不来40 分钟前
(学习总结32)Linux 基础 IO
linux·学习·io
Moonnnn.1 小时前
运算放大器(四)滤波电路(滤波器)
笔记·学习·硬件工程
吴梓穆1 小时前
UE5学习笔记 FPS游戏制作37 蓝图函数库 自己定义公共方法
笔记·学习·ue5
吴梓穆1 小时前
UE5学习笔记 FPS游戏制作41 世界模式显示UI
笔记·学习·ue5
虾球xz2 小时前
游戏引擎学习第200天
学习·游戏引擎