Server Core 1709 with Docker EE Preview LCOW 絕對運作筆記

Server Core 1709 with Docker EE Preview LCOW 絕對運作筆記

LCOW

Linux Containers on Windows (以下稱 LCOW) 對於 Windows Server 上的容器化提供非常重要的戰略位置。先不論 Windows Server 上的 Docker EE 僅能執行 Windows Container,講個笑話,用 Docker EE 連架個私有 Registry 都困難重重。而 Windows 10 上的 Docker CE 好一些,可以直接進行 Linux Container / Windows Container 切換與操作,但兩者並無法同時使用(不過,也快可以了)。也就是說,在使用 LCOW 技術之後,不用在特別區分這是 Linux Container 或 Windows Container,不用在特別去切換執行環境,即可在一個 Docker EE 執行環境下同時執行 Linux / Windows Container。

設定 Proxy

公司內通常需要設定 Proxy:

[Environment]::SetEnvironmentVariable("HTTP_PROXY", "http://IPAddress:Port/", [EnvironmentVariableTarget]::Machine)
[Environment]::SetEnvironmentVariable("HTTPS_PROXY", "http://IPAddress:Port/", [EnvironmentVariableTarget]::Machine)

Server Core 1709 並無 IE 之類應用程式可以讓你設置 Proxy,在 Server Core 是透過設定環境變數方式來設定。

啟用 Hyper-V

如果伺服器不是實體機,那麼 VM 需要啟用巢狀虛擬化功能。參考:Run Hyper-V in a Virtual Machine with Nested Virtualization

  • 開啟:Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true
  • 關閉:Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $false

如果你的 Host 主機是架在 VMWare 5.x 上面,比較麻煩,升級 VMWare 6.x 就容易很多。

啟用 Hyper-V 與管理工具。

Install-WindowsFeature –Name Hyper-V -IncludeManagementTools
# Uninstall-WindowsFeature -Name Hyper-V -IncludeManagementTools
Restart-Computer -Force

Windows 10:

  • Enable: Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V –All
  • Disable: Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All

確認安裝結果:

PS C:\> Get-WindowsFeature *hyper-v*

Display Name                                            Name                       Install State
------------                                            ----                       -------------
[X] Hyper-V                                             Hyper-V                        Installed
        [X] Hyper-V Management Tools                    RSAT-Hyper-V-Tools             Installed
            [X] Hyper-V Module for Windows PowerShell   Hyper-V-PowerShell             Installed

透過 systeminfo 確認結果:

PS C:\> systeminfo

OS Name:                   Microsoft Windows Server Standard
OS Version:                10.0.16299 N/A Build 16299
Hyper-V Requirements:      A hypervisor has been detected. Features required for Hyper-V will not be displayed.

啟用 Containers

啟用 Windows containers 支援:

Install-WindowsFeature containers
Restart-Computer -Force

確認安裝結果:

PS C:\> Get-WindowsFeature *container*

Display Name                                            Name                       Install State
------------                                            ----                       -------------
[X] Containers                                          Containers                     Installed

安裝 Docker Enterpise Edition Preview

參考:https://blog.docker.com/2017/09/docker-windows-server-1709/

Install-Module DockerProvider
Install-Package Docker -ProviderName DockerProvider -RequiredVersion preview

測試過程,如果想要升級 Docker EE Preview,可參考以下指令:

Install-Package -Name docker -ProviderName DockerProvider -RequiredVersion preview -Update -Force

確認安裝結果:

PS C:\> docker version
Client:
 Version:      17.10.0-ee-preview-3
 API version:  1.33
 Go version:   go1.8.4
 Git commit:   1649af8
 Built:        Fri Oct  6 17:52:28 2017
 OS/Arch:      windows/amd64

Server:
 Version:      17.10.0-ee-preview-3
 API version:  1.34 (minimum version 1.24)
 Go version:   go1.8.4
 Git commit:   b8571fd
 Built:        Fri Oct  6 18:01:48 2017
 OS/Arch:      windows/amd64
 Experimental: true

