どうも、株式会社KIYONOにてエンジニアをしております。
今回はGKE(Google Kubernetes Engine)を使用した基本的なKubernetes環境を構築する手順についてご紹介致します。今回はk8sクラスター上にnginxをデプロイし、ロードバランサーで外部公開するまでをゴールとします。
1.前提条
- GCPアカウントをセットアップ済み
- Terraformを使用できる状態
- kubectlコマンドをインストール済み
2.主な使用技術
基本
名称 | 説明 |
GKE | GCPのk8sマネージドサービス |
kubectl | kubernetesクラスターの操作(CLI) |
Terraform 1.2.4 | IaC(※バージョンによる影響にご注意下さい。) |
Terraformモジュール
GCP上へのVPC、k8sクラスターの作成に下記の公式モジュール(Terraform Registry)を使用します。モジュールを使用することで煩雑な設定を意識するとこなく様々なリソースを作成できます。
名称 | 説明 |
terraform-google-modules/network
|
k8sクラスターを配置するVPCを設定、作成 |
terraform-google-modules/kubernetes-engine
|
k8sクラスターの設定、作成 |
3.準備
プロジェクト構成
今回作成するプロジェクト構成になります(※主要なファイルのみ記載)。まずはこの状態を目指します。
.
├── main.tf ...インフラ構成を記述
├── output.tf ...クラスター名を出力
├── kubeconfig-dev...kubeconfigファイル(apply後に生成)
├── secret.json ...サービスアカウントの鍵json
├── terraform.tfvars ...環境に依存する値や機密性の高い値を変数化(※.gitignore推奨)
└── variables.tf ...変数定義
サービスアカウントの作成
GCPコンソールからterraformで使用するGCPサービスアカウントを作成します。オーナー権限を付与して鍵(json)を取得しsecret.json
としてプロジェクト配下に設置してください。(※必ずGitの管理対象から外してください。また、強力な権限になりますので扱いには注意してください。)
tfファイルの作成
実際にterraformコードを記述していきます。
main.tf
インフラ構成を記述します。VPC、GKEの二本軸です。※変数部分は後述
# provider setting
terraform {
required_version = "= 1.2.4"
required_providers {
google = {
source = "hashicorp/google"
version = "4.31.0"
}
}
}
provider "google" {
credentials = file("./secret.json")
project = var.gcp_project_id
region = var.gcp_region
zone = "${var.gcp_region}-a"
}
# network
module "vpc" {
source = "terraform-google-modules/network/google"
version = "~> 4.0"
project_id = var.gcp_project_id
network_name = "${var.network}-${var.env_name}"
subnets = [
{
subnet_name = "${var.subnetwork}-${var.env_name}"
subnet_ip = "10.10.0.0/16"
subnet_region = var.gcp_region
},
]
secondary_ranges = {
"${var.subnetwork}-${var.env_name}" = [
{
range_name = var.ip_range_pods_name
ip_cidr_range = "10.20.0.0/16"
},
{
range_name = var.ip_range_services_name
ip_cidr_range = "10.30.0.0/16"
},
]
}
}
# gke
module "gke" {
source = "terraform-google-modules/kubernetes-engine/google//modules/private-cluster"
project_id = var.gcp_project_id
name = "${var.cluster_name}-${var.env_name}"
regional = true
region = var.gcp_region
network = module.vpc.network_name
subnetwork = module.vpc.subnets_names[0]
ip_range_pods = var.ip_range_pods_name
ip_range_services = var.ip_range_services_name
node_pools = [
{
name = "node-pool"
machine_type = "n2-standard-2"
node_locations = "${var.gcp_region}-a" # 複数のゾーンを指定できる
min_count = 1
max_count = 2
disk_size_gb = 30
},
]
}
マルチゾーンクラスタによる冗長化構成にしたい場合は、
node_locations
へ複数のゾーンを記載します。
続いて、kubetcltからクラスターへのアクセス認証に使用するkubeconfigファイルを作成するコードを記述します。
# gke auth
module "gke_auth" {
source = "terraform-google-modules/kubernetes-engine/google//modules/auth"
depends_on = [module.gke]
project_id = var.gcp_project_id
location = module.gke.location
cluster_name = module.gke.name
}
# kubeconfig
resource "local_file" "kubeconfig" {
content = module.gke_auth.kubeconfig_raw
filename = "kubeconfig-${var.env_name}"
}
terraform apply
によるリソース作成完了後に"kubeconfig-${var.env_name}"
ファイル名の認証情報が記載されたファイルが生成されます。今回の場合はkubeconfig-devとなります。
terraform.tfvars
プロジェクト固有の値を設定します。ここに定義した値は後述するvariable
変数に自動的に代入されます。
gcp_project_id="your-project-id"
gcp_region="your-region1"
variables.tf
main.tfから参照する変数の一式を定義します。
# from terraform.tfvars
variable gcp_project_id {
description = "GCP project id"
}
variable gcp_region {
description = "GCP region"
}
# others
variable "cluster_name" {
description = "name of gke cluster"
default = "dev-cluster"
}
variable "env_name" {
description = "name of environment"
default = "dev"
}
variable "network" {
description = "name of VPC"
default = "dev-gek-network"
}
variable "subnetwork" {
description = "name of subnetwork"
default = "dev-gke-subnet"
}
variable "ip_range_pods_name" {
description = "name of secondary ip range used in pods"
default = "ip-range-pods"
}
variable "ip_range_services_name" {
description = "name of secondary ip range used in services"
default = "ip-range-services"
}
output.tf
terraform apply
後に作成されたクラスター名称がターミナルに出力されます。
output "cluster_name" {
description = "cluster name"
value = module.gke.name
}
インフラの構築
terraformコマンドを使用して実際にコード定義したインフラをGCP上へ構築します。以下のコマンドを実施してください。
# モジュールのセットアップ
$ terraform init
# ドライランを実施し、作成されるリソースを確認する
$ terraform plan
# 実際にリソースを作成する
$ terraform apply
リソースが作成されるまで10分程かかります。
※また、リソースの作成後プロジェクト配下にkubeconfig-devファイルが作成されますので必ずバージョン管理から外してください。
クラスターへの接続と確認
kubectlで実際に作成されたクラスターを確認してみます。
# kubectlコマンドが対象のクラスターを見にいくように下記を実施します。
$ export KUBECONFIG="${PWD}/kubeconfig-dev"
# クラスターにアクセスしnodeを確認する
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gke-dev-cluster-dev-node-pool-a9c02cfb-tpf8 Ready <none> 5m55s v1.24.3-gke.900
4.デプロイと公開
nginxのデプロイ
主にクラスター内部へのリソースの作成、アプリケーションのデプロイはymlで記述した「マニフェストファイル」を使用します。まずはデプロイ用のマニフェストファイルを作成します。
deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-nginx
spec:
selector:
matchLabels:
name: hello-nginx
template:
metadata:
labels:
name: hello-nginx
spec:
containers:
- name: app
image: nginx:alpine # nginxイメージ
ports:
- containerPort: 80
詳細な説明は省きますが、上記ファイルにて特に重要なのはkind
プロパティで、作成するk8sオブジェクトの種類を指定します。Deployment
オブジェクトは使用するイメージバージョンに変更がある際などの容易なローリングアップデートをサポートします。その他主要なプロパティは以下の通りです。
metadata
… k8sオブジェクトの一意の識別名(オブジェクト種別単位)
spec.selector
… 対象となるオブジェクト識別名
デプロイ
deployment.ymlを用意できたので実際にkubectl
を使用してクラスターへnginxのデプロイと確認を行います。
# デプロイ
$ kubectl apply -f deployment.yml
# 確認
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-nginx-5dd8f754fd-dbzgd 1/1 Running 0 4m39s
ポートフォワーディングで接続する
nginxのデプロイはできましたが、コンテナはpublicIPを持っておらずこの時点では外部公開されていません。ロードバランサー経由で公開する前にまずはポートフォワーディングを利用して8080ポートにマッピングしlocalhost:8080にアクセスしてみます。Welcomeページが表示されるはずです。
# 8080ポートへマッピング
$ kubectl port-forward hello-nginx-5dd8f754fd-dbzgd 8080:80
ロードバランサーの作成
ロードバランサー用のマニフェストを定義してnginxコンテナをネットワークに公開します。
loadbalancer.yml
apiVersion: v1
kind: Service
metadata:
name: hello-nginx
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
name: hello-nginx
Service
はネットワークに関わるオブジェクトになりspec
以下で設定部分を記述しています。
作成と確認
先ほどと同じ要領でロードバランサーを設置します。
# ロードバランサーの作成
$ kubectl apply -f loadbalancer.yml
# 確認
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-nginx LoadBalancer 10.30.195.150 34.85.90.129 80:31792/TCP 48s
EXTERNAL-IP
に表示されたpublicIPにブラウザでアクセスし、nginxのウェルカムページが表示されたら成功です。
作成したGCPリソースを削除する場合は下記コマンド実行してください。
$ terraform destroy
5.まとめ
いかがでしたでしょうか、本記事ではterraformを使用した基本的なGKE構築からwebサーバー(nginx)の公開の手順をご紹介致しました。k8sは「コンテナオーケストレーション」と銘打っている通り同一クラスター内で様々なコンテナをマイクロサービス展開、構成管理できるのが強みの一つです。今回はnginxのデプロイまででしたので、そのような強みを生かした構成とは言えないのが正直なところです。より深掘りした内容は追々、ご紹介できればと思います。
コメント