RH134学习进程——十二.运行容器(3)

十二.运行容器

3.管理容器存储和网络资源

3.1管理容器资源

容器默认是临时、无状态的(容器删除后,内部数据和配置会丢失)。但像数据库、文件存储这类 "需要长期运行且数据不能丢" 的服务,必须添加持久存储 (确保数据永久保存)和DNS 解析(确保容器能在网络中正确寻址):

3.2持久存储

3.2.1容器持久存储

默认容器存储为临时存储,容器删除后数据丢失,需挂载主机目录实现持久化。

通过在容器上创建挂载的目录,映射到容器主机上创建持久存储。将容器内的存储目录与 主机或外部存储系统关联,即使容器重启 / 删除,数据也能保留(例如数据库的/var/lib/mysql目录挂载到主机的持久化路径)。

操作:(手动配置GID/UID)

前提:已经创建并运行该容器

适用于自定义镜像或非标准用户权限的场景

(1)主机上创建存储目录

mkdir -p $HOME/目录名字

要求权限至少为700(保证主机目录所有者需与容器内进程的 UID/GID 一致)

如:


(2)配置目录权限

podman unshare chown UID:GID 目录

需要与容器内进程UID/GID匹配

如:

先从容器中获取需要的UID/GID

podman exec -it 容器名 grep 容器内服务 /etc/passwd

再配置主机目录中的UID/GID

podman unshare chown 27:27 /home/student/databases/

验证:


(3)停止并删除容器

podman stop 容器

podman rm 容器

(4)挂载目录并启动容器(绝对路径)

podman run -v 主机目录:容器目录 镜像名

如:

podman run -d --name 容器名 \

-v 主机目录:容器目录 \

镜像地址

注:

已创建 的容器无法直接补充挂载 ,需要删除后 重新按需求创建,建议删除前备份数据。

3.2.2容器存储的SELinux上下文

当用podman run -v将主机目录挂载到容器作为持久存储 时,若主机目录的 SELinux 上下文不是container_file_t容器内进程 会因权限被拒而无法访问该目录,导致数据持久化失败(比如数据库容器无法写入数据)。

必须设置目录container_file_t SELinux Context,才能作为持久存储挂载到容器。

方法:

:Z选项自动配置上下文;

在podman run -v挂载目录时,添加:Z选项,Podman 会自动将主机目录的 SELinux 上下文设置为container_file_t,让容器进程有权限访问。

即:(自动挂载)

podman run -v 主机目录:容器目录 镜像名

如:

podman run -d --name 容器名 \

-v 主机目录:容器目录****:Z****\

registry.lab.example.com/rhel8/镜像名


3.2.3目录挂载(bind mount 绑定挂载)

对于仅需单个容器无需横向扩展 的简单场景(如个人测试、小型工具服务),可直接通过"目录挂载"实现持久存储:

操作:

podman run -v 主机路径:容器路径:权限选项 镜像名称

|--------------|--------------------------------------------|---------------|--------------------------------------------------------------|
| 参数部分 | 含义 | 可选/必选 | 格式要求与示例 |
| 主机路径 | 主机上要挂载的目录或文件(必须是绝对路径 ,不能用相对路径) | 必选 | 目录:/home/user/data、$HOME/nginx/html; 文件:/etc/hosts |
| 容器路径 | 容器内要关联的目录或文件(必须是绝对路径 ,容器内不存在会自动创建) | 必选 | 目录:/app/data、/usr/share/nginx/html; 文件:/etc/nginx/nginx.conf |
| 权限选项 | 限制容器对挂载目录的操作权限(默认rw可读写) | 可选 | rw(默认,可读写) ro(只读,容器无法修改主机文件) |

如:

podman run -v****$HOME/test**** :/app/data nginx

主机 $HOME/test 目录挂载到容器 /app/data,双向可读写

3.3容器中的DNS解析

默认情况:Podman 容器默认网络不支持 DNS 解析,容器间无法通过名称通信。

自RHEL9起,Podman v4.0 默认使用 Netavark 网络后端。

podman info --format {{.Host.NetworkBackend}}


操作:

(1)创建支持DNS的网络

podman network create \

--gateway 网关IP --subnet 子网 网络名

如:

创建具有10.89.1.0/24子网和10.89.1.1网关的frontend网络

podman network create \

--gateway 10.89.1.1 --subnet 10.89.1.0/24 frontend


(2)启动容器时加入该网络

podman run --network 网络名 镜像名


(3)容器内安装网络根据测试,并通过"ping 容器名"验证DNS解析

