docker entrypoint入口文件詳解
在編寫(xiě)Dockerfile的時(shí)候,包含一個(gè)entrypoint配置,該配置的作用是在容器啟動(dòng)之前做一些初始化配置,或者一些自定義的配置等。通常是一個(gè)腳本,然后在腳本里配置相關(guān)預(yù)定義項(xiàng)。這篇文檔就詳細(xì)說(shuō)一說(shuō)entrypoint入口文件的編寫(xiě)技巧。
下面以mysql官方鏡像中的entrypoint文件docker-entrypoint.sh為例,文件地址為:
set -e
你寫(xiě)的每個(gè)腳本都應(yīng)該在文件開(kāi)頭加上set -e, 這句語(yǔ)句告訴bash如果任何語(yǔ)句的執(zhí)行結(jié)果不是true則應(yīng)該退出. 這樣的好處是防止錯(cuò)誤像滾雪球般變大導(dǎo)致一個(gè)致命的錯(cuò)誤, 而這些錯(cuò)誤本應(yīng)該在之前就被處理掉. 如果要增加可讀性, 可以使用set -o errexit, 它的作用與set -e相同
set -o pipefail
設(shè)計(jì)用途同上, 就是希望在執(zhí)行錯(cuò)誤之后立即退出, 不要再向下執(zhí)行了. 而 -o pipefail 的作用域是管道, 也就是說(shuō)在 Linux 腳本中的管道, 如果前面的命令執(zhí)行出了問(wèn)題, 應(yīng)該立即退出
shopt -s nullglob
在使用 Linux 中的通配符時(shí) * ?等 如果沒(méi)有匹配到任何文件, 不會(huì)報(bào) No such file or directory 而是將命令后面的參數(shù)去掉執(zhí)行
if [ "${1:0:1}" = '-' ]; then...
這是一個(gè)判斷語(yǔ)句, 在官方文件中, 上一行已經(jīng)給出了注釋: if command starts with an option, prepend mysqld
這個(gè)判斷語(yǔ)句是 ${1:0:1}
意思是判斷 $1
(調(diào)用該腳本的第一個(gè)參數(shù)), 偏移量0(不偏移), 取一個(gè)字符(取字符串的長(zhǎng)度)
如果判斷出來(lái)調(diào)用這個(gè)腳本后面所跟的參數(shù)第一個(gè)字符是-中橫線(xiàn)的話(huà), 就認(rèn)為后面的所有字符串都是 mysqld 的啟動(dòng)參數(shù)
上面的這個(gè)操作類(lèi)似于 Python 的字符串切片
set -- mysqld "$@"
在上面判斷完第一個(gè)參數(shù)是-開(kāi)頭之后, 緊接著就執(zhí)行了 set -- mysqld "$@" 這個(gè)命令. 使用了 set -- 的用法. set --會(huì)將他后面所有以空格區(qū)分的字符串, 按順序分別存儲(chǔ)到$1, $2, $3 變量中, 其中新的$@為set --后面的全部?jī)?nèi)容
舉例來(lái)說(shuō): bash docker-entrypoint.sh -f xxx.conf
在這種情況下, set -- mysqld "$@"
中的 $@ 的值為 -f xxx.conf
當(dāng)執(zhí)行完 set -- mysqld "$@" 這條命令后:
- $1=mysqld
- $2=-f
- $3=xxx.conf
- $@=mysqld -f xxx.conf
可以看到, 當(dāng)執(zhí)行 docker-entrypoint.sh腳本的時(shí)候后面加了 -x形式的參數(shù)之后, $@的值發(fā)生的改變, 在原有$@值的基礎(chǔ)之上, 在前面又預(yù)添加了 mysqld 命令
exec "$@"
幾乎在每個(gè)docker-entrypoint.sh腳本的最后一行, 執(zhí)行的都是 exec "$@"命令
這個(gè)命令的意義在于你已經(jīng)為你的鏡像預(yù)想到了應(yīng)該有的調(diào)用情況, 當(dāng)實(shí)際使用鏡像的人執(zhí)行了你沒(méi)有預(yù)料到的可執(zhí)行命令時(shí), 將會(huì)走到腳本的這最后一行, 去執(zhí)行用戶(hù)新的可執(zhí)行命令
情況判斷
上面直接說(shuō)了腳本的最后一行, 在之前的腳本中, 需要充分的去考慮你自己的腳本可能會(huì)被調(diào)用的情況. 還是拿 MySQL 官方的 dockerfile 來(lái)說(shuō), 他判斷以下情況:
- 開(kāi)頭是 - , 認(rèn)為是參數(shù)的情況
- 開(kāi)頭是 mysqld, 且用戶(hù) id 為0 (root 用戶(hù)) 的情況
- 開(kāi)頭是 mysqld 的情況
- 判斷完自己應(yīng)用的所有調(diào)用形態(tài)之后, 最后應(yīng)該加上exec "$@" 命令兜底
${mysql[@]}
Shell 中的數(shù)組, 直接執(zhí)行 ${mysql[@]} 會(huì)把這個(gè)數(shù)組當(dāng)做可執(zhí)行程序來(lái)執(zhí)行
mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" ) echo ${mysql[1]} -- output: mysql echo ${mysql[2]} --output: --protocol=socket echo ${mysql[3]} --output: -uroot echo ${mysql[4]} --output: -hlocalhost echo ${mysql[@]} --output: mysql --protocol=socket -uroot -hlocalhost --socket=
exec gosu mysql "$BASH_SOURCE" "$@"
這里的 gosu 命令, 是 Linux 中 sudo 命令的輕量級(jí)”替代品”
gosu 是一個(gè) golang 語(yǔ)言開(kāi)發(fā)的工具, 用來(lái)取代 shell 中的 sudo 命令. su 和 sudo 命令有一些缺陷, 主要是會(huì)引起不確定的 TTY, 對(duì)信號(hào)量的轉(zhuǎn)發(fā)也存在問(wèn)題. 如果僅僅為了使用特定的用戶(hù)運(yùn)行程序, 使用 su 或 sudo 顯得太重了, 為此 gosu 應(yīng)運(yùn)而生.
gosu 直接借用了 libcontainer 在容器中啟動(dòng)應(yīng)用程序的原理, 使用 /etc/passwd 處理應(yīng)用程序. gosu 首先找出指定的用戶(hù)或用戶(hù)組, 然后切換到該用戶(hù)或用戶(hù)組. 接下來(lái), 使用 exec 啟動(dòng)應(yīng)用程序. 到此為止, gosu 完成了它的工作, 不會(huì)參與到應(yīng)用程序后面的聲明周期中. 使用這種方式避免了 gosu 處理 TTY 和轉(zhuǎn)發(fā)信號(hào)量的問(wèn)題, 把這兩個(gè)工作直接交給了應(yīng)用程序去完成
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
docker環(huán)境下安裝jenkins容器的詳細(xì)教程
這篇文章主要介紹了docker環(huán)境下安裝jenkins容器的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05使用Docker?Compose搭建部署ElasticSearch的配置過(guò)程
Elasticsearch使用的是一種名為倒排索引的數(shù)據(jù)結(jié)構(gòu),這一結(jié)構(gòu)的設(shè)計(jì)可以允許十分快速地進(jìn)行全文本搜索,本文重點(diǎn)給大家介紹使用Docker?Compose搭建部署ElasticSearch的配置過(guò)程,感興趣的朋友一起看看吧2022-02-02Docker部署MinIO對(duì)象存儲(chǔ)服務(wù)器結(jié)合Cpolar實(shí)現(xiàn)遠(yuǎn)程訪(fǎng)問(wèn)的操作方法
MinIO是一個(gè)開(kāi)源的軟件,可以免費(fèi)使用,還可以在普通硬件上運(yùn)行,降低了存儲(chǔ)成本,本文介紹在本地Docker中部署MinIO服務(wù),并實(shí)現(xiàn)遠(yuǎn)程訪(fǎng)問(wèn)管理界面,節(jié)約云服務(wù)器運(yùn)行成本,感興趣的朋友一起看看吧2023-12-12詳解Docker數(shù)據(jù)管理(數(shù)據(jù)卷&數(shù)據(jù)卷容器)
容器中管理數(shù)據(jù)主要有兩種方式,這篇文章主要介紹了詳解Docker數(shù)據(jù)管理(數(shù)據(jù)卷&數(shù)據(jù)卷容器) ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10docker搭建dnsmasq服務(wù)的實(shí)現(xiàn)
本文將指導(dǎo)讀者如何使用Docker搭建DNSmasq服務(wù),通過(guò)簡(jiǎn)單的步驟和詳細(xì)的說(shuō)明,幫助讀者快速在Docker環(huán)境中部署DNSmasq,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01