確認 docker 資訊:

PS C:\> docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 17.10.0-ee-preview-3
Storage Driver: windowsfilter (windows) lcow (linux)
 LCOW:
Logging Driver: json-file
Plugins:
 Volume: local
 Network: ics l2bridge l2tunnel nat null overlay transparent
 Log: awslogs etwlogs fluentd json-file logentries splunk syslog
Swarm: inactive
Default Isolation: hyperv
Kernel Version: 10.0 16299 (16299.15.amd64fre.rs3_release.170928-1534)
Operating System: Windows Server Standard
OSType: windows
Architecture: x86_64
CPUs: 4
Total Memory: 7.999GiB
Name: twvtdockerlix
ID: UFZV:ZT43:SBU6:7IXD:ADDW:I3VZ:S22F:ZN7D:BZ6X:OX2D:5BU7:6ZBQ
Docker Root Dir: C:\ProgramData\docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Experimental: true
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

啟用 LCOW:

[Environment]::SetEnvironmentVariable("LCOW_SUPPORTED", "1", "Machine")
Restart-Service Docker

關閉 LCOW

[Environment]::SetEnvironmentVariable("LCOW_SUPPORTED", $null, "Machine")
Restart-Service Docker

確認 LCOW 設定:

PS C:\> Get-ChildItem Env:

Name                           Value
----                           -----
LCOW_SUPPORTED                 1

好了,到這裡之後,LCOW 看似完成,當你開始執行 docker pull 一個 Linux 的 Image 時,Docker 真的在下載且不會跳出這是 Windows 架構不能下載...之類的錯誤訊息,不過最後還是會出現一個關鍵字 Linux Container 的錯誤。就這樣,我前後搞了一個多月測試,不管 Server Core 怎麼架、Docker EE Preview 怎麼玩 LCOW 效果總是在最後一步出錯。有一陣子總覺得,是不是官方那篇 blog 在唬爛我們。好處不能說沒有,拜 Server Core 只有指令模式之賜,和 Powershell 的感情突然好了起來。

啟用 LCOW 的最後一哩

要啟用 LCOW 功能,其實還有最後一哩要走。

參考:https://github.com/linuxkit/lcow

目前 Docker EE Preview 並無把 LinuxKit with LCOW 整合進來,所以我們必須幫 Docker EE Preview 改頭換面。

首先,安裝全新 docker.exe 與 dockerd.exe:

Invoke-WebRequest -UseBasicParsing -OutFile dockerd.exe https://master.dockerproject.org/windows/x86_64/dockerd.exe
Invoke-WebRequest -UseBasicParsing -OutFile docker.exe https://master.dockerproject.org/windows/x86_64/docker.exe

把取得的 docker.exe 與 dockerd.exe 覆蓋 C:\Program Files\Docker 的原執行檔。然後到 Linuxkit 下載最新的 LinuxKit 的 release.zip:

Remove-Item "$env:ProgramFiles\Linux Containers" -Force -Recurse
Expand-Archive release.zip -DestinationPath "$Env:ProgramFiles\Linux Containers\."
rm release.zip

這裡如果透過 Powershell 去下載 LinuxKit 的 release.zip,會收到一個 SSL/TLS 的錯誤,可以參考:Powershell Invoke-WebRequest Fails with SSL/TLS Secure Channel 討論,預設 Powershell 使用 TLS 1.0,但 github 已升級使用 TLS 1.2。可以先執行 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 來宣告採用 TLS 1.2 連線。

PS C:\> docker version
Client:
 Version:       master-dockerproject-2018-03-06
 API version:   1.37
 Go version:    go1.9.4
 Git commit:    0c75f522
 Built: Tue Mar  6 23:53:10 2018
 OS/Arch:       windows/amd64
 Experimental:  false
 Orchestrator:  swarm

Server:
 Engine:
  Version:      master-dockerproject-2018-03-06
  API version:  1.37 (minimum version 1.24)
  Go version:   go1.9.4
  Git commit:   f3a3778
  Built:        Wed Mar  7 00:01:03 2018
  OS/Arch:      windows/amd64
  Experimental: false

可以看到 Version 明顯不同了。不過 LCOW 需要在 Experimental 模式下,執行 .\dockerd.exe -D --experimental 試著在 Debug 模式下啟用 --experimental

如果重新啟動後的 docker service 的 Experimental 沒有啟動,可重新註冊 dockerd.exe 服務:

  • .\dockerd.exe --unregister-service
  • .\dockerd.exe --experimental --register-service

測試 LCOW 功能

docker run --platform linux --rm -ti busybox sh
docker run --platform linux --rm -ti ubuntu sh

現在你可以看到 Linux Container 已順利運作在 Windows Container 之中。

如果要執行舊版本的 Images,那麼請加上 --isolation=hyperv

這是在公司 VMWare 裡巢狀 Hyper-V 的 Server Core 操作:

PS C:\> docker load -i .\ubuntu.tar
0f5ff0cf6a1c: Loading layer [==================================================>]    126MB/126MB
f1c896f31e49: Loading layer [==================================================>]  15.87kB/15.87kB
51db18d04d72: Loading layer [==================================================>]  14.85kB/14.85kB
f51f76255b02: Loading layer [==================================================>]  5.632kB/5.632kB
174a611570d4: Loading layer [==================================================>]  3.072kB/3.072kB
Loaded image: ubuntu:latest
PS C:\> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              dd6f76d9cc90        4 months ago        177MB
PS C:\> docker run -it --rm ubuntu:latest sh
# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
#

執行不用特別加 --platform 參數 LCOW 也能正常運作。

FAQ

如果 VM 巢狀虛擬化失敗,那麼會得到以下錯誤訊息:

PS C:\> docker load -i .\ubuntu.tar
failed to start service utility VM (applydiff 02649b8c5149885e888016039f2de79ff1e9fbfdd9bf1cb84cb3593d0901e2af): container 02649b8c5149885e888016039f2de79ff1e9fbfdd9bf1cb84cb3593d0901e2af_svm encountered an error during CreateContainer: failure in a Windows system call: No hypervisor is present on this system. (0xc0351000) extra info: {"SystemType":"container","Name":"02649b8c5149885e888016039f2de79ff1e9fbfdd9bf1cb84cb3593d0901e2af_svm","Layers":null,"HvPartition":true,"HvRuntime":{"ImagePath":"C:\\Program Files\\Linux Containers","LinuxInitrdFile":"initrd.img","LinuxKernelFile":"bootx64.efi"},"ContainerType":"linux","TerminateOnLastHandleClosed":true}

可以確認 systeminfo 的內容:

PS C:\> systeminfo

Hyper-V Requirements:      VM Monitor Mode Extensions: No
                           Virtualization Enabled In Firmware: No
                           Second Level Address Translation: No
                           Data Execution Prevention Available: Yes

這部分需要先處理好巢狀虛擬化。

小結

說真的,你想想,Windows 這招有容乃大,真的是絕殺。Windows 平台擁抱 Linux 可以做到 1 + 1 > 2 的效果,當 Windows 整體 Linux 相關生態成熟後,Windows + Linux 雙生態的運作環境,這是多麼強大的組合。相反,Linux 平台反而無法去整合 Windows (VM不算)。

另一件事,再說一次,目前 LCOW 只能運作在 Server Core 1709 以上版本,Server Core 是無 GUI 純指令環境,如果你只專注在 Docker 管理與使用,那麼其實影響不大,但 Powershell 的投資我覺得是值得的。

Preview 一定有風險,使用前請詳細評估。

沒有留言:

張貼留言

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