Cloud Run ユーザーによる Kubernetes 入門
Kubernetesに入門してみる
この記事は Commune Advent Calendar 2024 シリーズ 1 の 22日目の記事です。
Kubernetes の第一歩として「Kubernetes の基本をちょっと知る」ことをテーマに記事という名の備忘録を書きます。
はじめに
Google Cloudを使用しているとCloud Run は便利ですが、柔軟なスケーリングや高度な設定が必要な場合、Kubernetes の導入を検討することがあります。しかし、Kubernetes には "とっつきにくい" イメージがあり、最初の一歩を踏み出すのが難しいと感じる人も多いのではないでしょうか?
この記事では、ほとんど使ったことがない私が Kubernetes の基本的な使い方を知るための第一歩を紹介します。個人的には概念をさらっと眺めた上で手を動かすのがオススメな気がしています。
Kubernetes の概要
Kubernetes(K8s)は、Google が開発したコンテナオーケストレーションツールです。アプリケーションのデプロイ、スケーリング、管理を自動化するための強力な仕組みを提供します。
Kubernetes の特徴
-
自動デプロイと管理
- 定義した状態(YAML)に基づいてコンテナをデプロイし、安定した動作状態を維持します。
-
自己修復
- 異常が発生したコンテナを自動的に再起動・置き換えし、サービスを維持します。
-
宣言的な設定管理
- 設定は YAML ファイルに記述し、コードとして管理できます。
Kubernetes のアーキテクチャ概要
Kubernetes は複数のコンポーネントから構成されています。以下に主要なコンポーネントとその役割を示します。
1. Kubernetes の全体図
以下は Kubernetes の全体アーキテクチャのイメージです。
2. コントロールプレーン (Control Plane)
Kubernetes クラスタ全体を管理するコンポーネントです。
-
kube-api-server: Kubernetes の全ての操作を受け付けるインターフェース。
kubectl
からのリクエストがここに送られます。 - kube-controller-manager: 複数のコントローラープロセスを管理・実行する。
- kube-scheduler: 新しく作成された Pod に対して適切な配置先となるノードを決定します。nodeSelectorやaffinityなどを使用することで意図したスケジューリングをすることも可能なようです。
- cloud-controller-manager: Cloudとの連携が必要になる複数のコントローラープロセスを管理・実行する。
- etcd: クラスタの設定や状態情報を保存する分散キーバリューストアです。
3. ワーカーノード (Worker Nodes)
実際にアプリケーションコンテナが動作する場所です。
- Kubelet: 各ノード上で動作し、Pod のライフサイクルを管理します。
- Kube-proxy: ネットワークルーティングを管理し、Service へのアクセスを制御します。
- Container Runtime: コンテナの実行エンジン。
4. その他のリソース
- Pod: Kubernetes の最小単位であり、1つまたは複数のコンテナを含みます。
- Service: Pod へのネットワークアクセスを提供します。
- Deployment: 複数の Pod を管理し、スケーリングやローリングアップデートを制御します。
Kubernetes を触ってみる (ローカル環境編)
まずは Kubernetes をローカル環境で動かしてみましょう。Docker Desktop の Kubernetes 機能を使うと手軽に始められます。
環境準備
- Docker Desktop のインストール: Docker Desktop 公式サイト
-
Kubernetes を有効化:
- Docker Desktop の設定 > Kubernetes > "Enable Kubernetes" にチェック。
- kubectlのインストール: こちらの手順に従い、実行します。このkubectlを使用してyamlやコマンドをAPIリクエストとしてkube-api-serverに送ります。
kubeconfigの設定
kubectlの設定ファイルはデフォルトでは$HOME/.kube/config
にあるのでそれを見てみます。
less $HOME/.kube/config > config.yaml
のように書き出すと見やすくなります。
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: xxxxx
server: https://127.0.0.1:6443
name: docker-desktop
- cluster:
certificate-authority-data: xxxxx
server: https://127.0.0.1:64639
name: kind-kind
contexts:
- context:
cluster: docker-desktop
user: docker-desktop
name: docker-desktop
- context:
cluster: kind-kind
user: kind-kind
name: kind-kind
current-context: docker-desktop
kind: Config
preferences: {}
users:
- name: docker-desktop
user:
client-certificate-data: xxxxx
client-key-data: xxxxx
- name: kind-kind
user:
client-certificate-data: xxxxx
client-key-data: xxxxx
-
clusters
: 複数のクラスター(cluster)を指定することができます。(私のローカル環境ではdocker-desktopとkindでクラスターを扱っているので下記では複数のクラスターが表示されています。) -
users
: clustersと同様で複数のユーザー情報、認証情報が指定されています。 -
context
: clusterとuserのデータのペアでどのクラスターにどのユーザーで接続するかという情報がコンテキストになります。 -
current-context
: 現在のコンテキスト情報です。(現在繋いでるのはどのクラスターでどのユーザーかという情報が入っています。)
次のコマンドで現在のコンテキストを確認します。
kubectl config current-context
docker-desktop
Podのデプロイ
Kubernetes の最小単位である Pod をデプロイしてみます。シンプルな NGINX コンテナを例にします。Podは1つまたは複数のコンテナのグループであり、ネットワークやストレージを共有リソース(namespace, cgroup)として持ち、コンテナの実行方法に関する仕様(entrypoint, healthcheck...)を持ちます。
Podの概要
- 基本的には1つのアプリケーションを複数のPodとしてデプロイします。
- 複数のアプリケーションを1つのPodに入れません。
- ログや監視用途で入れる場合は別。
- 一時的なデバッグ、テスト、勉強で使用してみるといった用途を除いて、本番環境でPodを直接操作することはなく、Deploymentなどの管理リソースを使用するのが一般的です。
1. Pod の YAML 定義
以下の YAML を pod-nginx.yaml
として保存します。
apiVersion: v1
kind: Pod
metadata:
name: nginx-sample
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
-
apiVersion
: Kubernetes リソースの API バージョン。 -
kind
: リソースの種類 (ここでは Pod)。 -
metadata
: Pod 名やラベル情報。 -
spec
: コンテナやポート情報を定義。
2. Pod のデプロイ
以下のコマンドで Pod をデプロイします。
kubectl apply -f pod-nginx.yaml
3. Pod の確認
Pod が正しく起動しているか確認します。
kubectl get pods
4. アクセス確認
kubectl port-forward
コマンドを使い、ローカルから NGINX にアクセスします。
kubectl port-forward pod/nginx-sample 8080:80
ブラウザや curl
でアクセス:
curl http://localhost:8080
これで Kubernetes 上で NGINX が動いていることを確認できます!
Namespace
Namespaceの概要
同一のクラスター上で複数の仮想クラスターの動作をサポートします。要は1つのクラスターを論理的に分けて使用するためのものです。チーム単位や環境単位で分けたりされます。
初期Namespace
- default: デフォルトのNamespaceです。Namespaceの指定をしない場合リソースはここに作成されます。
- kube-system: Kubernetesのシステムコンポーネントが稼働しているNamespaceです。下記コマンドでkube-systemのpodを確認してみるとcorednsやkube-api-serverなどのコンポーネントを確認することができます。
kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-76f75df574-mkbc9 1/1 Running 1 (42h ago) 10d
coredns-76f75df574-rscxn 1/1 Running 1 (42h ago) 10d
etcd-docker-desktop 1/1 Running 1 (42h ago) 10d
kube-apiserver-docker-desktop 1/1 Running 1 (42h ago) 10d
kube-controller-manager-docker-desktop 1/1 Running 1 (42h ago) 10d
kube-proxy-k425s 1/1 Running 1 (42h ago) 10d
kube-scheduler-docker-desktop 1/1 Running 1 (42h ago) 10d
storage-provisioner 1/1 Running 2 (42h ago) 10d
vpnkit-controller 1/1 Running 1 (42h ago) 10d
- kube-public: クラスタ全体で共有可能な公開情報を格納するために存在している名前空間で全てのユーザーから読み取りが可能になっています。
- kube-node-lease: Nodeの存在確認するための名前空間で各Nodeに対するLeaseオブジェクトを保持しています。(各NodeがLeaseオブジェクトを更新します。)
ReplicaSet
ReplicaSet は、指定された数(レプリカ数)の Pod を常に維持する役割を持つリソースです。たとえば、アプリケーションを 3 つの Pod としてデプロイしたい場合に、ReplicaSet を使用すれば、Pod が異常終了した場合でも自動で再生成されます。
ReplicaSet の YAML 定義例
以下は ReplicaSet
の具体例です。名前やラベルを nginx-sample
に合わせています。
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-sample-rs
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
ReplicaSet の主な要素
-
metadata.name
: ReplicaSetの名前です。 -
replicas
: 作成する Pod の数を指定します(この例では 3)。 -
selector
: Pod を識別するためのラベルを定義します。 -
template
: Pod のテンプレート。生成される Pod の名前やコンテナイメージを記述します。
ReplicaSet実行してみる
上記のyamlファイルをnginx-sample-rs.yaml
として保存し、下記を実行します。
kubectl apply -f nginx-sample-rs.yaml
kubectl get pod
nginx-sample-rs-9bt5h 1/1 Running 0 41s
nginx-sample-rs-qxpk4 1/1 Running 0 41s
上記のyamlのreplicas
を5にして、再度applyをすると・・・次のようになります。
nginx-sample 1/1 Running 0 137m
nginx-sample-rs-9bt5h 1/1 Running 0 5m9s
nginx-sample-rs-psv8x 1/1 Running 0 6s
nginx-sample-rs-qxpk4 1/1 Running 0 5m9s
nginx-sample-rs-x4zpt 1/1 Running 0 6s
おわりに
今回、Kubernetesを触ったことがない状態から雑ではありましたが諸々触ってきました。ローカルでもdocker-desktopを使用して気軽に操作はできたので是非操作してみて欲しいです。今回は記事の途中で力尽きてしまったのでここで終わりにしてしまいましたがDeploymentやServiceに入る手前の気持ち悪いところで終わってしまったので続きがやりたくなっていると思います。次はGKEやKubernetesを使用してnamespaceを分割し実際のアプリケーション間で通信させるなどの例をご紹介できればと思います。
Discussion