Dockerfile 指令 功能 三 (ENTRYPOINT)

ENTRYPOINT 的格式和 RUN 指令格式一样,分为 exec 格式 和 shell 格式

ENTRYPOINT 的目的和 CMD 一样,都是在指定的容器启动程序及参数。ENTRYPOINT 在运行时也可以替代,不过比 CMD 要略显繁琐,需要通过 docker run 的参数 --entrypoint 来指定。

当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:

<ENTRYPOINT> "<CMD>"

场景一:让镜像变成像命令一样使用

传参的用途

使用一个公网IP的镜像来得知自己当前的公网IP,那么可以先用 CMD来实现:

FROM ubuntu:18.04
RUN apt-get update
&& apt-get install -y curl
&& rm -rf /var/lib/apt/lists/*
CMD ["curl","-s","http://myip.ipip.net"]

使用docker build 构建镜像

[root@ip-10-1-0-142 ipip]# docker build -t myip:v1 .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM ubuntu:18.04
18.04: Pulling from library/ubuntu
feac53061382: Pull complete
Digest: sha256:7bd7a9ca99f868bf69c4b6212f64f2af8e243f97ba13abb3e641e03a7ceb59e8
Status: Downloaded newer image for ubuntu:18.04
---> 39a8cfeef173
Step 2/3 : RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
---> Running in 35433ebb43d4
Get:1 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]
Get:2 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
Get:3 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
.
.
.
Running hooks in /etc/ca-certificates/update.d...
done.
Removing intermediate container 35433ebb43d4
---> 4d4e2a6ea83b
Step 3/3 : CMD [ "curl", "-s", "http://myip.ipip.net" ]
---> Running in 30a3a5f2f303
Removing intermediate container 30a3a5f2f303
---> 2c191ad0c4c5
Successfully built 2c191ad0c4c5
Successfully tagged myip:v1

运行myip

[root@ip-10-1-0-142 ipip]# docker run myip
当前 IP:52.215.213.34 来自于:爱尔兰 都柏林郡 都柏林 amazon.com

嗯,这么看起来好像可以直接把镜像当做命令使用了,不过命令总有参数,如果我们希望加参数呢?比如从上面的 CMD 中可以看到实质的命令是 curl,那么如果我们希望显示 HTTP 头信息,就需要加上 -i 参数。那么我们可以直接加 -i 参数给 docker run myip 么?

[root@ip-10-1-0-142 ipip]# docker run myip -i
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-i": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled

我们可以看到可执行文件找不到的报错,executable file not found。之前我们说过,跟在镜像名后面的是 command,运行时会替换 CMD 的默认值。因此这里的 -i 替换了原来的 CMD,而不是添加在原来的 curl -s http://myip.ipip.net 后面。而 -i 根本不是命令,所以自然找不到。

那么如果我们希望加入 -i 这参数,我们就必须重新完整的输入这个命令:

[root@ip-10-1-0-142 ipip]# docker run myip curl -s http://myip.ipip.net -i
HTTP/1.1 200 OK
Date: Mon, 02 Aug 2021 11:00:28 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 84
Connection: keep-alive
CF-Cache-Status: DYNAMIC
Report-To: {"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v3?s=RUCd8%2BCdlxsaLUf44f7INb92ZCnaIYiD4X2GYbLNyXJTiKg%2BOsAfEp3bPXOnfJrfRFnNDfyAP9p058HJ06wjUpA44ezop7eQEpLUBq37DiBP4GXI2YMaAt%2FkO%2Fz7Xx0%3D"}],"group":"cf-nel","max_age":604800}
NEL: {"report_to":"cf-nel","max_age":604800}
Server: cloudflare
CF-RAY: 6786cd23feed1e89-AMS

当前 IP:52.215.213.34 来自于:爱尔兰 都柏林郡 都柏林 amazon.com

我们尝试使用 ENTRYPOINT 解决这个问题,使用 ENTRYPOINT 更新 Dockerfile 文件

FROM ubuntu:18.04
RUN apt-get update
&& apt-get install -y curl
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT [ "curl", "-s", "http://myip.ipip.net" ]

直接使用 docker run myipe 查看输出结果,

[root@ip-10-1-0-142 ipip]# docker run myipe
当前 IP:52.215.213.34 来自于:爱尔兰 都柏林郡 都柏林 amazon.com

这次我们再来尝试直接使用 docker run myip -i:

[root@ip-10-1-0-142 ipip]# docker run myipe -i
HTTP/1.1 200 OK
Date: Mon, 02 Aug 2021 11:04:59 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 84
Connection: keep-alive
CF-Cache-Status: DYNAMIC
Report-To: {"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v3?s=K2An7ZP3qbdYTYdDYzojNsNZSi2jbEPs8N%2BQ7pwalGsr6kYLF9RE2ZSU2l%2FekmmBabeN9h%2FqBSwXZ2SuW%2F9RPbSx76YnYUtOAkSFGeC1CXEu6GyUWuRM7sB4Z%2BCyG4I%3D"}],"group":"cf-nel","max_age":604800}
NEL: {"report_to":"cf-nel","max_age":604800}
Server: cloudflare
CF-RAY: 6786d416eaab53ec-LHR

当前 IP:52.215.213.34 来自于:爱尔兰 都柏林郡 都柏林 amazon.com

运行 docker run myipe -i 执行成功。是因为当 ENTRYPOINT 后,CMD 的内容被作为参数传给 ENTRYPOINT,而这里 -i 就是新的 CMD,因此会作为参数传给 curl,从而达到想要的结果,可以查看到HTTP 头的信息。

场景二 应用运行前的准备工作

启动容器就是启动主进程,有些时候需要在启动主进程前做一些准备工作。

比如mysql的数据库,需要做数据库的配置、初始化等,这些动作需要在启动mysql 服务之前准备好。

另外,避免使用root用户去启动服务,从提高安全性来讲,在启动前需要使用root做一些准备工作,然后在使用普通服务用户去启动服务。

这些准备工作和容器 CMD 无关,无论 CMD 为什么指令,都需要预先做一个预处理的工作。
使用脚本,然后利用 ENTRYPOINT 传参执行,脚本会接到参数作为命令,在脚本最后执行。
官方镜像 redis 是这么做的:

[root@ip-10-1-0-142 redis]# tree
.
├── docker-entrypoint.sh
└── redis-server

0 directories, 2 files

FROM alpine:3.4
RUN addgroup -S redis && adduser -S -G redis redis
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 6379
CMD [ "redis-server" ]

可以看到其中为 redis 服务创建 redis 用户,并在最后指定了 ENTRYPOINT 为 docker-entrypoint.sh 脚本。

!/bin/sh

# allow the container to be started with --user
if [ "1" = 'redis-server' -a "(id -u)" = '0' ]; then
find . ! -user redis -exec chown redis '{}' +
exec gosu redis "0" "@"
fi

exec "$@"

该脚本的内容就是根据 CMD 的内容来判断,如果是 redis-server ,则切换到 redis 用户身份启动服务器,否则依旧使用 root 身份执行。比如,
$ docker run -it redis id
uid=0(root) gid=0(root) groups=0(root)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容