最近听说了两个技术 —— 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
可以查看到
参考: