初探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 可以查看到
参考:
floating-kwaaaay-with-podman-and-systemd
replacing-docker-with-podman-power-of-podman