Overview Kubernetes (k8s)

Overview Kubernetes

Với các dịch vụ web hiện đại, người dùng luôn mong muốn sử dụng các ứng dụng bất kì lúc nào, trong khi các nhà phát triển lại luôn triển khai các phiên bản mới của các ứng dụng đó nhiều lần trong ngày. Containerization giúp đóng gói phần mềm để phục vụ mục tiêu này, cho phép các ứng dụng được phát hành và cập nhật mà không cần thời gian chết. Kubernetes giúp bạn đảm bảo quản lí các ứng dụng chạy ở đâu và khi nào, đồng thời giúp chúng tìm thấy các tài nguyên và công cụ cần thiết để hoạt động. Kubernetes là một nền tảng mã nguồn mở, được thiết kế với kinh nghiệm tích lũy của Google trong việc điều phối vùng chứa, kết hợp với những ý tưởng tốt nhất từ cộng đồng.

Overview Module 1: Create a cluster with Minikube

Kubernetes là một nền tảng mã nguồn mở, sắp xếp vị trí (lập lịch) và thực thi các vùng chứa ứng dụng trong và trên các cụm máy tính. Qua bài này, bạn có thể nắm được những nội dung sau:

  • Hiểu được cụm Kubernetes là gì
  • Hiểu được Minikube là gì
  • Triển khai một cụm Kubernetes bằng terminal

Overview Module 2:

Deployment chịu trách nhiệm tạo và cập nhật các phiên bản ứng dụng. Qua bài này, bạn có thể nắm được:

  • Hiểu về cách triển khai ứng dụng.
  • Triển khai ứng dụng đầu tiên của bạn trên Kubernetes với kubectl.

Overview Module 3:

Pod là một nhóm gồm một hoặc nhiều vùng chứa ứng dụng (chẳng hạn như Docker) và bao gồm bộ nhớ dùng chung (volumes), địa chỉ IP và thông tin về cách vận hành chúng. Qua bài này, bạn sẽ:

  • Tìm hiểu về Kubernetes Pods.
  • Tìm hiểu về Kubernetes Nodes.
  • Khắc phục sự cố các ứng dụng đã triển khai.

Overview Module 4:

Dịch vụ Kubernetes (Kubernetes Service) là một lớp trừu tượng xác định một tập hợp lôgic của các Pod và cho phép tiếp xúc với kết nối bên ngoài (external traffic), cân bằng tải (load balancing) và khám phá dịch vụ cho các Pod đó. Qua bài này, bạn sẽ:

  • Tìm hiểu về Service trong Kubernetes
  • Hiểu cách các nhãn và các đối tượng LabelSelector của Service
  • Hiển thị ứng dụng bên ngoài Kubernetes cluster bằng Service

Overview Module 5: Scale Your App - Mở rộng ứng dụng

Trong các module trước, chúng ta đã tạo một Deployment và sau đó hiển thị nó một cách công khai thông qua một Service. Deployment chỉ tạo một Pod để chạy ứng dụng của chúng ta. Khi lưu lượng truy cập tăng, chúng ta cần mở rộng ứng dụng để đáp ứng nhu cầu của người dùng. Qua bài này, bạn sẽ:

  • Mở rộng quy mô ứng dụng với kubectl

Overview Module 6:

Rolling update cho phép cập nhật Deployment mà không có thời gian chết bằng cách cập nhật từng bước các phiên bản Pods bằng những phiên bản mới. Qua bài này, bạn sẽ:

  • Thực hiện rolling update bằng kubectl.

Module 1: Create a Kubernetes cluster - Tạo một cụm Kubernetes

Mục tiêu

  • Hiểu được Kubernetes cluster (cụm) là gì
  • Hiểu được Minikube là gì
  • Triển khai một cụm Kubernetes bằng terminal trực tuyến

Kubernetes Cluster - Cụm Kubernetes

Kubernetes là một nền tảng mã nguồn mở, đáp ứng tốt các tiêu chuẩn triển khai trong thực tế, quản lí, tự động hóa quy trình (lập lịch), và thực thi các vùng chứa ứng dụng trong và trên các cụm máy tính. Kubernetes có thể:

  • điều phối một cụm máy tính có tính sẵn sàng hoạt động, được kết nối để hoạt động như một đơn vị duy nhất,
  • triển khai các ứng dụng được chứa trong một cluster mà không cần ràng buộc chúng cụ thể với từng máy riêng lẻ.
  • tự động hóa việc phân phối và lập lịch các vùng chứa ứng dụng trên một cluster theo cách hiệu quả hơn.

Một cluster bao gồm hai loại tài nguyên:

  • Control Plane điều phối cluster.
  • Node giống như những worker có nhiệm vụ chạy các ứng dụng.

Sơ đồ cluster

Các thành phần của một cluster gồm:

  • Control Plane: điều phối các hoạt động trong cluster (ví dụ: lập lịch ứng dụng, duy trì trạng thái mong muốn của ứng dụng, mở rộng ứng dụng và tung ra các bản cập nhật mới, …).
  • Node (nút): là một máy ảo hoặc một máy tính vật lý, chứa Kubelet để tương tác với Control Plane. Một Kubernetes Cluster xử lý lưu lượng sản xuất phải có tối thiểu ba nút.

Để học phát triển Kubernetes, bạn có thể sử dụng Minikube - một phương pháp triển khai cụm Kubernetes đơn giản (chỉ chứa một Node) trên máy ảo - tương thích với các hệ thống Linux, macOS và Windows.

Step-by-step Tutorial

Hướng dẫn này được thực hiện trong terminal (Linux, macOS, Windows)

Step 1: Cluster up and running

  1. Kiểm tra xem đã cài đặt minikube hay chưa bằng lệnh:
    • minikube version
    • Nếu thông báo tương tự như sau thì có nghĩa là bạn đã cài minikube:
      minikube version: v1.18.0
            commit: ec61815d60f66a6e4f6353030a40b12362557caa-dirty
    • Lệnh này cũng có thể dùng để kiểm tra phiên bản minikube bạn đang sử dụng

  1. Bắt đầu một cluster mới với lệnh:
    • minikube start
    • Minikube đã khởi động một máy ảo và một cluster đang hoạt động trên máy ảo đó.
    * minikube v1.18.0 on Ubuntu 18.04 (kvm/amd64)
          * Using the none driver based on existing profile
          
          X The requested memory allocation of 2200MiB does not leave room for system overhead (total system memory: 2460MiB). You may face stability issues.
          * Suggestion: Start minikube with less memory allocated: 'minikube start --memory=2200mb'
          
          * Starting control plane node minikube in cluster minikube
          * Running on localhost (CPUs=2, Memory=2460MB, Disk=194868MB) ...
          * OS release is Ubuntu 18.04.5 LTS
          * Preparing Kubernetes v1.20.2 on Docker 19.03.13 ...
            - kubelet.resolv-conf=/run/systemd/resolve/resolv.conf
            - Generating certificates and keys ...
            - Booting up control plane ...
            - Configuring RBAC rules ...
          * Configuring local host environment ...
          * Verifying Kubernetes components...
            - Using image gcr.io/k8s-minikube/storage-provisioner:v4
          * Enabled addons: default-storageclass, storage-provisioner
          * Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

Step 2: Cluster details

  1. Xem thông tin chi tiết của cluster bằng lệnh:
    • kubectl cluster-info
    • Màn hình terminal hiển thị:
    Kubernetes control plane is running at https://172.17.0.46:8443
          KubeDNS is running at https://172.17.0.46:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
          
          To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

  1. Để xem các Node trong cluster trên, chạy lệnh:
    • kubectl get nodes
    • Lệnh này hiển thị tất cả các Node có thể được sử dụng để lưu trữ các ứng dụng.
    NAME       STATUS   ROLES                  AGE     VERSION
          minikube   Ready    control-plane,master   3m17s   v1.20.2

Module 2: Deploy an app

Mục tiêu

  • Tìm hiểu về triển khai ứng dụng.
  • Triển khai ứng dụng đầu tiên của bạn trên Kubernetes với kubectl.

Kubernetes Deployments (Triển khai Kubernetes)

Khi bạn có một cluster đang chạy, bạn có thể triển khai các ứng dụng được chứa trong bộ chứa của mình bằng cách tạo cấu hình Kubernetes Deployment. Khi đã triển khai ứng dụng trong bộ nhớ, lúc này Control Plane sẽ làm các việc sau để quản lí Deployment:

  • Lên lịch cho các phiên bản ứng dụng để chạy trên các Node riêng lẻ trong cluster.
  • Liên tục giám sát các phiên bản
  • Nếu Node lưu trữ một phiên bản gặp sự cố hoặc bị xóa, Control Plane sẽ thay thế phiên bản đó bằng một phiên bản trên Node khác trong cluster ⇒ cung cấp một cơ chế tự phục hồi để giải quyết sự cố hoặc bảo trì máy.

Trong thế giới tiền quy trình hóa, các tập lệnh cài đặt thường được sử dụng để khởi động các ứng dụng, nhưng chúng không cho phép khôi phục khi máy bị lỗi. Bằng cách vừa tạo các phiên bản ứng dụng của bạn vừa giữ cho chúng chạy trên các Node, Kubernetes Deployments cung cấp một cách tiếp cận khác về cơ bản để quản lý ứng dụng.

Triển khai ứng dụng đầu tiên của bạn trên Kubernetes

Chúng ta có thể tạo và quản lý một Deployment bằng cách sử dụng giao diện dòng lệnh Kubernetes (Kubernetes command line), Kubectl. Khi tạo Deployment, chúng ta cần xác định rõ container image cho ứng dụng của mình và số lượng bản sao hoạt động.

Các ứng dụng cần phải được đóng gói thành một định dạng được hỗ trợ trong container để được triển khai trên Kubernetes. (Ví dụ như định dạng gói cài đặt ứng dụng trên android là file *.apk)

Đối với Deployment đầu tiên này, chúng ta sẽ sử dụng ứng dụng hello-node được đóng gói trong vùng chứa Docker sử dụng NGINX để gửi lại tất cả các yêu cầu.

Step-by-step instruction

Để hoàn thành các bước bên dưới (từ Step 1 trở đi), chúng ta cần chuẩn bị ứng dụng Hello Minikube hoặc bạn có thể tự viết một ứng dụng đơn giản dựa trên hướng dẫn ở Step 0.

Step 0: Hello Minikube

Create a minikube cluster

Trong giao diện command line, chạy lệnh:

  • minikube start

Mở thêm một của sổ command line song song khác (không tắt cái command line trên) và chạy lệnh:

  • minikube dashboard

Sau đó quay về cửa sổ terminal cũ (nơi chạy lệnh minikube start)

Create a Deployment

  1. Sử dụng lệnh kubectl create để tạo một Deployment nhằm quản lí Pod. Pod này chạy trên một container dựa trên image được cung cấp bởi Docker.

    kubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4

  1. Hiển thị thông tin về Deployment:

    kubectl get deployments

    Kết quả ở terminal:

    NAME         READY   UP-TO-DATE   AVAILABLE   AGE
          hello-node   1/1     1            1           1m
  1. Hiển thị tình trạng Pod:

    kubectl get pods

    The output is similar to:

    NAME                          READY     STATUS    RESTARTS   AGE
          hello-node-5f76cf6ccf-br9b5   1/1       Running   0          1m
          
  1. Hiển thị các việc mà cluster đã xử lí:

    kubectl get events

  1. Hiển thị cấu hình của kubectl:

    kubectl config view

Step 1: kubectl basics

  1. Kiểm tra xem kubectl có được thiết lập để tương tác với cluster hay không bằng cách chạy lệnh kubectl version:

    kubectl version

    Nếu kubectl đã được cài đặt, ta sẽ nhận được thông báo sau trong terminal:

    Client Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.4", GitCommit:"e87da0bd6e03ec3fea7933c4b5263d151aafd07c", GitTreeState:"clean", BuildDate:"2021-02-18T16:12:00Z", GoVersion:"go1.15.8", Compiler:"gc", Platform:"linux/amd64"}
          Server Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.2", GitCommit:"faecb196815e248d3ecfb03c680a4507229c2a56", GitTreeState:"clean", BuildDate:"2021-01-13T13:20:00Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"linux/amd64"}
  1. Để xem các Node trong cluster, ta dùng lệnh kubectl get nodes:
    • kubectl get nodes
    • Ở đây ta có thể thấy thấy các Node có sẵn. Kubernetes sẽ chọn nơi triển khai ứng dụng của bạn dựa trên tài nguyên sẵn có của Node.
    NAME       STATUS   ROLES                  AGE     VERSION
          minikube   Ready    control-plane,master   4m17s   v1.20.2

Step 2: Deploy our app

  1. Để triển khai ứng dụng trên Kubernetes, ta dùng lệnh kubectl create deployment. Ta cần cung cấp tên triển khai và image của ứng dụng (bao gồm respository URL của image được lưu trữ bên ngoài trung tâm Docker).
    • Khi thành công ta có thông báo sau:
    deployment.apps/kubernetes-bootcamp created
  1. Để liệt kê các Deployment, ta dùng lệnh get deployments
    • kubectl get deployments
    • Ta có thể thấy các deployment đang chạy:
    NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
          kubernetes-bootcamp   1/1     1            1           3m41s

Step 3: View our app

Các Pod bên trong Kubernetes đang chạy trong một mạng lưới riêng (private network), bị cô lập. Trong thiết lập mặc định, các pod và service khác trong cùng một kubernetes cluster có thể thấy lẫn nhau trong nội bộ mạng cluster, nhưng không hiển thị ra bên ngoài mạng đó. Ta dùng kubectl để tương tác thông qua API endpoint nhằm giao tiếp với ứng dụng trong private network.

Lệnh kubectl có thể tạo một proxy chuyển tiếp thông tin liên lạc vào private network của toàn cluster. Ta kết thúc proxy này bằng cách nhấn Control-C

  1. Đầu tiên, ta sẽ mở một cửa sổ terminal thứ 2 để chạy proxy: kubectl proxy Ta có kết quả hiển thị trong cửa sổ terminal thứ 2 như sau:
    Starting to serve on 127.0.0.1:8001

    Bây giờ ta đã thiết lập kết nối giữa máy chủ và Kubernetes cluster. Proxy cho phép truy cập trực tiếp vào API từ các terminal.

  1. Bạn có thể xem tất cả các API đó được lưu trữ thông qua proxy endpoint. Ví dụ: ta có thể truy vấn phiên bản thông qua API bằng cách sử dụng lệnh curl:

    curlhttp://localhost:8001/version

    {
            "major": "1",
            "minor": "20",
            "gitVersion": "v1.20.2",
            "gitCommit": "faecb196815e248d3ecfb03c680a4507229c2a56",
            "gitTreeState": "clean",
            "buildDate": "2021-01-13T13:20:00Z",
            "goVersion": "go1.15.5",
            "compiler": "gc",
            "platform": "linux/amd64"
          }

    Nếu không truy cập được cổng 8001, hãy đảm bảo rằng proxy kubectl đang chạy trong một terminal khác.

  1. Máy chủ API sẽ tự động tạo một endpoint cho mỗi pod, dựa trên tên pod, và ta cũng có thể truy cập được thông qua proxy: Trước tiên, chúng ta cần lấy tên pod và lưu trữ trong biến môi trường POD_NAME:

    export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') echo Name of the Pod: $POD_NAME

    Kết quả tương tự sẽ được hiển thị trong terminal:

    Name of the Pod: kubernetes-bootcamp-57978f5f5d-xndsv

    Từ đó ta có thể truy cập Pod thông qua API bằng cách chạy lệnh: curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/

    Kết quả trả ra ở terminal:

    {
            "kind": "Pod",
            "apiVersion": "v1",
            "metadata": {
              "name": "kubernetes-bootcamp-57978f5f5d-jll7m",
              "generateName": "kubernetes-bootcamp-57978f5f5d-",
              "namespace": "default",
              "uid": "3318dfbe-44f2-4af0-91f1-2c94e01a479a",
              "resourceVersion": "564",
              "creationTimestamp": "2021-11-04T06:38:32Z",
              "labels": {
                "app": "kubernetes-bootcamp",
                "pod-template-hash": "57978f5f5d"
              },
              "ownerReferences": [
                {
                  "apiVersion": "apps/v1",
                  "kind": "ReplicaSet",
                  "name": "kubernetes-bootcamp-57978f5f5d",
                  "uid": "8a64dfee-1da0-4c0d-804c-d00d7b51d23e",
                  "controller": true,
                  "blockOwnerDeletion": true
                }
              ],
              "managedFields": [
                {
                  "manager": "kube-controller-manager",
                  "operation": "Update",
                  "apiVersion": "v1",
                  "time": "2021-11-04T06:38:32Z",
                  "fieldsType": "FieldsV1",
                  "fieldsV1": {"f:metadata":{"f:generateName":{},"f:labels":{".":{},"f:app":{},"f:pod-template-hash":{}},"f:ownerReferences":{".":{},"k:{\"uid\":\"8a64dfee-1da0-4c0d-804c-d00d7b51d23e\"}":{".":{},"f:apiVersion":{},"f:blockOwnerDeletion":{},"f:controller":{},"f:kind":{},"f:name":{},"f:uid":{}}}},"f:spec":{"f:containers":{"k:{\"name\":\"kubernetes-bootcamp\"}":{".":{},"f:image":{},"f:imagePullPolicy":{},"f:name":{},"f:resources":{},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{}}},"f:dnsPolicy":{},"f:enableServiceLinks":{},"f:restartPolicy":{},"f:schedulerName":{},"f:securityContext":{},"f:terminationGracePeriodSeconds":{}}}
                },
                {
                  "manager": "kubelet",
                  "operation": "Update",
                  "apiVersion": "v1",
                  "time": "2021-11-04T06:38:37Z",
                  "fieldsType": "FieldsV1",
                  "fieldsV1": {"f:status":{"f:conditions":{"k:{\"type\":\"ContainersReady\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:status":{},"f:type":{}},"k:{\"type\":\"Initialized\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:status":{},"f:type":{}},"k:{\"type\":\"Ready\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:status":{},"f:type":{}}},"f:containerStatuses":{},"f:hostIP":{},"f:phase":{},"f:podIP":{},"f:podIPs":{".":{},"k:{\"ip\":\"172.18.0.3\"}":{".":{},"f:ip":{}}},"f:startTime":{}}}
                }
              ]
            },
            "spec": {
              "volumes": [
                {
                  "name": "default-token-kr6hz",
                  "secret": {
                    "secretName": "default-token-kr6hz",
                    "defaultMode": 420
                  }
                }
              ],
              "containers": [
                {
                  "name": "kubernetes-bootcamp",
                  "image": "gcr.io/google-samples/kubernetes-bootcamp:v1",
                  "resources": {
                    
                  },
                  "volumeMounts": [
                    {
                      "name": "default-token-kr6hz",
                      "readOnly": true,
                      "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
                    }
                  ],
                  "terminationMessagePath": "/dev/termination-log",
                  "terminationMessagePolicy": "File",
                  "imagePullPolicy": "IfNotPresent"
                }
              ],
              "restartPolicy": "Always",
              "terminationGracePeriodSeconds": 30,
              "dnsPolicy": "ClusterFirst",
              "serviceAccountName": "default",
              "serviceAccount": "default",
              "nodeName": "minikube",
              "securityContext": {
                
              },
              "schedulerName": "default-scheduler",
              "tolerations": [
                {
                  "key": "node.kubernetes.io/not-ready",
                  "operator": "Exists",
                  "effect": "NoExecute",
                  "tolerationSeconds": 300
                },
                {
                  "key": "node.kubernetes.io/unreachable",
                  "operator": "Exists",
                  "effect": "NoExecute",
                  "tolerationSeconds": 300
                }
              ],
              "priority": 0,
              "enableServiceLinks": true,
              "preemptionPolicy": "PreemptLowerPriority"
            },
            "status": {
              "phase": "Running",
              "conditions": [
                {
                  "type": "Initialized",
                  "status": "True",
                  "lastProbeTime": null,
                  "lastTransitionTime": "2021-11-04T06:38:32Z"
                },
                {
                  "type": "Ready",
                  "status": "True",
                  "lastProbeTime": null,
                  "lastTransitionTime": "2021-11-04T06:38:35Z"
                },
                {
                  "type": "ContainersReady",
                  "status": "True",
                  "lastProbeTime": null,
                  "lastTransitionTime": "2021-11-04T06:38:35Z"
                },
                {
                  "type": "PodScheduled",
                  "status": "True",
                  "lastProbeTime": null,
                  "lastTransitionTime": "2021-11-04T06:38:32Z"
                }
              ],
              "hostIP": "172.17.0.50",
              "podIP": "172.18.0.3",
              "podIPs": [
                {
                  "ip": "172.18.0.3"
                }
              ],
              "startTime": "2021-11-04T06:38:32Z",
              "containerStatuses": [
                {
                  "name": "kubernetes-bootcamp",
                  "state": {
                    "running": {
                      "startedAt": "2021-11-04T06:38:34Z"
                    }
                  },
                  "lastState": {
                    
                  },
                  "ready": true,
                  "restartCount": 0,
                  "image": "jocatalin/kubernetes-bootcamp:v1",
                  "imageID": "docker-pullable://jocatalin/kubernetes-bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af",
                  "containerID": "docker://71c1866b8a2e5b3421abbd3b4d1c5efe750bf719c9e1ea72226b269ff963d2b4",
                  "started": true
                }
              ],
              "qosClass": "BestEffort"
            }
          }

Module 3: Explore your app

Mục tiêu

  • Tìm hiểu về Kubernetes Pods.
  • Tìm hiểu về Kubernetes Nodes.
  • Khắc phục sự cố các ứng dụng đã triển khai.

Kubernetes Pods

Khi tạo một Deployment, Kubernetes đã tạo một Pod để lưu trữ phiên bản ứng dụng đó. Pod là đơn vị cơ bản của Kubernetes, đại diện cho các vùng chứa ứng dụng (chẳng hạn như Docker) và tài nguyên được chia sẻ, bao gồm:

  • Bộ nhớ dùng chung (dưới dạng Volumes).
  • Kết nối đến network (như một địa chỉ IP duy nhất)
  • Thông tin về cách chạy từng vùng chứa, chẳng hạn như phiên bản hình ảnh vùng chứa hoặc các cổng cụ thể để sử dụng

Khi tạo một Deployment, Kubernetes sẽ tạo các Pods với các vùng chứa bên trong chúng (trái ngược với việc tạo các containers trực tiếp). Mỗi Pod được gắn với Node nơi nó được lên lịch và tồn tại cho đến khi kết thúc hoặc bị xóa. Trong trường hợp Node bị lỗi, các Pod giống hệt nhau sẽ được lên lịch trên các Node có sẵn khác trong cluster.

Pods overview

Nodes

Một Pod luôn chạy trên một Node. Node là một máy công nhân (worker machine) trong Kubernetes và có thể là máy ảo (VM) hoặc máy vật lý (computer) và được quản lí bởi Control Plane. Một Node có thể có nhiều Pod và Kubernetes Control Plane tự động xử lý việc lập lịch các Pod lên các Node trong cluster.

Mỗi Kubernetes Node luôn thực hiện các hoạt động sau:

  • Kubelet, một quá trình chịu trách nhiệm liên lạc giữa Control Plane và Node; nó quản lý các Pod và các vùng chứa đang chạy trên máy.
  • Thời gian chạy container (như Docker) chịu trách nhiệm kéo hình ảnh container từ registry, giải nén container và chạy ứng dụng.

Node overview

Khắc phục sự cố với kubectl

Trong phần 2, chúng ta đã sử dụng giao diện dòng lệnh với Kubectl. Chúng ta sẽ tiếp tục sử dụng nó trong phần 3 để nhận thông tin về các ứng dụng đã triển khai và môi trường của chúng bằng các lệnh kubectl sau:

  • kubectl get - liệt kê tài nguyên
  • kubectl describe - hiển thị thông tin chi tiết về tài nguyên
  • kubectl logs - in nhật ký từ một container trong một pod
  • kubectl exec - thực hiện lệnh trên container trong pod

Chúng ta có thể sử dụng các lệnh này để xem khi nào các ứng dụng được triển khai, trạng thái hiện tại, chúng đang chạy ở đâu và cấu hình của chúng.

Step-by-step tutorial

Step 1: Check application configuration

  1. Để xác minh rằng ứng dụng đã triển khai trong phần trước đó đang hoạt động, ta có thể sử dụng lệnh: kubectl get pod
    • Kết quả trả ra trong command-line:
      NAME                                  READY   STATUS    RESTARTS   AGE
            kubernetes-bootcamp-fb5c67579-wdl9r   1/1     Running   0          2m15s
    • Nếu không có pod nào đang chạy thì môi trường tương tác vẫn đang tải lại trạng thái trước đó. Chúng ta có thể đợi vài giây và liệt kê lại các pod.
  1. Tiếp theo, để xem những container nào bên trong pod đó và những images nào được sử dụng để tạo các container đó, chúng ta chạy lệnh description pods:
    • kubectl describe pods
    • Kết quả trong command-line:
      Name:         kubernetes-bootcamp-fb5c67579-wdl9r
            Namespace:    default
            Priority:     0
            Node:         minikube/172.17.0.38
            Start Time:   Wed, 03 Nov 2021 02:38:16 +0000
            Labels:       app=kubernetes-bootcamp
                          pod-template-hash=fb5c67579
            Annotations:  <none>
            Status:       Running
            IP:           172.18.0.4
            IPs:
              IP:           172.18.0.4
            Controlled By:  ReplicaSet/kubernetes-bootcamp-fb5c67579
            Containers:
              kubernetes-bootcamp:
                Container ID:   docker://96754f5d1b573480d6fc591d9ca3241714165d4099f9f81b7c206d70a2670000
                Image:          gcr.io/google-samples/kubernetes-bootcamp:v1
                Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
                Port:           8080/TCP
                Host Port:      0/TCP
                State:          Running
                  Started:      Wed, 03 Nov 2021 02:38:18 +0000
                Ready:          True
                Restart Count:  0
                Environment:    <none>
                Mounts:
                  /var/run/secrets/kubernetes.io/serviceaccount from default-token-qsvmk (ro)
            Conditions:
              Type              Status
              Initialized       True 
              Ready             True 
              ContainersReady   True 
              PodScheduled      True 
            Volumes:
              default-token-qsvmk:
                Type:        Secret (a volume populated by a Secret)
                SecretName:  default-token-qsvmk
                Optional:    false
            QoS Class:       BestEffort
            Node-Selectors:  <none>
            Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
            Events:
              Type    Reason     Age   From               Message
              ----    ------     ----  ----               -------
              Normal  Scheduled  12m   default-scheduler  Successfully assigned default/kubernetes-bootcamp-fb5c67579-wdl9r to minikube
              Normal  Pulled     12m   kubelet            Container image "gcr.io/google-samples/kubernetes-bootcamp:v1" already present on machine
              Normal  Created    12m   kubelet            Created container kubernetes-bootcamp
              Normal  Started    12m   kubelet            Started container kubernetes-bootcamp
    • Tại đây, chúng ta có thể thấy những thông tin chi tiết về vùng chứa của Pod: địa chỉ IP, các cổng được sử dụng và danh sách các sự kiện liên quan đến vòng đời của Pod.

Step 2: Show the app in the terminal

  1. Pod chạy trong một mạng riêng (private network), cô lập - vì vậy chúng ta cần quyền truy cập proxy để có thể gỡ lỗi và tương tác. Để thực hiện việc này, chúng ta sẽ sử dụng lệnh kubectl proxy trong một terminal mới:
    • Kết quả trả ra terminal
      Starting Proxy. After starting it will not output a response. Please click the first Terminal Tab
            
            Starting to serve on 127.0.0.1:8001

  1. Bây giờ, quay lại terminal ban đầu, chúng ta sẽ lấy tên pod và truy vấn pod đó trực tiếp thông qua proxy. Để lấy tên Pod và lưu trữ nó trong biến môi trường POD_NAME, ta chạy lệnh:
    • export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')
    • echo Name of the Pod: $POD_NAME
    • Kết quả trả ra terminal:
      Name of the Pod: kubernetes-bootcamp-fb5c67579-wdl9r

  1. Để xem đầu ra của ứng dụng, ta dùng lệnh curl :
  • curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/
  • Đường dẫn trên dẫn đến API của pod.

Step 3: View the container logs

  1. Những thứ mà ứng dụng thường gửi đến STDOUT sẽ trở thành nhật ký (logs) cho vùng chứa bên trong Pod. Chúng ta có thể truy xuất các nhật ký này bằng lệnh: kubectl log
    • kubectl logs $POD_NAME
    • Kết quả trả ra terminal
      Kubernetes Bootcamp App Started At: 2021-11-03T02:38:18.919Z | Running On:  kubernetes-bootcamp-fb5c67579-wdl9r

Step 4: Executing command on the container

Chúng ta có thể thực hiện các lệnh trực tiếp trên vùng chứa sau khi Pod hoạt động bằng lệnh execute và sử dụng tên Pod làm tham số.

  1. Đầu tiên, liệt kê các biến môi trường trong pod:
    • kubectl exec $POD_NAME -- env
    • Kết quả:
      PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
            HOSTNAME=kubernetes-bootcamp-fb5c67579-wdl9r
            KUBERNETES_PORT_443_TCP_PORT=443
            KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
            KUBERNETES_SERVICE_HOST=10.96.0.1
            KUBERNETES_SERVICE_PORT=443
            KUBERNETES_SERVICE_PORT_HTTPS=443
            KUBERNETES_PORT=tcp://10.96.0.1:443
            KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
            KUBERNETES_PORT_443_TCP_PROTO=tcp
            NPM_CONFIG_LOGLEVEL=info
            NODE_VERSION=6.3.1
            HOME=/root

  1. Bắt đầu một bash session trong vùng chứa của Pods:
    • kubectl exec -ti $POD_NAME -- bash
    • Kết quả minh họa:
      root@kubernetes-bootcamp-fb5c67579-wdl9r:/#

  1. Chúng ta có thể kiểm tra xem ứng dụng đã hoạt động chưa bằng cách chạy lệnh curl:
    • curl localhost:8080
    • Kết quả:
      Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-fb5c67579-wdl9r | v=1

Module 4: Expose your app publicly - Đưa ứng dụng ra public

Mục tiêu

  • Tìm hiểu về Service trong Kubernetes
  • Hiểu cách các nhãn và các đối tượng LabelSelector của Service
  • Hiển thị ứng dụng bên ngoài Kubernetes cluster bằng Service

Tổng quan về Dịch vụ (Service) trong Kubernetes

Một Kubernetes Service là một tập hợp các Pod và các quy định để truy cập chúng. Service được viết bằng YAML hoặc JSON, giống các đối tượng Kubernetes khác. Tập hợp các pod được Service ngắm đến thường được xác định bởi Bộ dò nhãn (Label Selector)

Mặc dù mỗi Pod có một địa chỉ IP duy nhất, các IP đó không được hiển thị ra bên ngoài cluster nếu không có Service. Các Service cho phép các ứng dụng của bạn được truy cập từ bên ngoài. Các Service có thể được hiển thị theo nhiều cách khác nhau bằng cách xác định một trong những ServiceSpec sau đây:

  • ClusterIP (mặc định) - Hiển thị Service trên một IP nội bộ trong cluster. Loại này làm cho Service chỉ có thể truy cập được từ bên trong cluster.
  • NodePort - Hiển thị Service trên cùng một cổng của mỗi Node được chọn trong cluster bằng cách sử dụng NAT. Làm cho một Service có thể truy cập từ bên ngoài cluster bằng cách sử dụng <NodeIP>: <NodePort>.
  • LoadBalancer - Tạo bộ cân bằng tải bên ngoài trong cloud hiện tại (nếu được hỗ trợ) và chỉ định một IP bên ngoài, cố định cho Service.
  • ExternalName - Gắn dịch vụ tới với nội dung của externalName (ví dụ: foo.bar.example.com), bằng cách trả về CNAME với giá trị của nó. Không có bất kỳ hình thức ủy quyền nào được thiết lập. Loại này yêu cầu phiên bản kube-dns v1.7 trở lên hoặc CoreDNS phiên bản 0.0.8 trở lên.

Dịch vụ và Nhãn dán (Labels)

Dịch vụ định tuyến lưu lượng (Service routes traffic) truy cập qua một tập hợp các Pod. Service cho phép các Pod ngừng hoạt động và tái tạo trong Kubernetes mà không ảnh hưởng đến ứng dụng của chúng ta. Việc khám phá và định tuyến giữa các Pod phụ thuộc (chẳng hạn như các thành phần frontend và backend trong một ứng dụng) sẽ được Kubernetes Services xử lý.

Các Service kết nối với một tập hợp các Pod bằng cách sử dụng nhãn và bộ chọn. Nhãn là các cặp key/value gắn liền với các đối tượng và có thể được sử dụng theo nhiều cách:

  • Chỉ định các đối tượng để phát triển, thử nghiệm và sản xuất
  • Nhúng thẻ phiên bản
  • Phân loại một đối tượng bằng cách sử dụng các thẻ

Nhãn dán được gắn vào các đối tượng tại thời điểm khởi tạo hoặc sau này, và có thể được chỉnh sửa bất cứ lúc nào.

Step-by-step Tutorial

Step 1: Create a new service

  1. Liệt kê các dịch vụ hiện tại trong cluster: kubectl get services Chúng ta có Service kubernetes được tạo một cách mặc định khi minikube khởi động cluster..
    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
          kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   2m20s

  1. Để tạo một Service mới và hiển thị nó ra bên ngoài, chúng ta sẽ sử dụng lệnh expose với NodePort làm tham số (minikube chưa hỗ trợ tùy chọn LoadBalancer): kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080 Kết quả thành công:
    service/kubernetes-bootcamp exposed

  1. Bây giờ, chạy lại lệnh liệt kê các dịch vụ hiện tại trong cluster để kiểm tra: kubectl get services Bây giờ chúng ta có một Service đang chạy tên là kubernetes-bootcamp. Ở đây chúng ta thấy rằng Service đã nhận được một IP duy nhất, một cổng nội bộ (private port) và một IP bên ngoài (External IP) (IP của Node).
    NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
          kubernetes            ClusterIP   10.96.0.1       <none>        443/TCP          6m47s
          kubernetes-bootcamp   NodePort    10.98.165.193   <none>        8080:32611/TCP   2m51s

  1. Để tìm hiểu cổng nào đã được mở ra để tiếp xúc với bên ngoài (bằng tùy chọn NodePort), chúng ta dùng lệnh: kubectl describe services/kubernetes-bootcamp
    Name:                     kubernetes-bootcamp
          Namespace:                default
          Labels:                   app=kubernetes-bootcamp
          Annotations:              <none>
          Selector:                 app=kubernetes-bootcamp
          Type:                     NodePort
          IP Families:              <none>
          IP:                       10.98.165.193
          IPs:                      10.98.165.193
          Port:                     <unset>  8080/TCP
          TargetPort:               8080/TCP
          NodePort:                 <unset>  32611/TCP
          Endpoints:                172.18.0.4:8080
          Session Affinity:         None
          External Traffic Policy:  Cluster
          Events:                   <none>
          $ kubectl describe services/kubernetes-bootcamp
          Name:                     kubernetes-bootcamp
          Namespace:                default
          Labels:                   app=kubernetes-bootcamp
          Annotations:              <none>
          Selector:                 app=kubernetes-bootcamp
          Type:                     NodePort
          IP Families:              <none>
          IP:                       10.98.165.193
          IPs:                      10.98.165.193
          Port:                     <unset>  8080/TCP
          TargetPort:               8080/TCP
          NodePort:                 <unset>  32611/TCP
          Endpoints:                172.18.0.4:8080
          Session Affinity:         None
          External Traffic Policy:  Cluster
          Events:                   <none>

  1. Tạo một biến môi trường NODE_PORT có giá trị của cổng: export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}') echo NODE_PORT=$NODE_PORT
    NODE_PORT=32611

  1. Bây giờ chúng ta có thể kiểm tra xem ứng dụng có được hiển thị bên ngoài cluster hay không bằng cách sử dụng curl, IP của Node và cổng tiếp xúc bên ngoài: curl $(minikube ip):$NODE_PORT Và chúng ta nhận được phản hồi từ máy chủ.
    Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-fb5c67579-tkc2d | v=1

Step 2: Using labels

  1. Deployment đã tự động tạo một nhãn cho Pod của chúng ta. Với lệnh describe deployment, bạn có thể thấy tên của nhãn: kubectl describe deployment
    Name:                   kubernetes-bootcamp
          Namespace:              default
          CreationTimestamp:      Fri, 05 Nov 2021 03:22:50 +0000
          Labels:                 app=kubernetes-bootcamp
          Annotations:            deployment.kubernetes.io/revision: 1
          Selector:               app=kubernetes-bootcamp
          Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
          StrategyType:           RollingUpdate
          MinReadySeconds:        0
          RollingUpdateStrategy:  25% max unavailable, 25% max surge
          Pod Template:
            Labels:  app=kubernetes-bootcamp
            Containers:
             kubernetes-bootcamp:
              Image:        gcr.io/google-samples/kubernetes-bootcamp:v1
              Port:         8080/TCP
              Host Port:    0/TCP
              Environment:  <none>
              Mounts:       <none>
            Volumes:        <none>
          Conditions:
            Type           Status  Reason
            ----           ------  ------
            Available      True    MinimumReplicasAvailable
            Progressing    True    NewReplicaSetAvailable
          OldReplicaSets:  <none>
          NewReplicaSet:   kubernetes-bootcamp-fb5c67579 (1/1 replicas created)
          Events:
            Type    Reason             Age   From                   Message
            ----    ------             ----  ----                   -------
            Normal  ScalingReplicaSet  15m   deployment-controller  Scaled up replica set kubernetes-bootcamp-fb5c67579 to 1

  1. Hãy sử dụng nhãn này để truy vấn danh sách Pod của chúng ta bằng cách sử dụng lệnh kubectl get pods với -l làm tham số, theo sau là các giá trị nhãn: kubectl get pods -l app=kubernetes-bootcamp
    NAME                                  READY   STATUS    RESTARTS   AGE
          kubernetes-bootcamp-fb5c67579-tkc2d   1/1     Running   0          16m

  1. Để truy vấn danh sách Service bằng nhãn, ta sử dụng tương tự lệnh ở mục 2: kubectl get services -l app=kubernetes-bootcamp
    NAME                  TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
          kubernetes-bootcamp   NodePort   10.98.165.193   <none>        8080:32611/TCP   14m

  1. Lấy tên của Pod và lưu trữ nó trong biến môi trường POD_NAME:: export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') echo Name of the Pod: $POD_NAME
    Name of the Pod: kubernetes-bootcamp-fb5c67579-tkc2d

  1. Để áp dụng một nhãn mới, chúng ta sử dụng lệnh label theo sau là loại đối tượng, tên đối tượng và nhãn mới: kubectl label pods $POD_NAME version=v1 và chúng ta có thể kiểm tra bằng lệnh description pod: kubectl describe pods $POD_NAME
    Name:         kubernetes-bootcamp-fb5c67579-tkc2d
          Namespace:    default
          Priority:     0
          Node:         minikube/172.17.0.65
          Start Time:   Fri, 05 Nov 2021 03:23:05 +0000
          Labels:       app=kubernetes-bootcamp
                        pod-template-hash=fb5c67579
                        version=v1
          Annotations:  <none>
          Status:       Running
          IP:           172.18.0.4
          IPs:
            IP:           172.18.0.4
          Controlled By:  ReplicaSet/kubernetes-bootcamp-fb5c67579
          Containers:
            kubernetes-bootcamp:
              Container ID:   docker://e940409a31090183e3ecc1078225317f8add67f61b9f5102a98094f7dfb3d4e4
              Image:          gcr.io/google-samples/kubernetes-bootcamp:v1
              Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
              Port:           8080/TCP
              Host Port:      0/TCP
              State:          Running
                Started:      Fri, 05 Nov 2021 03:23:07 +0000
              Ready:          True
              Restart Count:  0
              Environment:    <none>
              Mounts:
                /var/run/secrets/kubernetes.io/serviceaccount from default-token-rrhr5 (ro)
          Conditions:
            Type              Status
            Initialized       True 
            Ready             True 
            ContainersReady   True 
            PodScheduled      True 
          Volumes:
            default-token-rrhr5:
              Type:        Secret (a volume populated by a Secret)
              SecretName:  default-token-rrhr5
              Optional:    false
          QoS Class:       BestEffort
          Node-Selectors:  <none>
          Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                           node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
          Events:
            Type    Reason     Age   From               Message
            ----    ------     ----  ----               -------
            Normal  Scheduled  22m   default-scheduler  Successfully assigned default/kubernetes-bootcamp-fb5c67579-tkc2d to minikube
            Normal  Pulled     22m   kubelet            Container image "gcr.io/google-samples/kubernetes-bootcamp:v1" already present on machine
            Normal  Created    22m   kubelet            Created container kubernetes-bootcamp
            Normal  Started    22m   kubelet            Started container kubernetes-bootcamp

Step 3: Deleting a service

  1. Để xóa Service, bạn có thể sử dụng lệnh delete service. Nhãn cũng có thể được sử dụng chung với lệnh này: kubectl delete service -l app=kubernetes-bootcamp
    service "kubernetes-bootcamp" deleted

  1. Để xác nhận rằng route không được hiển thị nữa, bạn có thể check lại IP và cổng đã tiếp xúc trước đó: curl $(minikube ip):$NODE_PORT
    curl: (7) Failed to connect to 172.17.0.65 port 32611: Connection refused

    Điều này chứng tỏ rằng ứng dụng không thể truy cập được nữa từ bên ngoài cluster

  1. Bạn có thể xác nhận rằng ứng dụng vẫn đang chạy bên trong Pod: kubectl exec -ti $POD_NAME -- curl localhost:8080
    Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-fb5c67579-tkc2d | v=1

Module 5: Scale up your app

Mục tiêu

  • Mở rộng quy mô ứng dụng với kubectl

Mở rộng quy mô ứng dụng

Khi lưu lượng truy cập tăng, chúng ta cần phải mở rộng ứng dụng để đáp ứng nhu cầu của người dùng. Việc mở rộng quy mô được thực hiện bằng cách thay đổi số lượng bản sao trong một Deployment.

Tổng quan về mở rộng quy mô

Mở rộng quy mô Deployment sẽ đảm bảo các Pod mới được tạo và lên lịch cho các Node với các tài nguyên có sẵn. Việc chia tỷ lệ sẽ tăng số lượng Pod lên trạng thái mới. Chúng ta cũng có thể mở rộng quy mô về 0 và nó sẽ kết thúc tất cả các Pod của Deployment đó.

Chạy nhiều phiên bản của một ứng dụng sẽ yêu cầu phân phối lưu lượng truy cập cho toàn bộ các phiên bản. Các dịch vụ có bộ cân bằng tải tích hợp sẽ phân phối lưu lượng mạng tới tất cả các Pod của một Deployment được tiếp xúc. Các dịch vụ sẽ theo dõi liên tục các Pod đang chạy bằng cách sử dụng endpoint, để đảm bảo lưu lượng chỉ được gửi đến các Pod có sẵn.

Như đã đề cập ở trên, việc mở rộng quy mô được thực hiện bằng cách thay đổi số lượng bản sao trong một Deployment để phân chia người dùng sử dụng các bản sao đó.

Step-by-step Instruction

Step 1: Scaling a deployment

  1. Để liệt kê các Deployment, hãy sử dụng lệnh get deployments:
    • kubectl get deployments
    • Output:
    • Màn hình nên hiển thị ít nhất 1 Pod. Nếu không, thực hiện lại command.

  1. Để xem ReplicaSet được tạo bởi Deployment, chạy lệnh:
    • kubectl get rs
    • Lưu ý rằng ReplicaSet luôn được định dạng như sau:
    [DEPLOYMENT-NAME]-[RANDOM-STRING]

    RANDOM-STRING được tạo ngẫu nhiên và sử dụng pod-template-hash làm hạt giống.

    • Output:

  1. Để mở rộng Deployment thành các bản sao (VD: 4 bản sao), sử dụng lệnh kubectl scale, theo sau là loại Deployment, tên và số lượng bản sao mong muốn:
    • kubectl scale deployments/kubernetes-bootcamp --replicas=4

  1. Để liệt kê các Deployment một lần nữa, thực hiện:
    • kubectl get deployments

  1. Tiếp theo, kiểm tra xem số lượng Pods có thay đổi hay không:
    • kubectl get pods -o wide
    • Output:
    NAME                                   READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED NODE   READINESS GATES
          hello-node-7567d9fdc9-xb9p9            1/1     Running   0          5h40m   172.17.0.3   minikube   <none>           <none>
          kubernetes-bootcamp-57978f5f5d-6g8sw   1/1     Running   0          6s      172.17.0.7   minikube   <none>           <none>
          kubernetes-bootcamp-57978f5f5d-8frvh   1/1     Running   0          6s      172.17.0.9   minikube   <none>           <none>
          kubernetes-bootcamp-57978f5f5d-mv8cm   1/1     Running   0          5h37m   172.17.0.4   minikube   <none>           <none>
          kubernetes-bootcamp-57978f5f5d-xfw5z   1/1     Running   0          6s      172.17.0.8   minikube   <none>           <none>

  1. Thay đổi cũng đã được áp dụng trong Deployment events log. Để kiểm tra điều đó, thực hiện:
    • kubectl describe deployments/kubernetes-bootcamp
    • Output:
    Name:                   kubernetes-bootcamp
          Namespace:              default
          CreationTimestamp:      Fri, 05 Nov 2021 14:53:53 +0700
          Labels:                 app=kubernetes-bootcamp
          Annotations:            deployment.kubernetes.io/revision: 1
          Selector:               app=kubernetes-bootcamp
          Replicas:               4 desired | 4 updated | 4 total | 4 available | 0 unavailable
          StrategyType:           RollingUpdate
          MinReadySeconds:        0
          RollingUpdateStrategy:  25% max unavailable, 25% max surge
          Pod Template:
            Labels:  app=kubernetes-bootcamp
            Containers:
             kubernetes-bootcamp:
              Image:        gcr.io/google-samples/kubernetes-bootcamp:v1
              Port:         <none>
              Host Port:    <none>
              Environment:  <none>
              Mounts:       <none>
            Volumes:        <none>
          Conditions:
            Type           Status  Reason
            ----           ------  ------
            Progressing    True    NewReplicaSetAvailable
            Available      True    MinimumReplicasAvailable
          OldReplicaSets:  <none>
          NewReplicaSet:   kubernetes-bootcamp-57978f5f5d (4/4 replicas created)
          Events:
            Type    Reason             Age    From                   Message
            ----    ------             ----   ----                   -------
            Normal  ScalingReplicaSet  8m18s  deployment-controller  Scaled up replica set kubernetes-bootcamp-57978f5f5d to 4

Step 2: Load Balancing

  1. Để kiểm tra xem Service có đang cân bằng với lưu lượng truy cập hay không. Ta có thể sử dụng lệnh Describe như chúng ta đã học trong Mô-đun trước để tìm ra exposed IP và Port:
    • kubectl describe services/kubernetes-bootcamp

  1. Tạo một biến môi trường được gọi là NODE_PORT có giá trị là Node port:
    export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
          echo NODE_PORT=$NODE_PORT

  1. Tạo curl đến với exposed IP và Port và lặp lại nhiều lần:
    curl $(minikube ip):$NODE_PORT

    Nếu quan sát thấy một Pod riêng được tạo ra với mỗi lần thực thi lệnh thì chứng tỏ rằng Service cân bằng.

Step 3: Scale Down

  1. Để thu nhỏ Service xuống còn (VD:2) bản sao, hãy chạy lại câu lệnh scale tương tự như trên:
    • kubectl scale deployments/kubernetes-bootcamp --replicas=2

  1. Liệt kê các Deployment để kiểm tra xem thay đổi có được áp dụng hay không với lệnh get deployments:
    • kubectl get deployments

  1. Liệt kê số lượng Pod để xác nhận thay đổi đã được áp dụng:
    • kubectl get pods -o wide

Module 6: Update your app

Mục tiêu

  • Thực hiện cập nhật liên tục bằng kubectl.

Cập nhật ứng dụng

Người dùng luôn có nhu cầu sử dụng ứng dụng không bị gián đoạn. Nhưng đôi khi các nhà phát triển dự kiến sẽ triển khai các phiên bản mới của ứng dụng nhiều lần trong ngày. Trong Kubernetes, điều này được thực hiện bằng rolling update (cập nhật liên tục).

Rolling update cho phép cập nhật Deployment mà không có thời gian chết bằng cách cập nhật từng bước các phiên bản Pods bằng những phiên bản mới. Các Pod mới sẽ được lên lịch trên các Nodes với các tài nguyên có sẵn để người dùng có thể sử dụng ứng dụng mà không bị gián đoạn.

Trong bài trước, chúng ta đã mở rộng ứng dụng của mình để chạy nhiều phiên bản, đáp ứng nhiều người dùng hợp. Đó chính là một yêu cầu để thực hiện cập nhật mà không ảnh hưởng đến tính khả dụng của ứng dụng.

  • "tính khả dụng": khả năng một sản phẩm có thể đáp ứng cho người dùng

Theo mặc định, số lượng Pod tối đa có thể không có trong quá trình cập nhật và số lượng Pod mới tối đa có thể được tạo là 1. Cả hai tùy chọn đều có thể được cấu hình thành số hoặc tỷ lệ phần trăm (của Pod). Trong Kubernetes, các bản cập nhật được tạo phiên bản và mọi bản cập nhật Deployment đều có thể quay về phiên bản trước đó

Tổng quan về rolling updates

Tương tự như mở rộng ứng dụng, nếu Deployment được hiển thị công khai, Service sẽ cân bằng tải lưu lượng chỉ đến các Pod có sẵn (một phiên bản cho người dùng có thể sử dụng) trong quá trình cập nhật.

Rolling update cho phép các hành động sau:

  • Đưa ứng dụng từ môi trường này sang môi trường khác (thông qua cập nhật hình ảnh vùng chứa)
  • Quay lại các phiên bản trước
  • Tích hợp liên tục và phân phối ứng dụng liên tục mà không có thời gian chết

Step-by-step Instruction

Step 1: Update the version of the app

  1. Để liệt kê các Deployment và Pod:
    • kubectl get deployments
    • kubectl get pods
    • Output pod hiện tại:
    NAME                                  READY   STATUS    RESTARTS   AGE
              kubernetes-bootcamp-fb5c67579-fq75v   1/1     Running   0          7m7s
              kubernetes-bootcamp-fb5c67579-hcqlr   1/1     Running   0          7m8s
              kubernetes-bootcamp-fb5c67579-qvrxt   1/1     Running   0          7m8s
              kubernetes-bootcamp-fb5c67579-tpl94   1/1     Running   0          7m8s

  1. Để xem phiên bản giao diện hiện tại của ứng dụng:
    • kubectl describe pods

  1. Để cập nhật giao diện của ứng dụng lên phiên bản mới (VD:2):
    • kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
    • Hệ thống đã thông báo cho Deployment sử dụng một giao diện khác cho ứng dụng của bạn và bắt đầu cập nhật liên tục.

  1. Để kiểm tra trạng thái của Pod mới và quan sát Pod cũ đang terminate:
    • kubectl get pods
    • Output pod sau khi update:
    NAME                                   READY   STATUS        RESTARTS   AGE
              kubernetes-bootcamp-7d44784b7c-2k7wg   1/1     Running       0          16s
              kubernetes-bootcamp-7d44784b7c-c9zpj   1/1     Running       0          11s
              kubernetes-bootcamp-7d44784b7c-kkkxr   1/1     Running       0          11s
              kubernetes-bootcamp-7d44784b7c-q6w2f   1/1     Running       0          15s
              kubernetes-bootcamp-fb5c67579-fq75v    1/1     Terminating   0          8m28s
              kubernetes-bootcamp-fb5c67579-hcqlr    1/1     Terminating   0          8m29s
              kubernetes-bootcamp-fb5c67579-qvrxt    1/1     Terminating   0          8m29s
              kubernetes-bootcamp-fb5c67579-tpl94    1/1     Terminating   0          8m29s

Step 2: Verify an update

  1. Trước tiên, hãy kiểm tra xem ứng dụng có đang chạy hay không. Để tìm exposed IP và Port:
    • kubectl describe services/kubernetes-bootcamp

  1. Tạo một biến môi trường được gọi là NODE_PORT có giá trị của Node port được gán vào:
    export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
              echo NODE_PORT=$NODE_PORT

  1. Sau đó, thực thi 1 curl đến exposed IP và port:
    • curl $(minikube ip):$NODE_PORT
    • Mỗi khi bạn chạy lệnh curl, bạn sẽ tác động 1 Pod khác nhau. Lưu ý rằng tất cả các Pod đang chạy phiên bản mới nhất (v2).
    • Output:
    $ curl $(minikube ip):$NODE_PORT
              Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-7d44784b7c-c9zpj | v=2
              $ curl $(minikube ip):$NODE_PORT
              Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-7d44784b7c-kkkxr | v=2
              $ curl $(minikube ip):$NODE_PORT
              Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-7d44784b7c-q6w2f | v=2

  1. Bạn cũng có thể xác nhận trạng thái cập nhật bằng cách:
    • kubectl rollout status deployments/kubernetes-bootcamp
    • Output:
    deployment "kubernetes-bootcamp" successfully rolled out

  1. Để xem phiên bản hình ảnh hiện tại của ứng dụng:
    • kubectl describe pods
    • Trong Image field, kiểm tra để xác minh rằng bạn đang chạy phiên bản hình ảnh mới nhất (v2).
    • Ví dụ:
    ...
              Image:          jocatalin/kubernetes-bootcamp:v2
                  Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
              ....

Step 3: Rollback an update

  1. Hãy thực hiện một bản cập nhật khác và triển khai một giao diện được gắn thẻ v10:

  1. Liệt kê các Deployment và Pod để kiểm tra trạng thái:
    • kubectl get deployments
      NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
                kubernetes-bootcamp   3/4     2            3           18m
    • kubectl get pods
      NAME                                   READY   STATUS             RESTARTS   AGE
                kubernetes-bootcamp-59b7598c77-5bcz6   0/1     ImagePullBackOff   0          91s
                kubernetes-bootcamp-59b7598c77-f7n6c   0/1     ImagePullBackOff   0          91s
                kubernetes-bootcamp-7d44784b7c-2k7wg   1/1     Running            0          10m
                kubernetes-bootcamp-7d44784b7c-c9zpj   1/1     Running            0          10m
                kubernetes-bootcamp-7d44784b7c-q6w2f   1/1     Running            0          10m

  1. Lưu ý rằng một số Pod có trạng thái ImagePullBackOff. Để hiểu rõ hơn về vấn đề, ta chạy lệnh:
    • kubectl describe pods
    • Output:
    Name:         kubernetes-bootcamp-59b7598c77-5bcz6
              Namespace:    default
              Priority:     0
              Node:         minikube/172.17.0.20
              Start Time:   Fri, 05 Nov 2021 17:41:24 +0000
              Labels:       app=kubernetes-bootcamp
                            pod-template-hash=59b7598c77
              Annotations:  <none>
              Status:       Pending
              IP:           172.18.0.3
              IPs:
                IP:           172.18.0.3
              Controlled By:  ReplicaSet/kubernetes-bootcamp-59b7598c77
              Containers:
                kubernetes-bootcamp:
                  Container ID:   
                  Image:          gcr.io/google-samples/kubernetes-bootcamp:v10
                  Image ID:       
                  Port:           8080/TCP
                  Host Port:      0/TCP
                  State:          Waiting
                    Reason:       ImagePullBackOff
                  Ready:          False
                  Restart Count:  0
                  Environment:    <none>
                  Mounts:
                    /var/run/secrets/kubernetes.io/serviceaccount from default-token-97nxg (ro)
              Conditions:
                Type              Status
                Initialized       True 
                Ready             False 
                ContainersReady   False 
                PodScheduled      True 
              Volumes:
                default-token-97nxg:
                  Type:        Secret (a volume populated by a Secret)
                  SecretName:  default-token-97nxg
                  Optional:    false
              QoS Class:       BestEffort
              Node-Selectors:  <none>
              Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                               node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
              Events:
                Type     Reason     Age                  From               Message
                ----     ------     ----                 ----               -------
                Normal   Scheduled  2m29s                default-scheduler  Successfully assigned default/kubernetes-bootcamp-59b7598c77-5bcz6 to minikube
                Normal   BackOff    66s (x6 over 2m27s)  kubelet            Back-off pulling image "gcr.io/google-samples/kubernetes-bootcamp:v10"
                Normal   Pulling    52s (x4 over 2m28s)  kubelet            Pulling image "gcr.io/google-samples/kubernetes-bootcamp:v10"
                Warning  Failed     52s (x4 over 2m28s)  kubelet            Failed to pull image "gcr.io/google-samples/kubernetes-bootcamp:v10": rpc error: code = Unknown desc = Error response from daemon: manifest for gcr.io/google-samples/kubernetes-bootcamp:v10 not found: manifest unknown: Failed to fetch "v10" from request "/v2/google-samples/kubernetes-bootcamp/manifests/v10".
                Warning  Failed     52s (x4 over 2m28s)  kubelet            Error: ErrImagePull
                Warning  Failed     36s (x7 over 2m27s)  kubelet            Error: ImagePullBackOff
              
              
              Name:         kubernetes-bootcamp-59b7598c77-f7n6c
              Namespace:    default
              Priority:     0
              Node:         minikube/172.17.0.20
              Start Time:   Fri, 05 Nov 2021 17:41:24 +0000
              Labels:       app=kubernetes-bootcamp
                            pod-template-hash=59b7598c77
              Annotations:  <none>
              Status:       Pending
              IP:           172.18.0.4
              IPs:
                IP:           172.18.0.4
              Controlled By:  ReplicaSet/kubernetes-bootcamp-59b7598c77
              Containers:
                kubernetes-bootcamp:
                  Container ID:   
                  Image:          gcr.io/google-samples/kubernetes-bootcamp:v10
                  Image ID:       
                  Port:           8080/TCP
                  Host Port:      0/TCP
                  State:          Waiting
                    Reason:       ImagePullBackOff
                  Ready:          False
                  Restart Count:  0
                  Environment:    <none>
                  Mounts:
                    /var/run/secrets/kubernetes.io/serviceaccount from default-token-97nxg (ro)
              Conditions:
                Type              Status
                Initialized       True 
                Ready             False 
                ContainersReady   False 
                PodScheduled      True 
              Volumes:
                default-token-97nxg:
                  Type:        Secret (a volume populated by a Secret)
                  SecretName:  default-token-97nxg
                  Optional:    false
              QoS Class:       BestEffort
              Node-Selectors:  <none>
              Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                               node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
              Events:
                Type     Reason     Age                  From               Message
                ----     ------     ----                 ----               -------
                Normal   Scheduled  2m29s                default-scheduler  Successfully assigned default/kubernetes-bootcamp-59b7598c77-f7n6c to minikube
                Normal   Pulling    61s (x4 over 2m28s)  kubelet            Pulling image "gcr.io/google-samples/kubernetes-bootcamp:v10"
                Warning  Failed     61s (x4 over 2m27s)  kubelet            Failed to pull image "gcr.io/google-samples/kubernetes-bootcamp:v10": rpc error: code = Unknown desc = Error response from daemon: manifest for gcr.io/google-samples/kubernetes-bootcamp:v10 not found: manifest unknown: Failed to fetch "v10" from request "/v2/google-samples/kubernetes-bootcamp/manifests/v10".
                Warning  Failed     61s (x4 over 2m27s)  kubelet            Error: ErrImagePull
                Normal   BackOff    49s (x6 over 2m27s)  kubelet            Back-off pulling image "gcr.io/google-samples/kubernetes-bootcamp:v10"
                Warning  Failed     38s (x7 over 2m27s)  kubelet            Error: ImagePullBackOff
              
              
              Name:         kubernetes-bootcamp-7d44784b7c-2k7wg
              Namespace:    default
              Priority:     0
              Node:         minikube/172.17.0.20
              Start Time:   Fri, 05 Nov 2021 17:32:02 +0000
              Labels:       app=kubernetes-bootcamp
                            pod-template-hash=7d44784b7c
              Annotations:  <none>
              Status:       Running
              IP:           172.18.0.10
              IPs:
                IP:           172.18.0.10
              Controlled By:  ReplicaSet/kubernetes-bootcamp-7d44784b7c
              Containers:
                kubernetes-bootcamp:
                  Container ID:   docker://81555dad0720ca3e6609a00e7861ea311989ae49ee870165e1d3ed3e830f3185
                  Image:          jocatalin/kubernetes-bootcamp:v2
                  Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
                  Port:           8080/TCP
                  Host Port:      0/TCP
                  State:          Running
                    Started:      Fri, 05 Nov 2021 17:32:06 +0000
                  Ready:          True
                  Restart Count:  0
                  Environment:    <none>
                  Mounts:
                    /var/run/secrets/kubernetes.io/serviceaccount from default-token-97nxg (ro)
              Conditions:
                Type              Status
                Initialized       True 
                Ready             True 
                ContainersReady   True 
                PodScheduled      True 
              Volumes:
                default-token-97nxg:
                  Type:        Secret (a volume populated by a Secret)
                  SecretName:  default-token-97nxg
                  Optional:    false
              QoS Class:       BestEffort
              Node-Selectors:  <none>
              Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                               node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
              Events:
                Type    Reason     Age   From               Message
                ----    ------     ----  ----               -------
                Normal  Scheduled  11m   default-scheduler  Successfully assigned default/kubernetes-bootcamp-7d44784b7c-2k7wg to minikube
                Normal  Pulled     11m   kubelet            Container image "jocatalin/kubernetes-bootcamp:v2" already present on machine
                Normal  Created    11m   kubelet            Created container kubernetes-bootcamp
                Normal  Started    11m   kubelet            Started container kubernetes-bootcamp
              
              
              Name:         kubernetes-bootcamp-7d44784b7c-c9zpj
              Namespace:    default
              Priority:     0
              Node:         minikube/172.17.0.20
              Start Time:   Fri, 05 Nov 2021 17:32:07 +0000
              Labels:       app=kubernetes-bootcamp
                            pod-template-hash=7d44784b7c
              Annotations:  <none>
              Status:       Running
              IP:           172.18.0.13
              IPs:
                IP:           172.18.0.13
              Controlled By:  ReplicaSet/kubernetes-bootcamp-7d44784b7c
              Containers:
                kubernetes-bootcamp:
                  Container ID:   docker://e18a347d296bb115b8cdbe687ca5a3339af6670439ba45a3a22002ec1c7d72b7
                  Image:          jocatalin/kubernetes-bootcamp:v2
                  Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
                  Port:           8080/TCP
                  Host Port:      0/TCP
                  State:          Running
                    Started:      Fri, 05 Nov 2021 17:32:08 +0000
                  Ready:          True
                  Restart Count:  0
                  Environment:    <none>
                  Mounts:
                    /var/run/secrets/kubernetes.io/serviceaccount from default-token-97nxg (ro)
              Conditions:
                Type              Status
                Initialized       True 
                Ready             True 
                ContainersReady   True 
                PodScheduled      True 
              Volumes:
                default-token-97nxg:
                  Type:        Secret (a volume populated by a Secret)
                  SecretName:  default-token-97nxg
                  Optional:    false
              QoS Class:       BestEffort
              Node-Selectors:  <none>
              Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                               node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
              Events:
                Type    Reason     Age   From               Message
                ----    ------     ----  ----               -------
                Normal  Scheduled  11m   default-scheduler  Successfully assigned default/kubernetes-bootcamp-7d44784b7c-c9zpj to minikube
                Normal  Pulled     11m   kubelet            Container image "jocatalin/kubernetes-bootcamp:v2" already present on machine
                Normal  Created    11m   kubelet            Created container kubernetes-bootcamp
                Normal  Started    11m   kubelet            Started container kubernetes-bootcamp
              
              
              Name:         kubernetes-bootcamp-7d44784b7c-q6w2f
              Namespace:    default
              Priority:     0
              Node:         minikube/172.17.0.20
              Start Time:   Fri, 05 Nov 2021 17:32:03 +0000
              Labels:       app=kubernetes-bootcamp
                            pod-template-hash=7d44784b7c
              Annotations:  <none>
              Status:       Running
              IP:           172.18.0.11
              IPs:
                IP:           172.18.0.11
              Controlled By:  ReplicaSet/kubernetes-bootcamp-7d44784b7c
              Containers:
                kubernetes-bootcamp:
                  Container ID:   docker://2068ff7b62c0594b2071f7969e33d65e12d6baac9513618105955540c6edeb00
                  Image:          jocatalin/kubernetes-bootcamp:v2
                  Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
                  Port:           8080/TCP
                  Host Port:      0/TCP
                  State:          Running
                    Started:      Fri, 05 Nov 2021 17:32:06 +0000
                  Ready:          True
                  Restart Count:  0
                  Environment:    <none>
                  Mounts:
                    /var/run/secrets/kubernetes.io/serviceaccount from default-token-97nxg (ro)
              Conditions:
                Type              Status
                Initialized       True 
                Ready             True 
                ContainersReady   True 
                PodScheduled      True 
              Volumes:
                default-token-97nxg:
                  Type:        Secret (a volume populated by a Secret)
                  SecretName:  default-token-97nxg
                  Optional:    false
              QoS Class:       BestEffort
              Node-Selectors:  <none>
              Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                               node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
              Events:
                Type    Reason     Age   From               Message
                ----    ------     ----  ----               -------
                Normal  Scheduled  11m   default-scheduler  Successfully assigned default/kubernetes-bootcamp-7d44784b7c-q6w2f to minikube
                Normal  Pulled     11m   kubelet            Container image "jocatalin/kubernetes-bootcamp:v2" already present on machine
                Normal  Created    11m   kubelet            Created container kubernetes-bootcamp
                Normal  Started    11m   kubelet            Started container kubernetes-bootcamp
    • Trong phần Events cho các Pod bị ảnh hưởng, ta nhận thấy rằng phiên bản giao diện v10 không tồn tại trong repository.

  1. Để khôi phục Deployment về phiên bản giao diện cuối cùng:
    • kubectl rollout undo deployments/kubernetes-bootcamp
    • Lệnh rollout undo hoàn nguyên việc deploy về trạng thái đã biết trước đó (giao diện v2). Các bản cập nhật được chia thành các phiên bản và bạn có thể hoàn nguyên về bất kỳ Deployment nào đã biết trước đó.
  1. Kiểm tra lại Pod và để xác nhận kết quả:
    kubectl get pods
              kubectl describe pods
    • Output:
    NAME                                   READY   STATUS              RESTARTS   AGE
              kubernetes-bootcamp-59b7598c77-5bcz6   0/1     Terminating         0          9m3s
              kubernetes-bootcamp-59b7598c77-f7n6c   0/1     Terminating         0          9m3s
              kubernetes-bootcamp-7d44784b7c-2k7wg   1/1     Running             0          18m
              kubernetes-bootcamp-7d44784b7c-9s6jc   0/1     ContainerCreating   0          2s
              kubernetes-bootcamp-7d44784b7c-c9zpj   1/1     Running             0          18m
              kubernetes-bootcamp-7d44784b7c-q6w2f   1/1     Running             0          18m
    Name:         kubernetes-bootcamp-7d44784b7c-2k7wg
              Namespace:    default
              Priority:     0
              Node:         minikube/172.17.0.20
              Start Time:   Fri, 05 Nov 2021 17:32:02 +0000
              Labels:       app=kubernetes-bootcamp
                            pod-template-hash=7d44784b7c
              Annotations:  <none>
              Status:       Running
              IP:           172.18.0.10
              IPs:
                IP:           172.18.0.10
              Controlled By:  ReplicaSet/kubernetes-bootcamp-7d44784b7c
              Containers:
                kubernetes-bootcamp:
                  Container ID:   docker://81555dad0720ca3e6609a00e7861ea311989ae49ee870165e1d3ed3e830f3185
                  Image:          jocatalin/kubernetes-bootcamp:v2
                  Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
                  Port:           8080/TCP
                  Host Port:      0/TCP
                  State:          Running
                    Started:      Fri, 05 Nov 2021 17:32:06 +0000
                  Ready:          True
                  Restart Count:  0
                  Environment:    <none>
                  Mounts:
                    /var/run/secrets/kubernetes.io/serviceaccount from default-token-97nxg (ro)
              Conditions:
                Type              Status
                Initialized       True 
                Ready             True 
                ContainersReady   True 
                PodScheduled      True 
              Volumes:
                default-token-97nxg:
                  Type:        Secret (a volume populated by a Secret)
                  SecretName:  default-token-97nxg
                  Optional:    false
              QoS Class:       BestEffort
              Node-Selectors:  <none>
              Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                               node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
              Events:
                Type    Reason     Age   From               Message
                ----    ------     ----  ----               -------
                Normal  Scheduled  19m   default-scheduler  Successfully assigned default/kubernetes-bootcamp-7d44784b7c-2k7wg to minikube
                Normal  Pulled     19m   kubelet            Container image "jocatalin/kubernetes-bootcamp:v2" already present on machine
                Normal  Created    18m   kubelet            Created container kubernetes-bootcamp
                Normal  Started    18m   kubelet            Started container kubernetes-bootcamp
              
              
              Name:         kubernetes-bootcamp-7d44784b7c-9s6jc
              Namespace:    default
              Priority:     0
              Node:         minikube/172.17.0.20
              Start Time:   Fri, 05 Nov 2021 17:50:25 +0000
              Labels:       app=kubernetes-bootcamp
                            pod-template-hash=7d44784b7c
              Annotations:  <none>
              Status:       Running
              IP:           172.18.0.5
              IPs:
                IP:           172.18.0.5
              Controlled By:  ReplicaSet/kubernetes-bootcamp-7d44784b7c
              Containers:
                kubernetes-bootcamp:
                  Container ID:   docker://b66219d09960e9afae0c6a5bfdd42ce78f561ae03ce318a0ae1868c857007c68
                  Image:          jocatalin/kubernetes-bootcamp:v2
                  Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
                  Port:           8080/TCP
                  Host Port:      0/TCP
                  State:          Running
                    Started:      Fri, 05 Nov 2021 17:50:27 +0000
                  Ready:          True
                  Restart Count:  0
                  Environment:    <none>
                  Mounts:
                    /var/run/secrets/kubernetes.io/serviceaccount from default-token-97nxg (ro)
              Conditions:
                Type              Status
                Initialized       True 
                Ready             True 
                ContainersReady   True 
                PodScheduled      True 
              Volumes:
                default-token-97nxg:
                  Type:        Secret (a volume populated by a Secret)
                  SecretName:  default-token-97nxg
                  Optional:    false
              QoS Class:       BestEffort
              Node-Selectors:  <none>
              Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                               node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
              Events:
                Type    Reason     Age   From               Message
                ----    ------     ----  ----               -------
                Normal  Scheduled  40s   default-scheduler  Successfully assigned default/kubernetes-bootcamp-7d44784b7c-9s6jc to minikube
                Normal  Pulled     39s   kubelet            Container image "jocatalin/kubernetes-bootcamp:v2" already present on machine
                Normal  Created    39s   kubelet            Created container kubernetes-bootcamp
                Normal  Started    38s   kubelet            Started container kubernetes-bootcamp
              
              
              Name:         kubernetes-bootcamp-7d44784b7c-c9zpj
              Namespace:    default
              Priority:     0
              Node:         minikube/172.17.0.20
              Start Time:   Fri, 05 Nov 2021 17:32:07 +0000
              Labels:       app=kubernetes-bootcamp
                            pod-template-hash=7d44784b7c
              Annotations:  <none>
              Status:       Running
              IP:           172.18.0.13
              IPs:
                IP:           172.18.0.13
              Controlled By:  ReplicaSet/kubernetes-bootcamp-7d44784b7c
              Containers:
                kubernetes-bootcamp:
                  Container ID:   docker://e18a347d296bb115b8cdbe687ca5a3339af6670439ba45a3a22002ec1c7d72b7
                  Image:          jocatalin/kubernetes-bootcamp:v2
                  Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
                  Port:           8080/TCP
                  Host Port:      0/TCP
                  State:          Running
                    Started:      Fri, 05 Nov 2021 17:32:08 +0000
                  Ready:          True
                  Restart Count:  0
                  Environment:    <none>
                  Mounts:
                    /var/run/secrets/kubernetes.io/serviceaccount from default-token-97nxg (ro)
              Conditions:
                Type              Status
                Initialized       True 
                Ready             True 
                ContainersReady   True 
                PodScheduled      True 
              Volumes:
                default-token-97nxg:
                  Type:        Secret (a volume populated by a Secret)
                  SecretName:  default-token-97nxg
                  Optional:    false
              QoS Class:       BestEffort
              Node-Selectors:  <none>
              Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                               node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
              Events:
                Type    Reason     Age   From               Message
                ----    ------     ----  ----               -------
                Normal  Scheduled  18m   default-scheduler  Successfully assigned default/kubernetes-bootcamp-7d44784b7c-c9zpj to minikube
                Normal  Pulled     18m   kubelet            Container image "jocatalin/kubernetes-bootcamp:v2" already present on machine
                Normal  Created    18m   kubelet            Created container kubernetes-bootcamp
                Normal  Started    18m   kubelet            Started container kubernetes-bootcamp
              
              
              Name:         kubernetes-bootcamp-7d44784b7c-q6w2f
              Namespace:    default
              Priority:     0
              Node:         minikube/172.17.0.20
              Start Time:   Fri, 05 Nov 2021 17:32:03 +0000
              Labels:       app=kubernetes-bootcamp
                            pod-template-hash=7d44784b7c
              Annotations:  <none>
              Status:       Running
              IP:           172.18.0.11
              IPs:
                IP:           172.18.0.11
              Controlled By:  ReplicaSet/kubernetes-bootcamp-7d44784b7c
              Containers:
                kubernetes-bootcamp:
                  Container ID:   docker://2068ff7b62c0594b2071f7969e33d65e12d6baac9513618105955540c6edeb00
                  Image:          jocatalin/kubernetes-bootcamp:v2
                  Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
                  Port:           8080/TCP
                  Host Port:      0/TCP
                  State:          Running
                    Started:      Fri, 05 Nov 2021 17:32:06 +0000
                  Ready:          True
                  Restart Count:  0
                  Environment:    <none>
                  Mounts:
                    /var/run/secrets/kubernetes.io/serviceaccount from default-token-97nxg (ro)
              Conditions:
                Type              Status
                Initialized       True 
                Ready             True 
                ContainersReady   True 
                PodScheduled      True 
              Volumes:
                default-token-97nxg:
                  Type:        Secret (a volume populated by a Secret)
                  SecretName:  default-token-97nxg
                  Optional:    false
              QoS Class:       BestEffort
              Node-Selectors:  <none>
              Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                               node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
              Events:
                Type    Reason     Age   From               Message
                ----    ------     ----  ----               -------
                Normal  Scheduled  19m   default-scheduler  Successfully assigned default/kubernetes-bootcamp-7d44784b7c-q6w2f to minikube
                Normal  Pulled     19m   kubelet            Container image "jocatalin/kubernetes-bootcamp:v2" already present on machine
                Normal  Created    18m   kubelet            Created container kubernetes-bootcamp
                Normal  Started    18m   kubelet            Started container kubernetes-bootcamp
    • Việc khôi phục đã thành công.

