卸载原有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
posted @ 2026-07-28 16:43  厚礼蝎  阅读(10)  评论(0)    收藏  举报