Docker device-cgroups-rule, mknod and mount - docker

I'm attempting to implement what is described here:
https://docs.docker.com/engine/reference/commandline/create/#dealing-with-dynamically-created-devices---device-cgroup-rule
Similar to the page I am creating (and then starting) a container as follows:
docker create --device-cgroup-rule='b 8:* rmw' -name my-container my-image
Quoting from the above page
Then, a user could ask udev to execute a script that would docker exec
my-container mknod newDevX c 42 the required device when it is
added.
Within the container (docker exec -it my-container sh) I then mknod a device:
mknod /dev/sdc1 b 8 33
The device was reported as above by lsblk:
sdc 8:32 1 500M 0 disk
└─sdc1 8:33 1 500M 0 part
mknod succeeds but mounting /dev/sdc1 gives an error:
$ mount /dev/sdc1 /mnt
mount: /mnt: permission denied.
I also tried various other things like
mknod with -m
docker start with --cap-add=CAP_MKNOD
EDIT:
I also tried starting with --privileged but without the /dev/sdc1 precreated and it worked. It must have something to do with Capabilities or other differences between privileged and non-privileged mode. I tried with --cap-add=CAP_MKNOD and CAP_SYS_ADMIN but it now reports a difference message:
$ mount /dev/sdc1 /mnt
mount: /mnt: cannot mount /dev/sdc1 read-only.

Related

docker mount - Error response from daemon: invalid mount config for type "bind"

I am facing an issue with mounting a host directory into docker container with both -v and --mount options.
Using mount:
docker run --mount type=bind,source=/home/myuser/docker_test/out_dir,target=/home/out_dir --user 12345:1000 -it docker-name:0.1 bash
docker: Error response from daemon: invalid mount config for type "bind": stat /home/myuser/docker_test/out_dir: permission denied.
But I am able to do stat on this directory.
stat /home/myuser/docker_test/out_dir
File: '/home/myuser/docker_test/out_dir'
Size: 4096 Blocks: 8 IO Block: 32768 directory
Device: 33h/51d Inode: 9275022755226025350 Links: 2
Access: (0770/drwxrwx---) Uid: (12345/ myuser) Gid: ( 1000/ hercules)
Access: 2022-12-01 02:12:54.430582000 -0500
Modify: 2022-12-01 02:12:38.239629000 -0500
Change: 2022-12-01 02:12:38.239629000 -0500
Birth: -
Using -v:
docker run -v /home/myuser/docker_test/out_dir:/home/out_dir --user 12345:1000 -it docker-name:0.1:0.1 bash
docker: Error response from daemon: error while creating mount source path '/home/myuser/docker_test/out_dir': mkdir /home/myuser/docker_test: permission denied.
ERRO[0000] error waiting for container: context canceled
I don't know why it's trying to do mkdir but /home/myuser/docker_test already exists and is writable for the current user.
Am I missing something here?
BTW - /home is a NFS mounted directory.
EDIT: mounting /tmp worked. So this means it is related to the NFS mounted directory /home.
EDIT 2
I am working on a network machine where I don’t have root (sudo) access.
The docker service is installed by root user.
/home/myuser/docker_test/out_dir has 700 (rwx------) permissions. If I change the permission to 755, it will work. But I can’t change the directory permissions.
My question is why stat is failing when the user starting the docker has the permissions to access the source directory?
Is the stat being called by the docker executable as some ‘other’ user?
Use:
sudo docker run -v /home/myuser/docker_test/out_dir:/home/out_dir --user 12345:1000 -it docker-name:0.1:0.1 bash

Aerospike Connect to kafka: docker: Error response from daemon: invalid mode: /etc/aerospike-kafka-outbound/aerospike-kafka-outbound.yml

I am trying Aerospike Connect to Kafka.
OS: Windows
I referred https://enterprise.aerospike.com/docs/connect/streaming-from-asdb/installing/from-asdb-to-kafka-installing.html.
I referred: '# With Aerospike 5.0 and later' for deploying on docker
I have these running in docker:
My Windows path for the file: C:/aerospike-kafka-outbound/aerospike-kafka-outbound.yml
C:\Users\Nupur>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1114b8a97406 aerospike/aerospike-kafka-outbound:4.0.0 "/bin/sh -c '/opt/${…" 37 seconds ago Up 29 seconds compassionate_hofstadter
93343be1d481 aerospike/aerospike-tools "wrapper aql -h 172.…" 4 hours ago Up 4 hours dreamy_mendeleev
5f00ee532c4e aerospike/amc "/opt/amc/amc ' -con…" 8 days ago Up 4 hours 0.0.0.0:8081->8081/tcp aerospike-consoles
a81ff04dbd74 aerospike/aerospike-server-enterprise "/usr/bin/tini -r SI…" 8 days ago Up 4 hours 0.0.0.0:3000-3002->3000-3002/tcp aerospike
Error:
C:\Users\Nupur>docker run -p 8080:8080 -v /C:/aerospike-kafka-outbound/aerospike-kafka-outbound.yml:/etc/aerospike-kafka-outbound/aerospike-kafka-outbound.yml aerospike/aerospike-kafka-outbound:4.0.0
docker: Error response from daemon: invalid mode: /etc/aerospike-kafka-outbound/aerospike-kafka-outbound.yml.
See 'docker run --help'.
As for the front slash used in Windows path, on using backslash:
C:\Users\Nupur>docker run -p 8080:8080 -v C:\\aerospike-kafka-outbound\\aerospike-kafka-outbound.yml:/etc/aerospike-kafka-outbound/aerospike-kafka-outbound.yml aerospike/aerospike-kafka-outbound:4.0.0
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: rootfs_linux.go:76: mounting "/run/desktop/mnt/host/c/aerospike-kafka-outbound/aerospike-kafka-outbound.yml" to rootfs at "/etc/aerospike-kafka-outbound/aerospike-kafka-outbound.yml" caused: mount through procfd: 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.
This is my docker directory:
C:\Users\Nupur>docker exec -it 1114b8a97406 bash
root#1114b8a97406:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root#1114b8a97406:/# cd /etc
root#1114b8a97406:/etc# ls
adduser.conf ca-certificates.conf environment host.conf ld.so.cache machine-id pam.conf rc1.d resolv.conf shells timezone
aerospike-kafka-outbound cron.daily fstab hostname ld.so.conf mke2fs.conf pam.d rc2.d rmt skel update-motd.d
alternatives debconf.conf gai.conf hosts ld.so.conf.d motd passwd rc3.d securetty ssl xattr.conf
apt debian_version group init.d libaudit.conf mtab passwd- rc4.d security subgid
bash.bashrc default group- issue localtime nsswitch.conf profile rc5.d selinux subuid
bindresvport.blacklist deluser.conf gshadow issue.net login.defs opt profile.d rc6.d shadow systemd
ca-certificates dpkg gshadow- kernel logrotate.d os-release rc0.d rcS.d shadow- terminfo
root#1114b8a97406:/etc# cd aerospike-kafka-outbound
root#1114b8a97406:/etc/aerospike-kafka-outbound# ls
aerospike-kafka-outbound.yml
root#1114b8a97406:/etc/aerospike-kafka-outbound#

How to specify userid and groupid for volume mount point on Docker host

I have been frustrated by this issue for a while because this has been asked multiple times here, such as in How to deal with persistent storage (e.g. databases) in Docker and What is the (best) way to manage permissions for Docker shared volumes?, but the answers do not address the issue at all.
The first "answer" says to just use named volumes instead of traditional bind mounts. That solves nothing because when the named volume is mounted on the host, for instance at the default location /var/lib/docker/volumes/<volume name>/_data, then that mount point will have the uid/gid of the mount point inside the container.
The other "answer" given, before docker had named volumes, was to use a data-only container. This exhibits the same exact problem.
The reason this is a huge problem for me is that I have many embedded machines on which I want to run the docker host, and the user may have a different uid/gid on each of these. Therefore I cannot hardcode a uid/gid in a Dockerfile for the mount points for my persistent volumes, to achieve matching ids.
Here's an example of the problem: Say my user is foo on the host, with uid 1001 and gid 1001, and the user writing files to the volume inside the container has uid 1002. When I run the container, docker will chown 1002:1002 the mount point dir on the host, and write files with this uid, which I can't even read/write with my user foo.
Visually (all these operations on the host):
$ docker volume create --driver local --opt type=volume --opt device=/home/<my_host_user>/logs --opt o=bind logs
logs
$ docker volume inspect logs
[
{
"CreatedAt": "2020-08-26T16:26:08+01:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/logs/_data",
"Name": "logs",
"Options": {
"device": "/home/<myhostuser>/logs",
"o": "bind",
"type": "volume"
},
"Scope": "local"
}
]
$ pwd
/home/foo
$ mkdir logs && ls -ld logs
drwxr-xr-x 2 foo foo 4096 Aug 26 17:24 logs
Then running the container:
$ docker run --rm --name <cont_name> -it --net="host" --mount src=logs,target=/home/<container_user>/logs <my docker image>
And now the mount point:
$ ls -ld logs
drwxr-xr-x 2 1002 1002 4096 Aug 26 17:30 logs
$ ls -l logs/
total 4
-rw-r----- 1 1002 1002 0 Aug 26 17:30 log
-rw-r----- 1 1002 1002 2967 Aug 26 17:27 log.1
As you can see, the logs written to the volume have a uid/gid which doesn't correspond to something that exists on the host and which I can't access without root/sudo.
Now then, is there ANY way that docker can be told to map uid/gids in the container to uid/gids on the host, or even simpler to just use the specified uid/gid for the host mount point?
my env:
Ubuntu 22.04
Docker version 20.10.17, build 100c701
create mount piont path with suitable permission.
# docker file
RUN mkdir --parents '$volumeDir' ; chown --recursive '$userName':'$userGroup' '$volumeDir'
next, create container and mount volume .
# terminal
docker run --name=containerName --interactive
--user=$userName:$userGroup --mount='source=volumeName,target==$volumeDir,readonly=false'
imageName /bin/bash
you will got suitable permission

How to use loop devices locally in Docker

I want to use loop devices in a docker container locally. It means, when running a couple of container all of them should have for instance a /dev/loop0 connected to a file local in the container. I tried
[root#600bbfb452d1 /]# mknod /dev/loop20 b 7 20
[root#600bbfb452d1 /]# dd if=/dev/random of=loopfile1 bs=1M count=2
[root#600bbfb452d1 /]# losetup -a | grep 20
/dev/loop20: [0049]:3553002 (/loopfile1)
so far so good. But going back to host I can see:
[loewe#linux-2 ~]$ losetup -a | grep 20
/dev/loop20: []: (/loopfile1)
the loop device /dev/loop20 was also created in the hosts /dev - as my fear was because of the tmpfs mount - and worst the container local file "loopfile1" is attached to hosts loop dev.
I tries to umount the /dev filesystem in the container but didn't succeed (device busy but no proc visible with lsof).
Any idea what I am doing wrong?
BTW: using iscsi devices in a container should have the same problem.
Thanks Heiko

Why is File Mounted on Container via docker-compose not Accessible?

In my docker-compose file, I try to mount a file from the host into the docker container.
The docker-compose file I have something like this:
version "2"
services:
myservice:
image: images/previmage:1.0.0
volumes:
- /opt/files/aaa.conf:/aaa.conf
After the service is started, I look at the contents at the root of the container using docker from the host:
sudo docker container exec myservice_1 ls /
The result of that ls command for the aaa.conf entry shows that it looks like it is there, but permissions are not what I expect:
drwxr-xr-x. 2 root root 6 Apr 11 2018 opt
-?????????? ? ? ? ? ? aaa.conf
ls: cannot access /aaa.conf: Permission denied
Similarly, if I try other commands like 'cat aaa.conf', I get Permission denied.
I understand that permissions for the file need to be set on the host side.
On the host I made permissions both 755 and then 777, but I still get Permission denied.
Is this the expected behavior?
Edit [running on AWS/EC2]
sudo docker container exec myservice_1 cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
sudo docker container exec myservice_1 id -u
33016
I had same problem, It's for SELinux (Check this post)
Disable SELinux for a specific container
You can disable SELinux for a specific container by adding --security-opt label:disable to your docker run command:
docker container run --security-opt label:disable myservice_1
Adding SELinux Rule (Recommended)
According to this post, You can also use this command to enable access to the files
chcon -Rt svirt_sandbox_file_t /path/to/volume
Completely disable SELinux!
Not recommended, but also works:
su -c "setenforce 0"

Resources