【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。

相关推荐
Tim风声(网络工程师)10 分钟前
DNS有关知识(根域名服务器、顶级域名服务器、权威域名服务器)
linux·运维·服务器
热爱跑步的恒川15 分钟前
告别服务器!Amazon Lambda无服务开发实战指南
运维·服务器
照物华27 分钟前
K8s概念之进程、容器与 Pod 的终极指南
云原生·容器·kubernetes
拾心2141 分钟前
【运维进阶】Shell 函数的知识与实践
运维
helloyaren1 小时前
Docker Desktop里搭建Redis 8.2.1集群的保姆级教程
redis·学习·集群·cluster
you秀1 小时前
linux中的iptables的简介与常用基础用法
linux·运维·服务器
风和日丽 随波逐流2 小时前
java17学习笔记
笔记·学习
画中有画2 小时前
使用AI来实现拼多多自动化运营脚本
运维·人工智能·自动化·ai编程·rpa·自动化脚本
vvilkim6 小时前
Java主流框架全解析:从企业级开发到云原生
java·运维·云原生
Wy_编程10 小时前
Linux-文本搜索工具grep
linux·运维·服务器