From 07aae4fb4523a76edbe4326a3af140d4ffcf016e Mon Sep 17 00:00:00 2001
From: Kelsey Hightower <kelsey.hightower@gmail.com>
Date: Mon, 18 Dec 2017 06:53:32 -0800
Subject: [PATCH] update to kubernetes 1.9

---
 README.md                                     |   6 +-
 deployments/kube-dns.yaml                     | 332 +++++++++---------
 docs/01-prerequisites.md                      |   2 +-
 docs/02-client-tools.md                       |   8 +-
 docs/03-compute-resources.md                  |   8 +-
 docs/07-bootstrapping-etcd.md                 |   6 +-
 ...08-bootstrapping-kubernetes-controllers.md |  18 +-
 docs/09-bootstrapping-kubernetes-workers.md   |  16 +-
 docs/10-configuring-kubectl.md                |   6 +-
 docs/11-pod-network-routes.md                 |   4 +-
 docs/13-smoke-test.md                         |  45 ++-
 11 files changed, 232 insertions(+), 219 deletions(-)

diff --git a/README.md b/README.md
index 621c99c..fc490ec 100644
--- a/README.md
+++ b/README.md
@@ -14,10 +14,10 @@ The target audience for this tutorial is someone planning to support a productio
 
 Kubernetes The Hard Way guides you through bootstrapping a highly available Kubernetes cluster with end-to-end encryption between components and RBAC authentication.
 
-* [Kubernetes](https://github.com/kubernetes/kubernetes) 1.8.0
-* [cri-containerd Container Runtime](https://github.com/kubernetes-incubator/cri-containerd) 1.0.0-alpha.0
+* [Kubernetes](https://github.com/kubernetes/kubernetes) 1.9.0
+* [cri-containerd Container Runtime](https://github.com/kubernetes-incubator/cri-containerd) 1.0.0-beta.0
 * [CNI Container Networking](https://github.com/containernetworking/cni) 0.6.0
-* [etcd](https://github.com/coreos/etcd) 3.2.8
+* [etcd](https://github.com/coreos/etcd) 3.2.11
 
 ## Labs
 
diff --git a/deployments/kube-dns.yaml b/deployments/kube-dns.yaml
index cc1f7d1..477ba72 100644
--- a/deployments/kube-dns.yaml
+++ b/deployments/kube-dns.yaml
@@ -1,8 +1,47 @@
+# Copyright 2016 The Kubernetes Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: kube-dns
+  namespace: kube-system
+  labels:
+    k8s-app: kube-dns
+    kubernetes.io/cluster-service: "true"
+    addonmanager.kubernetes.io/mode: Reconcile
+    kubernetes.io/name: "KubeDNS"
+spec:
+  selector:
+    k8s-app: kube-dns
+  clusterIP: 10.32.0.10
+  ports:
+  - name: dns
+    port: 53
+    protocol: UDP
+  - name: dns-tcp
+    port: 53
+    protocol: TCP
+---
 apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: kube-dns
   namespace: kube-system
+  labels:
+    kubernetes.io/cluster-service: "true"
+    addonmanager.kubernetes.io/mode: Reconcile
 ---
 apiVersion: v1
 kind: ConfigMap
@@ -12,181 +51,156 @@ metadata:
   labels:
     addonmanager.kubernetes.io/mode: EnsureExists
 ---
-apiVersion: v1
-kind: Service
-metadata:
-  name: kube-dns
-  namespace: kube-system
-  labels:
-    k8s-app: kube-dns
-    kubernetes.io/cluster-service: "true"
-    kubernetes.io/name: "KubeDNS"
-spec:
-  clusterIP: 10.32.0.10
-  ports:
-    - name: dns
-      port: 53
-      protocol: UDP
-      targetPort: 53
-    - name: dns-tcp
-      port: 53
-      protocol: TCP
-      targetPort: 53
-  selector:
-    k8s-app: kube-dns
-  sessionAffinity: None
-  type: ClusterIP
----
 apiVersion: extensions/v1beta1
 kind: Deployment
 metadata:
+  name: kube-dns
+  namespace: kube-system
   labels:
     k8s-app: kube-dns
     kubernetes.io/cluster-service: "true"
-  name: kube-dns
-  namespace: kube-system
+    addonmanager.kubernetes.io/mode: Reconcile
 spec:
-  replicas: 2
-  selector:
-    matchLabels:
-      k8s-app: kube-dns
+  # replicas: not specified here:
+  # 1. In order to make Addon Manager do not reconcile this replicas parameter.
+  # 2. Default is 1.
+  # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
   strategy:
     rollingUpdate:
       maxSurge: 10%
       maxUnavailable: 0
-    type: RollingUpdate
+  selector:
+    matchLabels:
+      k8s-app: kube-dns
   template:
     metadata:
-      annotations:
-        scheduler.alpha.kubernetes.io/critical-pod: ""
-      creationTimestamp: null
       labels:
         k8s-app: kube-dns
+      annotations:
+        scheduler.alpha.kubernetes.io/critical-pod: ''
     spec:
-      containers:
-        - name: kubedns
-          image: gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.4
-          env:
-            - name: PROMETHEUS_PORT
-              value: "10055"
-          args:
-            - --domain=cluster.local.
-            - --dns-port=10053
-            - --config-dir=/kube-dns-config
-            - --v=2
-          livenessProbe:
-            failureThreshold: 5
-            httpGet:
-              path: /healthcheck/kubedns
-              port: 10054
-              scheme: HTTP
-            initialDelaySeconds: 60
-            periodSeconds: 10
-            successThreshold: 1
-            timeoutSeconds: 5
-          ports:
-            - name: dns-local
-              containerPort: 10053
-              protocol: UDP
-            - name: dns-tcp-local
-              containerPort: 10053
-              protocol: TCP
-            - name: metrics
-              containerPort: 10055
-              protocol: TCP
-          readinessProbe:
-            failureThreshold: 3
-            httpGet:
-              path: /readiness
-              port: 8081
-              scheme: HTTP
-            initialDelaySeconds: 3
-            periodSeconds: 10
-            successThreshold: 1
-            timeoutSeconds: 5
-          resources:
-            limits:
-              memory: 170Mi
-            requests:
-              cpu: 100m
-              memory: 70Mi
-          volumeMounts:
-            - name: kube-dns-config
-              mountPath: /kube-dns-config
-        - name: dnsmasq
-          image: gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.4
-          args:
-            - -v=2
-            - -logtostderr
-            - -configDir=/etc/k8s/dns/dnsmasq-nanny
-            - -restartDnsmasq=true
-            - --
-            - -k
-            - --cache-size=1000
-            - --log-facility=-
-            - --server=/cluster.local/127.0.0.1#10053
-            - --server=/in-addr.arpa/127.0.0.1#10053
-            - --server=/ip6.arpa/127.0.0.1#10053
-          livenessProbe:
-            failureThreshold: 5
-            httpGet:
-              path: /healthcheck/dnsmasq
-              port: 10054
-              scheme: HTTP
-            initialDelaySeconds: 60
-            periodSeconds: 10
-            successThreshold: 1
-            timeoutSeconds: 5
-          ports:
-            - name: dns
-              containerPort: 53
-              protocol: UDP
-            - name: dns-tcp
-              containerPort: 53
-              protocol: TCP
-          resources:
-            requests:
-              cpu: 150m
-              memory: 20Mi
-          volumeMounts:
-            - name: kube-dns-config
-              mountPath: /etc/k8s/dns/dnsmasq-nanny
-        - name: sidecar
-          image: gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.4
-          args:
-            - --v=2
-            - --logtostderr
-            - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,A
-            - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.cluster.local,5,A
-          livenessProbe:
-            failureThreshold: 5
-            httpGet:
-              path: /metrics
-              port: 10054
-              scheme: HTTP
-            initialDelaySeconds: 60
-            periodSeconds: 10
-            successThreshold: 1
-            timeoutSeconds: 5
-          ports:
-            - name: metrics
-              containerPort: 10054
-              protocol: TCP
-          resources:
-            requests:
-              cpu: 10m
-              memory: 20Mi
-      dnsPolicy: Default
-      restartPolicy: Always
-      serviceAccount: kube-dns
-      serviceAccountName: kube-dns
-      terminationGracePeriodSeconds: 30
       tolerations:
-        - key: CriticalAddonsOnly
-          operator: Exists
+      - key: "CriticalAddonsOnly"
+        operator: "Exists"
       volumes:
+      - name: kube-dns-config
+        configMap:
+          name: kube-dns
+          optional: true
+      containers:
+      - name: kubedns
+        image: gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.7
+        resources:
+          # TODO: Set memory limits when we've profiled the container for large
+          # clusters, then set request = limit to keep this container in
+          # guaranteed class. Currently, this container falls into the
+          # "burstable" category so the kubelet doesn't backoff from restarting it.
+          limits:
+            memory: 170Mi
+          requests:
+            cpu: 100m
+            memory: 70Mi
+        livenessProbe:
+          httpGet:
+            path: /healthcheck/kubedns
+            port: 10054
+            scheme: HTTP
+          initialDelaySeconds: 60
+          timeoutSeconds: 5
+          successThreshold: 1
+          failureThreshold: 5
+        readinessProbe:
+          httpGet:
+            path: /readiness
+            port: 8081
+            scheme: HTTP
+          # we poll on pod startup for the Kubernetes master service and
+          # only setup the /readiness HTTP server once that's available.
+          initialDelaySeconds: 3
+          timeoutSeconds: 5
+        args:
+        - --domain=cluster.local.
+        - --dns-port=10053
+        - --config-dir=/kube-dns-config
+        - --v=2
+        env:
+        - name: PROMETHEUS_PORT
+          value: "10055"
+        ports:
+        - containerPort: 10053
+          name: dns-local
+          protocol: UDP
+        - containerPort: 10053
+          name: dns-tcp-local
+          protocol: TCP
+        - containerPort: 10055
+          name: metrics
+          protocol: TCP
+        volumeMounts:
         - name: kube-dns-config
-          configMap:
-            defaultMode: 420
-            name: kube-dns
-            optional: true
+          mountPath: /kube-dns-config
+      - name: dnsmasq
+        image: gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.7
+        livenessProbe:
+          httpGet:
+            path: /healthcheck/dnsmasq
+            port: 10054
+            scheme: HTTP
+          initialDelaySeconds: 60
+          timeoutSeconds: 5
+          successThreshold: 1
+          failureThreshold: 5
+        args:
+        - -v=2
+        - -logtostderr
+        - -configDir=/etc/k8s/dns/dnsmasq-nanny
+        - -restartDnsmasq=true
+        - --
+        - -k
+        - --cache-size=1000
+        - --no-negcache
+        - --log-facility=-
+        - --server=/cluster.local/127.0.0.1#10053
+        - --server=/in-addr.arpa/127.0.0.1#10053
+        - --server=/ip6.arpa/127.0.0.1#10053
+        ports:
+        - containerPort: 53
+          name: dns
+          protocol: UDP
+        - containerPort: 53
+          name: dns-tcp
+          protocol: TCP
+        # see: https://github.com/kubernetes/kubernetes/issues/29055 for details
+        resources:
+          requests:
+            cpu: 150m
+            memory: 20Mi
+        volumeMounts:
+        - name: kube-dns-config
+          mountPath: /etc/k8s/dns/dnsmasq-nanny
+      - name: sidecar
+        image: gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.7
+        livenessProbe:
+          httpGet:
+            path: /metrics
+            port: 10054
+            scheme: HTTP
+          initialDelaySeconds: 60
+          timeoutSeconds: 5
+          successThreshold: 1
+          failureThreshold: 5
+        args:
+        - --v=2
+        - --logtostderr
+        - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,SRV
+        - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.cluster.local,5,SRV
+        ports:
+        - containerPort: 10054
+          name: metrics
+          protocol: TCP
+        resources:
+          requests:
+            memory: 20Mi
+            cpu: 10m
+      dnsPolicy: Default  # Don't use cluster DNS.
+      serviceAccountName: kube-dns
diff --git a/docs/01-prerequisites.md b/docs/01-prerequisites.md
index fd419e4..79ff65a 100644
--- a/docs/01-prerequisites.md
+++ b/docs/01-prerequisites.md
@@ -14,7 +14,7 @@ This tutorial leverages the [Google Cloud Platform](https://cloud.google.com/) t
 
 Follow the Google Cloud SDK [documentation](https://cloud.google.com/sdk/) to install and configure the `gcloud` command line utility.
 
-Verify the Google Cloud SDK version is 173.0.0 or higher:
+Verify the Google Cloud SDK version is 183.0.0 or higher:
 
 ```
 gcloud version
diff --git a/docs/02-client-tools.md b/docs/02-client-tools.md
index 738b879..e6b728d 100644
--- a/docs/02-client-tools.md
+++ b/docs/02-client-tools.md
@@ -69,7 +69,7 @@ The `kubectl` command line utility is used to interact with the Kubernetes API S
 ### OS X
 
 ```
-curl -o kubectl https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/darwin/amd64/kubectl
+curl -o kubectl https://storage.googleapis.com/kubernetes-release/release/v1.9.0/bin/darwin/amd64/kubectl
 ```
 
 ```
@@ -83,7 +83,7 @@ sudo mv kubectl /usr/local/bin/
 ### Linux
 
 ```
-wget https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kubectl
+wget https://storage.googleapis.com/kubernetes-release/release/v1.9.0/bin/linux/amd64/kubectl
 ```
 
 ```
@@ -96,7 +96,7 @@ sudo mv kubectl /usr/local/bin/
 
 ### Verification
 
-Verify `kubectl` version 1.8.0 or higher is installed:
+Verify `kubectl` version 1.9.0 or higher is installed:
 
 ```
 kubectl version --client
@@ -105,7 +105,7 @@ kubectl version --client
 > output
 
 ```
-Client Version: version.Info{Major:"1", Minor:"8", GitVersion:"v1.8.0", GitCommit:"6e937839ac04a38cac63e6a7a306c5d035fe7b0a", GitTreeState:"clean", BuildDate:"2017-09-28T22:57:57Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"darwin/amd64"}
+Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.0", GitCommit:"925c127ec6b946659ad0fd596fa959be43f0cc05", GitTreeState:"clean", BuildDate:"2017-12-15T21:07:38Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"darwin/amd64"}
 ```
 
 Next: [Provisioning Compute Resources](03-compute-resources.md)
diff --git a/docs/03-compute-resources.md b/docs/03-compute-resources.md
index d81202d..ffe8ac3 100644
--- a/docs/03-compute-resources.md
+++ b/docs/03-compute-resources.md
@@ -17,7 +17,7 @@ In this section a dedicated [Virtual Private Cloud](https://cloud.google.com/com
 Create the `kubernetes-the-hard-way` custom VPC network:
 
 ```
-gcloud compute networks create kubernetes-the-hard-way --mode custom
+gcloud compute networks create kubernetes-the-hard-way --subnet-mode custom
 ```
 
 A [subnet](https://cloud.google.com/compute/docs/vpc/#vpc_networks_and_subnets) must be provisioned with an IP address range large enough to assign a private IP address to each node in the Kubernetes cluster.
@@ -63,9 +63,9 @@ gcloud compute firewall-rules list --filter "network: kubernetes-the-hard-way"
 > output
 
 ```
-NAME                                         NETWORK                  DIRECTION  PRIORITY  ALLOW                 DENY
-kubernetes-the-hard-way-allow-external       kubernetes-the-hard-way  INGRESS    1000      tcp:22,tcp:6443,icmp
-kubernetes-the-hard-way-allow-internal       kubernetes-the-hard-way  INGRESS    1000      tcp,udp,icmp
+NAME                                    NETWORK                  DIRECTION  PRIORITY  ALLOW                 DENY
+kubernetes-the-hard-way-allow-external  kubernetes-the-hard-way  INGRESS    1000      tcp:22,tcp:6443,icmp
+kubernetes-the-hard-way-allow-internal  kubernetes-the-hard-way  INGRESS    1000      tcp,udp,icmp
 ```
 
 ### Kubernetes Public IP Address
diff --git a/docs/07-bootstrapping-etcd.md b/docs/07-bootstrapping-etcd.md
index 1df5129..93ad388 100644
--- a/docs/07-bootstrapping-etcd.md
+++ b/docs/07-bootstrapping-etcd.md
@@ -18,17 +18,17 @@ Download the official etcd release binaries from the [coreos/etcd](https://githu
 
 ```
 wget -q --show-progress --https-only --timestamping \
-  "https://github.com/coreos/etcd/releases/download/v3.2.8/etcd-v3.2.8-linux-amd64.tar.gz"
+  "https://github.com/coreos/etcd/releases/download/v3.2.11/etcd-v3.2.11-linux-amd64.tar.gz"
 ```
 
 Extract and install the `etcd` server and the `etcdctl` command line utility:
 
 ```
-tar -xvf etcd-v3.2.8-linux-amd64.tar.gz
+tar -xvf etcd-v3.2.11-linux-amd64.tar.gz
 ```
 
 ```
-sudo mv etcd-v3.2.8-linux-amd64/etcd* /usr/local/bin/
+sudo mv etcd-v3.2.11-linux-amd64/etcd* /usr/local/bin/
 ```
 
 ### Configure the etcd Server
diff --git a/docs/08-bootstrapping-kubernetes-controllers.md b/docs/08-bootstrapping-kubernetes-controllers.md
index b526bbc..3175c2c 100644
--- a/docs/08-bootstrapping-kubernetes-controllers.md
+++ b/docs/08-bootstrapping-kubernetes-controllers.md
@@ -18,10 +18,10 @@ Download the official Kubernetes release binaries:
 
 ```
 wget -q --show-progress --https-only --timestamping \
-  "https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kube-apiserver" \
-  "https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kube-controller-manager" \
-  "https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kube-scheduler" \
-  "https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kubectl"
+  "https://storage.googleapis.com/kubernetes-release/release/v1.9.0/bin/linux/amd64/kube-apiserver" \
+  "https://storage.googleapis.com/kubernetes-release/release/v1.9.0/bin/linux/amd64/kube-controller-manager" \
+  "https://storage.googleapis.com/kubernetes-release/release/v1.9.0/bin/linux/amd64/kube-scheduler" \
+  "https://storage.googleapis.com/kubernetes-release/release/v1.9.0/bin/linux/amd64/kubectl"
 ```
 
 Install the Kubernetes binaries:
@@ -301,12 +301,12 @@ curl --cacert ca.pem https://${KUBERNETES_PUBLIC_ADDRESS}:6443/version
 ```
 {
   "major": "1",
-  "minor": "8",
-  "gitVersion": "v1.8.0",
-  "gitCommit": "6e937839ac04a38cac63e6a7a306c5d035fe7b0a",
+  "minor": "9",
+  "gitVersion": "v1.9.0",
+  "gitCommit": "925c127ec6b946659ad0fd596fa959be43f0cc05",
   "gitTreeState": "clean",
-  "buildDate": "2017-09-28T22:46:41Z",
-  "goVersion": "go1.8.3",
+  "buildDate": "2017-12-15T20:55:30Z",
+  "goVersion": "go1.9.2",
   "compiler": "gc",
   "platform": "linux/amd64"
 }
diff --git a/docs/09-bootstrapping-kubernetes-workers.md b/docs/09-bootstrapping-kubernetes-workers.md
index 8b777bd..2e72e9e 100644
--- a/docs/09-bootstrapping-kubernetes-workers.md
+++ b/docs/09-bootstrapping-kubernetes-workers.md
@@ -25,10 +25,10 @@ sudo apt-get -y install socat
 ```
 wget -q --show-progress --https-only --timestamping \
   https://github.com/containernetworking/plugins/releases/download/v0.6.0/cni-plugins-amd64-v0.6.0.tgz \
-  https://github.com/kubernetes-incubator/cri-containerd/releases/download/v1.0.0-alpha.0/cri-containerd-1.0.0-alpha.0.tar.gz \
-  https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kubectl \
-  https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kube-proxy \
-  https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kubelet
+  https://github.com/kubernetes-incubator/cri-containerd/releases/download/v1.0.0-beta.0/cri-containerd-1.0.0-beta.0.linux-amd64.tar.gz \
+  https://storage.googleapis.com/kubernetes-release/release/v1.9.0/bin/linux/amd64/kubectl \
+  https://storage.googleapis.com/kubernetes-release/release/v1.9.0/bin/linux/amd64/kube-proxy \
+  https://storage.googleapis.com/kubernetes-release/release/v1.9.0/bin/linux/amd64/kubelet
 ```
 
 Create the installation directories:
@@ -50,7 +50,7 @@ sudo tar -xvf cni-plugins-amd64-v0.6.0.tgz -C /opt/cni/bin/
 ```
 
 ```
-sudo tar -xvf cri-containerd-1.0.0-alpha.0.tar.gz -C /
+sudo tar -xvf cri-containerd-1.0.0-beta.0.linux-amd64.tar.gz -C /
 ```
 
 ```
@@ -227,9 +227,9 @@ kubectl get nodes
 
 ```
 NAME       STATUS    ROLES     AGE       VERSION
-worker-0   Ready     <none>    1m        v1.8.0
-worker-1   Ready     <none>    1m        v1.8.0
-worker-2   Ready     <none>    1m        v1.8.0
+worker-0   Ready     <none>    18s       v1.9.0
+worker-1   Ready     <none>    18s       v1.9.0
+worker-2   Ready     <none>    18s       v1.9.0
 ```
 
 Next: [Configuring kubectl for Remote Access](10-configuring-kubectl.md)
diff --git a/docs/10-configuring-kubectl.md b/docs/10-configuring-kubectl.md
index d7258fa..3d63825 100644
--- a/docs/10-configuring-kubectl.md
+++ b/docs/10-configuring-kubectl.md
@@ -70,9 +70,9 @@ kubectl get nodes
 
 ```
 NAME       STATUS    ROLES     AGE       VERSION
-worker-0   Ready     <none>    2m        v1.8.0
-worker-1   Ready     <none>    2m        v1.8.0
-worker-2   Ready     <none>    2m        v1.8.0
+worker-0   Ready     <none>    1m        v1.9.0
+worker-1   Ready     <none>    1m        v1.9.0
+worker-2   Ready     <none>    1m        v1.9.0
 ```
 
 Next: [Provisioning Pod Network Routes](11-pod-network-routes.md)
diff --git a/docs/11-pod-network-routes.md b/docs/11-pod-network-routes.md
index 96db243..f0d39be 100644
--- a/docs/11-pod-network-routes.md
+++ b/docs/11-pod-network-routes.md
@@ -50,8 +50,8 @@ gcloud compute routes list --filter "network: kubernetes-the-hard-way"
 
 ```
 NAME                            NETWORK                  DEST_RANGE     NEXT_HOP                  PRIORITY
-default-route-77bcc6bee33b5535  kubernetes-the-hard-way  10.240.0.0/24                            1000
-default-route-b11fc914b626974d  kubernetes-the-hard-way  0.0.0.0/0      default-internet-gateway  1000
+default-route-236a40a8bc992b5b  kubernetes-the-hard-way  0.0.0.0/0      default-internet-gateway  1000
+default-route-df77b1e818a56b30  kubernetes-the-hard-way  10.240.0.0/24                            1000
 kubernetes-route-10-200-0-0-24  kubernetes-the-hard-way  10.200.0.0/24  10.240.0.20               1000
 kubernetes-route-10-200-1-0-24  kubernetes-the-hard-way  10.200.1.0/24  10.240.0.21               1000
 kubernetes-route-10-200-2-0-24  kubernetes-the-hard-way  10.200.2.0/24  10.240.0.22               1000
diff --git a/docs/13-smoke-test.md b/docs/13-smoke-test.md
index df6644e..7e91805 100644
--- a/docs/13-smoke-test.md
+++ b/docs/13-smoke-test.md
@@ -27,19 +27,18 @@ gcloud compute ssh controller-0 \
 00000010  73 2f 64 65 66 61 75 6c  74 2f 6b 75 62 65 72 6e  |s/default/kubern|
 00000020  65 74 65 73 2d 74 68 65  2d 68 61 72 64 2d 77 61  |etes-the-hard-wa|
 00000030  79 0a 6b 38 73 3a 65 6e  63 3a 61 65 73 63 62 63  |y.k8s:enc:aescbc|
-00000040  3a 76 31 3a 6b 65 79 31  3a 70 88 d8 52 83 b7 96  |:v1:key1:p..R...|
-00000050  04 a3 bd 7e 42 9e 8a 77  2f 97 24 a7 68 3f c5 ec  |...~B..w/.$.h?..|
-00000060  9e f7 66 e8 a3 81 fc c8  3c df 63 71 33 0a 87 8f  |..f.....<.cq3...|
-00000070  0e c7 0a 0a f2 04 46 85  33 92 9a 4b 61 b2 10 c0  |......F.3..Ka...|
-00000080  0b 00 05 dd c3 c2 d0 6b  ff ff f2 32 3b e0 ec a0  |.......k...2;...|
-00000090  63 d3 8b 1c 29 84 88 71  a7 88 e2 26 4b 65 95 14  |c...)..q...&Ke..|
-000000a0  dc 8d 59 63 11 e5 f3 4e  b4 94 cc 3d 75 52 c7 07  |..Yc...N...=uR..|
-000000b0  73 f5 b4 b0 63 aa f9 9d  29 f8 d6 88 aa 33 c4 24  |s...c...)....3.$|
-000000c0  ac c6 71 2b 45 98 9e 5f  c6 a4 9d a2 26 3c 24 41  |..q+E.._....&<$A|
-000000d0  95 5b d3 2c 4b 1e 4a 47  c8 47 c8 f3 ac d6 e8 cb  |.[.,K.JG.G......|
-000000e0  5f a9 09 93 91 d7 5d c9  c2 68 f8 cf 3c 7e 3b a3  |_.....]..h..<~;.|
-000000f0  db d8 d5 9e 0c bf 2a 2f  58 0a                    |......*/X.|
-000000fa
+00000040  3a 76 31 3a 6b 65 79 31  3a ea 7c 76 32 43 62 6f  |:v1:key1:.|v2Cbo|
+00000050  44 02 02 8c b7 ca fe 95  a5 33 f6 a1 18 6c 3d 53  |D........3...l=S|
+00000060  e7 9c 51 ee 32 f6 e4 17  ea bb 11 d5 2f e2 40 00  |..Q.2......./.@.|
+00000070  ae cf d9 e7 ba 7f 68 18  d3 c1 10 10 93 43 35 bd  |......h......C5.|
+00000080  24 dd 66 b4 f8 f9 82 77  4a d5 78 03 19 41 1e bc  |$.f....wJ.x..A..|
+00000090  94 3f 17 41 ad cc 8c ba  9f 8f 8e 56 97 7e 96 fb  |.?.A.......V.~..|
+000000a0  8f 2e 6a a5 bf 08 1f 0b  c3 4b 2b 93 d1 ec f8 70  |..j......K+....p|
+000000b0  c1 e4 1d 1a d2 0d f8 74  3a a1 4f 3c e0 c9 6d 3f  |.......t:.O<..m?|
+000000c0  de a3 f5 fd 76 aa 5e bc  27 d9 3c 6b 8f 54 97 45  |....v.^.'.<k.T.E|
+000000d0  31 25 ff 23 90 a4 2a f2  db 78 b1 3b ca 21 f3 6b  |1%.#..*..x.;.!.k|
+000000e0  dd fb 8e 53 c6 23 0d 35  c8 0a                    |...S.#.5..|
+000000ea
 ```
 
 The etcd key should be prefixed with `k8s:enc:aescbc:v1:key1`, which indicates the `aescbc` provider was used to encrypt the data with the `key1` encryption key.
@@ -100,13 +99,13 @@ curl --head http://127.0.0.1:8080
 
 ```
 HTTP/1.1 200 OK
-Server: nginx/1.13.5
-Date: Mon, 02 Oct 2017 01:04:20 GMT
+Server: nginx/1.13.7
+Date: Mon, 18 Dec 2017 14:50:36 GMT
 Content-Type: text/html
 Content-Length: 612
-Last-Modified: Tue, 08 Aug 2017 15:25:00 GMT
+Last-Modified: Tue, 21 Nov 2017 14:28:04 GMT
 Connection: keep-alive
-ETag: "5989d7cc-264"
+ETag: "5a1437f4-264"
 Accept-Ranges: bytes
 ```
 
@@ -132,7 +131,7 @@ kubectl logs $POD_NAME
 > output
 
 ```
-127.0.0.1 - - [02/Oct/2017:01:04:20 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.54.0" "-"
+127.0.0.1 - - [18/Dec/2017:14:50:36 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.54.0" "-"
 ```
 
 ### Exec
@@ -148,7 +147,7 @@ kubectl exec -ti $POD_NAME -- nginx -v
 > output
 
 ```
-nginx version: nginx/1.13.5
+nginx version: nginx/1.13.7
 ```
 
 ## Services
@@ -195,13 +194,13 @@ curl -I http://${EXTERNAL_IP}:${NODE_PORT}
 
 ```
 HTTP/1.1 200 OK
-Server: nginx/1.13.5
-Date: Mon, 02 Oct 2017 01:06:11 GMT
+Server: nginx/1.13.7
+Date: Mon, 18 Dec 2017 14:52:09 GMT
 Content-Type: text/html
 Content-Length: 612
-Last-Modified: Tue, 08 Aug 2017 15:25:00 GMT
+Last-Modified: Tue, 21 Nov 2017 14:28:04 GMT
 Connection: keep-alive
-ETag: "5989d7cc-264"
+ETag: "5a1437f4-264"
 Accept-Ranges: bytes
 ```