目次
(1)概要
(2)準備・前提条件
(3)構築手順
・(3-1)フォルダ構成
・(3-2)DockerDesktop設定
・(3-3)Dockerローカル環境設定
・(3-4)今回使用するKubernetes要素4つ
・(3-5)DBポッド起動
・(3-6)APIポッド起動
・(3-7)FRONTポッド起動
・(3-8)ブラウザ動作確認
(1)概要
本記事では、DockerDesktopを使用し、以下の技術構成の「Kubernetesローカル環境」をしていきます。
- Go
- MySQL
- TypeScript
- React
ローカル環境でもKubernetesを使用し、「本番環境」や「検証環境」でもKubernetesを使用している場合に、環境間の差異を無くすことができます。環境間の差異により、ローカルではうまくいっていても本番環境でポッドが起動しない等のエラーを未然に防ぎましょう!
Kubernetes初学者にとっても無料でKubernetesをいじれるのでおすすめです!
(2)準備・前提条件
【準備するもの】
- VSCode等のエディタ
- DockerDesktop
- asdf等のバージョン管理パッケージ
【前提条件】
- 既にDockerのローカル開発環境があることを前提といたします。
- バックエンド、フロントエンドは無理に合わせる必要はありません。
(3)構築手順
【3-1 フォルダ構成】
以下のようなフォルダ構成で、「api」「front」「db」それぞれのpodを立てる構成で構築します。
sample_app/
- api/
- Dockerfile
- local-k8s.yaml
- その他アプリファイル..
- front/
- Dockerfile
- local-k8s.yaml
- その他アプリファイル..
- test/
- db/
- Dockerfile
- local-k8s.yaml
- docker-compose.yml
【3-2 DockerDesktop設定】
DockerDesktopのKubernetesの設定をします。
-
DockerDesktopを起動し、右上の設定ボタンで設定画面に遷移します。
-
設定画面に遷移したら、サイドメニューの「Kubernetes」を選択し、「Enable Kubernetes」にチェックを入れてください。すると右下の「Apply & restart」ボタンが活性化するのでクリックします。
※ 再起動するまで少し時間がかかります。
-
右下に黄緑色のKubernetesのマークが表示されていれば設定完了です。
【3-3 Dockerローカル環境設定】
Docker環境設定はほぼ関係ありませんが、一部設定するとKubernetesのローカル環境構築に役立つので、設定します。
-
docker-compose.ymlの各サービスに「コンテナ名」「イメージ名」を指定します。Kubernetes設定でDockerの「コンテナ名」と「イメージ名」を指定するためです。
version: '3.8' services: front: image: sample-app-front:latest container_name: sample-app-front その他設定.... api: image: sample-app-api:latest container_name: sample-app-api その他設定.... db: image: sample-app-db:latest container_name: sample-app-db その他設定....
【3-4 今回使用するKubernetes要素4つ】
「ポッド起動」のために必要なKubernetesの要素4つの解説をします。Kubernetesの基礎を理解している方は、構築とは関係ないので読み飛ばしてください!
【3-4-1 Secret】
【概要】
- 機密データを保存し、ポッドに渡す
【本記事での使用用途】
- パスワード等を環境変数として、ポッドに渡すことができるので、DBの接続情報を渡します
【メリット】
- 機密データを安全にポッドに渡すことができる
【3-4-2 Persistent VolumeClaim(PVC)】
【概要】
- データストレージ(PV)へ要求を行う
【本記事での使用用途】
- データストレージの作成
【メリット】
- サイズ、アクセスモードを指定してストレージを作成できる
- データベースのデータをポッドが終了しても永続化できる
- DB以外のポッドでも使用できる
【用語】
※ Persistent Volume (PV)は、Kubernetesクラスター内のストレージのこと、Persistent VolumeClaim(PVC)はPVへの要求
【 3-4-3 Deployment】
【概要】
-
ポッドの管理方法の指定
※ Kubernetesのメインの設定はほぼここで設定します。
【本記事での使用用途】
- 指定したポッドの設定をKubernetesクラスター内にデプロイする
- 維持するポッド(レプリカ)の数の指定
- ポッド作成に使うDockerイメージ、コンテナの指定、設定
【メリット】
-
ポッドが停止する等の異常が起こった際も、指定したポッド数を維持するため自動で新しいポッドの作成を行ってくれる
-
アクセスを複数のポッドに分散できる
※ DockerデスクトップのKubernetesではこの分散機能は提供していません。 EKS等の本番環境用のKubernetesではこの恩恵を受けることができます。
-
deploymentの設定をあとから変えることで、ポッドの増減を容易に操作できる
【用語】
※ レプリカは、指定したポッドの設定を元にコピーされたポッドのこと。deploymentによって作成されるレプリカ数の指示書のようなものを「ReplicaSet」 という
【3-4-5 Service】
【概要】
- ポッド間、外部からのアクセスを設定します
【本記事での使用用途】
- 「NodePort」を設定して、外部からアクセスできる設定をします。
【メリット】
- ポッド毎に柔軟なアクセス制限が可能になる
【3-5 DBポッド起動】
dbポッドを作成します。Kubernetesでは、yamlファイルに設定を記述し、Kubernetesにデプロイすることで作成されます。
yamlファイルはフォルダ構成の「test/db/local-k8s.yaml」に記載していきます。
- test/
- db/
- Dockerfile
- local-k8s.yaml
- docker-compose.yml
DBのポッド作成に使用する要素は以下の4つです。
- Secret
- Persistent VolumeClaim(PVC)
- Deployment
- Service
最終的な完成コードは以下です。
# 認証情報の設定
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
MYSQL_ROOT_PASSWORD: 「Base64でエンコードしたルートパスワード」
MYSQL_DATABASE: 「Base64でエンコードしたデータベース名」
MYSQL_USER: 「Base64でエンコードしたユーザー名」
MYSQL_PASSWORD: 「Base64でエンコードしたユーザーパスワード」
---
# ストレージの設定
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
# deploymentの設定
apiVersion: apps/v1
kind: Deployment
metadata:
name: db
spec:
replicas: 1
selector:
matchLabels:
app: db
template:
metadata:
labels:
app: db
spec:
containers:
- name: sample-app-db
image: sample-app-db:latest
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: MYSQL_ROOT_PASSWORD
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: db-secret
key: MYSQL_DATABASE
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: db-secret
key: MYSQL_USER
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: MYSQL_PASSWORD
ports:
- containerPort: 3306
volumeMounts:
- name: db-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: db-persistent-storage
persistentVolumeClaim:
claimName: db-pvc
---
# serviceの設定
apiVersion: v1
kind: Service
metadata:
name: db
spec:
selector:
app: db
ports:
- protocol: TCP
port: 3306
targetPort: 3306
nodePort: 31306
type: NodePort
【3-5-1 Secret】
- 以下がSecret完成コードです。コメントの解説を読んでみてください。
local-k8s.yaml
## KubernetesAPIのバージョンの指定
apiVersion: v1
## 作成するリソースをSecretにする
kind: Secret
## Secretの名前を指定
metadata:
name: db-secret
## Secretのタイプを「Opaque」に指定します
## Opaqueは任意のキーと値のペアで機密情報を格納できる
type: Opaque
## DB接続に必要な情報を設定します
## 接続情報は何のルールでもいいので、Base64にエンコードした値を記述するようにしましょう
data:
MYSQL_ROOT_PASSWORD: 「Base64でエンコードしたルートパスワード」
MYSQL_DATABASE: 「Base64でエンコードしたデータベース名」
MYSQL_USER: 「Base64でエンコードしたユーザー名」
MYSQL_PASSWORD: 「Base64でエンコードしたユーザーパスワード」
【3-5-2 Persistent VolumeClaim(PVC)】
- 以下が完成コードです。コメントの解説を読んでみてください。
local-k8s.yaml
.... 前の項目のコード
## 「---」を記述することは1つのyamlファイルで複数リソースを記述できます。
---
apiVersion: v1
## 作成するリソースをPersistentVolumeClaimにする
kind: PersistentVolumeClaim
## PersistentVolumeClaimの名前を指定
metadata:
name: db-pvc
## ストレージボリュームへアクセス設定
## 一度に一つのノードからのみアクセスできるよう設定
spec:
accessModes:
- ReadWriteOnce
## PVの最小ストレージ容量を1ギガバイトに指定
resources:
requests:
storage: 1Gi
【3-5-3 Deployment】
- 以下が完成コードです。コメントの解説を読んでみてください。
local-k8s.yaml
.... 前の項目のコード
---
apiVersion: apps/v1
## 作成するリソースをDeploymentにする
kind: Deployment
## Deploymentの名前を指定
metadata:
name: db
spec:
## 実行するポッドのレプリカ数を1つに設定
replicas: 1
## ポッドのラベル名を指定
selector:
matchLabels:
app: db
## ポッド作成のためのテンプレートを定義
## metadata.labelsに「app: db」を設定し、selectorと一致させる
template:
metadata:
labels:
app: db
spec:
containers:
## コンテナ名を指定
- name: sample-app-db
## コンテナに使用するイメージを指定
image: sample-app-db:latest
## ローカルのイメージを優先的に取得し、ない場合にイメージをプルする設定
imagePullPolicy: IfNotPresent
## Secretsで設定した値を環境変数として設定
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: MYSQL_ROOT_PASSWORD
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: db-secret
key: MYSQL_DATABASE
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: db-secret
key: MYSQL_USER
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: MYSQL_PASSWORD
## ポートを3306で指定
ports:
- containerPort: 3306
## コンテナ内でマウントされるボリュームを指定
volumeMounts:
- name: db-persistent-storage
mountPath: /var/lib/mysql
## Pod内で使用されるボリュームを指定
## 作成したPVCをclaimNameに指定する
volumes:
- name: db-persistent-storage
persistentVolumeClaim:
claimName: db-pvc
【3-5-4 Service】
- 以下が完成コードです。コメントの解説を読んでみてください。
local-k8s.yaml
apiVersion: v1
## 作成するリソースをServiceにする
kind: Service
## Serviceの名前をdbに指定
metadata:
name: db
## Serviceがリクエストを転送する対象とするポッド名を指定
spec:
selector:
app: db
ports:
- protocol: TCP
## クラスタ内部からServiceにアクセスするためのポート
port: 3306
## Serviceがリクエストを転送するポッドのポート番号
targetPort: 3306
## クラスター外部からServiceにアクセスするためのノードのポートを指定
nodePort: 31306
type: NodePort
【3-5-5 ポッド起動】
- ポッド起動に必要な「kubectlコマンド」がインストール済みか以下のコマンドで確認します。
コマンドの説明が出力されたらインストール済みです。
$ kubectl
-
インストールがされていない場合は、brewや、asdfでkubectlをインストールしましょう。
以下はasdfの例です。
$ asdf plugin add kubectl ## インストールできるバージョンを出力 $ asdf list all kubectl ## kubectlをインストール $ asdf install kubectl 1.28.3 ## インストールしたバージョンを一覧表示 $ asdf list kubectl ## グローバルでの使用するkubectlバージョンを宣言 $ asdf global kubectl 1.28.3 ## ローカルでの使用するkubectlバージョンを宣言 $ asdf local kubectl 1.28.3 $ kubectl
-
yamlファイルのあるフォルダまで移動する
$ cd test/db
-
yamlファイルの内容をデプロイします。
$ kubectl apply -f local-k8s.yaml
【3-5-6 5つの要素の作成確認】
-
secret確認
$ kubectl get secrets
以下のような内容が出力されたらOKです
-
pvc確認
$ kubectl get pvc
以下のような内容が出力されたらOKです
-
deployment確認
$ kubectl get deploy
以下のような内容が出力されたらOKです
-
pod確認
$ kubectl get po
以下のような内容が出力されたらOKです
-
service確認
$ kubectl get service
以下のような内容が出力されたらOKです
【3-6 APIポッドの起動】
次はAPIポッドを作成します。
yamlファイルはapiフォルダ配下の「local-k8s.yaml」に記載していきます。
sample_app/
- api/
- Dockerfile
- local-k8s.yaml
- その他アプリファイル..
APIポッド作成に使用する要素は以下2つです。
- Deployment
- Service
最終的な完成コードは以下です。
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
ports:
- nodePort: 31000
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: api
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- image: sample-app-api:latest
imagePullPolicy: IfNotPresent
name: sample-app-api
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /api
name: api-volume
volumes:
- hostPath:
path: /Users/自身のPCのユーザー名/sample-app/api
name: api-volume
【3-6-1 Service】
- 以下が完成コードです。コメントの解説を読んでみてください。
local-k8s.yaml
apiVersion: v1
## 作成するリソースをServiceにする
kind: Service
## Serviceの名前をapi-serviceに指定
metadata:
name: api-service
spec:
ports:
## クラスター外部からServiceにアクセスするためのノードのポートを指定
- nodePort: 31000
## クラスタ内部からServiceにアクセスするためのポート
port: 8080
protocol: TCP
## Serviceがリクエストを転送するポッドのポート番号
targetPort: 8080
## Serviceがリクエストを転送する対象とするポッド名を指定
selector:
app: api
type: NodePort
【3-6-2 Deployment】
- 以下が完成コードです。コメントの解説を読んでみてください。
local-k8s.yaml
.... 前の項目のコード
---
apiVersion: apps/v1
## 作成するリソースをDeploymentにする
kind: Deployment
## Deploymentの名前を指定
metadata:
name: api
spec:
## 実行するポッドのレプリカ数を1つに設定
replicas: 1
## ポッドのラベル名を指定
selector:
matchLabels:
app: api
## ポッド作成のためのテンプレートを定義
## metadata.labelsに「app: api」を設定し、selectorと一致させる
template:
metadata:
labels:
app: api
spec:
containers:
## コンテナに使用するイメージを指定
- image: sample-app-api:latest
## ローカルのイメージを優先的に取得し、ない場合にイメージをプルする設定
imagePullPolicy: IfNotPresent
## コンテナ名を指定
name: sample-app-api
ports:
- containerPort: 8080
## 下で設定するボリュームをマウント対象として指定
volumeMounts:
- mountPath: /api
name: api-volume
## ボリュームの設定
volumes:
- hostPath:
path: /Users/自身のPCのユーザー名/sample-app/api
name: api-volume
【3-6-3 ポッド起動】
-
api用のyamlファイルのあるフォルダまで移動する
$ cd api
-
yamlファイルの内容をデプロイします。
$ kubectl apply -f local-k8s.yaml
【3-6-4 3つの要素の作成確認】
-
deployment確認
$ kubectl get deploy
以下のような内容が出力されたらOKです
-
pod確認
$ kubectl get po
-
service確認
$ kubectl get service
以下のような内容が出力されたらOKです
【3-7 FRONTポッドの起動】
次はFRONTポッドを作成します。
yamlファイルはfrontフォルダ配下の「local-k8s.yaml」に記載していきます。
sample_app/
- front/
- Dockerfile
- local-k8s.yaml
- その他アプリファイル..
FRONTポッド作成に使用する要素は以下4つです。
- Deployment
- Service
最終的な完成コードは以下です。
apiVersion: v1
kind: Service
metadata:
name: front-service
spec:
ports:
- nodePort: 31001
port: 3000
protocol: TCP
targetPort: 3000
selector:
app: front
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: front
spec:
replicas: 1
selector:
matchLabels:
app: front
template:
metadata:
labels:
app: front
spec:
containers:
- image: sample-app-front:latest
imagePullPolicy: IfNotPresent
name: sample-app-front
ports:
- containerPort: 3000
volumeMounts:
- mountPath: /front
name: front-volume
volumes:
- hostPath:
path: /Users/自身のPCのユーザー名/sample-app/front
name: front-volume
【3-7-1 Service】
- 以下が完成コードです。コメントの解説を読んでみてください。
local-k8s.yaml
apiVersion: v1
## 作成するリソースをServiceにする
kind: Service
## Serviceの名前をfront-serviceに指定
metadata:
name: front-service
spec:
ports:
## クラスター外部からServiceにアクセスするためのノードのポートを指定
- nodePort: 31001
## クラスタ内部からServiceにアクセスするためのポート
port: 3000
protocol: TCP
## Serviceがリクエストを転送するポッドのポート番号
targetPort: 3000
## Serviceがリクエストを転送する対象とするポッド名を指定
selector:
app: front
type: NodePort
【3-7-2 Deployment】
- 以下が完成コードです。コメントの解説を読んでみてください。
local-k8s.yaml
.... 前の項目のコード
---
apiVersion: apps/v1
## 作成するリソースをDeploymentにする
kind: Deployment
## Deploymentの名前を指定
metadata:
name: front
spec:
## 実行するポッドのレプリカ数を1つに設定
replicas: 1
## ポッドのラベル名を指定
selector:
matchLabels:
app: front
## ポッド作成のためのテンプレートを定義
## metadata.labelsに「app: front」を設定し、selectorと一致させる
template:
metadata:
labels:
app: front
spec:
containers:
## コンテナに使用するイメージを指定
- image: sample-app-front:latest
## ローカルのイメージを優先的に取得し、ない場合にイメージをプルする設定
imagePullPolicy: IfNotPresent
## コンテナ名を指定
name: sample-app-front
ports:
- containerPort: 3000
## 下で設定するボリュームをマウント対象として指定
volumeMounts:
- mountPath: /front
name: front-volume
## ボリュームの設定
volumes:
- hostPath:
path: /Users/自身のPCのユーザー名/sample-app/front
name: front-volume
【3-7-3 ポッドの起動】
-
front用のyamlファイルのあるフォルダまで移動する
$ cd front
-
yamlファイルの内容をデプロイします。
$ kubectl apply -f local-k8s.yaml
【3-7-4 3つの要素の作成確認】
-
deployment確認
$ kubectl get deploy
以下のような内容が出力されたらOKです
-
pod確認
$ kubectl get po
以下のような内容が出力されたらOKです
-
service確認
$ kubectl get service
以下のような内容が出力されたらOKです
【3-8 ブラウザでの動作確認】
-
ブラウザでAPIのポートにアクセスしましょう。
-
続いてブラウザでfrontのポートにアクセスします。
解説は以上になります、お疲れ様でした!
「kustomize」というKubernetesの設定を環境別に変更できるツールもあるのでぜひ試してみてください!