云原生学习笔记(八) Docker 实战:宿主机与容器的信息交互与共享策略

3 阅读3分钟

🧱 一、docker cp:最直接的文件交互方式

docker cp 是最简单、原生支持的文件交互方式,适合脚本注入、数据提取等任务。

🔍 背后机制解析

  • docker cp 不是在容器内部执行 cp 命令,而是由 Docker Engine API 调用实现的;
  • 对容器使用了 overlay 文件系统(如 overlay2)时:
/var/lib/docker/overlay2/
├── lower (镜像层)
├── upper (容器可写层)
└── merged -> 容器可见视图

当执行:

docker cp ./my.conf mycontainer:/etc/my.conf

Docker 会定位 merged 层中的目标路径,完成 copy-on-write 操作,并将宿主文件复制到可写层。

✅ 典型使用场景

# 复制脚本到容器
docker cp ./start.sh mycontainer:/opt/app/start.sh

# 备份容器内日志
docker cp mycontainer:/var/log/app.log ./logs/

❌ 常见限制

  • 不能处理符号链接;
  • 容器需处于运行状态或未完全退出;
  • 容器层文件权限可能干扰拷贝操作;
  • 不适合持续交互或批量共享场景。

🛠️ 扩展实战:配合 tar 做批量归档

# 容器打包 volume 内容并导出
docker exec mycontainer tar czf /tmp/backup.tar.gz /data

# 拷贝到宿主机
docker cp mycontainer:/tmp/backup.tar.gz ./

🌐 二、Samba 容器:灵活可控的共享目录方案

当需要在宿主机与多个容器之间进行持续共享时,推荐使用 Samba 搭建共享目录服务。

🧩 背后网络机制

  • Samba 运行于容器中,默认暴露 445 端口;
  • 若使用 bridge 网络,需通过端口映射方式访问;
  • 或者使用 --network host 让容器共享宿主机网络。
docker run -d \
  --name samba \
  -p 445:445 \
  -v /mydata:/mount \
  dperson/samba \
  -u "user;password" -s "public;/mount;yes;no;yes;user"

🧱 Samba 配置详解

  • -u 设置用户密码;
  • -s 设置共享名、路径、是否可读、是否可写、是否可浏览、用户授权;
  • 例如:-s "public;/data;yes;yes;yes;user"

✅ 宿主机访问测试

# 创建挂载点
mkdir -p /mnt/smbshare

# 手动挂载测试
mount -t cifs //localhost/public /mnt/smbshare -o username=user,password=pass,vers=3.0

🔄 Docker 中以 Volume 形式挂载 Samba

docker volume create \
  --driver local \
  --opt type=cifs \
  --opt device=//localhost/public \
  --opt o=username=user,password=pass \
  smb-volume

# 在容器中使用

docker run -it --rm \
  -v smb-volume:/data \
  ubuntu bash

🔒 权限与安全实践

🔑 主机访问权限控制

  • Samba 用户需显式授权(-u 指定);
  • 可设置只读共享(共享配置中设定);
  • 可以结合 iptables、防火墙限制 IP 来源;

🧿 SELinux 或 AppArmor

若启用了 SELinux,需为挂载目录设置共享类型:

chcon -t samba_share_t /mydata

若在 Docker 中使用,需要额外添加:

--security-opt label=type:container_file_t

🔁 哪种方式更适合你?

场景推荐方案理由
快速复制配置或日志docker cp简洁、无需额外配置
批量数据打包导出docker cp + tar适合任务数据处理
宿主与容器共享目录Samba + mount跨平台、灵活、持续共享
多容器共享同一目录docker volume + Samba集群共享、高效稳定
Windows ↔ Linux 文件交互Samba原生支持 SMB 协议

📈 与 DevOps 生命周期集成视角

生命周期阶段典型操作推荐交互方式
开发调试注入脚本、热更新docker cp
集成测试导入测试集、报告共享Samba + Volume
生产部署持久化目录、统一配置Samba + mount
运维监控拉取日志、共享分析脚本Samba + cron
灾难恢复与迁移打包数据卷、恢复配置文件docker cp + tar

⚠️ 常见反例与误区补充

❌ 容器内尝试 mount CIFS 失败

mount: permission denied

原因可能包括:

  • 未授权 --cap-add=SYS_ADMIN
  • 容器镜像中缺失 mount 命令或 cifs-utils
  • Docker 安全策略(AppArmor)限制挂载行为。

🔚 总结:选择方案的参考建议

推荐方向原因
一次性拷贝、临时交互使用 docker cp,最轻量无依赖
跨系统共享文件夹使用 Samba 容器,兼容性高、灵活配置
高性能共享目录使用 bind mount,性能优但隔离性差
多容器共享、集群部署使用 Samba + Volume 管理,结构清晰、安全可控