![将 Samba 共享挂载到 Docker 容器](https://linux22.com/image/792067/%E5%B0%86%20Samba%20%E5%85%B1%E4%BA%AB%E6%8C%82%E8%BD%BD%E5%88%B0%20Docker%20%E5%AE%B9%E5%99%A8.png)
目标
在我的服务器上,我运行着各种 Docker 容器,特别是 syncthing 容器。此外,我还将我的服务器用于不同的 Samba 共享。
我的目标是将主机目录挂载/mnt/basis/software/backups/syncthing
到 syncthing 容器,以便所有同步的文件都可以在 Samba 共享“备份”下访问。请注意,父目录backups
用于 Samba 共享。该syncthing
目录具有以下权限和标签设置:
drwxrwx---. 4 myuser applications system_u:object_r:samba_share_t:s0 11 12. Jan 00:06 syncthing
配置
我的 Samba 共享“备份”的配置如下:
[backups]
path = /mnt/basis/software/backups
writeable = yes
browseable = yes
read only = no
valid users = @applications
public = no
guest ok = no
force group = applications
directory mask = 0770
force directory mode = 0770
create mask = 0770
force create mode = 0770
inherit acls = yes
用于同步的docker-compose文件如下:
version: "3.9"
services:
syncthing:
image: lscr.io/linuxserver/syncthing:1.27.2
container_name: syncthing
hostname: syncthing-docker
environment:
- PUID=1000
- PGID=1006
- TZ=Europe/Berlin
volumes:
- /mnt/basis/software/docker/syncthing:/config:z
ports:
- 8384:8384
- 22000:22000/tcp
- 22000:22000/udp
- 21027:21027/udp
restart: always
在 docker-compose 文件中,我指定了挂载卷的后缀:z
,以确保目录的标签正确。此外,我确保分配了正确的用户 ID 和组 ID。在我的例子中,这是1006
引用组的组 ID applications
(如我的 Samba 共享配置中所述)。
问题
目前,当前设置无法正常工作。我可以成功启动 syncthing 容器,并且可以在端口 8384 上访问 Web 应用程序。我还能够在一个小测试中确认文件已成功同步。但是,不再能够访问/syncthing
Samba 共享中的目录,因为使用后缀重新标记会从目录中:z
删除标签并添加标签,从而使目录无法访问。问题似乎出在已挂载目录的重新标记上。samba_share_t
container_file_t
但是如果我省略后缀:z
并且目录未重新绑定,则容器无法正确启动。我查看了容器日志,发现权限显然被拒绝,如下所示。
[start] 2024/01/12 01:24:04 INFO: syncthing v1.27.2 "Gold Grasshopper" (go1.20.11 linux-amd64) root@buildkitsandbox 2024-01-02 08:15:35 UTC [noupgrade]
[start] 2024/01/12 01:24:04 INFO: Generating ECDSA key and certificate for syncthing...
[start] 2024/01/12 01:24:04 WARNING: Failed to load/generate certificate: save cert: open /config/cert.pem: permission denied
看来我在设置syncthing
目录的权限时做错了什么。
问题
根据前面的解释,我想问一下是否可以将目录挂载/mnt/basis/software/backups/syncthing
到 syncthing 容器中,以便我可以通过 Samba 共享从远程机器访问同步文件?
如果您能提供任何关于如何进行的想法或建议,我将不胜感激。
答案1
事实证明,问题实际上源于 SELinux 策略。具体来说,podman 容器进程(标记为container_t
)无法访问 samba 共享目录(标记为samba_share_t
)。
经过一番研究,我发现了这篇文章:
如那里所述,我们可以使用ausearch
检查 SELinux 的拒绝决定,并为拒绝创建例外规则audit2allow
。然而,经过反复测试,我提出了这个 SELinux 模块规范:
module docker-samba 1.0;
require {
type container_t;
type samba_share_t;
type mnt_t;
class dir { read write setattr getattr create rename open add_name rmdir remove_name lock watch};
class file { read write setattr getattr create rename open lock unlink append};
}
#============= container_t ==============
allow container_t samba_share_t:dir { read write setattr getattr create rename open add_name rmdir remove_name lock watch};
allow container_t samba_share_t:file { read write setattr getattr create rename open lock unlink append};
allow container_t mnt_t:dir { setattr };
然后可以按如下方式安装该模块:
sudo checkmodule -M -m -o docker-samba.mod docker-samba.te
sudo semodule_package -m docker-samba.mod -o docker-samba.pp
sudo semodule -i docker-samba.pp
要检查您的模块规范是否确实正确,您可以再次使用ausearch
之前描述的方法检查 SELinux 拒绝消息。
答案2
看起来你正在使用基于 Linux 的 docker 容器,因此无法识别 Z:,因为那是 windows/Microsoft
因此,您需要在卷中指定一个 Linux 路径,例如 /data
volumes:
- /mnt/basis/software/docker/syncthing:/var/syncthing
还要确保 1006 对文件/目录/共享具有足够的权限
他们的 github 上有一个例子 docker-compose https://github.com/syncthing/syncthing/blob/main/README-Docker.md
---
version: "3"
services:
syncthing:
image: syncthing/syncthing
container_name: syncthing
hostname: my-syncthing
environment:
- PUID=1000
- PGID=1000
volumes:
- /wherever/st-sync:/var/syncthing
ports:
- 8384:8384 # Web UI
- 22000:22000/tcp # TCP file transfers
- 22000:22000/udp # QUIC file transfers
- 21027:21027/udp # Receive local discovery broadcasts
restart: unless-stopped