Windowsコンテナのしくみ

0f5f81b602e9ad7f24e7ebe9b994d04c?s=47 kyo
January 16, 2020

 Windowsコンテナのしくみ

Slides for a study meeting.
https://dockerjp.connpass.com/event/159781/

0f5f81b602e9ad7f24e7ebe9b994d04c?s=128

kyo

January 16, 2020
Tweet

Transcript

  1. Windowsコンテナのしくみ

  2. Kyohei Mizumoto(@kyohmizu) C# Software Engineer Interests Cloud Native Docker Kubernetes

    Golang Azure whoami
  3. 今⽇話すこと Windowsコンテナの概要 Windowsコンテナのアーキテクチャ HCS HNS コンテナを実⾏して⾊々確認

  4. より詳しく知りたい⽅は

  5. Windowsコンテナの特徴 2つの分離モード プロセス分離、Hyper-V分離 --isolation オプションで指定 4つのベースイメージ https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage- containers/container-base-images コンテナはホストOSのバージョンに依存 プロセス分離の場合、同⼀バージョンのイメージのみ実⾏可能

    ドキュメントがない、少ない
  6. Get Started Dockerをインストール PS> Install-Module -Name DockerMsftProvider -Repository PSGallery -Force

    PS> Install-Package -Name docker -ProviderName DockerMsftProvider PS> Restart-Computer -Force 再起動後、docker コマンドが有効に HNS (後述)の管理モジュールもインストールされる PS> docker version PS> Get-HnsNetwork Hyper-Vを有効化 PS> Install-WindowsFeature -Name Hyper-V -IncludeManagementTools -Restart
  7. アーキテクチャ (Linux) 引⽤︓https://qiita.com/kikuchi_kentaro/items/2fb0171e18821d402761

  8. アーキテクチャ (Windows) 引⽤︓https://qiita.com/kikuchi_kentaro/items/2fb0171e18821d402761#hcs--host-compute-service-

  9. インターフェイス HCS (Host Compute Service) コンテナ管理のための低レベル機能をAPIとして提供 cgroups、namespace 等の役割 実体は vmcompute.dll

    Docker ではGo Wrapperの hcsshim を使⽤ HNS (Host Networking Service) 仮想スイッチやエンドポイント、ポリシーの作成等を⾏う 5つのネットワークドライバをサポート (nat, overlay, transparent, l2bridge, l2tunnel) hcsshim に含まれる 今は HCN (Host Compute Networking) と呼ばれる︖
  10. コンテナランタイム https://github.com/microsoft/hcsshim/tree/master/cmd/runhcs runhcs OCI準拠のコンテナランタイム runc をforkしたもの Windowsコンテナのプロセス分離とHyper-V分離、LCOWに対応 containerd (on Windows)

    + runhcs の構成 runhcs run [ -b bundle ] <container-id> Docker では hcsshim で直接HCS、HNSを呼び出している
  11. Linuxコンテナとの機能⽐較 引⽤︓https://www.slideshare.net/Docker/windows-container-security

  12. Kernel Isolation in Windows Job Objects プロセスをグループ化して管理 グループ毎にリソースを制限 https://docs.microsoft.com/en-us/windows/win32/procthread/job-objects Silos

    Job Objectを拡張し、namespaceやレジストリ等を分離 https://docs.microsoft.com/en-us/archive/msdn-magazine/2017/april/containers- bringing-docker-to-windows-developers-with-windows-server-containers Syscall Filtering コンテナ内からのWin32kシステムコールを制限 https://improsec.com/tech-blog/win32k-system-call-filtering-deep-dive Sandoxing Linux Capability相当の機能
  13. Union File System https://xebia.com/blog/deep-dive-into-windows-server-containers-and-docker-part-2- underlying-implementation-of-windows-server-containers/ WindowsアプリはNTFSセマンティクスを想定 トランザクション、USN Journal等 完全なunionFSを作成するのが困難 ハイブリッドモデルを採⽤

    コンテナ毎に仮想ブロックデバイス + NTFSパーティション ブロックデバイスのサイズを⼩さくするためsymlinkを使⽤ 実体はwcifs.sys(Windows Container Isolation FS Filter Driver)
  14. ネットワーク コンテナに仮想NICを割り当て Hyper-V virtual switch (vSwitch)経由で接続 引⽤︓https://docs.microsoft.com/en-us/virtualization/windowscontainers/container-networking/architecture

  15. 動作確認

  16. 環境 Microsoft Azure VM Windowsプロセス分離コンテナを実⾏ nat ネットワーク (Default) PS> docker

    container run -it --isolation process mcr.microsoft.com/windows/servercore:1809 powershell PS> docker container ls -q #56dae625d7c0
  17. Job Objects \ 内にコンテナのJob Objectが追加されている PS> docker container inspect --format="{{.Id}}"

    56dae625d7c0 #56dae625d7c0d69235147f0c8f1b4aa64ac9c51f92a03f35e5ba168d30d7817a
  18. Silos JID (Job ID)経由で割り当て

  19. リソース制限 メモリに制限をかける PS> docker container run -it --isolation process -m

    "100m" mcr.microsoft.com/windows/nanoserver:1809
  20. 割り当てボリューム https://qiita.com/kikuchi_kentaro/items/2fb0171e18821d402761#change-root

  21. 割り当てボリューム Disk2のPartition2にマウントされている PS> diskpart DISKPART> list vdisk # VDisk ###

    Disk ### State Type File # --------- -------- -------------------- --------- ---- # VDisk 0 Disk 2 Attached not open Expandable # C:\ProgramData\docker\windowsfilter\56dae625d7c0d69235147f0c8f1b4aa64ac9c51f92a03f35e5ba168d30d7817a\sandbox.vhdx コンテナを停⽌してホストに割り当て DISKPART> select vdisk file=` "C:\ProgramData\docker\windowsfilter\56dae625d7c0d69235147f0c8f1b4aa64ac9c51f92a03f35e5ba168d30d7817a\sandbox.vhdx" DISKPART> attach vdisk # 100 percent completed # DiskPart successfully attached the virtual disk file. DISKPART> list vol # Volume ### Ltr Label Fs Type Size Status Info # ---------- --- ----------- ----- ---------- ------- --------- -------- # ... # Volume 3 NTFS Partition 19 GB Healthy DISKPART> select volume 3 # Volume 3 is the selected volume. DISKPART> assign letter=x # DiskPart successfully assigned the drive letter or mount point.
  22. 割り当てボリューム 中⾝が確認できた

  23. ネットワーク設定 (nat) PS> docker network inspect 5bdb5d65193e [ { "Name":

    "nat", "Id": "5bdb5d65193e0f2c75324bfb491bddfdfe832fbc5274b17bb65ffc159b813c35", "Created": "2020-01-16T00:33:51.3521196Z", "Scope": "local", "Driver": "nat", "EnableIPv6": false, "IPAM": { "Driver": "windows", "Options": null, "Config": [ { "Subnet": "192.168.48.0/20", "Gateway": "192.168.48.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": { "com.docker.network.windowsshim.hnsid": "AB1F91D2-F403-409F-8E8A-F70BF850CC30", "com.docker.network.windowsshim.networkname": "nat" }, "Labels": {} } ]
  24. ネットワーク設定 (nat) # 実体はDockerインストール時に作成された仮想NIC PS> Get-NetAdapter -Name "vEthernet (nat)" `

    | fl Name,MacAddress,DeviceID,DeviceName,InterfaceIndex,InterfaceName,InterfaceType,Virtual #Name : vEthernet (nat) #MacAddress : 00-15-5D-70-3C-17 #DeviceID : {1D1CEF6D-9BB1-4C9A-B594-7BA93992DF73} #DeviceName : \Device\{1D1CEF6D-9BB1-4C9A-B594-7BA93992DF73} #InterfaceIndex : 8 #InterfaceName : ethernet_32771 #InterfaceType : 6 #Virtual : True PS> Get-NetIPAddress | ? {$_.InterfaceIndex -eq 8} ` | fl IPAddress,InterfaceAlias,AddressFamily,IPAddress,Type #IPAddress : fe80::6d79:bf22:3a:e5bb%8 #InterfaceAlias : vEthernet (nat) #AddressFamily : IPv6 #IPAddress : fe80::6d79:bf22:3a:e5bb%8 #Type : Unicast #IPAddress : 192.168.48.1 #InterfaceAlias : vEthernet (nat) #AddressFamily : IPv4 #IPAddress : 192.168.48.1 #Type : Unicast
  25. ネットワーク設定 (nat) # 以下のコマンドでも確認可能 PS> ipconfig /all #Ethernet adapter vEthernet

    (nat): # # Connection-specific DNS Suffix . : # Description . . . . . . . . . . . : Hyper-V Virtual Ethernet Adapter # Physical Address. . . . . . . . . : 00-15-5D-70-3C-17 # DHCP Enabled. . . . . . . . . . . : No # Autoconfiguration Enabled . . . . : Yes # Link-local IPv6 Address . . . . . : fe80::6d79:bf22:3a:e5bb%8(Preferred) # IPv4 Address. . . . . . . . . . . : 192.168.48.1(Preferred) # Subnet Mask . . . . . . . . . . . : 255.255.240.0 # Default Gateway . . . . . . . . . : # DHCPv6 IAID . . . . . . . . . . . : 134223197 # DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-25-96-9D-2D-00-0D-3A-CC-CE-DC # DNS Servers . . . . . . . . . . . : fec0:0:0:ffff::1%1 # fec0:0:0:ffff::2%1 # fec0:0:0:ffff::3%1 # NetBIOS over Tcpip. . . . . . . . : Enabled PS> netsh int ipv4 show int # Idx Met MTU State Name # --- ---------- ---------- ------------ --------------------------- # ... # 8 5000 1500 connected vEthernet (nat)
  26. ネットワーク設定 (コンテナ) PS> docker container inspect 56dae625d7c0 "NetworkSettings": { "Bridge":

    "", "SandboxID": "56dae625d7c0d69235147f0c8f1b4aa64ac9c51f92a03f35e5ba168d30d7817a", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "56dae625d7c0d69235147f0c8f1b4aa64ac9c51f92a03f35e5ba168d30d7817a", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "", "Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "MacAddress": "", "Networks": { "nat": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "5bdb5d65193e0f2c75324bfb491bddfdfe832fbc5274b17bb65ffc159b813c35", "EndpointID": "7b9b8eea699c59e7943031d67e81d34e7e077f3d74b17866d6c137a72b71ceed", "Gateway": "192.168.48.1", "IPAddress": "192.168.51.62", "IPPrefixLen": 24, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "00:15:5d:70:38:c8", "DriverOpts": null } } }
  27. ネットワーク設定 (コンテナ) # コンテナに割り当てられる仮想NICの確認 # コンテナ内 (CONTAINER) PS> Get-NetAdapter `

    | fl -Property Name,MacAddress,DeviceID,DeviceName,InterfaceIndex,InterfaceName,InterfaceType,Virtual #Name : vEthernet (Ethernet) 5 #MacAddress : 00-15-5D-70-38-C8 #DeviceID : {FEAD9E20-FE87-4FE4-A91C-4EA8FEAD738E} #DeviceName : #InterfaceIndex : 17 #InterfaceName : iftype0_0 #InterfaceType : 0 #Virtual : # ホスト側 PS> Get-NetAdapter -Name "vEthernet (Ethernet) 5" ` | fl Name,MacAddress,DeviceID,DeviceName,InterfaceIndex,InterfaceName,InterfaceType,Virtual #Name : vEthernet (Ethernet) 5 #MacAddress : 00-15-5D-70-38-C8 #DeviceID : {FEAD9E20-FE87-4FE4-A91C-4EA8FEAD738E} #DeviceName : \Device\{FEAD9E20-FE87-4FE4-A91C-4EA8FEAD738E} #InterfaceIndex : 17 #InterfaceName : ethernet_32775 #InterfaceType : 6 #Virtual : True
  28. ネットワーク設定 (コンテナ) # コンテナのIPアドレス # コンテナ内 (CONTAINER) PS> Get-NetIPAddress |

    ? {$_.InterfaceIndex -eq 17} ` | fl -Property IPAddress,InterfaceIndex,InterfaceAlias,AddressFamily #IPAddress : fe80::e433:a183:579:ac65%17 #InterfaceIndex : 17 #InterfaceAlias : vEthernet (Ethernet) 5 #AddressFamily : IPv6 #IPAddress : 192.168.51.62 #InterfaceIndex : 17 #InterfaceAlias : vEthernet (Ethernet) 5 #AddressFamily : IPv4 (CONTAINER) PS> Get-NetIPConfiguration | ? {$_.InterfaceIndex -eq 17} | ft -Property ` InterfaceIndex,@{Expression={$_.IPv4Address}},@{Expression={$_.IPv4DefaultGateway.NextHop}} #InterfaceIndex $_.IPv4Address $_.IPv4DefaultGateway.NextHop #-------------- -------------- ----------------------------- # 17 192.168.51.62 192.168.48.1 # ホスト側 PS> Get-NetIPAddress | ? {$_.InterfaceIndex -eq 17} ` | fl -Property IPAddress,InterfaceIndex,InterfaceAlias,AddressFamily # ホストからは確認できない
  29. ネットワーク設定 (コンテナ) # HNS Networkでコンテナ数を確認できる PS> Get-HnsNetwork #ActivityId : 47E672B6-69C8-4A35-AB2C-02E8B88F2C76

    #AdditionalParams : #CurrentEndpointCount : 1 ← ネットワーク内のコンテナ数 #Extensions : {@{Id=E7C3B2F0-F3C5-48DF-AF2B-10FED6D72E7A; IsEnabled=False; Name=Microsoft Windows Filtering # Platform}, @{Id=E9B59CFA-2BE1-4B21-828F-B6FBDBDDC017; IsEnabled=False; Name=Microsoft Azure # VFP Switch Extension}, @{Id=EA24CD6C-D17A-4348-9190-09F0D5BE83DD; IsEnabled=True; # Name=Microsoft NDIS Capture}} #Flags : 0 #Health : @{AddressNotificationMissedCount=0; AddressNotificationSequenceNumber=0; # InterfaceNotificationMissedCount=0; InterfaceNotificationSequenceNumber=0; LastErrorCode=0; # LastUpdateTime=132236084313701171; RouteNotificationMissedCount=0; # RouteNotificationSequenceNumber=0} #ID : AB1F91D2-F403-409F-8E8A-F70BF850CC30 #IPv6 : False #LayeredOn : 29D2B655-EC21-4157-9343-868669D233CE #MacPools : {@{EndMacAddress=00-15-5D-70-3F-FF; StartMacAddress=00-15-5D-70-30-00}} #MaxConcurrentEndpoints : 1 #Name : nat #NatName : ICS1D1CEF6D-9BB1-4C9A-B594-7BA93992DF73 #Policies : {} #Resources : @{AdditionalParams=; AllocationOrder=2; Allocators=System.Object[]; Health=; # ID=47E672B6-69C8-4A35-AB2C-02E8B88F2C76; PortOperationTime=0; State=1; SwitchOperationTime=0; # VfpOperationTime=0; parentId=79DDED38-22DF-4929-8B77-F870D6646077} #State : 1 #Subnets : {@{AdditionalParams=; AddressPrefix=192.168.48.0/20; GatewayAddress=192.168.48.1; Health=; # ID=1A5FE614-132F-44E2-A58A-049BEE86F2A4; Policies=System.Object[]; State=0}} #TotalEndpoints : 5 #Type : nat #Version : 38654705666
  30. 今回はここまで…

  31. (再掲) より詳しく知りたい⽅は

  32. 参考 Docker Desktop の復習と、Windows Container に⼊⾨: Windows Server Container 理論編

    https://qiita.com/kikuchi_kentaro/items/2fb0171e18821d402761 Introducing the Host Compute Service (HCS) https://techcommunity.microsoft.com/t5/containers/introducing-the-host-compute-service-hcs/ba- p/382332 Containers on Windows Documentation https://docs.microsoft.com/en-us/virtualization/windowscontainers/ Windows container security https://www.slideshare.net/Docker/windows-container-security Deep dive into Windows Server Containers and Docker – Part 2 https://xebia.com/blog/deep-dive-into-windows-server-containers-and-docker-part-2-underlying- implementation-of-windows-server-containers/ Bringing Docker To Windows Developers with Windows Server Containers https://docs.microsoft.com/en-us/archive/msdn-magazine/2017/april/containers-bringing-docker-to- windows-developers-with-windows-server-containers
  33. Thank you!