Minikubeで動かして学ぶKubernetesとHelm入門
はじめに
本記事は、KubernetesとHelmに初めて触れる方に向けて、できるだけわかりやすく、最小構成でアプリをデプロイする手順を紹介するものです。
筆者自身、現在の職場でKubernetesやHelmを初めて触れた際、最初の理解に非常に苦労しました。この記事は、そのときの「どこでつまずいたか」「どうすれば理解が進んだか」をベースに、同じように悩む方の助けになればという思いと、自分の備忘録の意味も込めて書いています。
Kubernetes
Kubernetesは、コンテナ化されたワークロードやサービスを、宣言的な設定や自動化を用いながら、管理するための、ポータブルで拡張可能なオープンソースプラットフォームです。公式サイトでは以下のような定義がされています。
Kubernetes is a portable, extensible, open source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation. It has a large, rapidly growing ecosystem. Kubernetes services, support, and tools are widely available.
https://kubernetes.io/docs/concepts/overview/
Kubernetesは、コンテナの起動や停止だけでなく、必要に応じたスケーリング(Podの増減)や障害発生時のフェイルオーバーも自動的に行ってくれるため、安定した運用と効率的なリソース管理を実現できます。
Kubernetesの理解を深めるうえでは、コンテナの基本を押さえておくと理解がスムーズになります。コンテナは、仮想化技術の一つで、コードやその依存関係、ランタイムなどをパッケージにすることができます。これにより、アプリケーションをどの環境でも同じように動作させることが可能になります。Kubernetesは、こうしたコンテナを効率的かつ安定的に運用するためのプラットフォームです。
以下に公式サイトのリンクを貼っておきますが、ネット上に先人の方が書いた解説記事なども多数あるので、そちらを調べてみても良いかもしれません。今回の記事では、KubernetesとHelmのデプロイ周りに焦点を当てたいので、説明は省きます。
https://www.docker.com/ja-jp/resources/what-container/
Kubernetes Objects
Kubernetesでは、アプリケーションの状態を「オブジェクト」として宣言し、それに基づいてシステム全体が自動的に管理・調整されます。
オブジェクトはすべてYAML(またはJSON)形式のマニフェストファイルで定義され、kubectl や API 経由でKubernetesに適用されます。
Kubernetes objects are persistent entities in the Kubernetes system. Kubernetes uses these entities to represent the state of your cluster.
https://kubernetes.io/docs/concepts/overview/working-with-objects/
以下が主要なオブジェクトの一覧です。
オブジェクト | 説明 |
---|---|
Pod | コンテナを実行する最小単位(通常は1コンテナ) |
Deployment | 複数のPodを一貫して管理・スケーリング・更新 |
ReplicaSet | Deploymentが内部で使う、Podのレプリカ維持機構 |
Service | Podに対するネットワークアクセスを提供 |
Ingress | 外部のHTTPリクエストを、内部のServiceへルーティング |
ConfigMap / Secret | アプリの設定値や機密情報をPodに渡す仕組み |
これらのオブジェクトをどのように記述し、適用していくかは、次の章で紹介する「マニフェストファイル」の構造とあわせて具体的に見ていきます。
マニフェストファイル
Kubernetesでは、クラスタ上で動かすオブジェクトの情報を、マニフェストという設定ファイルに記述して管理します。このファイルは主に YAML形式 で書かれ、Kubernetesに「こういう状態にしてほしい」と伝えるための宣言的な定義です。
When you use the Kubernetes API to create the object (either directly or via kubectl), that API request must include that information as YAML or JSON in the request body. Most often, you provide the information to kubectl in a file known as a manifest.
https://kubernetes.io/docs/concepts/overview/working-with-objects/
マニフェストの特徴として、以下が挙げられます。
- 宣言的(declarative)
「何をどうしてほしいか」を定義するだけで、Kubernetesが状態を維持・調整してくれる - バージョン管理が容易
YAMLファイルなのでGitなどで変更履歴を管理しやすい - 再現性が高い
同じマニフェストを適用すれば、他の環境でも同じ状態を再現できる
マニフェストの基本構造は以下のようになっており、必須のプロパティとして、以下を持ちます。
フィールド | 説明 |
---|---|
apiVersion | そのリソースが使う Kubernetes API のバージョン |
kind | 作成したいオブジェクトの種類(例: Deployment, Service など) |
metadata | オブジェクト名、ラベル、Namespace などの識別情報 |
spec | 望ましい状態(例: Pod 数、イメージ名、ポートなど)を具体的に記述するセクション |
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
# ここにPodのテンプレート(containers、imageなど)を定義します
作成したマニフェストファイルは、kubectl apply コマンドでKubernetesに適用します:
kubectl apply -f deployment.yaml
これにより、Kubernetesは指定されたオブジェクトを作成し、望ましい状態に保つよう自動で制御を始めます。
これらのオブジェクトをどのように記述し、適用していくかは、Developmentと Service、Ingressの書き方を例として、この先の章で紹介していきます。
Deployment
Kubernetesにおける Deployment は、アプリケーションを構成するPodを安定的に管理するためのコントローラーです。
公式ドキュメントでは次のように定義されています:
A Deployment manages a set of Pods to run an application workload, usually one that doesn't maintain state.
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
Deploymentは内部的に ReplicaSet を利用して、指定した数のPodを常に維持し、必要に応じて再起動やローリングアップデート(段階的な更新)を行います。そのため、単なるPodの起動だけでなく、バージョン更新・スケーリング・フェイルオーバーといった実運用に欠かせない機能を支えてくれる重要な存在です。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: proxy
template:
metadata:
labels:
app.kubernetes.io/name: proxy
spec:
containers:
- name: nginx
image: nginx:stable
ports:
- containerPort: 80
name: http-web-svc
フィールド | 説明 |
---|---|
replicas | 起動するPodの数(例:2つ) |
selector | このDeploymentが管理するPodを識別するための条件 |
template | 実際に作成されるPodの仕様を定義 |
containers | Pod内で起動するコンテナ(ここではnginx) |
このマニフェストを deployment.yaml として保存し、以下のコマンドで適用することができます。
kubectl apply -f deployment.yaml
このように、Deploymentを使うことで、アプリケーションの起動・維持・更新をKubernetesに任せることができます。
次章では、Podに外部からアクセスするために必要なServiceの定義について紹介します。
Service
Kubernetesにおける Service は、複数のPodに対して安定したネットワークアクセスを提供するための抽象化オブジェクトです。
アプリケーションをPodとして動かす場合、Deploymentの仕組みによってPodは動的に作成・削除され、IPアドレスも変わります。
そのため、クライアントが直接PodのIPを指定して通信するのは現実的ではありません。Serviceは、複数のPodを1つのサービスとしてまとめ、仮想IPやDNS名を通じてアクセスできるようにする“ネットワーク上の入り口”です。
公式ドキュメントでは以下のように説明されています:
Expose an application running in your cluster behind a single outward-facing endpoint, even when the workload is split across multiple backends.
https://kubernetes.io/docs/concepts/services-networking/service/
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app.kubernetes.io/name: proxy
ports:
- name: name-of-service-port
protocol: TCP
port: 80
targetPort: http-web-svc
フィールド | 説明 |
---|---|
selector | ラベルにより対象Podを指定。DeploymentのPodと一致させる必要がある |
port | クライアントがアクセスするServiceのポート |
targetPort | http-web-svc は、Pod定義内のコンテナポートに name: http-web-svc が指定されている場合に使用されます。数値(例: 80)で書くことも可能です。 |
このマニフェストを service.yaml として保存し、以下のコマンドで適用することができます。
kubectl apply -f service.yaml
次章では、URLルーティングや複数Serviceの統合入り口として使える Ingress について解説します。
Ingress
Kubernetesにおける Ingress は、クラスタ外部から内部のServiceへHTTP/HTTPSアクセスをルーティングするためのエントリポイントです。
公式ドキュメントでは次のように説明されています。
Make your HTTP (or HTTPS) network service available using a protocol-aware configuration mechanism, that understands web concepts like URIs, hostnames, paths, and more. The Ingress concept lets you map traffic to different backends based on rules you define via the Kubernetes API.
https://kubernetes.io/docs/concepts/services-networking/ingress/
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
ingressClassName: nginx
rules:
- host: example.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
フィールド | 説明 |
---|---|
ingressClassName | 利用する Ingress Controller の指定(例: nginx ) |
rules | リクエストのホストやパスに基づいてルーティングするための定義 |
backend.service | 該当リクエストを転送するServiceとそのポート番号 |
pathType |
Prefix (前方一致)や Exact (完全一致)などのマッチ方式 |
このマニフェストを ingress.yaml として保存し、以下のコマンドで適用することができます。
kubectl apply -f ingress.yaml
※Gateway APIについて
Kubernetesでは、Ingressに代わるよオブジェクトとして、 Gateway API が登場しています。
Gateway API is a family of API kinds that provide dynamic infrastructure provisioning and advanced traffic routing.
詳細は以下をご参照ください。
https://kubernetes.io/docs/concepts/services-networking/gateway/
Helm
Kubernetesでは、アプリケーションを構成するマニフェスト(Deployment、Service、Ingressなど)を複数ファイルで管理する必要があります。これが増えてくると、設定の重複や環境差分の管理が煩雑になってきます。
Helm は、こうしたKubernetesのマニフェストをテンプレート化して管理・再利用・バージョン管理しやすくするパッケージマネージャーです。
公式では以下のように紹介されています。
Helm helps you manage Kubernetes applications — Helm Charts help you define, install, and upgrade even the most complex Kubernetes application.
Helm Chart
Helm Chartは、Kubernetesアプリケーションを定義するためのテンプレートの集合体です。
A Chart is a Helm package. It contains all of the resource definitions necessary to run an application, tool, or service inside of a Kubernetes cluster. Think of it like the Kubernetes equivalent of a Homebrew formula, an Apt dpkg, or a Yum RPM file.
チャートの構成の例
mychart/
Chart.yaml # チャートのメタ情報(名前、バージョンなど)
values.yaml # 変数のデフォルト値(テンプレートに注入される)
templates/ # Kubernetesマニフェストのテンプレートが格納される
deployment.yaml # Podの起動定義(アプリケーション本体)
service.yaml # PodにアクセスするためのService定義
ingress.yaml # 外部からのアクセスをルーティングするIngress定義
テンプレート内では {{ .Values.image.repository }} のように テンプレート構文を用いて値を埋め込みます。これにより、開発・ステージング・本番などの環境ごとに設定だけを変えて同じチャートを使い回すことができます。
minikube上で、オブジェクトを作成する
ローカルで Kubernetes を試すには、minikube を使うのが最も手軽です。ここでは Helm を使って Nginx アプリケーションを minikube 上にデプロイし、Ingress 経由でアクセスできるように構築します。
minikubeに関しては、公式ドキュメントに以下のように説明が載っています。
minikube quickly sets up a local Kubernetes cluster on macOS, Linux, and Windows. We proudly focus on helping application developers and new Kubernetes users.
https://minikube.sigs.k8s.io/docs/
minikube の起動
minikube start
完了したら、以下でクラスタが起動していることを確認できます。
kubectl get nodes
Helm チャートの作成
helm create mychart
cd mychart
生成されたチャート構成は以下のようになっています。
mychart/
Chart.yaml
values.yaml
templates/
deployment.yaml
service.yaml
ingress.yaml
...
values.yaml を編集
values.yaml を以下のようにシンプル化します。
replicaCount: 2
image:
repository: nginx
tag: stable
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: nginx
hosts:
- host: example.local
paths:
- path: /
pathType: Prefix
設定ファイルの編集
各ファイルの以下のように編集します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mychart.fullname" . }}-deployment
spec:
replicas: {{ .Values.replicaCount | default 1 }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "mychart.name" . }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "mychart.name" . }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.port }}
name: http-web-svc
apiVersion: v1
kind: Service
metadata:
name: {{ include "mychart.fullname" . }}-service
spec:
type: {{ .Values.service.type }}
selector:
app.kubernetes.io/name: {{ include "mychart.name" . }}
ports:
- name: http
protocol: TCP
port: {{ .Values.service.port }}
targetPort: http-web-svc
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "mychart.fullname" . }}-ingress
spec:
ingressClassName: {{ .Values.ingress.className }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "mychart.fullname" $ }}-service
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}
Ingress Controller を有効化
minikube addons enable ingress
以下で反映が完了したか確認することができます。
kubectl get pods -n ingress-nginx
アプリケーションのインストール
helm install myapp .
インストールされたリソースを確認:
kubectl get all
kubectl get ingress
hosts ファイルの設定
以下のように minikube ip を使って example.local をローカルで解決できるようにします
minikube ip
/etc/hosts に以下を追記(macOS / Linux):
192.168.49.2 example.local
動作確認
以下のコマンドを実施して、
minikube tunnel
ブラウザで http://example.local にアクセス。Nginx の初期画面が表示されれば成功です。
まとめ
本記事では、Kubenertesの主要なオブジェクトと、Helmの使い方の概要と、実践の説明をしました。本記事が、読者が Kubenertesに触れる際の、理解の一助になると幸いです。
Discussion