Integrating Windows Authentication for Windows AP containers


這篇文章在說明容器化Windows Server 應用程式整合 AD 的原理與方法。

Windows 容器無法加入網域,但仍可使用 Active Directory 網域身分識別來支援各種驗證案例。可以設定 Windows 容器以 gMSA (group managed service account) 執行,這是 Windows Server 2012 中引進的一種特殊的服務帳戶,其設計目的是讓多部電腦共用身分識別,而不需要知道密碼。

關於 gMSA 的進一步說明,可以參考: 

  • https://www.itprotoday.com/windows-8/understanding-differences-between-msas-and-gmsas
  • https://span.eu/en/business-solution/group-managed-service-accounts-gmsa-protect-service-account-credentials/


使用 gMSA 執行容器時,容器主機會從 Active Directory 網域控制站抓取 gMSA 密碼,並將其提供給容器實例。gMSA 的密碼不存在容器主機上。每次其電腦帳戶(系統)需要存取網路資源時,容器都會使用 gMSA 認證。

建立群組受管理的服務帳戶 (Group Managed Service Account)


使用整合式 Windows 驗證的每個容器都需要至少一個 gMSA



必須使用屬於Domain Admins安全性群組的帳戶,或是已被委派Create msds-groupmanagedserviceaccount objects許可權,才能執行下列命令。

# Create the security group #
New-ADGroup

# Create the gMSA #

New-ADServiceAccount


# Add your container hosts to the security group #

Add-ADGroupMember







確認主機可以使用 gMSA 帳戶




在 Windows Docker Worker 主機上,

開啓 PowerShell 執行下列指令結果進行GMSA帳號測試,


Install-WindowsFeature RSAT-AD-PowerShell


Enable-WindowsOptionalFeature -FeatureName ActiveDirectory-Powershell -online -all


Test-ADServiceAccount WebApp01


上述指令結果最後應返回TRUE。





建立認證規格 (CredentialSpec)




1)認證規格檔案是一份 JSON 檔
2)包含您想要容器使用之 gMSA 帳戶的相關中繼資料
3)藉由將身分識別設定與容器映射分開,可以變更容器所使用的 gMSA,方法是直接交換認證規格檔案,而不需要變更程式碼
4)使用已加入網域之容器主機上的 CredentialSpec PowerShell 模組來建立認證規格檔案
5)建立檔案之後,可以將它複製到其他容器主機或 orchestrator
6)認證規格檔案不包含任何密碼,因為容器主機會代表容器來抓取 gMSA 資訊



要建立 CredentialSpec 前需先下載 PowerShell 模組,
要使用 CredentialSpec PowerShell 模組,主機上必須符合幾個條件
(1)作業系統版本:Windows 10 version 1607/Windows Server 2016 or later;
(2)容器主機必須已經加入企業AD網域;
(3)Docker Desktop for Windows 10 or Docker EE for Windows Server 已安裝在主機上;
(4)至少一個 gMSA 已經建立在網域內

安裝 CredentialSpec PowerShell 模組的指令:

Install-Module CredentialSpec

建立 CredentialSpec :
New-CredentialSpec <gMSA id>

設定應用程式以使用 gMSA



(1) 以網路服務的身分執行 IIS 應用程式集區

要將 IIS 網站裝載在容器中,只需要將應用程式集區身分識別設定為Network Service,
即可充分利用 gMSA, Dockerfile 文件內容加上:
RUN %windir%\system32\inetsrv\appcmd.exe set AppPool DefaultAppPool -processModel.identityType:NetworkService

(2) 以網路服務的形式執行 Windows 服務

Dockerfile 文件內容加上:
RUN sc.exe config "YourServiceName" obj= "NT AUTHORITY\NETWORK SERVICE" password= ""

(3) 以網路服務的形式執行任意的主控台應用程式

Dockerfile 文件內容加上:

USER "NT AUTHORITY\NETWORK SERVICE"

使用 docker exec 指令加入 --user 排除網路錯誤,

# Opens an interactive PowerShell console in the container (id = 85d) as the Network Service account

docker exec -it --user "NT AUTHORITY\NETWORK SERVICE" 85d powershell





使用 gMSA 執行容器


docker run --security-opt "credentialspec=file://contoso_webapp01.json" --hostname webapp01 -it mcr.microsoft.com/windows/servercore:ltsc2016 powershell





搭配使用 gMSA 與 Docker Swarm


Windows Server 2016 或 Windows Server 2019 環境下都可支持




docker service create --credential-spec "file://contoso_webapp01.json" --hostname "WebApp01" <image name>
--credential-spec 支援兩種格式:registry 以及 file  
  1. registry://<value-name>
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs
  1. file://spec.json
Docker 預期會在 Docker data 目錄中的CredentialSpecs目錄下尋找認證規格檔案。在預設安裝中,在 C:\ProgramData\Docker\CredentialSpecs 找到此資料夾
C:\ProgramData\Docker\CredentialSpecs\spec.json



搭配使用 gMSA 與 Kubernetes


截至目前為止,在 Kubernetes 1.14 搭配 gMSA 布署容器服務的進度處於 Alpha 階段,
在 Kubernetes 1.16 搭配 gMSA 布署容器服務的進度處於 Beta 階段,

且不論使用 Kubernetes 1.14 或是 Kubernetes 1.16 來布署,兩者都是要在 Windows Server 2019 環境上才可進行,在 Windows Server 2016 環境 Kubernetes 都是不支援的 。故在此不做詳細介紹。





(TBD)

留言

這個網誌中的熱門文章

Docker 環境下的 Proxy 配置