1. Qiita
  2. Items
  3. kubernetes

Kubernetesの主な機能一覧 (v1.5時点)

  • 41
    Like
  • 0
    Comment

この記事はKubernetes Advent Calendar 2016の13日目の記事です。ちょうどこの記事の投稿日(12/13)に Kubernetes v1.5.0がリリースされました :tada:

日夜、進化し機能が増えているKubernetesについて、開発中のものも含めv1.5時点での主な機能の一覧をまとめてみました。

スケーラビリティ関連

クラスタリング機能

Kubernetesのクラスタリング機能はマスターコンポーネント(kube-apiserver,etcd,kube-scheduler,kube-controller-manager)とNodeコンポーネント(kubelet,kube-proxy)から構成されます。

クラスタが対応するノード数に関してはKubeCon 2016でMarek Grabowskiさんが発表した2000 Nodes and Beyond: How We Scaled Kubernetes to 60,000-Container Clusters and Where We're Going Nextというセッションの資料がまとまっています。

Kubernetesの構造上、各種コンポーネントはAPIサーバーを参照して処理を行うため、スケーラビリティの向上は主にAPIサーバーを中心に行われています。

2000 Nodes and Beyond のスライドより引用
image

2000 Nodes and Beyondのスライドによると、Kubernetesのバージョンごとの対応するノード数は下記のようになっています。

バージョン 対応ノード数 主な取り組み
v1.0 100 内部の型変換(versioned -> unversioned)をreflectからコード生成にした
v1.1 250 APIサーバーのetcdのwatchを1キーにつき1watchにまとめるようにした(cacher層)
v1.2 1,000 kubemarkというベンチマークができた
v1.3 2,000 APIサーバーの通信で内部クライアントはjsonからprotobufを使うようになった
v1.4 2,000
v1.5 ? etcd v2からv3への移行が予定されていたが見送りに

参考

複数クラスタ連携 (Federated Kubernetes)

Federated Kubernetesは複数のKubernetesを連携させる機能です。Ubernetes("uber-"は"超える"の意味の接頭辞)とも呼ばれます。AWS, GCPなどのクラウドプロバイダーやAvaiability Zoneをまたがってクラスタを連携させることで、可用性の向上やクラスタサイズの拡張を実現することができます。鋭意開発が進められており、v1.5でもDeployment, ConfigMapなどのリソースが対応されました。

@toshitanianさんが書かれたKubernetes Federationの今とこれからという記事が素晴らしくまとまっています。

参考

アプリケーションの水平オートスケール (HorizontalPodAutoscaler)

HorizontalPodAutoscalerという機能によりアプリケーションの水平(horizontal)オートスケールがサポートされます。アプリケーション(Pod)の数がCPU使用率等の計測値を用いて自動的に調整される機能です。計測値はデフォルトで用意されるCPU使用率の他、alpha機能で独自のメトリクスを使用することができます。

将来的にはアプリケーションの垂直(Vertical)スケールの機能も考えられているようです。垂直スケールの必要性に関してはKubeCon 2016でKubernetesのコア開発者であるTim Hockinさんが発表したEverything You Ever Wanted To Know About Resource Scheduling... Almostが詳しいです。

参考

アプリケーションのデプロイ・実行

アプリケーションの単位の提供 (Pod)

PodはKubernetesでアプリケーションを動かす最小単位で、Kubernetesの一番基本となるリソースです。同じプロセス空間、ネットワーク、ストレージを共有する1つ以上のコンテナから構成されます。これによりログコレクタのような補助プロセスを含めて1つのアプリケーションとしてデプロイすることができます。

アプリケーションのレプリカ数管理 (ReplicationController / ReplicaSet)

ReplicationController及びReplicaSetはアプリケーション(Pod)のレプリカ数を管理するための仕組みです。クラスタで動くPodの数をユーザーが望むレプリカ数(desired state)に近づける形で動作します。オートヒーリングの仕組みもこの機能で実現しています。

