Kubernetes v1.7: 主な変更点 (Major Themes)

このエントリは Kubernetes v1.7 CHANGELOG の 主な変更点 (Major Themes) をまとめています。

- https://github.com/kubernetes/kubernetes/blob/3f0141edd52ab6fd7b6fe473ecceb480faf12079/CHANGELOG.md#major-themes

その他の項目は下記を参照してください。

- [Kubernetes v1.7: 主な変更点 (Major Themes)](http://qiita.com/tkusumi/items/817cf85917efd24c7a4f)
- [Kubernetes v1.7: Action Required Before Upgrading](https://qiita.com/superbrothers/items/e52a364a88783f85dd75)
- [Kubernetes v1.7: Deprecations](http://qiita.com/superbrothers/items/2c867c9d5087b9910a61)
- [Kubernetes v1.7: Notable Features 抜粋](http://qiita.com/tkusumi/items/0e5856ed58a1ec7bb644)


# 主な変更点

詳細は右メニューの各項目へのリンクからご覧ください。

- セキュリティ強化
  - etcd の暗号化 (alpha)
  - Pod 間通信を制御する NetworkPolicy が stable に昇格
  - Node の権限をより厳密にする Node Authorization の追加
  - Kubelet client / server の TLS 証明書のローテーション (alpha)
  - 高度な監査ログの追加 (alpha)
- ステートフルアプリ
  - StatefulSet の自動アップデート
  - DaemonSet のアップデートの強化
  - StatefulSet に高速なスケールのオプションが追加
  - ローカルディスクを PersistentVolume として使える local ストレージの追加 (alpha)
- 拡張性
  - API アグリゲーション機能 (beta)
  - ThirdPartyResource に代わる CustomResourceDefinitionの導入 (beta)
  - 拡張できる Admission Controller の機能 (beta)
  - プラガブルな Cloud Provider (alpha)
  - Container Runtime Interface (CRI) の強化

## etcd の暗号化 (alpha)

https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/

新規に追加された etcd のデータを暗号化できる Alpha 機能です。

- リソース種別を指定して etcd のデータを暗号化できる
  - AES-CBC など[複数の暗号化方式に対応](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#providers)
- API サーバーのオプションとして指定する `--experimental-encryption-provider-config`
  - この設定ファイル `EncryptionConfig` に秘密鍵も記載されている
- 暗号化されたデータには `k8s:enc:aescbc:v1:` といった prefix が付くため区別できる
- etcd v3 でのみ動作。v2 では動作しない模様
  - minikube では v2 のため試せませんでした
- [ドキュメント](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)には v1.8.0 アップグレード時に一度復号化が必要な可能性があるとかかれている

**設定ファイル例** (`EncryptionConfig`)

```yaml
kind: EncryptionConfig
apiVersion: v1
resources:
  - resources:
    # 暗号化対象のリソース
    - secrets
    providers:
    # 一つ目の provider が暗号化時に使われる (他に並べたものは復号化に使われる)
    - aescbc:
        keys:
        - name: key1
          secret: <BASE 64 ENCODED SECRET>
    - identity: {}
```

## Pod 間通信を制御する NetworkPolicy が stable に昇格

https://kubernetes.io/docs/concepts/services-networking/network-policies/

Pod 間の通信をポリシーによって分離することができる [Network Policy](https://kubernetes.io/docs/concepts/services-networking/network-policies/) が Stable になりました。

- Beta だった Network Policy の機能が Stable になった
  - 通常 Pod 間の通信はどの Pod からでも許可されているが、NetworkPolicy を使うことで分離できるようになる
- 例えば特定の namespace からのみアクセスを許可するなど設定できる
- この機能が使えるかは選択したネットワークプラグインに依る
  - Calico, Romana, Weave Net は対応している模様


**設定例** [Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/)より

```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
```

## Node の権限をより厳密にする Node Authorization の追加


[Node Authorization](https://kubernetes.io/docs/admin/authorization/node/) とは Node (Kubelet) の権限管理をより厳密に行う機能です。この機能を有効にすることで、Node はその Node が関連するオブジェクトにのみ権限が制限されるようになります。例えば Node は割り当てられた Pod が参照する Secret 以外にはアクセスできなくなります。これにより Node のクレデンシャルが漏洩したときのセキュリティリスクを最小限にすることができます。

詳細は以下の記事にまとめています。

- http://qiita.com/tkusumi/items/f6a4f9150aa77d8f9822


## Kubelet client / server の TLS 証明書のローテーション (alpha)

https://kubernetes.io/docs/admin/kubelet-tls-bootstrapping/

[TLS bootstrapping](https://kubernetes.io/docs/admin/kubelet-tls-bootstrapping/) における kubelet のクライアントとサーバーの TLS 証明書のローテーションが Alpha として実装されました。

- [Kubelet Client TLS Certificate Rotation #266](https://github.com/kubernetes/features/issues/266)
- [Kubelet Server TLS Certificate Rotation #267](https://github.com/kubernetes/features/issues/267)

## 高度な監査ログの追加 (alpha)
https://kubernetes.io/docs/tasks/debug-application-cluster/audit/#advanced-audit

より詳細な監査情報を記録する高度な監査ログ(Advanced audit)の機能が実装されました。

- API サーバーが受けたリクエスト、レスポンスの body など詳細なログを残すことができるようになった
- 従来のファイルベースの監査ログに加え、webhook のバックエンドが追加された
  - 高度なログを記録できるのは v1.7 時点では webhook だけ
- Alpha 機能のため API サーバーに `--feature-gates=AdvancedAuditing=true` のオプションを指定する必要
- ログをどの程度残すかのポリシーは設定により細かく制御できる

**設定例の一部** [Advanced audit](https://kubernetes.io/docs/tasks/debug-application-cluster/audit/#advanced-audit) より抜粋

```yaml
rules:
  # "system:kube-proxy" ユーザによる endpoints, services の watch はログに落とさない
  - level: None
    users: ["system:kube-proxy"]
    verbs: ["watch"]
    resources:
    - group: "" # core API group
      resources: ["endpoints", "services"]

  # kube-system の configmap の変更のリクエスト body はロギングする
  - level: Request
    resources:
    - group: "" # core API group
      resources: ["configmaps"]
    # This rule only applies to resources in the "kube-system" namespace.
    # The empty string "" can be used to select non-namespaced resources.
    namespaces: ["kube-system"]

  # 全ての namespace の Configmap と Secret の変更は Metadata レベルでロギングする
  - level: Metadata
    resources:
    - group: "" # core API group
      resources: ["secrets", "configmaps"]
```


## StatefulSet の自動アップデート

https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets

StatefulSet Rolling Update 機能が Beta として入りました。

- 1.7 以前では pod は手動で削除してアップデートする必要があった
- `.spec.template` が更新されると Pod をローリングアップデートする
  - 1.7 以前からある自動的にはアップデートしない方式 `OnDelete` が 1.7 ではデフォルト


## DaemonSet のアップデートの強化

https://kubernetes.io/docs/tasks/manage-daemon/rollback-daemon-set/

DaemonSet にロールバックと履歴(rollout history)の機能が入りました。v1.6 で DaemonSet に RollingUpdate が入り、今回はそれに続く機能の実装となっています。

## StatefulSet に高速なスケールのオプションが追加

https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies

StatefulSet で高速にスケールを行うための機能が追加されました。

- 従来の StatefulSet では pod-0, pod-1 ...と1つづつ ready になるのを待ちながらスケールさせる
  - このため場合によってはスケールに時間がかかる
- `.spec.podManagementPolicy` というフィールドが追加されスケールの方法を指定できるようになった
  - デフォルトは `OrderedReady` で従来の一つづつ ready になるのを待つ
  - 1.7 で追加された `Parallel` は順序を待つことなく並列に pod を作成していくことで高速なスケールを行う

## ローカルディスクを PersistentVolume として使える local ストレージの追加 (alpha)

https://kubernetes.io/docs/concepts/storage/volumes/#local

v1.7 で導入された Node のローカルディスクを PersistentVolume として PVC から利用できる機能です。

- Node のローカルディスクを PersistentVolume として PVC から利用できる機能
- 従来の EmptyDir では容量の指定や制限やノードの固定ができませんでしたが、local storage ではそれらの指定ができるようになった
- キャッシュやログなどの一時的なデータの他、ローカルディスクを使った分散ファイルシステムの構築などに利用することが可能


## API アグリゲーション機能 (beta)

[Extending the Kubernetes API with the aggregation layer \| Kubernetes](https://kubernetes.io/docs/concepts/api-extension/apiserver-aggregation/)

kube-apiserver を拡張し任意の API を Kubernetes API に追加することができる機能が追加されました。

- kube-apiserver を拡張する機能
- アグリゲーションレイヤとして任意の API を Kubernetes に追加することができる
    - APIService オブジェクトを作成することでアグリゲーションレイヤにおいてリクエストが登録した APIService にプロキシされる
- APIService は拡張 apiserver としてクラスタ内に Pod として構築される
    - 追加したリソースをアクティブに管理するには、合わせて複数のコントローラと組み合わせる必要がある
    - [apiserver-builder](https://github.com/kubernetes-incubator/apiserver-builder) は、拡張 apiserver と controller 両方のスケルトンを提供している

```yaml
apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
  name: v1alpha1.wardle.k8s.io
spec:
  insecureSkipTLSVerify: true
  group: wardle.k8s.io
  priority: 200
  service:
    name: api
    namespace: wardle
  version: v1alpha1
```

## ThirdPartyResource に代わる CustomResourceDefinitionの導入 (beta)

[Extend the Kubernetes API with CustomResourceDefinitions \| Kubernetes](https://kubernetes.io/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/)

ThirdPartyResources (TPRs) が廃止され、代わりの CustomResourceDefinition が導入されました。

- ThirdPartyResources (TPRs) が廃止され、代わりにより洗練された CustomResourceDefinitions が提供される
    - TPRs と異なり、shortName や plural, singular などを明示的に指定できるようになった
- apiserver に独自のカスタムリソースを簡単に定義することができるが、API aggregation と比較して柔軟性がない

```yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  # name must match the spec fields below, and be in the form: <plural>.<group>
  name: crontabs.stable.example.com
spec:
  # group name to use for REST API: /apis/<group>/<version>
  group: stable.example.com
  # version name to use for REST API: /apis/<group>/<version>
  version: v1
  # either Namespaced or Cluster
  scope: Namespaced
  names:
    # plural name to be used in the URL: /apis/<group>/<version>/<plural>
    plural: crontabs
    # singular name to be used as an alias on the CLI and for display
    singular: crontab
    # kind is normally the CamelCased singular type. Your resource manifests use this.
    kind: CronTab
    # shortNames allow shorter string to match your resource on the CLI
    shortNames:
    - ct
```

## 拡張できる Admission Controller の機能 (beta)

[Dynamic Admission Control \| Kubernetes](https://kubernetes.io/docs/admin/extensible-admission-controllers/)

- これまで Admission Controller に独自の処理を追加するにはソースコードをフォークして kube-apiserver をコンパイルする必要があった
    - External Admission Controllers は、Initializers と External Admission Webhooks をアルファとして提供してこの制約を解消する
- Initializers は、AlwaysPullImages や DefaultStorageClass など管理者がポリシーを強制する用途に使うことができる
    - 対象のオブジェクトが作成されると metadata.initializers[] に処理対象の Initialzer Controller が格納されており、metadata.initializers[0] が自身である場合処理を実行し、完了後 metadata.initializers[0] から自身を削除しなければならない
        - 全ての metadata.initializers が削除されるまでそのオブジェクトは作成されていないように見なさえる
    - Initializers の処理は直列で行われるため、オブジェクトを操作しないのであればパフォーマンスを優先して External Admission Webhooks を検討したほうがよい
- External Admission Webhooks は、リソースのバリデーションなどに利用する。例えば Pod には必ず特定のラベルが設定されていなければならないなどに有用である。
    - Initializers と異なり、リクエストの内容を操作することができないが、並行して実行されるためパフォーマンスが優れている


## プラガブルな Cloud Provider (alpha)

[Build and Run cloud\-controller\-manager \| Kubernetes](https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/)

- 全てのクラウドプロバイダの処理は kube-controller-manager に集約されていたが、それぞれのクラウドプロバイダ毎にそれぞれのリリースサイクルがあるなどの理由から分離できるようになった
    - この機能は v1.6 でアルファとして導入されたようだが、なぜか v1.7 で紹介されている（紹介し忘れ？）
- 既に GCP や AWS, OpenStack など既に kube-controller-manager に実装されているクラウドプロバイダについてはこれまで通りで問題なく動作する
    - Rancher などいくつかのクラウドプロバイダについては外部クラウドプロバイダコントローラとして提供されている
    - [rancher/rancher\-cloud\-controller\-manager: A kubernetes cloud\-controller\-manager for the rancher cloud](https://github.com/rancher/rancher-cloud-controller-manager)
- 外部クラウドプロバイダコントローラを利用する際は、kube-controller-manager の `--cloud-provider` フラグを `external` と指定する必要がある


## Container Runtime Interface (CRI) の強化

- Docker CRI integration が GA に昇格
- 旧 Docker CRI integration は kubelet から完全に削除された。廃止予定だった kubelet `--enable-cri` フラグが削除された。
- CRI はランタイムからコンテナメトリクスを収集するように拡張された
    - https://github.com/kubernetes/community/blob/master/contributors/devel/cri-container-stats.md