1. 程式人生 > >Windows Server 2019 的6處變化,提升您的 Windows 容器體驗(一)

Windows Server 2019 的6處變化,提升您的 Windows 容器體驗(一)

screenshot

出品丨Docker公司(ID:docker-cn)
編譯丨小東
每週一、三、五,與您不見不散!


目前,有大量的應用程式以 Docker 容器的形式執行在 Windows Server 2016 上,但 Windows 容器一直與 Linux 容器在效能方面存在著一些細小的差距。但是,在已經到來的 Windows Server 2019 中,它彌補了大部分的效能差距,因此現在的 Windows Docker 容器幾乎與 Linux 容器旗鼓相當。

接下來,我將介紹它主要的新功能。演示中所有的 Docker 映象都來自我在 GitHub 上的 dockerfiles-windows repo 中,您可以瀏覽

https://github.com/sixeyed/dockerfiles-windows 檢視完整程式碼。


screenshot

Windows Server 2019 使用的是 1809 版本的作業系統,Windows 10 的更新正在進行中,它將把這個核心新增到 Windows 10 中。所以,您可以在 Windows Server 2019 或者 Windows 10 的1809版本或更高版本上使用這些映象。


釋出的埠可以在 localhost 上訪問

Windows 容器可以讓您以常用的方式來發布埠,因此當網路流量在特定埠上進入您的計算機時,Docker 會將其定向到要處理的容器。但是在 Windows Server 2016 上,您只能從外部訪問埠,而不能在計算機上使用 localhost。

Windows 10 上的 Docker Desktop 已經解決了這一問題。所以,您可以在桌面上使用 localhost,但網路的相關問題是發生在 Docker Desktop 中而不是作業系統層(不能進行“loopback”操作)。

現在,在 Windows Server 2019 中,作業系統中的網路堆疊已經可以進行“loopback”操作了。所以,您可以這樣做:

PS> docker container run -d -p 8041:80 sixeyed/nginx:windowsservercore-1809 
103b486d29818e02bd0da8ab42d854c42179de3e116bf4bd38c1840adca9cde9

PS> iwr -useb -method Head http://localhost:8041

StatusCode : 200

如果您在 VM 中開發,或者在 CI 過程中使用 Docker,那麼這將變得非常方便。在 Windows Server 2016 上,您必須先獲取容器的 IP 地址才能從主機訪問它,但現在您可以直接從 localhost 中使用已釋出的埠來進行訪問。


命名管道可以與 Docker API 結合使用

在許多情況下,您希望在容器中執行軟體,該容器可以在執行它的主機上訪問 Docker API。 CI 是一個很好的例子,如果您使用的是多階段構建這種方法來構建您的應用程式,那麼您可以從容器內的原始碼進行編譯,而無需使用一大堆的工具來設定 CI 伺服器。

相反,您可以在容器中執行 Jenkins,並使用 docker 或 docker-compose 命令進行構建。在構建步驟中,您只需在桌面上執行的相同 Docker 命令即可。

但是在 Windows Server 2016 中,您必須通過 TCP / IP 來訪問 Docker API,這意味著您必須公開 Docker API 並使用 TLS 證書來保護它。然後,您還需對構建命令轉換為引數化,以便傳入 Docker API 配置:

& docker $dockerConfig image build $buildArg -t $fullTag .

構建時,在呼叫構建指令碼之前,您需要在 $ dockerConfig 變數中設定 Docker API 的配置來完成將證書儲存為 Jenkins 中的機密檔案:

