成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

sudo or gosu

luckyyulin / 2556人閱讀

摘要:所謂的,正如其名,就是該鏡像的根命令。個(gè)人認(rèn)為,跟第二大不同,在于是對使用者鑒權(quán),而是對目標(biāo)權(quán)限進(jìn)行鑒權(quán)。即使遇到了這樣默認(rèn)行為是終止進(jìn)程的信號(hào),也不會(huì)直接終止,而會(huì)轉(zhuǎn)發(fā)出去。但是,和兩個(gè)信號(hào)是無法捕獲的,對此也無能為力。

太長不看:如果需要在Dockerfile的ENTRYPONNT中指定運(yùn)行命令的用戶,用gosu代替sudo可以避免某些信號(hào)處理上的邊界條件。不過這些邊界條件比較罕見,就算不用也沒多大關(guān)系

docker官方文檔的Dockerfile部分,有一節(jié)講的是ENTRYPOINT。在這一節(jié)中,提到了如果在啟動(dòng)腳本中需要指定運(yùn)行命令的用戶,建議用gosu代替sudo,并給出了一個(gè)例子:

#!/bin/bash
set -e

if [ "$1" = "postgres" ]; then
    chown -R postgres "$PGDATA"

    if [ -z "$(ls -A "$PGDATA")" ]; then
        gosu postgres initdb
    fi

    exec gosu postgres "$@"
fi

exec "$@"

上面的腳本中,docker run指定的命令會(huì)以postgres用戶的身份執(zhí)行。

所謂的ENTRYPOINT,正如其名,就是該鏡像的根命令。默認(rèn)的ENTRYPOINT為/bin/sh -c,通過docker runCMD指定的命令會(huì)作為ENTRYPOINT的參數(shù)執(zhí)行。舉個(gè)例子,docker run ubuntu:latest ls就是執(zhí)行/bin/sh -c ls。有些時(shí)候我們需要指定ENTRYPOINT的值,比如換成自己的包裝腳本。

默認(rèn)docker中的命令都是以root身份啟動(dòng)的(因?yàn)槟J(rèn)只有root用戶)。不過你也可以通過USER指令設(shè)置當(dāng)前使用的用戶。某些時(shí)候,你可能需要在docker build中使用多個(gè)用戶,比如上面例子中,安裝依賴需要root,運(yùn)行程序時(shí)使用的是postgres。這時(shí)候就需要?jiǎng)討B(tài)指定一個(gè)用戶身份。

docker文檔中建議,如果需要?jiǎng)討B(tài)指定一個(gè)用戶身份,需要使用gosu而非平常的sudo

然而文檔中并沒有解釋為什么。gosu的項(xiàng)目主頁中也只提到gosu避免了strange and often annoying TTY and signal-forwarding behavior。(然后順便黑了下sudo太過于復(fù)雜)。不過gosu的測試用例透露了些蛛絲馬跡,可以看出它認(rèn)為sudo至少有兩點(diǎn)不好:

sudo會(huì)作為被授權(quán)的命令的父進(jìn)程一直存在,直到該命令退出。

sudo模式下的HOME環(huán)境變量仍是用sudo者原來的值。

可以實(shí)證下這兩個(gè)指責(zé):

~ sudo ps -o pid,ppid,cmd
  PID  PPID CMD
12599  4281 sudo ps -o pid,ppid,cmd
12600 12599 ps -o pid,ppid,cmd
~ sudo env | grep HOME
HOME=/home/lzx

這兩個(gè)現(xiàn)象確實(shí)存在,不過會(huì)造成什么危害呢?如果真有鬼,夜路走多了自然會(huì)碰見。然而平時(shí)都是用著sudo,也沒遇到什么事呀。

我們先來看看第二點(diǎn),sudo模式下HOME環(huán)境變量保存不變的事情。

