Podman容器管理工具使用入门

668 阅读4分钟

Podman容器管理工具使用入门

API文档

Podman Restful Api

具备以界面向导方式进行软件容器(Podman)

安装(Debian发行版为例)

. /etc/os-release
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list

sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 4D64390375060AA4
#curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key | sudo apt-key add -

sudo apt-get update
#sudo apt-get -y upgrade
sudo apt-get -y install podman

运行容器 podman run

  • 参数
-d 守护(后台)进程运行
-t 分配一个伪终端
-i 向终端输入
--device=host-device[:container-device][:permissions]
--privileged 开放容器所有权限
--cap-drop 关闭容器指定能力

#静态资源配额
#内存
--memory-swap 500m 可用交换空间 不配置则与内存大小一样
--memory 500m 可用内存=可用内存+交换空间
--shm-size 共享内存
#cpu
--cpus=5 指定容器可用cpu个数(5)
--cpuset-cpus=1-3,6-9 容器可绑定cpu(1236789)

--mount type=tmpfs,tmpfs-size=512M,destination=/path/in/container

--oom-kill-disable 内存溢出停止容器

--user 指定启动用户 没有会自动创建
--passwd 指定用户密码

--restart on-failure:3 失败尝试重启3次 always 容器退出重启 unless-stopped 
--rm 容器退出后删除容器

--workdir 工作目录

-cpuset-mems=nodes
--cpu-period=limit
--cpu-quota=limit
--cpu-rt-period=microseconds
--cpu-rt-runtime=microseconds
--cpu-shares, -c=shares
  • 举例
podman run --cap-add NET_ADMIN --cap-add NET_RAW

其他 --cao-add 见附录1

停止容器

podman stop container_id or container_name

导入资源到容器

podman cp local_path container_name:abs_container_path

从容器导出资源

podman cp container_name:abs_container_path  local_path

删除容器文件

podman exec -it  container_name /bin/bash -c rm "-rf container_dir"

远程操作podman

远程快速部署功能,能将封装好的容器按照配置好的IP地址和路径,远程部署到目标机,可以通过ssh 启动podman的远程api服务 将远程链接添加本地,然后使用podman-remote本地操作,执行命令部署

  • ssh连接远程机器启动服务
1. podman system service tcp:0.0.0.0:8888 --time=0 & 
2. podman system service --time=0 unix:///run/podman/podman.sock

--time=0:禁用超时,不访问也一直运行,默认5,单位:秒

  • 将连接地址加入本地
podman system connection add [connect_name](默认debug) tcp://remote-ip:8888

支持如下连接

  • [user@]hostname[:port]
  • ssh://[user@]hostname[:port]
  • unix://path 如 unix:///run/podman/podman.sock
  • tcp://hostname:port

测试:http://127.0.0.1:8888/info

  • 查看本地连接列表
podman system connection list
Name        Identity    URI
debug*                  tcp://localhost:8888
  • 删除本地连接
podman system connection remove <connect_name>
  • 修改本地连接
podman system connection rename <old_name> <new_name>
  • 将连接设置为默认
podman system connection default <connect_name>

操作默认连接更简便,将podman执行换为podman-remote接口

如:podman-remote images

REPOSITORY                                 TAG         IMAGE ID      CREATED      SIZE
localhost/wanglf589/code-server-withnginx  2.1         67bcd0b4c13d  10 days ago  7.13 GB
  • 操作远程podman
podman-remote -c <connect_name> <command> 
e.g.
podman-remote -c debug images
REPOSITORY                                 TAG         IMAGE ID      CREATED      SIZE
localhost/wanglf589/code-server-withnginx  2.1         67bcd0b4c13d  10 days ago  7.13 GB

容器封装与Docker类似(略)

自定义配置

  • podman配置分为root和普通用户

  • 配置文件

/usr/containers/storage.conf
/etc/containers/storage.conf
$HOME/.config/containers/storage.conf
 $XDG_CONFIG_HOME/containers/storage.conf (If XDG_CONFIG_HOME is set)
  • 说明
#该文件是所有工具的配置文件
#使用容器/存储库。
#更多信息请参见man 5 containers-storage.conf
#“容器存储”表包含所有服务器选项。
[storage]

# 默认存储驱动,必须设置,才能正常使用。
driver = "overlay"

