卸载原有docker,安装podman
前置操作
停止 Docker、清理业务(可选)
如果还有运行容器,先处理;全新机器可跳过清理容器镜像步骤
# 停止所有容器
docker stop $(docker ps -aq)
# 删除容器(可选)
docker rm $(docker ps -aq)
# 删除本地镜像(可选,不需要镜像再执行)
docker rmi $(docker images -q)
# 停止并禁用docker全家服务
systemctl stop docker docker.socket containerd
systemctl disable docker docker.socket containerd
彻底卸载 Docker 相关包
查看已安装 docker 包
dnf list installed | grep -E "docker|containerd"
containerd.x86_64 1.7.29-1.tl4 @AppStream
卸载所有 docker 组件
dnf remove -y docker-ce docker-ce-cli docker-ce-rootless-extras \
containerd.io docker-buildx-plugin docker-compose-plugin
删除 Docker 残留目录(重要!避免冲突)
rm -rf /var/lib/docker
rm -rf /etc/docker
rm -rf /var/lib/containerd
rm -rf /run/docker.sock
rm -rf ~/.docker
验证
docker --version
-bash: /usr/bin/docker: No such file or directory
# 返回 command not found 代表卸载成功
安装 Podman
# 直接安装podman + 配套工具
dnf install -y podman podman-docker podman-compose containernetworking-plugins
- podman-docker:提供docker命令兼容层,原有脚本不用改,直接执行docker xxx等价于podman xxx
- containernetworking-plugins:提供容器网络(bridge 等)
验证安装
podman --version
podman version 5.8.4
podman info
host:
arch: amd64
buildahVersion: 1.43.2
cgroupControllers:
- cpuset
- cpu
- io
- memory
- net_cls
- hugetlb
- pids
- rdma
- misc
cgroupManager: systemd
cgroupVersion: v2
conmon:
package: conmon-2.1.13-2.tl4.x86_64
path: /usr/bin/conmon
version: 'conmon version 2.1.13, commit: '
cpuUtilization:
idlePercent: 91.39
systemPercent: 2.47
userPercent: 6.14
cpus: 4
databaseBackend: sqlite
distribution:
distribution: tencentos
version: "4.4"
eventLogger: journald
freeLocks: 2048
hostname: VM-26-213-tencentos
idMappings:
gidmap: null
uidmap: null
kernel: 6.6.119-49.27.tl4.x86_64
linkmode: dynamic
logDriver: journald
memFree: 5335195648
memTotal: 7921995776
networkBackend: netavark
networkBackendInfo:
backend: netavark
defaultNetwork: podman
dns:
package: aardvark-dns-1.16.0-1.tl4.x86_64
path: /usr/libexec/podman/aardvark-dns
version: aardvark-dns 1.16.0
package: netavark-1.16.0-1.tl4.x86_64
path: /usr/libexec/podman/netavark
version: netavark 1.16.0
ociRuntime:
name: crun
package: crun-1.17-2.tl4.x86_64
path: /usr/bin/crun
version: |-
crun version 1.17
commit: 000fa0d4eeed8938301f3bcf8206405315bc1017
rundir: /run/user/0/crun
spec: 1.0.0
+SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +YAJL
os: linux
pasta:
executable: ""
package: ""
version: ""
remoteSocket:
exists: true
path: /run/podman/podman.sock
rootlessNetworkCmd: pasta
security:
apparmorEnabled: false
capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
rootless: false
seccompEnabled: true
seccompProfilePath: /usr/share/containers/seccomp.json
selinuxEnabled: false
serviceIsRemote: false
slirp4netns:
executable: /usr/bin/slirp4netns
package: slirp4netns-1.2.0-6.tl4.x86_64
version: |-
slirp4netns version 1.2.0
commit: 656041d45cfca7a4176f6b7eed9e4fe6c11e8383
libslirp: 4.7.0
SLIRP_CONFIG_VERSION_MAX: 4
libseccomp: 2.5.4
swapFree: 0
swapTotal: 0
uptime: 0h 11m 28.00s
variant: ""
plugins:
authorization: null
log:
- k8s-file
- none
- passthrough
- journald
network:
- bridge
- macvlan
- ipvlan
volume:
- local
registries:
search:
- registry.fedoraproject.org
- registry.access.redhat.com
- docker.io
- quay.io
store:
configFile: /usr/share/containers/storage.conf
containerStore:
number: 0
paused: 0
running: 0
stopped: 0
graphDriverName: overlay
graphOptions:
overlay.mountopt: nodev,metacopy=on
graphRoot: /var/lib/containers/storage
graphRootAllocated: 107306004480
graphRootUsed: 10481164288
graphStatus:
Backing Filesystem: xfs
Native Overlay Diff: "false"
Supports d_type: "true"
Supports shifting: "true"
Supports volatile: "true"
Using metacopy: "true"
imageCopyTmpDir: /var/tmp
imageStore:
number: 0
runRoot: /run/containers/storage
transientStore: false
volumePath: /var/lib/containers/storage/volumes
version:
APIVersion: 5.8.4
Built: 0
BuiltTime: Thu Jan 1 08:00:00 1970
GitCommit: ""
GoVersion: go1.26.3-X:nodwarf5
Os: linux
OsArch: linux/amd64
Version: 5.8.4
关键配置
配置镜像搜索地址(兼容 docker 默认行为)
编辑 /etc/containers/registries.conf
unqualified-search-registries = ["docker.io"]
不加配置时,podman pull nginx 会报错,必须写完整地址 docker.io/library/nginx
启用 podman socket
如果程序依赖 docker.sock,例如 docker-compose、部分监控
systemctl enable --now podman.socket
配置podman的存储位置
创建目标目录
mkdir -p /data/podman/storage
chmod 700 /data/podman/storage
修改全局存储配置
/etc/containers/storage.conf
如果文件不存在直接新建;root 用户读取这个文件生效
[storage]
driver = "overlay"
# 持久化存储目录,放到/data
graphroot = "/data/podman/storage"
# 运行时目录保留在/run,不要改动
runroot = "/run/containers/storage"
[storage.options.overlay]
mountopt = "nodev,metacopy=on"
- 全新环境,没有任何镜像容器 直接启动podman就好了
- 已经有镜像 / 容器,需要迁移旧数据
# 停止所有容器 podman stop -a # 同步原有数据到新目录 rsync -av /var/lib/containers/storage/ /data/podman/storage/ # 修改storage.conf之后再启动 systemctl start podman.socket注意:修改 graphroot 后 podman 不会自动迁移数据,要么 rsync 拷贝,要么全新重建。
验证
# 查看存储根目录
podman info | grep graphRoot
# 测试拉取镜像
podman pull hello-world
# 观察文件生成在 /data/podman/storage/
ls /data/podman/storage/
配置podman监听在tcp端口 (非必须)
如果有需求需要让其他主机也能访问当前主机的podman,那就需要将podman监听到tcp端口上
重点:
Podman 没有 daemon 配置文件直接定义 TCP 监听,依靠 podman system service 启动 API 服务;
使用 --tls-client-ca 开启强制校验客户端证书(没有证书 / 证书不合法直接拒绝);
推荐端口 2376(和 docker TLS 端口保持一致)。
生成自签名证书
mkdir -p /etc/podman/tls
cd /etc/podman/tls
修改 SERVER_IP 为你服务器对外 IP,多 IP 就用逗号隔开
export SERVER_IP="192.168.1.100"
# 1. CA根证书
openssl genrsa -out ca-key.pem 4096
openssl req -new -x509 -days 3650 -key ca-key.pem -sha256 -subj "/CN=podman-ca" -out ca.pem
# 2. Server证书(必须带上IP SAN,否则客户端报错)
openssl genrsa -out server-key.pem 4096
openssl req -new -key server-key.pem -subj "/CN=${SERVER_IP}" -out server.csr
cat > extfile.cnf <<EOF
subjectAltName = IP:${SERVER_IP}
extendedKeyUsage = serverAuth
EOF
openssl x509 -req -days 3650 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
# 3. Client证书(远程连接使用)
openssl genrsa -out client-key.pem 4096
openssl req -new -key client-key.pem -subj "/CN=podman-client" -out client.csr
cat > client-ext.cnf <<EOF
extendedKeyUsage = clientAuth
EOF
openssl x509 -req -days 3650 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile client-ext.cnf
# 权限收紧(非常重要)
chmod 600 *.pem
chown root:root *.pem
文件清单:
- ca.pem:根证书(服务端校验客户端、客户端校验服务端)
- server-cert.pem / server-key.pem:Podman 服务端证书
- client-cert.pem / client-key.pem:客户端连接证书
ca-key.pem 不要分发到任何客户端,妥善保管!
创建 systemd 服务的文件
不要复用默认 podman.socket,默认只能监听 unix socket,新建独立服务
vim /etc/systemd/system/podman-tcp-api.service
[Unit]
Description=Podman TCP API with mTLS
After=network.target
[Service]
Type=simple
# --time=0 不自动退出;tcp://0.0.0.0:2376 监听所有网卡2376
# --tls-client-ca 开启强制客户端证书校验(核心!)
ExecStart=/usr/bin/podman system service \
--time=0 \
--tls-cert=/etc/podman/tls/server-cert.pem \
--tls-key=/etc/podman/tls/server-key.pem \
--tls-client-ca=/etc/podman/tls/ca.pem \
tcp://0.0.0.0:2376
Restart=always
RestartSec=3
# 安全加固
NoNewPrivileges=true
ProtectHome=read-only
PrivateTmp=true
# 允许访问/data目录
ReadWritePaths=/data /etc/podman/tls
[Install]
WantedBy=multi-user.target
启动
# 重载systemd
systemctl daemon-reload
# 开机自启并启动
systemctl enable --now podman-tcp-api.service
# 查看状态
systemctl status podman-tcp-api.service
客户端连接测试
把这 3 个文件拷贝到客户端:
- ca.pem
- client-cert.pem
- client-key.pem
方法1:curl 直接调用 API 测试
curl -v \
--cacert ./ca.pem \
--cert ./client-cert.pem \
--key ./client-key.pem \
https://服务器IP:2376/v1.44/info
方法2:docker/podman 客户端远程连接
# docker客户端环境变量
export DOCKER_HOST=tcp://服务器IP:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=/证书目录
docker info
docker ps
方法3:直接指定参数访问
docker --tlsverify \
--tlscacert=./ca.pem \
--tlscert=./client-cert.pem \
--tlskey=./client-key.pem \
-H tcp://服务器IP:2376 \
info
本文来自博客园,作者:厚礼蝎,转载请注明原文链接:https://www.cnblogs.com/guangdelw/p/22007353

浙公网安备 33010602011771号