亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

管理Docker共享卷權限的(最佳)方法是什么?

管理Docker共享卷權限的(最佳)方法是什么?

qq_花開花謝_0 2019-11-21 10:58:36
我已經和Docker玩了一段時間,在處理持久性數據時繼續尋找相同的問題。我創建我的文件Dockerfile并公開一個卷,或使用--volumes-from它在容器中安裝主機文件夾。我應該對主機上的共享卷應用什么權限?我可以想到兩種選擇:到目前為止,我已經授予所有人讀取/寫入訪問權限,因此我可以從Docker容器寫入該文件夾。將用戶從主機映射到容器,以便我可以分配更多的細化權限。不確定這是否可能,但尚未找到很多相關信息。到目前為止,我只能以某些用戶身份運行容器:docker run -i -t -user="myuser" postgres,但是該用戶的UID與主機不同myuser,因此權限不起作用。另外,我不確定映射用戶是否會帶來一些安全風險。還有其他選擇嗎?你們如何處理這個問題?
查看完整描述

3 回答

?
胡說叔叔

TA貢獻1804條經驗 獲得超8個贊

從Docker 1.9.0開始,Docker已命名卷來替換僅數據容器。在我如何思考docker內部的數據的意義上,下面的答案以及我的鏈接博客文章仍然有價值,但是可以考慮使用命名卷而不是數據容器來實現下面描述的模式。


我相信解決這一問題的規范方法是使用僅數據容器。通過這種方法,所有對卷數據的訪問都是通過使用-volumes-from數據容器的容器進行的,因此主機uid / gid無關緊要。


例如,文檔中給出的一個用例是備份數據量。為此,另一個容器用于通過進行備份tar,它也用于-volumes-from裝載卷。因此,我認為grok的關鍵點在于:與其考慮如何通過適當的權限訪問主機上的數據,不如考慮如何通過另一個容器來執行所需的任何操作(備份,瀏覽等)。 。容器本身需要使用一致的uid / gids,但它們不需要映射到主機上的任何內容,從而保持可移植性。


對于我來說,這也是相對較新的,但是如果您有特定的用例,請隨時發表評論,我將嘗試擴展答案。


更新:對于注釋中的給定用例,您可能有一個some/graphite運行石墨的圖像,以及一個some/graphitedata作為數據容器的圖像。因此,忽略端口等,Dockerfile映像some/graphitedata的類似于:


FROM debian:jessie

# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later

RUN groupadd -r graphite \

  && useradd -r -g graphite graphite

RUN mkdir -p /data/graphite \

  && chown -R graphite:graphite /data/graphite

VOLUME /data/graphite

USER graphite

CMD ["echo", "Data container for graphite"]

構建和創建數據容器:


docker build -t some/graphitedata Dockerfile

docker run --name graphitedata some/graphitedata

該some/graphiteDockerfile也應該得到相同的UID /導報,因此它可能是這個樣子:


FROM debian:jessie

# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later

RUN groupadd -r graphite \

  && useradd -r -g graphite graphite

# ... graphite installation ...

VOLUME /data/graphite

USER graphite

CMD ["/bin/graphite"]

它將如下運行:


docker run --volumes-from=graphitedata some/graphite

好的,現在這為我們的石墨容器和關聯的僅數據容器提供了正確的用戶/組(請注意,您也可以將some/graphite容器重新用于數據容器,在運行時覆蓋entrypoing / cmd,但是將它們作為IMO更加清晰)。


現在,假設您要編輯數據文件夾中的內容。因此,與其將卷綁定到主機上并在其上進行編輯,不如創建一個新容器來完成該工作。叫它吧some/graphitetools。讓我們也創建適當的用戶/組,就像some/graphite圖像一樣。


FROM debian:jessie

# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later

RUN groupadd -r graphite \

  && useradd -r -g graphite graphite

VOLUME /data/graphite

USER graphite

CMD ["/bin/bash"]

您可以通過從Dockerfile 繼承some/graphite或some/graphitedata在Dockerfile中進行此DRY ,或者代替重新創建新映像,而僅重用現有映像之一(必要時覆蓋entrypoint / cmd)。


現在,您只需運行:


docker run -ti --rm --volumes-from=graphitedata some/graphitetools

然后vi /data/graphite/whatever.txt。這非常有效,因為所有容器的石墨用戶都相同,并且具有匹配的uid / gid。


