釐清多 Windows Container 針對同一 Volume 運作時的權限身份

釐清多 Windows Container 針對同一 Volume 運作時的權限身份

專案有個需求,會同時有多個 Windows Container 對 Docker Host 同一資料夾進行操作,讀取、新增、刪除、修改都有,而且操作的量不小(秒級)。問題出在,A Container 建立資料夾與檔案,B Container 要操作時會出現 Access Denied。找了好久原因,終於釐清整個 Windows Container 在 Volume 運作時的身份與權限。

簡化的情境如下:

Docker Host --> A Container / B Container

docker run -it --rm --name ima -v c:\temp\:c:\temp microsoft/nanoserver:1803 cmd.exe
docker run -it --rm --name imb -v c:\temp\:c:\temp microsoft/nanoserver:1803 cmd.exe

以上是一個非常直覺的 Lab 模擬。不過,不論你怎麼玩,就是不會出現前述的 A / B Container 在 c:\temp 進行互相操作時出現 Access Denied 的情況。這讓我卡了一陣了,想了好久。看著專案有問題的 docker psdocker images 改成這樣:

docker run -it --rm --name ima -v c:\temp\:c:\temp microsoft/nanoserver:1803 cmd.exe
docker run -it --rm --name imb -v c:\temp\:c:\temp microsoft/windowsservercore:1803 cmd.exe

Bing Go!但重點是 Why?

  • A Container (nanoserver image) 新增一個 FromNano.txt
  • B Container (windowsservercore image) 新增一個 FromCore.txt

並查看檔案的【安全性】(我把資料夾分享出來),看到了蛛絲馬跡:

FromNano.txt Security
FromCore.txt Security

也能使用 PowerShell 的 Get-ACL 來看,只是沒那麼直覺:

PS Get-ACL

看到這裡我大概知道原因了:

Docker Host --> A Container / B Container

Docker Host 的資料夾有自己的安全性(身分與權限),但 A / B Container 裡的 Windows Server 的身份並不是 Docker Host 上身份,當一個不認識的人在你的資料夾寫了個東西,那個奇怪的「S-1-5-93-2-1」「S-1-5-93-2-2」身份就出現了。A 身份寫的檔案,當然 B 身份不能進行修改之類的異動操作,Access Denied 就出現了。

另外,在反覆實驗後,也了解為什麼一開始的 Lab 不會造成問題,原因在 Docker Image,那個【「S-1-5-93-2-1」「S-1-5-93-2-2」身份】是跟著 Image 來產生的,也就是說,我使用同一個 image 來產生 10 個 Container,這 10 個 Container 會拿到同一個 S-x-x 的身份,對 Docker Host 的 Windows Server 而言都是同一個人,Docker Host 才不管你對自己的檔案做什麼操作。

換個方向,每個 Container 也是獨立的 Windows Server,這是檔案互動操作的權限問題:

Windows Host --> A nano server / B core server

了解原因後,那麼解決辦法就回到身份驗證身上,能不能讓 A nano server / B core server 拿到一樣的身份?

找了一些討論串,發現目前 Docker for Windows 無法讓 Container 在啟動設定 Host 本身 LocalAccount,不過在 moby #28585看到一絲希望:

docker run -it --rm -v c:\temp\:c:\temp --user "NT AUTHORITY\SYSTEM" microsoft/nanoserver:1803 cmd.exe
docker run -it --rm -v c:\temp\:c:\temp --user "NT AUTHORITY\SYSTEM" microsoft/windowsservercore:1803 cmd.exe
Get-ACL

現在,雖然是不同 Image 產生的 Container,但現在在 Volume 操作都是相同身份,換句話說,現在 A / B Container 才是同根生的狀態,不在產生那個怪怪「S-1-5-93-2-1」「S-1-5-93-2-2」身份了。

在 docker-compose.yml 一樣使用 user 來指定:

version: '3'
services:

  nano:
    image: microsoft/nanoserver:1803
    user: 'NT AUTHORITY\SYSTEM'
    volumes:
      - c:\temp\:c:\temp
    stdin_open: true
    tty: true

  core:
    image: microsoft/windowsservercore:1803
    user: 'NT AUTHORITY\SYSTEM'
    volumes:
      - c:\temp\:c:\temp
    stdin_open: true
    tty: true

雖然看文只用了簡單 --user "NT AUTHORITY\SYSTEM" 幾個字就解決,但解題過程可以花費了一整天。

沒有留言:

張貼留言

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。