この連載が書籍になりました!『Kubernetes完全ガイド

Kubernetesの基礎

2018年3月14日(水)
青山 真也
連載の3回目となる今回は、Kubernetesの基本とkubectlコマンドの概要について解説する。

Kubernetes の基礎

第2回目までは分かりやすくするために、「KubernetesがDockerホストを管理している」とお話してきました。しかし実際には、Docker以外のコンテナランタイムを用いたホストも管理することができるように作られています。そのため、これ以降はKubernetes Nodeと表記していきます。実際にはKubernetesはKubernetes MasterとKubernetes Nodeから成り立っています。Kubernetes MasterはAPIエンドポイントの提供、コンテナのスケジューリング、コンテナのスケーリングなどを担います。もう一方のKubernetes Nodeは、いわゆるDocker Hostに相当する実際にコンテナが起動するホストです。

Kubernetes MasterとKubernetes Nodeの関係

Kubernetes MasterとKubernetes Nodeの関係

Kubernetesクラスタを操作する際には、CLIツールのkubectlとYAML形式で書かれたManifestファイルを用いてKubernetes Masterに「リソース」の登録を行います。実際にはkubectlも内部でKubernetes MasterのAPIを叩いているだけなので、ライブラリやcurlなどでも操作することが可能です。

Kubernetesとリソース

Kubernetes では「リソース」を登録することで、非同期にコンテナの実行やロードバランサの作成が行われます。リソースにはコンテナ、ロードバランサ、ノードなど様々な種類があり、リソースによってYAMLマニフェストに指定できるパラメータが異なります。PodリソースがKubernetesクラスタのdefault namespace上に登録されている場合には、API的には/api/v1/namespaces/default/pods/以下に登録されています。

Kubernetesのリソースはたくさんの種類がありますが、大きく分けて次の5種類に大別されています。

Kubernetes API Reference Docs

Kubernetesのリソース

リソースの分類内容
Workloadsリソースコンテナの実行に関するリソース
Discovery&LBリソースコンテナを外部公開するようなエンドポイントを提供するリソース
Config&Storageリソース設定・機密情報・永続化ボリュームなどに関するリソース
Clusterリソースセキュリティやクォータなどに関するリソース
Metadataリソースリソースを操作する系統のリソース

今回の連載では全体像を把握出来るように、ユーザが利用する5種類のリソースについて説明していきます(内部的に利用されているリソースは除きます)。次回以降、これらの各リソースについて詳細な説明を行います。また、この中でもアプリケーション開発者が特に利用するのは、Workload、Discovery&LB、Config&Storageの3種類になります。

Workloadsリソース

1つ目のWorkloadsリソースは、クラスタ上にコンテナを起動させるのに利用するリソースです。内部的に利用されているものを除いて利用者が直接利用するものとしては、全部で8種類のWorkloadsリソースが存在します。

  • Pod
  • ReplicationController
  • ReplicaSet
  • Deployment
  • DaemonSet
  • StatefulSet
  • Job
  • CronJob

Discovery&LBリソース

2つ目のDiscovery&LBリソースは、コンテナのサービスディスカバリや、外部からもアクセス可能なエンドポイントなどを提供するリソースです。内部的に利用されているものを除いて利用者が直接利用するものとしては、ServiceとIngressの2種類のDiscovery&LBリソースが存在します。そのうちのServiceには、エンドポイントの提供方式が異なる複数のタイプが用意されています。

  • Service
    • ClusterIP
    • NodePort
    • LoadBalancer
    • ExternalIP
    • ExternalName
    • Headless
  • Ingress

Config&Storageリソース

3つ目のConfig&Storageリソースは、設定や機密データをコンテナに埋め込んだり、永続ボリュームを提供するリソースです。SecretとConfigMapはいずれもKey-Valueのデータ構造を持ち、設定に適しているか機密データに適しているかの違いがあります。PersistentVolumeClaimは、コンテナから永続ボリュームを利用する際に利用します。

  • Secret
  • ConfigMap
  • PersistentVolumeClaim

Clusterリソース

