ソフトウェア開発の世界で働いているなら、Kubernetesという言葉をきっと聞いたことがあるでしょう。しかし、それは一体何であり、なぜコンテナ化されたアプリケーションを管理するためのデファクトスタンダードになったのでしょうか?このガイドでは、基本から始めて、実践的な例と図を使って基本的な概念を理解する手助けをします。
Kubernetes以前:少し歴史を振り返って
Kubernetesがなぜそれほど革命的であるかを理解するために、一歩下がってみましょう。
- 従来のデプロイメント:当初、アプリケーションは物理サーバー上で実行されていました。このアプローチはコストが高く、スケーリングが難しく、リソースの競合が発生しやすいものでした。
- 仮想化デプロイメント:次に仮想マシン(VM)が登場しました。VMにより、同じハードウェア上で複数の隔離されたアプリケーションを実行できるようになり、リソースの利用率とセキュリティが向上しました。しかし、各VMは完全なオペレーティングシステムを実行するため、多くのリソースを消費します。
- コンテナ化デプロイメント:コンテナ(Dockerなど)は次の進化です。コンテナは同じホストオペレーティングシステムを共有しますが、隔離されたプロセスを実行します。軽量で、起動が速く、ポータブルです。
コンテナはポータビリティの問題を解決しましたが、別の問題を生み出しました。それは、本番環境で数百(または数千)のコンテナをどのように管理するかということです。それらが常に実行されていること、互いに通信できること、そして負荷に応じてスケールすることを確認するにはどうすればよいでしょうか?
ここでKubernetesが登場します。
Kubernetesとは?
Kubernetes(しばしばK8sと略されます)は、コンテナオーケストレーションのためのオープンソースプラットフォームです。簡単に言えば、コンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化します。Googleによって作成され、現在はCloud Native Computing Foundation(CNCF)によって維持されており、Kubernetesはマイクロサービスを大規模に扱うすべての人にとって頼りになるツールとなっています。
Kubernetesクラスターのアーキテクチャ
Kubernetes環境はクラスターと呼ばれます。クラスターは、アプリケーションを実行する一連のマシン(ノードと呼ばれます)で構成されています。アーキテクチャは、コントロールプレーンとワーカーノードの2つの主要部分に分かれています。
コントロールプレーン
コントロールプレーンはクラスターの「頭脳」です。グローバルな決定(スケジューリングなど)を行い、クラスターイベントを検出して応答します。その主要なコンポーネントは次のとおりです。
- APIサーバー (
kube-apiserver
):クラスターへのゲートウェイです。Kubernetes APIを公開し、ユーザー(kubectl
経由)、クラスターコンポーネント、外部ツールが通信するために使用します。 - etcd:一貫性があり、高可用性のキーバリューデータベースです。すべてのクラスターデータを保存し、システムの望ましい状態と現在の状態を表します。
- スケジューラ (
kube-scheduler
):新しく作成されたPodを、リソース要件、ポリシー、その他の制約を考慮して利用可能なワーカーノードに割り当てます。 - コントローラーマネージャー (
kube-controller-manager
):コントローラーを実行します。これらは、クラスターの状態を監視し、それを望ましい状態にするために働く制御ループです。たとえば、Node Controller
はノードを管理し、Replication Controller
は正しい数のPodが実行されていることを確認します。
ワーカーノード
ワーカーノードは、アプリケーションが実際に実行されるマシン(物理または仮想)です。各ノードはコントロールプレーンによって管理され、次のコンポーネントが含まれています。
- Kubelet:各ノードで実行されるエージェントです。Podで記述されたコンテナが実行され、正常であることを確認します。
- Kube-proxy:ノード上のネットワークルールを管理するネットワークプロキシです。クラスター内外のネットワークセッションからPodへのネットワーク通信を可能にします。
- コンテナランタイム:コンテナの実行を担当するソフトウェアです。Dockerが最も有名ですが、Kubernetesは
containerd
やCRI-O
などの他のランタイムもサポートしています。
Kubernetesの基本オブジェクト
Kubernetesでは、すべてがオブジェクトによって表されます。これらのオブジェクトは「意図の記録」です。オブジェクトを作成すると、Kubernetesはそれが存在し、望ましい状態と一致することを保証するために常に働きます。
最も重要なものは次のとおりです。
Pod
PodはKubernetesで最小の実行単位です。同じノードで一緒に実行される1つ以上のコンテナを表し、ネットワークやストレージなどのリソースを共有します。
通常、Podごとに1つのコンテナしか実行しませんが、高度なシナリオ(ロギングやモニタリングのための「サイドカーコンテナ」など)では、複数持つことができます。
Podを直接作成することはほとんどありません。Deploymentのような高レベルの抽象化を使用します。
Deployment
Deploymentは、最も頻繁に使用するオブジェクトです。同一のPodのグループの望ましい状態を記述します。Deploymentコントローラーは、次のことを担当します。
- ReplicaSet(特定の数のPodのレプリカが常に実行されていることを保証する別のオブジェクト)を作成および管理します。
- Podの数をスケーリング(増減)します。
- ダウンタイムなしで、制御された方法でアプリケーションの更新(例:ローリングアップデート)を管理します。
以下は、NGINXサーバーの3つのレプリカを実行するDeploymentのYAMLファイルの例です。
# nginx-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
Service
KubernetesのPodは一時的なものです。いつでも作成および破棄できます。各Podには独自のIPアドレスがありますが、このIPは安定していません。では、どうすればアプリケーションを確実に公開できるのでしょうか?
Serviceを使用します。Serviceは、論理的なPodのセットとそれらにアクセスするためのポリシーを定義する抽象化です。Podのグループに安定したアクセスポイント(仮想IPアドレスとDNS名)を提供します。
Serviceは、labels
に基づくselector
を使用して、トラフィックを転送するPodを見つけます。
以下は、NGINX Deployment用のServiceを作成する方法です。
# nginx-service.yaml apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP # デフォルト - クラスター内でのみサービスを公開
Serviceにはさまざまな種類があります。
ClusterIP
:クラスター内部IPでサービスを公開します(デフォルト)。NodePort
:各ワーカーノードの静的ポートでサービスを公開します。LoadBalancer
:クラウドプロバイダー(AWS、GCPなど)に外部ロードバランサーを作成し、サービスにパブリックIPを割り当てます。
Ingress
LoadBalancer
タイプのServiceは素晴らしいですが、サービスごとに作成するとコストがかかる可能性があります。複数のHTTP/HTTPSサービスを外部に公開するには、Ingressを使用します。
Ingressは、外部トラフィックの「インテリジェントなルーター」として機能します。ホスト(例:api.mysite.com
)またはパス(例:mysite.com/api
)に基づいてルーティングルールを定義できます。
以下はIngressの例です。
# example-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress spec: rules: - host: mysite.com http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 8080 - path: /ui pathType: Prefix backend: service: name: ui-service port: number: 3000
その他の便利なオブジェクト
- Namespace:物理クラスター内に「仮想クラスター」を作成できます。環境(例:
development
、staging
、production
)やチームを隔離するのに便利です。 - ConfigMapとSecret:コンテナイメージから切り離して、設定データやシークレット(パスワードやAPIキーなど)を管理します。
- StatefulSet:Deploymentに似ていますが、安定したネットワークIDと永続ストレージを必要とするステートフルなアプリケーション(データベースなど)に特化しています。
- PersistentVolume (PV)とPersistentVolumeClaim (PVC):クラスター内の永続ストレージを管理します。
結論
Kubernetesは非常に強力なツールですが、学習曲線が急な場合があります。このガイドは表面をなぞっただけですが、基本的な概念をしっかりと理解する助けになったことを願っています。
次に何をすべきか?
- ローカルで実験する:MinikubeまたはKindをインストールして、お使いのコンピューターにKubernetesクラスターを作成します。
kubectl
を使用する:クラスターと対話するための主要なツールであるkubectl
コマンドに慣れましょう。この記事のNGINX DeploymentとServiceを作成してみてください。- 公式チュートリアルを調べる:Kubernetesドキュメントは、例が豊富な素晴らしいリソースです。
コンテナオーケストレーションは、クラウドネイティブの世界における基本的なスキルであり、Kubernetesをマスターすれば、可能性の世界が広がります。楽しんでください!