解决Podman构建Azure IoT Edge模块挂载失败及读写权限问题
我开发了一个需要读写IoT Edge服务器指定目录文件的自定义Azure IoT Edge模块。之前用Docker Desktop构建时,通过Docker Bind配置可以正常授予模块读写权限,但改用Podman Desktop构建后容器无法启动,报错如下:
Error response from daemon: failed to create shim: OCI runtime create
failed: container_linux.go:380: starting container process caused:
process_linux.go:545: container init caused: rootfs_linux.go:75:
mounting "/var/SampleModule" to rootfs at "/app/SampleModule" caused:
mount through procfd: open o_path procfd: open
/var/lib/docker/overlay2/871b2e9e4e03.../merged/app/SampleModule: not
a directory: unknown: Are you trying to mount a directory onto a file
(or vice-versa)? Check if the specified host path exists and is the
expected type
对应的deployment.template.json配置如下:
{ "$schema-template": "4.0.0", "modulesContent": { "$edgeAgent": { "properties.desired": { "schemaVersion": "1.1", "runtime": { "type": "docker", "settings": { "minDockerVersion": "v1.25", "loggingOptions": "", "registryCredentials": { "<Container Registry Name>": { "username": "$CONTAINER_REGISTRY_USERNAME_<Container Registry Name>", "password": "$CONTAINER_REGISTRY_PASSWORD_<Container Registry Name>", "address": "<Container Registry hostname>" } } } }, "systemModules": { "edgeAgent": { "type": "docker", "settings": { "image": "mcr.microsoft.com/azureiotedge-agent:1.4", "createOptions": {} } }, "edgeHub": { "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "mcr.microsoft.com/azureiotedge-hub:1.4", "createOptions": { "HostConfig": { "PortBindings": { "5671/tcp": [ { "HostPort": "5671" } ], "443/tcp": [ { "HostPort": "443" } ] } } } } } }, "modules": { "SampleModule": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "${MODULES.SampleModule}", "createOptions": { "HostConfig": { "Binds": [ "/var/SampleModule/data:/app/SampleModule/data" ] } } } }, "SimulatedTemperatureSensor": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.4", "createOptions": {} } } } } }, "$edgeHub": { "properties.desired": { "schemaVersion": "1.2", "routes": { "SampleModuleToIoTHub": "FROM /messages/modules/SampleModule/outputs/* INTO $upstream", "sensorToSampleModule": "FROM /messages/modules/SimulatedTemperatureSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/SampleModule/inputs/input1\")" }, "storeAndForwardConfiguration": { "timeToLiveSecs": 7200 } } } } }
这个错误的核心是容器内目标路径类型不符,或宿主机路径配置存在问题,结合Podman与Docker的差异,按以下步骤修复:
1. 校验容器镜像内的挂载目标路径
首先确认SampleModule镜像中/app/SampleModule/data是目录而非文件:
- 拉取镜像后运行临时容器查看:
podman run --rm -it <你的镜像ID> ls -ld /app/SampleModule/data
如果路径不存在,需在Dockerfile中添加RUN mkdir -p /app/SampleModule/data构建命令;如果是文件,删除镜像中该文件后重新构建。
2. 修复宿主机路径的存在性与权限
在IoT Edge服务器上执行:
- 创建宿主机目标目录:
sudo mkdir -p /var/SampleModule/data - 配置IoT Edge运行时可读写的权限:
sudo chown -R iotedge:iotedge /var/SampleModule/data sudo chmod -R 755 /var/SampleModule/data
3. 适配Podman挂载语法(可选)
部分环境下Podman对Docker的Binds语法兼容存在问题,可改用Podman原生Mounts格式修改createOptions:
"createOptions": { "Mounts": [ { "type": "bind", "source": "/var/SampleModule/data", "target": "/app/SampleModule/data", "readOnly": false } ] }
4. 配置IoT Edge运行时适配Podman
Azure IoT Edge默认使用Docker,切换到Podman需修改运行时配置:
- 编辑
/etc/iotedge/config.yaml:runtime: type: "containerd" settings: containerd_socket: "/run/podman/podman.sock" - 重启IoT Edge服务:
sudo systemctl restart iotedge
5. 清理旧容器与镜像缓存
Podman可能保留了旧状态,执行以下命令清理后重新部署:
podman stop SampleModule podman rm SampleModule podman rmi <你的SampleModule镜像>
内容的提问来源于stack exchange,提问作者Satyam Chauhan