這個(gè)事情涉及到sudo的應(yīng)用場景。sudo用于扮演某個(gè)用戶來執(zhí)行給定的命令,這一點(diǎn)類似于su。個(gè)人認(rèn)為,sudosu第二大不同,在于sudo是對使用者鑒權(quán),而su是對目標(biāo)權(quán)限進(jìn)行鑒權(quán)。假定你是sudoer,運(yùn)行sudo時(shí)你要輸入自己的密碼,也即證明自己有扮演的權(quán)限;而運(yùn)行su時(shí),你要輸入的是要扮演的用戶的密碼,也即證明你有扮演的那個(gè)用戶的權(quán)限。所以sudo會(huì)認(rèn)為,那你使用sudo只是想臨時(shí)使用某一身份。既然如此,sudo下HOME環(huán)境變量還是原來的樣子,也不是什么bug,而是個(gè)feature。如果你不認(rèn)同這個(gè)feature,可以使用sudo -H

再來看看第一點(diǎn),sudo作為命令的父進(jìn)程會(huì)一直存在。sudo之所以退而不休,是因?yàn)樗枰O(jiān)控命令的輸入輸出。作為一個(gè)非常關(guān)注安全性的程序,sudo會(huì)重置自己的環(huán)境變量,盡量以干凈的環(huán)境來執(zhí)行命令。不止如此,它還允許用戶定義安全策略,來處理命令的輸入輸出。不過有種情況下,sudo會(huì)直接exec給定的命令。那就是當(dāng)用戶沒有指定安全策略,且執(zhí)行的命令不需要占用偽終端的時(shí)候。舉個(gè)例子,sudo sh -c "sleep 20 &"時(shí),sudo就真的不再作為父進(jìn)程一直存在了(注意這里我用了個(gè)sh來分割整條命令.如果直接輸入sudo sleep 20 &,會(huì)被解析成后臺(tái)運(yùn)行sudo sleep 20)。不過這種情況非常特殊,基本上可以忽略。這一點(diǎn)跟上面那條不同,不存在一個(gè)改變該默認(rèn)行為的選項(xiàng)。

看來所謂的“annoying behavior”就是指這個(gè)了。不過平時(shí)用的時(shí)候從沒考慮過這個(gè)呀,為什么到了docker里就不建議用呢?
原因在于docker中處理signal的方式。很多程序,比如Apache和Nginx,允許用戶通過發(fā)信號(hào)的方式來控制程序的生命周期(重啟、關(guān)閉、停止,等等)。由于docker把進(jìn)程封裝了一層,如果想要給這些程序發(fā)信號(hào),直接發(fā)給docker進(jìn)程是不行的。那只會(huì)影響docker本身的行為。而且這些程序在docker里面運(yùn)行時(shí),不可能意識(shí)到自己在一個(gè)獨(dú)立的容器里。它們所報(bào)告的pid,跟外界的pid是不符合的。
為了跟UNIX的信號(hào)機(jī)制和諧相處,docker另外提供了發(fā)送信號(hào)的接口:docker stopdocker kill。docker stop會(huì)發(fā)兩撥信號(hào),一個(gè)是SIGTERM,另一個(gè)是SIGKILL。而docker kill則是kill的翻版。這兩個(gè)命令有個(gè)奇怪的地方,就是它們發(fā)送信號(hào),從來都只發(fā)給所謂的main process進(jìn)程,也即ENTRYPOINT進(jìn)程。如果該進(jìn)程不會(huì)轉(zhuǎn)發(fā)信號(hào)(比如默認(rèn)的/bin/sh -c),目標(biāo)進(jìn)程就收不到信號(hào),這個(gè)功能便廢了。而當(dāng)我們用sudo啟動(dòng)某個(gè)命令時(shí),最終收到信號(hào)的會(huì)是sudo進(jìn)程,而不是那個(gè)命令。

