Virtual Kubeletを使ってKubernetesからAWS Fargateも管理しよう

# 概要
Virtual Kubelet (以降VK)とは MicrosoftがOSSとして開発しているもので、Kubernetesクラスタ外のプラットフォームに対してAPI通信することで仮想的にクラスタ内部にあるかのうように管理できるKubeletを拡張した機能です。
発音としてはバーチャルキューブレットと言っている人が多いようです。
2018年12月にCNCFのSandbox Projectsに加わったことで注目が集まっています。
現在は開発途上のため、プロダクション環境での利用は非推奨です。

## 嬉しいこと
メリットは大きく３つあると思います。

1. VKの開発者は「ユーザがハードウェアの管理からの開放される」ことが最も大きいメリットと言っています。
例えば、Kubernetesクラスタを運用していて、一時的にリソースの拡張が必要になった時、VKを利用すれば AWS Fargate・Azure Container Instances・AliCloudなどを利用して必要な分だけリソースを拡張することができます。

1. KubernetesのIoTへの応用です。
IoTデバイスはkubeletを動作させられるほどのリソースを持っていないことが多いです。そのような機器にAPIで通信するだけでKubernetesから操作できるようになるというのは大きなメリットになると言えます。実際、MicrosoftはVKのIoTへの応用を考えているようです。

1. これは個人的な意見ですが、一つのKubernetesクラスタから複数のクラウドベンダーに接続することができるようになることで、クラウドベンダーにロックインされなくなるというのも大きなメリットであると思います。
## 仕組み
![VKArchitecture.PNG](https://qiita-image-store.s3.amazonaws.com/0/285536/c0b1e8b0-98c8-4c2e-e7e4-c807d9a5d97f.png)

KubernetesクラスタにVKのPodがあり、そのPodはKubernetesからはNodeとしても認識されます。そのPod兼Nodeが外部環境とAPI通信をすることでクラスタ外のプラットフォームと接続することができるようになっています。

また、現在はproviderとして連携できるのは以下の通りですが、今後更に増えていくことが予想されます。（クラウドプロバイダーだけでなくVMwareなども対応していくと個人的には嬉しいです。）
providerを個人で作成することもそこまで難しくはないそうです。

- Alibaba Cloud ECI Provider
- Azure Container Instances Provider
- AWS Fargate Provider
- Hyper.sh Provider
- Service Fabric Mesh Provider

# 実際に使ってみる
※ VKは現在開発段階のものなのでプロダクション環境での利用は非推奨です。
## 必要な環境
以下の環境が既にある前提で進めます。

- Kubernetesクラスタ
- kubectlコマンド
- Go動作環境（VKはgoで書かれてます）
- Worker NodeにECSFullAccess権限が付与済み

## VKのインストール
以下の通り実行すればVKコマンドのインストールは完了です。
複雑なことはやっていないので説明は省略します。

```bash
export GOPATH=$HOME/go
mkdir -p $GOPATH/src/github.com/virtual-kubelet
cd $GOPATH/src/github.com/virtual-kubelet
git clone https://github.com/virtual-kubelet/virtual-kubelet
cd virtual-kubelet
make build
mv bin/virtual-kubelet /usr/bin/
```
※ t2.microでは`make build`でrun time errorによりbuildできませんでした。

## 設定変更
```bash
mkdir -p /etc/kubernetes/
cp providers/aws/fargate.toml /etc/kubernetes/
```
fargate.tomlの必要な部分を書き換えます。

```fargate.toml
Region = "ap-northeast-1(Fargateクラスタのリージョン)"
ClusterName = "virtual-kubelet-test（Fargateクラスタの名前。指定した名前がなければ作成されます。）"
Subnets = "subnet-1234（Fargateクラスタの所属するサブネット）"
SecurityGroups = "sg-1234（アタッチするSG）"
AssignPublicIPv4Address = true
ExecutionRoleArn = ""
CloudWatchLogGroupName = ""
PlatformVersion = "LATEST"
OperatingSystem = "Linux"
CPU = "20"
Memory = "40Gi"
Pods = "20"
```

## VKの起動
kubelet port の設定（デフォルトでは`10250`ですが変更している方は適宜変更してください）

```bash
export KUBELET_PORT="10250"
```

fargate.tomlがあるディレクトリで以下のコマンドを実行

```bash
virtual-kubelet --provider aws --provider-config fargate.toml --namespace all
```
コマンド実行後、以下の通りnodeにvirtual-kubeletがあることが確認できます。
また、AWS Fargate の画面でも指定したクラスタの名前でクラスタが作成されていることが確認できます。

```bash
kubectl get nodes
NAME                                            STATUS    ROLES                      AGE       VERSION
ip-10-0-1-172.ap-northeast-1.compute.internal   Ready     controlplane,etcd,worker   5m        v1.12.3
ip-10-0-1-177.ap-northeast-1.compute.internal   Ready     worker                     3m        v1.12.3
ip-10-0-1-57.ap-northeast-1.compute.internal    Ready     worker                     4m        v1.12.3
virtual-kubelet                                 Ready     agent                      6s        v1.11.2
```
![キャプチャ1.PNG](https://qiita-image-store.s3.amazonaws.com/0/285536/d303e839-7372-2287-2c2d-27c33a9fc5a0.png)


## デプロイテスト
```nginx-VKtest.yml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: nginx
    ports:
    - containerPort: 80
      name: http
      protocol: TCP
    - containerPort: 443
      name: https
  dnsPolicy: ClusterFirst
  nodeSelector:
    kubernetes.io/role: agent
    beta.kubernetes.io/os: linux
    type: virtual-kubelet
  tolerations:
  - key: virtual-kubelet.io/provider
    operator: Exists
```

正常に実行できていれば以下の通りpodsがデプロイされていることが確認できます。
また、AWS Fargateの画面でも指定したクラスタにデプロイされていることが確認できます。

```bash
kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
nginx     1/1       Running   0          38s
```
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/285536/0973e01b-88d4-7564-a6ad-53408405bdb8.png)

以上。
# 参考
[公式GitHub](https://github.com/virtual-kubelet/virtual-kubelet)
[AWS Open Source Blog - Running AWS Fargate with virtual-kubelet](https://aws.amazon.com/jp/blogs/opensource/aws-fargate-virtual-kubelet/)