4. 容器化运行时环境部署
任务目标
在边缘智能工业网关(x86_64 / ARM64 Linux)上部署 containerd 作为容器运行时,配置 veth 桥接网络与本地持久化存储,验证边缘应用可在隔离环境中正常运行并访问外部网络。
环境依赖
- Linux 内核 ≥ 5.11(建议),已加载
overlay、br_netfilter模块 - 已安装
containerd(版本 ≥ 1.7)与runc - 已安装
cni-plugins(至少包含bridge、loopback、portmap) - 已安装
nerdctl(containerd 的 CLI 客户端,兼容 Docker 命令风格)
核心实现
以下脚本完成:生成 CNI 桥接网络配置、创建持久化数据目录、启动一个运行 Nginx 的边缘容器并挂载宿主机目录,最后通过宿主机端口访问容器服务。
#!/bin/bash
# edge-container-deploy.sh
# 用途:在网关部署 containerd 容器运行时环境,验证隔离与持久化
set -euo pipefail
# ---------- 1. 检查运行时 ----------
if ! command -v nerdctl >/dev/null 2>&1; then
echo "[ERROR] nerdctl 未安装,请先安装 containerd 与 nerdctl"
exit 1
fi
# ---------- 2. 配置 CNI 桥接网络 ----------
CNI_CONF_DIR="/etc/cni/net.d"
CNI_CONF_FILE="${CNI_CONF_DIR}/10-edge-bridge.conflist"
mkdir -p "${CNI_CONF_DIR}"
cat > "${CNI_CONF_FILE}" <<'EOF'
{
"cniVersion": "1.0.0",
"name": "edge-bridge",
"plugins": [
{
"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" }]
}
},
{
"type": "portmap",
"capabilities": { "portMappings": true }
}
]
}
EOF
echo "[OK] CNI 网络配置已写入 ${CNI_CONF_FILE}"
# ---------- 3. 创建持久化存储目录 ----------
DATA_ROOT="/var/lib/edge-containers"
APP_DATA="${DATA_ROOT}/nginx-html"
mkdir -p "${APP_DATA}"
echo "<h1>Edge Gateway Container OK</h1>" > "${APP_DATA}/index.html"
echo "[OK] 持久化目录已创建: ${APP_DATA}"
# ---------- 4. 拉取镜像并启动容器 ----------
IMAGE="nginx:1.27-alpine"
CONTAINER_NAME="edge-nginx"
# 清理可能存在的同名容器
nerdctl rm -f "${CONTAINER_NAME}" 2>/dev/null || true
echo "[INFO] 拉取镜像 ${IMAGE} ..."
nerdctl pull "${IMAGE}"
echo "[INFO] 启动容器 ${CONTAINER_NAME} ..."
nerdctl run -d \
--name "${CONTAINER_NAME}" \
--network edge-bridge \
-p 8080:80 \
-v "${APP_DATA}:/usr/share/nginx/html:ro" \
--restart=unless-stopped \
"${IMAGE}"
# ---------- 5. 验证状态 ----------
sleep 2
echo ""
echo "===== 容器运行状态 ====="
nerdctl ps --filter "name=${CONTAINER_NAME}"
echo ""
echo "===== 网络连通性测试 ====="
if nerdctl exec "${CONTAINER_NAME}" wget -qO- http://127.0.0.1/ 2>/dev/null | grep -q "Edge Gateway"; then
echo "[PASS] 容器内 HTTP 服务自检通过"
else
echo "[FAIL] 容器内 HTTP 服务自检失败"
exit 1
fi
echo ""
echo "===== 宿主机端口访问测试 ====="
HOST_IP=$(ip -4 addr show eth0 2>/dev/null | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1)
if [ -z "${HOST_IP}" ]; then
HOST_IP="127.0.0.1"
fi
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://${HOST_IP}:8080/" || true)
if [ "${HTTP_CODE}" = "200" ]; then
echo "[PASS] 宿主机通过 ${HOST_IP}:8080 访问成功 (HTTP 200)"
else
echo "[FAIL] 宿主机访问失败,HTTP 状态码: ${HTTP_CODE}"
exit 1
fi
echo ""
echo "===== 持久化验证 ====="
nerdctl exec "${CONTAINER_NAME}" ls -la /usr/share/nginx/html/index.html
echo "[PASS] 容器内已挂载宿主机持久化目录"
echo ""
echo "[DONE] 容器化运行时环境部署完成"
运行方式
- 将脚本保存为
edge-container-deploy.sh,赋予执行权限:chmod +x edge-container-deploy.sh - 以 root 或具有 sudo 权限的用户执行:
sudo ./edge-container-deploy.sh - 脚本执行完成后,容器
edge-nginx将持续运行
验证方法与判定标准
- 运行时状态:执行
nerdctl ps,应看到edge-nginx状态为Up - 网络隔离与连通:脚本自动执行容器内自检与宿主机端口访问测试,输出
[PASS]即通过 - 持久化存储:在宿主机执行
echo "test" >> /var/lib/edge-containers/nginx-html/index.html后,容器内访问http://127.0.0.1/应看到更新内容;重启容器(nerdctl restart edge-nginx)后数据仍保留 - 手动验证:在网关局域网内另一台设备浏览器访问
http://<网关IP>:8080/,应显示Edge Gateway Container OK页面
常见问题
- CNI 网络创建失败:确认
/etc/cni/net.d下无其他冲突配置,且内核已加载br_netfilter(执行modprobe br_netfilter) - 端口映射不生效:检查
portmap插件是否在 CNI 配置中正确声明,且nerdctl run使用了-p参数 - 容器重启后数据丢失:确认挂载路径
-v使用的是宿主机路径,而非容器卷名