はじめに
近年、Windows のコンテナ技術が進み、ニュースの記事でも見る機会が増えているように思います。
今回はそんな Windows のコンテナ化です。
Windows 10Pro / DockerDesktop の記事が散見されていたため、今回は記事少なめな k8s / WindowsServer2019SE で構築します。
環境構成
いつも通りに VirtualBox 上に・・・
Host Machine
開発端末 : Window10 Pro
VirtualBox:6.0.16
Guest Machine
# | Rancher | K8S Master | K8S Worker |
---|---|---|---|
OS | CentOS 7.6.1810 | CentOS 7.6.1810 | WindowsServer 2019 StandardEvaluation |
docker | 19.03.5 | 19.03.5 | 19.03.5 |
Rancher | 2.3.5 | - | - |
K8S | - | 1.17.2 | 1.17.2 |
CPU/MEM/Disk | 2P / 4GB / 8GB | 2P / 4GB / 8GB | 4P / 8GB / 50GB |
IPAddress | 192.168.10.70 | 192.168.10.71 | 192.168.10.72 |
準備
- VirtualBox 上に予め3台のサーバを構築します
※各サーバのはネットワークはブリッジアダプターで構築し、IP アドレスを静的に設定します
※Windows サーバは「デスクトップ エクスペリエンス」でインストールします
⇒今回は 180 日間の無料トライアル版の ISO を使ってインストールしています
Windows Server 2019 Evaluation
※Windows サーバには以下の設定をしています
・WindowsDefender Firewall / Windows Firewall の無効化
・VirtualBox Guest Additions をインストール(任意)
・コンピュータ名変更(任意)
※以下、K8S の基本構成のため、注意事項だけ記載しているのと「gluster on k8s」を参考に - Rancher の構築
注意事項、特になし。docker run
の 1 liner で起動します - クラスタの作成
※クラスターのタイプは「カスタム」で構築します
※今回は Windows Worker を登録するため、以下設定でクラスタを構築しています
・ネットワークプロバイダー:Flannel
・Windows Support:有効
・Flannel Backend:VXLAN(Overlay)
- K8S Master の構築
※Rancher の管理コンソールにある「Node Run Command」から実行用コマンドを使って構築してください
※「etcd」、「Control」をチェックし、「Worker」のチェックは外してください
※必要に応じて詳細オプションを指定してください(複数 NIC 指している場合は IP を指定できます)
ここまでで、VM の準備、Rancher、K8S Master の構築が完了しました。
WindowsServer2019SE docker install
以下を参考にして構築していきます。
MS 公式:環境をセットアップする
# 以下、1~3 を Powershell で実行
# 1. Docker-Microsoft PackageManagement プロバイダーのインストール
PS C:\Users\Administrator> Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
続行するには NuGet プロバイダーが必要です
...
今すぐ PowerShellGet で NuGetプロバイダーをインストールしてインポートしますか?
[Y] はい(Y) [N] いいえ(N) [S] 中断(S) [?] ヘルプ (既定値は "Y"): Y
# 2. docker install
PS C:\Users\Administrator> Install-Package -Name docker -ProviderName DockerMsftProvider
パッケージは、信頼済みとマークされていないパッケージ ソースから取得されています。
'DockerDefault' からソフトウェアをアンインストールしますか?
[Y] はい(Y) [A] すべて続行(A) [N] いいえ(N) [L] すべて無視(L) [S] 中断(S) [?] ヘルプ (既定値は "N"): Y
警告: A restart is required to enable the containers feature. Please restart your machine.
Name Version Source Summary
---- ------- ------ -------
Docker 19.03.5 DockerDefault Contains Docker EE for use with Windows Server.
# 3. OS reboot
PS C:\Users\Administrator> Restart-Computer -Force
# 4. 確認(cmd(コマンドプロンプト)で実行)
C:\Users\Administrator>docker version
Client: Docker Engine - Enterprise
Version: 19.03.5
...
Server: Docker Engine - Enterprise
Engine:
Version: 19.03.5
...
k8s Worker 登録
Rancher の管理コンソールからクラスターの編集画面、再下端で Windows 用のコマンドを取得します。
※ノードの「オペレーティングシステム」を「Windows」にすると自動的に「Worker」のみが選択されるようです。
青いボタンをクリックしてコマンドをコピーし、Windows サーバのPowershellで実行しましょう。
途中、Rancherの画面でエラーが何度か表示されますが、時間経過で解消されます。
10~20分を目安で構築が完了し、クラスターに組み込まれます。
Windows コンテナ作成
それでは早速 Windows コンテナを作成してみましょう。
こちらも以下の公式サイトを参考にデプロイします。
MS 公式:Kubernetes リソースのデプロイ
※今回使った K8S バージョンですと公式の yaml をそのまま使えなかったので、少し修正しています
まずはコンテナのデプロイから。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: win-webserver
name: win-webserver
spec:
selector:
matchLabels:
app: win-webserver
replicas: 1
template:
metadata:
labels:
app: win-webserver
name: win-webserver
spec:
containers:
- name: windowswebserver
image: mcr.microsoft.com/windows/servercore:1809
command:
- powershell.exe
- -command
- "<#code used from https://gist.github.com/wagnerandrade/5424431#> ; $$listener = New-Object System.Net.HttpListener ; $$listener.Prefixes.Add('http://*:80/') ; $$listener.Start() ; $$callerCounts = @{} ; Write-Host('Listening at http://*:80/') ; while ($$listener.IsListening) { ;$$context = $$listener.GetContext() ;$$requestUrl = $$context.Request.Url ;$$clientIP = $$context.Request.RemoteEndPoint.Address ;$$response = $$context.Response ;Write-Host '' ;Write-Host('> {0}' -f $$requestUrl) ; ;$$count = 1 ;$$k=$$callerCounts.Get_Item($$clientIP) ;if ($$k -ne $$null) { $$count += $$k } ;$$callerCounts.Set_Item($$clientIP, $$count) ;$$ip=(Get-NetAdapter | Get-NetIpAddress); $$header='<html><body><H1>Windows Container Web Server</H1>' ;$$callerCountsString='' ;$$callerCounts.Keys | % { $$callerCountsString+='<p>IP {0} callerCount {1} ' -f $$ip[1].IPAddress,$$callerCounts.Item($$_) } ;$$footer='</body></html>' ;$$content='{0}{1}{2}' -f $$header,$$callerCountsString,$$footer ;Write-Output $$content ;$$buffer = [System.Text.Encoding]::UTF8.GetBytes($$content) ;$$response.ContentLength64 = $$buffer.Length ;$$response.OutputStream.Write($$buffer, 0, $$buffer.Length) ;$$response.Close() ;$$responseStatus = $$response.StatusCode ;Write-Host('< {0}' -f $$responseStatus) } ; "
nodeSelector:
beta.kubernetes.io/os: windows
デプロイも Rancher から実施できます。
「Default」の名前空間の「リソース」⇒「ワークロード」を選択し、右上「YAML をインポート」をクリックします。
「インポートモード」を「プロジェクト」とし、yaml コードを入力 ⇒ 「インポート」ボタンでデプロイされます。
次にアクセス確認用に Service をデプロイします。
こちらも Rancher からデプロイできます(デプロイ方法は上記と一緒)。
apiVersion: v1
kind: Service
metadata:
name: win-webserver
labels:
app: win-webserver
spec:
ports:
- nodePort: 30600
port: 80
protocol: TCP
targetPort: 80
selector:
app: win-webserver
type: NodePort
コンテナ、サービスがデプロイできたでしょうか。
初回起動時にコンテナイメージを pull するため、10~15分くらいかかります。
※servercore:1809 のイメージで 4.82 GB のサイズがありました。
また、NodePort で指定したポートに対して、Windows サーバにブラウザアクセスするとサンプルアプリがレスポンスします。
※今回の場合ブラウザで「 http://192.168.10.72:30600 」にアクセスすると以下の表示がされます
※コンテナの yaml ファイルに書かれている command 部のプログラムがレスポンスされます
まとめ
Windows コンテナいかがでしたでしょうか。
意外と簡単に k8s / WindowsServer 上にも windows コンテナが作成できたのではないでしょうか。
また、作成されたコンテナについて補足を。
プロセス分離化されている、Hyper-V 分離ではない
ProcessExplorer でプロセス状況を確認してみます。
Hyper-V 分離ですと「vmcompute.exe」の子プロセスとして起動しますが、
今回の場合「CExecSvc.exe」の子プロセスとして起動しているため「プロセス分離」としてコンテナが起動しています。
また、docker コマンドで確認すると、
こちらでもプロセス分離で起動していることが確認とれます。
※ついでにイメージ情報も表示してあります
コマンドラインにアクセスもできる
他コンテナ同様に Rancher からコンソールアクセスができます。
勿論のことですが、cmd から powershell も呼び出せます。