初探Podman容器管理

Published: 2019-08-25

Tags: Podman


最近听说了两个技术 —— Podman 与 Buildah

本篇博文记录一下学习了解 Podman 的过程,以作备忘

Docker 是很流行的容器技术,它在运行的时候有一个守护进程,需要把服务启动起来,才能通过CLI管理容器,镜像,守护进程负责处理很多的事情,所以就可能有单点故障登风险,当Docker服务程序挂了,依赖它启动的容器就都不能使用了,另外 这篇文章 还列举可能存在的安全隐患。

Podman 是做什么的呢,它无需守护进程,可以用来管理容器,镜像,以下是它的一些特点

  • 无需安装 Docker,安装 Podman 后就可以进行管理
  • Podman 的命令与 Docker 几乎相同
  • Docker 下的镜像 Podman 也可以使用
  • Podman 存储它的镜像和容器与 Docker 的位置不同(即通过 Podman 载入镜像后,用 Docker 查看镜像是看不到的)

Podman 一个很不错的特性是拥有 rootless 模式,非 root 用户也可以使用 Podman 来启动容器,用户和root用户的镜像/容器是互不影响的。

安装

这里是安装文档:Postman 安装

各个发行版都可以很方便的安装方式,比如 Fedora

$ sudo yum -y install podman

# 安装测试版本
$ sudo yum distro-sync --enablerepo=updates-testing podman

安装好后,应该有个 “Hello World” 来庆祝一下,别急,在国内需要了解一点先行知识

跟Docker一样,不设置源 pull 镜像会很慢,我了解得知有两个配置文件

  • /etc/containers/registries.conf
  • ~/.config/containers/registries.conf

上边对应的是全局的配置文件,下边的是用户自己的配置文件,如果用户有自己的配置文件则会忽略全局配置文件

内容大概是这样的:

# This is a system-wide configuration file used to
# keep track of registries for various container backends.
# It adheres to TOML format and does not support recursive
# lists of registries.

[registries.search]
registries = ['docker.io', 'registry.fedoraproject.org', 'registry.access.redhat.com']

# If you need to access insecure registries, add the registry's fully-qualified name.
# An insecure registry is one that does not have a valid SSL certificate or only does HTTP.
[registries.insecure]
registries = ['localhost:5000']

我尝试使用国内Docker源来替换Podman的源,会报错,不清楚什么原因

然后我在下载镜像的时候指定源地址加速常用镜像的下载

$ podman pull daocloud.io/library/nginx

启动Nginx容器

$ podman run --name nginx -p 8080:80 -d nginx

打开浏览器访问 http://[服务器ip]:8080 就能看到 Nginx 的欢迎界面了

容器组——Pod

Podman 正如它的名字,其中的 pod 概念与 kubernetes 的 pod 相仿

可以创建一个容器组,然后在容器组里启动容器,可以统一的管理容器,下面使用一下这个功能

创建 Pod

因为 Podman 的容器组需要一个,后台运行的容器,用来保持容器组状态等。

这个小容器名为 “k8s.gcr.io/pause:3.1” 遗憾的是daocloud源里没有,我是到国外的服务器pull下来导出,下载回来再倒入进来的

# 如果运行了前边的 Nginx 容器,先删除一下
$ podman rm -f nginx

# 创建 Pod
$ podman pod create --name super_pod -p 8080:80 -p 6379:6379

此处创建了一个名为 super_pod 的容器组,初始化端口号绑定,这个绑定之后不能进行动态的添加

在 pod 里创建 Nginx

$ podman run --name nginx --pod super_pod -d nginx

在 pod 里创建 Redis

$ podman run -d --name redis --pod super_pod -v /etc/localtime:/etc/localtime:ro redis:latest redis-server --requirepass redis --notify-keyspace-events Ex

因为容器组已经绑定了端口号,那么在容器组里面启动的容器则不需要绑定端口

查看 pod 列表

$ podman pod list   

查看运行种的 pod 容器信息

$ podman pod top super_pod

值得一提的是,Pod里面的容器,查看它们的 hostname,都为pod的名称

# 创建临时容器
$ podman run --rm -it --pod super_pod daocloud.io/library/alpine /bin/sh

# 查看容器的主机名
$ cat /etc/hostname

# Out: super_pod

也就是说,容器组里面的容器可以指定容器名来互相访问

开启启动

相较于 Docker 守护进程指定 --restart 来启动容器,Podman 没有守护进程,该如何在系统启动的时候把容器启动呢?—— systemd

此处以启动一个 Redis 服务为例

创建文件及映射目录

$ sudo mkdir -p /opt/containers/var/lib/redis/data$ sudo mkdir -p /opt/containers/var/lib/redis/data
$ sudo chown 1001:1001 /opt/containers/var/lib/redis/data
$ sudo setfacl -m u:1001:-wx /opt/containers/var/lib/redis/data

创建配置文件 /etc/systemd/system/redis-service.service

[Unit]
Description=Redis Podman Container
After=network.target

[Service]
Type=simple
TimeoutStartSec=5m
ExecStartPre=-/usr/bin/podman rm "redis-service"

ExecStart=/usr/bin/podman run --name redis-service -v /opt/containers/var/lib/redis/data:/var/lib/redis/data:Z -e REDIS_PASSWORD=redis --net host daocloud.io/library/redis:latest

ExecReload=-/usr/bin/podman stop "redis-service"
ExecReload=-/usr/bin/podman rm "redis-service"
ExecStop=-/usr/bin/podman stop "redis-service"
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target

防火墙开放访问权限

$ sudo firewall-cmd --zone=public --add-service=redis

启动 Redis

$ sudo systemctl start redis-service

设置开机启动

$ sudo systemctl enable redis-service

另外:

  • 通过 --net host 启动的容器,其它容器访问这个 Redis,可以使用 127.0.0.1 进行连接
  • systemctl 启动的容器,切换到 root 用户,用 podman ps 可以查看到

参考: