Skip to content

Commit 043ef88

Browse files
dak1n1jrhouston
andauthored
Add an example for GKE + NFS + PVC (#840)
This example config shows how to use GKE with Google Filestore (NFS) to create Persistent Volumes in Kubernetes. Co-authored-by: John Houston <[email protected]>
1 parent dc0d813 commit 043ef88

File tree

4 files changed

+313
-1
lines changed

4 files changed

+313
-1
lines changed

_examples/google-gke-cluster/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Google GKE (Google Container Enginer) cluster
1+
# Google GKE (Google Container Engine) cluster
22

33
In case you don't have a K8S cluster yet the easiest way
44
to create one from scratch is to use GKE (Google Container Service).
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# GKE (Google Container Engine) and Google Filestore (NFS)
2+
3+
This example demonstrates building a Google GKE cluster and Google Filestore (NFS) to create persistent volumes for use in applications in Kubernetes. There is an example application Deployment included to demonstrate mounting the NFS volume using a Persistent Volume Claim.
4+
5+
You will need the following environment variables to be set:
6+
7+
- `GOOGLE_CREDENTIALS`
8+
- `GOOGLE_PROJECT`
9+
- `GOOGLE_REGION`
10+
11+
For example:
12+
```
13+
[myuser@linux ~]$ env | grep GOOGLE
14+
GOOGLE_REGION=us-west1
15+
GOOGLE_CREDENTIALS=/home/myuser/.config/gcloud/legacy_credentials/mygoogleuser/adc.json
16+
GOOGLE_PROJECT=my-gcp-project
17+
```
18+
19+
See [Google Cloud Provider docs](https://www.terraform.io/docs/providers/google/index.html#configuration-reference) for more details about these variables.
20+
21+
Install the example using the GKE default version of Kubernetes:
22+
```
23+
terraform init
24+
terraform apply
25+
```
26+
27+
Or optionally specify a version to use:
28+
```
29+
terraform apply -var=kubernetes_version=1.15
30+
```
31+
32+
## Versions
33+
34+
Other available versions of Kubernetes can be found by running the [gcloud](https://cloud.google.com/sdk/docs#install_the_latest_cloud_tools_version_cloudsdk_current_version) tool. However, be aware that your chosen version must be present in the `validMasterVersions`, or else the GKE `defaultClusterVersion` will be used.
35+
36+
```
37+
gcloud container get-server-config --region $GOOGLE_REGION
38+
```
39+
40+
## Exporting K8S variables
41+
To access the cluster you need to export the `KUBECONFIG` variable pointing to the `kubeconfig` file for the current cluster.
42+
```
43+
export KUBECONFIG="$(terraform output kubeconfig_path)"
44+
export GOOGLE_ZONE=$(terraform output google_zone)
45+
```
46+
47+
Now you can access the cluster via `kubectl`.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
apiVersion: v1
2+
kind: Config
3+
preferences:
4+
colors: true
5+
current-context: tf-k8s-gcp-test
6+
contexts:
7+
- context:
8+
cluster: ${cluster_name}
9+
namespace: default
10+
user: ${user_name}
11+
name: tf-k8s-gcp-test
12+
clusters:
13+
- cluster:
14+
server: https://${endpoint}
15+
certificate-authority-data: ${cluster_ca}
16+
name: ${cluster_name}
17+
users:
18+
- name: ${user_name}
19+
user:
20+
password: ${user_password}
21+
username: ${user_name}
22+
client-certificate-data: ${client_cert}
23+
client-key-data: ${client_cert_key}
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
provider "google" {
2+
// Provider settings to be provided via ENV variables
3+
}
4+
5+
data "google_compute_zones" "available" {
6+
}
7+
8+
resource "random_id" "cluster_name" {
9+
byte_length = 10
10+
}
11+
12+
resource "random_id" "username" {
13+
byte_length = 14
14+
}
15+
16+
resource "random_id" "password" {
17+
byte_length = 16
18+
}
19+
20+
variable "kubernetes_version" {
21+
default = ""
22+
}
23+
24+
variable "workers_count" {
25+
default = "3"
26+
}
27+
28+
data "google_container_engine_versions" "supported" {
29+
location = data.google_compute_zones.available.names[0]
30+
version_prefix = var.kubernetes_version
31+
}
32+
33+
# If the result is empty '[]', the GKE default_cluster_version will be used.
34+
output "available_master_versions_matching_user_input" {
35+
value = data.google_container_engine_versions.supported.valid_master_versions
36+
}
37+
38+
# Shared network for GKE cluster and Filestore to use.
39+
resource "google_compute_network" "vpc" {
40+
name = "shared"
41+
auto_create_subnetworks = true
42+
}
43+
44+
resource "google_container_cluster" "primary" {
45+
name = "tf-acc-test-${random_id.cluster_name.hex}"
46+
location = data.google_compute_zones.available.names[0]
47+
network = google_compute_network.vpc.name
48+
initial_node_count = var.workers_count
49+
min_master_version = data.google_container_engine_versions.supported.latest_master_version
50+
# node version must match master version
51+
# https://www.terraform.io/docs/providers/google/r/container_cluster.html#node_version
52+
node_version = data.google_container_engine_versions.supported.latest_master_version
53+
54+
node_locations = [
55+
data.google_compute_zones.available.names[1],
56+
]
57+
58+
master_auth {
59+
username = random_id.username.hex
60+
password = random_id.password.hex
61+
}
62+
63+
node_config {
64+
machine_type = "n1-standard-4"
65+
66+
oauth_scopes = [
67+
"https://www.googleapis.com/auth/compute",
68+
"https://www.googleapis.com/auth/devstorage.read_only",
69+
"https://www.googleapis.com/auth/logging.write",
70+
"https://www.googleapis.com/auth/monitoring",
71+
]
72+
}
73+
}
74+
75+
76+
resource "google_filestore_instance" "test" {
77+
name = "test-nfs-server"
78+
tier = "STANDARD"
79+
zone = "us-west1-a"
80+
81+
file_shares {
82+
capacity_gb = 1024
83+
name = "vol1"
84+
}
85+
86+
networks {
87+
network = google_compute_network.vpc.name
88+
modes = ["MODE_IPV4"]
89+
}
90+
}
91+
92+
data "template_file" "kubeconfig" {
93+
template = file("${path.module}/kubeconfig-template.yaml")
94+
95+
vars = {
96+
cluster_name = google_container_cluster.primary.name
97+
user_name = google_container_cluster.primary.master_auth[0].username
98+
user_password = google_container_cluster.primary.master_auth[0].password
99+
endpoint = google_container_cluster.primary.endpoint
100+
cluster_ca = google_container_cluster.primary.master_auth[0].cluster_ca_certificate
101+
client_cert = google_container_cluster.primary.master_auth[0].client_certificate
102+
client_cert_key = google_container_cluster.primary.master_auth[0].client_key
103+
}
104+
}
105+
106+
resource "local_file" "kubeconfig" {
107+
content = data.template_file.kubeconfig.rendered
108+
filename = "${path.module}/kubeconfig"
109+
}
110+
111+
provider "kubernetes" {
112+
version = "1.11.2"
113+
load_config_file = "false"
114+
115+
host = google_container_cluster.primary.endpoint
116+
117+
username = google_container_cluster.primary.master_auth[0].username
118+
password = google_container_cluster.primary.master_auth[0].password
119+
client_certificate = base64decode(google_container_cluster.primary.master_auth[0].client_certificate)
120+
client_key = base64decode(google_container_cluster.primary.master_auth[0].client_key)
121+
cluster_ca_certificate = base64decode(google_container_cluster.primary.master_auth[0].cluster_ca_certificate)
122+
}
123+
124+
resource "kubernetes_namespace" "example" {
125+
metadata {
126+
name = "test"
127+
}
128+
}
129+
130+
resource "kubernetes_storage_class" "nfs" {
131+
metadata {
132+
name = "filestore"
133+
}
134+
reclaim_policy = "Retain"
135+
storage_provisioner = "nfs"
136+
}
137+
138+
resource "kubernetes_persistent_volume" "example" {
139+
metadata {
140+
name = "nfs-volume"
141+
}
142+
spec {
143+
capacity = {
144+
storage = "1T"
145+
}
146+
storage_class_name = kubernetes_storage_class.nfs.metadata[0].name
147+
access_modes = ["ReadWriteMany"]
148+
persistent_volume_source {
149+
nfs {
150+
server = google_filestore_instance.test.networks[0].ip_addresses[0]
151+
path = "/${google_filestore_instance.test.file_shares[0].name}"
152+
}
153+
}
154+
}
155+
}
156+
157+
resource "kubernetes_persistent_volume_claim" "example" {
158+
metadata {
159+
name = "mariadb-data"
160+
namespace = "test"
161+
}
162+
spec {
163+
access_modes = ["ReadWriteMany"]
164+
storage_class_name = kubernetes_storage_class.nfs.metadata[0].name
165+
volume_name = kubernetes_persistent_volume.example.metadata[0].name
166+
resources {
167+
requests = {
168+
storage = "1T"
169+
}
170+
}
171+
}
172+
}
173+
174+
resource "kubernetes_deployment" "mariadb" {
175+
metadata {
176+
name = "mariadb-example"
177+
namespace = "test"
178+
labels = {
179+
mylabel = "MyExampleApp"
180+
}
181+
}
182+
183+
spec {
184+
replicas = 1
185+
186+
selector {
187+
match_labels = {
188+
mylabel = "MyExampleApp"
189+
}
190+
}
191+
192+
template {
193+
metadata {
194+
labels = {
195+
mylabel = "MyExampleApp"
196+
}
197+
}
198+
199+
spec {
200+
container {
201+
image = "mariadb:10.5.2"
202+
name = "example"
203+
204+
env {
205+
name = "MYSQL_RANDOM_ROOT_PASSWORD"
206+
value = true
207+
}
208+
209+
resources {
210+
limits {
211+
cpu = "0.5"
212+
memory = "512Mi"
213+
}
214+
requests {
215+
cpu = "250m"
216+
memory = "50Mi"
217+
}
218+
}
219+
220+
volume_mount {
221+
mount_path = "/var/lib/mysql"
222+
name = "mariadb-data"
223+
}
224+
}
225+
volume {
226+
name = "mariadb-data"
227+
persistent_volume_claim {
228+
claim_name = "mariadb-data"
229+
}
230+
}
231+
}
232+
}
233+
}
234+
}
235+
236+
output "node_version" {
237+
value = google_container_cluster.primary.node_version
238+
}
239+
240+
output "kubeconfig_path" {
241+
value = local_file.kubeconfig.filename
242+
}

0 commit comments

Comments
 (0)