I’m learning both Linux(ubuntu) and docker.
I’m so far that my servies is running as it should in my docker container.
The service needs to access a fileshare for data access.
I also want the docker mounts to reside on a fileshare so noting “important” lies on the host itself.
How should I set this up properly?
If would think that for the docker mounts that this should be done on the host?
The file access from the docker however should I set this up via the dockerfile or is it just as fast to set it up on the host and mount it through docker?
There is no security concern as to mount on host in this case.
My next question will probably be how do I mount the share correct?
Regard Lars
Related
I would like to access a Windows file share share (SMB3) from a docker container, but I do not want to compromise the security of the host machine. All the guides I have read state that I need to use either the --privileged flag or --cap-add SYS_ADMIN capability.
Here is the command I use:
mount -t cifs -o
username='some_account#mydomain.internal',password='some_password'
//192.168.123.123/MyShare /mnt/myshare
Which results in the message:
Unable to apply new capability set.
When I apply the --cap-add SYS_ADMIN capability the mount command works fine, but I understand this exposes the host to obvious security vulnerabilities.
I have also read the suggestion in this StackOverflow question (Mount SMB/CIFS share within a Docker container) to mount the volume locally on the server that runs docker. This is undesirable for two reasons, firstly, the container is orchestrated by a Rancher Kubernetes cluster and I don't know how to achieve what is described by nPcomp using Rancher, and two, this means the volume is accessible to the docker host. I'd prefer only the container have access to this share via the credentials given to it via secrets.
My question is: is there way to mount a CIFS/SMB3 share in a docker container (within Kubernetes) without exposing the host to privilege escalation vulnerabilities and protecting the credentials? Many thanks.
After more research I have figured out how to do this. There is a Container Storage Interface (CSI) driver for SMB called SMB CSI Driver for Kubernetes (https://github.com/kubernetes-csi/csi-driver-smb).
After installing the CSI driver using helm (https://github.com/kubernetes-csi/csi-driver-smb/tree/master/charts) you can follow the example at https://github.com/kubernetes-csi/csi-driver-smb/blob/master/deploy/example/e2e_usage.md (Option #2 Create PV/PVC) to create a Persistent Volume (PV) and Persistent Volume Claim (PVC) which mounts the SMB3 share.
Then you create your container and give it the relevant Persistent Volume Claim, specifying you want to mount it as /mnt/myshare etc.
I tested this and it gets deployed to multiple worker nodes automatically and works well, without needing the privileged flag or --cap-add SYS_ADMIN to be given to the containers.
This supports SMB3 and even authentication & encryption. To enable encryption go to your Windows Server > File and Storage Services, select the share, Properties > Settings > Encrypt Data Access.
Wireshark shows all the SMB traffic is encrypted. Only thing I don't recall is if you have to install cifs-utils manually first, since I had already done this on all my nodes I wasn't able to test.
Hope this helps somebody.
I have seen the terms "bind mount" and "host volume" being used in various articles but none of them mention whether they are the same thing or not. But looking at their function, it looks like they are pretty much the same thing. Can anyone answer whether it is the same thing or not? If not, what is the difference?
Ref:
Docker Docs - Use bind mounts
https://blog.logrocket.com/docker-volumes-vs-bind-mounts/
They are different concepts.
As mentioned in bind mounts:
Bind mounts have been around since the early days of Docker. Bind mounts have limited functionality compared to volumes. When you use a bind mount, a file or directory on the host machine is mounted into a container. The file or directory is referenced by its absolute path on the host machine. By contrast, when you use a volume, a new directory is created within Docker’s storage directory on the host machine, and Docker manages that directory’s contents.
And as mentioned in volumes:
Volumes are the preferred mechanism for persisting data generated by
and used by Docker containers. While bind mounts are dependent on the
directory structure and OS of the host machine, volumes are completely
managed by Docker. Volumes have several advantages over bind mounts:
Volumes are easier to back up or migrate than bind mounts.
You can manage volumes using Docker CLI commands or the Docker API.
Volumes work on both Linux and Windows containers.
Volumes can be more safely shared among multiple containers.
Volume drivers let you store volumes on remote hosts or cloud providers, to encrypt the contents of volumes, or to add other functionality.
New volumes can have their content pre-populated by a container.
Volumes on Docker Desktop have much higher performance than bind mounts from Mac and Windows hosts.
A "bind mount" is when you let your container see and use a normal directory in a normal filesystem on your host. Changes made by programs running in the container will be visible in your host's filesystem.
A "volume" is a single file on your host that acts like a whole filesystem visible to the container. You can't normally see what's inside it from the host.
I was able to figure it out.
There are 3 types of storage in Docker.
1. Bind mounts-also known as host volumes.
2. Anonymous volumes.
3. Named volumes.
So bind mount = host volume. They are the same thing. "Host volume" must be a deprecating term though, as I cannot see it in Docker docs. But it can be seen in various articles published 1-2 years ago.
Examples for where it is referred to as "host volume":
https://docs.drone.io/pipeline/docker/syntax/volumes/host/
https://spin.atomicobject.com/2019/07/11/docker-volumes-explained/
This docs page here Manage data in Docker is quite helpful
Volumes are stored in a part of the host filesystem which is managed by Docker (/var/lib/docker/volumes/ on Linux). Non-Docker processes should not modify this part of the filesystem. Volumes are the best way to persist data in Docker.
Bind mounts may be stored anywhere on the host system. They may even be important system files or directories. Non-Docker processes on the Docker host or a Docker container can modify them at any time.
I have a service or three that needs access to the same SMB share. The service(s) is running inside a Docker container. I think my choices are:
Have the Docker container(s) where the service(s) is running mount the SMB share itself
Have the host of the Docker container(s) mount the SMB share and then share it with the Docker container(s) where the service(s) is running
Which is better from a best practices perspective (which should probably include security as a dimension)?
Am I missing an option?
Thanks!
In standard Docker, you should almost always mount the filesystem on the host and then use a bind mount to attach the mounted filesystem to a container.
Containers can't usually call mount(2), a typical image won't contain smbclient(1) or mount.cifs(8), and safely passing credentials into a container is tricky. It will be much easier to do the mount on the host, and you can use standard images against the mounted filesystem without having to customize them to add site-specific tools.
One way is to mount the SMB shares on the host system as normal, for example if you are on Linux using mount and fstab. Afterwards you can use docker volumes to add the SMB shares, on your host system to your containers as volumes.
Advantages of using docker volumes are explained in the docker documentation.
More information about docker volumes in the docker documentation,
https://docs.docker.com/storage/volumes/
I'm reading a document from Microsoft that states about Docker volumes
Volumes are stored within directories on the host filesystem. Docker
will mount and manage the volumes in the container. Once mounted,
these volumes are isolated from the host machine.
Multiple containers can simultaneously use the same volumes. Volumes
also don't get removed automatically when a container stops using the
volume.
In our example, we can create a directory on our container host and
mount this volume into the container when we create the tracking
portal container. When our tracking portal logs data, we can access
this information via the container host's filesystem. We'll have
access to this log file even if our container is removed.
I'm confused as I understand that the volumes are isolated from the host machine, but how can that be if we can access to the data via the host.
I'm less familiar with Docker on Windows, but I'm sure it's probably the same as Linux in this regard...
Docker volumes are "isolated on the host machine" by being in a particular location with particular permissions on the host's filesystem (i.e. via namespaces). Users/accounts with elevated permissions would still be granted access to those directories/files.
By contrast a bind mount can be made to (pretty much) any directory on the host's file system.
Is it possible to mount Cinder volumes on docker containers in openstack?
And if it is, is there a way to encrypt data leaving the container to the cinder volume?
I was thinking of mounting the volume as a loopback device and encrypt the data as it was being flushed to the disk. Ist this possible?
Kind regards
It is not currently possible to mount Cinder volumes inside a Docker container in OpenStack.
A fundamental problem is that Docker is filesystem-based, rather than block-device-based. Any block device -- like a Cinder volume -- would need to be formatted with a filesystem and mounted prior to starting the container. While it might be technically feasible, the necessary support for this does not yet exist.
The Manila project may be a better solution for adding storage to containers, but I haven't looked into that and I don't know if (a) the project works at all yet and (b) it it works with nova-docker.
If you're not using the nova-docker driver but are instead using the Heat plugin for Docker, you can mount host volumes in a container similar to docker run -v ..., but making this work seamlessly across multiple nodes in a multi-tenant setting may be difficult or impossible.