KubernetesでWindowsコンテナをクラスタ化して管理～環境セットアップ編～

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

コンテナは1台のホスト上で起動することよりも、クラスタ化されたホスト群の中に複数分散配置して冗長化・負荷分散することが一般的です。コンテナをクラスタ化するソフトウェアはいくつかありますが、Kubernetesがほぼデファクトスタンダードになりつつあります。

<!--more-->

本記事から何回かに分けてKubernetesでWindowsコンテナをクラスタ化して管理する方法について解説します。なお、KubernetesでのWindowsコンテナの管理はKubernetes 1.9とWindows Server version 1709の組み合わせでベータサポートとなっています。（※前バージョンまではアルファサポートでした）


## 1. コンテナのクラスタ化をする目的

コンテナはアプリケーションとその実行環境（Library）をパッケージにし、どんな環境でも動くようにしたものです。この文面だけを読むと仮想マシンと同じに見えますが、コンテナは基本的には実行するOSとKernelを共有するため、ホストするOS上のプロセスとして起動されます。OS上のプロセスであるため、起動・再起動などが非常に高速で、Hypervisorのように仮想マシンごとにゲストOSが起動するよりオーバーヘッドが少ないのが特徴の一つです。

<strong>通常のアプリケーションとコンテナとの違い（<a href="https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/" rel="noopener" target="_blank">kubernetes.io</a>より引用）</strong>
<a href="https://www.takanyan.net/wp-content/uploads/2018/02/why_containers.png"><img src="https://www.takanyan.net/wp-content/uploads/2018/02/why_containers.png" alt="why_containers" width="1378" height="967" class="aligncenter size-full wp-image-440" /></a>


ただ、オーバーヘッドが少ないだけではコンテナの良さを生かし切れていません。実行環境がパッケージ化されている点とオーバーヘッドが少なく、プロセスとして気軽に起動・停止できる点を組み合わせると、Microserviceアーキテクチャを実装することができるようになります。

### 1-1. コンテナのクラスタはMicroserviceの実装方法の一つ

Microserviceについては、<a href="https://martinfowler.com/articles/microservices.html" rel="noopener" target="_blank">James Lewis/Martin Fowlerの"Microservices"(英語)</a>に詳細な解説があります。また、<a href="http://kimitok.hateblo.jp/entry/2014/11/09/211820" rel="noopener" target="_blank">日本語訳も存在</a>しています。

従来のアーキテクチャでは、一つのサービスを提供するためのシステムが、例えばWebシステムの3Tier Architectureのようにデータを持つDBサーバー、サービス提供のための機能を実装したアプリケーションサーバー、アプリケーションサーバーを負荷分散するためのロードバランサーのようにいくつかの機能で分けられています。そしてスケールアウトする場合はアプリケーションサーバーを複数用意することで実現します。

一般的に上記の例のようなアプリケーションサーバーには様々な機能が実装されているため、リリース後の運用をしてく中で保守開発をしていくことがだんだん困難になっていきます。これは、さまざまな機能が一つのOS上のプログラムとして実装されるため、ライブラリの依存関係などのテストが複雑になっていくためです。

そこで、アプリケーションサーバーに実装されている様々な機能を、一つ一つの機能単位で実行環境を分割し、それぞれの機能が単独で負荷分散されるような構成を考えます。機能単位で実行環境が分離されていれば、各機能は更新が容易になり、かつ機能ごとにスケーラビリティを確保することもできます。このように機能単位で小さなサービスを多数立ち上げるアーキテクチャをMicroserviceアーキテクチャと呼びます。


<strong>Microserviceと従来のアーキテクチャ（Monolithic）の違い（<a href="https://martinfowler.com/articles/microservices.html" rel="noopener" target="_blank">MartinFlower.com</a>より引用）</strong>
<a href="https://www.takanyan.net/wp-content/uploads/2018/02/microservice.png"><img src="https://www.takanyan.net/wp-content/uploads/2018/02/microservice.png" alt="Microservice Architecture" width="850" height="520" class="aligncenter size-full wp-image-433" /></a>


サービス提供に必要な機能を1つずつ小さなサービスとして分割する構成は、従来のHypervisorベースの仮想マシンではオーバーヘッドが大きくて実現できなかったのですが、コンテナのおかげで実現できるようになってきました。

