无root权限玩转容器:nerdctl+containerd-rootless实战教程(附CNI网络自定义配置技巧)
无root权限玩转容器:nerdctl+containerd-rootless实战指南
在共享主机环境或CI/CD流水线中,安全隔离和权限控制往往是刚需。传统容器方案要求root权限,这给多租户场景埋下安全隐患。而rootless容器技术的出现,让普通用户也能安全地创建、运行和管理容器,彻底告别权限泛滥风险。
本文将手把手带你用nerdctl和containerd-rootless搭建无root容器环境,重点解决/opt目录权限限制导致的CNI网络配置难题。无论你是关注安全隔离的DevOps工程师,还是需要在受限环境中部署容器化应用的技术人员,这套方案都能为你提供新的技术选择。
1. 环境准备与基础安装
1.1 系统依赖检查
在开始前,请确保你的Linux系统满足以下条件:
- 内核版本≥5.11(支持cgroup v2)
- 已安装
newuidmap和newgidmap工具(通常包含在shadow-utils包中) - 普通用户已加入
sudoers列表(仅限初始配置阶段)
验证命令如下:
# 检查内核版本
uname -r
# 确认cgroup版本
stat -fc %T /sys/fs/cgroup/
# 检查用户映射工具
which newuidmap
1.2 安装containerd-rootless
推荐使用官方提供的安装脚本,它会自动处理所有依赖:
# 下载最新版nerdctl-full(包含containerd)
wget https://github.com/containerd/nerdctl/releases/download/v1.6.2/nerdctl-full-1.6.2-linux-amd64.tar.gz
tar -xzf nerdctl-full-1.6.2-linux-amd64.tar.gz
cd nerdctl-full-1.6.2-linux-amd64
# 设置环境变量
export PATH=$PATH:$(pwd)/bin
export XDG_RUNTIME_DIR=/run/user/$(id -u)
# 执行安装
containerd-rootless-setuptool.sh install
安装完成后,脚本会输出需要添加到~/.bashrc的环境变量。建议立即生效:
source ~/.bashrc
注意:如果遇到
systemctl --user报错,请先执行loginctl enable-linger $(whoami)激活用户级systemd。
2. 解决CNI网络路径限制
2.1 传统方案的痛点
默认情况下,CNI插件需要安装在/opt/cni/bin目录,这在共享主机环境中常会遇到权限问题。通过以下方法可以自定义CNI路径:
# 创建用户本地CNI目录
mkdir -p ~/.local/lib/cni/bin
wget https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz
tar -xzf cni-plugins-linux-amd64-v1.1.1.tgz -C ~/.local/lib/cni/bin
# 设置环境变量
export CNI_PATH=~/.local/lib/cni/bin
2.2 自定义网络配置
在用户目录下创建CNI配置文件~/.config/cni/net.d/10-mynet.conf:
{
"cniVersion": "0.4.0",
"name": "mynet",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.88.0.0/16",
"routes": [
{ "dst": "0.0.0.0/0" }
]
}
}
验证网络配置:
nerdctl network ls
3. 存储方案优化
3.1 选择适合的snapshotter
在rootless模式下,推荐使用fuse-overlayfs作为存储驱动:
# 创建容器时显式指定
nerdctl run -d --snapshotter=fuse-overlayfs nginx:alpine
# 或设置为默认
export CONTAINERD_SNAPSHOTTER=fuse-overlayfs
各snapshotter性能对比:
| 驱动类型 | 兼容性 | 性能 | 功能完整性 |
|---|---|---|---|
| native | 高 | 高 | 部分受限 |
| fuse-overlayfs | 中 | 中 | 完整 |
| stargz | 低 | 低 | 完整 |
3.2 用户命名空间配置
通过/etc/subuid和etc/subgid配置UID/GID映射:
# 管理员执行(仅需一次)
sudo usermod --add-subuids 100000-165535 $(whoami)
sudo usermod --add-subgids 100000-165535 $(whoami)
验证映射:
cat /etc/subuid
cat /etc/subgid
4. 实战技巧与排错指南
4.1 常见错误处理
错误1:挂载权限不足
FATA[0000] failed to mount /run/user/1000/containerd-mount2759511587: operation not permitted
解决方案:
nerdctl run --snapshotter=fuse-overlayfs your-image
错误2:cgroup配置问题
ERRO[0000] failed to create shim task: OCI runtime create failed
解决方法:
mkdir -p ~/.config/systemd/user/containerd.service.d
echo -e '[Service]\nDelegate=yes' > ~/.config/systemd/user/containerd.service.d/delegate.conf
systemctl --user daemon-reload
4.2 性能调优参数
在~/.config/containerd/config.toml中添加:
[plugins."io.containerd.grpc.v1.cri".containerd]
snapshotter = "fuse-overlayfs"
disable_snapshot_annotations = true
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/home/user/.local/lib/cni/bin"
conf_dir = "/home/user/.config/cni/net.d"
4.3 CI/CD集成示例
GitLab Runner配置片段:
variables:
CNI_PATH: "${CI_PROJECT_DIR}/.cni/bin"
CONTAINERD_SNAPSHOTTER: "fuse-overlayfs"
before_script:
- mkdir -p ${CI_PROJECT_DIR}/.cni/bin
- wget -qO- https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz | tar -xz -C ${CI_PROJECT_DIR}/.cni/bin
5. 安全加固建议
5.1 用户命名空间隔离
通过/etc/containerd/rootless.toml配置:
[rootless]
enable = true
cgroup = true
no_new_privileges = true
5.2 内核参数优化
建议设置以下sysctl参数:
# 在/etc/sysctl.d/99-rootless.conf中配置
user.max_user_namespaces=28633
net.ipv4.ping_group_range=0 2147483647
5.3 镜像验证策略
启用镜像签名验证:
nerdctl pull --verify=cosign docker.io/library/nginx:latest
签名验证流程:
- 镜像拉取时自动获取签名
- 使用cosign验证签名有效性
- 验证通过后才创建容器
6. 高级网络配置
6.1 多网络接口方案
创建自定义bridge网络:
nerdctl network create --driver=bridge \
--subnet=192.168.100.0/24 \
--gateway=192.168.100.1 \
my-bridge
网络连接示例:
nerdctl run -d --name=web --network=my-bridge nginx
nerdctl run -it --network=container:web busybox
6.2 端口映射技巧
动态端口映射:
# 随机映射主机端口
nerdctl run -d -p 8080 nginx
# 查看实际映射端口
nerdctl port <container-id> 8080
6.3 网络性能测试
使用iperf3进行基准测试:
# 服务端
nerdctl run -d -p 5201:5201 --name=iperf-server networkstatic/iperf3 -s
# 客户端
nerdctl run -it --rm networkstatic/iperf3 -c <server-ip>
测试结果解读指标:
- 带宽:网络吞吐量上限
- 抖动:延迟波动范围
- 丢包率:数据传输可靠性
7. 监控与日志管理
7.1 容器日志收集
配置JSON日志驱动:
nerdctl run -d --log-driver=json-file --log-opt max-size=10m nginx
日志查看命令:
# 查看实时日志
nerdctl logs -f <container>
# 导出日志文件
nerdctl logs <container> > container.log
7.2 资源监控方案
安装cAdvisor进行监控:
nerdctl run -d \
--name=cadvisor \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=8080:8080 \
gcr.io/cadvisor/cadvisor:v0.47.0
关键监控指标:
- CPU使用率:容器进程CPU占用
- 内存用量:包括缓存和交换使用情况
- IOPS:磁盘读写操作频率
- 网络吞吐:进出流量统计
8. 持久化存储方案
8.1 用户空间卷管理
创建持久化卷:
mkdir -p ~/container_data/db
nerdctl run -d -v ~/container_data/db:/var/lib/mysql mysql:8.0
8.2 分布式存储集成
与CephFS集成示例:
nerdctl run -d \
--mount type=volume,source=ceph-volume,destination=/data,volume-driver=ceph \
-e CEPH_USERNAME=admin \
-e CEPH_CLUSTER_NAME=my-cluster \
my-app
存储驱动对比:
| 类型 | 性能 | 持久性 | 适用场景 |
|---|---|---|---|
| 本地目录 | 高 | 中 | 开发测试环境 |
| NFS | 中 | 高 | 共享存储需求 |
| CephFS | 中 | 极高 | 分布式环境 |
| tmpfs | 极高 | 无 | 临时数据处理 |
9. 镜像构建与分发
9.1 rootless模式下的镜像构建
使用BuildKit构建镜像:
nerdctl build \
--buildkitd-flags="--oci-worker-rootless" \
-t my-image .
构建缓存管理:
# 查看构建缓存
nerdctl builder prune
# 清理所有缓存
nerdctl builder prune --all
9.2 私有镜像仓库配置
启动本地registry:
nerdctl run -d \
-p 5000:5000 \
--name registry \
-v ~/registry:/var/lib/registry \
registry:2
镜像推送示例:
nerdctl tag my-image localhost:5000/my-image
nerdctl push localhost:5000/my-image
10. 容器编排进阶
10.1 简易编排方案
使用nerdctl compose管理多容器应用:
# 安装compose插件
wget https://github.com/containerd/nerdctl/releases/download/v1.6.2/nerdctl-1.6.2-linux-amd64.tar.gz
tar -xzf nerdctl-1.6.2-linux-amd64.tar.gz -C ~/.local/bin
示例docker-compose.yml:
services:
web:
image: nginx:alpine
ports:
- "8080:80"
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: example
10.2 与Kubernetes集成
通过k3s实现轻量级编排:
# 安装k3s(rootless模式)
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--rootless" sh -
# 验证安装
k3s kubectl get nodes
Pod配置示例:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
更多推荐
所有评论(0)