podman exec -it 容器名字 \

dnf install iputils iproute

如:

在容器db_client中,启动容器db_01中的数据库

podman exec -it db_client mysql -u dev1 -p -h db_01

解释:

(1) podman exec -it db_client:

在运行中的db_client容器内,执行交互式命令(-it 保证输入输出的交互性,让用户能输入密码、执行 SQL)。

(2) mysql -u dev1 -p -h db_01:

用于启动 MariaDB 客户端工具。

-u dev1:

指定连接数据库的用户为dev1(该用户是在db_01容器启动时,通过环境变量MYSQL_USER=dev1初始化的);

-p:

提示输入用户密码(对应MYSQL_PASSWORD=devpass,需手动输入);

-h db_01:

指定连接的数据库主机为db_01容器(依赖容器网络的 DNS 解析能力------ 同一网络内的容器可通过名称直接解析为 IP,无需手动配置)。

3.4多网络连接到单容器

多网络连接的核心是让单个容器接入多个独立网络,实现不同流量隔离(如业务流量、管理流量)、多服务网段通信等需求。

本质是通过为容器分配多个网络接口 (每个网络对应一个 IP),灵活适配复杂网络场景

操作:

(1)创建多个网络

podman network create 网络1 \

podman network create 网络2

如:


(2)运行中容器连接新网络

podman network connect 网络名 容器名


(3)验证

查看容器的多网络IP配置(Networks信息)

podman inspect 容器名

容器已经添加两个网络,backend和frontend

测试两个容器间通信:

podman exec -it 容器A ping -c4 容器B

如:

podman exec -it db_client ping -c4 db_01

注:

使用Ping命令测试前,需要安装iputils软件包:

podman exec -it 容器A dnf install iputils

3.5分配端口映射到容器

端口映射是 Podman中打通容器网络隔离 的核心功能,核心是将****"主机的端口**** " 与"容器内服务的端口 "建立绑定 ,实现外部客户端 (主机、局域网设备、公网)对容器内服务的访问。适用于仅需单个容器、无需复杂网络规划的简单场景,无需额外网络组件。

格式:

podman run -p 主机IP:主机端口:容器端口/协议类型 镜像名称

|--------------|------------------------------------------------|---------------|------------------------------------------------------------------|
| 参数部分 | 含义 | 可选/必选 | 格式要求与示例 |
| 主机IP | 指定主机的网卡 IP(限制仅该 IP 对外提供服务),默认 0.0.0.0(所有网卡可访问) | 可选 | 局域网 IP:192.168.1.100(仅局域网设备访问);公网 IP:203.0.113.5(公网可访问) |
| 主机端口 | 主机上对外开放的端口(需未被其他程序占用),范围 1-65535 | 必选 | 8080、9000(推荐用 1024 以上端口,避免与系统预留端口冲突) |
| 容器端口 | 容器内服务实际监听的端口(需与容器内应用配置一致) | 必选 | 80(Nginx 默认)、5000(Python Flask 默认)、3306(MySQL 默认)、6379(Redis 默认) |
| 协议类型 | 指定网络协议(TCP/UDP),默认 TCP(大部分服务用 TCP) | 可选 | /tcp(默认,可省略)、/udp(如 DNS、视频流服务) |

如:

podman run -p 8080:80 nginx

主机 8080 端口映射到容器 80 端口,所有网卡(本地、局域网、公网)可访问

操作:

(1)配置端口映射

podman run -p 主机IP:主机端口:容器端口


(2)查看端口映射关系

podman port 容器名字


(3)开放主机防火墙端口

firewall-cmd --add-port=主机端口/tcp --permanent

firewall-cmd --reload

注:

端口映射 是主机和容器的端口绑定,启动后无法动态添加/修改。需要删除旧容器 ,然后按需创建。

3.6容器的环境变量

3.6.1定义

容器的环境变量是在容器启动时注入到容器内部的 "键值对",容器内的应用可通过读取这些变量,动态调整自身行为(如配置数据库密码、服务端口、日志级别等)。

实现了"配置与代码分离",让容器更灵活、可复用(同一镜像可通过不同环境变量适配不同场景)。

3.6.2作用

容器化应用的配置需求通常是动态且场景化的(如开发 / 测试 / 生产环境的数据库地址不同),环境变量解决了以下痛点:

(1)配置动态化

无需修改应用代码或配置文件,仅通过启动参数 即可调整应用行为

(2)敏感信息隔离:

数据库密码、API 密钥等敏感信息不硬编码在代码中,降低泄露风险

(3)镜像复用性:

同一镜像 可通过不同环境变量 ,在开发、测试、生产等场景中复用

3.6.3关键操作

(1)排查因为缺少环境变量导致的失败原因:

podman container logs 容器名字

如:

podman container logs db_01

必须配置至少一组环境变量 来初始化数据库,否则容器无法正常启动


(2)传递环境变量,多个变量使用多个-e选项:

podman run -e 变量名=值

如:


(3)查看镜像所需要的环境变量说明:

skopeo inspect 镜像地址

3.7 总结------管理容器存储和网络一般流程

现有:

网络:frontend

子网:10.89.1.0/24

网关:10.89.1.1

容器:db_client、db_01

3.7.1创建网络并连接容器

(1)创建网络

podman network create \

--gateway 网关 --subnet 子网 \

网络名字

创建时指定子网和网关,避免与现有网络冲突,同时确保网络支持 DNS 解析。


(2)创建容器

podman run -d --name 容器名 \

--network 网络名

镜像地址

或者使用已经创建好的容器连接到网络:

podman network connect 网络名 容器名

注:

已运行容器关联网络后,需重启容器使配置生效(podman restart 容器名)。

(3)验证:

3.7.2持久化挂载
3.7.2.1(直接挂载)

适用于官方标准化镜像,如 MariaDB、Nginx 官方镜像;

需要挂载的容器名字:db_client

主机:/etc/yum.repos.d

容器路径:/etc/yum.repos.d

(1)删除已经创建的容器

podman rm 容器名


(2)重新创建持久挂载的容器

podman run -d --name db_client \

--network 网络名字 \

-v 主机文件:容器文件 \

镜像地址

如:

(3)验证:

3.7.2.2(手动挂载)

(1)主机创建存储目录(权限≥700 )


(2)获取容器内进程的 UID/GID(以 MySQL 为例)


(3)配置主机目录权限


(4)停止并删除旧容器


(5)重建容器并挂载


(6)验证挂载是否有效

3.7.3故障排除

(1)查看容器日志确定原因

podman container logs 容器名

如:

启动 MariaDB 容器时,必须配置至少一组环境变量 来完成数据库初始化,否则容器无法正常启动。

(2)删除旧容器

podman rm db_01


(3)使用环境变量重新创建容器

podman run -d --name 容器名字 \

--network frontend \

-e MYSQL_USER=dev1 \

-e MYSQL_PASSWORD=123456 \

通过-e选项设置上述找出的需要配置的环境变量

如:


3.7.4端口映射

主机端口:13306

容器端口:3306

主机的防火墙允许13306的端口流量

(1)删除旧容器


(2)创建带有端口映射的容器

podman run -d --name db_01 \

--network 网络名字 \

-e 环境变量配置 \

-v 主机文件:容器路径:Z \ #持久化挂载

-p 13306:3306 \

镜像地址


(3)验证

podman ps -a


(4)开放防火墙

firewall-cmd --add-port=主机端口/tcp --permanent

firewall-cmd --reload

如:

通过本篇的实操,解决容器 "数据丢失" 和 "网络隔离" 的核心问题,容器具备了稳定运行的基础条件。但在生产环境中,还需实现容器的 "服务化运维"------ 如主机开机自启、故障自动恢复、日志集中管理等。'下一篇将聚焦如何通过 systemd 将容器封装为系统服务,实现容器的自动化管理,进一步提升运维效率,为规模化部署保驾护航。

相关推荐
FoldWinCard8 小时前
D5 Linux 网络及端口命令
linux·运维·服务器
零涂毕业设计10 小时前
毕业设计模块开发-OLED显示屏(IIC协议0.96寸)STM32 ESP32 FPGA Linux驱动免费分享
linux·stm32·单片机·嵌入式·esp32·fpga·oled
tedcloud12310 小时前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
霸道流氓气质10 小时前
KMS 密钥管理服务(Key Management Service)原理与实践
linux·服务器·数据库
SakitamaX10 小时前
LVS(Linux Virtual Server)概念详解
linux·运维·lvs
小张同学a.10 小时前
Linux系统管理
linux·运维
阿龙的工作记录11 小时前
深入理解Linux设备驱动模型
linux·嵌入式硬件·工作记录
代码村新手11 小时前
Linux的基本指令
linux·运维·服务器
撩得Android一次心动13 小时前
Linux编程笔记3【个人用】
linux·笔记
OpenPomeloxCommunity13 小时前
3. Linux 同步机制之 spinlock 设计与实现(一):通用层
linux