├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── deployments └── kube-dns.yaml └── docs ├── 01-prerequisites.md ├── 02-client-tools.md ├── 03-create-cluster.md ├── 13-smoke-test.md ├── 14-cleanup.md └── images └── tmux-screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | admin-csr.json 2 | admin-key.pem 3 | admin.csr 4 | admin.pem 5 | admin.kubeconfig 6 | ca-config.json 7 | ca-csr.json 8 | ca-key.pem 9 | ca.csr 10 | ca.pem 11 | encryption-config.yaml 12 | kube-controller-manager-csr.json 13 | kube-controller-manager-key.pem 14 | kube-controller-manager.csr 15 | kube-controller-manager.kubeconfig 16 | kube-controller-manager.pem 17 | kube-scheduler-csr.json 18 | kube-scheduler-key.pem 19 | kube-scheduler.csr 20 | kube-scheduler.kubeconfig 21 | kube-scheduler.pem 22 | kube-proxy-csr.json 23 | kube-proxy-key.pem 24 | kube-proxy.csr 25 | kube-proxy.kubeconfig 26 | kube-proxy.pem 27 | kubernetes-csr.json 28 | kubernetes-key.pem 29 | kubernetes.csr 30 | kubernetes.pem 31 | worker-0-csr.json 32 | worker-0-key.pem 33 | worker-0.csr 34 | worker-0.kubeconfig 35 | worker-0.pem 36 | worker-1-csr.json 37 | worker-1-key.pem 38 | worker-1.csr 39 | worker-1.kubeconfig 40 | worker-1.pem 41 | worker-2-csr.json 42 | worker-2-key.pem 43 | worker-2.csr 44 | worker-2.kubeconfig 45 | worker-2.pem 46 | service-account-key.pem 47 | service-account.csr 48 | service-account.pem 49 | service-account-csr.json 50 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | This project is made possible by contributors like YOU! While all contributions are welcomed, please be sure and follow the following suggestions to help your PR get merged. 2 | 3 | ## License 4 | 5 | This project uses an [Apache license](LICENSE). Be sure you're comfortable with the implications of that before working up a patch. 6 | 7 | ## Review and merge process 8 | 9 | Review and merge duties are managed by [@kelseyhightower](https://github.com/kelseyhightower). Expect some burden of proof for demonstrating the marginal value of adding new content to the tutorial. 10 | 11 | Here are some examples of the review and justification process: 12 | - [#208](https://github.com/kelseyhightower/kubernetes-the-hard-way/pull/208) 13 | - [#282](https://github.com/kelseyhightower/kubernetes-the-hard-way/pull/282) 14 | 15 | ## Notes on minutiae 16 | 17 | If you find a bug that breaks the guide, please do submit it. If you are considering a minor copy edit for tone, grammar, or simple inconsistent whitespace, consider the tradeoff between maintainer time and community benefit before investing too much of your time. 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes The Easy Way 2 | 3 | Ok, you've done things [the hard way](https://github.com/kelseyhightower/kubernetes-the-hard-way) and now want to try out the same thing the easy way. 4 | 5 | ## Labs 6 | 7 | This tutorial assumes you have access to the [Google Cloud Platform](https://cloud.google.com). While GCP is used for basic infrastructure requirements the lessons learned in this tutorial can be applied to other platforms. 8 | 9 | * [Prerequisites](docs/01-prerequisites.md) 10 | * [Installing the Client Tools](docs/02-client-tools.md) 11 | * [Provisioning the Cluster](docs/03-create-cluster.md) 12 | * [Smoke Test](docs/13-smoke-test.md) 13 | * [Cleaning Up](docs/14-cleanup.md) 14 | -------------------------------------------------------------------------------- /deployments/kube-dns.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2016 The Kubernetes Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | kind: Service 17 | metadata: 18 | name: kube-dns 19 | namespace: kube-system 20 | labels: 21 | k8s-app: kube-dns 22 | kubernetes.io/cluster-service: "true" 23 | addonmanager.kubernetes.io/mode: Reconcile 24 | kubernetes.io/name: "KubeDNS" 25 | spec: 26 | selector: 27 | k8s-app: kube-dns 28 | clusterIP: 10.32.0.10 29 | ports: 30 | - name: dns 31 | port: 53 32 | protocol: UDP 33 | - name: dns-tcp 34 | port: 53 35 | protocol: TCP 36 | --- 37 | apiVersion: v1 38 | kind: ServiceAccount 39 | metadata: 40 | name: kube-dns 41 | namespace: kube-system 42 | labels: 43 | kubernetes.io/cluster-service: "true" 44 | addonmanager.kubernetes.io/mode: Reconcile 45 | --- 46 | apiVersion: v1 47 | kind: ConfigMap 48 | metadata: 49 | name: kube-dns 50 | namespace: kube-system 51 | labels: 52 | addonmanager.kubernetes.io/mode: EnsureExists 53 | --- 54 | apiVersion: apps/v1 55 | kind: Deployment 56 | metadata: 57 | name: kube-dns 58 | namespace: kube-system 59 | labels: 60 | k8s-app: kube-dns 61 | kubernetes.io/cluster-service: "true" 62 | addonmanager.kubernetes.io/mode: Reconcile 63 | spec: 64 | # replicas: not specified here: 65 | # 1. In order to make Addon Manager do not reconcile this replicas parameter. 66 | # 2. Default is 1. 67 | # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on. 68 | strategy: 69 | rollingUpdate: 70 | maxSurge: 10% 71 | maxUnavailable: 0 72 | selector: 73 | matchLabels: 74 | k8s-app: kube-dns 75 | template: 76 | metadata: 77 | labels: 78 | k8s-app: kube-dns 79 | annotations: 80 | scheduler.alpha.kubernetes.io/critical-pod: '' 81 | spec: 82 | tolerations: 83 | - key: "CriticalAddonsOnly" 84 | operator: "Exists" 85 | volumes: 86 | - name: kube-dns-config 87 | configMap: 88 | name: kube-dns 89 | optional: true 90 | containers: 91 | - name: kubedns 92 | image: gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.7 93 | resources: 94 | # TODO: Set memory limits when we've profiled the container for large 95 | # clusters, then set request = limit to keep this container in 96 | # guaranteed class. Currently, this container falls into the 97 | # "burstable" category so the kubelet doesn't backoff from restarting it. 98 | limits: 99 | memory: 170Mi 100 | requests: 101 | cpu: 100m 102 | memory: 70Mi 103 | livenessProbe: 104 | httpGet: 105 | path: /healthcheck/kubedns 106 | port: 10054 107 | scheme: HTTP 108 | initialDelaySeconds: 60 109 | timeoutSeconds: 5 110 | successThreshold: 1 111 | failureThreshold: 5 112 | readinessProbe: 113 | httpGet: 114 | path: /readiness 115 | port: 8081 116 | scheme: HTTP 117 | # we poll on pod startup for the Kubernetes master service and 118 | # only setup the /readiness HTTP server once that's available. 119 | initialDelaySeconds: 3 120 | timeoutSeconds: 5 121 | args: 122 | - --domain=cluster.local. 123 | - --dns-port=10053 124 | - --config-dir=/kube-dns-config 125 | - --v=2 126 | env: 127 | - name: PROMETHEUS_PORT 128 | value: "10055" 129 | ports: 130 | - containerPort: 10053 131 | name: dns-local 132 | protocol: UDP 133 | - containerPort: 10053 134 | name: dns-tcp-local 135 | protocol: TCP 136 | - containerPort: 10055 137 | name: metrics 138 | protocol: TCP 139 | volumeMounts: 140 | - name: kube-dns-config 141 | mountPath: /kube-dns-config 142 | - name: dnsmasq 143 | image: gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.7 144 | livenessProbe: 145 | httpGet: 146 | path: /healthcheck/dnsmasq 147 | port: 10054 148 | scheme: HTTP 149 | initialDelaySeconds: 60 150 | timeoutSeconds: 5 151 | successThreshold: 1 152 | failureThreshold: 5 153 | args: 154 | - -v=2 155 | - -logtostderr 156 | - -configDir=/etc/k8s/dns/dnsmasq-nanny 157 | - -restartDnsmasq=true 158 | - -- 159 | - -k 160 | - --cache-size=1000 161 | - --no-negcache 162 | - --log-facility=- 163 | - --server=/cluster.local/127.0.0.1#10053 164 | - --server=/in-addr.arpa/127.0.0.1#10053 165 | - --server=/ip6.arpa/127.0.0.1#10053 166 | ports: 167 | - containerPort: 53 168 | name: dns 169 | protocol: UDP 170 | - containerPort: 53 171 | name: dns-tcp 172 | protocol: TCP 173 | # see: https://github.com/kubernetes/kubernetes/issues/29055 for details 174 | resources: 175 | requests: 176 | cpu: 150m 177 | memory: 20Mi 178 | volumeMounts: 179 | - name: kube-dns-config 180 | mountPath: /etc/k8s/dns/dnsmasq-nanny 181 | - name: sidecar 182 | image: gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.7 183 | livenessProbe: 184 | httpGet: 185 | path: /metrics 186 | port: 10054 187 | scheme: HTTP 188 | initialDelaySeconds: 60 189 | timeoutSeconds: 5 190 | successThreshold: 1 191 | failureThreshold: 5 192 | args: 193 | - --v=2 194 | - --logtostderr 195 | - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,SRV 196 | - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.cluster.local,5,SRV 197 | ports: 198 | - containerPort: 10054 199 | name: metrics 200 | protocol: TCP 201 | resources: 202 | requests: 203 | memory: 20Mi 204 | cpu: 10m 205 | dnsPolicy: Default # Don't use cluster DNS. 206 | serviceAccountName: kube-dns 207 | -------------------------------------------------------------------------------- /docs/01-prerequisites.md: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | 3 | ## Google Cloud Platform 4 | 5 | This tutorial leverages the [Google Cloud Platform](https://cloud.google.com/) to streamline provisioning of a Kubernetes cluster. [Sign up](https://cloud.google.com/free/) for $300 in free credits. 6 | 7 | [Estimated cost](https://cloud.google.com/products/calculator/#id=0af4dffa-ed80-4d6a-a7d9-3089b9d1b4fe) to run this tutorial: $0.10 per hour ($2.39 per day). 8 | 9 | > The compute resources required for this tutorial exceed the Google Cloud Platform free tier. 10 | 11 | ## Google Cloud Platform SDK 12 | 13 | ### Install the Google Cloud SDK 14 | 15 | Follow the Google Cloud SDK [documentation](https://cloud.google.com/sdk/) to install and configure the `gcloud` command line utility. 16 | 17 | Verify the Google Cloud SDK version is 218.0.0 or higher: 18 | 19 | ``` 20 | gcloud version 21 | ``` 22 | 23 | ### Set a Default Compute Region and Zone 24 | 25 | This tutorial assumes a default compute region and zone have been configured. 26 | 27 | If you are using the `gcloud` command-line tool for the first time `init` is the easiest way to do this: 28 | 29 | ``` 30 | gcloud init 31 | ``` 32 | 33 | Otherwise: 34 | 1. Set the project: 35 | ``` 36 | gcloud config set project YOUR_PROJECT_ID 37 | ``` 38 | > To list projects: `gcloud projects list` 39 | 40 | 1. Set a default compute region: 41 | ``` 42 | gcloud config set compute/region us-west1 43 | ``` 44 | 45 | 1. Set a default compute zone: 46 | ``` 47 | gcloud config set compute/zone us-west1-c 48 | ``` 49 | > Use the `gcloud compute zones list` command to view additional regions and zones. 50 | 51 | Next: [Installing the Client Tools](02-client-tools.md) 52 | -------------------------------------------------------------------------------- /docs/02-client-tools.md: -------------------------------------------------------------------------------- 1 | # Installing the Client Tools 2 | 3 | ### Install The Kubernetes CLI 4 | 5 | Install `kubectl` via `gcloud`: 6 | ``` 7 | gcloud components install kubectl 8 | ``` 9 | 10 | Test the install: 11 | ``` 12 | kubectl version --client 13 | ``` 14 | 15 | You should see something like: 16 | ``` 17 | Client Version: version.Info{Major:"1", Minor:"18+", GitVersion:"v1.18.18-dispatcher", GitCommit:"de944d802c49735ad0f4bfe82ddfa19737ebe962", GitTreeState:"clean", BuildDate:"2021-05-13T17:51:55Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"} 18 | ``` 19 | 20 | Next: [Provisioning The Cluster](03-create-cluster.md) 21 | -------------------------------------------------------------------------------- /docs/03-create-cluster.md: -------------------------------------------------------------------------------- 1 | # Create A Kubernetes Cluster on Google Cloud 2 | 3 | Make sure the "container" service is enabled for your account: 4 | ``` 5 | gcloud services enable container 6 | ``` 7 | Otherwise you get an error like `Consumer XXXXXXXXX should enable service:container.googleapis.com before generating a service account.` 8 | 9 | Create the Kubernetes Cluster: 10 | ``` 11 | gcloud container clusters create kubernetes-the-easy-way 12 | ``` 13 | 14 | Next: [Smoke Test](13-smoke-test.md) 15 | -------------------------------------------------------------------------------- /docs/13-smoke-test.md: -------------------------------------------------------------------------------- 1 | # Smoke Test 2 | 3 | In this lab you will complete a series of tasks to ensure your Kubernetes cluster is functioning correctly. 4 | 5 | ## Data Encryption 6 | 7 | In this section you will verify the ability to [encrypt secret data at rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#verifying-that-data-is-encrypted). 8 | 9 | Create a generic secret: 10 | 11 | ``` 12 | kubectl create secret generic kubernetes-the-easy-way \ 13 | --from-literal="mykey=mydata" 14 | ``` 15 | Create a pod with the secret as an environment variable and print it to the logs: 16 | ``` 17 | cat < output 60 | 61 | ``` 62 | NAME READY STATUS RESTARTS AGE 63 | nginx-dbddb74b8-6lxg2 1/1 Running 0 10s 64 | ``` 65 | 66 | ### Port Forwarding 67 | 68 | In this section you will verify the ability to access applications remotely using [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/). 69 | 70 | Retrieve the full name of the `nginx` pod: 71 | 72 | ``` 73 | POD_NAME=$(kubectl get pods -l app=nginx -o jsonpath="{.items[0].metadata.name}") 74 | ``` 75 | 76 | Forward port `8080` on your local machine to port `80` of the `nginx` pod: 77 | 78 | ``` 79 | kubectl port-forward $POD_NAME 8080:80 80 | ``` 81 | 82 | > output 83 | 84 | ``` 85 | Forwarding from 127.0.0.1:8080 -> 80 86 | Forwarding from [::1]:8080 -> 80 87 | ``` 88 | 89 | In a new terminal make an HTTP request using the forwarding address: 90 | 91 | ``` 92 | curl --head http://127.0.0.1:8080 93 | ``` 94 | 95 | > output 96 | 97 | ``` 98 | HTTP/1.1 200 OK 99 | Server: nginx/1.15.4 100 | Date: Sun, 30 Sep 2018 19:23:10 GMT 101 | Content-Type: text/html 102 | Content-Length: 612 103 | Last-Modified: Tue, 25 Sep 2018 15:04:03 GMT 104 | Connection: keep-alive 105 | ETag: "5baa4e63-264" 106 | Accept-Ranges: bytes 107 | ``` 108 | 109 | Switch back to the previous terminal and stop the port forwarding to the `nginx` pod: 110 | 111 | ``` 112 | Forwarding from 127.0.0.1:8080 -> 80 113 | Forwarding from [::1]:8080 -> 80 114 | Handling connection for 8080 115 | ^C 116 | ``` 117 | 118 | ### Logs 119 | 120 | In this section you will verify the ability to [retrieve container logs](https://kubernetes.io/docs/concepts/cluster-administration/logging/). 121 | 122 | Print the `nginx` pod logs: 123 | 124 | ``` 125 | kubectl logs $POD_NAME 126 | ``` 127 | 128 | > output 129 | 130 | ``` 131 | 127.0.0.1 - - [30/Sep/2018:19:23:10 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.58.0" "-" 132 | ``` 133 | 134 | ### Exec 135 | 136 | In this section you will verify the ability to [execute commands in a container](https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/#running-individual-commands-in-a-container). 137 | 138 | Print the nginx version by executing the `nginx -v` command in the `nginx` container: 139 | 140 | ``` 141 | kubectl exec -ti $POD_NAME -- nginx -v 142 | ``` 143 | 144 | > output 145 | 146 | ``` 147 | nginx version: nginx/1.15.4 148 | ``` 149 | 150 | ## Services 151 | 152 | In this section you will verify the ability to expose applications using a [Service](https://kubernetes.io/docs/concepts/services-networking/service/). 153 | 154 | Expose the `nginx` deployment using a [LoadBalancer](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer) service: 155 | 156 | ``` 157 | kubectl expose deployment nginx --port=80 --type=LoadBalancer 158 | ``` 159 | 160 | Watch the new service until it gets an address (might take a few minutes), then *CTRL-C* to get back to the shell: 161 | ``` 162 | kubectl get svc nginx --watch -o jsonpath="{.status.loadBalancer}" 163 | ``` 164 | 165 | Retrieve the external IP address of a worker instance: 166 | ``` 167 | EXTERNAL_IP=$(kubectl get service nginx -o jsonpath="{.status.loadBalancer.ingress[0].ip}") 168 | ``` 169 | 170 | Make an HTTP request using the external IP address: 171 | 172 | ``` 173 | curl --head http://${EXTERNAL_IP} 174 | ``` 175 | 176 | > output 177 | 178 | ``` 179 | HTTP/1.1 200 OK 180 | Server: nginx/1.15.4 181 | Date: Sun, 30 Sep 2018 19:25:40 GMT 182 | Content-Type: text/html 183 | Content-Length: 612 184 | Last-Modified: Tue, 25 Sep 2018 15:04:03 GMT 185 | Connection: keep-alive 186 | ETag: "5baa4e63-264" 187 | Accept-Ranges: bytes 188 | ``` 189 | 190 | ## Untrusted Workloads 191 | 192 | These are not yet supported but there is a private alpha for [GKE Sandboxes](http://gke.page.link/sandbox). 193 | 194 | 195 | Next: [Cleaning Up](14-cleanup.md) 196 | -------------------------------------------------------------------------------- /docs/14-cleanup.md: -------------------------------------------------------------------------------- 1 | # Cleaning Up 2 | 3 | In this lab you will delete the compute resources created during this tutorial. 4 | 5 | ## Delete the Cluster 6 | 7 | ``` 8 | gcloud container clusters delete kubernetes-the-easy-way 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/images/tmux-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesward/kubernetes-the-easy-way/ae91f48495a24fe7b72fb661b2034b5b002425ec/docs/images/tmux-screenshot.png --------------------------------------------------------------------------------