ReplicationControllerReplicaSetの違いは現状ほとんどなく、ReplicationControllerという名前が長く、リソース名にcontrollerとついて紛らわしいといったことからReplicaSetが作られました。

参考

ローリングアップデートなどのデプロイ管理 (Deployment)

Deploymentはデプロイを管理する仕組みでローリングアップデートやロールバックの機能を提供します。内部的にはReplicaSetを使用しており、ローリングアップデートは新旧2つのReplicaSetを作って切り替えていく形を取っています。

参考

ステートフルアプリケーションの管理 (StatefulSet)

StatefulSet(v1.4まではPetSet)はステートフルアプリケーションをサポートするための機能です。ReplicaSetと違って管理するPodの1つづつがそれぞれの名前と状態を持てることになります。具体的にはetcdやzookeeperのようにそれぞれのメンバー(Pod)が状態を持ち識別が必要なアプリケーションをデプロイする場合が想定されています。

なおPetSetからStatefulSetに名前が変更された経緯はPlease consider changing the name of PetSet before General Availability #27430というissueで議論されていました。

参考

ノード毎のデーモンのデプロイ管理 (DaemonSet)

DaemonSetはクラスタの各ノードで特定のデーモンを実行する機能です。例えばcephのようなストレージのデーモンや、fluentdのようなログコレクタ、linkerdのような透過プロクシーなどをノードごとに動かす場合に利用します。

参考

ジョブ・バッチ処理 (Job)

Jobは単独のジョブ処理(明示的な終了がある処理)を行うための機能です。

スケジュールジョブ (CronJob)

CronJob(v1.4まではScheduledJob)を使うとcronのようなスケジュールに基づく処理を実行することができます。

@koudaiiiさんのCronJob(ScheduledJob)の記事がとてもよくまとまっています。

ネットワーク・サービス提供

サービスディスカバリ & ロードバランシング (Service / KubeDNS / kube-proxy)

Serviceはクラスタ内のサービスディスカバリとロードバランシングを提供する機能です。ServicePodLabelとSelectorという仕組みで選択し、配下のPod群に対してロードバランスする仮想的なIPアドレス(ClusterIP)を提供します。また内部のDNS(KubeDNS)に自動的にドメインの登録を行いサービスディスカバリの機能を提供します。

ロードバランシングはノード毎にデーモンとして動くkube-proxyServiceの情報をiptablesに設定することで実装されています(デフォルトの挙動)。そのため通常の構成ではClusterIPはクラスタの外部から通信を受けることはできません。 クラスタ外部からの通信を受けるには通常Servicetype=LoadBalancerの指定か、IngressリソースによるL7ロードバランサなどの設定が必要になります。

クラウドプロバイダのL4ロードバランサとの連携(Service.Type=LoadBalancer)

Servicetype=LoadBalancerの指定により外部のL4ロードバランサによってサービスを公開することができます。この指定がなされると、自動的にServiceに連携したクラウドプロバイダ(AWS, GCPなど)ごとのロードバランサが作られます。

参考

L7ロードバランサとの連携 (Ingress)

Ingressはクラスタ外部(主にインターネット)からの通信を受けるL7ロードバランサに必要となる設定情報をリソースとして表現する機能になります。

    internet
        |
   [ Ingress ]
   --|-----|--
   [ Services ]

Service.Type=LoadBalancerとの主な違いは下記になります

  • L7ロードバランサであること(Service.Type=LoadBalancerはL4)
    • ホスト名やパスによるルーティング、TLS終端が可能
  • Ingress自体はリソースとしてL7ロードバランサの情報をリソースとして表現するだけのもの
    • 実際のロードバランサの設定はIngress ControllerというIngressリソースを監視する別の仕組みで行われる
    • これによりロードバランサの情報と具体的なロードバランサが分離される

Ingress Controllerの実装としては下記のようなものがあります

参考

プラガブルなネットワーク機能 (CNI)

KubernetesのネットワークはContainer Network Interface(CNI)というコンテナネットワークの共通インタフェースをプラグインとしてサポートしています。Canal(Calico, Flannel), Weave Netなどのネットワークプラグインが存在します。

