はじめに
この記事は、普段Kubenetes(k8s)を触らないエンジニアがMinikubeというツールを用いて雑にk8sの環境を作ってみたという内容になります。なので、概念的な説明はPerplexityくんに任せます。
下記リポジトリで色々試しています。
必要なツール
$ docker --version
$ kubectl version
$ minikube version
Kubenetes(k8s)とは?
以下はPerplexityが要約した内容になります。詳しい内容は、公式ドキュメントを見てください。
Kubernetesは、コンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化するオープンソースのコンテナオーケストレーションプラットフォームです123。「クバネティス」「クーべネティス」などと読み、略して「K8s」や「kube」とも呼ばれます12。
主な特徴
- 自動化: 複数のホストにまたがるコンテナの運用管理を自動化し、システム開発・管理の効率を大幅に向上させます3。
- スケーラビリティ: アプリケーションの負荷に応じて自動的にスケーリングを行います35。
- 自己修復: システムの障害を検知し、自動的に修復を試みる機能を持っています3。
- 負荷分散: サービスディスカバリーと負荷分散機能を提供します3。
利点
- システムダウンタイムの減少
- 複雑なタスクの簡素化
- クラウドネイティブ開発のサポート
- マルチクラウド環境での運用が容易
Kubernetesは、現在コンテナオーケストレーションのデファクトスタンダードとなっており、多くのクラウドプロバイダーやソフトウェアベンダーがKubernetesベースのサービスを提供しています45。
Minikubeとは?
Minikubeとは、ローカル環境で小規模なk8s環境を簡単に構築するためのツールです。
MacOSの場合はhomebrewで導入することができます。
$ brew install minikube
そのほかの方は、こちらのドキュメントを参照してください。
Minikubeを起動する
Minikubeを実行するドライバーにはいくつか選択肢があります。(参照:https://minikube.sigs.k8s.io/docs/drivers/)
- Docker
- KVM2
- VirtualBox
- Parallels
- etc...
おそらくDockerが一番手軽に立てられると思うので、Dockerを先に起動しておきましょう。
Dockerを起動したら、下記コマンドでMinikubeを起動します。Dockerが立ち上がっている場合は、自動でドライバーにDockerが使用されます。
$ minikube start
$ minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
$ kubectl config current-context
minikube
Dockerコンテナを見てみると、Minikubeコンテナが立ち上がっていることを確認できます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e37e0f61bb7f gcr.io/k8s-minikube/kicbase:v0.0.46 "/usr/local/bin/entr…" 3 minutes ago Up 3 minutes 127.0.0.1:53174->22/tcp, 127.0.0.1:53175->2376/tcp, 127.0.0.1:53177->5000/tcp, 127.0.0.1:53173->8443/tcp, 127.0.0.1:53176->32443/tcp minikube
初期状態だと、ClusterIPのみが存在するはずです。
$ kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8m11s
NginxのWebサーバーをk8sで作ってみる
Nginxを用いた簡単なWebサーバーの例で、k8sを体験してみます。まず最終的な構成図は以下のようになります。
flowchart LR
User<-->|port forward|NodePort
subgraph Cluster
NodePort-->PodA
NodePort-->PodB
NodePort-->PodC
subgraph Node
NodePort
subgraph Replicaset
PodA
PodB
PodC
end
end
end
Podを作る
PodについてはPerplexityの回答をご覧ください。
Kubernetes (k8s) のPodは、1つ以上のコンテナをグループ化した、最小のデプロイ可能な単位です123。Podの主な特徴と役割は以下の通りです
- リソース共有: Pod内のコンテナは、ネットワークとストレージリソースを共有します1。これにより、コンテナ間のデータや通信の効率が向上します。
- ネットワーキング: 各Podには固有のIPアドレスが割り当てられ、Pod内のコンテナはこのIPアドレスとポートスペースを共有します23。
- スケジューリング: Podは常に同じノード上で実行され、同じスケジュールに従います2。
- 自己修復機能: 障害が発生した場合、Podは自動的に再起動され、アプリケーションの可用性が維持されます1。
- スケーラビリティ: Podを基準にアプリケーションの自動スケーリングが実現されます1。
- 負荷分散とサービスディスカバリ: Podを通じて外部トラフィックの負荷分散と内部サービスディスカバリが容易になります1。
Podは、アプリケーション固有の「論理ホスト」をモデル化しており、密接に結合された複数のアプリケーションコンテナを含むことができます2。例えば、Webサーバーとデータベースのコンテナを1つのPodにまとめることができます。Kubernetesでは、通常Podは直接作成されず、Deploymentなどのワークロードリソースを通じて作成・管理されます3。これにより、アプリケーションの管理やスケーリングが容易になります。
Nginxを用いたWebサーバーのPodを立ててみます。まず、nginx-deployment.yaml
を作成し、Podの情報を記載します。
$ touch nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
上記の構成ファイルは、nginxのDockerイメージからnginxのWebサーバーをポート番号80で起動するPodを3つ作成します。
では、構成ファイルを適用し、Podを作成してみましょう。
$ kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
下記コマンドを実行するとPodが作成されていることを確認できます。
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-647677fc66-8k4pr 0/1 ContainerCreating 0 6s
nginx-deployment-647677fc66-ljz8c 0/1 ContainerCreating 0 6s
nginx-deployment-647677fc66-tsl9q 0/1 ContainerCreating 0 6s
NodePortを作る
Podだけだとネットワークから参照できないので、NodePortを作成します。NodePortについてはPerplexityの回答をご覧ください。
NodePortは、Kubernetesクラスタ内の特定のServiceとそれに関連するPodに外部からのトラフィックを転送するサービスタイプです14
では、nginx-service.yaml
を作成し、NodePortの情報を記載します。
$ touch nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: NodePort
selector:
app: nginx
上記の構成ファイルは、先ほど作成したNginxのPodに外部からのトラフィックを転送するNodePortを作成します。
では、構成ファイルを適用し、NodePortを作成してみましょう。
$ kubectl apply -f nginx-service.yaml
service/nginx-service created
下記コマンドを実行するとNodePortが作成されていることを確認できます。
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 27m
nginx-service NodePort 10.108.205.30 <none> 80:30863/TCP 22s
localhostでアクセスできるようにする
今のままでは外部からアクセスできないので、ポートフォワードする必要があります。
$ kubectl port-forward service/nginx-service 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
http://localhost:8080/ にアクセスすると、Webサーバーにアクセスすることができます。

そのほかのk8sサンプルを紹介
https://github.com/Alesion30/mini-k8s-playground では他にもいろんなケースの構成を試しています。
- lb-sample: ロードバランサーのサービスを用いた構成
- local-image-sample: ローカルでビルドしたDockerイメージを用いた構成