|
| 1 | +# Zone Printer |
| 2 | + |
| 3 | +Zone printer is an application that displays the |
| 4 | +[Google Cloud Platform (GCP) zone](https://cloud.google.com/compute/docs/regions-zones/) |
| 5 | +where the application is running. |
| 6 | + |
| 7 | +# How does it work? |
| 8 | + |
| 9 | +> **Note:** This section explains how the application is setup. Feel free to skip to the next section if you don't care about these |
| 10 | +details. |
| 11 | + |
| 12 | +Zone printer is intended to be run in a Kubernetes cluster and is |
| 13 | +composed of: a ConfigMap (`app/zonefetch.yaml`), a Deployment |
| 14 | +(`app/nginx-dep.yaml`) and a Service (`app/nginx-svc.yaml`). |
| 15 | + |
| 16 | +The ConfigMap consists of a script that fetches GCP zone |
| 17 | +information from the |
| 18 | +[GCE metadata server](https://cloud.google.com/compute/docs/storing-retrieving-metadata). The Deployment consists of a pod |
| 19 | +spec with two containers. One container mounts the aforementioned |
| 20 | +ConfigMap, executes the script in the ConfigMap and writes the |
| 21 | +output to `/usr/share/nginx/html/index.html`. The other container |
| 22 | +runs a standard nginx server that reads from `/usr/share/nginx/html/`. |
| 23 | + |
| 24 | +The pod, therefore, exposes the fetched zone information at |
| 25 | +`/` or `/index.html` HTTP paths. |
| 26 | + |
| 27 | +The Service exposes the Deployment pods on port `30061` on all the |
| 28 | +nodes in its Kubernetes cluster. |
| 29 | + |
| 30 | +The example also includes an Ingress manifest (`ingress/nginx.yaml`) |
| 31 | +that will be used by `kubemci`. |
| 32 | + |
| 33 | +# Tutorial |
| 34 | + |
| 35 | +## 0. Prerequisite |
| 36 | + |
| 37 | +### 0.1 GCP Project |
| 38 | + |
| 39 | +Ensure you that you have a GCP Project. If you don't have one already, |
| 40 | +you can create a project by following the instructions at |
| 41 | +[Creating and Managing Projects](https://cloud.google.com/resource-manager/docs/creating-managing-projects). |
| 42 | + |
| 43 | +After your project is created, run the following command in your |
| 44 | +terminal: |
| 45 | + |
| 46 | +```shell |
| 47 | +PROJECT=<your-project-name> |
| 48 | +``` |
| 49 | + |
| 50 | +### 0.2 `gcloud` installed and initialized |
| 51 | + |
| 52 | +You can install `gcloud` by following the instructions at |
| 53 | +[Installing Cloud SDK](https://cloud.google.com/sdk/downloads) and |
| 54 | +initialize it by running the following commands: |
| 55 | + |
| 56 | +```shell |
| 57 | +gcloud init # Set $PROJECT as the default project |
| 58 | +gcloud auth login |
| 59 | +gcloud auth application-default login |
| 60 | +``` |
| 61 | + |
| 62 | +### 0.3 kubectl |
| 63 | + |
| 64 | +You can install `kubectl` by running: |
| 65 | + |
| 66 | +```shell |
| 67 | +gcloud components install kubectl |
| 68 | +``` |
| 69 | + |
| 70 | +### 0.4 Kubernetes clusters on GCP |
| 71 | + |
| 72 | +#### Existing clusters |
| 73 | + |
| 74 | +> **Note:**: If you don't already have Kubernetes cluster on GCP, |
| 75 | +skip to the next subsection on [creating new clusters](#creating-new-clusters). |
| 76 | + |
| 77 | +`kubemci` requires Kubernetes clusters that are v1.8.1 or newer. Please |
| 78 | +ensure that all the clusters you are using in this tutorial satisfy the |
| 79 | +minimum version requirement. You can check your cluster version using |
| 80 | +the `kubectl version` command. |
| 81 | + |
| 82 | +If you already have clusters with their credentials in your local |
| 83 | +kubeconfig (`$HOME/.kube/config` by default) file, you need to ensure |
| 84 | +that you either only have clusters you are going to use for this |
| 85 | +tutorial in your default kubeconfig file or create a new kubeconfig |
| 86 | +file that just contains credentials for those clusters. Assuming that |
| 87 | +the clusters you are going to use for this tutorial are called |
| 88 | +`us-east`, `eu-west` and `asia-east`. |
| 89 | + |
| 90 | +List the contexts available (note the names of the ones you wish to |
| 91 | +use with kubemci) |
| 92 | + |
| 93 | +```shell |
| 94 | +$ kubectl config get-contexts -o name |
| 95 | +us-east |
| 96 | +eu-west |
| 97 | +asia-east |
| 98 | +i-dont-care |
| 99 | +doesnt-exist |
| 100 | +``` |
| 101 | + |
| 102 | +Now iterate over the contexts you identified, making it the context |
| 103 | +in-use and then extracting that context to its own file. |
| 104 | + |
| 105 | +```shell |
| 106 | +# First, do this for the us-east one. |
| 107 | +kubectl config use-context us-east |
| 108 | +kubectl config view --minify --flatten > mciuseast |
| 109 | + |
| 110 | +# Second, do this for the eu-west one. |
| 111 | +kubectl config use-context eu-west |
| 112 | +kubectl config view --minify --flatten > mcieuwest |
| 113 | + |
| 114 | +# Finally, do this for the asia-east one. |
| 115 | +kubectl config use-context asia-east |
| 116 | +kubectl config view --minify --flatten > mciasiaeast |
| 117 | +``` |
| 118 | + |
| 119 | +Combine (flatten) all of these extracted contexts to create a |
| 120 | +single kubeconfig file with just the contexts we care about |
| 121 | + |
| 122 | +```shell |
| 123 | +# Use KUBECONFIG to specify the context filenames we created in |
| 124 | +# the previous step |
| 125 | +KUBECONFIG=mciuseast:mcieuwest:mciasiaeast kubectl config view \ |
| 126 | + --flatten > zpkubeconfig |
| 127 | +``` |
| 128 | + |
| 129 | +#### Creating new clusters |
| 130 | + |
| 131 | +You need at least two Kubernetes clusters in two different GCP zones |
| 132 | +to verify that `kubemci` works. Clusters must be v1.8.1 or newer. |
| 133 | +Let's create three GKE clusters and get their credentials for the |
| 134 | +purposes of this tutorial: |
| 135 | + |
| 136 | +```shell |
| 137 | +# Create a cluster in us-east and get its credentials |
| 138 | +gcloud container clusters create \ |
| 139 | + --cluster-version=1.8.1-gke.0 \ |
| 140 | + --zone=us-east4-a \ |
| 141 | + cluster-us-east |
| 142 | + |
| 143 | +KUBECONFIG=./zpkubeconfig gcloud container clusters get-credentials \ |
| 144 | + --zone=us-east4-a \ |
| 145 | + cluster-us-east |
| 146 | + |
| 147 | + |
| 148 | +# Create a cluster in eu-west and get its credentials |
| 149 | +gcloud container clusters create \ |
| 150 | + --cluster-version=1.8.1-gke.0 \ |
| 151 | + --zone=europe-west1-c \ |
| 152 | + cluster-eu-west |
| 153 | + |
| 154 | +KUBECONFIG=./zpkubeconfig gcloud container clusters get-credentials \ |
| 155 | + --zone=europe-west1-c \ |
| 156 | + cluster-eu-west |
| 157 | + |
| 158 | + |
| 159 | +# Create a cluster in asia-east and get its credentials |
| 160 | +gcloud container clusters create \ |
| 161 | + --cluster-version=1.8.1-gke.0 \ |
| 162 | + --zone=asia-east1-b \ |
| 163 | + cluster-asia-east |
| 164 | + |
| 165 | +KUBECONFIG=./zpkubeconfig gcloud container clusters get-credentials \ |
| 166 | + --zone=asia-east1-b \ |
| 167 | + cluster-asia-east |
| 168 | +``` |
| 169 | + |
| 170 | +## 1. Deploy the application |
| 171 | + |
| 172 | +Deploy the application along with its NodePort service in each of the |
| 173 | +three clusters. You can get the cluster contexts from `kubectl config get-contexts` and iterate through all the clusters to deploy the |
| 174 | +application manifests. This could be accomplished by running the |
| 175 | +following loop: |
| 176 | + |
| 177 | +```shell |
| 178 | +for ctx in $(kubectl config get-contexts --kubeconfig=./zpkubeconfig -o name); do |
| 179 | + kubectl --context="${ctx}" create -f app/ |
| 180 | +done |
| 181 | +``` |
| 182 | + |
| 183 | +## 2. Reserve a static IP on GCP. |
| 184 | + |
| 185 | +We need to reserve a static IP on GCP for kubemci. Run the following |
| 186 | +command to reserve the IP. |
| 187 | + |
| 188 | +```shell |
| 189 | +ZP_KUBEMCI_IP="zp-kubemci-ip" gcloud compute addresses create \ |
| 190 | + --global "${ZP_KUBEMCI_IP}" |
| 191 | +``` |
| 192 | + |
| 193 | +## 3. Modify the Ingress manifest. |
| 194 | + |
| 195 | +Replace the value of `kubernetes.io/ingress.global-static-ip-name` |
| 196 | +annotation in `ingress/nginx.yaml` with the value of $ZP_KUBEMCI_IP. |
| 197 | + |
| 198 | +```shell |
| 199 | +sed -e "s/\$ZP_KUBEMCI_IP/${ZP_KUBEMCI_IP}/" ingress/nginx.yaml |
| 200 | +``` |
| 201 | + |
| 202 | +## 4. Deploy the Multi-Cluster Ingress (with kubemci) |
| 203 | + |
| 204 | +Run kubemci to create the multi-cluster ingress. |
| 205 | + |
| 206 | +```shell |
| 207 | +kubemci create zone-printer \ |
| 208 | + --ingress=ingress/nginx.yaml \ |
| 209 | + --gcp-project=$PROJECT \ |
| 210 | + --kubeconfig=./zpkubeconfig |
| 211 | +``` |
| 212 | + |
| 213 | +Voila! You should have a multi-cluster ingress once the command |
| 214 | +successfully exits! |
| 215 | + |
| 216 | + |
| 217 | +## 5. Get the status of Multi-Cluster Ingress |
| 218 | + |
| 219 | +You can get the status of the multi-cluster ingress you just created |
| 220 | +by using `kubemci get-status` command. |
| 221 | + |
| 222 | +```shell |
| 223 | +kubemci get-status zone-printer --gcp-project=$PROJECT |
| 224 | +``` |
| 225 | + |
| 226 | +## 6. Clean up |
| 227 | + |
| 228 | +Delete the multi-cluster ingress by using the `kubemci delete` command. |
| 229 | + |
| 230 | +```shell |
| 231 | +kubemci delete zone-printer \ |
| 232 | + --ingress=ingress/nginx.yaml \ |
| 233 | + --gcp-project=$PROJECT \ |
| 234 | + --kubeconfig=./zpkubeconfig |
| 235 | +``` |
| 236 | + |
| 237 | +Delete the GKE clusters if you created them earlier in this tutorial |
| 238 | +and you don't need them any more. |
| 239 | + |
| 240 | +```shell |
| 241 | +gcloud container clusters delete \ |
| 242 | + --zone=us-east4-a \ |
| 243 | + cluster-us-east |
| 244 | + |
| 245 | +gcloud container clusters delete \ |
| 246 | + --zone=europe-west1-c \ |
| 247 | + cluster-eu-west |
| 248 | + |
| 249 | +gcloud container clusters delete \ |
| 250 | + --zone=asia-east1-b \ |
| 251 | + cluster-asia-east |
| 252 | +``` |
0 commit comments