那么sudo是否會(huì)轉(zhuǎn)發(fā)信號(hào)?答案是,如果可以的話,sudo會(huì)盡可能地轉(zhuǎn)發(fā)信號(hào)。即使遇到了SIGTERM這樣默認(rèn)行為是終止進(jìn)程的信號(hào),sudo也不會(huì)直接終止,而會(huì)轉(zhuǎn)發(fā)出去。所以盡管多了個(gè)sudo攔在路上,大多數(shù)情況下,想要發(fā)送給目標(biāo)進(jìn)程的信號(hào)還是能到達(dá)的。但是,SIGSTOPSIGKILL兩個(gè)信號(hào)是無法捕獲的,sudo對此也無能為力。SIGKILL的話情況還好,因?yàn)閙ain process進(jìn)程(這里的sudo)退出后,整個(gè)docker進(jìn)程都會(huì)退出,無意中也達(dá)到了一樣的結(jié)果。不過SIGSTOP只會(huì)讓sudo停下來,結(jié)果該停的沒停,不該停的卻停了。

gosu的實(shí)現(xiàn)很簡單。它包括以下幾個(gè)步驟:

setgroup

setuid

setgid

設(shè)置$HOME

exec 目標(biāo)命令

除了最后關(guān)鍵的兩步,其它跟sudo差不多。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/26542.html

相關(guān)文章

  • Docker Volume 之權(quán)限管理(轉(zhuǎn))

    摘要:發(fā)現(xiàn)問題之后,相應(yīng)的解決方法也很簡單把當(dāng)前目錄的擁有者賦值給,再啟動(dòng)容器就一切正常了。這時(shí)我們已經(jīng)可以知道容器的本地?cái)?shù)據(jù)卷中文件目錄的權(quán)限是和宿主機(jī)上一致的,只是在容器和宿主機(jī)中可能映射為不同的用戶組名稱。 Volume數(shù)據(jù)卷是Docker的一個(gè)重要概念。數(shù)據(jù)卷是可供一個(gè)或多個(gè)容器使用的特殊目錄,可以為容器應(yīng)用存儲(chǔ)提供有價(jià)值的特性: 持久化數(shù)據(jù)與容器的生命周期解耦:在容器刪除之后數(shù)據(jù)卷...

    sf190404 評論0 收藏0
  • Docker 筆記(2):Dockerfile

    摘要:是由一系列命令和參數(shù)構(gòu)成的腳本,這些命令應(yīng)用于基礎(chǔ)鏡像并最終創(chuàng)建一個(gè)新的鏡像。每個(gè)中只能有一個(gè),當(dāng)指定多個(gè)時(shí),只有最后一個(gè)生效。是改變工作目錄,則是改變之后層的執(zhí)行以及這類命令的身份。 Dockerfile是由一系列命令和參數(shù)構(gòu)成的腳本,這些命令應(yīng)用于基礎(chǔ)鏡像并最終創(chuàng)建一個(gè)新的鏡像。 常用的選項(xiàng) 例子: FROM node:latest MAINTAINER my_name ADD ....

    DesGemini 評論0 收藏0
  • Dockerfile最佳實(shí)踐

    摘要:比如和指令,鏡像中的文件內(nèi)容被檢查并且為每個(gè)文件計(jì)算校驗(yàn)和。這些文件的最終修改和訪問時(shí)間將不被考慮到校驗(yàn)和內(nèi)。在查找緩存期間,校驗(yàn)和將被用于與已存在的鏡像校驗(yàn)和進(jìn)行對比。 Docker 可以從 Dockerfile 中讀取指令自動(dòng)構(gòu)建鏡像,Dockerfile是一個(gè)包含構(gòu)建指定鏡像所有命令的文本文件。Docker堅(jiān)持使用特定的格式并且使用特定的命令。你可以在 Dockerfile參考 ...

    張金寶 評論0 收藏0
  • docker學(xué)習(xí)

    摘要:入坑嘿嘿安裝官方安裝教程常用命令用構(gòu)建鏡像通過鏡像生成容器是交互式模式對應(yīng)是后臺(tái)啟動(dòng)用本機(jī)的端口映射容器的端口進(jìn)入正在運(yùn)行的容器內(nèi)查看鏡像查看所有容器狀態(tài)刪除容器刪除鏡像重啟構(gòu)建用官方鏡像啟動(dòng)將存放數(shù)據(jù)庫信息的文件夾映射 Docker 入坑docker嘿嘿 ubantu安裝docker 官方安裝教程 docker常用命令 #用Dockerfile構(gòu)建鏡像 docker build ...

    沈建明 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<