今天理解了两个用法
docker 和 uid
动机: 部署在docker容器的算法输出的图片总是带有root权限,删除或者后续操作很麻烦。
产生该现象的原因是我在docker run和dockerfile中都未指定user给docker,在此情况下docker会默认使用root用户。这篇文章描述了详细的原因和解决方案。
提炼一些关键点:docker和host通过同一个内核来管理和uid和gid,内核只认识uid和gid,而username和uid之间的映射由外部文件记录(如etc/passwd)。
可在docker run时用–user 指定uid ---- 这样因为容器内找不到1001对应的username,所以在username的位置显示“I have no name!”
marc@server:~$ docker run -d --user 1001 ubuntu:latest sleep infinity
84f436065c90ac5f59a2256e8a27237cf8d7849d18e39e5370c36f9554254e2b
marc@server$ ps aux | grep sleep
marc 17058 0.1 0.0 4380 664 ? Ss 21:23 0:00 sleep infinity
marc@server:~$ docker exec -it 84f43 /bin/bash
I have no name!@84f436065c90:/$
或在dockerfile中指定user和uid:
FROM ubuntu:latest
RUN useradd -r -u 1001 -g appuser appuser
USER appuser
ENTRYPOINT [“sleep”, “infinity”]
marc@server:~$ docker run -d test
8ad0cd43592e6c4314775392fb3149015adc25deb22e5e5ea07203ff53038073
marc@server:~$ ps aux | grep sleep
marc 16507 0.3 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity
marc@server:~$ docker exec -it 8ad0 /bin/bash
appuser@8ad0cd43592e:/$ ps aux | grep sleep
appuser 1 0.0 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity
那么在本地查到sleep的发起者是marc; 而在容器里查到sleep的发起者是appuser。
解决方案就是在docker run或dockerfile中都指定uid给docker。
entrypoint
在构建dockerfile时,CMD如果和ENTRYPOINT一起使用,则会被当成ENTRYPOINT中命令的额外参数。这篇博客提供了一个例子。
如果指定了ENTRYPOINT命令,那么生成容器和重启容器的时候都为默认调用该命令,docker run 所指定的命令会被当做这条命令的额外参数(效果同CMD)。 这时可以用 --entrypoint 来覆盖这条命令。