小白入门教程(番外筑基)--- nerdctl 容器基本功 + K8s 资源编写
定位:这是控制器篇的前置筑基章。控制器管的是 Pod,Pod 里的容器怎么拉镜像、怎么跑、怎么挂数据,都是 nerdctl 的活。先把 nerdctl 玩熟,再看控制器就顺了。
0. 先搞清楚 nerdctl 是啥
一句话:nerdctl = 长得像 docker 的 containerd 客户端,命令 99% 跟 docker 一样,生产环境首选。
| 概念 | 它是啥 | 类比 |
|---|---|---|
| containerd | 底层容器运行时(真正的引擎) | 发动机 |
| nerdctl | 操作 containerd 的命令行工具 | 方向盘 |
| docker | 老方案,生产环境越来越少直接用 | 旧款车 |
类比:containerd 是发动机,nerdctl 是方向盘,方向盘开法跟 docker 一模一样。
1. 安装 nerdctl(手把手)
1.1 下载并解压
# 下载二进制包(内网源)
wget [http://192.168.46.100/01.softwares/03.stage-3/nerdctl-1.7.7-linux-amd64.tar.gz](http://192.168.46.100/01.softwares/03.stage-3/nerdctl-1.7.7-linux-amd64.tar.gz)
# 解压到 /usr/bin,命令全局可用
tar -xf nerdctl-1.7.7-linux-amd64.tar.gz -C /usr/bin/
1.2 配置命令补全(按Tab能补全命令)
# 安装补全工具
apt install -y bash-completion
# 创建补全目录(不存在才建)
[ ! -d /etc/bash_completion.d ] && mkdir /etc/bash_completion.d
# 把nerdctl的补全脚本写进去
nerdctl completion bash > /etc/bash_completion.d/nerdctl
# 立即生效
source /etc/bash_completion.d/nerdctl
1.3 装 CNI 插件(容器联网用的)
# 下载CNI插件包
wget [http://192.168.46.100/01.softwares/03.stage-3/cni-plugins-linux-amd64-v1.6.0.tgz](http://192.168.46.100/01.softwares/03.stage-3/cni-plugins-linux-amd64-v1.6.0.tgz)
# 插件统一放 /opt/cni/bin
mkdir -p /opt/cni/bin
tar -xf cni-plugins-linux-amd64-v1.6.0.tgz -C /opt/cni/bin
1.4 装依赖 + 内核参数(一次性配好)
# nerdctl网络需要防火墙工具
apt install -y iptables
# 加载两个内核模块(overlay文件系统 + 网桥过滤)
modprobe -a overlay br_netfilter
# 开机自动加载:写入modules-load.d
cat > /etc/modules-load.d/k8s-net.conf << EOF
br_netfilter
overlay
EOF
# 配置内核网络参数(让网桥流量走iptables、开启转发)
cat > /etc/sysctl.d/k8s.conf << 'EOF'
net.bridge.bridge-nf-call-iptables=1 # 网桥流量经过iptables(容器通信必需)
net.bridge.bridge-nf-call-ip6tables=1 # IPv6版本
net.ipv4.ip_forward=1 # 开启IP转发(容器访问外网必需)
EOF
# 立即生效
sysctl -p /etc/sysctl.d/k8s.conf
1.5 验证装好了
nerdctl version # 看客户端/服务端版本
nerdctl info # 看环境信息(存储驱动overlayfs、Cgroup Driver: systemd)
💡
version里 WARN buildctl 找不到是正常的,不影响使用。
2. nerdctl 配置(管它是谁在说话)
2.1 配置文件在哪
| 身份 | 路径 |
|---|---|
| root/sudo(rootful) | /etc/nerdctl/nerdctl.toml |
| 普通用户(rootless) | ~/.config/nerdctl/nerdctl.toml |
2.2 nerdctl.toml 内容注释
# 1. containerd socket 地址(默认位置)
address = "unix:///run/containerd/containerd.sock"
# 2. 镜像加速目录(自动读取 certs.d 下的配置)
hosts_dir = ["/etc/containerd/certs.d", "/etc/docker/certs.d"]
# 3. 默认命名空间(k8s 环境用 k8s.io)
namespace = "default"
2.3 nerdctl 怎么找到 containerd(socket查找顺序)
顺序:命令行参数 → 环境变量 → nerdctl.toml → 默认路径 ,找到就用,平时默认路径
/run/containerd/containerd.sock不用配。
# ① 命令行参数(临时一次)
nerdctl -H unix:///path/to/containerd.sock images
# ② 环境变量(当前会话)
export CONTAINERD_ADDRESS=unix:///run/k3s/containerd/containerd.sock
nerdctl images # 自动用这个sock
# ③ 配置文件写死(持久化)→ 见2.2的 address 字段
3. 镜像加速配置(重点!最容易卡住)
原理一句话:nerdctl 不读 CRI 那套 registry 配置(crictl 专用的),它用 containerd 原生方式:config_path + certs.d 目录。配不好,拉镜像巨慢或直接失败。
# 第一步:改 containerd 主配置,开启 config_path 方式
vim /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d" # 加速配置都放这个目录
# 第二步:创建目录
mkdir -p /etc/containerd/certs.d
# 第三步:分别给每个镜像源建目录 + hosts.toml(下面三个小节)
docker.io 加速
mkdir -p /etc/containerd/certs.d/docker.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
server = "[https://registry-1.docker.io](https://registry-1.docker.io)" # 原始源地址
[host."[https://docker.m.daocloud.io](https://docker.m.daocloud.io)"] # 加速镜像站
capabilities = ["pull", "resolve"] # 只允许拉取和解析,不允许推送
[host."[https://09def58152000fc00ff0c00057bad7e0.mirror.swr.myhuaweicloud.com](https://09def58152000fc00ff0c00057bad7e0.mirror.swr.myhuaweicloud.com)"]
capabilities = ["pull", "resolve"]
EOF
registry.k8s.io 加速(k8s官方镜像仓库,国内必须加速)
mkdir -p /etc/containerd/certs.d/registry.k8s.io
cat > /etc/containerd/certs.d/registry.k8s.io/hosts.toml << EOF
server = "[https://registry.k8s.io](https://registry.k8s.io)"
# 首选 DaoCloud
[host."[https://k8s.m.daocloud.io](https://k8s.m.daocloud.io)"]
capabilities = ["pull", "resolve"]
[host."[https://09def58152000fc00ff0c00057bad7e0.mirror.swr.myhuaweicloud.com](https://09def58152000fc00ff0c00057bad7e0.mirror.swr.myhuaweicloud.com)"]
capabilities = ["pull", "resolve"]
EOF
私有 http 仓库加速(内网镜像站)
mkdir -p /etc/containerd/certs.d/hub.laoma.cloud
cat > /etc/containerd/certs.d/hub.laoma.cloud/hosts.toml << EOF
server = "[http://hub.laoma.cloud](http://hub.laoma.cloud)" # 私有仓库是http协议
[host."[http://hub.laoma.cloud](http://hub.laoma.cloud)"]
capabilities = ["pull", "resolve"]
EOF
最后:重启 containerd 并验证
systemctl restart containerd
# 能秒拉hello-world说明加速生效
nerdctl pull hello-world
4. 管理镜像(image 命令)
| 命令 | 作用 | 速记 |
|---|---|---|
nerdctl images |
查看本地镜像 | 同docker images |
nerdctl pull 镜像 |
下载镜像 | 同docker pull |
nerdctl image rm 镜像 |
删除镜像 | 同docker rmi |
nerdctl tag 旧 新 |
给镜像打标签 | 同docker tag |
nerdctl push 镜像 |
推送到仓库 | 先login |
nerdctl save 镜像 -o 文件 |
导出镜像为tar | 离线传输用 |
nerdctl load -i 文件 |
导入tar镜像 | 离线安装用 |
nerdctl image history 镜像 |
看构建层历史 | 调试用 |
nerdctl image inspect 镜像 |
看镜像详细信息 | 看配置用 |
nerdctl image prune --all --force |
清空所有未用镜像 | 一键瘦身 |
# 拉镜像(可简写)
nerdctl pull busybox
# 看本地镜像
nerdctl images
# 删除镜像(用完整仓库名)
nerdctl image rm docker.io/library/mysql
# 打标签(同一个镜像ID,多一个名字)
nerdctl tag busybox mage16196/busybox
# 推送前登录
nerdctl login
# Enter Username: mage16196
# Enter Password:
# 推送
nerdctl push mage16196/busybox
# 导出镜像成文件(发到离线环境)
nerdctl save busybox -o busybox.tar
# 导入tar文件里的镜像
nerdctl load -i busybox.tar
# 查看镜像构建历史(Dockerfile每步一层)
nerdctl image history docker.io/library/mysql
# 查看镜像详细配置(环境变量、端口、启动命令都在这)
nerdctl image inspect docker.io/library/mysql
# 清空所有未使用镜像
nerdctl image prune --all --force
5. 管理容器(container 命令)
| 命令 | 作用 | 速记 |
|---|---|---|
nerdctl ps |
看运行中容器 | 加-a看所有 |
nerdctl run |
创建并运行容器 | 核心命令 |
nerdctl rm 容器 |
删除容器 | 同docker rm |
nerdctl container prune --force |
删所有未运行容器 | 一键清理 |
nerdctl rename 旧 新 |
重命名容器 | ------ |
nerdctl stop / start / restart |
停止/启动/重启 | 同docker |
nerdctl pause / unpause |
挂起/恢复容器 | 冻结进程 |
nerdctl kill 容器 |
发KILL信号强杀 | 退出码137 |
nerdctl exec -it 容器 bash |
进容器内部执行命令 | 排障神器 |
nerdctl cp 文件 容器: |
复制文件进容器 | 同docker cp |
nerdctl logs 容器 |
看容器日志 | 排错必用 |
nerdctl port 容器 |
看端口映射 | ------ |
nerdctl commit 容器 新镜像 |
容器固化成镜像 | 很少用 |
# 查看容器
nerdctl ps # 只看运行的
nerdctl ps -a # 看所有(含退出的)
# 交互式进入容器(exit退出后容器状态Exited)
nerdctl run -it ubuntu
# 后台运行nginx(-d后台 --name起名)
nerdctl run -d --name nginx -p 8080:80 nginx
# 删除容器
nerdctl rm 249c162d8db6
# 清理所有已退出的容器
nerdctl container prune --force
# 重命名
nerdctl run --name ubuntu-1 ubuntu
nerdctl rename ubuntu-1 ubuntu
# 停止/启动/重启(stop后状态Exited (0))
nerdctl stop nginx-de224
nerdctl start nginx-de224
nerdctl restart nginx-de224
# 挂起/恢复(pause后状态Paused,进程冻结)
nerdctl pause nginx-de224
nerdctl unpause nginx-de224
# 强杀(kill后退出码137,说明被信号杀掉)
nerdctl kill nginx-de224
# 进容器内部执行命令
nerdctl exec -it nginx-de224 bash
# 复制宿主机文件进容器
nerdctl cp /etc/hostname nginx-de224:
# 看端口映射(容器80 → 宿主机8080)
nerdctl port nginx
# 输出: 80/tcp -> 0.0.0.0:8080
# 看日志(nginx启动过程全在这)
nerdctl logs nginx-de224
run 常用选项注释
nerdctl run \
-d \ # 后台运行(不占终端)
--name nginx \ # 指定容器名
-p 8080:80 \ # 端口映射 宿主机8080→容器80
-v /data:/data \ # 挂载目录(宿主机目录:容器目录)
-e MYSQL_ROOT_PASSWORD=123 \ # 设置环境变量
--restart always \ # 退出自动重启
--rm \ # 退出即删(临时容器用)
-it \ # 交互模式进终端
nginx # 镜像名
6. 管理网络(容器怎么互联)
原理一句话:容器和宿主机之间是一对 veth 虚拟网线(veth pair),插在叫
nerdctl0的网桥上。容器 IP 是 10.4.0.x,网关是 10.4.0.1。
# 查看网络列表(bridge/host/none三种)
nerdctl network ls
# 查看网桥详情(子网、网关)
nerdctl network inspect bridge
# 输出关键信息: Subnet 10.4.0.0/24, Gateway 10.4.0.1
# 看容器内网卡(eth0@if7,@if7=对端是宿主机7号网卡)
nerdctl exec busybox-bab94 -- ip a
# 看宿主机网卡(vethf9f77444@if2,@if2=对端是容器内2号网卡)
ip a
# 用brctl看网桥上挂了几根"网线"
apt install -y bridge-utils
brctl show
# bridge name interfaces
# nerdctl0 vethf9f77444
对应关系:容器
eth0@if7↔ 宿主机vethf9f77444@if2,一对虚拟网线穿过网桥,容器就这么上网的。
7. 管理存储(数据不丢)
方式1:挂载宿主机目录(bind mount)
# -v 宿主机目录:容器目录,容器里改=宿主机里改
nerdctl run -d -v /data:/data busybox -- sleep infinity
# 验证:宿主机建文件,容器里能看到
touch /data/f1
nerdctl exec busybox-6afe6 -- ls /data # 输出 f1
方式2:用卷(volume,nerdctl统一管理)
# -v 卷名:容器目录,卷实际存在 /var/lib/nerdctl/.../volumes/ 下
nerdctl run -d -v data:/data busybox -- sleep infinity
# 看卷列表(DIRECTORY就是卷的真实存放位置)
nerdctl volume ls
# data /var/lib/nerdctl/1935db59/volumes/k8s.io/data/_data
区别:目录挂载 =你指定宿主机路径,好找但换个机器就得改;卷=containerd 帮你管,路径固定,适合正式环境。
8. 管理命名空间(小心!跟K8s不是一回事)
⚠️
nerdctl namespace跟 Linux 命名空间、Kubernetes 命名空间完全无关 ,它是 containerd 自己的隔离空间,K8s 创建的容器都在k8s.io空间里。
nerdctl namespace ls
# NAME CONTAINERS IMAGES VOLUMES
# k8s.io 3 2 1
9. 用 PyCharm 写 K8s 资源文件(告别手敲)
9.1 装 Python(可选)
- 官网下载
Python 3.14.x的Windows installer (64-bit) - 双击安装,必须勾选
Add Python 3.14 to PATH(不勾就白装) - Win+R 输入 cmd →
python --version,能输出版本号就成功
9.2 装 PyCharm
- 官网下载 Community(社区版,免费) 就行
- 安装时勾选
Create Desktop Shortcut - 激活:找老师拿
pycharm-Crack.7z,把bin和jbr目录覆盖到安装目录,jetbraincrack放 C 盘根目录,重开后在 Help→Manage Subscriptions 看激活状态 - 汉化:File→Settings→Plugins→Marketplace→搜
Chinese→装中文语言包→重启
9.3 装 Kubernetes 插件(关键)
File → 设置 → 插件 → Marketplace → 搜 Kubernetes(JetBrains官方)→ 安装 → 重启
装失败就从官网下载插件 zip,在插件界面点齿轮→
从磁盘安装插件→选文件。
9.4 新建 K8s 资源文件
- 右键项目 → 新建 → Kubernetes 资源 → 输入
pod回车,生成模板 - 清空模板重写,先写
apiVersion:这行,之后才有自动补全(不写这行不补全) - 右键文件 → 重写文件类型 → Kubernetes Yaml,补全更完整
补全效果:写
metadata:自动提示 name/labels,写spec:自动提示 containers/restartPolicy,写容器后自动提示 image/ports,比手敲快一倍。
筑基速查表
| 模块 | 核心命令 | 一句人话 |
|---|---|---|
| 镜像 | pull / images / rm / tag / push / save / load |
跟 docker 一模一样 |
| 容器 | run / ps / exec / logs / stop / rm |
run创建、exec进内部、logs看日志 |
| 网络 | network ls / inspect |
全是 veth 网线插在 nerdctl0 网桥 |
| 存储 | -v 目录:目录 或 -v 卷名:目录 |
目录挂载 vs 卷管理 |
| 命名空间 | namespace ls |
containerd 自己的,别和 K8s 混淆 |
| 资源编写 | PyCharm + Kubernetes 插件 | 先写 apiVersion 才有补全 |
小白学习建议
- 镜像命令先背熟:pull、images、rm、tag,跟 docker 完全一样,零成本迁移;
- 容器重点练 run 选项:-d、--name、-p、-v、-e 五个必会,生产天天用;
- 遇到拉镜像失败先查加速 :
/etc/containerd/certs.d/下 hosts.toml 配好没、containerd 重启没; - 排障三板斧 :
nerdctl ps -a看状态 →nerdctl logs看日志 →nerdctl exec进容器查; - 筑基完成标志:能自己用 nerdctl 拉镜像、跑容器、挂数据、看日志,然后就可以进控制器篇学 Deployment 了。