Kahoot quiz

Kahoot data file

List of questions

  1. Đâu là thành phần của một cluster
    1. Node
    1. Control Variable
    1. Flag
    1. Kubernetes
  1. Lệnh kiểm tra phiên bản của minikube
    1. minikube get
    1. minikube git
    1. minikube versions
    1. minikube version
  1. Lệnh hiển thị thông tin tài nguyên của pod trong cluster
    1. kubectl gets pod
    1. kubectl manage pod
    1. kubectl get pod
    1. kubectl pod information
  1. Lệnh liệt kê các dịch vụ hiện tại trong cluster
    1. kubectl get services
    1. kubectl manage services
    1. kubectl get service
    1. kubectl service information
  1. Dùng lệnh nào sau đây để mở rộng deployment của app kubernetes-bootcamp với 4 bản sao:
    1. kubectl scale deployments/kubernetes-bootcamp --replicas=4
    1. kubectl scale deployments/kubernetes-bootcamp --replica=4
    1. kubectl scales deployments/kubernetes-bootcamp --replicas=4
    1. kubectl scales deployments/kubernetes-bootcamp --replica=4
  1. Chức năng của Pod là:
    1. đại diện cho các vùng chứa ứng dụng và tài nguyên được chia sẻ
    1. chịu trách nhiệm liên lạc giữa Control Plane và Node
  1. Lệnh kubectl exec dùng để:
    1. in nhật ký từ một container trong một pod
    1. thực hiện lệnh trên container trong pod
    1. liệt kê tài nguyên
    1. hiển thị thông tin chi tiết về tài nguyên
  1. Control Plane là:
    1. một thành phần của cluster, có khả năng điều phối các hoạt động trong cluster
    1. là một máy ảo hoặc một máy tính vật lý
  1. "Rolling update cho phép cập nhật Deployment mà không có thời gian chết" là đúng hay sai?
    1. Đúng (True)
    1. Sai (False)
  1. "Một Node không thể chứa nhiều Pod" là đúng hay sai?
    1. Đúng (True)
    1. Sai (False)

Exercises

Exercise 1: Create a cluster and Deploy and app using

Hoàn thành qwiklabs Kubernetes Engine: Qwik Start để thành thạo các bước tạo cluster, triển khai một app với kubernetes.

Exercise 2: Managing Deployments Using Kubernetes Engine

Hoàn thành qwiklabs Managing Deployments Using Kubernetes Engine để hiểu được cách quản lí deployment với kubernetes (bao gồm cách deploy một app, rolling update và scale với kubernetes)