30 Jan 2021
# 保持selinux为enforcing状态 # 创建用户 useradd -d /data/container container # USER NAMESPACE最大数优化 echo "user.max_user_namespaces=28633" > /etc/sysctl.d/userns.conf sysctl -p /etc/sysctl.d/userns.conf # check uid and gid map setting of user namespace cat /etc/subuid cat /etc/subgid # 正常应该是有username uid mapuidstart maprange
# install podman
dnf -y install podman buildah crun fuse3
安装fuse3后,记得启用此内核模块
# ROOTLESS CONFIGURE mkdir -p /data/container/.config/containers cp /usr/share/containers/containers.conf /data/container/.config/containers/containers.conf chown -R container.container /data/container/.config/containers # 修改ociruntime为crun来支持cgroup v2:"runtime = "crun" # 确保cgroup用的是systemd
# 有些镜像,类似于redis,会使用非root用户运行,那么根据uid map的规则,我们需要修改宿主机映射文件的属主属组
podman unshare chown -R containeruid.containergid /path/to/dir/on/host/needed/mounted
podman run -it -d -p 80:80 -v /data/www/html:/var/www/html:Z nginx:latest
:Z,含义是让selinux挂载本地目录的时候,重新lable一下,使其符合container环境的读写权限 user namespaces & selinux & rootless container What happens behind the scenes of a rootless Podman container?echo "+pids +memory" >/sys/fs/cgroup/user.slice/cgroup.subtree_control echo "+pids +memory" >/sys/fs/cgroup/user.slice/user-1001.slice/cgroup.subtree_control
podman unshare cat /proc/self/uid_map
rootless podman运行的容器,不会写iptables规则,这就是如此设计的,它会启动一个进程专门来监听容器map的port
# 运行rootless podman nginx podman run -it -d --rm --name nginx -p 80:80 nginx:latest # 查看map的端口 podman port --all 02ede4d6178f 80/tcp -> 0.0.0.0:80 # 检查监听域名进程pid netstat -lnpt ...... tcp6 0 0 :::80 :::* LISTEN 2520/containers-roo # 查看pid ps aux |grep 2520 |grep -v grep contain+ 2520 0.0 0.4 1975428 62760 ? Sl 11:32 0:00 containers-rootlessport
podman虽然可以通过podman generate systemd来创建unit文件,但是这样创建出来的unit文件并不通用,它必须要求容器实现已经创建。
而很多人的要求可能是想要一个更加灵活和通用的systemd unit file。所以redhat的大神提供了一个下面的模板
[Unit] Description=Podman in Systemd [Service] Restart=on-failure ExecStartPre=/usr/bin/rm -f /%t/%n-pid /%t/%n-cid ExecStart=/usr/bin/podman run --conmon-pidfile /%t/%n-pid --cidfile /%t/%n-cid -d busybox:latest top ExecStop=/usr/bin/sh -c "/usr/bin/podman rm -f `cat /%t/%n-cid`" KillMode=none Type=forking PIDFile=/%t/%n-pid [Install] WantedBy=multi-user.target
其中重点在于四个点
%t,容器runtime的根目录/run/user/$UserID%n,service的名称(就是systemd unit file的文件名称)--conmon-pidfile,conmon进程的pid保存文件--cidfile,container的id保存文件
通过以上四个点,我们基本上就可以确定了这个容器的systemd unit file的信息,来保证了用固定一个模板,来在不同服务器上管理容器的灵活性
> redhat - byValentin Rothberg: Running containers with Podman and shareable systemd servicessystemctl --user daemon-reload systemctl --user start foo systemctl --user restart foo # 开机启动 systemctl --user enable foo Created symlink /home/container/.config/systemd/user/multi-user.target.wants/foo.service → /home/container/.config/systemd/user/foo.service.