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 将容器封装为系统服务,实现容器的自动化管理,进一步提升运维效率,为规模化部署保驾护航。

相关推荐
嵌入小生0072 小时前
数据结构 | 常用排序算法大全及二分查找
linux·数据结构·算法·vim·排序算法·嵌入式
Don't Look Down2 小时前
windows 脱机安装wsl 及 Docker Desktop 集成
windows·docker·容器
我也不曾来过12 小时前
进程控制(很详细)
linux·运维·服务器
Byte不洛2 小时前
POSIX 信号量:基于环形队列的生产者消费者模型
linux·多线程·并发编程·生产者消费者模型·posix信号量
_OP_CHEN2 小时前
【Linux系统编程】(二十五)从路径到挂载:Ext 系列文件系统的 “导航” 与 “整合” 核心揭秘
linux·操作系统·文件系统·c/c++·ext2文件系统·路径解析·挂载分区
2301_772204282 小时前
Linux内核驱动--设备驱动
linux·运维·服务器
qq_278787772 小时前
Windows 本地 EasySwoole 项目(Docker Desktop 挂载运行+热加载配置)
windows·docker·容器·easyswoole
郝学胜-神的一滴2 小时前
跨平台通信的艺术与哲学:Qt与Linux Socket的深度对话
linux·服务器·开发语言·网络·c++·qt·软件构建
鹏大师运维2 小时前
统信 UOS OpenSSL 漏洞如何修复?外网 / 内网两种方式一次讲清
linux·运维·openssl·国产操作系统·统信uos·麒麟桌面操作系统·补丁修复