4つ目のClusterリソースは、クラスタ自体の振る舞いを定義するリソースです。様々なリソースが存在していますが、セキュリティや利便性に関する設定、ポリシーなどのリソースが該当します。

  • Namespace
  • ServiceAccount
  • Role
  • ClusterRole
  • RoleBinding
  • ClusterRoleBinding
  • NetworkPolicy
  • ResourceQuota
  • PersistentVolume
  • Node

Metadataリソース

5つ目のMetadataリソースは、クラスタ内の他のリソースの動作を制御するようなリソースです。例えば、Podをオートスケールさせるために利用されるHorizontalPodAutoscalerは、Deploymentなどのリソースを操作することでオートスケールを実現しています。

  • CustomResourceDefinition
  • LimitRange
  • HorizontalPodAutoscaler

Namespaceによる仮想的なクラスタの分離

KubernetesにはNamespaceと呼ばれる仮想的なKubernetesクラスタの分離機能が存在します。完全な分離レベルではないため使い所は限られますが、1つのKubernetesクラスタを複数チームで利用することが可能です。マネージドサービスや構築ツールを使って構築されるKubernetesクラスタの大部分は、RBAC(Role-Based Access Control)がデフォルトで有効になっているため、Namespaceをスコープとした権限設定をすることにより、分離性を高めることが可能です。

Kubernetesは初期状態で、下記の3つのNamespaceを作成します。kube-systemでは、慣習的にKubernetes Dashboardといったシステムコンポーネントやアドオン的な位置づけのシステムが展開されます。もう一方のkube-publicでは、慣習的に全ユーザが共通して利用する設定値などを保存しておくNamespaceとして作られています。複数人で共有利用する予定がなく、システムが複雑ではない場合には、default Namespaceを利用する運用で問題ないと思います。

  • default:デフォルトのNamespace
  • kube-system:Kubernetesクラスタのコンポーネントやaddonが展開されるNamespace
  • kube-public:全ユーザが利用できるConfigMapなどを配置するNamespace
KubernetesのNamespace

KubernetesのNamespace

CLIツールkubectlと認証情報

kubectlがKubernetes Masterとやり取りを行う際には、接続先サーバの情報や認証情報などが必要となります。デフォルトではkubectlは「~/.kube/config」に書かれている情報をもとに接続を行います。~/.kube/configもYAML Maniestと同じフォーマットとなっており、下記のような形で書かれています。

リスト1:~/.kube/configの例

apiVersion: v1
kind: Config
preferences: {}
clusters:
  - name: sample-cluster
    cluster:
      server: https://localhost:6443
users:
  - name: sample-user
    user:
      client-certificate-data: LS0tLS1CRUdJTi...
      client-key-data: LS0tLS1CRUdJTi...
contexts:
  - name: sample-context
    context:
      cluster: sample-cluster
      namespace: default
      user: sample-user
current-context: sample-context

~/.kube/configにはcluster、user、contextの3種類を定義するようになっています。clustersには接続先クラスタの情報、usersには認証情報をそれぞれ定義します。認証情報には様々なproviderが利用できるようになっています。そしてcontextには、clusterとuser のペアにnamespaceを指定したものを定義します。kubectlはこのcontextを切り替えていくことで、複数の環境を操作できるように設計されています。

ContextとUser/Clusterの関係

ContextとUser/Clusterの関係

上記のような設定は手動で作成することも可能ですが、kubectlコマンドを使って作成することもできます。

リスト2:kubectlで設定を行う

# クラスタの定義
$ kubectl config set-cluster prd-cluster \
    --server=https://localhost:6443

# 認証情報の定義
$ kubectl config set-credentials admin-user \
    --client-certificate=./sample.crt \
    --client-key=./sample.key \
    --embed-certs=true

# コンテキストの定義 (クラスタ、認証情報、Namespace を定義)
$ kubectl config set-context prd-admin \
    --cluster=prd-cluster \
    --user=admin-user \
    --namespace=default

実際にコンテキストを切り替えながら使うことで、複数のクラスタやユーザを扱うことが可能です。

リスト3:kubectlでコンテキストを操作する

# コンテキストの切り替え
$ kubectl config use-context prd-admin
Switched to context "prd-admin".

# 現在のコンテキストを表示
$ kubectl config current-context
prd-admin

コンテキストやネームスペースの切り替えを行うkubectlのコマンドが冗長だと思う方は、kubectx/kubensの利用も検討してみて下さい。

リスト4:kubectx/kubensの使用例

# コンテキストの切り替え
$ kubectx prd-admin
Switched to context "prd-admin".

# ネームスペースの切り替え
$ kubens kube-system
Context "prd-admin" is modified.
Active Namespace is "kube-system".

kubectlとYAML Manifest

さて、kubectlが利用できるようになったところで、実際にYAML Maniefstを使ってコンテナを起動してみましょう。今回は次のような1コンテナからなるPodを作成してみます。

リスト5:Manifestの例

# sample-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
spec:
  containers:
    - name: nginx-container
      image: nginx:1.12

リソースを作る際は、kubectl createコマンドを利用します。すでに該当のリソースが存在する場合には、Errorが発生します。

リスト6:kubectl createコマンド

# リソースが存在しない場合
$ kubectl create -f sample-pod.yml
pod "sample-pod" created

# リソースが存在する場合
$ kubectl create -f sample-pod.yml
Error from server (AlreadyExists): error when creating "sample-pod.yml": pods "sample-pod" already exists

一方でリソースを削除する際は、kubectl deleteコマンドを利用します。こちらもリソースが存在しない場合には、Errorが発生します。

リスト7:kubectl deleteコマンド

# リソースが存在する場合
$ kubectl delete -f sample-pod.yml
pod "sample-pod" deleted

# リソースが存在しない場合
$ kubectl delete -f sample-pod.yml
Error from server (NotFound): error when stopping "sample-pod.yml": pods "sample-pod" not found

リソースの更新は、kubectl applyコマンドを利用します。今回はDockerイメージのアップデートを想定して、先ほどのsample-pod.ymlのイメージタグの部分を下記のように編集します。

リスト8:Manifestを更新

# 変更差分
8c8
<       image: nginx:1.12
---
>       image: nginx:1.13

新しいnginx imageを利用するようにYAMLファイルを書き換えたあとは、kubectl applyコマンドを使って変更を適用します。kubectl applyコマンドは、変更差分がある場合には変更処理を行い、変更差分がない場合には何もしません。また、リソースが存在しない場合には、kubectl createコマンドと同様に新規作成を行います。そのため基本的にはkubectl createではなくkubectl applyを使ったほうが利便性は高いといえます。

リスト9:kubectl applyコマンド

# 変更点がある場合
$ kubectl apply -f sample-pod.yml
pod "sample-pod" configured

# 変更点がない場合
$ kubectl apply -f sample-pod.yml
pod "sample-pod" unchanged

# リソースが存在しない場合
$ kubectl apply -f sample-pod.yml
pod "sample-pod" created

その他、kubectl set、kubectl replace、kubectl editなどの各コマンドでも、更新処理を行うことが可能です。

株式会社サイバーエージェント アドテク本部 Strategic Infrastructure Agency

2016年入社。OpenStackを使ったプライベートクラウドやGKE互換なコンテナプラットフォームをゼロから構築し、国内カンファレンスでのKeynoteに登壇。
その後、世界で2番目にCertified Kubernetes Application Developer、138番目にCertified Kubernetes Administratorの認定資格を取得。
現在はKubernetesやOpenStackなどOSSへのコントリビュート活動をはじめ、CNCF公式のCloud Native Meetup TokyoのOrganizerやJapan Container Daysの運営などコミュニティ活動にも従事している。

連載バックナンバー

仮想化/コンテナ技術解説
第9回

KubernetesのConfig&Storageリソース(その2)

2018/6/6
連載9回目となる今回は、Config&Storageリソースのうち、PersistentVolumeClaimについて解説する。
仮想化/コンテナ技術解説
第8回

KubernetesのConfig&Storageリソース(その1)

2018/5/31
今回と次回の2回に渡って、5種類に大別されるKubernetesのリソースのうち、Config&Storageリソースを解説する。
仮想化/コンテナ技術解説
第7回

KubernetesのDiscovery&LBリソース(その2)

2018/5/16
前回に引き続き、Discovery&LBリソースのServiceとIngressを紹介する。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています