Podman Pod中容器指定端口运行问题及方案咨询
错误:提供的配置无效:创建Pod时必须定义已发布或暴露的端口
创建带端口映射的Pod:
podman pod create --name $PODNAME
构建PostgreSQL容器镜像:
podman build -t $FILM_CONTAINER_NAME_POSTGRES --build-arg SQL_FILE=$FILM_DB_SQL ./docker/db
在Pod中运行带端口映射的PostgreSQL容器:
podman run -d --pod $PODNAME --name $FILM_CONTAINER_NAME_POSTGRES -p 54321:5432 $FILM_CONTAINER_NAME_POSTGRES
疑问点:
- 为什么无法在Pod中创建各自运行在指定端口的容器?
- 如果创建Pod时指定端口,容器该如何知晓自身应运行的端口?
- 尝试添加
--share cgroup解决,但容器间连接会被拒绝。
构建电影应用容器镜像:
podman build -t $FILM_CONTAINER_NAME .
在Pod中运行带端口映射的电影应用容器:
podman run -t --name $FILM_CONTAINER_NAME --pod $PODNAME \ -e POSTGRESQL_DATABASE="$FILM_DB_NAME" \ -e POSTGRESQL_USER=postgres \ -e POSTGRESQL_PASSWORD=postgres \ -e POSTGRESQL_DATASOURCE="$FILM_DATASOURCE" \ -e POSTGRESQL_SERVICE_PORT="$FILM_DB_PORT" \ -p 8081:8080 \ $FILM_CONTAINER_NAME
补充说明:
使用--net=host虽能解决连接问题,但需移除容器端口。现寻求无需使用YAML或Kubernetes的解决方案,期望让每个容器都运行在指定端口。
问题根源与解决方案
1. 端口错误的原因
Podman要求创建Pod时必须明确对外暴露或发布端口,因为Pod内所有容器共享同一网络命名空间,Pod的端口是对外提供服务的统一入口。直接执行podman pod create --name $PODNAME未指定任何端口,因此触发该错误。
2. 让容器运行在指定端口且正常通信的方案
Pod内容器共享网络栈,容器间可直接通过localhost+自身监听端口通信,不需要额外端口映射;对外暴露的端口只需在Pod层面指定一次即可,无需在容器重复设置。
正确操作流程:
创建带端口映射的Pod:
# 直接在创建Pod时指定对外暴露的端口映射规则 podman pod create --name $PODNAME -p 54321:5432 -p 8081:8080这里的
-p 宿主机端口:容器端口是将Pod的端口映射到宿主机,Pod内容器只要监听对应的容器端口(5432和8080),就能通过Pod的映射端口对外提供服务。运行PostgreSQL容器:
无需在podman run中重复加-p参数,直接加入Pod即可:podman run -d --pod $PODNAME --name $FILM_CONTAINER_NAME_POSTGRES $FILM_CONTAINER_NAME_POSTGRES运行电影应用容器:
同样去掉-p参数,应用连接PostgreSQL时直接使用localhost:5432(因共享网络栈),最终通过Pod的8081端口对外访问:podman run -t --name $FILM_CONTAINER_NAME --pod $PODNAME \ -e POSTGRESQL_DATABASE="$FILM_DB_NAME" \ -e POSTGRESQL_USER=postgres \ -e POSTGRESQL_PASSWORD=postgres \ -e POSTGRESQL_DATASOURCE="jdbc:postgresql://localhost:5432/$FILM_DB_NAME" \ -e POSTGRESQL_SERVICE_PORT="5432" \ $FILM_CONTAINER_NAME
3. 容器间连接被拒绝的解决
--share cgroup对网络连通性无帮助,问题核心在网络配置:
- 检查PostgreSQL容器是否正常启动,确认其监听了5432端口
- 确保应用的数据库连接地址为
localhost:5432,而非宿主机IP或其他地址
4. 替代--net=host的方案
按照上述流程,在创建Pod时指定端口映射,容器加入Pod时不再重复设置端口,既能满足对外暴露指定端口的需求,又能保证容器间正常通信,完全不需要使用--net=host或YAML配置。
内容的提问来源于stack exchange,提问作者Merostax

