やりたいこと
terraformを使って、vpcとgkeを作成して、gkeをvpc上に乗せます。
以下の記事を参考にさせていただきましたので、詳細は下記をご確認ください!
- https://qiita.com/takasp/items/8104c175232e74217cc3
- https://qiita.com/kawakawaryuryu/items/c74a7a90a8b4e7e01c1f
- https://qiita.com/MahoTakara/items/85096f8b2632c802ab22
ついでにこちらの本も参考にさせていただきました!
- Kubernetes完全ガイド (impress top gear) 青山 真也
手順
- vpcとgkeを作成
- gke上にnginxのサンプルコンテナを配置
ソースコード
terraform
terraformでGCPを使うときの事前設定
- サービスアカウントとjsonファイルの作成
- terraformのbackend用にgcsバケットの作成
- google compute engineのAPIを有効化
- gcloudコマンドのインストール
ディレクトリ構成
→ tree
.
├── README.md
├── _provider.tf
├── _variable.tf
├── compute.tf
├── gcp_key.json
├── gke.tf
├── terraform.sh
└── tfvars
└── sample.tfvars
provider
-
credentials
にはサービスアカウントのjsonファイルのパスを指定しています -
project
やregion
はtfvarsファイルで切り替えられるようにしています -
backend
はあえて設定を省略して、コンソール上から入力できるようにしています- githubに上げるためやっているので、ハードコードでOKです!
_provider.tf
provider "google" {
credentials = "${file("${var.gcp_key_path}")}"
project = "${var.project_id}"
region = "${var.region}"
zone = "${var.zone}"
}
terraform {
backend "gcs" {}
}
tfvarsとvariables
- サンプル用に作ったので、よしなに変えていただければOKです!
-
project_name
にはGCPのプロジェク名を指定してください -
project_id
にはGCPのプロジェクトIDをapply時に入力するようにしています- githubに公開するため、tfvarsには入れていません
-
gke_cidr_block
は下記を参考に作っていただけるとよいかと思います -
min_master_version
とnode_version
はできるだけ最新にしたほうが無難です
sample.tfvars
project_name = "sample"
gcp_key_path = "./gcp_key.json"
region = "asia-northeast1"
zone = "asia-northeast1-a"
network = "default"
initial_node_count = "3"
description = "cluster"
min_master_version = "1.13.7-gke.8"
node_version = "1.13.7-gke.8"
machine_type = "g1-small"
disk_size = "10"
gke_cidr_block = "192.168.0.0/16"
_variable.tf
# all
variable "project_id" {}
variable "project_name" {}
variable "gcp_key_path" {}
# gke
variable "region" {}
variable "zone" {}
variable "network" {}
variable "initial_node_count" {}
variable "description" {}
variable "min_master_version" {}
variable "node_version" {}
variable "machine_type" {}
variable "disk_size" {}
variable "gke_cidr_block" {}
# local
locals {
ws = "${terraform.workspace}"
}
vpcとglobal ip
-
google_compute_global_address
はkubernetesのingressで使う固定IPアドレスを生成しています -
auto_create_subnetworks
をtrueにすると自動でサブネットを作ってくれます- ちなみに以前、自分でサブネットを作ってみましたがうまく動きませんでした・・・
compute.tf
resource "google_compute_global_address" "gke" {
name = "${var.project_name}-global-ip"
}
resource "google_compute_network" "gke" {
name = "${var.project_name}-gke-vpc"
routing_mode = "REGIONAL"
auto_create_subnetworks = "true"
delete_default_routes_on_create = "false"
}
gkeとnode pool
- gkeの
network
にはvpcを指定しています -
remove_default_node_pool
はtrueにして、デフォルトで作られるnode poolを削除しています- node poolは
google_container_node_pool
で追加するのでデフォルトは必要ないです
- node poolは
-
cluster_ipv4_cidr_block
とservices_ipv4_cidr_block
は/20
で分けています-
cidrsubnet(var.gke_cidr_block, 8, 1)
にして/24
で分けてもいいです!- コンテナ数やクラスタ数の上限などはサービス毎に違うので、適宜考えていただけるといいかと思います
- cidrsubnetの計算は
terraform console
を使えば簡単に確認できます!
-
-
preemptible
はfalseにしています -
oauth_scopes
もサービス毎に使う権限が違いますので、考慮いただけるといいかと思います -
autoscaling
でオートスケールするnode数を決めれます!- 今回は1〜3ノードでスケールします
gke.tf
resource "google_container_cluster" "gke" {
name = "${var.project_name}"
location = "${var.zone}"
network = "${google_compute_network.gke.self_link}"
initial_node_count = "${var.initial_node_count}"
remove_default_node_pool = true
description = "${var.description}"
min_master_version = "${var.min_master_version}"
node_version = "${var.node_version}"
ip_allocation_policy {
use_ip_aliases = true
cluster_ipv4_cidr_block = "${cidrsubnet(var.gke_cidr_block, 4, 1)}"
services_ipv4_cidr_block = "${cidrsubnet(var.gke_cidr_block, 4, 2)}"
}
}
resource "google_container_node_pool" "gke" {
name = "${var.project_name}-node-pool"
location = "${var.zone}"
cluster = "${google_container_cluster.gke.name}"
node_count = "${var.initial_node_count}"
autoscaling {
max_node_count = 3
min_node_count = 1
}
node_config {
machine_type = "${var.machine_type}"
disk_size_gb = "${var.disk_size}"
preemptible = false
oauth_scopes = [
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring",
"https://www.googleapis.com/auth/compute",
]
}
}
Kubernetes
kubectlコマンドを使って適用していきます。
詳細は省略いたしますが、以下をご確認いただけるといいかと思います。
- https://qiita.com/suzukihi724/items/241f7241d297a2d4a55c
- https://qiita.com/ntoreg/items/74aa6de2f8f29b4a3b79
deployment
- サンプルでnginxを動かしています
-
namespace
は事前にkubectl create namespace
で作成してください -
readinessProbe
でヘルスチェックしています-
/
で200のレスポンスを返さないコンテナの場合、readinessProbe
は必須ですのでお気をつけ下さい
-
deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
namespace: sample-ns
labels:
app: sample
spec:
replicas: 1
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- name: sample-container
image: nginx:latest
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
resources:
limits:
cpu: 200m
memory: 10Mi
ingress
-
kubernetes.io/ingress.global-static-ip-name
にはgoogle_compute_global_address
で作ったIPアドレス名を指定します - httpsを使う場合は
annotations -> kubernetes.io/ingress.allow-http
とspec -> tls -> secretName
が必要です- kubernetesにsecretsとして証明書の登録も必要になります
-
serviceName
とservicePort
にはservice.yml
で設定したリソース名を指定します
ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: sample-ingress
namespace: sample-ns
annotations:
kubernetes.io/ingress.global-static-ip-name: sample-global-ip
spec:
backend:
serviceName: sample-service
servicePort: service-port
service
-
ports
にname
をつけて置くとingress
のservicePort
に名前で指定できます
service.yml
apiVersion: v1
kind: Service
metadata:
name: sample-service
namespace: sample-ns
labels:
app: sample
spec:
type: NodePort
ports:
- name: service-port
port: 80
protocol: TCP
targetPort: 80
selector:
app: sample
確認
- GCPで作った固定のIPアドレスにブラウザでアクセスして確認します