参考

ネットワークポリシーの制御 (NetworkPolicy)

NetworkPolicyNamespaceごとのネットワーク設定や、Podのアクセス制御の機能を提供します。KubernetesのネットワークがNetworkPolicyをサポートしない場合はこの設定は無視されます。

マニュアルの例(Namespaceごとのネットワーク設定)

kind: Namespace
apiVersion: v1
metadata:
  # アノテーションで分離の設定をいれる
  annotations:
    # 全てのPod外からの通信を拒否する。1.5時点でのサポートはDefaultDenyだけ
    net.beta.kubernetes.io/network-policy: |
      {
        "ingress": {
          "isolation": "DefaultDeny"
        }
      }

マニュアルの例(NetworkPolicy)

kind: NetworkPolicy
apiVersion: extensions/v1beta1
metadata:
  name: access-nginx
spec:
  # 制限する対象
  podSelector:
    matchLabels:
      run: nginx
  ingress:
    # 許可する対象
    - from:
      - podSelector:
          matchLabels:
            access: "true"

参考

リソース管理

Podのリソース制御 (requests, limits)

spec.containers[].resourcesrequests, limitsの指定によってPodのリソース(現状はCPUとメモリ)の制御が行えます。requestsは最低限確保して欲しい値を指定し、limitsは使用できる最大の値を指定します。

以下はマニュアルの例より

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: db
    image: mysql
    # リソース制御の指定
    resources:
      # 最低限確保してほしいCPU、メモリ
      requests:
        memory: "64Mi"
        # 0.25コア分
        cpu: "250m"
      # 使用できる最大の値
      limits:
        # メモリの場合はこれを超えるとターミネートされる
        memory: "128Mi"
        cpu: "500m"
  # 以下省略

Namespaceのリソース制御 (ResourceQuota)

ResourceQuotaNamespace単位でのリソース制御の仕組みを提供します。CPU、メモリのリソースの他に、オブジェクトの数(PodやServiceの数)をNamespaceごとに設定することができます。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-resources
spec:
  hard:
    # リソース数の制限(ここではPod数)
    pods: "4"
    # 最低限確保してほしいCPU、メモリ
    requests.cpu: "1"
    requests.memory: 1Gi
    # 使用できるCPU、メモリの最大値
    limits.cpu: "2"
    limits.memory: 2Gi

利用状況はkubectl describe ns NAMESPACEで以下のように確認することができます。

$ kubectl describe ns myspace
Name:   myspace
Labels: <none>
Status: Active

Resource Quotas
 Name:                  compute-resources
 Resource               Used    Hard
 --------               ---     ---
 limits.cpu             0       2
 limits.memory          0       2Gi
 pods                   0       4
 requests.cpu           0       1
 requests.memory        0       1Gi

No resource limits.

参考

設定管理

シークレット管理 (Secret)

Secretはパスワードや秘密鍵といった秘密情報を扱うための機能です。Secretを使うことでアプリケーションの定義に秘密情報を含まなくてよくなります。またアプリケーションからAPIサーバーにアクセスするためのServiceAccountのクレデンシャルにもSecretが使われており、これはVolumeとして自動的にマウントされるようになっています。

設定情報管理 (ConfigMap)

ConfigMapはアプリケーションの定義と別に設定情報を管理するための機能です。設定情報はPodに対して環境変数、、ファイル(Volume)、コンテナ引数といった形で渡すことができます。

認証・認可

認証

Kubernetesは下記のようないろいろなユーザ認証方式を提供しています。Kubernetes自体はユーザは管理しておらず(ServiceAccountは除く)、認証方法ごとに取得するユーザ名をそのまま利用する形を取っています。

