需求
实验室本来是给所有用户都开启了sudo使用docker
的权限。
出现了一些问题:
实操
在gpu2上有个nas挂载目录,只有csuoss目录组才有权限。而root不是该用户组的。
默认root用户运行命令。(注意,待挂载的目录必须是个空目录/data/DataLACP/mysql_b
)
1
|
sudo docker run --rm --name=mysql_lxy -v /data/DataLACP/mysql_b:/var/lib/mysql/data -it -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql /bin/bash
|
新建脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#!/bin/bash
# 设置变量
NEW_USER="mysql"
NEW_UID="212047"
NEW_GROUP="csuoss"
NEW_GID="212000"
# 创建新组
groupadd -g $NEW_GID $NEW_GROUP
# 创建新用户
useradd -u $NEW_UID -g $NEW_GID -G $NEW_GROUP $NEW_USER
|
sqlserver实操
- 还是用docker运行该容器
- 但是将该容器内所有用户都加入某个具备该权限的用户组,本文是csuoss。
- 然后就会发现可以读取了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
# docker 启动命令
docker run --name=sqlserver -it \
-e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=8580555@Mf' -e 'MSSQL_PID=Enterprise' \
--net host \
-p 1433:1433 \
-v /data/DataLACP/mssql_data:/var/opt/mssql \
-d mcr.microsoft.com/mssql/server bash
# 将所有用户都加入某个用户组(注意,其中某些用户只有root才能执行,请在docker中先用root登录)
NEW_GROUP="csuoss"
NEW_GID="212000"
# 创建新组
groupadd -g $NEW_GID $NEW_GROUP
#!/bin/bash
groupadd -g 212000 csuoss
# 将所有用户添加到csuoss组
for user in $(getent passwd | cut -f1 -d:); do
#echo $user
usermod -a -G csuoss $user
done
|
查看某个组的用户(但是这个命令获取的所有用户并不全)
注意:
修改用户分组前要保证
- 用户不能正在登录:如果要修改的用户当前正在登录系统,则无法直接更改其用户组。在修改用户组之前,请确保用户已注销或关闭所有与其相关的会话。
- 用户不能正在运行进程:如果用户有正在运行的进程,则无法直接修改其用户组。这可能是由于用户正在运行某些服务或应用程序。首先结束用户的所有进程,然后再尝试修改其用户组。
linux修改用户所属于的组后,不会立刻生效。
- 要么退出当前会话重新登录
- docker的话可以直接重新运行容器
- su - $USER : 使用这个命令重新开始一个 session , 并重新继承当前环境。
坑
对于挂载的特定用户组才能访问的nas目录,很奇怪。当即使我们刷新了用户权限后,如下:
1
2
|
root@gpu2-labot:/var/opt# id
uid=0(root) gid=0(root) groups=0(root),999(mssql),212000(csuoss)
|
对于root用户而言仍然是不可以访问的。
但是对于其他非root用户,mssql或者其他用户自建的用户则都可以访问。
启动server
1
|
/opt/mssql/bin/sqlserver
|
初始化
1
|
/opt/mssql/bin/mssql-conf setup
|
程序启动命令
1
|
(/opt/mssql/bin/sqlservr --accept-eula & ) | grep -q "Service Broker manager has started" && /opt/mssql-tools/bin/sqlcmd -S127.0.0.1 -Usa -P8580555@Mf -i filldata.sql
|
进入cli工具
1
|
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "8580555@Mf"
|
Tdengine:2.4.0.7
1
|
docker pull tdengine/tdengine:2.4.0.7
|
1
2
|
sudo docker run --rm -it --name tdengine_1 -v /data/DataLACP/td_data:/tmp1 \
-p 6030:6030 -p 6035:6035 -p 6041:6041 -p 6030-6040:6030-6040/udp tdengine/tdengine:2.4.0.7 bash
|
如何用docker进行用户管理
在网上查到了一个解决方案。能够有效进行docker用户的资源监控。
另一个作者原理
由于docker容器创建时并不会记录创建者的信息,所以没法锁定已经创建的容器的所有者,因此需要设法在容器创建时将容器创建者的信息记录下来。我的方法是在容器创建时给容器定义一个特殊的环境变量,并将创建者的宿主机用户名字符串设置到这个容器中的环境变量中。
1
|
docker run -itd -e CONTAINER_CREATED_USER=$(whoami) ubuntu /bin/bash
|
通过 docker inspect <container-name>
指令可以获取容器内的环境变量,由此,通过docker容器名获得容器创建者的用户名。
docker top aux
指令可以通过容器名获取容器内的进程信息,由此可以判断出进程的创建者。
结合以上指令,只需要让写一个类似top的资源管理器,将其中的user信息显示为进程所属容器的创建者名。为了方便开发,我直接使用在ctop的基础上修改。
个人思路
1 将所有csuoss组的用户都加入docker用户组
另一种方式
1
2
3
4
5
|
csuoss_gid=212000
for user in $(getent passwd | grep $csuoss_gid | cut -f1 -d:); do
echo $user
usermod -a -G docker $user
done
|
因为用户执行docker的方式不能通过sudo。否则会读取不到当前用户的环境变量。因此,只能将所有用户都加入到docker用户组
获取该容器的用户属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#!/bin/bash
get_container_env_vars() {
container_id="$1"
# 输入待处理字符串
str=$(sudo docker inspect --format='{{range $k, $v := .Config.Env}}{{$v}} {{end}}' "$container_id")
# 定义一个关联数组
declare -A my_dict
# 分割字符串并获取键值对
for pair in $str; do
key=$(echo "$pair" | cut -d'=' -f1)
value=$(echo "$pair" | cut -d'=' -f2)
my_dict[$key]=$value
done
# 输出结果
echo "目标容器的env:"
for key in "${!my_dict[@]}"; do
echo "$key: ${my_dict[$key]}"
done
# 查看指定属性的变量
echo ""
echo "目标容器的运行用户为:"
echo ${my_dict["CONTAINER_CREATED_USER"]}
}
# 使用示例:find_container_user.sh -c container_id
if [ "$1" == "-c" ]; then
container_id="$2"
get_container_env_vars "$container_id"
fi
|
使用
1
2
3
|
find_container_user.sh -c 容器id
alias find_container_user=\"/home/labot/lib/find_container_user.sh\"
|
查找给定PID所属Docker容器的脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#!/bin/bash
get_container_id() {
while getopts "p:" opt; do
case $opt in
p) pid=$OPTARG ;;
\?) echo "Invalid option: -$OPTARG" >&2; exit 1 ;;
esac
done
if [ -z "$pid" ]; then
echo "请使用 -p 参数指定进程的 PID"
exit 1
fi
# 使用 cgroup 查找 PID 所属的容器 ID
container_ids=$(awk -F/ '$2 == "docker"{ print $(NF-0) }' /proc/"$pid"/cgroup | sort -u)
# 输出结果
if [ -z "$container_ids" ]; then
echo "该进程没有在任何 Docker 容器中运行!"
else
echo "该进程所属的 Docker 容器 ID 为:$container_ids"
fi
}
# 使用示例:find_container_id.sh -p pid
get_container_id "$@"
|
使用
1
|
$ ./find_container.sh -p 12345
|
覆盖原有的docker命令
新的docker命令脚本
1
2
3
4
5
6
7
8
9
10
|
#!/bin/bash
docker_command=docker
ctop_command=ctop
if [ $1 == "run" ]
then
$docker_command run -e CONTAINER_CREATED_USER=$(whoami) ${@:2}
else
$docker_command $@
fi
|
别名,要对所有用户生效,加入/etc/profile
1
|
echo "alias docker=\"docker_wrapper.sh\"" >> /etc/bash.bashrc
|
然后每隔几秒检查一下,更新所有csuoss用户组的用户到docker用户组。
最后使用方式是,普通1用户登录后可以直接使用docker命令,无需root。
docker cuda
Ubuntu 22.10 安装:
1
2
3
|
distribution=ubuntu22.04 && \
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg && \
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
|
命令执行完毕之后,我们的系统中就添加好了 Lib Nvidia Container 工具的软件源啦,然后更新系统软件列表,使用命令安装 nvidia-container-toolkit
即可:
1
|
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
|
完成 nvidia-container-toolkit
的安装之后,我们继续执行 nvidia-ctk runtime configure
命令,为 Docker 添加 nvidia
这个运行时。完成后,我们的应用就能在容器中使用显卡资源了:
1
|
sudo nvidia-ctk runtime configure --runtime=docker
|
命令执行成功,我们将看到类似下面的日志输出:
1
2
3
4
5
6
7
8
|
# sudo nvidia-ctk runtime configure --runtime=docker
INFO[0000] Loading docker config from /etc/docker/daemon.json
INFO[0000] Successfully loaded config
INFO[0000] Flushing docker config to /etc/docker/daemon.json
INFO[0000] Successfully flushed config
INFO[0000] Wrote updated config to /etc/docker/daemon.json
INFO[0000] It is recommended that the docker daemon be restarted.
|
在完成配置之后,别忘记重启 docker 服务,让配置生效:
1
|
sudo systemctl restart docker
|
服务重启完毕,我们查看 Docker 运行时列表,能够看到 nvidia
已经生效啦。
1
2
3
|
# docker info | grep Runtimes
Runtimes: nvidia runc io.containerd.runc.v2
|
测试
1
2
3
4
|
git clone https://github.com/wilicc/gpu-burn
cd gpu-burn
docker build -t gpu_burn .
docker run --rm --gpus all gpu_burn
|
ref
Docker多用户资源监控解决方案