KubernetesでWindowsコンテナをクラスタ化して管理～Windows Node構築編～

本記事は[「クラウド時代のシステム管理」のこちらの記事](https://www.takanyan.net/kubernetes-windows-3-setup-nodes/)の転載です。

過去2回の記事で<a href="https://www.takanyan.net/kubernetes-windows-1/" rel="noopener" target="_blank">環境のセットアップ</a>と<a href="https://www.takanyan.net/kubernetes-windows-2-setup-master/" rel="noopener" target="_blank">Linux上でのKubernetes Master Nodeの構築</a>を行いました。今回はクラスタ化されるWindows Nodeの構築を行います。

<!--more-->

## 0. 環境の構成の確認と参考サイト

今回解説する手順は、環境全体のうち次の図にあるWorker Node部分の構築手順です。

<a href="https://www.takanyan.net/wp-content/uploads/2018/03/windows-node.png"><img src="https://www.takanyan.net/wp-content/uploads/2018/03/windows-node.png" alt="Windows Node" class="aligncenter size-full wp-image-484" /></a>

以下の手順は、Microsoft Docsにある<a href="https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/creating-a-linux-master" rel="noopener" target="_blank">こちらのサイトの手順</a>をもとに構築しています。ただし、Kubernetesは新しいバージョンがどんどんリリースされるため、手順が使えなくなる可能性もあるのでご注意ください。また、日本語版のドキュメントも存在していますが、内容のUpdateや間違いの修正が反映されていないため、実行するコマンドや手順自体は上記リンク先の英語版で確認することをお勧めします。

### 0-1. 執筆後～記事リリースまでの間の追記

現在、Microsoft本社で行われているMVP Global Summitに参加しております。以下の手順の検証を行った2018年2月中旬の段階では正しい内容でした。しかし、参照元ドキュメントを書いたりWindowsのKubernetes対応開発を行っているチームとディスカッション・交流をした数時間後、Github上のScriptやツール類の更新が急激に進み、正しくなくなっている可能性があります。最新の内容は本記事の後に「flannelを使ったネットワーク構成自動化編」のような内容で執筆しようと考えています。

## 1. Windows Server 1709上でDockerセットアップ

### 1-1. NIC名を英語名称に変更
後半（2-1.）でKubernetesの設定を行うPowerShellスクリプトをダウンロードしますが、その内容が英語版Windows前提となっているため、事前にKubernetes Masterと通信するNICの名称を『Ethernet』に変更しておきます。日本語版Windowsのデフォルトでは『イーサネット』となっているため、このままでは設定スクリプトが正常に動きません（動いたように見えてしまいますが・・・）

NICの名称を変更するには、Windows Nodeのコンソール接続かRDP接続をした後、PowerShellで以下のコマンドを実行します。以下の例では前後に確認コマンドも実行しています。

```PowerShell
C:\> powershell
PS C:\> Get-NetAdapter
Name                   InterfaceDescription                              ifIndex  Status   MacAddress              LinkSpeed
----                        --------------------                                        -------     ------      ----------                       ---------
イーサネット   Microsoft Hyper-V Network Adapter 2            Up         00-15-5D-01-0B-0E  1 Gbps

PS C:\> Rename-NetAdapter -Name "イーサネット" -NewName "Ethernet"
PS C:\> Get-NetAdapter
Name                   InterfaceDescription                              ifIndex  Status   MacAddress              LinkSpeed
----                        --------------------                                        -------     ------      ----------                       ---------
Ethernet             Microsoft Hyper-V Network Adapter 2            Up         00-15-5D-01-0B-0E  1 Gbps
```

### 1-2. Dockerのインストール

過去の記事でも書いていますが、WindowsへのDockerのインストールはPowerShellで以下のとおり実行可能です。なお、Windows Server version 1709ではインストール後に2回OS再起動を行わないとDockerサービスが自動起動しませんでした。

```PowerShell
PS C:\> Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
PS C:\> Install-Package -Name Docker -ProviderName DockerMsftProvider 
（Yes/Noを聞かれたら「Y」と明示的に入力する）
PS C:\> Restart-Computer -Force
【2回OS再起動する】
```

## 2. Kubernetesのインストールと設定

### 2-1. Kubernetes設定Scriptの導入

まずはMicrosoftがGithub上で公開しているSDNリポジトリから必要なScriptやプログラムを入手します。ここでは、私が動作検証を行った2018年2月7日のCommitからファイルをダウンロードします。最新版などに変更したい場合は1行目のURLを変更します。また最終行の削除するフォルダ名も適宜変更します。

```PowerShell
PS C:\> wget https://github.com/Microsoft/SDN/archive/908983aa5ad5814a521fe57c7d7720950ac1ec25.zip -o master.zip
PS C:\> Expand-Archive master.zip -DestinationPath master
PS C:\> mkdir C:\k\
PS C:\> mv master\SDN-master\Kubernetes\windows\* C:\k\
PS C:\> rm -recurse -force master,master.zip
```

スクリプトのダウンロードが完了したら、ダウンロードしたスクリプトの実行を許可するためのPowerShellを実行します。

```
PS C:\> Unblock-File C:\k\*
```


### 2-2. Kubernetes実行用コンテナのPausedイメージ作成

後で利用するため、コンテナのPausedイメージを作成します。まず、Windows Serverのイメージをダウンロードし、ダウンロードしたバージョンを最新であるとタグ打ちします。

```PowerShell
PS C:\> docker pull microsoft/windowsservercore:1709
PS C:\> docker tag microsoft/windowsservercore:1709 Microsoft/windowsservercore:latest
```

次に、先ほどダウンロードしたスクリプトの中にあるDockerfileを使ってPausedイメージを作成します。

```PowerShell
PS C:\> cd C:\k\
PS C:\k\> docker build -t kubeletwin/pause .　←最後のピリオドを忘れない
```


### 2-3. Kubernetesのインストール

Kubernetesのバイナリはtar.gz形式で配布されているので、Linuxサーバーでダウンロードして展開します。

```bash
$ wget https://storage.googleapis.com/kubernetes-release/release/v1.9.2/kubernetes-node-windows-amd64.tar.gz 
$ tar zxf kubernetes-node-windows-amd64.tar.gz
```

展開後、中にあるkubelet.exe, kube-proxy.exeといったkubeから始まるファイルをSCPなどで取り出し、Windows Nodeに展開します。Windows Nodeへのファイル転送には共有フォルダなどを使います。PowerShellでは共有フォルダから直接<code>cp</code>コマンドでファイルをコピーできるので便利です。（コマンドプロンプトの場合は一旦ネットワークドライブとしてマウントする必要がある）

```PowerShell
PS C:\>  mkdir C:\k\
PS C:\>  cd C:\k\
PS C:\k\>  cp \\(共有ファイルサーバーのIP)\(フォルダのパス)\kube*.exe .\
```

### 2-4. Kubernetesの設定とKubernetesクラスタへの参加

Kubernetes Masterに管理操作を実行できるよう、認証ファイルを作ります。認証設定ファイルの内容を表示させ、コピーします。

```bash
$ cat ~/.kube/config
(出力結果をすべてコピー)
```

コピーした結果をWindows Nodeに作成したテキストファイルに書き込みます。なお、SCPで認証ファイルをそのまま持ってきても大丈夫です。

```PowerShell
PS C:\> cd C:\k\
PS C:\k\> notepad
```

次に、Kubernetes Node Agent実行に必要な環境変数を設定します。

```PowerShell
PS C:\k\> [Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\k", [EnvironmentVariableTarget]::Machine)
PS C:\k\> [Environment]::SetEnvironmentVariable("KUBECONFIG", "C:\k\config", [EnvironmentVariableTarget]::Machine)
```

## 3. Kubernetes起動とクラスタ参加確認

### 3-1. Kubernetesの起動

ここまででKubernetesのWindows Node Agent起動の準備ができたので、起動を行います。ここでは、サービスとしてではなくフォアグラウンドのプログラムとして起動します。正、フォアグラウンドで起動すると非常に多くの出力が出るので、別のPowerShell実行Windowを起動してKubernetesのkubeleet.exeを起動します。

```PowerShell
PS C:\k\> Start-Process powershell
(別ウィンドウで以下を実行。念のため環境変数を再度設定)
PS C:\k\> $env:Path += ";C:\k"
PS C:\k\> $env:KUBECONFIG="C:\k\config"
PS C:\k\> ./start-kubelet.ps1 -ClusterCidr 172.16.0.0/16
```

次にkube-proxy.exeを起動します。

```PowerShell
PS C:\k\> Start-Process powershell
(別ウィンドウで以下を実行。念のため環境変数を再度設定。)
PS C:\k\> $env:Path += ";C:\k"
PS C:\k\> $env:KUBECONFIG="C:\k\config"
PS C:\k\> ./start-kubeproxy.ps1
```

### 3-2. 動作テスト

ここまでのWindows Nodeの構築作業をWinWorker01,02,03の3台で行うことでクラスタを構成するNodeを作ります。3台ともKubernetesのプロセスを起動したら、Kubernetesマスターから認識されていることを確認します。

```bash
$ kubectl get nodes
NAME          STATUS     ROLES     AGE       VERSION
kube-master   Ready   <none>   15d       v1.9.2
winworker01   Ready  <none>   15d       v1.9.2
winworker02   Ready  <none>   14d       v1.9.2
winworker03   Ready  <none>   14d       v1.9.2
```

ここまででコンテナを起動するNodeと管理するWorkerができましたが、このままではコンテナ間のルーティングが設定されていないため、コンテナ同士で通信したりすることができません。
次回は、コンテナ間のネットワーク設定の方法と将来について書きます。