Windows コンテナを AKS に追加する
竹井 悠人 (@yutopio_ja)
ソフトウェア エンジニア
株式会社 bitFlyer
2018/12/1 JAZUG札幌支部(きたあず) 第21回勉強会
https://jazug.connpass.com/event/103496/
免責
このトークは、情報提供のみを目的として行われており、正確性・最新性についての保
障は一切ありません。内容は、会社の見解ではありません。この情報を元にして生じた
不利益について、当社およびスピーカは一切の責任を負いません。
bitFlyer 上での取引についての詳細は、当社カスタマ サポートへお問い合わせくださ
い。
自己紹介
竹井 悠人
Yuto Takei C# 大好き一筋 17 年
あるときは大学生/ あるときは料理人
Let’s GO イーブイ欲しいです
投げ銭いつでもウェルカム
Software Engineer / CISO
最近 Kubernetes のこと、何もかもわからない...!!
参照: 2018/9/22 JAZUG 8周年記念のときの発表
本日のテーマ
Windows 用コンテナを
Azure 上の Kubernetes に追加してみる
(AKS でも簡単に Windows コンテナが走らせられる!)
本日の裏テーマ
Windows 用コンテナを
Azure 上の Kubernetes に追加してみる
(私とクジラの 3 日間に渡る死闘記)
何が問題なのか
ポータルで作れる AKS では Linux コンテナしか走らない
AKS と以下のそれぞれ (例) との相性はいまいち
● IIS が必要な Web アプリ
● .NET Framework をターゲットにしているバイナリ
● マネージド C++ とか P/Invoke が入るコード
● Deployment が Linux と Windows の両方を使うヘテロ構成
解決方法
1. Virtual Kubelet で、Pod を ACI で走らせる。簡単!
https://docs.microsoft.com/azure/aks/virtual-kubelet
2. 既存マシンに Kubelet をインストールする。自由!
https://docs.microsoft.com/virtualization/windowscontainers/kubernetes/joi
ning-windows-workers (英語のみ)
1. Virtual Kubelet の方法
ACI Connector なるツールを導入。以上!
az aks install-connector -g <RG> -n <Name>
https://docs.microsoft.com/cli/azure/aks#az-aks-install-connector
ざっくりいえば、インストールしたコンピュータで Kubelet もどきをホストし、
Pod を作成する指示があったら、ACI をその都度作って実行する
(ACI の全世界 GA がまだなので、リージョン選択は重要)
参考: 「Virtual Kubelet」を使って、Azure Kubernetes Service
(AKS)とAzure Container Instances (ACI)を連係する
https://qiita.com/hideaki_aoyagi/items/6228ed7cf62446deed93
2. Kubelet を本気で作る方法
作業手順
1. Docker をインストールする (Hyper-V)
2. OS のバージョンにあう Nano Server のイメージを走らせる
3. MS 謹製の SDN が利用されるようにする
4. Kubelet のスクリプトを起動する!
コンテナ技術と Azure
コンテナについて
仮想化技術の比較
● 仮想マシン (OS 含めゲストが実行する命令をホストがシミュレーション)
● コンテナ (カーネルをホストとゲストが共有。アプリ レイヤだけ仮想化)
関連するツールたち
● Docker
仮想化のための OS 機能の統合操作やコンテナ管理のためのユーティリティ
● Docker Compose
コンテナを自動的に起動するための YAML 記述ツール
● Kubernetes
機能群ごとのコンテナ作成やスケールのためのオーケストレーション ツール
Azure で使えるコンテナ系サービスたち
● Azure Kubernetes Service (AKS)
Kubernetes をホストするためのリソース。自動的に VM が作成され、管理される。
スケーリング可能 (クォータ上限に注意)
● Azure Container Instance (ACI)
単発でコンテナを起動するためのリソース
● Azure Container Registry (ACR)
コンテナ イメージを保存しておくためのストレージ。Docker Hub とだいたい同じ
デプロイ環境の作成
Azure VM 上でコンテナをビルドするには、入れ子仮想化のため v3 系のスケールが必
須。加えて次のソフトウェアを使う
● Visual Studio Code と以下の拡張機能
○ Docker
○ Kubernetes
○ Azure CLI
● Azure CLI (https://docs.microsoft.com/en-us/cli/azure/install-azure-cli)
● Docker for Windows (ダウンロードに Docker Hub アカウント必要)
● Git
● .NET Core SDK
Azure 上でのリソースの作成
● AKS の立ち上げ
○ Bs シリーズがおすすめ。事前にコア クオータをあげておく
○ 裏側で VM を作成するので 20 分くらいかかる
● ACR の作成
注: 今回はデモ用に専用のサブスクリプションを用意しています
認証について
Kubernetes を作成する際に、自動的に Azure AD 上にサービス プリンシパルが作成さ
れる
デプロイ環境での準備
ログイン
az login
az acr login --name <ACR Name>
az aks get-credentials --resource-group <RG Name> --name <AKS Name>
AKS から ACR への読み取り権限を通す
az aks show --resource-group <RG Name> --name <AKS Name>
--query "servicePrincipalProfile.clientId" --output tsv
az acr show --resource-group <RG Name> --name <ACR Name>
--query "id" --output tsv
az role assignment create --assignee <SP ID> --scope <ACR Res ID>
--role Reader
Kubernetes の準備
Kubernetes 管理ツールのインストール
az aks install-cli
このあと PATH に kubectl へのパスを通す
Kubernetes から ACR を開けるようにする
kubectl create secret docker-registry <ACR Name>
--docker-server <ACR Name>.azurecr.io
--docker-username <ACR Name>
--docker-password <Token>
--docker-email <Email>
ステータスの表示
AKS のステータスを見る
az aks browse --resource-group <RG Name> --name <AKS Name>
VS Code からもダッシュボードを起動できる
デプロイの表示
kubectl get deploy
ノードの表示
kubectl get pods
Dockerfile を作成する
基本となるコンテナを指定して、その上のファイル システムを展開。バイナリをビルドし
て、最後にコマンドを実行する
FROM microsoft/dotnet:2.1.403-sdk-alpine3.7 AS build
WORKDIR /app
ADD . .
RUN dotnet restore && 
dotnet publish -c Release -o out
FROM microsoft/dotnet:2.1.5-aspnetcore-runtime-alpine3.7 AS runtime
WORKDIR /app
COPY --from=build /app/MinChain/out .
ENTRYPOINT [ "dotnet", "MinChain.dll", "run", "config2.json" ]
コンテナのビルドからプッシュまで
ACR 上のコンテナの名前は
<ACR Name>.azurecr.io/<Name>:<Ver>
のようなタグで管理される
Dockerfile を作成したあとビルドして実行、うまく行ったら ACR にプッシュする
docker build --rm --tag=<Tag> .
docker run -it --rm <Tag>
docker push <Tag>
Git Bash 上から docker run や exec を実行する場合、先頭に winpty が必要なこと
がある
Windows Kubelet の作成
前提
● Azure アカウントを持っている
● AKS (Azure Kubernetes Service) はデプロイ済み
● サブスクリプションのコアのクオータが十分にある
● Windows コンテナのホストは Dv3 系 (Nested VM が必要なので)
> [System.Environment]::OSVersion.Version
Major Minor Build Revision
----- ----- ----- --------
10 0 17763 0
ホストとコンテナのバージョンとが一致していないと、動作しないケースがある
(古いコンテナ イメージは、原則として新しいホストから動く模様)
参考: https://docs.microsoft.com/virtualization/windowscontainers/
deploy-containers/version-compatibility
PowerShell でイメージのバージョンを確認
Windows イメージを作る
Docker をインストールした上で、ホスト上にコンテナを作っておく必要がある
docker pull mcr.microsoft.com/windows/nanoserver:1809
docker tag mcr.microsoft.com/windows/nanoserver:1809
microsoft/nanoserver:latest
docker run microsoft/nanoserver:latest
docker ps -a
現状の start.ps1 スクリプトでは Ethernet の NIC が決め打ちされている...
ので、スクリプトから見つけられるようアダプタ名を変更する必要がある。
Get-NetAdapter
Rename-NetAdapter -Name "vEthernet (nat)" -NewName "vEthernet (Ethernet)"
ネットワーク アダプタ名の変更
Kubelet を落としてくる
以下から、必要なバージョンの kubernetes-node-windows-amd64.tar.gz を落とす
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.12.md#n
ode-binaries
注意
● .tar.gz なので Linux マシンで tar xzf で解凍して scp して持ってくるか
7-zip などを落として解凍する必要がある
● いかにも公式そうな v1.12 Release Notes からは RC 版までしか落とせない
https://kubernetes.io/docs/setup/release/notes/
MS の SDN レイヤーをいれる
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
wget https://github.com/Microsoft/SDN/archive/master.zip -o master.zip
Expand-Archive master.zip -DestinationPath master
mv master/SDN-master/Kubernetes/flannel/l2bridge/* C:/k/
GitHub 上にある以下のパスのコードを C:k に展開している
https://github.com/Microsoft/SDN/tree/master/Kubernetes/flannel/l2bridge
最後に実行
.start-kubelet.ps1
これで行けるはず...!!!!
Demo
やってみよう!
備考
Windows Server 2016 では動作が怪しい
HSN (Host Network Service) 系の PowerShell コマンドがない
新しめの Windows 10 でも動く
Hyper-V を入れるためコマンドは以下
Enable-WindowsOptionalFeature -Online
-FeatureName Microsoft-Hyper-V
-All
1. エラーがでている場合でも、先頭が E ならば致命傷ではない
気づくまでに私の 2 日分のランチ時間が蒸発しました
E1130 15:47:33.276038 4720 server.go:731] Kubelet needs to run as uid `0`.
It is being run as -1
E1130 15:47:34.384035 4720 eviction_manager.go:243] eviction manager:
failed to get get summary stats: failed to get node info: node "sv2019" not
found
E1130 15:47:34.464392 4720 kubelet.go:2236] node "sv2019" not found
E1130 15:48:15.206372 4720 perfcounter_nodestats.go:144] Unable to get cpu
perf counter data; err: unable to collect data from counter. Error code is
800007d6
奮闘記
普通、このエラーみたら、起動に失敗したんだ、と
思うじゃないですか
https://github.com/kubernetes/kubernetes/blob/master/cmd/kubelet/app/server.go
731 行目付近
if err := checkPermissions(); err != nil {
klog.Error(err)
}
checkPermissions の定義は 417 行目あたりに
func checkPermissions() error {
if uid := os.Getuid(); uid != 0 {
return fmt.Errorf("Kubelet needs to run as uid `0`. It is being run as
%d", uid)
}
奮闘記 (いちおう調べた)
エラー出力するだけで、落ちる様子がない? あれ?
そもそもこいつの戻り値を変えるにはどうすれば?
どうやってもエラー
出るやないかい!
奮闘記
2. Server Core バージョンでは動作しない
私の 2 日分の睡眠時間が蒸発(ry
以下のすべての組み合わせでうまく行きませんでした
● Windows Server
2016 (Build 14393), 1709 (16299), 1803 (17134), 2019 (17763)
● Kubelet 1.12.0 - 3
(原因がわかる方がいたら、ぜひ教えてください)
Docker 単体であれば、次のコマンドでうまくはいる
Install-WindowsFeature -Name Hyper-V -IncludeManagementTools
Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name Docker -ProviderName DockerMsftProvider
なお Desktop Experience ありのバージョンとでは、
インストールできる Docker のランタイムが異なる模様
奮闘記
奮闘記
3. ネットワークが起動しないことがある
start-kubelet.ps1 実行後、ダッシュボードからは、ノードが正しく動いているように見える
奮闘記
3. ネットワークが起動しないことがある
しかしノードの状態をみると、ネットワーク利用不可、となっている
(すなわち、Pod を作成しても、このノードにいかない)
こちらも原因がわかる方がいたら、ぜひ教えてください
まとめ
目的: AKS 上で Windows コンテナが使いたいケースがある
(.NET Framework のターゲット、ネイティブ アプリを走らせたいなどの理由)
方法
1. Virtual Kubelet を作る方法 (簡単。ACI のプロキシになる)
2. Kubelet を作る方法
● VNet を自由に配置できる、スケール アップできる、などの自由度あり
● Windows マシンに Kubelet を配置して、Kubernetes と SDN を構築する
欠点
ハマりポイント多数。泥沼化しても調べる覚悟が必要

Windows コンテナを AKS に追加する