Podman容器管理工具使用入门
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
- 查看本地连接列表
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 xfschgrp -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 下行128kbpswondershper -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:可选择如下地址- keyserver.ubuntu.com
- pgp.mit.edu
- subkeys.pgp.net
- www.gpg-keyserver.de
- 添加秘钥到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