前一陣子在公司的內(nèi)網(wǎng)機(jī)器上創(chuàng)建鏡像万俗,php 的項(xiàng)目鏡像一直無法創(chuàng)建成功词疼,總是卡在安裝 php 擴(kuò)展時(shí)的那一層命令,提示的是在對擴(kuò)展進(jìn)行編譯時(shí)沒有權(quán)限废境,錯(cuò)誤就是下邊圖上的提示畜挨。
這個(gè)時(shí)候開啟了漫長的排錯(cuò)過程。首先既然提示權(quán)限不足了噩凹,先切了 root 再說巴元,換成 root 執(zhí)行依然報(bào)這個(gè)問題,排除賬號權(quán)限問題驮宴。
再對比其他鏡像 nginx逮刨、redis、mysql 鏡像能夠正常創(chuàng)建堵泽,排除 docker 服務(wù)出現(xiàn)問題修己。這個(gè)時(shí)候已經(jīng)陷入了僵局,明明本地能創(chuàng)建成功的迎罗,為什么換個(gè)機(jī)器不行了睬愤。
收拾下糟糕的心情,繼續(xù)排錯(cuò)纹安,既然我的本地能創(chuàng)建成功尤辱,首先能確定是 Dockerfile 文件是沒有問題砂豌,配置也是正確的,那就看下內(nèi)網(wǎng)的機(jī)器 Docker 的版本光督,果然版本存在差異阳距,內(nèi)網(wǎng)的為19,本地的是24版本结借,差比較多了娄涩,但是想著版本不對和權(quán)限有什么關(guān)系,果斷跳過這個(gè)差異點(diǎn)映跟。
再次回到錯(cuò)誤的原點(diǎn)蓄拣,既然是構(gòu)建鏡像時(shí)那一層的錯(cuò)誤,那我先去掉那層擴(kuò)展的構(gòu)建試試努隙,果然去掉后是正常的球恤,這就更加詭異了,php 的擴(kuò)展方式是按照官方鏡像教程做的荸镊,沒道理會報(bào)錯(cuò)咽斧,接著就想著容器既然已經(jīng)創(chuàng)建了,就進(jìn)入容器內(nèi)執(zhí)行安裝擴(kuò)展試試躬存,該死的容器內(nèi)執(zhí)行命令還是提示無權(quán)限张惹。
嘗試問了同事、GPT都無解岭洲,已經(jīng)逐漸紅溫走向了暴躁宛逗。
最后其實(shí)還有一張牌問 google,我描述了一下自己碰到的問題盾剩,在 github 上找到了答案雷激,問題的根本還是 docker 的版本過低,至于解迷的過程如下:
我所使用的 Dockerfile 鏡像構(gòu)建中告私,php 的構(gòu)建層為 FROM php:8.2.17-fpm-alpine3.18屎暇,問題就出在了 alpine3.18 這個(gè) linux 鏡像上,原來 alpine3.14 發(fā)布后更新了一個(gè)叫做 faccessat2 的系統(tǒng)調(diào)度驻粟,這個(gè)就是專門負(fù)責(zé)系統(tǒng)上的文件權(quán)限檢測的根悼,并且更新文檔說明了低于 docker 20的版本會有問題,至此鏡像無法構(gòu)建的問題算是徹底破案了蜀撑!
解決方法
1挤巡、升級 docker ,這個(gè)最是簡單粗暴屯掖,但是如果是線上環(huán)境或是多人共享主機(jī)的情況下慎用
2玄柏、修改 docker 后臺運(yùn)行配置,強(qiáng)制指定文件權(quán)限檢測不使用 faccessat2 的系統(tǒng)調(diào)度贴铜。首先下載 docker 的默認(rèn)配置文件,是一個(gè)json文件 https://github.com/moby/moby/blob/master/profiles/seccomp/default.json,下載完成后修改第一行配置 defaultAction 绍坝,將 SCMP_ACT_ERRNO 改為 SCMP_ACT_TRACE徘意,然后建議把文件放到 docker 配置目錄下 /etc/docker,
配置文件準(zhǔn)備好了轩褐,接下來 docker 需要先停止后臺服務(wù)椎咧,在啟動 docker 指定參數(shù),其中參數(shù)中的文件路徑為剛才配置文件的絕對路徑
dockerd --seccomp-profile=/etc/docker/default.json &
3把介、在 docker run 時(shí)修改默認(rèn)的配置勤讽,沒試過,只能甩個(gè)官方的鏈接
https://docs.docker.com/engine/security/seccomp/