方法 備考
X509 Client Certs クライアント証明書。CNがユーザ名、Oがグループになります。例: /CN=jbeda/O=app1/O=app2
Static Token File トークン認証。CSVで定義します。Authorization: Bearer $TOKENヘッダで認証。
Static Password File Basic認証。CSVで定義します。
Service Account Tokens ServiceAccountのJWT形式のトークン認証。
OpenID Connect Tokens OIDCのID Tokenによる認証。
Webhook Token Authentication 外部のWebAPIによる認証。
Authenticating Proxy 認証プロクシーを前段においてヘッダでユーザ名が渡される方式
Keystone Password Openstack Keystoneを使ったBasic認証。

参考

認可

Kubernetesでは認可も下記のように複数の方式が提供されています。認証されたユーザが何ができるかを管理する機能です。

方法 備考
AlwaysDeny 全て否認。テスト用です。
AlwaysAllow 全て承認。AlwaysAllowの設定です。認可が不要な場合に使います
ABAC Attribute-Based Access Control。属性によるアクセス制御。Policyファイルによる静的な定義になるため、反映には再起動が必要です
RBAC Roles-Based Access Contro。ロールによるアクセス制御。リソースを使った動的な管理が可能です
Webhook 外部のWebAPIによる認可。

参考

ヘッドレスアカウント (ServiceAccount)

Kubernetesでは人に対する認証の他に、アプリケーションなど人を介さない(ヘッドレス)場合の認証としてServiceAccountという仕組みが用意されています。例えばKubernetes DashboardのようなアプリケーションがAPIサーバーとやり取りする場合にServiceAccountが使われています。

NamespaceごとにdefaultというServiceAccountが作られている他、kubectl create serviceaccountで独自のServiceAccountを作ることができます。

参考

APIサーバーのリクエスト制御 (AdmissionControl)

Admission ControlはKubernetesのAPIサーバーのリクエスト制御の機能です。APIリクエストに対して認証、認可を行ったあとのフェーズで、別途そのリクエストを受け入れるか制御を行います。また場合によって、リクエストの変更や別の操作を行います。

プラグイン形式で複数の制御の方法が用意されており、APIの起動オプション--admission-controlで有効にしたいものをカンマ区切りで指定します。

v1.5では下記のプラグインが用意されています。

  • AlwaysAdmit
  • AlwaysDeny
  • AlwaysPullImages
  • DefaultStorageClass
  • DenyEscalatingExec
  • DenyExecOnPrivileged
  • ImagePolicyWebhook
  • InitialResources
  • LimitPodHardAntiAffinityTopology
  • LimitRanger
  • NamespaceAutoProvision
  • NamespaceExists
  • NamespaceLifecycle
  • OwnerReferencesPermissionEnforcement
  • PersistentVolumeLabel
  • PodNodeSelector
  • PodSecurityPolicy
  • ResourceQuota
  • SecurityContextDeny
  • ServiceAccount

参考

セキュリティ

セキュリティ設定(SecurityContext)

SecurityContext, PodSecurityContextContainerPodに対して下記のセキュリティの設定を可能にします。

Podに対する設定 (PodSecurityContext)

  • seLinuxOptions SELinuxのオプション
  • runAsUser 実行するユーザのUID
  • runAsNonRoot rootで動かさないことを保証する (デフォルトfalse)
  • seLinuxContext SE Linuxのコンテキスト
  • supplementalGroups Supplemental Groupの指定
  • fsGroup ファイルシステムのGroupの指定

コンテナに対する設定 (SecurityContext)

  • capabilities Linuxのcapabilitiesの設定
  • privileged 特権モードで動かすかどうか (デフォルトfalse)
  • seLinuxOptions SELinuxのオプション
  • runAsUser 実行するユーザのUID
  • runAsNonRoot rootで動かさないことを保証する (デフォルトfalse)
  • readOnlyRootFilesystem read-onlyのルートファイルシステムかどうか (デフォルトfalse)

参考

Podのセキュリティポリシーの強制 (PodSecurityPolicy)