$dockerConfig = '--host', 'tcp://192.168.160.1:2376', '--tlsverify', `
         '--tlscacert', $env:DOCKER_CA,'--tlscert', $env:DOCKER_CERT, '--tlskey', $env:DOCKER_KEY

程式碼看起來很難看,而且這意味著您還需要知道執行容器的機器的 IP 地址或主機名。 當在 Swarm 模式下執行時,這會變得更加困難。

現在,在Windows Server 2019中,您可以將 Docker API 的命名管道作為捲來安裝。管道是 Docker CLI 訪問在同一臺機器上執行的 Docker API 的預設端點,它也適用於在執行它們的機器上訪問 Docker API 的容器:

docker container run -d ` 
 -p 8080:8080 `
 -v C:\jenkins:C:\data `
 -v \\.\pipe\docker_engine:\\.\pipe\docker_engine `
 sixeyed/jenkins-sample:windowsservercore-1809

現在,您可以使用普通的 docker 和 docker-compose 命令而無需進行其他配置,因為容器內的 Docker CLI 可以從命名管道到達主機 API。這使得您的 Jenkins 工作步驟變得非常簡單。

您不再需要通過 TCP / IP 來公開 Docker API 了,這意味著您不需要建立、應用和迴圈 TLS 證書,並且容器內的客戶端也不需要知道執行它的主機的詳細資訊。


Swarm 模式支援Ingress網路

Docker Swarm 模式是一個非常簡單但功能非常強大的容器編排工具。您可以將執行 Docker 的多個伺服器連線到一個叢集中,然後通過將應用棧部署到群集來管理您的工作負載。

Windows Server 2019 也可能是第一個支援 Kubernetes 與 Windows 節點的版本。

Docker Swarm 負責排程容器來在 Swarm 中的節點上執行,並維護您請求的服務級別。如果您指定一個 Web 應用程式應該執行10個容器來進行 HA 和擴充套件,那麼 Docker 將在整個 Swarm 中啟動10個容器,如果關閉了一個帶有3個容器的伺服器,那麼 Docker 將在其餘伺服器上啟動替代容器。

您還可以使用 Docker 入口網路的路由網為跨容器的傳入流量進行負載均衡。這可以讓您做兩件非常有用的事情:

  • 您可以配置過度的服務,這將讓執行它的容器多於您叢集中的節點。部分或全部節點將執行服務容器的多個副本。
  • 您可以配置不足的服務,這將讓執行服務的容器少於您叢集中的節點。 部分節點將執行服務的零個副本,其他節點將執行單個副本。

入口網路意味著流量可以進入叢集的任何節點,Docker 將其路由到監聽容器。如果在收到請求的節點上執行的副本數為零,則會以靜默的方式將其重定向到執行容器的另一個節點。如果有多個副本,Docker 將負責負載平衡。

這是一個很棒的功能,但 Server 2016 中的 Windows 容器不支援它。您必須使用主機模式釋出,這意味著如果您想擁有公共可訪問的埠,則每個伺服器只能執行一個容器。(實際上,人們將 Windows 工作負載作為全域性服務執行,或者使用在混合叢集中的 Linux 容器上執行的反向代理來執行它們。)

現在 Windows Server 2019 支援 Docker 的入口模式,因此您可以使用所需的服務級別執行容器,並且可以增加或減少伺服器,Docker 會自動引導和負載均衡流量。

您可以切換到 Swarm 模式並執行我提供的簡單案例來驗證這一點:

案例程式碼地址:https://github.com/sixeyed/dockerfiles-windows/tree/master/whoami-dotnet

docker swarm init --advertise-addr 127.0.0.1 
 
docker service create ` 
 --publish 8070:80 `
 --replicas 5 `
 sixeyed/whoami-dotnet:nanoserver-1809

您會看到這樣的輸出,並且還可以看到所有副本都在執行:

overall progress: 5 out of 5 tasks 
1/5: running  [==================================================>] 
2/5: running  [==================================================>] 
3/5: running  [==================================================>] 
4/5: running  [==================================================>] 
5/5: running  [==================================================>] 
verify: Service converged

在 Swarm 模式下,您無法使用 localhost 來訪問已釋出的埠。您需要從外部發送通訊以使其到達入口網路。

在另一臺計算機上,您可以向叢集發出客戶端請求,並檢視來自不同容器的響應,即使它們都是在單個伺服器上執行的:

$ hostname
DESKTOP-BBD7UUM 
$
$ for ((i=1;i<=5;i++)); do curl http://win2019:8070; printf "\n"; done
I'm fccdf0ecea5b running on Microsoft Windows 10.0.17763 
I'm b00baa697176 running on Microsoft Windows 10.0.17763 
I'm 60a2be72474e running on Microsoft Windows 10.0.17763 
I'm 30edb8b1b302 running on Microsoft Windows 10.0.17763 
I'm 45c110bc5d34 running on Microsoft Windows 10.0.17763