GDG Cloud KH Meetup #4 - 給 RD 的 Kubernetes 初體驗 === ###### tags: `GDG-Cloud-KH` `K8S` :::info - **Event:** - https://www.meetup.com/GCPUG-Kaohsiung/events/262412299/ - **Slide:** - https://www.slideshare.net/williamyeh/rd-kubernetes-gdg-cloud-kh-201908-version - **Sample project:** - https://github.com/William-Yeh/workshop-k8s201908 - **WiFi**: - AP: `GCPUG-KH` - password: `gcpug-kh-2019` ::: * 今日的優惠碼,是給已沒有免費額度的人使用,若是新申請的使用者,會有 GCP 新用戶的免費額度可用。 * Google Cloud 中文開發社群的 Telegram 群組 - https://t.me/googlecloudzhug * 請大家一張桌子至少坐 2 個人,這樣過程中有問題時,還有隔壁的伙伴可以討論。 前言 --- ### Agenda 1. Containers 2. Kubernetes 3. Cloud (Use the Kubernetes in Cloud) ### Goals 1. Kubernetes promising trends (賣點在哪?) 1. Adopt gradually 1. Prepare mindset ### GKE Setup 1. Redeem Google Cloud coupon 1. Create project in GCP 1. ## Redeem Google Cloud coupon Please reference the workflow on paper. > cloud.google.com/redeem --- ## Create K8s-enabled Project 1. Go to the "Kubernetes Engine". > https://console.cloud.google.com/projectselector2/kubernetes ![](https://i.imgur.com/hW7OFPk.png) 1. 建立一個新專案 (或選取之前建立好的專案)。 ![](https://i.imgur.com/BpT8KWi.png) 1. 確定專案名稱是否是剛剛選取的名稱。 ![](https://i.imgur.com/X24nsYt.png) ## 1. 啟動 Cloud Shell (1/2)。 ![](https://i.imgur.com/zTC4ZTC.png) 1. 啟動 Cloud Shell (2/2)。 ![](https://i.imgur.com/frmcOtP.png) 1. Get the **project ID**. > my-gke-lab1 ![](https://i.imgur.com/BpT8KWi.png) ### Key in some commands 1. gcloud config set project <PROJECT_ID> ``` chusiang_lai@cloudshell:~ (my-gke-lab1)$ gcloud config set project my-gke-lab1 Updated property [core/project]. ``` 1. gcloud config set compute/zone us-west1-a ``` chusiang_lai@cloudshell:~ (my-gke-lab1)$ gcloud config set compute/zone us-west1-a Updated property [compute/zone]. ``` 1. gcloud container clusters create k8s201908 --num-nodes 3 ``` chusiang_lai@cloudshell:~ (my-gke-lab1)$ gcloud container clusters create k8s201908 --num-nodes 3 WARNING: In June 2019, node auto-upgrade will be enabled by default for newly created clusters and node pools. To disable it, use the `--no-enable-autoupgrade` flag. WARNING: Starting in 1.12, new clusters will have basic authentication disabled by default. Basic authentication can be enabled (or disabled) manually using the `--[no-]enable-basic-auth` flag. WARNING: Starting in 1.12, new clusters will not have a client certificate issued. You can manually enable (or disable) the issuance of the client certificate u sing the `--[no-]issue-client-certificate` flag. WARNING: Currently VPC-native is not the default mode during cluster creation. In the future, this will become the default mode and can be disabled using `--no- enable-ip-alias` flag. Use `--[no-]enable-ip-alias` flag to suppress this warning. WARNING: Starting in 1.12, default node pools in new clusters will have their legacy Compute Engine instance metadata endpoints disabled by default. To create a cluster with legacy instance metadata endpoints disabled in the default node pool, run `clusters create` with the flag `--metadata disable-legacy-endpoints=tru e`. WARNING: Your Pod address range (`--cluster-ipv4-cidr`) can accommodate at most 1008 node(s). This will enable the autorepair feature for nodes. Please see https://cloud.google.com/kubernetes-engine/docs/node-auto-repair for more information on node auto repairs. Creating cluster k8s201908 in us-west1-a... Cluster is being deployed...⠏ ``` (Back to slides ...) ## Get example code 1. Go to the https://github.com/William-Yeh/workshop-k8s201908 . 1. Clone example project. ``` $ git clone https://github.com/William-Yeh/workshop-k8s201908.git ``` ## Lab # 1.0 1. C# 1. MVC ## Lab # 2.0 1. Add a Dockerfile. ## Lab # 3.0 1. 前後端分離。 1. 前端 30000 port、後端 30080 port。 1. Checkout to 3.0 tag. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 2.0)) - 14:48 (cmd)$ git checkout 3.0 Previous HEAD position was 89f2e7f 2.0: Dockerize the app with simple Dockerfile and docker-compose.yml. HEAD is now at f7dc3e4 3.0: Separate frontend and backend into 2 distinct containers. ``` 1. Review files. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 3.0)) - 14:48 (ins)$ tree . . ├── LICENSE ├── README.md ├── TodoApi │   ├── Controllers │   │   └── TodoController.cs │   ├── Dockerfile │   ├── LICENSE │   ├── Models │   │   ├── TodoContext.cs │   │   └── TodoItem.cs │   ├── Program.cs │   ├── Startup.cs │   ├── TodoApi.csproj │   ├── appsettings.Development.json │   └── appsettings.json ├── TodoApi-original.zip ├── TodoFrontend │   ├── Dockerfile │   ├── index.html │   ├── jquery-3.3.1.min.js │   └── site.js └── docker-compose.yml 4 directories, 18 files ``` 1. Run containers. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 3.0)) - 14:48 (ins)$ docker-compose up -d Creating network "workshop-k8s201908_default" with the default driver Building todo-api Step 1/13 : FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build ---> 3af77ac73731 Step 2/13 : WORKDIR /app ---> Running in f430e0b20b52 Removing intermediate container f430e0b20b52 ---> 8b7149f6bdcd Step 3/13 : COPY *.csproj . ---> a349dbb180b8 Step 4/13 : RUN dotnet restore ---> Running in ada285379fba Restore completed in 3.65 sec for /app/TodoApi.csproj. Removing intermediate container ada285379fba ---> e638dde0c78d Step 5/13 : COPY . . ---> 832aa52eb047 Step 6/13 : RUN dotnet publish -o out ---> Running in 0541629e4e1d Microsoft (R) Build Engine version 16.2.32702+c4012a063 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 61.12 ms for /app/TodoApi.csproj. TodoApi -> /app/bin/Debug/netcoreapp2.2/TodoApi.dll TodoApi -> /app/out/ Removing intermediate container 0541629e4e1d ---> ea17fcdd991a Step 7/13 : FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime ---> 3ee0429b27ad Step 8/13 : LABEL maintainer="william.pjyeh@gmail.com" ---> Running in 4eaf3256b79f Removing intermediate container 4eaf3256b79f ---> b4a4070d93e4 Step 9/13 : ENV ASPNETCORE_URLS http://+:80 ---> Running in 19a4868bcb30 Removing intermediate container 19a4868bcb30 ---> 9a64e28f467f Step 10/13 : EXPOSE 80 ---> Running in 5c3038f9097c Removing intermediate container 5c3038f9097c ---> 38331774d119 Step 11/13 : WORKDIR /app ---> Running in 9e33aaeb1e01 Removing intermediate container 9e33aaeb1e01 ---> f0bb3fb67cc4 Step 12/13 : COPY --from=build /app/out ./ ---> 69a3362e64c2 Step 13/13 : ENTRYPOINT ["dotnet", "TodoApi.dll"] ---> Running in 4fd7f7a5be59 Removing intermediate container 4fd7f7a5be59 ---> 6e5ddb8f2e3f Successfully built 6e5ddb8f2e3f Successfully tagged todoapi:3.0 WARNING: Image for service todo-api was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Building todo Step 1/5 : FROM busybox:1.30 1.30: Pulling from library/busybox 53071b97a884: Pull complete Digest: sha256:4b6ad3a68d34da29bf7c8ccb5d355ba8b4babcad1f99798204e7abb43e54ee3d Status: Downloaded newer image for busybox:1.30 ---> 64f5d945efcc Step 2/5 : WORKDIR /app ---> Running in 0ae754b31362 Removing intermediate container 0ae754b31362 ---> 169cf1e37654 Step 3/5 : COPY . . ---> b3accd7b6ee3 Step 4/5 : EXPOSE 80 ---> Running in b67f2f80d0f3 Removing intermediate container b67f2f80d0f3 ---> fdb878c03886 Step 5/5 : CMD ["busybox", "httpd", "-f", "-p", "80"] ---> Running in e901359151a3 Removing intermediate container e901359151a3 ---> 524f3da6f6df Successfully built 524f3da6f6df Successfully tagged todofrontend:3.0 WARNING: Image for service todo was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Creating workshop-k8s201908_todo-api_1 ... done Creating workshop-k8s201908_todo_1 ... done [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 3.0)) - 14:49 (ins)$ ``` 1. Remove current containers. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 3.0)) - 14:54 (ins)$ docker-compose stop Stopping workshop-k8s201908_todo_1 ... done Stopping workshop-k8s201908_todo-api_1 ... done ``` ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 3.0)) - 14:54 (ins)$ docker-compose rm -f Going to remove workshop-k8s201908_todo_1, workshop-k8s201908_todo-api_1 Removing workshop-k8s201908_todo_1 ... done Removing workshop-k8s201908_todo-api_1 ... done ``` ### Lab # 3.0 Review 1. Architecture 1. Main tasks 1. Diff 1. Tricks 1. Quexxxxx ## Lab # 4.0 Local Kubernetes 1. git checkout 4.0 ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 3.0)) - 15:11 (ins)$ git checkout 4.0 Previous HEAD position was f7dc3e4 3.0: Separate frontend and backend into 2 distinct containers. HEAD is now at 3a3502b 4.0: Support Kubernetes (locally). [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:11 (ins)$ ``` 1. git log ``` commit 3a3502b1ab772c9d5618f7142266371887cae124 (HEAD, tag: 4.0) Author: William Yeh <william.pjyeh@gmail.com> Date: Wed Jul 10 11:15:57 2019 +0800 4.0: Support Kubernetes (locally). commit f7dc3e4f11af64d9ec5c7a3ad248b18ff9853cad (tag: 3.0) Author: William Yeh <william.pjyeh@gmail.com> Date: Wed Jul 10 11:14:48 2019 +0800 3.0: Separate frontend and backend into 2 distinct containers. commit 89f2e7f76760257854aab0b1a0248e9fedee5f39 (tag: 2.0) Author: William Yeh <william.pjyeh@gmail.com> Date: Wed Jul 10 11:13:54 2019 +0800 2.0: Dockerize the app with simple Dockerfile and docker-compose.yml. commit 64b77d3322668f21c64a5d387d7dd2a4b68ebd0e (tag: 1.0) Author: William Yeh <william.pjyeh@gmail.com> Date: Wed Jul 10 11:12:29 2019 +0800 : ``` 1. git diff --stat HEAD~1 HEAD ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:13 (ins)$ git diff --stat HEAD~1 HEAD README.md | 40 ++++++++++++++++--- k8s-dashboard.md | 38 ++++++++++++++++++ k8s/kubernetes-dashboard.yaml | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ k8s/todoapi-service.yml | 52 +++++++++++++++++++++++++ k8s/todofrontend-service.yml | 52 +++++++++++++++++++++++++ 5 files changed, 338 insertions(+), 6 deletions(-) [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:13 (ins)$ ``` 1. Review todofrontend-service.yml Container: 將許多服務包進同一個容器中 kubernetes 架構: * Service * Deployment * Pod: 把多個 containers 綁在同個 IP、主機上。常見的例子有: * Backend service + redis。 * Nginx + uWSGI + ... * Container > 奇數選舉策略:最少一定要有 3 個 ``` --- # 對應的版號。 apiVersion: v1 # 對應 K8s 的 Service 或 Deployment。 kind: Service # => Service # 描述。 metadata: name: todofrontend labels: app: todo tier: frontend # 真正的核心。 spec: type: NodePort ports: - port: 80 nodePort: 30000 selector: app: todo tier: frontend --- apiVersion: apps/v1 kind: Deployment # ==> Deployment metadata: name: todofrontend labels: app: todo tier: frontend spec: replicas: 3 selector: matchLabels: app: todo tier: frontend strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 1 type: RollingUpdate template: # pod definition # ===> pod metadata: labels: app: todo tier: frontend spec: containers: # ====> container - name: todofrontend image: todofrontend:3.0 imagePullPolicy: IfNotPresent ports: - containerPort: 80 #dnsPolicy: ClusterFirst #restartPolicy: Always ``` ### Deployment & Replica > Replicas = 3 1. Deployment 包含 Pod 和 container。 1. Pod 包含 container。 ### Make sure you're using local Kubernetes > https://github.com/William-Yeh/workshop-k8s201908/tree/4.0 1. kubectl config view ### Lab start Create todo. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:40 (ins)$ kubectl create ns todo namespace/todo created ``` Get status. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:40 (cmd)$ kubectl get ns NAME STATUS AGE default Active 19m kube-node-lease Active 20m kube-public Active 20m kube-system Active 20m todo Active 36s ``` #### Build ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:41 (ins)$ docker-compose build Building todo-api Step 1/13 : FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build ---> 3af77ac73731 Step 2/13 : WORKDIR /app ---> Running in 0dd4ba363418 Removing intermediate container 0dd4ba363418 ---> a7e67b42ca56 Step 3/13 : COPY *.csproj . ---> 7dcba74980a0 Step 4/13 : RUN dotnet restore ---> Running in fc08f13bae4c Restore completed in 996.91 ms for /app/TodoApi.csproj. Removing intermediate container fc08f13bae4c ---> 121cf4a9687b Step 5/13 : COPY . . ---> 78d96bf15d59 Step 6/13 : RUN dotnet publish -o out ---> Running in 52a9ff3b903a Microsoft (R) Build Engine version 16.2.32702+c4012a063 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 63.2 ms for /app/TodoApi.csproj. TodoApi -> /app/bin/Debug/netcoreapp2.2/TodoApi.dll TodoApi -> /app/out/ Removing intermediate container 52a9ff3b903a ---> 60b5a1d8b0e4 Step 7/13 : FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime ---> 3ee0429b27ad Step 8/13 : LABEL maintainer="william.pjyeh@gmail.com" ---> Running in 215d38d42979 Removing intermediate container 215d38d42979 ---> 0881e064ebd7 Step 9/13 : ENV ASPNETCORE_URLS http://+:80 ---> Running in 16c32079f774 Removing intermediate container 16c32079f774 ---> 4a488a38ad7a Step 10/13 : EXPOSE 80 ---> Running in 872944d628dc Removing intermediate container 872944d628dc ---> 7a4504f487e4 Step 11/13 : WORKDIR /app ---> Running in 7d312d731af2 Removing intermediate container 7d312d731af2 ---> 2a1ce265ad47 Step 12/13 : COPY --from=build /app/out ./ ---> 60241e9eb65a Step 13/13 : ENTRYPOINT ["dotnet", "TodoApi.dll"] ---> Running in 804aa3123794 Removing intermediate container 804aa3123794 ---> e62cc653f93a Successfully built e62cc653f93a Successfully tagged todoapi:3.0 Building todo Step 1/5 : FROM busybox:1.30 1.30: Pulling from library/busybox 53071b97a884: Pull complete Digest: sha256:4b6ad3a68d34da29bf7c8ccb5d355ba8b4babcad1f99798204e7abb43e54ee3d Status: Downloaded newer image for busybox:1.30 ---> 64f5d945efcc Step 2/5 : WORKDIR /app ---> Running in c09d9fb7e8ea Removing intermediate container c09d9fb7e8ea ---> 11e21cf61811 Step 3/5 : COPY . . ---> e74c99765c36 Step 4/5 : EXPOSE 80 ---> Running in 30041ed33d2c Removing intermediate container 30041ed33d2c ---> 1af64117bba0 Step 5/5 : CMD ["busybox", "httpd", "-f", "-p", "80"] ---> Running in 7cf678322ccd Removing intermediate container 7cf678322ccd ---> 2ae4f98e0e80 Successfully built 2ae4f98e0e80 Successfully tagged todofrontend:3.0 [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:42 ``` Before run, we can review pods status of default pool. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:43 (ins)$ kubectl get pods No resources found. ``` Before run, we can review pods status of todo pool. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:43 (ins)$ kubectl get pods -n todo No resources found. ``` Before run, we can review deployment status of todo pool. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:44 (cmd)$ kubectl get deploy -n todo No resources found. ``` #### Run apply todoapi-service to todo pool. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:42 (ins)$ kubectl apply -f k8s/todoapi-service.yml -n todo service/todoapi created deployment.apps/todoapi created ``` ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:45 (ins)$ kubectl get svc -n todo NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE todoapi NodePort 10.101.6.95 <none> 80:30080/TCP 3m50s ``` ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:49 (ins)$ kubectl get deploy -n todo NAME READY UP-TO-DATE AVAILABLE AGE todoapi 0/3 3 0 5m47s ``` ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:50 (ins)$ kubectl get pods -n todo NAME READY STATUS RESTARTS AGE todoapi-7c5c486947-5tw6t 0/1 ImagePullBackOff 0 6m34s todoapi-7c5c486947-rz7h2 0/1 ErrImagePull 0 6m34s todoapi-7c5c486947-z5wgk 0/1 ImagePullBackOff 0 6m34s ``` Try to delete one pod. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:50 (ins)$ kubectl delete pods todoapi-7c5c486947-rz7h2 -n todo pod "todoapi-7c5c486947-rz7h2" deleted [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:51 (cmd)$ kubectl get pods -n todo NAME READY STATUS RESTARTS AGE todoapi-7c5c486947-5tw6t 0/1 ImagePullBackOff 0 7m18s todoapi-7c5c486947-wz2tj 0/1 ErrImagePull 0 7s todoapi-7c5c486947-z5wgk 0/1 ImagePullBackOff 0 7m18s [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:51 (ins)$ ``` ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:51 (ins)$ kubectl apply -f k8s/todofrontend-service.yml -n todo service/todofrontend created deployment.apps/todofrontend created ``` ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 15:51 (cmd)$ kubectl get svc -n todo NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE todoapi NodePort 10.101.6.95 <none> 80:30080/TCP 9m todofrontend NodePort 10.99.135.208 <none> 80:30000/TCP 54s ``` 1. 如有安裝 minikube,記得切回 docker-desktop! ![](https://i.imgur.com/dUztGDK.png) 1. Get api status via curl. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 16:10 (cmd)$ curl http://localhost:30080/api/todo [{"id":1,"name":"Item1","isComplete":false}][ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 16:10 (cmd)$ curl http://localhost:30080/api/todo [{"id":1,"name":"Item1","isComplete":false}][ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 16:10 (cmd)$ curl http://localhost:30080/api/todo [{"id":1,"name":"Item1","isComplete":false}][ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 16:10 (cmd)$ curl http://localhost:30080/api/todo [{"id":1,"name":"Item1","isComplete":false}][ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 16:10 (cmd)$ curl http://localhost:30080/api/todo [{"id":1,"name":"Item1","isComplete":false}][ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 16:10 (ins)$ ``` ## Lab # 5.0 > https://github.com/William-Yeh/workshop-k8s201908/tree/5.0 1. Checkout to 5.0 tag. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 4.0)) - 16:15 (cmd)$ git checkout 5.0 Previous HEAD position was 3a3502b 4.0: Support Kubernetes (locally). HEAD is now at 47f84f0 5.0: Support ConfigMap and naming convention. ``` 1. Remove todo namespace of 4.0 Lab. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 5.0)) - 16:15 (ins)$ kubectl delete ns todo namespace "todo" deleted ``` 1. Review changes. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 5.0)) - 16:19 (ins)$ git diff --stat HEAD~1 HEAD README.md | 41 +++++++++++++++++++++++++++++++---------- TodoFrontend/Dockerfile | 11 ++++++++++- TodoFrontend/run.sh | 16 ++++++++++++++++ TodoFrontend/site.js | 2 +- docker-compose.yml | 2 +- k8s/config.local.yml | 9 +++++++++ k8s/todofrontend-service.yml | 14 ++++++++++++-- 7 files changed, 80 insertions(+), 15 deletions(-) ``` > TodoFrontend 的部分將 Dockerfile 的 CMD 改為執行 `run.sh` 這個 [shell script](https://github.com/William-Yeh/workshop-k8s201908/blob/5.0/TodoFrontend/run.sh) ,主要的目的為取代程式碼中的環境變數 * Replace with `sed`: `{{xxx}}` -> $xxx ### Preparation 1. Create the **todo** namespace. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 5.0)) - 16:19 (ins)$ kubectl create ns todo namespace/todo created ``` 1. foo ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 5.0)) - 16:25 (ins)$ kubectl apply -f k8s/config.local.yml -n todo configmap/config.local created ``` 1. foo ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 5.0)) - 16:25 (ins)$ kubectl get configmaps -n todo NAME DATA AGE config.local 3 37s ``` ### Build Build new 5.0 image. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 5.0)) - 1 (ins)$ docker-compose build Building todo-api Step 1/13 : FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build ---> 3af77ac73731 Step 2/13 : WORKDIR /app ---> Using cache ---> a7e67b42ca56 Step 3/13 : COPY *.csproj . ---> Using cache ---> 7dcba74980a0 Step 4/13 : RUN dotnet restore ---> Using cache ---> 121cf4a9687b Step 5/13 : COPY . . ---> Using cache ---> 78d96bf15d59 Step 6/13 : RUN dotnet publish -o out ---> Using cache ---> 60b5a1d8b0e4 Step 7/13 : FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime ---> 3ee0429b27ad Step 8/13 : LABEL maintainer="william.pjyeh@gmail.com" ---> Using cache ---> 0881e064ebd7 Step 9/13 : ENV ASPNETCORE_URLS http://+:80 ---> Using cache ---> 4a488a38ad7a Step 10/13 : EXPOSE 80 ---> Using cache ---> 7a4504f487e4 Step 11/13 : WORKDIR /app ---> Using cache ---> 2a1ce265ad47 Step 12/13 : COPY --from=build /app/out ./ ---> Using cache ---> 60241e9eb65a Step 13/13 : ENTRYPOINT ["dotnet", "TodoApi.dll"] ---> Using cache ---> e62cc653f93a Successfully built e62cc653f93a Successfully tagged todoapi:3.0 Building todo Step 1/8 : FROM busybox:1.30 ---> 64f5d945efcc Step 2/8 : WORKDIR /app ---> Using cache ---> 11e21cf61811 Step 3/8 : COPY . . ---> 98be11d67ac1 Step 4/8 : RUN chmod +x run.sh ---> Running in 85c55155993a Removing intermediate container 85c55155993a ---> 8e7c83565fbb Step 5/8 : ENV TODOAPI_HOST localhost ---> Running in b36f5fe1f734 Removing intermediate container b36f5fe1f734 ---> 01d29407f4c6 Step 6/8 : ENV TODOAPI_PORT 30080 ---> Running in 2386c465df0b Removing intermediate container 2386c465df0b ---> 33b0c0a091ee Step 7/8 : EXPOSE 80 ---> Running in 7918de7a342d Removing intermediate container 7918de7a342d ---> ceb4d9576c47 Step 8/8 : CMD ["./run.sh"] ---> Running in 9c0db2048fed Removing intermediate container 9c0db2048fed ---> 8a51613c8863 Successfully built 8a51613c8863 Successfully tagged todofrontend:5.0 [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 5.0)) - 16:28 $ ``` ### Run ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 5.0)) - 1 (cmd)$ kubectl apply -f k8s/todoapi-service.yml -n todo service/todoapi created deployment.apps/todoapi created ``` ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 5.0)) - 16:30 (ins)$ kubectl apply -f k8s/todofrontend-service.yml -n todo service/todofrontend created deployment.apps/todofrontend created ``` ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 5.0)) - 16:30 (cmd)$ kubectl get svc -n todo NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE todoapi NodePort 10.111.165.42 <none> 80:30080/TCP 21s todofrontend NodePort 10.111.152.45 <none> 80:30000/TCP 7s ``` ### EnvFrom 目的在於可以將 configMap 注入 env 設定 * [configmap reference](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) https://github.com/William-Yeh/workshop-k8s201908/blob/5.0/k8s/todofrontend-service.yml#L51 ``` spec: containers: - name: todofrontend image: todofrontend:5.0 imagePullPolicy: IfNotPresent ports: - containerPort: 80 envFrom: - configMapRef: name: config.local ``` ## LAB # 6.0 1. Checkout to 6.0 tag. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 5.0)) - 16:32 (cmd)$ git checkout 6.0 Previous HEAD position was 47f84f0 5.0: Support ConfigMap and naming convention. HEAD is now at 0e7fd39 6.0: Support Kubernetes on the cloud (GKE for example) and use Skaffold to simplify the process. ``` 1. Diff. ``` [ jonny@unicorn ~/vcs/7.workshop/workshop-k8s201908 ] ((HEAD detached at 6.0)) - 16:41 (ins)$ git diff --stat HEAD~1 HEAD README.md | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------ docker-compose.yml | 23 ----------------- gke-steps.md | 49 +++++++++++++++++++++++++++++++++++ k8s/cloud/config.cloud.yml.tpl | 9 +++++++ k8s/cloud/fix-name.py | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ k8s/cloud/todoapi-service.yml.tpl | 55 +++++++++++++++++++++++++++++++++++++++ k8s/cloud/todofrontend-service.yml.tpl | 65 ++++++++++++++++++++++++++++++++++++++++++++++ k8s/{ => local}/config.local.yml | 0 k8s/{ => local}/todoapi-service.yml | 5 ++-- k8s/{ => local}/todofrontend-service.yml | 5 ++-- skaffold.yaml | 35 +++++++++++++++++++++++++ 11 files changed, 405 insertions(+), 44 deletions(-) ``` * 本次 LAB 是 手動選號 vs 自動選號 都會實作到。 ### Usage: the cloud case > https://github.com/William-Yeh/workshop-k8s201908/tree/6.0#usage-the-cloud-case 1. 建成功的,就會看到 RUNNING 的狀態。 ![](https://i.imgur.com/esvKGMy.png) 1. 回頭記得砍掉已建好的環境,多練習個幾次! ![](https://i.imgur.com/3GKjtRv.png) #### Preparation 1. Run the Workshop on GKE (Google Kubernetes Engine) > https://github.com/William-Yeh/workshop-k8s201908/blob/6.0/gke-steps.md ![](https://i.imgur.com/3oMci1g.png) 1. Allocate a static external IP address for TODOAPI_HOST: ``` # reserve a new static external IP address for backend todoapi % gcloud compute addresses create todoapi --region=us-west1 --network-tier=PREMIUM # make sure the static external IP address has been allocated % gcloud compute addresses list ``` ![](https://i.imgur.com/e0CJTfU.png) * todoapi ip address: 35.247.16.87 1. We will replace the ip address at https://github.com/William-Yeh/workshop-k8s201908/blob/6.0/k8s/cloud/todoapi-service.yml.tpl#L11 . ``` spec: type: LoadBalancer loadBalancerIP: TODOAPI_IP_ADDR # external IP (ephemeral or static) ports: - name: http port: 80 targetPort: 80 selector: app: todo tier: backend ``` 1. 回頭練習完,記得把會收錢的 VPC IP 給拔掉。 ![](https://i.imgur.com/5UuwPfd.png) 1. Fill in correct image names and static IP addresses by modifying the PROJECT_ID and TODOAPI_IP_ADDR symbols in manifest files, by either: ``` k8s/cloud/fix-name.py PROJECT_ID TODOAPI_IP_ADDR ``` ![](https://i.imgur.com/U5Kdhe6.png) 1. Create a todo namespace for this app: Create a todo namespace for this app: Load the ConfigMap content: ![](https://i.imgur.com/tbI2hID.png) #### Build and Run The Skaffold is like docker-compose for K8s. > https://github.com/William-Yeh/workshop-k8s201908/blob/6.0/skaffold.yaml 1. Use Skaffold to streamline the build-and-run process continuously: ``` # dev: LiveReload mode. $ skaffold dev -p cloud --default-repo gcr.io/PROJECT_ID -n todo ``` ![](https://i.imgur.com/TW3mmaV.png) > 若時間允許,可在 local 先體驗一下 Skaffold 的威力!再上 cloud 玩。 ![](https://i.imgur.com/L0RT10s.png) 1. Review the ip address. ``` $ kubectl get svc -n todo ``` ![](https://i.imgur.com/AOFbFHK.png) ### Q&A 1. K8s 在本機練習上,算穩定嗎? 1. minikube 會比較穩定,但相對吃資源。 ### LAB # 6.0 Review 1. Architecture 1. Main tasks 1. .... ## LAB # 7.0 Canary release 1. 新的 K8s 會使用 Istio 來跑 Canary release,比傳統 K8s 方法來得簡單好用。 1. 09/11 K8s Summit 有人會分享這一塊。 ## END ### Remove GKE cluster 1. Delete the `todo` namespace. ![](https://i.imgur.com/5524WkE.png) 1. Release the static ip address. (1/3) ![](https://i.imgur.com/UZcpKdm.png) 1. Release the static ip address. (2/3) ![](https://i.imgur.com/Nfq2puC.png) 1. Release the static ip address. (3/3) ![](https://i.imgur.com/lzgw8uQ.png) 1. Delete the Kubernetes clusters. ![](https://i.imgur.com/tfYcikV.png) 1. DONE (1/2). ![](https://i.imgur.com/Usdwv84.png) 1. DONE (2/2). ![](https://i.imgur.com/Uo90UZ2.png)