PodSecurityPolicyはPodに対してセキュリティポリシーを強制する機能です。AdmissionControlでPodSecurityPolicyプラグインを有効にすることで、下記のようなポリシーを全てのPodに強制することができます。

  • runAsUser 実行するユーザのUID
  • seLinuxContext SE Linuxのコンテキスト
  • supplementalGroups Supplemental Groupの指定
  • fsGroup ファイルシステムのGroupの指定
  • volumes 使えるボリュームの種別の制限

参考

コンテナイメージのポリシー制御 (ImagePolicyWebhook)

ImagePolicyWebhookはKubernetesクラスタ上で動かすコンテナイメージを独自に制御したい場合に使える仕組みです。下記のようなユースケースが想定されているようです。

  • 既知の脆弱性を含まないことを確認されたイメージだけを動かしたい
  • 特定のベースイメージを使ったイメージだけを動かしたい
  • レビュー済みのコードでビルドされたイメージだけを動かしたい
  • 署名されたイメージだけを動かしたい

Image Policy Webhookは、ユーザが定義するWebAPIに対してそのPodに含まれるコンテナイメージの情報を渡し、実行可否をチェックする仕組みです。コンテナイメージ制御自体は自前のWebAPIで行う必要があります。Admission ControllerプラグインImagePolicyWebhookとして実装されています。

参考

外部システムとの連携

クラウドプロバイダの対応 (cloudprovider)

Kubernetesはクラウドプロバイダ(AWS, GCPなど)のロードバランサやインスタンス情報と連携する機能を持っています。v1.5時点では下記のクラウドプロバイダの実装が用意されています。

  • Amazon Web Services
  • Microsoft Azure
  • CloudStack
  • Google Compute Engine
  • Mesos
  • OpenStack
  • oVirt
  • Photon
  • Rackspace
  • vSphere

cloudproviderには下記のインタフェースが定義されており、プロバイダごとにこれを実装する形になっています。サポート状況はプロバイダによって異なります。

// Interface is an abstract, pluggable interface for cloud providers.
type Interface interface {
    // LoadBalancer returns a balancer interface. Also returns true if the interface is supported, false otherwise.
    LoadBalancer() (LoadBalancer, bool)
    // Instances returns an instances interface. Also returns true if the interface is supported, false otherwise.
    Instances() (Instances, bool)
    // Zones returns a zones interface. Also returns true if the interface is supported, false otherwise.
    Zones() (Zones, bool)
    // Clusters returns a clusters interface.  Also returns true if the interface is supported, false otherwise.
    Clusters() (Clusters, bool)
    // Routes returns a routes interface along with whether the interface is supported.
    Routes() (Routes, bool)
    // ProviderName returns the cloud provider ID.
    ProviderName() string
    // ScrubDNS provides an opportunity for cloud-provider-specific code to process DNS settings for pods.
    ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string)
}

永続ストレージ連携(PersisntentVolume / PersisntentVolumeClaim)

PersistentVolumeは永続ストレージとの連携する機能を提供します。Kubernetes v1.5時点では下記のストレージに対応しています。

  • awsElasticBlockStore
  • azureDisk
  • azureFile
  • cephFS
  • cinder (OpenStack block storage)
  • fc (Fibre Channel)
  • flexVolume
  • flocker
  • gcePersistentDisk
  • glusterfs
  • hostPath (Nodeのホストのパス)
  • iscsi
  • nfs
  • photonPersistentDisk
  • quobyte
  • rbd (Ceph Block Device)
  • vsphereVolume

参考

拡張性

独自のリソース定義(ThirdPartyResource)

ThirdPartyResourceはユーザが独自のKubernetesのリソースを定義できる機能です。Kubernetesのリソース管理の仕組みをそのままフレームワークとして利用することができます。高度なアプリケーションの運用を実現するCoreOSのOperatorや、同じくCoreOSのOpenID Connect Provider dexのデータストアなど活用例が増えてきました。

ThirdPartyResourceの詳細については @shmurata さんのフレームワークとしての Kubernetesという記事がよくまとまっています。

おわりに

機能をまとめてみて改めてKubernetesの機能の多さに驚かされました。引き続きKubernetesの発展に注目していきたいと思います。 :eyes: