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身份以正確的用戶身份運行命令。如果有人對此方法感興趣,請發表評論,我可以提供使用該方法的示例鏈接。

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,否則最新的容器將劫持前一個容器的用戶權限。

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特權)。此外,它還大叫黑客工作;-)
如果您想成為鐵桿,顯然可以通過多種方式擴展它-例如,在任何子文件,多個卷等上搜索所有組。
- 3 回答
- 0 關注
- 1070 瀏覽
添加回答
舉報