Podman容器基础介绍
虚拟化技术简介
- 在学习容器之前, 我们需要知道什么是虚拟化技术, 虚拟化是一种资源管理技术, 它能够接管OS (操作系统) 对硬件资源的访问申请, 并将其重定向到虚拟资源池然后再次进行资源分配, 我们可以使用虚拟化技术在一台物理主机上同时运行多台虚拟主机, 而且各台虚拟主机之间完全隔离不会互相影响, 从而实现更安全的资源访问, 更高效的资源利用, 更方便的迁移环境
虚拟机 (Virtual Machine)
- 虚拟机是最常见的一种虚拟化技术, 其采用硬件虚拟化的方式, 能模拟出整套硬件与OS, 每台虚拟机都是一个完整的设备,但由于每台虚拟机都需要运行一个完整的OS导致被浪费的资源非常多,只适合在需要模拟不同的OS或不同的硬件的情况下使用
- 常见的虚拟机管理器有VMware Workstation,VirtualBox,Hyper-V等
容器(Container)
- 容器是将操作系统虚拟化, 它会复制物理机的 OS Kernel (操作系统内核) 并进行复用, 每一个容器都是在这个复制出来的虚拟内核的基础上进行操作, 而我们在创建一个容器的时候只会将虚拟内核的增量部分打包成容器, 然后我们再在物理机的 OS 中划分出多个不同的独立空间去存放这些容器, 每一个容器内的进程在运行时都只能调用当前所处的容器空间内的文件, 但所有的容器内都拥有物理机的 OS 需要的全部依赖关系, 因此不会出现缺少某个文件导致无法执行的情况, 事实上我们可以把容器看做一种特殊的进程, 他不需要额外的模拟硬件和 OS, 虽然安全性比不上虚拟机,但浪费的资源几乎可以忽略不计, 是一种更轻量更高效的虚拟化技术
- 常见的容器管理器有 Docker,Containerd,Podman等
Podman简介
- Docker是容器时代的开创者, 但由于Docker需要依赖于Docker Daemon守护进程导致稳定性与安全性存在一定问题一直被人诟病,现在人们已经逐渐放弃Docker并使用它更加底层的Containerd或是另一种解决方案Podman
- Podman是由Redhat开发的一种开源的容器引擎, 其与Docker容器的最主要的区别在于
- Podman不依赖于守护进程, 不用担心Docker Daemon进程死亡导致所有容器全部死亡的问题
- Podman不需要root权限就能使用,也支持更多的安全功能,比Docker容器更安全
- Podman 基于 OCI (Open Container Initiative, 开放容器倡议) 标准, 能直接集成到 Kubernetes 等主流容器编排工具中, 而Docker必须使用桥接服务才能接入到Kubernetes中
- 除此之外Podman与Docker没有太大的区别,它们指令都是类似的,如果你会使用Docker容器,那么5分钟内就能学会如何使用Podman
配置Podman
- 安装podman
yum -y install podman
通过yum安装podman或者通过yum -y module install container-tools
安装整个容器工具模块podman version
查看podman的版本
- 配置访问加速器和镜像仓库
vim /etc/containers/registries.conf
[registries.search]
registries.search=['docker.io','registry.access.redhat.com']
将docker.io加到最前面unqualified-search-registries = ["docker.io","docker.mirrors.ustc.edu.cn"]
添加其他服务商提供的加速服务
- 登录到容器
podman login 容器仓库地址
- 使用
podman [command] --help
获取帮助文档,查看如何使用podman,本文只介绍podman的基础内容,每个选项的具体参数请自行配合帮助文档查看
镜像管理
podman search 镜像名称
检索服务器上的镜像podman pull 镜像地址
拉取镜像到本地podman images
列出本地的所有镜像podman images rm 容器id
删除本地镜像podman build
构建镜像podman save
保存镜像podman load
加载镜像podmanfile
制作镜像
容器管理
podman run [option] 镜像id
创建并启动容器- -i: 以交互模式运行容器,通常与-t同时使用
- -t: 为容器分配一个伪输入终端,通常与-i同时使用
- -d: 后台运行容器,并返回容器ID
- --name="nginx-lb": 为容器指定一个名称
- -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
- -P: 随机端口映射,容器内部端口随机映射到主机的端口
- --volume , -v: 绑定一个卷
- 绑定挂载卷: -v 宿主机目录:容器目录 在podman里宿主机目录须事先存在,在启动容器时自动生成
- 在容器目录参数后再加上
:z
参数可以同步宿主机和容器的安全上下文,避免selinux导致的问题,如果使用:Z
参数的话则只有对应挂载的容器能访问宿主机的对应目录,其他容器不能访问
- 在容器目录参数后再加上
- 容器管理卷: -v 容器目录`只需指定容器的目录,宿主机的挂载点由docker引擎自行生成
- --volumes-from: 在新容器当中挂载已存在的容器的卷`
- --volumes-from 要挂载的容器名
- 绑定挂载卷: -v 宿主机目录:容器目录 在podman里宿主机目录须事先存在,在启动容器时自动生成
- -h "mars": 指定容器的hostname
- --restart always: 让容器保持运行状态
- -m :设置容器使用内存最大值
- -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项
- -e username="ritchie": 设置环境变量
- --dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致
- --dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致
- --env-file=[]: 从指定文件读入环境变量
- --cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行
- --net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型
- --link=[]: 添加链接到另一个容器
- --expose=[]: 开放一个端口或一组端口
podman start 容器id或名字
启动容器podman stop 容器id或名字
终止容器podman restart 容器id或名字
重启容器podman ps
查看容器进程, 默认只显示运行中的进程,-a
显示所有进程podman attach 容器id或名字
进入容器,退出后会自动停止容器podman exec [option] 容器id或名字 要执行的命令
在容器内执行命令,通过此方法进入容器在退出时不会停止容器podman logs 容器id或名字
查看容器日志podman rm 容器id或名字
删除容器podman export 容器名称 > 导出的路径
导出容器podman import 容器地址 导入后容器的名字
导入容器快照podman diff
检查容器或映像文件系统上的更改
使用systemd管理容器
podman generate {systemd|kube} [options] 容器id或名称
使用 generate 生成systemd或者 Kubernetes的服务文件--container-prefix string
容器的systemd单元名称前缀(默认为“container”)--name, -n
使用容器名称,而不是 ID--files, -f
生成.service 文件,默认生成到当前目录下,需要手动移动到/etc/systemd目录中--format string
以指定格式(json)打印创建的单位--new
创建新容器,而不是启动现有容器--no-header
跳过标题生成--pod-prefix string
pod 的 Systemd 单元名称前缀(默认为“pod”)--restart-policy string
Systemd 重新启动策略(默认为“故障时”)--separator string
Systemd 单元名称:名称/id 和前缀之间的分隔符(默认“-”)--time uint, -t
停止超时覆盖(默认值为 10)
- 如果我们直接使用
systemctl enable
的话,会以root用户的身份启动,因此我们需要加上--user
参数代表以用户身份启动容器- 以下用户级别的systemd目录
~/.config/systemd/user/
优先级最高/etc/systemd/user/
~/.local/share/systemd/user/
/usr/lib/systemd/user/ 优先级最低
- 在配置好新的单元文件后,我们还需要使用
systemctl -user daemon-reload
重新加载单元文件
- 以下用户级别的systemd目录
- 还存在一个问题是系统服务会在系统启动时开启,系统关闭时停止,但非系统服务只会在使用服务时启用,会话结束后会自动终止进程,因此我们需要使用
loginctl enable-linger 服务的用户名
为该服务启用逗留功能
例题讲解
一. 容器开机自启
- 利用注册表服务器上的nginx镜像,创建名为cyserver的容器
- 将其配置为systemd服务的形式运行,且仅面向现有用户contsvc
- 该服务应命名为container-cyserver.service,此服务在系统重启后将自动启动
- 使用 ssh 连接到 servera, 安装 podman
ssh root@servera
yum -y module install container-tools
- 使用 ssh 连接到 contsvc, 并登陆到容器仓库
ssh contsvc@servera
podman login registry.lab.example.com --tls-verify=false
--tls-verify=false代表跳过验证
- 拉取镜像到本地
podman pull registry.lab.example.com/library/Nginx --tls=verify=false
- 查看镜像, 记下镜像 id
podman images
- 运行容器
podman run -itd --name cyserver 镜像id
podman ps
查看容器进程状态
- 设置容器为开机自启
mkdir -p /home/contsvc/.config/systemd/user
创建文件podman generate systemd --name cyserver --files
生成 systemd 服务单元文件vim /home/contsvc/.config/systemd/user/container-cyserver.service
WantedBy=default.target
systemctl --user enable container-cyserver.service
普通用户使用 systemctl 需要加上--userloginctl enable-linger contsvc
开启逗留功能
二. 容器持久化存储
- 在容器主机的/home/contsvc 下创建一个名为 container_journal 的目录
- 服务器应将主机目录/home/contsvc/container_journal 挂载到容器上的/var/log/journal 中
- 启动容器服务时, 应自动永久挂载存储
- 在容器上执行命令: echo RHCSA>/var/log/journal/rhcsa.log , 确保容器和容器主机对应目录内的文件显示的内容一致
podman stop 容器id && podman rm 容器id
停止之前创建的容器并删除他ssh root@servera
切回root用户vim /etc/systemd/journal.conf
修改journal的配置文件Storage=persistent
启用持久化存储
systemctl restart systemd-journald
重启journald服务ssh contsvc@servera
回到contsvc用户podman run -itd --name cyserver -v /home/contsvc/container_journal/:/var: log/journal/:Z 镜像id
重新运行容器,挂载目录- -v 创建挂载点将宿主机的目录挂载到容器的目录
- -Z 同步安全上下文
- -v 创建挂载点将宿主机的目录挂载到容器的目录
podman exec -it cyserver /bin/bash
在cyserver容器中以交互式终端执行/bin/bash解释器以进入容器echo RHCSA > /var/log/journal/rhcsa.log
创建日志文件exit
退出容器