由于您從未/data/graphite從主機上進行掛載,因此無需關心主機uid / gid如何映射到graphite和graphitetools容器中定義的uid / gid 。這些容器現在可以部署到任何主機,并且它們將繼續正常運行。


這樣做的好處是,它graphitetools可能具有各種有用的實用程序和腳本,您現在也可以以可移植的方式進行部署。


更新2:寫完這個答案后,我決定寫一篇關于此方法的更完整的博客文章。希望對您有所幫助。


更新3:我更正了此答案,并添加了更多細節。它先前包含有關所有權和權限的一些錯誤假設-所有權通常是在卷創建時即在數據容器中分配的,因為這是在創建卷時分配的。看到這個博客。不過,這不是必須的-您可以僅將數據容器用作“引用/句柄”,并通過入口處的chown在另一個容器中設置所有權/權限,最后以gosu身份以正確的用戶身份運行命令。如果有人對此方法感興趣,請發表評論,我可以提供使用該方法的示例鏈接。


查看完整回答
反對 回復 2019-11-21
?
藍山帝景

TA貢獻1843條經驗 獲得超7個贊

可以在官方Redis圖像上以及通常在所有官方圖像中看到一個非常優雅的解決方案。


分步介紹:


首先創建Redis用戶/組

如Dockerfile注釋所示:


首先添加我們的用戶和組,以確保一致分配其ID,而不考慮添加了任何依賴項


安裝古藪與Dockerfile

gosu是su/ 的替代方案,sudo用于從根用戶輕松降級。(Redis始終與redis用戶一起運行)


配置/data音量并將其設置為workdir

通過使用VOLUME /data命令配置/ data卷,我們現在有了一個單獨的卷,該卷既可以是docker卷,也可以綁定安裝到主機目錄。


將其配置為workdir(WORKDIR /data)使其成為執行命令的默認目錄。


添加docker-entrypoint文件并使用默認CMD redis-server將其設置為ENTRYPOINT

這意味著所有容器執行將通過docker-entrypoint腳本運行,并且默認情況下要運行的命令是redis-server。


docker-entrypoint是一個執行簡單功能的腳本:將當前目錄(/ data)的所有權和降級從root更改為redisuser以運行redis-server。(如果執行的命令不是redis-server,它將直接運行該命令。)


這具有以下效果


如果將/ data目錄綁定安裝到主機,則docker-entrypoint將在用戶下運行redis-server之前準備用戶權限redis。


這使您可以輕松設置零設置,以便在任何卷配置下運行容器。


當然,如果需要在不同圖像之間共享卷,則需要確保它們使用相同的用戶ID /組ID,否則最新的容器將劫持前一個容器的用戶權限。


查看完整回答
反對 回復 2019-11-21
?
墨色風雨

TA貢獻1853條經驗 獲得超6個贊

可以說這不是大多數情況下的最佳方法,但是尚未提及,因此也許會對某人有所幫助。


綁定掛載主機卷


Host folder FOOBAR is mounted in container /volume/FOOBAR


修改容器的啟動腳本以找到您感興趣的卷的GID


$ TARGET_GID=$(stat -c "%g" /volume/FOOBAR)


確保您的用戶屬于具有此GID的組(您可能必須創建一個新組)。在此示例中,我假設我的軟件nobody在容器中時以用戶身份運行,因此我想確保其nobody所屬組的組ID等于TARGET_GID


  EXISTS=$(cat /etc/group | grep $TARGET_GID | wc -l)


  # Create new group using target GID and add nobody user

  if [ $EXISTS == "0" ]; then

    groupadd -g $TARGET_GID tempgroup

    usermod -a -G tempgroup nobody

  else

    # GID exists, find group name and add

    GROUP=$(getent group $TARGET_GID | cut -d: -f1)

    usermod -a -G $GROUP nobody

  fi

我之所以這樣,是因為我可以輕松地修改主機卷上的組權限,并且知道這些更新的權限適用于Docker容器。發生這種情況時,沒有對我的主機文件夾/文件進行任何許可或所有權修改,這讓我很高興。


我不喜歡這樣,因為它假定將自己添加到恰好使用您想要的GID的容器內的任意組中沒有危險。它不能與USERDockerfile中的子句一起使用(除非我認為該用戶具有root特權)。此外,它還大叫黑客工作;-)


如果您想成為鐵桿,顯然可以通過多種方式擴展它-例如,在任何子文件,多個卷等上搜索所有組。


查看完整回答
反對 回復 2019-11-21
  • 3 回答
  • 0 關注
  • 1070 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號