├── .gitignore ├── CONTRIBUTING.md ├── COPYRIGHT.md ├── LICENSE ├── README.md ├── deployments ├── coredns.yaml └── kube-dns.yaml └── docs ├── 01-prerequisites.md ├── 02-client-tools.md ├── 03-compute-resources.md ├── 04-certificate-authority.md ├── 05-kubernetes-configuration-files.md ├── 06-data-encryption-keys.md ├── 07-bootstrapping-etcd.md ├── 08-bootstrapping-kubernetes-controllers.md ├── 09-bootstrapping-kubernetes-workers.md ├── 10-configuring-kubectl.md ├── 11-pod-network-routes.md ├── 12-dns-addon.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 | *.swp 51 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /COPYRIGHT.md: -------------------------------------------------------------------------------- 1 | # Copyright 2 | 3 | Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License 4 | -------------------------------------------------------------------------------- /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 Hard Way(日本語版) 2 | 3 | ### 【注意】この翻訳は、1.21.0時点で動作が確認できているバージョンの凍結版です。動作確認できた次のバージョンがリリースされない限り、しばらくの間更新の予定はありません。Typoや誤訳などを見つけた場合はPR、Issue、または[Twitter](https://twitter.com/_inductor_)にてお知らせください。 4 | 5 | 本チュートリアルでは、Kubernetesを地道にセットアップする方法を説明します。本ガイドは、Kubernetesクラスターを立てるための自動化コマンドを探している人には向いていません。そういう人は、[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine)や[Getting Started Guides](https://kubernetes.io/docs/setup)を御覧ください。 6 | 7 | Kubernetes The Hard Wayは勉強に適しています。長い道のりを経て、Kubernetesクラスターを起動するのに必要な各タスクを理解してください。 8 | 9 | > 本チュートリアルの結果はプロダクションレディではなく、コミュニティからのサポートも限られていますが、だからといって勉強しない理由にはなりません! 10 | 11 | ## Copyright 12 | 13 | Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. 14 | 15 | 16 | ## 対象者 17 | 18 | 本チュートリアルの対象読者は、Kubernetesの本番クラスターのサポートを予定していて、すべてがどのように連携しているかを理解したいという人です。 19 | 20 | ## クラスターの詳細 21 | 22 | Kubernetes The Hard Wayは、コンポーネント間のエンドツーエンドの暗号化とRBAC認証を使用して、可用性の高いKubernetesクラスターをブートストラップする手順を説明します。 23 | 24 | * [kubernetes](https://github.com/kubernetes/kubernetes) v1.21.0 25 | * [containerd](https://github.com/containerd/containerd) v1.4.4 26 | * [coredns](https://github.com/coredns/coredns) v1.8.3 27 | * [cni](https://github.com/containernetworking/cni) v0.9.1 28 | * [etcd](https://github.com/etcd-io/etcd) v3.4.15 29 | 30 | ## 実習内容 31 | 32 | 本チュートリアルは、Google Cloud Platformへのアクセス権があることを前提としています。GCPは基本的なインフラストラクチャ要件に使用されますが、本チュートリアルで学習したレッスンは他のプラットフォームにも適用できます。 33 | 34 | * [前提条件](docs/01-prerequisites.md) 35 | * [クライアントツールのインストール](docs/02-client-tools.md) 36 | * [計算資源のプロビジョニング](docs/03-compute-resources.md) 37 | * [CA証明書のプロビジョニングとTLS証明書の生成](docs/04-certificate-authority.md) 38 | * [認証用Kubernetes設定ファイルの生成](docs/05-kubernetes-configuration-files.md) 39 | * [データ暗号化の設定とキーの生成](docs/06-data-encryption-keys.md) 40 | * [etcdクラスターのブートストラップ](docs/07-bootstrapping-etcd.md) 41 | * [Kubernetesコントロールプレーンのブートストラップ](docs/08-bootstrapping-kubernetes-controllers.md) 42 | * [Kubenretesワーカーノードのブートストラップ](docs/09-bootstrapping-kubernetes-workers.md) 43 | * [リモートアクセス用のkubectl設定](docs/10-configuring-kubectl.md) 44 | * [Podネットワークルートのプロビジョニング](docs/11-pod-network-routes.md) 45 | * [DNSクラスターアドオンのデプロイ](docs/12-dns-addon.md) 46 | * [スモークテスト](docs/13-smoke-test.md) 47 | * [お掃除](docs/14-cleanup.md) 48 | -------------------------------------------------------------------------------- /deployments/coredns.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: coredns 5 | namespace: kube-system 6 | --- 7 | apiVersion: rbac.authorization.k8s.io/v1 8 | kind: ClusterRole 9 | metadata: 10 | labels: 11 | kubernetes.io/bootstrapping: rbac-defaults 12 | name: system:coredns 13 | rules: 14 | - apiGroups: 15 | - "" 16 | resources: 17 | - endpoints 18 | - services 19 | - pods 20 | - namespaces 21 | verbs: 22 | - list 23 | - watch 24 | - apiGroups: 25 | - "" 26 | resources: 27 | - nodes 28 | verbs: 29 | - get 30 | --- 31 | apiVersion: rbac.authorization.k8s.io/v1 32 | kind: ClusterRoleBinding 33 | metadata: 34 | annotations: 35 | rbac.authorization.kubernetes.io/autoupdate: "true" 36 | labels: 37 | kubernetes.io/bootstrapping: rbac-defaults 38 | name: system:coredns 39 | roleRef: 40 | apiGroup: rbac.authorization.k8s.io 41 | kind: ClusterRole 42 | name: system:coredns 43 | subjects: 44 | - kind: ServiceAccount 45 | name: coredns 46 | namespace: kube-system 47 | --- 48 | apiVersion: v1 49 | kind: ConfigMap 50 | metadata: 51 | name: coredns 52 | namespace: kube-system 53 | data: 54 | Corefile: | 55 | .:53 { 56 | errors 57 | health 58 | ready 59 | kubernetes cluster.local in-addr.arpa ip6.arpa { 60 | pods insecure 61 | fallthrough in-addr.arpa ip6.arpa 62 | } 63 | prometheus :9153 64 | cache 30 65 | loop 66 | reload 67 | loadbalance 68 | } 69 | --- 70 | apiVersion: apps/v1 71 | kind: Deployment 72 | metadata: 73 | name: coredns 74 | namespace: kube-system 75 | labels: 76 | k8s-app: kube-dns 77 | kubernetes.io/name: "CoreDNS" 78 | spec: 79 | replicas: 2 80 | strategy: 81 | type: RollingUpdate 82 | rollingUpdate: 83 | maxUnavailable: 1 84 | selector: 85 | matchLabels: 86 | k8s-app: kube-dns 87 | template: 88 | metadata: 89 | labels: 90 | k8s-app: kube-dns 91 | spec: 92 | priorityClassName: system-cluster-critical 93 | serviceAccountName: coredns 94 | tolerations: 95 | - key: "CriticalAddonsOnly" 96 | operator: "Exists" 97 | nodeSelector: 98 | beta.kubernetes.io/os: linux 99 | containers: 100 | - name: coredns 101 | image: coredns/coredns:1.7.0 102 | imagePullPolicy: IfNotPresent 103 | resources: 104 | limits: 105 | memory: 170Mi 106 | requests: 107 | cpu: 100m 108 | memory: 70Mi 109 | args: [ "-conf", "/etc/coredns/Corefile" ] 110 | volumeMounts: 111 | - name: config-volume 112 | mountPath: /etc/coredns 113 | readOnly: true 114 | ports: 115 | - containerPort: 53 116 | name: dns 117 | protocol: UDP 118 | - containerPort: 53 119 | name: dns-tcp 120 | protocol: TCP 121 | - containerPort: 9153 122 | name: metrics 123 | protocol: TCP 124 | securityContext: 125 | allowPrivilegeEscalation: false 126 | capabilities: 127 | add: 128 | - NET_BIND_SERVICE 129 | drop: 130 | - all 131 | readOnlyRootFilesystem: true 132 | livenessProbe: 133 | httpGet: 134 | path: /health 135 | port: 8080 136 | scheme: HTTP 137 | initialDelaySeconds: 60 138 | timeoutSeconds: 5 139 | successThreshold: 1 140 | failureThreshold: 5 141 | readinessProbe: 142 | httpGet: 143 | path: /ready 144 | port: 8181 145 | scheme: HTTP 146 | dnsPolicy: Default 147 | volumes: 148 | - name: config-volume 149 | configMap: 150 | name: coredns 151 | items: 152 | - key: Corefile 153 | path: Corefile 154 | --- 155 | apiVersion: v1 156 | kind: Service 157 | metadata: 158 | name: kube-dns 159 | namespace: kube-system 160 | annotations: 161 | prometheus.io/port: "9153" 162 | prometheus.io/scrape: "true" 163 | labels: 164 | k8s-app: kube-dns 165 | kubernetes.io/cluster-service: "true" 166 | kubernetes.io/name: "CoreDNS" 167 | spec: 168 | selector: 169 | k8s-app: kube-dns 170 | clusterIP: 10.32.0.10 171 | ports: 172 | - name: dns 173 | port: 53 174 | protocol: UDP 175 | - name: dns-tcp 176 | port: 53 177 | protocol: TCP 178 | - name: metrics 179 | port: 9153 180 | protocol: TCP 181 | -------------------------------------------------------------------------------- /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 | # 前提条件 2 | 3 | ## Google Cloud Platform 4 | 5 | 本チュートリアルでは、Kubernetesクラスターのブートストラップに必要な計算資源のプロビジョニングを一から効率的に行うために[Google Cloud Platform](https://cloud.google.com/)を活用しています。300ドル分の無料クレジットに[サインアップ](https://cloud.google.com/free/)してください。 6 | 7 | 本チュートリアルの[推定実行コスト](https://cloud.google.com/products/calculator#id=873932bc-0840-4176-b0fa-a8cfd4ca61ae)は1時間あたり$0.23(1日あたり$5.50)です。 8 | 9 | > 本チュートリアルに必要な計算資源は、Google Cloud Platformの無料枠を超えています。 10 | 11 | ## Google Cloud Platform SDK 12 | 13 | ### Google Cloud SDKのインストール 14 | 15 | Google Cloud SDKの[ドキュメント](https://cloud.google.com/sdk/)に従って `gcloud` コマンドをインストールし、設定してください。 16 | 17 | Google Cloud SDKのバージョンが338.0.0以上であることを確認してください: 18 | 19 | ``` 20 | gcloud version 21 | ``` 22 | 23 | ### デフォルトのリージョンとゾーンの設定 24 | 25 | 本チュートリアルでは、デフォルトのリージョンとゾーンが既に設定されている前提で進められます。 26 | 27 | はじめて `gcloud` コマンドをお使いの場合、`init` を使うと最も簡単に初期設定が行えます: 28 | 29 | ``` 30 | gcloud init 31 | ``` 32 | 33 | その後、ご自身のGoogleユーザーの認証情報でgcloudがCloud Platformにアクセスすることを必ず確認してください: 34 | 35 | ``` 36 | gcloud auth login 37 | ``` 38 | 39 | 次に、デフォルトのリージョンを設定します: 40 | 41 | ``` 42 | gcloud config set compute/region us-west1 43 | ``` 44 | 45 | 次に、デフォルトのゾーンを設定します: 46 | 47 | ``` 48 | gcloud config set compute/zone us-west1-c 49 | ``` 50 | 51 | > 追加で利用できるリージョンやゾーンを確認するには、`gcloud compute zones list` を使ってください。 52 | 53 | ## tmuxを使った並列なコマンド実行 54 | 55 | [tmux](https://github.com/tmux/tmux/wiki)を使用すると、複数のcomputeインスタンスで同時にコマンドを実行できます。本チュートリアルでは、同じコマンドを複数のコンピュートインスタンスで実行する必要がある場合があります。その場合、tmuxを使用して、プロビジョニングプロセスを高速化するために同期を有効にした複数のペインにウィンドウを分割することを検討してください。 56 | 57 | > tmuxの使用はオプションであり、このチュートリアルを完了するために必須ではありません。 58 | 59 | ![tmux screenshot](images/tmux-screenshot.png) 60 | 61 | > Enable synchronize-panes by pressing `ctrl+b` followed by `shift+:`. Next type `set synchronize-panes on` at the prompt. To disable synchronization: `set synchronize-panes off`. 62 | 63 | Next: [クライアントツールのインストール](02-client-tools.md) 64 | -------------------------------------------------------------------------------- /docs/02-client-tools.md: -------------------------------------------------------------------------------- 1 | # クライアントツールのインストール 2 | 3 | 本実習では、チュートリアルの実行に必要なコマンドである[cfssl](https://github.com/cloudflare/cfssl)、[cfssljson](https://github.com/cloudflare/cfssl)、[kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl)をインストールします。 4 | 5 | 6 | ## cfsslのインストール 7 | 8 | [公開鍵基盤](https://ja.wikipedia.org/wiki/%E5%85%AC%E9%96%8B%E9%8D%B5%E5%9F%BA%E7%9B%A4)のプロビジョニングとTLS証明書の生成には、`cfssl`および`cfssljson`コマンドラインユーティリティが使用されます。 9 | 10 | `cfssl`と`cfssljson`をダウンロードし、インストールします: 11 | 12 | ### macOS 13 | 14 | ``` 15 | curl -o cfssl https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/darwin/cfssl 16 | curl -o cfssljson https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/darwin/cfssljson 17 | ``` 18 | 19 | ``` 20 | chmod +x cfssl cfssljson 21 | ``` 22 | 23 | ``` 24 | sudo mv cfssl cfssljson /usr/local/bin/ 25 | ``` 26 | 27 | macOSユーザーの中でビルド済みバイナリーに問題があった人は、[Homebrew](https://brew.sh)を使うと改善されるかもしれません: 28 | 29 | ``` 30 | brew install cfssl 31 | ``` 32 | 33 | ### Linux 34 | 35 | ``` 36 | wget -q --show-progress --https-only --timestamping \ 37 | https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/linux/cfssl \ 38 | https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/linux/cfssljson 39 | ``` 40 | 41 | ``` 42 | chmod +x cfssl cfssljson 43 | ``` 44 | 45 | ``` 46 | sudo mv cfssl cfssljson /usr/local/bin/ 47 | ``` 48 | 49 | ### 検証 50 | 51 | インストールされた`cfssl`と`cfssljson`のバージョンが1.4.1以上であることを検証します: 52 | 53 | ``` 54 | cfssl version 55 | ``` 56 | 57 | > 出力結果 58 | 59 | ``` 60 | Version: 1.4.1 61 | Runtime: go1.12.12 62 | ``` 63 | 64 | ``` 65 | cfssljson --version 66 | ``` 67 | ``` 68 | Version: 1.4.1 69 | Runtime: go1.12.12 70 | ``` 71 | 72 | ## kubectlのインストール 73 | 74 | `kubectl`コマンドは、KubernetesのAPIサーバーとの対話に使用されます。公式リリースバイナリーから`kubectl`をダウンロードしてインストールします: 75 | 76 | ### macOS 77 | 78 | ``` 79 | curl -o kubectl https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/darwin/amd64/kubectl 80 | ``` 81 | 82 | ``` 83 | chmod +x kubectl 84 | ``` 85 | 86 | ``` 87 | sudo mv kubectl /usr/local/bin/ 88 | ``` 89 | 90 | ### Linux 91 | 92 | ``` 93 | wget https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/amd64/kubectl 94 | ``` 95 | 96 | ``` 97 | chmod +x kubectl 98 | ``` 99 | 100 | ``` 101 | sudo mv kubectl /usr/local/bin/ 102 | ``` 103 | 104 | ### 検証 105 | 106 | インストールされた`kubectl`のバージョンが1.21.0以上であることを検証します: 107 | 108 | ``` 109 | kubectl version --client 110 | ``` 111 | 112 | > 出力結果 113 | 114 | ``` 115 | Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.0", GitCommit:"cb303e613a121a29364f75cc67d3d580833a7479", GitTreeState:"clean", BuildDate:"2021-04-08T16:31:21Z", GoVersion:"go1.16.1", Compiler:"gc", Platform:"linux/amd64"} 116 | ``` 117 | 118 | Next: [計算資源のプロビジョニング](03-compute-resources.md) 119 | -------------------------------------------------------------------------------- /docs/03-compute-resources.md: -------------------------------------------------------------------------------- 1 | # 計算資源のプロビジョニング 2 | 3 | Kubernetesには、コントロールプレーンとコンテナが最終的に実行されるワーカーノードをホストするマシンのセットが必要です。本実習では、安全で可用性の高いKubernetesクラスターを単一の[ゾーン](https://cloud.google.com/compute/docs/regions-zones/regions-zones)で実行するために必要な計算資源をプロビジョニングします。 4 | 5 | > デフォルトのゾーンおよびリージョンが、[前提条件](01-prerequisites.md#デフォルトのリージョンとゾーンの設定)ページの説明通りに設定されていることを確認してください。 6 | 7 | ## ネットワーク 8 | 9 | Kubernetesの[ネットワークモデル](https://kubernetes.io/docs/concepts/cluster-administration/networking/#kubernetes-model)は、コンテナとノードが相互に通信できるフラットなネットワークを想定しています。これが望ましくない場合は、[ネットワークポリシー](https://kubernetes.io/docs/concepts/services-networking/network-policies/)を使ってコンテナのグループが相互に、もしくは外部ネットワークエンドポイントと通信することを制限できます。 10 | 11 | > ネットワークポリシーの設定は、本チュートリアルの対象外です。 12 | 13 | ### 仮想プライベートクラウドネットワーク(VPC) 14 | 15 | 本セクションではKubernetesクラスタをホストする専用の[仮想プライベートクラウド](https://cloud.google.com/compute/docs/networks-and-firewalls#networks)(VPC)を設定します。 16 | 17 | `kubernetes-the-hard-way`という名前のカスタムVPCネットワークを作成します: 18 | 19 | ``` 20 | gcloud compute networks create kubernetes-the-hard-way --subnet-mode custom 21 | ``` 22 | 23 | [サブネット](https://cloud.google.com/compute/docs/vpc/#vpc_networks_and_subnets)は、Kubernetesクラスター内の各ノードにプライベートIPアドレスを割り当てるのに十分なIPアドレス範囲でプロビジョニングする必要があります。 24 | 25 | `kubernetes`という名前のサブネットを`kubernetes-the-hard-way`VPCネットワーク内に作成します: 26 | 27 | ``` 28 | gcloud compute networks subnets create kubernetes \ 29 | --network kubernetes-the-hard-way \ 30 | --range 10.240.0.0/24 31 | ``` 32 | 33 | > IPアドレス範囲`10.240.0.0/24`を指定すると、254個までのインスタンスまで作成することができます。 34 | 35 | ### Firewall Rules 36 | 37 | 内部通信にて全プロトコルを許可するファイアウォールルールを作成します: 38 | 39 | ``` 40 | gcloud compute firewall-rules create kubernetes-the-hard-way-allow-internal \ 41 | --allow tcp,udp,icmp \ 42 | --network kubernetes-the-hard-way \ 43 | --source-ranges 10.240.0.0/24,10.200.0.0/16 44 | ``` 45 | 46 | 外部からのSSH、ICMP、およびHTTPS通信を許可するファイアウォールルールを作成します: 47 | 48 | ``` 49 | gcloud compute firewall-rules create kubernetes-the-hard-way-allow-external \ 50 | --allow tcp:22,tcp:6443,icmp \ 51 | --network kubernetes-the-hard-way \ 52 | --source-ranges 0.0.0.0/0 53 | ``` 54 | 55 | > KubernetesのAPIサーバーをリモートクライアントに公開するために[外部ロードバランサ](https://cloud.google.com/compute/docs/load-balancing/network/)が利用されます。 56 | 57 | `Kubernetes-the-hard-way`VPCネットワークにおけるファイアウォールルール一覧を確認します: 58 | 59 | ``` 60 | gcloud compute firewall-rules list --filter="network:kubernetes-the-hard-way" 61 | ``` 62 | 63 | > 出力結果 64 | 65 | ``` 66 | NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED 67 | kubernetes-the-hard-way-allow-external kubernetes-the-hard-way INGRESS 1000 tcp:22,tcp:6443,icmp False 68 | kubernetes-the-hard-way-allow-internal kubernetes-the-hard-way INGRESS 1000 tcp,udp,icmp False 69 | ``` 70 | 71 | ### Kubernetesの公開IPアドレス 72 | 73 | KubernetesのAPIサーバの前面に置かれる外部ロードバランサにアタッチする静的IPアドレスを割り当てます: 74 | 75 | ``` 76 | gcloud compute addresses create kubernetes-the-hard-way \ 77 | --region $(gcloud config get-value compute/region) 78 | ``` 79 | 80 | `kubernetes-the-hard-way`という名前の静的IPアドレスがデフォルトリージョンに作成されたことを確認します: 81 | 82 | ``` 83 | gcloud compute addresses list --filter="name=('kubernetes-the-hard-way')" 84 | ``` 85 | 86 | > 出力結果 87 | 88 | ``` 89 | NAME ADDRESS/RANGE TYPE PURPOSE NETWORK REGION SUBNET STATUS 90 | kubernetes-the-hard-way XX.XXX.XXX.XXX EXTERNAL us-west1 RESERVED 91 | ``` 92 | 93 | ## インスタンス 94 | 95 | 本実習のインスタンスでは、コンテナランタイムの[containerd](https://github.com/containerd/containerd)にて推奨される[Ubuntu Server](https://www.ubuntu.com/server) 20.04を使用します。各インスタンスは、Kubernetesのブートストラッピング処理を単純化するために、固定のプライベートIPアドレスでプロビジョニングされます。 96 | 97 | ### Kubernetesコントロールプレーン 98 | 99 | Kubernetesコントロールプレーンをホストする3つのインスタンスを作成します: 100 | 101 | ```sh 102 | for i in 0 1 2; do 103 | gcloud compute instances create controller-${i} \ 104 | --async \ 105 | --boot-disk-size 200GB \ 106 | --can-ip-forward \ 107 | --image-family ubuntu-2004-lts \ 108 | --image-project ubuntu-os-cloud \ 109 | --machine-type e2-standard-2 \ 110 | --private-network-ip 10.240.0.1${i} \ 111 | --scopes compute-rw,storage-ro,service-management,service-control,logging-write,monitoring \ 112 | --subnet kubernetes \ 113 | --tags kubernetes-the-hard-way,controller 114 | done 115 | ``` 116 | 117 | ### Kubernetesワーカー 118 | 119 | 各ワーカーインスタンスは、KubernetesクラスターにおけるCIDR範囲からのPodサブネット割り当てを必要とします。Podサブネットの割り当ては、後の実習にてコンテナネットワークの設定に使用します。`pod-cidr`インスタンスメタデータは、実行時にインスタンスを計算するためのPodサブネット割り当てを公開するために使用されます。 120 | 121 | > KubernetesクラスターのCIDR範囲は、コントローラーマネージャーの`--cluster-cidr`フラグで定義されます。本チュートリアルでは、クラスターのCIDR範囲を`10.200.0.0/16に設定します。これは、254のサブネットをサポートします。 122 | 123 | Kubernetesワーカーノードをホストするインスタンスを3つ作成します: 124 | 125 | ```sh 126 | for i in 0 1 2; do 127 | gcloud compute instances create worker-${i} \ 128 | --async \ 129 | --boot-disk-size 200GB \ 130 | --can-ip-forward \ 131 | --image-family ubuntu-2004-lts \ 132 | --image-project ubuntu-os-cloud \ 133 | --machine-type e2-standard-2 \ 134 | --metadata pod-cidr=10.200.${i}.0/24 \ 135 | --private-network-ip 10.240.0.2${i} \ 136 | --scopes compute-rw,storage-ro,service-management,service-control,logging-write,monitoring \ 137 | --subnet kubernetes \ 138 | --tags kubernetes-the-hard-way,worker 139 | done 140 | ``` 141 | 142 | ### 検証 143 | 144 | デフォルトのゾーン内にあるインスタンスの一覧を表示します: 145 | 146 | ``` 147 | gcloud compute instances list --filter="tags.items=kubernetes-the-hard-way" 148 | ``` 149 | 150 | > 出力結果 151 | 152 | ``` 153 | NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS 154 | controller-0 us-west1-c e2-standard-2 10.240.0.10 XX.XX.XX.XXX RUNNING 155 | controller-1 us-west1-c e2-standard-2 10.240.0.11 XX.XXX.XXX.XX RUNNING 156 | controller-2 us-west1-c e2-standard-2 10.240.0.12 XX.XXX.XX.XXX RUNNING 157 | worker-0 us-west1-c e2-standard-2 10.240.0.20 XX.XX.XXX.XXX RUNNING 158 | worker-1 us-west1-c e2-standard-2 10.240.0.21 XX.XX.XX.XXX RUNNING 159 | worker-2 us-west1-c e2-standard-2 10.240.0.22 XX.XXX.XX.XX RUNNING 160 | ``` 161 | 162 | ## SSHアクセスの設定 163 | 164 | SSHは、コントローラーおよびワーカーインスタンスの設定に使用されます。初めてインスタンスに接続するとSSHキーが生成され、プロジェクトまたはインスタンスのメタデータに格納されます ([インスタンスへの接続](https://cloud.google.com/compute/docs/instances/connecting-to-instance)のマニュアルを参照してください)。 165 | 166 | 試しに、`controller-0`インスタンスにSSHしてみます: 167 | 168 | ``` 169 | gcloud compute ssh controller-0 170 | ``` 171 | 172 | インスタンスに初めて接続する場合はSSHキーが生成されます。ターミナル上でパスフレーズを入力して続行します: 173 | 174 | ``` 175 | WARNING: The public SSH key file for gcloud does not exist. 176 | WARNING: The private SSH key file for gcloud does not exist. 177 | WARNING: You do not have an SSH key for gcloud. 178 | WARNING: SSH keygen will be executed to generate a key. 179 | Generating public/private rsa key pair. 180 | Enter passphrase (empty for no passphrase): 181 | Enter same passphrase again: 182 | ``` 183 | 184 | この時点で生成されたSSHキーがアップロードされ、GCPのプロジェクトに保存されます:: 185 | 186 | ``` 187 | Your identification has been saved in /home/$USER/.ssh/google_compute_engine. 188 | Your public key has been saved in /home/$USER/.ssh/google_compute_engine.pub. 189 | The key fingerprint is: 190 | SHA256:nz1i8jHmgQuGt+WscqP5SeIaSy5wyIJeL71MuV+QruE $USER@$HOSTNAME 191 | The key's randomart image is: 192 | +---[RSA 2048]----+ 193 | | | 194 | | | 195 | | | 196 | | . | 197 | |o. oS | 198 | |=... .o .o o | 199 | |+.+ =+=.+.X o | 200 | |.+ ==O*B.B = . | 201 | | .+.=EB++ o | 202 | +----[SHA256]-----+ 203 | Updating project ssh metadata...-Updated [https://www.googleapis.com/compute/v1/projects/$PROJECT_ID]. 204 | Updating project ssh metadata...done. 205 | Waiting for SSH key to propagate. 206 | ``` 207 | 208 | SSHキーが更新されると`controller-0`インスタンスにログインします: 209 | 210 | ``` 211 | Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-1042-gcp x86_64) 212 | ... 213 | ``` 214 | 215 | ターミナルで`exit`と入力し、`controller-0`インスタンスを終了します: 216 | 217 | ``` 218 | $USER@controller-0:~$ exit 219 | ``` 220 | > 出力結果 221 | 222 | ``` 223 | logout 224 | Connection to XX.XX.XX.XXX closed 225 | ``` 226 | 227 | Next: [CA証明書のプロビジョニングとTLS証明書の生成](04-certificate-authority.md) 228 | -------------------------------------------------------------------------------- /docs/04-certificate-authority.md: -------------------------------------------------------------------------------- 1 | # CA証明書のプロビジョニングとTLS証明書の生成 2 | 3 | 本実習では、CloudFlareのPKIツールキットである[cfssl](https://github.com/cloudflare/cfssl)を使用して[公開鍵基盤](https://ja.wikipedia.org/wiki/%E5%85%AC%E9%96%8B%E9%8D%B5%E5%9F%BA%E7%9B%A4)をプロビジョニングし、それを使用して認証機関を起動し、etcd、kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxyの各コンポーネントのTLS証明書を生成します。 4 | 5 | ## Certificate Authority 6 | 7 | 本セクションでは、追加のTLS証明書を生成するために使用できる認証局をプロビジョニングします。 8 | 9 | CA構成ファイル、証明書、および秘密鍵を生成します: 10 | 11 | ```sh 12 | { 13 | 14 | cat > ca-config.json < ca-csr.json < admin-csr.json <`で識別するクレデンシャルを使用する必要があります。本セクションでは、各Kubernetesワーカーノード用にNode Authorizerの要件を満たす証明書を作成します。 111 | 112 | 各ワーカーノード用の証明書と秘密鍵を生成します: 113 | 114 | ```sh 115 | for instance in worker-{0..2}; do 116 | cat > ${instance}-csr.json < kube-controller-manager-csr.json < kube-proxy-csr.json < kube-scheduler-csr.json < kubernetes-csr.json < KubernetesのAPIサーバーには自動的にKubernetesの内部DNS名が割り当てられます。この名前は、[コントロールプレーンのブートストラップ](08-bootstrapping-kubernetes-controllers.md#configure-the-kubernetes-api-server)で内部クラスタサービス用に予約されたアドレス範囲(`10.32.0.0/24`)の最初のIPアドレス(`10.32.0.1`)にリンクされます。 339 | 340 | 結果: 341 | 342 | ``` 343 | kubernetes-key.pem 344 | kubernetes.pem 345 | ``` 346 | 347 | ## サービスアカウントのキーペア 348 | 349 | Kubernetesのコントローラーマネージャーは、[サービスアカウントの管理](https://kubernetes.io/docs/admin/service-accounts-admin/)に関するドキュメントで説明されているように、キーペアを使用してサービスアカウントトークンを生成して署名します。 350 | 351 | `service-account`用クライアント証明書と秘密鍵を生成します: 352 | 353 | ```sh 354 | { 355 | 356 | cat > service-account-csr.json <`kube-proxy`、`kube-controller-manager`、`kube-scheduler`、および`kubelet`用クライアント証明書は、次の実習でクライアントの認証用設定ファイルを生成するために使用します。 413 | 414 | Next: [認証用Kubernetes設定ファイルの生成](05-kubernetes-configuration-files.md) 415 | -------------------------------------------------------------------------------- /docs/05-kubernetes-configuration-files.md: -------------------------------------------------------------------------------- 1 | # 認証用Kubernetes設定ファイルの生成 2 | 3 | 本実習では[Kubernetesのコンフィグファイル](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/)(kubeconfigとも呼ばれます)を生成します。これにより、KubernetesクライアントがKubernetesのAPIサーバーを特定して認証できるようになります。 4 | 5 | ## クライアント認証コンフィグ 6 | 7 | 本セクションでは、`controller manager`、`kubelet`、`kube-proxy`、および`scheduler`のクライアントと`admin`ユーザー用のkubeconfigファイルを生成します。 8 | 9 | ### Kubernetesの公開IPアドレス 10 | 11 | kubeconfigには接続先のKubernetes APIサーバーが必要です。高可用性をサポートするために、Kubernetes APIサーバの前面に配置した外部ロードバランサに割り当てられたIPアドレスが使用されます。 12 | 13 | 静的IPアドレス`kubernetes-the-hard-way`を取得します: 14 | 15 | ``` 16 | KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \ 17 | --region $(gcloud config get-value compute/region) \ 18 | --format 'value(address)') 19 | ``` 20 | 21 | ### kubelet用Kubernetesコンフィグファイル 22 | 23 | kubelet用のkubeconfigファイルを生成する際、kubeletのノード名に一致するクライアント証明書を使用する必要があります。これにより、kubeletがKubernetes [Node Authorizer](https://kubernetes.io/docs/admin/authorization/node/)によって適切に許可されます。 24 | 25 | > 次のコマンドは、[TLS証明書の生成](04-certificate-authority.md)でSSL証明書を生成するときに使用したディレクトリと同じディレクトリで実行する必要があります。 26 | 27 | 各ワーカーノード用kubeconfigファイルを生成します: 28 | 29 | ```sh 30 | for instance in worker-{0..2}; do 31 | kubectl config set-cluster kubernetes-the-hard-way \ 32 | --certificate-authority=ca.pem \ 33 | --embed-certs=true \ 34 | --server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 \ 35 | --kubeconfig=${instance}.kubeconfig 36 | 37 | kubectl config set-credentials system:node:${instance} \ 38 | --client-certificate=${instance}.pem \ 39 | --client-key=${instance}-key.pem \ 40 | --embed-certs=true \ 41 | --kubeconfig=${instance}.kubeconfig 42 | 43 | kubectl config set-context default \ 44 | --cluster=kubernetes-the-hard-way \ 45 | --user=system:node:${instance} \ 46 | --kubeconfig=${instance}.kubeconfig 47 | 48 | kubectl config use-context default --kubeconfig=${instance}.kubeconfig 49 | done 50 | ``` 51 | 52 | 結果: 53 | 54 | ``` 55 | worker-0.kubeconfig 56 | worker-1.kubeconfig 57 | worker-2.kubeconfig 58 | ``` 59 | 60 | ### kube-proxy用Kubernetesコンフィグファイル 61 | 62 | `kube-proxy`サービス用kubeconfigファイルを生成します: 63 | 64 | ``` 65 | { 66 | kubectl config set-cluster kubernetes-the-hard-way \ 67 | --certificate-authority=ca.pem \ 68 | --embed-certs=true \ 69 | --server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 \ 70 | --kubeconfig=kube-proxy.kubeconfig 71 | 72 | kubectl config set-credentials system:kube-proxy \ 73 | --client-certificate=kube-proxy.pem \ 74 | --client-key=kube-proxy-key.pem \ 75 | --embed-certs=true \ 76 | --kubeconfig=kube-proxy.kubeconfig 77 | 78 | kubectl config set-context default \ 79 | --cluster=kubernetes-the-hard-way \ 80 | --user=system:kube-proxy \ 81 | --kubeconfig=kube-proxy.kubeconfig 82 | 83 | kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig 84 | } 85 | ``` 86 | 87 | 結果: 88 | 89 | ``` 90 | kube-proxy.kubeconfig 91 | ``` 92 | 93 | ### kube-controller-manager用Kubernetesコンフィグファイル 94 | 95 | `kube-controller-manager`サービス用kubeconfigファイルを生成します: 96 | 97 | ``` 98 | { 99 | kubectl config set-cluster kubernetes-the-hard-way \ 100 | --certificate-authority=ca.pem \ 101 | --embed-certs=true \ 102 | --server=https://127.0.0.1:6443 \ 103 | --kubeconfig=kube-controller-manager.kubeconfig 104 | 105 | kubectl config set-credentials system:kube-controller-manager \ 106 | --client-certificate=kube-controller-manager.pem \ 107 | --client-key=kube-controller-manager-key.pem \ 108 | --embed-certs=true \ 109 | --kubeconfig=kube-controller-manager.kubeconfig 110 | 111 | kubectl config set-context default \ 112 | --cluster=kubernetes-the-hard-way \ 113 | --user=system:kube-controller-manager \ 114 | --kubeconfig=kube-controller-manager.kubeconfig 115 | 116 | kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig 117 | } 118 | ``` 119 | 120 | 結果: 121 | 122 | ``` 123 | kube-controller-manager.kubeconfig 124 | ``` 125 | 126 | 127 | ### kube-scheduler用Kubernetesコンフィグファイル 128 | 129 | `kube-scheduler`サービス用kubeconfigファイルを生成します: 130 | 131 | ``` 132 | { 133 | kubectl config set-cluster kubernetes-the-hard-way \ 134 | --certificate-authority=ca.pem \ 135 | --embed-certs=true \ 136 | --server=https://127.0.0.1:6443 \ 137 | --kubeconfig=kube-scheduler.kubeconfig 138 | 139 | kubectl config set-credentials system:kube-scheduler \ 140 | --client-certificate=kube-scheduler.pem \ 141 | --client-key=kube-scheduler-key.pem \ 142 | --embed-certs=true \ 143 | --kubeconfig=kube-scheduler.kubeconfig 144 | 145 | kubectl config set-context default \ 146 | --cluster=kubernetes-the-hard-way \ 147 | --user=system:kube-scheduler \ 148 | --kubeconfig=kube-scheduler.kubeconfig 149 | 150 | kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig 151 | } 152 | ``` 153 | 154 | 結果: 155 | 156 | ``` 157 | kube-scheduler.kubeconfig 158 | ``` 159 | 160 | ### admin用Kubernetesコンフィグファイル 161 | 162 | `admin`ユーザー用kubeconfigファイルを生成します: 163 | 164 | ``` 165 | { 166 | kubectl config set-cluster kubernetes-the-hard-way \ 167 | --certificate-authority=ca.pem \ 168 | --embed-certs=true \ 169 | --server=https://127.0.0.1:6443 \ 170 | --kubeconfig=admin.kubeconfig 171 | 172 | kubectl config set-credentials admin \ 173 | --client-certificate=admin.pem \ 174 | --client-key=admin-key.pem \ 175 | --embed-certs=true \ 176 | --kubeconfig=admin.kubeconfig 177 | 178 | kubectl config set-context default \ 179 | --cluster=kubernetes-the-hard-way \ 180 | --user=admin \ 181 | --kubeconfig=admin.kubeconfig 182 | 183 | kubectl config use-context default --kubeconfig=admin.kubeconfig 184 | } 185 | ``` 186 | 187 | 結果: 188 | 189 | ``` 190 | admin.kubeconfig 191 | ``` 192 | 193 | ## Kubernetesコンフィグファイルの配布 194 | 195 | 適切な`kubelet`及び`kube-proxy`用kubeconfigファイルを各ワーカーノード用インスタンスにコピーします: 196 | 197 | ```sh 198 | for instance in worker-{0..2}; do 199 | gcloud compute scp ${instance}.kubeconfig kube-proxy.kubeconfig ${instance}:~/ 200 | done 201 | ``` 202 | 203 | 適切な`kube-controller-manager`及び`kube-scheduler`用kubeconfigファイルをコントロールプレーン用インスタンスにコピーします: 204 | 205 | ```sh 206 | for instance in controller-{0..2}; do 207 | gcloud compute scp admin.kubeconfig kube-controller-manager.kubeconfig kube-scheduler.kubeconfig ${instance}:~/ 208 | done 209 | ``` 210 | 211 | Next: [データ暗号化の設定とキーの生成](06-data-encryption-keys.md) 212 | -------------------------------------------------------------------------------- /docs/06-data-encryption-keys.md: -------------------------------------------------------------------------------- 1 | # データ暗号化の設定とキーの生成 2 | 3 | Kubernetesはクラスタの状態、アプリケーションの構成、機密情報など、さまざまなデータを保存します。Kubernetesはクラスタデータを[暗号化](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data)する機能をサポートします。 4 | 5 | 本実習では、Kubernetes Secretsの暗号化に適したキーと[コンフィグ](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#understanding-the-encryption-at-rest-configuration)を生成します。 6 | 7 | ## 暗号化キー 8 | 9 | 暗号化キーを生成します: 10 | 11 | ```sh 12 | ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64) 13 | ``` 14 | 15 | ## 暗号化コンフィグファイル 16 | 17 | `encryption-config.yaml`という名前の暗号化コンフィグファイルを生成します: 18 | 19 | ```sh 20 | cat > encryption-config.yaml < 上記のコマンドは各コントローラノード`controller-0`、`controller-1`、`controller-2`にて忘れずに実行してください。 107 | 108 | ## 検証 109 | 110 | etcdのクラスターメンバーの一覧を表示します: 111 | 112 | ``` 113 | sudo ETCDCTL_API=3 etcdctl member list \ 114 | --endpoints=https://127.0.0.1:2379 \ 115 | --cacert=/etc/etcd/ca.pem \ 116 | --cert=/etc/etcd/kubernetes.pem \ 117 | --key=/etc/etcd/kubernetes-key.pem 118 | ``` 119 | 120 | > 出力結果 121 | 122 | ``` 123 | 3a57933972cb5131, started, controller-2, https://10.240.0.12:2380, https://10.240.0.12:2379, false 124 | f98dc20bce6225a0, started, controller-0, https://10.240.0.10:2380, https://10.240.0.10:2379, false 125 | ffed16798470cab5, started, controller-1, https://10.240.0.11:2380, https://10.240.0.11:2379, false 126 | ``` 127 | 128 | Next: [Kubernetesコントロールプレーンのブートストラップ](08-bootstrapping-kubernetes-controllers.md) 129 | -------------------------------------------------------------------------------- /docs/08-bootstrapping-kubernetes-controllers.md: -------------------------------------------------------------------------------- 1 | # Kubernetesコントロールプレーンのブートストラップ 2 | 3 | 本実習では、3つのインスタンスでコントロールプレーンをブートストラップして可用性の高い構成を実現します。また、KubernetesのAPIサーバーをリモートクライアントに公開する外部ロードバランサも作成します。各ノードには、Kubernetes API Server、Scheduler、Controller Managerの各コンポーネントがインストールされます。 4 | 5 | ## 前提条件 6 | 7 | 本実習のコマンドは`controller-0`、`controller-1`、`controller-2`の各コントロールプレーン用インスタンスで実行する必要があります。`gcloud`コマンドを使用して各コントローラインスタンスにログインします。例: 8 | 9 | ``` 10 | gcloud compute ssh controller-0 11 | ``` 12 | 13 | ### tmuxを使った並列なコマンド実行 14 | 15 | [tmux](https://github.com/tmux/tmux/wiki)を使用すると複数のインスタンスで同時にコマンドを実行できます。前提条件の[tmuxを使った並列なコマンド実行](01-prerequisites.md#tmuxを使った並列なコマンド実行)セクションを参照してください。 16 | 17 | ## Kubernetesコントロールプレーンのプロビジョニング 18 | 19 | Kubenretesのコンフィグ用ディレクトリを作成します: 20 | 21 | ``` 22 | sudo mkdir -p /etc/kubernetes/config 23 | ``` 24 | 25 | ### Kubernetesコントローラー用バイナリーのダウンロードとインストール 26 | 27 | Kubernetesの公式リリースバイナリーをダウンロードします: 28 | 29 | ``` 30 | wget -q --show-progress --https-only --timestamping \ 31 | "https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/amd64/kube-apiserver" \ 32 | "https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/amd64/kube-controller-manager" \ 33 | "https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/amd64/kube-scheduler" \ 34 | "https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/amd64/kubectl" 35 | ``` 36 | 37 | Kubernetesバイナリーをインストールします: 38 | 39 | ``` 40 | { 41 | chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl 42 | sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/ 43 | } 44 | ``` 45 | 46 | ### Kubernetes APIサーバーの設定 47 | 48 | ``` 49 | { 50 | sudo mkdir -p /var/lib/kubernetes/ 51 | 52 | sudo mv ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \ 53 | service-account-key.pem service-account.pem \ 54 | encryption-config.yaml /var/lib/kubernetes/ 55 | } 56 | ``` 57 | 58 | クラスターのメンバーにAPIサーバーを通知するためにインスタンスの内部IPアドレスが使用されます。以下のコマンドで現在作業中のインスタンスが持つ内部IPアドレスを取得します: 59 | 60 | ``` 61 | INTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" \ 62 | http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip) 63 | ``` 64 | 65 | ``` 66 | REGION=$(curl -s -H "Metadata-Flavor: Google" \ 67 | http://metadata.google.internal/computeMetadata/v1/project/attributes/google-compute-default-region) 68 | ``` 69 | 70 | ``` 71 | KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \ 72 | --region $REGION \ 73 | --format 'value(address)') 74 | ``` 75 | 76 | systemdユニットファイル`kube-apiserver.service`を作成します: 77 | 78 | ```sh 79 | cat < KubernetesのAPIサーバーが完全に初期化されるまでには最大10秒かかります。 213 | 214 | ### HTTPのヘルスチェックを有効化 215 | 216 | [Google Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network)を使用して3つのAPIサーバーにトラフィックを分散し、各APIサーバーがTLS接続を終端してクライアント証明書を検証できるようにします。ネットワークロードバランサーは、HTTPヘルスチェックのみをサポートします。つまり、APIサーバーによって公開されたHTTPSエンドポイントは使用できません。回避策として、nginxを使用してHTTPのヘルスチェックをプロキシすることができます。本セクションではnginxをインストールし、ポート`80`でHTTPヘルスチェックを受け入れ、`https://127.0.0.1:6443/healthz` 上のAPIサーバへの接続をプロキシするように設定します。 217 | 218 | > APIサーバーエンドポイント`/healthz`は、デフォルトで認証を必要としません。 219 | 220 | HTTPヘルスチェックを処理するために基本的なWebサーバーをインストールします: 221 | 222 | ``` 223 | sudo apt-get update 224 | sudo apt-get install -y nginx 225 | ``` 226 | 227 | ```sh 228 | cat > kubernetes.default.svc.cluster.local < 上記のコマンドは各コントローラノード`controller-0`、`controller-1`、`controller-2`にて忘れずに実行してください。 290 | 291 | ## RBACを使ったKubeletの認可 292 | 293 | 本セクションでは、RBACのアクセス権を設定して、KubernetesのAPIサーバーが各ワーカーノード上のKubeletにアクセスできるようにします。メトリクスやログを取得したり、Pod内でコマンドを実行するためにはKubelet APIへのアクセスが必要です。 294 | 295 | > 本チュートリアルでは、Kubeletの`--authorization-mode`フラグを`Webhook`に設定します。Webhookモードでは、[SubjectAccessReview](https://kubernetes.io/docs/admin/authorization/#checking-api-access) APIを使用して認可を判定します。 296 | 297 | 本セクションのコマンドはクラスター全体に影響するため、1つのコントローラーノードから1回実行するだけで大丈夫です。 298 | 299 | ``` 300 | gcloud compute ssh controller-0 301 | ``` 302 | 303 | `system:kube-apiserver-to-kubelet`という名前の[ClusterRole](https://kubernetes.io/docs/admin/authorization/rbac/#role-and-clusterrole)を作成し、Kubelet APIにアクセスしたり、Podの管理に関連する一般的なタスクを実行したりするための権限を付与します: 304 | 305 | ```sh 306 | cat < 本チュートリアルで作成したインスタンスには、本セクションを完了する権限がありません。**インスタンスの作成に使用したのと同じ作業マシンから次のコマンドを実行します**。 356 | 357 | ### ネットワークロードバランサーのプロビジョニング 358 | 359 | 外部ロードバランサーネットワークリソースを作成します: 360 | 361 | ```sh 362 | { 363 | KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \ 364 | --region $(gcloud config get-value compute/region) \ 365 | --format 'value(address)') 366 | 367 | gcloud compute http-health-checks create kubernetes \ 368 | --description "Kubernetes Health Check" \ 369 | --host "kubernetes.default.svc.cluster.local" \ 370 | --request-path "/healthz" 371 | 372 | gcloud compute firewall-rules create kubernetes-the-hard-way-allow-health-check \ 373 | --network kubernetes-the-hard-way \ 374 | --source-ranges 209.85.152.0/22,209.85.204.0/22,35.191.0.0/16 \ 375 | --allow tcp 376 | 377 | gcloud compute target-pools create kubernetes-target-pool \ 378 | --http-health-check kubernetes 379 | 380 | gcloud compute target-pools add-instances kubernetes-target-pool \ 381 | --instances controller-0,controller-1,controller-2 382 | 383 | gcloud compute forwarding-rules create kubernetes-forwarding-rule \ 384 | --address ${KUBERNETES_PUBLIC_ADDRESS} \ 385 | --ports 6443 \ 386 | --region $(gcloud config get-value compute/region) \ 387 | --target-pool kubernetes-target-pool 388 | } 389 | ``` 390 | 391 | ### 検証 392 | 393 | > 本チュートリアルで作成したインスタンスには、本セクションを完了する権限がありません。**インスタンスの作成に使用したのと同じ作業マシンから次のコマンドを実行します**。 394 | 395 | 静的IPアドレス`kubernetes-the-hard-way`を取得します: 396 | 397 | ``` 398 | KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \ 399 | --region $(gcloud config get-value compute/region) \ 400 | --format 'value(address)') 401 | ``` 402 | 403 | Kubernetesのバージョン情報を取得するHTTPリクエストを発行します: 404 | 405 | ``` 406 | curl --cacert ca.pem https://${KUBERNETES_PUBLIC_ADDRESS}:6443/version 407 | ``` 408 | 409 | > 出力結果 410 | 411 | ```json 412 | { 413 | "major": "1", 414 | "minor": "21", 415 | "gitVersion": "v1.21.0", 416 | "gitCommit": "cb303e613a121a29364f75cc67d3d580833a7479", 417 | "gitTreeState": "clean", 418 | "buildDate": "2021-04-08T16:25:06Z", 419 | "goVersion": "go1.16.1", 420 | "compiler": "gc", 421 | "platform": "linux/amd64" 422 | } 423 | ``` 424 | 425 | Next: [Kubenretesワーカーノードのブートストラップ](09-bootstrapping-kubernetes-workers.md) 426 | -------------------------------------------------------------------------------- /docs/09-bootstrapping-kubernetes-workers.md: -------------------------------------------------------------------------------- 1 | # Kubenretesワーカーノードのブートストラップ 2 | 3 | 4 | 5 | 本実習では、3つのKubernetesワーカーノードをブートストラップします。各ノードには[runc](https://github.com/opencontainers/runc)、[CNI](https://github.com/containernetworking/cni), [containerd](https://github.com/containerd/containerd)、[kubelet](https://kubernetes.io/docs/admin/kubelet)および[kube-proxy](https://kubernetes.io/docs/concepts/cluster-administration/proxies)がインストールされます。 6 | 7 | ## 前提条件 8 | 9 | 本実習のコマンドは`worker-0`, `worker-1`, and `worker-2`の各ワーカーノード用インスタンスで実行する必要があります。`gcloud`コマンドを使用して各コントローラインスタンスにログインします。例: 10 | 11 | ``` 12 | gcloud compute ssh worker-0 13 | ``` 14 | 15 | ### tmuxを使った並列なコマンド実行 16 | 17 | [tmux](https://github.com/tmux/tmux/wiki)を使用すると複数のインスタンスで同時にコマンドを実行できます。前提条件の[tmuxを使った並列なコマンド実行](01-prerequisites.md#tmuxを使った並列なコマンド実行)セクションを参照してください。 18 | 19 | ## 単一Kubernetesワーカーノードのプロビジョニング 20 | 21 | OSの依存ライブラリをインストールします: 22 | 23 | ``` 24 | { 25 | sudo apt-get update 26 | sudo apt-get -y install socat conntrack ipset 27 | } 28 | ``` 29 | 30 | > socatバイナリーは`kubectl port-forward`コマンドのサポートを有効にします。 31 | 32 | ### Swapの無効化 33 | 34 | デフォルトで[swap](https://help.ubuntu.com/community/SwapFaq)が有効になっている場合、kubeletの起動は失敗します。Kubernetesが適切なリソース割り当てとサービス品質を提供できるように、swapを無効にすることを[推奨](https://github.com/kubernetes/kubernetes/issues/7294)します。 35 | 36 | swapが有効になっているか確認します: 37 | 38 | ``` 39 | sudo swapon --show 40 | ``` 41 | 42 | 出力が空の場合、swapは有効になっていません。有効になっている場合は、次のコマンドを実行してただちに無効にします: 43 | 44 | ``` 45 | sudo swapoff -a 46 | ``` 47 | 48 | > インスタンスの再起動後もswapがオフのままになるようにするには、Linuxディストリビューションのドキュメントを参照してください。 49 | 50 | ### ワーカーバイナリーのダウンロードとインストール 51 | 52 | ``` 53 | wget -q --show-progress --https-only --timestamping \ 54 | https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.21.0/crictl-v1.21.0-linux-amd64.tar.gz \ 55 | https://github.com/opencontainers/runc/releases/download/v1.0.0-rc93/runc.amd64 \ 56 | https://github.com/containernetworking/plugins/releases/download/v0.9.1/cni-plugins-linux-amd64-v0.9.1.tgz \ 57 | https://github.com/containerd/containerd/releases/download/v1.4.4/containerd-1.4.4-linux-amd64.tar.gz \ 58 | https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/amd64/kubectl \ 59 | https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/amd64/kube-proxy \ 60 | https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/amd64/kubelet 61 | ``` 62 | 63 | インストール用ディレクトリを作成します: 64 | 65 | ``` 66 | sudo mkdir -p \ 67 | /etc/cni/net.d \ 68 | /opt/cni/bin \ 69 | /var/lib/kubelet \ 70 | /var/lib/kube-proxy \ 71 | /var/lib/kubernetes \ 72 | /var/run/kubernetes 73 | ``` 74 | 75 | ワーカーバイナリーをインストールします: 76 | 77 | ``` 78 | { 79 | mkdir containerd 80 | tar -xvf crictl-v1.21.0-linux-amd64.tar.gz 81 | tar -xvf containerd-1.4.4-linux-amd64.tar.gz -C containerd 82 | sudo tar -xvf cni-plugins-linux-amd64-v0.9.1.tgz -C /opt/cni/bin/ 83 | sudo mv runc.amd64 runc 84 | chmod +x crictl kubectl kube-proxy kubelet runc 85 | sudo mv crictl kubectl kube-proxy kubelet runc /usr/local/bin/ 86 | sudo mv containerd/bin/* /bin/ 87 | } 88 | ``` 89 | 90 | ### CNIのネットワーク設定 91 | 92 | 現在作業中のインスタンスが持つPodのCIDR範囲を取得します: 93 | 94 | ``` 95 | POD_CIDR=$(curl -s -H "Metadata-Flavor: Google" \ 96 | http://metadata.google.internal/computeMetadata/v1/instance/attributes/pod-cidr) 97 | ``` 98 | 99 | ネットワーク構成ファイル`bridge`を作成します: 100 | 101 | ```sh 102 | cat < `resolvConf`の設定は、`system-resolved`を実行しているシステムのサービスディスカバリにCoreDNSを使用する場合に、ループを回避するために使用されます。 216 | 217 | systemdユニットファイル`kubelet.service`を作成します: 218 | 219 | ```sh 220 | cat < 上記のコマンドは各コントローラノード`worker-0`、`worker-1`、`worker-2`にて忘れずに実行してください。 294 | 295 | ## 検証 296 | 297 | > 本チュートリアルで作成したインスタンスには、本セクションを完了する権限がありません。インスタンスの作成に使用したのと同じ作業マシンから次のコマンドを実行します。 298 | 299 | 登録されたKubernetesのノード一覧を表示します: 300 | 301 | ``` 302 | gcloud compute ssh controller-0 \ 303 | --command "kubectl get nodes --kubeconfig admin.kubeconfig" 304 | ``` 305 | 306 | > 出力結果 307 | 308 | ``` 309 | NAME STATUS ROLES AGE VERSION 310 | worker-0 Ready 22s v1.21.0 311 | worker-1 Ready 22s v1.21.0 312 | worker-2 Ready 22s v1.21.0 313 | ``` 314 | 315 | Next: [リモートアクセス用のkubectl設定](10-configuring-kubectl.md) 316 | -------------------------------------------------------------------------------- /docs/10-configuring-kubectl.md: -------------------------------------------------------------------------------- 1 | # リモートアクセス用のkubectl設定 2 | 3 | 本実習では、`admin`ユーザーの認証情報に基づいた`kubectl`コマンド用のkubeconfigファイルを生成します。 4 | 5 | > 本実習で使用するコマンドは、管理クライアント証明書の生成に使用したディレクトリと同じディレクトリから実行してください。 6 | 7 | ## admin用Kubernetesコンフィグファイル 8 | 9 | kubeconfigには接続先のKubernetes APIサーバーが必要です。高可用性をサポートするために、Kubernetes APIサーバの前面に配置した外部ロードバランサに割り当てられたIPアドレスが使用されます。 10 | 11 | `admin`ユーザとして認証するのに適したkubeconfigファイルを生成します: 12 | 13 | ```sh 14 | { 15 | KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \ 16 | --region $(gcloud config get-value compute/region) \ 17 | --format 'value(address)') 18 | 19 | kubectl config set-cluster kubernetes-the-hard-way \ 20 | --certificate-authority=ca.pem \ 21 | --embed-certs=true \ 22 | --server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 23 | 24 | kubectl config set-credentials admin \ 25 | --client-certificate=admin.pem \ 26 | --client-key=admin-key.pem 27 | 28 | kubectl config set-context kubernetes-the-hard-way \ 29 | --cluster=kubernetes-the-hard-way \ 30 | --user=admin 31 | 32 | kubectl config use-context kubernetes-the-hard-way 33 | } 34 | ``` 35 | 36 | ## 検証 37 | 38 | リモートにあるKubernetesクラスターのバージョンを確認します: 39 | 40 | ``` 41 | kubectl version 42 | ``` 43 | 44 | > 出力結果 45 | 46 | ``` 47 | Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.0", GitCommit:"cb303e613a121a29364f75cc67d3d580833a7479", GitTreeState:"clean", BuildDate:"2021-04-08T16:31:21Z", GoVersion:"go1.16.1", Compiler:"gc", Platform:"linux/amd64"} 48 | Server Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.0", GitCommit:"cb303e613a121a29364f75cc67d3d580833a7479", GitTreeState:"clean", BuildDate:"2021-04-08T16:25:06Z", GoVersion:"go1.16.1", Compiler:"gc", Platform:"linux/amd64"} 49 | ``` 50 | 51 | リモートにあるKubernetesクラスター上にあるノードの一覧を表示します: 52 | 53 | ``` 54 | kubectl get nodes 55 | ``` 56 | 57 | > 出力結果 58 | 59 | ``` 60 | NAME STATUS ROLES AGE VERSION 61 | worker-0 Ready 2m35s v1.21.0 62 | worker-1 Ready 2m35s v1.21.0 63 | worker-2 Ready 2m35s v1.21.0 64 | ``` 65 | 66 | Next: [Podが使うネットワーク経路のプロビジョニング](11-pod-network-routes.md) 67 | -------------------------------------------------------------------------------- /docs/11-pod-network-routes.md: -------------------------------------------------------------------------------- 1 | # Podが使うネットワーク経路のプロビジョニング 2 | 3 | ノードにスケジュールされたPodは、ノードが持つPod CIDR範囲からIPアドレスを受け取ります。この時点ではネットワーク[経路](https://cloud.google.com/compute/docs/vpc/routes)が欠落しているため、Podは異なるノード上で動作している他のPodと通信できません。 4 | 5 | 本実習では、ノードのPod CIDR範囲をノードの内部IPアドレスにマップするための経路を各ワーカーノード上に作成します。 6 | 7 | > Kubernetesのネットワーキングモデルを実装する方法は[他にも](https://kubernetes.io/docs/concepts/cluster-administration/networking/#how-to-achieve-this)あります。 8 | 9 | ## ルーティングテーブル 10 | 11 | ここでは、`kubernetes-the-hard-way`VPCネットワーク上に経路を作成するために必要な情報を収集します。 12 | 13 | 各ワーカーインスタンスの内部IPアドレスとPod CIDR範囲を表示します: 14 | 15 | ```sh 16 | for instance in worker-{0..2}; do 17 | gcloud compute instances describe ${instance} \ 18 | --format 'value[separator=" "](networkInterfaces[0].networkIP,metadata.items[0].value)' 19 | done 20 | ``` 21 | 22 | > 出力結果 23 | 24 | ``` 25 | 10.240.0.20 10.200.0.0/24 26 | 10.240.0.21 10.200.1.0/24 27 | 10.240.0.22 10.200.2.0/24 28 | ``` 29 | 30 | ## 経路 31 | 32 | 各ワーカーインスタンス用のネットワーク経路を作成します: 33 | 34 | ```sh 35 | for i in 0 1 2; do 36 | gcloud compute routes create kubernetes-route-10-200-${i}-0-24 \ 37 | --network kubernetes-the-hard-way \ 38 | --next-hop-address 10.240.0.2${i} \ 39 | --destination-range 10.200.${i}.0/24 40 | done 41 | ``` 42 | 43 | VPCネットワーク`kubernetes-the-hard-way`内の経路一覧を表示します: 44 | 45 | ``` 46 | gcloud compute routes list --filter "network: kubernetes-the-hard-way" 47 | ``` 48 | 49 | > 出力結果 50 | 51 | ``` 52 | NAME NETWORK DEST_RANGE NEXT_HOP PRIORITY 53 | default-route-1606ba68df692422 kubernetes-the-hard-way 10.240.0.0/24 kubernetes-the-hard-way 0 54 | default-route-615e3652a8b74e4d kubernetes-the-hard-way 0.0.0.0/0 default-internet-gateway 1000 55 | kubernetes-route-10-200-0-0-24 kubernetes-the-hard-way 10.200.0.0/24 10.240.0.20 1000 56 | kubernetes-route-10-200-1-0-24 kubernetes-the-hard-way 10.200.1.0/24 10.240.0.21 1000 57 | kubernetes-route-10-200-2-0-24 kubernetes-the-hard-way 10.200.2.0/24 10.240.0.22 1000 58 | ``` 59 | 60 | Next: [DNSクラスターアドオンのデプロイ](12-dns-addon.md) 61 | -------------------------------------------------------------------------------- /docs/12-dns-addon.md: -------------------------------------------------------------------------------- 1 | # DNSクラスターアドオンのデプロイ 2 | 3 | 本実習では、[CoreDNS](https://coredns.io/)によってサポートされるDNSベースのサービスディスカバリを提供する[アドオン](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/)を、Kubernetesクラスター内で稼働するアプリケーションに導入します。 4 | 5 | ## The DNS Cluster Add-on 6 | 7 | クラスターアドオン`coredns`をデプロイします: 8 | 9 | ``` 10 | kubectl apply -f https://storage.googleapis.com/kubernetes-the-hard-way/coredns-1.8.yaml 11 | ``` 12 | 13 | > 出力結果 14 | 15 | ``` 16 | serviceaccount/coredns created 17 | clusterrole.rbac.authorization.k8s.io/system:coredns created 18 | clusterrolebinding.rbac.authorization.k8s.io/system:coredns created 19 | configmap/coredns created 20 | deployment.apps/coredns created 21 | service/kube-dns created 22 | ``` 23 | 24 | Deploymentリソース`kube-dns`によって作られたPodの一覧を表示します: 25 | 26 | ``` 27 | kubectl get pods -l k8s-app=kube-dns -n kube-system 28 | ``` 29 | 30 | > 出力結果 31 | 32 | ``` 33 | NAME READY STATUS RESTARTS AGE 34 | coredns-8494f9c688-hh7r2 1/1 Running 0 10s 35 | coredns-8494f9c688-zqrj2 1/1 Running 0 10s 36 | ``` 37 | 38 | ## 検証 39 | 40 | Deploymentリソース`busybox`をデプロイします: 41 | 42 | ``` 43 | kubectl run busybox --image=busybox:1.28 --command -- sleep 3600 44 | ``` 45 | 46 | Deploymentリソース`busybox`によって作られたPodの一覧を表示します: 47 | 48 | ``` 49 | kubectl get pods -l run=busybox 50 | ``` 51 | 52 | > 出力結果 53 | 54 | ``` 55 | NAME READY STATUS RESTARTS AGE 56 | busybox 1/1 Running 0 3s 57 | ``` 58 | 59 | Podリソース`busybox`のフルネームを取得します: 60 | 61 | ``` 62 | POD_NAME=$(kubectl get pods -l run=busybox -o jsonpath="{.items[0].metadata.name}") 63 | ``` 64 | 65 | `busybox`の中で`kubernetes`のサービスに対するDNSルックアップを実行します: 66 | 67 | ``` 68 | kubectl exec -ti $POD_NAME -- nslookup kubernetes 69 | ``` 70 | 71 | > 出力結果 72 | 73 | ``` 74 | Server: 10.32.0.10 75 | Address 1: 10.32.0.10 kube-dns.kube-system.svc.cluster.local 76 | 77 | Name: kubernetes 78 | Address 1: 10.32.0.1 kubernetes.default.svc.cluster.local 79 | ``` 80 | 81 | Next: [スモークテスト](13-smoke-test.md) 82 | -------------------------------------------------------------------------------- /docs/13-smoke-test.md: -------------------------------------------------------------------------------- 1 | # スモークテスト 2 | 3 | 本実習では、Kubernetesクラスターが正常に機能していることを確認するために必要な一連のタスクを実行します。 4 | 5 | ## データの暗号化 6 | 7 | 本セクションでは、[保存されている秘密データを暗号化する](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#verifying-that-data-is-encrypted)機能を確認します。 8 | 9 | 一般的なSecretデータを作成する: 10 | 11 | ``` 12 | kubectl create secret generic kubernetes-the-hard-way \ 13 | --from-literal="mykey=mydata" 14 | ``` 15 | 16 | etcdに保存されているsecretデータ`kubernets-the-hard-way`のhexdumpを表示します: 17 | 18 | ``` 19 | gcloud compute ssh controller-0 \ 20 | --command "sudo ETCDCTL_API=3 etcdctl get \ 21 | --endpoints=https://127.0.0.1:2379 \ 22 | --cacert=/etc/etcd/ca.pem \ 23 | --cert=/etc/etcd/kubernetes.pem \ 24 | --key=/etc/etcd/kubernetes-key.pem\ 25 | /registry/secrets/default/kubernetes-the-hard-way | hexdump -C" 26 | ``` 27 | 28 | > 出力結果 29 | 30 | ``` 31 | 00000000 2f 72 65 67 69 73 74 72 79 2f 73 65 63 72 65 74 |/registry/secret| 32 | 00000010 73 2f 64 65 66 61 75 6c 74 2f 6b 75 62 65 72 6e |s/default/kubern| 33 | 00000020 65 74 65 73 2d 74 68 65 2d 68 61 72 64 2d 77 61 |etes-the-hard-wa| 34 | 00000030 79 0a 6b 38 73 3a 65 6e 63 3a 61 65 73 63 62 63 |y.k8s:enc:aescbc| 35 | 00000040 3a 76 31 3a 6b 65 79 31 3a 97 d1 2c cd 89 0d 08 |:v1:key1:..,....| 36 | 00000050 29 3c 7d 19 41 cb ea d7 3d 50 45 88 82 a3 1f 11 |)<}.A...=PE.....| 37 | 00000060 26 cb 43 2e c8 cf 73 7d 34 7e b1 7f 9f 71 d2 51 |&.C...s}4~...q.Q| 38 | 00000070 45 05 16 e9 07 d4 62 af f8 2e 6d 4a cf c8 e8 75 |E.....b...mJ...u| 39 | 00000080 6b 75 1e b7 64 db 7d 7f fd f3 96 62 e2 a7 ce 22 |ku..d.}....b..."| 40 | 00000090 2b 2a 82 01 c3 f5 83 ae 12 8b d5 1d 2e e6 a9 90 |+*..............| 41 | 000000a0 bd f0 23 6c 0c 55 e2 52 18 78 fe bf 6d 76 ea 98 |..#l.U.R.x..mv..| 42 | 000000b0 fc 2c 17 36 e3 40 87 15 25 13 be d6 04 88 68 5b |.,.6.@..%.....h[| 43 | 000000c0 a4 16 81 f6 8e 3b 10 46 cb 2c ba 21 35 0c 5b 49 |.....;.F.,.!5.[I| 44 | 000000d0 e5 27 20 4c b3 8e 6b d0 91 c2 28 f1 cc fa 6a 1b |.' L..k...(...j.| 45 | 000000e0 31 19 74 e7 a5 66 6a 99 1c 84 c7 e0 b0 fc 32 86 |1.t..fj.......2.| 46 | 000000f0 f3 29 5a a4 1c d5 a4 e3 63 26 90 95 1e 27 d0 14 |.)Z.....c&...'..| 47 | 00000100 94 f0 ac 1a cd 0d b9 4b ae 32 02 a0 f8 b7 3f 0b |.......K.2....?.| 48 | 00000110 6f ad 1f 4d 15 8a d6 68 95 63 cf 7d 04 9a 52 71 |o..M...h.c.}..Rq| 49 | 00000120 75 ff 87 6b c5 42 e1 72 27 b5 e9 1a fe e8 c0 3f |u..k.B.r'......?| 50 | 00000130 d9 04 5e eb 5d 43 0d 90 ce fa 04 a8 4a b0 aa 01 |..^.]C......J...| 51 | 00000140 cf 6d 5b 80 70 5b 99 3c d6 5c c0 dc d1 f5 52 4a |.m[.p[.<.\....RJ| 52 | 00000150 2c 2d 28 5a 63 57 8e 4f df 0a |,-(ZcW.O..| 53 | 0000015a 54 | ``` 55 | 56 | etcd上のキーのプレフィックスには`k8s:enc:aescbc:v1:key1`が付いているはずです。これは、`aescbc`プロバイダが暗号化されたキー`key1`のデータを暗号化するために使用されたことを示します。 57 | 58 | ## Deployment 59 | 60 | 本セクションでは、[Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)を作成および管理する機能を確認します。 61 | 62 | [nginx](https://nginx.org/en/)のDeploymentを作成します: 63 | 64 | ``` 65 | kubectl create deployment nginx --image=nginx 66 | ``` 67 | 68 | Deploymentリソース`nginx`によって作られたPodの一覧を表示します: 69 | 70 | ``` 71 | kubectl get pods -l app=nginx 72 | ``` 73 | 74 | > 出力結果 75 | 76 | ``` 77 | NAME READY STATUS RESTARTS AGE 78 | nginx-f89759699-kpn5m 1/1 Running 0 10s 79 | ``` 80 | 81 | ### ポート転送 82 | 83 | 本セクションでは、[ポート転送](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/)を使用してアプリケーションにリモートでアクセスする機能を確認します。 84 | 85 | Podリソース`nginx`のフルネームを取得します: 86 | 87 | ``` 88 | POD_NAME=$(kubectl get pods -l app=nginx -o jsonpath="{.items[0].metadata.name}") 89 | ``` 90 | 91 | `nginx`Podの`80`番ポートを、手元のマシンの`8080`番ポートに転送します: 92 | 93 | ```sh 94 | kubectl port-forward $POD_NAME 8080:80 95 | ``` 96 | 97 | > 出力結果 98 | 99 | ``` 100 | Forwarding from 127.0.0.1:8080 -> 80 101 | Forwarding from [::1]:8080 -> 80 102 | ``` 103 | 104 | 新しいターミナルを開き、転送済アドレスを使ってHTTPリクエストを発行します: 105 | 106 | ``` 107 | curl --head http://127.0.0.1:8080 108 | ``` 109 | 110 | > 出力結果 111 | 112 | ``` 113 | HTTP/1.1 200 OK 114 | Server: nginx/1.19.10 115 | Date: Sun, 02 May 2021 05:29:25 GMT 116 | Content-Type: text/html 117 | Content-Length: 612 118 | Last-Modified: Tue, 13 Apr 2021 15:13:59 GMT 119 | Connection: keep-alive 120 | ETag: "6075b537-264" 121 | Accept-Ranges: bytes 122 | ``` 123 | 124 | 前のターミナルに戻り、`nginx`Podへのポート転送を停止します: 125 | 126 | ``` 127 | Forwarding from 127.0.0.1:8080 -> 80 128 | Forwarding from [::1]:8080 -> 80 129 | Handling connection for 8080 130 | ^C 131 | ``` 132 | 133 | ### ログ 134 | 135 | 本セクションでは、[コンテナのログを取得](https://kubernetes.io/docs/concepts/cluster-administration/logging/)する機能を確認します。 136 | 137 | `nginx`Podのログを表示します: 138 | 139 | ```sh 140 | kubectl logs $POD_NAME 141 | ``` 142 | 143 | > 出力結果 144 | 145 | ``` 146 | ... 147 | 127.0.0.1 - - [02/May/2021:05:29:25 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.64.0" "-" 148 | ``` 149 | 150 | ### コマンドの実行 151 | 152 | 本セクションでは、[コンテナ内でコマンドが実行できる](https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/#running-individual-commands-in-a-container)ことを確認します。 153 | 154 | `nginx`コンテナで`nginx-v`コマンドを実行して、nginxバージョンを表示します: 155 | 156 | ```sh 157 | kubectl exec -ti $POD_NAME -- nginx -v 158 | ``` 159 | 160 | > 出力結果 161 | 162 | ``` 163 | nginx version: nginx/1.19.10 164 | ``` 165 | 166 | ## サービス 167 | 168 | 本セクションでは、[サービス](https://kubernetes.io/docs/concepts/services-networking/service/)を使用してアプリケーションを公開する機能を確認します。 169 | 170 | [NodePort](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport)サービスを使用して`nginx`のDeploymentを公開します。 171 | 172 | ``` 173 | kubectl expose deployment nginx --port 80 --type NodePort 174 | ``` 175 | 176 | >クラスターが[クラウドプロバイダーインテグレーション](https://kubernetes.io/docs/getting-started-guides/scratch/#cloud-provider)で構成されていないため、サービスのtype:LoadBalancerを使用できません。クラウドプロバイダーインテグレーションのセットアップについては本チュートリアルの対象外です。 177 | 178 | `nginx`サービスに割り当てられたノード上のポートを取得します: 179 | 180 | ``` 181 | NODE_PORT=$(kubectl get svc nginx \ 182 | --output=jsonpath='{range .spec.ports[0]}{.nodePort}') 183 | ``` 184 | 185 | `nginx`のノードポートへのアクセスを許可するファイアウォールルールを作成します: 186 | 187 | ```sh 188 | gcloud compute firewall-rules create kubernetes-the-hard-way-allow-nginx-service \ 189 | --allow=tcp:${NODE_PORT} \ 190 | --network kubernetes-the-hard-way 191 | ``` 192 | 193 | ワーカーインスタンスの外部IPアドレスを取得します: 194 | 195 | ``` 196 | EXTERNAL_IP=$(gcloud compute instances describe worker-0 \ 197 | --format 'value(networkInterfaces[0].accessConfigs[0].natIP)') 198 | ``` 199 | 200 | 取得した外部IPアドレスと`nginx`のノードポートを使ってHTTPリクエストを発行します: 201 | 202 | ```sh 203 | curl -I http://${EXTERNAL_IP}:${NODE_PORT} 204 | ``` 205 | 206 | > 出力結果 207 | 208 | ``` 209 | HTTP/1.1 200 OK 210 | Server: nginx/1.19.10 211 | Date: Sun, 02 May 2021 05:31:52 GMT 212 | Content-Type: text/html 213 | Content-Length: 612 214 | Last-Modified: Tue, 13 Apr 2021 15:13:59 GMT 215 | Connection: keep-alive 216 | ETag: "6075b537-264" 217 | Accept-Ranges: bytes 218 | ``` 219 | 220 | Next: [お掃除](14-cleanup.md) 221 | -------------------------------------------------------------------------------- /docs/14-cleanup.md: -------------------------------------------------------------------------------- 1 | # お掃除 2 | 3 | 本実習では、チュートリアルで作成した計算資源を削除します。 4 | 5 | ## Compute Instances 6 | 7 | コントロールプレーン及びワーカーノード用に作成したインスタンスを削除します: 8 | 9 | ``` 10 | gcloud -q compute instances delete \ 11 | controller-0 controller-1 controller-2 \ 12 | worker-0 worker-1 worker-2 \ 13 | --zone $(gcloud config get-value compute/zone) 14 | ``` 15 | 16 | ## ネットワーク 17 | 18 | 外部ロードバランサーリソースを削除します: 19 | 20 | ``` 21 | { 22 | gcloud -q compute forwarding-rules delete kubernetes-forwarding-rule \ 23 | --region $(gcloud config get-value compute/region) 24 | 25 | gcloud -q compute target-pools delete kubernetes-target-pool 26 | 27 | gcloud -q compute http-health-checks delete kubernetes 28 | 29 | gcloud -q compute addresses delete kubernetes-the-hard-way 30 | } 31 | ``` 32 | 33 | ファイアウォールルール`kubernetes-the-hard-way`を削除します: 34 | 35 | ``` 36 | gcloud -q compute firewall-rules delete \ 37 | kubernetes-the-hard-way-allow-nginx-service \ 38 | kubernetes-the-hard-way-allow-internal \ 39 | kubernetes-the-hard-way-allow-external \ 40 | kubernetes-the-hard-way-allow-health-check 41 | ``` 42 | 43 | ネットワークVPC`kubernetes-the-hard-way`を削除します: 44 | 45 | ``` 46 | { 47 | gcloud -q compute routes delete \ 48 | kubernetes-route-10-200-0-0-24 \ 49 | kubernetes-route-10-200-1-0-24 \ 50 | kubernetes-route-10-200-2-0-24 51 | 52 | gcloud -q compute networks subnets delete kubernetes 53 | 54 | gcloud -q compute networks delete kubernetes-the-hard-way 55 | } 56 | ``` 57 | 58 | compute address用に確保した`kubernetes-the-hard-way`を削除します: 59 | 60 | ``` 61 | gcloud -q compute addresses delete kubernetes-the-hard-way \ 62 | --region $(gcloud config get-value compute/region) 63 | ``` -------------------------------------------------------------------------------- /docs/images/tmux-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inductor/kubernetes-the-hard-way/74dfa54ba52cad888b4a64958f1a6d541f8bd35c/docs/images/tmux-screenshot.png --------------------------------------------------------------------------------