# 临时存放地点
runroot = "/run/containers/storage"

# 主容器存储的读写位置
graphroot = "/var/lib/containers/storage"

# 无root用户的存储路径
#
# rootless_storage_path = "$HOME/.local/share/containers/storage"

[storage.options]
# 将存储选项传递给底层存储驱动程序

# AdditionalImageStores用于传递路径到额外的只读image存储
# 必须是逗号分隔的列表。
additionalimagestores = [
]


#
# remap-uids = 0:1668442479:65536
# remap-gids = 0:1668442479:65536


#
# remap-user = "containers"
# remap-group = "containers"

# root-auto-userns-user = "storage"
#
# Auto-userns-min-size is the minimum size for a user namespace created automatically.
# auto-userns-min-size=1024
#
# Auto-userns-min-size是自动创建的用户命名空间的最小大小。
# auto-userns-max-size=65536

[storage.options.overlay]

#ignore_chown_errors = "false"

# Inodes用于设置容器映像的最大Inodes。
# inodes = ""

# 用于挂载文件系统而不是直接挂载它的辅助程序的路径。
#mount_program = "/usr/bin/fuse-overlayfs"

# Mountopt指定以逗号分隔的额外挂载选项列表
mountopt = "nodev,metacopy=on"

# 设置为跳过存储主目录上的PRIVATE绑定挂载。
# skip_mount_home = "false"

# Size用于设置容器映像的最大大小。
size = "10G"
#
# ForceMask指定用于新文件和目录的权限掩码。.

#  "": No value specified.
#  "private": it is equivalent to 0700.

#  "shared": it is equivalent to 0755.

# force_mask = "shared"

[storage.options.thinpool]
# Storage Options for thinpool

# autoextend_percent 自动扩容 百分比
# autoextend_percent = "20"

# autoextend_threshold 自动扩容上限
# autoextend_threshold = "80"

# basesize 指定创建基本设备时使用的大小,这限制了镜像和容器的大小
# basesize = "10G"

# blocksize 块大小
# blocksize="64k"
# 参考https://icloudnative.io/
# directlvm_device 块设备路径
# directlvm_device = ""

# directlvm_device_force 强制擦除设备文件
# directlvm_device_force = "True"

# fs 指定设备文件系统
# fs="xfs"

# log_level sets the log level of devicemapper.
# 0: LogLevelSuppress 0 (Default)
# 2: LogLevelFatal
# 3: LogLevelErr
# 4: LogLevelWarn
# 5: LogLevelNotice
# 6: LogLevelInfo
# 7: LogLevelDebug
# log_level = "7"

# min_free_space 创建设备最小可用空间
# min_free_space = "10%"

# mkfsarg指定在创建基本设备时使用的额外MKFS参数。
# mkfsarg = ""

# metadata_size 创建
# metadata_size = "128k"

# Size is used to set a maximum size of the container image.
# size = ""

# use_deferred_removal 设备繁忙,返回尽快删除
# use_deferred_removal = "True"

# use_deferred_deletion 每30秒尝试删除未使用设备
# use_deferred_deletion = "True"

# xfs_nospace_max_retries 当返回没有空间,重试次数
# xfs_nospace_max_retries = "0"

磁盘配额

基于overlay2驱动配置

overlay2支持xfs文件系统配额

ubuntu20为例建立xfs分区(自带分区工具不支持xfs)

apt-get install xfsprogs
fdisk /dev/sdb (新建分区略)
mkfs.xfs /dev/sdb
mkdir /mydata
mount /dev/sdb /mydata
挂载配额类型
  • 根据用户(uquota/usrquota/quota)
  • 根据组(gquota/grpquota) ;
  • 根据目录(pquota/prjquota)(不能与grpquota同时设定)
