Kubernetes 1.3の変更点(予定)

Kubernetes 1.3で入りそうな機能についてまとめてみました。現時点(2016/5/17)ではFeature Completeになっていなく、決定した情報ではないのでご注意ください。1.3のリリースは2016年6月末を予定しているようです。

主な参考情報

- [kubernetes/kubernetes v1.3 milestone](https://github.com/kubernetes/kubernetes/milestones/v1.3)
- [Kubernetes Community Hangout Working Doc](https://docs.google.com/document/d/1VQDIAB0OqiSjIHI8AWMvSdceWhnz56jNpZrLs6o7NJY)
- [Kubernetes 1.3 - Effort tracking dashboard](https://docs.google.com/spreadsheets/d/1QJeLJj3Zwft3xVW0ZIdmq5N-uJrCjL5TG_om1yoje-A/edit?ts=572bd4c6#gid=0)
- Youtubeの [Kubernetes Community Meeting](https://www.youtube.com/channel/UCZ2bu0qutTOM0tHYa_jkIwg) の録画
- Kubernetes Wiki [Release 1.3
](https://github.com/kubernetes/kubernetes/wiki/Release-1.3)


## 主な変更点

### Ubernetes(複数クラスタ連携)の実装 (alpha)

Ubernetesは複数のKubernetesクラスタを連携させる機能です。("uber-"は"超える"の意味の接頭辞)。Ubernetesの利点は例えば以下のようなものがあります。

- **High Avaiability**: AWS, GCPなどのクラウドプロバイダーやAvaiability Zoneをまたがってクラスタを連携させることで可用性が向上する
- **クラスタサイズの拡張**: 現状クラスタのサイズの上限が1000〜2000ノードであるため、連携させることでそれ以上に拡張できる。

Phase1では構成的には以下のように、Ubernetes用のAPI Server、Scheduler、Cluster Controller、Service Controllerがクラスタの上位層として用意されるようです。(参考: [Ubernetes Design Spec (phase one)](https://github.com/kubernetes/kubernetes/blob/master/docs/design/federation-phase-1.md))。

![image](https://qiita-image-store.s3.amazonaws.com/0/100377/7ffae9d0-04cb-7373-5cbf-8744a9855d0e.png)

すでにmasterブランチにはトップディレクトリに[`federation`](https://github.com/kubernetes/kubernetes/tree/master/federation)という新しいディレクトリがマージされており、`federated-apiserver`というmainが追加されています。

Kubernetes 1.2の時点では、Ubernetes Liteと呼ばれる同一プロバイダの複数のAvailability Zoneだけをサポートするものが実装されています。(参考: kubernetes blog: [Building highly available applications using Kubernetes new multi-zone clusters (a.k.a. "Ubernetes Lite")](http://blog.kubernetes.io/2016/03/building-highly-available-applications-using-Kubernetes-new-multi-zone-clusters-a.k.a-Ubernetes-Lite.html))


参考

- [Ubernetes: task list #23653](https://github.com/kubernetes/kubernetes/issues/23653)
  - Ubernetesの実装状況がまとまっています
- [SIG Federation](https://github.com/kubernetes/community/tree/master/sig-federation)
- [Ubernetes Working Group - meeting notes](https://docs.google.com/document/d/18mk62nOXE_MCSSnb4yJD_8UadtzJrYyJxFwbrgabHe8/edit#heading=h.oncbuz49k7ei)
- [Kubernetes Cluster Federation (a.k.a. "Ubernetes")
](https://github.com/kubernetes/kubernetes/blob/master/docs/design/federated-services.md)
- [Ubernetes Design Spec (phase one)](https://github.com/kubernetes/kubernetes/blob/master/docs/design/federation-phase-1.md)

### PetSet(ステートフルアプリのサポート)の追加 (alpha)

PetSetは、ZooKeeperやetcdのように複数のインスタンスがそれぞれの状態を持って連携しあうような、ステートフルなアプリケーションをサポートするための仕組みです。初期から提案されている仕様らしく、元のIssueの連番は[#260](https://github.com/kubernetes/kubernetes/issues/260)と若いです。

**Pet** という単語はおそらく[Pets vs. Cattle](https://blog.engineyard.com/2014/pets-vs-cattle)という話から来ており、ペットの様にそれぞれに名前を付けてユニークに扱う必要があるものを指します。逆にCattle(畜牛)はそれぞれを区別せず連番で呼ばれるようなものを指します。

ステートレスなアプリケーションは、それぞれのインスタンスを区別する必要がない**Catlle**的な扱いで良かったため、従来のReplication Controller(Replica Set)で単純に同一のPodを並べるだけで十分でした。しかし、それぞれのインスタンスごとに固有のデータを持つステートフルなアプリケーションは、それぞれをユニークに扱う**Pet**的な扱いが必要ため、Replicaton Controllerで扱うのは難しい状況でした。そのためPetSetという機能が提案されました。

PetSetについてはドキュメント類がまだなので、マージされている[/pkg/apis/apps/types.go](https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/apps/types.go)のコメントが参考になります。

このコメントによれば、PetSetとはネットワークの識別子(DNSとホスト名)とストレージ(PersistentVolumeClaim)のマッピングを常に保証する仕組みのようです。

```/pkg/apis/apps/types.go
// PetSet represents a set of pods with consistent identities.
// Identities are defined as:
//  - Network: A single stable DNS and hostname.
//  - Storage: As many VolumeClaims as requested.
// The PetSet guarantees that a given network identity will always
// map to the same storage identity. PetSet is currently in alpha and
// and subject to change without notice.
```

以下はコメントからの自分の想像なので、間違っている可能性があります。

例えばetcdの場合、下記のテーブルようなマッピングを定義をしたとします。`e1.etcd.default.svc.cluster.local ` の `Pod-a` が削除されたとしても、新しく生成された `Pod-d` は同じストレージ`storage-1` をマウントし、同じDNS名`e1.etcd.default.svc.cluster.local ` でアクセスできるのでメンバーとして復帰できる、という仕組みだと理解しました。

DNS名 |ストレージ | Pod
--- | --- | ---
e1.etcd.default.svc.cluster.local | storage-1 | Pod-a → Pod-d
e2.etcd.default.svc.cluster.local | storage-2 | Pod-b
e3.etcd.default.svc.cluster.local | storage-3 | Pod-c

KubernetesのIssue上では[area/stateful-apps](https://github.com/kubernetes/kubernetes/issues?utf8=%E2%9C%93&q=label%3Aarea%2Fstateful-apps+)というラベルが振られていて、下記のようなアプリケーションがサポート予定の対象としてIssueが切られています。

- ZooKeeper
- etcd
- Cassandra
- Galera Cluster
- Kafka
- Vtess
- ElasticSearch
- Cockroach DB


参考

- [PetSet (was nominal services) #260](https://github.com/kubernetes/kubernetes/issues/260)
- [Apigroup and alpha resource for petset #24315](https://github.com/kubernetes/kubernetes/pull/24315)
- [Petset controller #24912](https://github.com/kubernetes/kubernetes/pull/24912)

### スケーラビリティ向上(2000ノード対応)

1.3でのゴールとしては2000ノードを目指すようです。

> 2000 nodes, 30 pods/node, 60K pods, 100 pods/node max, current latency
>
> SIG-Scaleの資料 [k8scale community update - 5/12](https://docs.google.com/presentation/d/1yNaDf41gjY93i1MP46zKtjuhs1VDzZaEpgHmkD5lsV0/edit#slide=id.g13f436536a_0_0) より

1.3の後は、クラスタのサイズの表現を変えて、200K cores/cluster, 10 pods/core, 100 pods/sec を目指すとしています。

以下は資料で挙げられていたパフォーマンスに関連するIssueです。

- [epic: Reducing network overhead and optimizing kubernetes control plane communications #23709](https://github.com/kubernetes/kubernetes/issues/23709)
  - ネットワークのオーバーヘッド低減とKubernetes APIサーバーへの通信の最適化
- [Enable http2 on client connections. #25280](https://github.com/kubernetes/kubernetes/pull/25280)
  - 通信をHTTP/2を使うようにする
- [Upgrade to etcd v3 plan #22448](https://github.com/kubernetes/kubernetes/issues/22448)
  - etcd v3へのアップグレード
- [Proposal for introducing Protobuf serialization #22600](https://github.com/kubernetes/kubernetes/pull/22600)
  - protocol buffersのサポート
- [Split the "resync interval" on reflectors into "relist interval" and "resync interval" #23394](https://github.com/kubernetes/kubernetes/issues/23394)

参考

- [K8scale weekly agenda](https://docs.google.com/a/bobsplanet.com/document/d/1hEpf25qifVWztaeZPFmjNiJvPo-5JX1z0LSvvVY5G2g/edit?usp=drive_web)
- [k8scale community update - 5/12](https://docs.google.com/presentation/d/1yNaDf41gjY93i1MP46zKtjuhs1VDzZaEpgHmkD5lsV0/edit#slide=id.g13f436536a_0_0)

### rktnetes 1.0

rktnetesとはCoreOS社が開発するコンテナランタイムrktとKubernetesの組み合わせことです。1.3で正式版リリースを目指しているようです。CoreOS Fest 2016での発表時点(5/10)では、90%以上のE2Eテストが通るところまで来たと言っていました。

Dockerに対しての主な利点は以下が挙げられます。

- Podをネイティブに扱える
  - DockerのようにPause container(Infra Container)を使ったトリッキーな仕組みが不要
- コンテナを動かすのにdockerdのようなデーモンが不要
- systemdとシームレスに統合できる

参考

- [rktnetees-v1.0 milestone](https://github.com/kubernetes/kubernetes/milestones/rktnetes-v1.0)
- [KubeCon EU 2016: "rktnetes": what's new with container runtimes and Kubernetes](http://www.slideshare.net/kubecon/kubecon-eu-2016-rktnetes-whats-new-with-container-runtimes-and-kubernetes)

### Init Containers (alpha)
Pod内で初期化処理をするコンテナを指定をできる機能です。Podの定義に`initContainers`という項目で、従来の`containers`で指定したコンテナの前に起動するコンテナを指定できるようになるようです。複数のコンテナを指定することができますが、`containers`がパラレルに起動されるのに対して`initContainers`は指定した順番に１つずつ起動していくようです。

使用用途としては例えば以下のようなものが挙げられます。

- データを動的にダウンロードしてくる
- データベーススキーマの反映
- アプリケーションが何らかの事前条件を満たすまでウェイトする

```yaml:Proposalにあったyamlの例
pod:
  spec:
    initContainers:
    - name: wait
      image: centos:centos7
      command: ["/bin/sh", "-c", "for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; exit 1"]
    containers:
    - name: run
      image: application-image
      command: ["/my_application_that_depends_on_myservice"]
```


参考

- [Proposal for implementing init containers #23666](https://github.com/kubernetes/kubernetes/pull/23666)
- [Add init containers to pods #23567](https://github.com/kubernetes/kubernetes/pull/23567)


### Scheduled Job (alpha)

Scheduled Jobはcronのようにスケジュールを指定したJobの指定ができるようになるものです。 (@koudaiii さんにコメントで教えてもらいました)。ConcurrencyPolicyという項目で多重起動の制御(Allow, Forbid, Replaceが設定できる模様)もできるようです。


```yaml:Issueで挙げられていた例
apiVersion: batch/v2alpha1
kind: ScheduledJob
metadata:
  name: pi
spec:
  schedule: "0 0 0 0 0"
  startingDeadlineSeconds: 30
  concurrencyPolicy: "Allow" 
  suspend: false
  jobTemplate:
    spec: 
      template:
        spec:
          containers:
          - name: pi
            image: perl
            command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
            restartPolicy: Never
```

参考

- [ScheduledJob ControllerのProposal](https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/scheduledjob.md)


## その他の変更点

- [NVIDIA GPU support #24836](https://github.com/kubernetes/kubernetes/pull/24836)
  - NodeのGPUをcpu, memoryなどと同じようなリソースとして扱えるようにするもの
- [Automatically create the kube-system namespace #25196](https://github.com/kubernetes/kubernetes/pull/25196)  
  - `kube-system`ネームスペースが自動的に作られるようになった。地味に嬉しい
- [Upstream Openshift Authz #23396](https://github.com/kubernetes/kubernetes/issues/23396)
  - Openshiftの認可の仕組みを取り入れる
- [Implement OIDC client AuthProvider #25270](https://github.com/kubernetes/kubernetes/pull/25270)
  - OpenID ConnectのRefresh Tokenの実装され、[Refresh Tokens #18549](https://github.com/kubernetes/kubernetes/issues/18549)の問題が解決
- [kubectl create secret tls #20176](https://github.com/kubernetes/kubernetes/issues/20176)
  - ingressにtlsのサポートが入ったので、証明書のシークレットをkubectlで作れるようにするもの