### 1-2. コンテナクラスタ管理ソフトウェアの役割

コンテナのクラスタ化はMicroserviceアーキテクチャの実装の一つであると説明しました。Microserviceアーキテクチャを実際に作るためには、単体のコンテナホストだけでは不足している機能を管理ソフトウェアが提供する必要があります。コンテナ管理ソフトウェアのデファクトになってきている<a href="https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/" rel="noopener" target="_blank">Kubernetesのドキュメント「What is Kubernetes?」</a>では、提供する機能が記載されています。その一部を抜粋します。

* 秘密情報（パスワードなど）の配布
* アプリケーションのヘルスチェック
* オートスケール
* 負荷分散
* ローリングアップデート
* リソース監視

上記にある「負荷分散」「オートスケール」を実現するために、複数のコンテナホストにまたがって分散配置された1つの機能を提供するコンテナたちをネットワークでつなぐ必要があります。一つの提供サービスが多数の機能の組み合わせで実現できるような大規模な環境では、機能ごとに負荷分散するためのサブネットが必要になるため、必然的にコンテナ間をつなぐネットワークはSDNがベースとなります。そういったSDNの管理もKubernetes（やそのPlugin）の役割になります。


## 2. クラスタ環境に必要なOSの準備

### 2-1. 今回構築する環境の構成

ここまで長々と説明を書いてきましたが、作ってみたほうがどういった構成になるのか理解が進みます。ここでは、以下の図にあるような環境のセットアップを通じてKubernetesでWindowsコンテナをクラスタ化していきます。

<a href="https://www.takanyan.net/wp-content/uploads/2018/02/environment-1.png"><img src="https://www.takanyan.net/wp-content/uploads/2018/02/environment-1.png" alt="Kubernetes environment" width="937" height="518" class="aligncenter size-full wp-image-446" /></a>

上記の図の環境は、1台のHyper-Vホスト上で構築することが可能です。執筆時点ではKubernetesはHyper-Vコンテナの管理には対応していないため、Windows Serverコンテナのクラスタ化にNested Hyper-Vは必須ではありません。つまり、Windows 10 Proホスト上でも環境を作ることができます。以下では、Hyper-V上に環境を構築する前提で手順を紹介します。

### 2-2. Kubernetes Master用Linuxのセットアップ

KubernetesのMaster Nodeは現状Windows上でセットアップすることはできません。そこで、Master Node用にLinuxを用意します。ここではUbuntu Server 17.10を<a href="https://www.ubuntu.com/download/server" rel="noopener" target="_blank">こちらのサイト</a>からISOとしてダウンロードしてOSインストールを行います。OSインストール自体はウィザードに従って進めていき、SSH Serverのみ有効にしてインストールを完了させます。

OS起動後、IPアドレスを固定で設定するために<code>/etc/netplan/01-netcfg.yaml</code>ファイルの<code>eth0:</code>以下の行を編集します。

```sh
$ sudo vi /etc/netplan/01-netcfg.yaml
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
      addresses: [192.168.1.20/24]
      gateway4: 192.168.1.1
      nameservers:
        addresses: [192.168.1.253,192.168.1.1]
      dhcp6: no
```

また、パッケージを最新に更新しておきます。

```sh
$ sudo apt-get update
$ sudo apt-get upgrade
```

### 2-3. Worker Node用Windows Server 1709のセットアップ

Windows Server version 1709の初期セットアップは、ISOファイルからのOSインストール後、<code>sconfig</code>コマンドでIPアドレス、Remote Desktop有効化、Windows Updateを行います。

### 2-4. MACアドレススプーフィングの有効化

今回構築する環境では、1つのOS内に複数のコンテナが起動することができるため、コンテナごとにMACアドレスが異なります。仮想マシンではHypervisorが指定したMACアドレス以外の通信は拒否される設定になっていることが多いです。そこで、下図のようにネットワークアダプタの設定でMACアドレススプーフィングを許可するようにします。

<a href="https://www.takanyan.net/wp-content/uploads/2018/02/mac-address-spoofing.png"><img src="https://www.takanyan.net/wp-content/uploads/2018/02/mac-address-spoofing.png" alt="enable-mac-address-spoofing" width="722" height="682" class="aligncenter size-full wp-image-447" /></a>

以上で構築する環境の下準備が整います。次回はKubernetes Masterを構築します。