Amazon Elastic Container Service for Kubernetes (EKS)の所感

ついにAWSのマネージドKubernetesサービス「EKS」が発表されましたね！

この記事では、これまでKubernetes on AWSに取り組んできた @mumoshu の観点でEKSについてまとめてみたいと思います。

## @mumoshuって誰？

Kubernetes Incubatorのひとつ、[kube-aws](https://github.com/kubernetes-incubator/kube-aws)というKubernetesクラスタのプロビジョニングツールのメンテナです。

## Kubernetes on AWSのつらみ

これまでKubernetesをAWSで運用する場合の最も大きなつらみ（と思われていた）は、Kubernetesを自前でAWSにデプロイすることでした。

例えば、AzureやGCPにはそれぞれAKSやGKEといったKubernetesのマネージドサービスがあります。

AKSやGKEは「クラスタを作成する」という操作をすればKubernetesが使い始められたり、CLIやWeb UIから気軽に設定変更ができたりなど、Kubernetesのデプロイの敷居の高さや運用の複雑さをうまく隠蔽してくれます。

とはいえ、そもそもAWSとは前提が色々異なる(GKEは全ノードにPublic IPが振られてしまう=Private Subnetを利用したい場合は利用できない?、とか）ので普通は「GKEがあるからGCPに移行しよう」とはならないのですが、AWSを利用していた企業がGKEのためにわざわざGCPも使ってマルチクラウドに移行しちゃう、ということもあったようです。

それくらい、Kubernetesを自前でデプロイすることは忌諱されてきました。

AWSなどマネージドサービスが存在しないクラウド、またオンプレでのデプロイをサポートするために、

- kube-spray(Ansible)
- kops(Terraform)
- kube-aws(CloudFormation)

のようなOSSがコミュニティによってメンテされてきました。

## 既存のデプロイツールのスコープ

既存のデプロイツールのスコープは、

- Masterノード
    - Etcdノード
    - Controllerノード
- Workerノード

の２または３種類のノードから構成されるKubernetesクラスタをつくること、でした。

２か３なのは、ツールやその設定によって、EtcdとControllerを同じノードに同居させるか、させないかが異なるからです。

// ベストプラクティスとしてはEtcdはEtcdだけでクラスタを組んだほうがいいので、同居させない３の構成がよいとされています。

## EKSのスコープ

いよいよEKSの話です。

EKSは一言で言うと、Kubernetesマスタ（Etcd + Controller Node）のマネージドサービスです。

## EKSの特徴

細かい点は、Heptio社CTOのこの一連のツイートが参考になりますが、かいつまむと以下のとおりです。

https://twitter.com/jbeda/status/936006108430270464

### Workerノードのデプロイはスコープ外

- Kubernetesクラスタをデプロイする場合
    - 前述のデプロイメントツールやCloudFormationを利用して、EKS + Workerノードをセットでつくる
    - または、EKSをポチポチしてMasterノードをつくり、EC2インスタンスをポチポチして　AnsibleやkubeadmでプロビジョニングすることでWorkerをつくる
    - など、ということになります。
- EtcdやControllerノードのデプロイからは解放されそうです
- 「WorkerノードもEKSが管理してほしい」という声もあるようです
    - ただ、管理されたWorkerノードしか使えない、というのは個人的には悪手だと思うので、ファーストリリースとしてはこれでよかった！
        - 理由１．管理されたWorkerノードしか使えないと、ノードの設定を色々と変えながら安定性やパフォーマンスをチューニングすることが難しくなるため
        - 理由２．既存のKubernetesデプロイツールのUI/UXを変えずに引き続き利用できる
            - ツール側でMasterノードのプロビジョニングをEKSに委譲するように変更するだけで済むので、これまで利用していたツールの知識は無駄になりません

### AWSユーザとKubernetesユーザの一元管理サポート

- 具体的には、AWS IAMユーザ、IAMロールとKubernetesユーザの変換をサポート（他社OSSで）
    - Heptioが開発しているOSSの [authenticator](https://github.com/heptiolabs/kubernetes-aws-authenticator) をそのまま利用するそうです
    - ちょっと自慢ですが、@mumoshu がコントリビュータです
    - ほんとにこれしかソリューションがなかったのですが、公式化されてうれしい

### Kubernetesのネットワークレベルアクセス制御サポート

- 他社OSSを利用
    - 具体的には、CalicoというKubernetes界隈で標準的に使われているOSSを利用するようです
- 後述の「高速なネットワーキング」との兼ね合いを考えると、おそらくAWSのSecurity GroupやNetwork ACLをKubernetesのAPIからコントロールできるようになるということだと予想されます

参考リンク:

[Project Calico - Secure Networking for the Cloud Native Era](https://www.projectcalico.org/)

### 高速なネットワーキング

- これまでKubernetesをAWSにデプロイする場合、ほとんどのケースではAWS VPCの仮想ネットワークのうえにさらにVXLANで仮想ネットワークを組んでいました
- 仮想ネットワークを挟むことで、ネットワークのレイテンシやスループットが10%ほど落ちるというベンチマークが以前ありました
    - これをAWS VPCネイティブで実現することで、VXLANのオーバーヘッドをなくせそうです

#### ECS CNI Pluginsとは異なる方式を採用

- 先日AWS ECS向けに公開された[Amazon ECS CNI Plugins](https://github.com/aws/amazon-ecs-cni-plugins)とはまた別ものです。
    - ECS CNI Pluginsはコンテナ毎にENIを作っちゃうので、EC2インスタンスのENI数上限（低い。c4.largeで3。1 EC2インスタンスあたり3コンテナで打ち止め?）にすぐ引っかかってしまいます
- 今回発表されたのは[amazon-vpc-cni-k8s](https://github.com/aws/amazon-vpc-cni-k8s/)のほう
    - こちらはENIに複数のSecondary IPs=Kubernetes Pod IPsを割り当てる方式のようです
    - ENI数の上限はEC2に準ずるのでしょうが、ENIあたりのIPアドレス数上限はもっと大きい(c3.largeで10 IPs/ENI)

参考リンク:

[AWS公式の「EC2インスタンスタイプ別ENI数上限、IPアドレス数/ENI上限について」](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI)

### マネージドサービスにありがちなセキュリティ面の難点もカバー

- 具体的には、AWS Private Linkに対応
    - Kubernetesの重要なAPIをインターネットに公開せず、プライベートネットワークだけに公開できる（セキュリティが高まります）
    - 例えばAWS上で運用されている各社さんのサービスはほとんどAWS VPC（というAWS内に隔離された仮想データセンター）で稼働しています
    - マネージドサービスを利用する場合、VPCから一度インターネットにでなければならないことが多いです
        - DynamoDB, Elasticsearch, S3, etc.
- マネージドサービスをインターネットを経由しなくても使えるようにするのがVPC Endpoint、Private Linkのようなサービスです

## その他、発表でカバーされていなかった気になること

### Fargateとの連携したときのCluster Networkingとホストへのアクセス(特にDaemonSet)

EKS+Fargate連携も同時発表されてましたね。
前提として、Fargate管理化のコンテナはどこかのEC2インスタンスと思われます。
そのときに気になるのは、それらのコンテナが動いているホストをKubernetesクラスタのネットワークに参加させるのか・させないのか、です。

クラスタネットワークに参加させない場合、[virtual-kubelet](https://github.com/virtual-kubelet/virtual-kubelet/issues/13)プロジェクトでも課題になっているように、現状のK8Sのままでは「K8SからFargateコンテナをつくることはできるけど、K8SネイティブなコンテナとFargateコンテナとの間で直接通信ができない」という状態になってしまいます。それだと片手落ちですよね。

今のところ、理想は「Fargateノードは超高速に起動できるKubernetesノードとして見える。Fargate上のPodはKubernetes上の通常のPodと相互に通信でき、Service経由での通信も可能で、DaemonSet管理化のPodも通常のノードと同じようにスケジュールされる」という状態です。どうなるんでしょうか。

### IAMロールをKubernetesのPodから利用する方法

- IAMロールをKubernetesのPodから利用する（コンテナにIAMポリシーを適用する）方法はどうなる？
- 定番だけど安定性の問題があると言われている[kube2iam](https://github.com/jtblin/kube2iam)を使うのか、
- kube2iamと互換性のある新進気鋭の[kiam](https://github.com/uswitch/kiam)を使うのか、
- またはAWS公式に何か出るのか・・・

### Kubernetesクラスタの可視化

- モニタリング・分散ロギング・分散トレーシング・・・
- CloudWatchとX-rayでやるのか?
    - 個人的な意見ですが、現状ままKubernetesサポートを追加しても、[Datadog](https://www.datadoghq.com)と比べると見劣りしてしまう・・・

参考リンク：

- @spesnovaさんの[Monitoring Kubernetes with Datadog](https://www.datadoghq.com/ja/blog/monitoring-kubernetes-datadog/)
- Datadogの新機能[Log Management](https://www.datadoghq.com/blog/announcing-logs/)

## まとめ

Kubernetesのデプロイメントツールのメンテナから見ても、ワクワクする内容でした！

HeptioのauthenticatorやCalico採用の件も含めて、AWSさんがよりOSSコミュニティに近づいて来られたのも好印象です。

現状はまだプレビュー申込受付中というステータスで、一般利用はできない状態ですが、早く東京リージョンでも試せるようになるといいですね。