# 根据目录
sudo mount -o uquota,prjquota /dev/sdb /mydata/
# 查看配置
mount | grep mydata
$$/dev/sdb on /mydata type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,usrquota,prjquota)
修改podman配置
  • 个人配置文件:$HOME/.config/containers/storage.conf(toml格式配置文件参考:https://zhuanlan.zhihu.com/p/50412485)

    • /dev/sdb /xfs xfs rw,defaults,usrquota,prjquota 0 0

    [storage] 
    driver = "overlay2"
    
    rootless_storage_path = "$HOME/.local/share/containers/storage" # 如果目录存在则备份或#删除
    [storage.options.overlay]
    size = "10G"
    
  • 修改挂载点权限

    • chown -R ubuntu20 xfs
    • chgrp -R ubuntu20 xfs
  • 测试

podman run -it --rm --name disklimit ubuntu-base-richide:20.04 /bin/bash

dd if=/dev/zero of=tmp.5G bs=512M count=10
dd: error writing 'tmp.5G': No space left on device
10+0 records in
9+0 records out
5368119296 bytes (5.4 GB, 5.0 GiB) copied, 2.62911 s, 2.0 GB/s
  • 查看磁盘情况
df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay         5.0G   12K  5.0G   1% /
podman不支持devicemapper(略)

内存配额

podman run -it --rm --cpus=2 --name memorylimit -m 1024m  --memory-swap 1024m -v $PWD:/data ubuntu-base-richide:20.04 /bin/bash
cd /data
sudo ./memory-limit
...
分配了1004 MB 
Killed

网络配额

网卡限速
  • sudo apt install wondershaper
  • 启动:sudo systemctl start wondershaper
  • 使用:
    • wondershper -a eno1 -d 128 -u 128 : eno1网卡上行128kbps 下行128kbps
    • wondershper -a eno1 -c: 取消eno1网卡限速
端口限速
#!/bin/sh
#  "./limitRate.sh help (帮助)"
#  "./limitRate.sh stop (停止限速)"
#  "./limitRate.sh 参数1 参数2 参数3 参数4(参数代表:网卡总速 下载限速 允许峰值 限速端口),流量单位:kbit"
#  "./limitRate.sh 无参数则默认 100 90 90 9080"
# 
# eg: ./limitRate.sh eno1 100 90 90 9080(启动限速命令,网卡总速100kbit 下载限速90kbit允许峰值90kbit限速端口9080)



if [ "$1" = "stop" ];then
   tc qdisc del dev $2 root;#清除限速
   echo "stop success..."
elif [ "$1" = "help" ];then
   echo "./limitRate.sh stop (停止限速)"
   echo "./limitRate.sh 参数1 参数2 参数3 参数4 参数5(参数代表:网卡 网卡总速 下载限速 允许峰值 限速断口),流量单位:kbit"
   echo "./limitRate.sh 无参数则默认 ens1 100 90 90 9080"
else
   netdev=$1
   totalRate=$2
   limitRate=$3
   limitMaxRate=$4
   limitPort=$5
   if [ ! $netdev ];then
      netdev=eth0
      echo "netdev默认eth0..."
   fi
   if [ ! $totalRate ];then
      totalRate=100
      echo "totalRate默认100kbit..."
   fi
   if [ ! $limitRate ];then
      limitRate=85
      echo "limitRate默认90kbit..."
   fi
   if [ ! $limitMaxRate ];then
      limitMaxRate=85
      echo "limitMaxRate默认90kbit..."
   fi
   if [ ! $limitPort ];then
      limitPort=9080
      echo "limitPort默认9080..."
   fi
   #网卡eth0对这个网卡进行带宽的限制#建立eth0队列 命令解释:将一个htb队列绑定在eth0上,编号为1:0,设置默认号是 20
   tc qdisc add dev $netdev root handle 1: htb default 20;
   #建立跟分类 命令解释:在队列1:0上创建根分类1:1 限速,类别htb,限速100kbit
   tc class add dev $netdev parent 1:0 classid 1:1 htb  rate ${totalRate}"kbit";
   #创建分类 以根分类1:1为父类创建分类1:20 ,类别为htb 限速 90kbit 最大90kbit
   tc class add dev $netdev parent 1:1 classid 1:20 htb rate ${limitRate}"kbit" ceil ${limitMaxRate}"kbit" ;
   #添加公平队列 命令解释:sfq是公平队列 ,防止一个会话占用全部带宽
   tc qdisc add dev $netdev parent 1:20 handle 20: sfq perturb 10;
   #.创建分类过滤器 命令解释:以分类1:20为父类创建编号为1:20的过滤器 ,加载u32模块,指定端口
   tc filter add dev $netdev protocol ip parent 1:0 prio 1 u32 match ip dport ${limitPort} 0xffff flowid 1:20
   #输出
   echo "limitRate start..."
fi

镜像源

  • 相关配置文件
    • podman 全局配置文件:/etc/containers/registries.conf

    • 用户单独配置文件:~/.config/containers/registries.conf

      配置文件有两种版本格式,v1和v2,两种格式的配置不能混用,混用会提示错误。

      • v2:
      v2
      unqualified-search-registries = ["docker.io", "quay.io"]
      [[registry]]
      # 镜像名前缀 192.168.1.96:7000/nginx
      prefix = "192.168.1.96:7000"
      # 实际拉取地址 127.0.0.1:7000/nginx
      location = "127.0.0.1:7000"
      # 可用http
      insecure = true 
      
      v1
      [registries.search]
      registries = ['docker.io']
      [registries.insecure]
      registries = ['192.168.0.1:7000']
      
      
      
      # 例:使用 podman pull registry.access.redhat.com/ubi8-minimal 时,
      # 仅仅会从registry.access.redhat.com去获取镜像。
      # 如果直接使用 podman pull ubuntu 时,没有明确指明仓库的时候,使用以下配置的仓库顺序去获取
      unqualified-search-registries = ["docker.io", "registry.access.redhat.com"]
       
      # 配置仓库的地址,可以直接在location里配置国内镜像例如:docker.mirrors.ustc.edu.cn
      # 直接在location里配置的时候,可以不需要后面的 [[registry.mirror]] 内容,
      # 但是这样只能配置一个镜像地址,这个镜像挂了就没法尝试其它镜像
      [[registry]]
      prefix = "docker.io"
      location = "docker.io"
       
       
      # 当使用 podman pod create 命令时候,因需要从k8s.gcr.io拉取 pause:3.2 镜像,但是该站点在国内被墙了。
      # 所以给该站点搞个镜像。以下镜像是阿里云第三方用户,非官方。
      # 或者 registry.aliyuncs.com/googlecontainersmirror ,也是第三方用户。
      # 目前没找到国内官方的镜像。gcr.mirrors.ustc.edu.cn 返回403不能用了
      [[registry]]
      prefix = "k8s.gcr.io"
      location = "registry.aliyuncs.com/google_containers"
       
       
      # 在这里可以配置多个镜像地址,前提是至少有一个[[registry]]配置。
      # 需要注意的是,无论 unqualified-search-registries 选择了哪个仓库,
      # 都会先从这里的上下顺序开始去拉取镜像,最后才会去匹配上 prefix 的 [[registry]]
      # 配置的 location 位置拉取镜像。所以这里需要注意,上面配置的不同仓库类型,这里配置的镜像并不
      # 能是通用的,所以 unqualified-search-registries 配置了多个仓库的时候,就最好直接使用
      # [[registry]] 的 location 指定镜像地址,不要配置 [[registry.mirror]] 了。
      # redhat 的国内镜像暂未发现。
      [[registry.mirror]]
      location = "docker.mirrors.ustc.edu.cn"
      [[registry.mirror]]
      location = "registry.docker-cn.com"
      
      • v1:
      # 使用tls
      [registries.search]
      registries = ['registry.access.redhat.com', 'registry.redhat.io', 'docker.io']
       
      # 不适用tls
      [registries.insecure]
      registries = []
       
      # 不允许使用的
      [registries.block]
      registries = []
      

根据镜像名称配置地址

  • /etc/containers/registries.conf.d/000-shortnames.conf

附录1

解决apt 秘钥问题

错误:5 https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04  InRelease
  由于没有公钥,无法验证下列签名: NO_PUBKEY 4D64390375060AA4
  • 4D64390375060AA4:根据实际替换
  • keyserver.ubuntu.com:可选择如下地址
  • 添加秘钥到apt
    • sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 4D64390375060AA4
  • 更新镜像
    • sudo apt update

解决证书过期错误

错误:8 https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04  Release
  Certificate verification failed: The certificate is NOT trusted. The certificate chain uses expired certificate.  Could not handshake: Error in the certificate verification. [IP: 195.135.221.134 443]
错误:9 https://download.opensuse.org/repositories/devel:kubic:libcontainers:unstable/xUbuntu_20.04  Release
  Certificate verification failed: The certificate is NOT trusted. The certificate chain uses expired certificate.  Could not handshake: Error in the certificate verification. [IP: 195.135.221.134 443]
  • sudo apt install ca-certificates