Serial blog Nhập môn Kubernetes

Nội dung

  • Mở đầu
  • Lịch sử kubernetes
  • Các khái niệm trong kubernetes.
  • Kubernetes làm được những gì
  • Kết luận
  • Tài liệu tham khảo

Mở đầu

Kubernetes là một Platform dùng để tự động hoá việc quản lý, scaling và triển khai ứng dụng dưới dạng container hoá, Kubernetes còn gọi là Container orchestration engine. Trong serial bài viết về kubernetes này, mục tiêu là cho dù bạn là người chưa từng đụng đến kubernestes đi nữa thì cũng có thể hiểu được khái niệm k8s, và có thể tự mình triển khai k8s trên một ứng dụng thực tế.
Trong những năm gần đây, nhiều ứng dụng đã thực hiện container hoá bằng cách sử dụng docker. Trên thực tế nhiều ứng dụng sử dụng docker chạy trên môi trường production ngày càng tăng lên. Trên môi trường production, Vì việc cấu trúc hệ thống chạy bằng container chỉ sử dụng docker là rất khó khăn. Cho nên việc sử dụng một Platform gọi là Container orchestration engine như là k8s thì khá phổ biến hiện nay.
Ngoài K8s thì còn có docker swarm, DC/OS, tuy nhiên loạt bài viết này tôi chỉ đề cập về k8s, vì mấy cái kia tôi chưa đụng đến :D.
uc?id=1UhmdvzQ2Yunp1T3lvZMMLPjOULFyeGHP&export=download

Lịch sử của kubernetes

Dựa theo website của Kubernetes thì chúng được định nghĩ như sau:
“Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications.”
Kubernetes là một hệ thống mã nguồn mở để tự động triển khai, scaling, quản lý các container. Kubernetes được xây dựng bởi Google dựa trên kinh nghiệm quản lý sử dụng các container trong khi triển khai một hệ thống quản lý gọi là Borg ( nhiều lúc gọi là Omega).
Nó được phát hành vào tháng 6 năm 2014, và thời điểm ra mắt phiên bản 1.0 vào tháng 7/2015 thì nó được chuyển giao cho Cloud Native Computing Foundation (CNCF).
Trong bối cảnh có thể nói là K8s đã trở thành De facto standard thì có sự đối ứng phù hợp của những nhà cung cấp dịch vụ Cloud. Trong khoảng tháng 11/2014 Google Cloud Platform(GCP)đã bắt đầu cung cấp dịch vụ Google Container Engine (GKE, sau này là Google Kubernetes Engine). Để sử dụng k8s đã được quản lý, GKE là một lựa chọn, tuy nhiên tháng 2/2017 Microsoft Azure cũng đã release Azure Container Service (AKS), Tháng 11/2017 Amazon Web Service(AWS)cũng cho ra đời Amazon Elastic Container Service for Kubernetes(Amazon EKS).
Kubernetes được quản lý bởi những nhà cung cấp dịch vụ Cloud hàng đầu đã ra đời.

Các khái niệm trong Kubernetes.

Nhắc lại về kiến trúc của docker

uc?id=1YIf4OwtVNb4f5-XdkiICIdMOn0plBj5A&export=download
Link tham khảo: [Docker] – Part 2 – Cấu trúc và quy trình hoạt động của Docker.

Nếu cái hình phía trên có nhiều thứ bạn chưa hiểu thì mình sẽ rút gọn nó như ở ví dụ sau: Giả sử mình có 1 ứng dụng chạy bằng docker trên 1 máy. Ứng dụng web bao gồm Nginx, Mysql, php-fpm. Mình dùng docker nên mình có được kiến trúc như hình dưới đây:
uc?id=1fRlYKAK5jENdOpdW0D963q1fv_IJ89lL&export=download

Kubernetes Architecture

uc?id=1X8MR70R-MOY6UgTbAq_9iBN0nOtFeqFL&export=download
Link tham khảo: https://thenewstack.io/kubernetes-an-overview/
Là người mới nên bạn chưa thể hiểu được cái hình phía trên, không sao, mình sẽ đi từng khái niệm một.

Kubernetes Cluster.

Cluster có nghĩa là cụm, vậy Kubernetes Cluster có nghĩa là cụm các máy chạy docker có phải vậy không? không đơn giản thế đâu, nhưng trước tiên cứ hãy xem như vậy đã.
Một cluster là một tập các máy vật lý hay máy ảo được sử dụng bởi Kubernetes để chạy các ứng dụng.
Kubernetes Cluster bao gồm Nodes(master) và Nodes(worker).
uc?id=1S_jqz8wkHt9n_o7_uOSmJekqnwf45jeR&export=download
Đến đây các bạn sẽ hỏi Nodes là gì, Nodes master và Nodes worker có nhiệm vụ gì. OK, Mình sẽ trình bày ngay sau đây.

Nodes

Một node là một máy ảo hoặc máy vật lý chạy Kubernetes. Nodes hay còn gọi là docker host. Để cho không bị rối, mình tạm thời chưa nhắc đến vai trò của Nodes Master (Kubernetes master) hay Nodes worker (nodes).
Bạn hiểu Nodes như hình sau:
uc?id=1Yyxcvqtc3Ex-_e_f0_mcLx6RXpWyrJNu&export=download
Link tham khảo:Kubernetes 101: Pods, Nodes, Containers, and Clusters

Khi làm việc chỉ với một máy, sẽ gặp các vấn đề như không đủ tài nguyên, không thể backup khi sự cố xảy ra, vv. Ta nghĩ đến vấn đề join các máy tính riêng lẽ tạo thành 1 cụm, ta có Kubernetes Cluster như hình dưới đây:
uc?id=1qz2-BQ0rRJqxP8t37FRSwsWYHM1b1AdF&export=download
Link tham khảo:Kubernetes 101: Pods, Nodes, Containers, and Clusters

Pods

Bây giờ đến khái niệm Pods, nó là gì? đầu tiên các bạn chắc chắn đã biết đến khái niệm container rồi.
Pod là 1 nhóm (1 trở lên) các container thực hiện một mục đích nào đó, như là chạy software nào đó. Nhóm này chia sẻ không gian lưu trữ, địa chỉ IP với nhau. Pod thì được tạo ra hoặc xóa tùy thuộc vào yêu cầu của dự án.
Đơn vị nhỏ nhất của ứng dụng chạy Kubernetes đó là container, nhưng đơn vị quản lý cơ bản nhất thì là Pods.
Ví dụ cho dễ hiểu:
Mình có 2 ứng dụng sau:

  • backend: có 3 container: backend (chứa code php backend), nginx(cấu hình dành cho backend), fluentd (tool gửi log)
  • frontend: có 2 container: frontend (chứa code php frontend), nginx (cấu hình dành cho frontend), fluentd (tool gửi log)

Mình sẽ thiết kế theo Kubernetes là sẽ chia làm 2 pods.

  • backend-pod
  • frontend-pod
    Cụ thể các bạn theo dõi hình sau.
    uc?id=1iaXmbIkefOU2PfPCg5Ec2W7R65Yl3Wsf&export=download

Ở đây các bạn có thể hỏi 2 Pods này có thể nằm cùng trên 1 Node được không? Dĩ nhiên là được vì chúng là 2 ứng dụng độc lập, có địa chỉ IP riêng. Không gian lưu trữ cho mỗi ứng dụng (pod) thì sao? Như các bạn đã biết về khái niệm Volume ở docker rồi. Vậy thì chỉ cần chỉ định vùng lưu trữ riêng thì mỗi Pods đều không ảnh hưởng gì đến nhau.

Deployment

Đến đây thì các bạn cũng chưa thấy có gì hay ở Kubernetes cả, chỉ mới là nhóm cụm các container có liên quan với nhau thành 1 Pod. Tiếp theo mình muốn nói đến khái niệm Deployment trong Kubernetes, nó dùng để phân phối các pods cho các nodes cụ thể, mang tính dự phòng. Ví dụ như hình trên, nếu lỡ Node 1 bị die (chết server) thì ứng dụng backend coi như xong.
Đầu tiên mình muốn nói đến Replica Set. Replica Set đảm nhận vai trò tạo ra số lượng Pods giống nhau dựa vào yêu cầu và luôn luôn duy trì số lượng đó.
Giả sử quy định replicas: 3 thì nó sẽ tạo ra 3 Pods giống nhau, giả sử 1 pod ở Node (server) nào đó bị sự cố, nó sẽ tạo ra 1 Pod mới để duy trì số lượng là 3 như yêu cầu lúc đầu.
Vậy Deployment là việc định nghĩa policy update/phân phối của Replica Set. Nghĩa là sao, là nó sẽ quy định Pods gồm những container nào, các Pods được tạo ra sẽ phân phối đến các Nodes nào trong Kubernetes.
uc?id=1070PbXntD2Gr_duND5QlrE12Huts4y5U&export=download

Đến đây mình đã giới thiệu qua 1 vài khái niệm lớn trong Kubernetes. Tổng kết lại:

  • Kubernetes Cluster là 1 cụm các Nodes: Master Nodes và Worker Nodes
  • Nodes là một máy vật lý hoặc máy ảo, mỗi Node bao gồm 1 hoặc nhiều Pods
  • Pods là đơn vị quản lý container, mỗi Pod có thể có 1 hoặc nhiều container.
  • Replica Set Dùng để tạp ra nhiều Pods giống nhau
  • Deployment dùng để quản lý việc tạo Pod và phân bổ các Pod vào các Node quy định.

Kubernetes còn hàng đống các khái niệm mà mình không thể trình bày hết trong bài viết này. Như đã nói, mình sẽ viết một series blog về Kubernetes, nên mình sẽ nói về cơ chế hoạt động cùng hình ảnh minh hoạ cụ thể ở các phần sau.

Kubernetes làm được những gì

Bằng việc sử dụng docker, trên 1 host bạn có thể tạo ra nhiều container, tuy nhiên nếu bạn có ý định sử dụng trên môi trường production thì phải bắt buộc phải nghĩ đến những vấn đề dưới đây:

  • Việc quản lý hàng loạt docket host
  • Container Scheduling
  • Rolling update
  • Scaling/Auto Scaling
  • Monitor vòng đời và tình trạng sống chết của container.
  • Self-hearing trong trường hợp có lỗi xãy ra. (Có khả năng phát hiện và tự correct lỗi)
  • Service discovery
  • Load balancing
  • Quản lý data
  • Quản lý work node
  • Quản lý log
  • Infrastructure as Code
  • Sự liên kết và mở rộng với các hệ thống khác

Bằng việc sử dụng một Container orchestration engine như K8s có thể giải quyết được nhưng vấn đề trên đây. Trong trường hợp không sử dụng k8s, Thì sẽ phải cần thiết tạo ra cơ chế tự động hoá cho những cái kể trên, theo tôi thì không có tính khả thi lắm. Trong trường hợp sử dụng máy ảo thông thường VMs Thì nó chính là việc thực hiện tự động hoá một phần bằng việc sử dụng AWS CloudFormation hay OpenStack Heat. K8s cũng quản lý thực thi các container sử dụng YAML để viết các Manifest.
Dưới đây là một ví dụ:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-server
spec:
  replicas: 1
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx-server
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: "app"
                operator: In
                values:
                  - develop
      containers:
      - name: nginx
        image: "nginx:latest"
        imagePullPolicy: "Always"
        ports:
          - containerPort: 80
        volumeMounts:
        - mountPath: /etc/nginx
          name: nginx-conf
        - mountPath: /var/log/nginx
          name: nginx-log

Kubernetes quản lý các docker host và cấu trúc container cluster. Thêm nữa, khi thực thi các container trên K8s, Bằng cách thực hiện replicas (tạo ra nhiều container giống nhau) làm cho hệ thống có sức chịu lỗi cao và tự động thực hiện load balancing.
Thêm nữa, thông qua cơ chế load balancing, chúng ta có thể tăng giảm số lượng container replica (auto scaling).
uc?id=1WCu3JDEOeYp4MapPt5VGYZk_pFiMptJh&export=download
Image: scaling/auto scaling

Khi thực hiện phân bổ container vào các Node (docker host), dựa trên các loại docker host kiểu như "Disk SSD" hay "số lượng clock của CPU cao" v.v Hoặc dựa trên loại Workload kiểu như "Disk I/O quá nhiều", "Băng thông đến một container chỉ định quá nhiều" v.v, K8s sẽ ý thực được việc affinity hay anti-affinity và thực hiện Scheduling một cách hợp lý cho chúng ta.
uc?id=1NRbNu-FRp26rAfH_j23SQ79FjVDoYqDh&export=download
Image: Scheduling

Trong trường hợp không được chỉ định host cụ thể, K8s sẽ thực thực hiện scheduling tuỳ thuộc vào tình trạng CPU, memmory của docker host có trống hay không, chính vì vậy, chúng ta không cần thiết quan tâm đến việc quản lý bố trí container vào các docker host như thế nào. Hơn nữa, trường hợp resource không đủ, thì việc auto scheduling của K8s cluster cũng sẽ được thực hiện tự động.
uc?id=1jwVxqEla5jPLiGhpOA73I-QzsBk6PXkS&export=download
Image: k8s resource management

Trên quan điểm tính chịu lỗi cao, K8s thực hiện monitor các container theo tiêu chuẩn. Trong trường hợp hi hữu nào đó, khi một container process bị stop, K8s sẽ thực hiện Self-hearing bằng cách scheduling một container nữa. Self-hearing là một khái niệm khá quan trọng trong k8s, trong trường hợp có một node nào đó trong cluster xảy ra vấn đề (có thể là bị die, hay node đó được move đi). Cơ chế self-hearing sẽ sẽ tự động phục hồi mà không ảnh hưởng đến service.
Thêm nữa, ngoài việc monitor hệ thống, k8s còn có khả năng thiết lập helth check bằng HTTP/TCP script.
uc?id=1oSfYJe3gwF35a0gRARlPzHMIvYRvPg1B&export=download
Image: auto hearing.

Trường hợp sau khi auto scaling, phát sinh một vấn đề của endpoint đến container. Trong trường hợp sử dụng máy ảo, bằng việc setting load balancing endpoint sẽ được sử dụng như một VIP. K8s cũng có một chức năng tương tự như vậy đó là Service. Service của k8s cung cấp chức năng load balancing cho hàng loạt các container được chỉ định. Việc tự động thêm, xoá container thời điểm scale là điều đương nhiên, khi một container xảy ra sự cố thì tự động cách ly. Khi thực hiện rolling update container thì việc đầu tiên k8s sẽ làm là cách ly container cho chúng ta, vì vậy k8s có thể đảm nhận việc quản lý các endpoint ở mức SLA cao.
Thêm nữa, trường hợp cấu trúc một hệ thống sử dụng docker, tôi nghĩ rằng nên phân tách nhỏ các chức năng trong Microservice architecture. Trong Microservice architecture, để sử dụng các image container được tạo ra tương ứng với từng chức năng và deploy chúng thì chức năng Service discovery thực sự cần thiết.
uc?id=11DaKIuULFmeYM8X65ssExezc2RpSVO-v&export=download

K8s là một Platform nhưng có khả năng liên kết tốt với các hệ sinh thái bên ngoài, có nhiều middleware chạy trên các service của k8s, trong tương lai chắc chắn sẽ còn nhiều hơn nữa.

  • Ansible: Deploy container tới Kubernetes
  • Apache Ignite: Sử dụng Service Discovery của Kubernetes, tự động tạo và scaling k8s clkuster
  • Fluentd: gửi log của container trong Kubernetes
  • Jenkins: Deploy container đến Kubernetes
  • OpenStack:Cấu trúc k8s liên kết với Cloud
  • Prometheus: Monitor Kubernetes
  • Spark: Thực thi native job trên Kubernetes(thay thế cho YARN)
  • Spinnaker:Deploy container đến Kubernetes
  • v.v

Thêm nữa, K8s chuẩn bị một vài cơ thế để có thể mở rộng, thực thi chức năng độc lập, nó có thể sử dụng platform như là một framework. Bằng cách sử dụng khả năng mở rộng, chúng ta có thể thực hiện release một ReplicaSet mà k8s cung cấp.

Kết luận

Bài viết này tôi đã giới thiệu đến các bạn khái lược về k8s, không biết các bạn cảm nhận thế nào.
Việc sử dụng docker trên môi trường Production mà không sử dụng Container orchestration engine như K8s, Thì những tính năng tôi sẽ dự định viết tới thời điểm này là cần thiết cho bạn. Nếu sử dụng k8s, bạn có thể sử dụng cơ chế tự động hoá Borg được nghĩ ra bởi những người tiền nhiệm. Để thực hiện được những công việc tự động hoá như vậy với VMs thông thường, chúng ta cần thiết phải chuẩn bị những thứ như là: Sử dụng CloudFormation, tạo ra cơ chế load balancing, cơ chế update application. Nhưng với việc sử dụng k8s, bạn có thể tận dụng được tính portability và Light weight của container và phát triển hệ thống mức High cycle.

Bài viết tiếp theo, tôi sẽ trình bày về [Lựa chọn môi trường Kubernetes].

Tài liệu tham khảo

  1. https://thenewstack.io/kubernetes-an-overview/
  2. https://luanbn.wordpress.com/2015/08/27/docker-part-2-cau-truc-va-quy-trinh-hoat-dong-cua-docker/
  3. https://medium.com/google-cloud/kubernetes-101-pods-nodes-containers-and-clusters-c1509e409e16
  4. https://thinkit.co.jp/article/13289