Cloud kietna

Bài 4: Container

Bài 4: Container

Bài 4: Container

Table of Contents

1. Tìm hiểu về kiến trúc docker engine

1.1. Giới thiệu về Docker Engine

  • Docker Engine là phần cốt lõi của Docker
    • Công cụ để đóng gói ứng dụng
    • Xây dựng theo kiểu kiến trúc client-server
    • Cài đặt trên máy Host

1.2. Các thành phần của Docker Engine

  • Có 3 thành phần
  • Server: Docker Daemon dùng để tạo và quản lý các images, containers, networks, volumes.
  • Rest API: Controller cho Docker Daemon, chỉ ra những gì Docker Daemon sẽ làm
  • Client: Công cụ giúp người dùng giao tiếp với Docker host
    • Thông qua Command trong Terminal (Docker CLI)
    • Docker Client sử dụng API gửi lệnh tới Docker Daemon

2. Docker Image

2.1. Giới thiệu về Docker Image

  • Một container image là một gói được chuẩn hóa chứa tất cả các file, tệp nhị phân, thư viện và file cấu hình để chạy một container

2.2. Hai yếu tố quan trọng của một images

  • Images là bất biến, khi một images được tạo, nó không để được chỉnh sửa, bạn chỉ có thể tạo một image mới và thêm thay đổi lên trên nó.
  • Image được tạo thành từ nhiều Layer xếp chồng lên nhau
    • Bên trong là một hệ điều hành thu gọn
    • Các phần phụ thuộc (Dependencies)
    • Mỗi lớp thể hiện một tập hợp các file hệ thống giúp thêm, xóa, sửa file
  • Ví dụ: Để xây dựng một App dựa trên Python
    • Bắt đầu từ Python image
    • Thêm các layer để cài các Dependencies
    • Thêm mã nguồn
    • Giúp tập trung vào ứng dụng, thay vì tập trung vào Python

Untitled

2.3. Image Layer

  • Ví dụ về Image Layer
    • Lớp 1 chứa hệ điều hành và các câu lệnh cơ bản, và một trình quản lí gói (chẳng hạn như apt)
    • Lớp 2 chứa Python runtime và pip để quản lí các dependency
    • Lớp 3 chứa file requirements.txt của ứng dụng
    • Lớp 4 cài đặt các phần phụ thuộc (dependencies) của ứng dụng
    • Lớp 5 chứa mã nguồn ứng dụng

Untitled

  • Sắp xếp các lớp
    • Các lớp được sắp xếp bằng một bộ nhớ có thể định địa chỉ nội dung và một hệ thống file hợp nhất
    • Cách hoạt động
      • Khi mỗi layer được tải về, nó sẽ được giải nén ra thư mục riêng nằm trên hệ thống file của host
      • Khi bạn chạy container từ image, một hệ thống file thống nhất được tạo ra nơi các lớp sẽ được sắp xếp chồng lên nhau, tạo ra một view mới và thống nhất
      • Khi container được khởi động, thư mục gốc được đặt về vị trí của thư mục thống nhất, sử dụng chroot
    • Khi hệ thống file thống nhất được tạo, ngoài các lớp của image, một thư mục riêng được tạo ra chỉ để chạy các container
      • Cho phép các container có thể thực hiện những thay đổi trên hệ thống file mà vẫn giữ nguyên các layer gốc của image
      • Cho phép chạy nhiều containers

2.4. Một số tác vụ liên quan tới images

  • Build Image: Build một image dựa trên Dockerfile
  • Tagging images: Gán tên cho Image, xác định nơi mà images sẽ được phân phối
  • Publishing Images: Quá trình phân phối hoặc chia sẻ image vừa tạo thông qua container registry

2.5 Một số cách giữ cho images được nhỏ gọn

  • Bắt đầu băng một base image thích hợp
  • Sử dụng multistage builds
  • Nếu có nhiều images với nhiều điểm chung thì nên tạo một base image riêng
  • Xem xét việc dùng production image là base image của debug image, các hoạt động kiểm thử. gỡ lỗi thêm lên trên đầu của production image
  • Khi build image, luôn tag chúng với những tag hữu ích như prod, test

2.6. Một số lưu ý về bảo mật khi build image

  • Chọn đúng base image được cung cấp chính thứuc (Official Images) hoặc từ nhà cung cấp được xác thực (Verified Publisher)
  • Bảo mật code và các phần phụ thuộc
  • Chọn một base image tối giản chỉ chứa những packages thật cần thiết
  • Sử dụng multi-stage builds để tối ưu hóa image
  • Theo dõi cẩn thận công cụ và các phần phụ thuộc đã add vào images
  • Đảm bảo đã quét image tại từng công đoạn trong vòng đời phát triển
  • Kiểm tra images thường xuyên để phát hiện các lỗ hổng bảo mật

3. Docker Volume

3.1. Giới thiệu

  • Docker volume là cơ chế tạo và sử dụng dữ liệu của Docker, có nhiệm vụ lưu trữ dữ liệu độc lập với vòng đời Container

3.2. So sánh Volume và Bind Mounts

  • Volume sử dụng tối ưu hơn bind mounts ở các đặc điểm sau
    • Volumes dễ dàng backup hay di chuyển hơn bind mounts
    • Có thể quản lí volumes qua Docker CLI hoặc Docker API
    • Volumes hoạt động tốt ở cả Container Linux và Windows
    • Volumes có thể chia sẻ an toàn hơn giữa các containers
    • Volumes drivers cho phép bạn lưu trữ volumes ở host từ xa hoặc trên đám mây, mã hóa nội dung của volumes hoặc thêm các tính năng khác
    • Volume mới có thể chứa các nội dung đã được phân phối trước đó bởi một container
    • Volume mang lại hiệu năng cao hơn

3.3. Các trường hợp sử dụng Docker Volume

  • Giữ lại dữ liệu một Container bị xóa
  • Để chia sẻ dữ liệu giữa máy chủ vật lý và Docker Container
  • Chia sẻ dữ liệu giữa các Docker Container

Untitled

  • Lưu ý: Với các dữ liệu không cần thiết phải lưu trữ vĩnh viễn, cân nhắc sử dụng tmpfs mount để tăng cường hiệu năng bằng cách viết vào layer writable của container

4. Docker network

  • Có nhiệm vụ cung cấp private network để các container trên một host có thể liên lạc được với nhau
  • Hoặc các Container trên nhiều host có thể liên lạc được với nhau

5. DockerFile

5.1. Giới thiệu

  • Dockerfile là một file dạng text không có phần đuổi mở rộng, chứa các đặc tả về môi trường thực thi phần mềm, cấu trúc cho Docker Image
  • Docker Image tạo ra tự động bằng cách đọc các chỉ dẫn trong Dockerfile
  • Từ những câu lệnh đó, Docker sẽ build ra Docker Image

Untitled

5.2. Các chỉ dẫn trong Dockerfile

Chỉ dẫnGiải thích
ADDThêm một file hoặc một thư mục
ARGSử dụng biến build-time
CMDChỉ định câu lệnh mặc định
COPYSao chép file và thư mục
ENTRYPOINTChỉ định đường dẫn thực thi mặc định
ENVCài đặt các biến môi trường
EXPOSEMô tả cổng mà ứng dụng sẽ hoạt động
FROMTạo một build stage từ một base image
HEALTHCHECKKiểm tra container trước khi khởi động
LABELThêm một metadata vào một image
MAINTAINERNêu lên tác giả của một image
ONBUILDĐưa ra chỉ dẫn khi image được dùng trong một build
RUNThực thi câu lệnh build
SHELLCài đặt shell mặc định cho một image
STOPSIGNALChỉ định tín hiệu gọi hệ thống mặc định khi thoát một container
USERCài đặt User và Group ID
VOLUMETạo volume mount
WORKDIRThay đổi thư mục hoạt động

5.3. Các lưu ý khi viết DockerFile

  • Sử dụng Multi-stage build
    • Cho phép giảm kích thước của image cuối cùng
    • Bằng cách phân tách rõ ràng giữa việc xây dựng image và output cuối cùng
    • Đảm bảo kết quả cuối cùng chỉ chứa những file thực sự cần thiết để chạy ứng dụng
  • Loại trừ bằng file .dockerignore
    • Cấu trúc giống như file .gitignore
    • Để loại trừ các file không liên quan tới build, mà không cần cấu trúc lại mã nguồn
  • Tạo ra các Container mang tính tạm thời
    • Những image được định nghĩa trong Dockerfile nên tạo ra các containers có tính không bền nhất có thể
    • Tính không bền có nghĩa là container có thể dừng và xóa sau đó xây dựng lại và thay thế việc setup và cấu hình là tối thiểu
  • Không cài những package không cần thiết
  • Phân rã ứng dụng của bạn
    • Mỗi container chỉ nên đảm nhận một nhiệm vụ duy nhất
    • Phân rã ứng dụng giúp dễ dàng nhân bản theo hướng dọc và sử dụng lại container
  • Sắp xếp các tham số nhiều dòng
    • Nên sắp xếp các tham số nhiều dòng theo thứ tự chữ cái, và dùng \ để xuống dùng
  • Tận dụng build cache
  • Gắn chặt base image với phiên bản của chúng để tránh lỗi
    • Image Tag là có thể thay đổi

6. Docker Container

Untitled

Untitled

  • Container là một tiến trình tách biệt cho mỗi thành phần trong ứng dụng của bạn
  • Container có các đặc điểm
    • Tự chứa: Mỗi Container có mọi thứ nó cần để hoạt động và không bị phụ thuộc vào bất cứ môi trường nào có trong máy
    • Tách biệt: Mỗi Container chạy trong môi trường riêng của nó, do đó có rất ít tương tác với máy host hay các container khác, tăng cường bảo mật của ứng dụng
    • Độc lập: Mỗi Container được quản lí độc lập, xóa một container sẽ không ảnh hưởng tới những container khác
    • Gọn nhẹ: Container có thể chạy ở mọi nơi, từ máy cá nhân tới trung tâm dữ liệu hay trên đám mây
  • Một Image có thể được sử dụng để tạo 1 hay nhiều container
  • Có thể create, start, stop, move, delete dựa trên Docker API hoặc Docker CLI
  • Trên hệ điều hành, ta cài đặt container engine là docker. Sau đó container sẽ lấy các tài nguyên hệ điều hành và ghép chúng lại thành các cấu trúc riêng biệt được gọi là container

Untitled

  • Mỗi Container sẽ bao gồm mọi thứ cần thiết để chạy
    • Code, Runtime, System tools, System libraries, Setting
    • Mỗi containter như một hệ điều hành thực sự, bên trong mỗi container sẽ chạy một ứng dụng
  • Container và VM có sự cách ly và phân bổ tài nguyên tương tự nhưng có chức năng khác nhau
    • Container ảo hóa hệ điều hành
    • VM ảo hóa phần cứng
  • Quy trình đưa một ứng dụng chạy trong Container
    • Chuẩn bị source code, các phần phụ thuộc
    • Tạo Dockerfile mô tả app, các phụ thuộc, cách khởi chạy app
    • Build Dockerfile thành Image
    • Push image mới build vào registry
    • Chạy container từ image

7. Docker-compose

Untitled

  • Một cách sử dụng Docker hiệu quả là mỗi container sẽ hoàn thành nhiệm vụ riêng của nó
  • Docker-compose là công cụ dùng để định nghĩa và run multi-container cho Docker app
  • Với compose bạn dùng file YAML để config các services cho ứng dụng của bạn, dịnh nghĩa các container cần chạy, cách chúng kết nối với nhau.

8. Docker Swarm

8.1. Orchestration

  • Orchestration là thuật ngữ chỉ việc lên lịch container, quản lí cụm và khả năng cung cấp các máy chủ bổ sung
  • Container Orchestration làm tất cả những việc quản lý vòng đời của container như
    • Cung cấp và triển khai Container
    • Quản lí Cluster
    • Mở rộng hoặc loại bỏ các Containers để phân bố ứng dụng tải đồng đều trên cơ sở hạ tầng máy chủ
    • Di chuyển containers từ máy host này sang máy host khác nếu thiếu tài nguyên trong máy host nào đó, hoặc nếu một host nào đó die

8.2. Giới thiệu Docker Swarm

  • Docker Swarm là một trong những giải
  • Docker Swarm là công cụ native clustering cho Docker
  • Cho phép có thể gom một số Docker host với nhau thành dạng cụm (Cluster) và có thể xem nó như một máy chủ Docker ảo duy nhất
  • Hỗ trợ việc tạo và quản lí các container hoặc các hệ thống Container Orchestration

Untitled

8.3. Lợi ích của Docker Swarm

  • Tận dụng sức mạnh của Containers, scale hệ thống: Container cho phép developer triển khai các ứng dụng hoặc dịch vụ trong môi trường ảo độc lập
  • Đảm bảo tính khả dụng của dịch vụ cao: Docker Swarm có một trình quản lí có thể phân công nhiệm vụ cho các Worker Node. Bằng cách triển khai nhiều trình quản lí, có thể đảm bảo rằng hệ thống có thể tiếp tục hoạt động ngay cả khi một trong các Manager node bị lỗi
  • Cân bằng tải tự động: Docker swarm lên lịch các tác vụ bằng nhiều phương pháp khác nhau để đảm bảo rằng có đủ tài nguyên cho tất cả containers, giúp đảm bảo khối lượng công việc container được chỉ định chạy trên máy chủ phù hợp nhất để đạt hiệu quả tối ưu

8.4. Thành phần của Docker Swarm

8.4.1. Swarm (Cluster)

  • Tập hợp các node có ít nhất một node chính và một số node worker có thể là máy ảo hoặc vật lý

8.4.2. Node

  • Mỗi node của một Docker Swarm là một Docker Host, có 2 loại Node
  • Manager Node: Node nắm mọi quyền quản lí và phân phối công việc cho các Node còn lại (Worker Node) trong Swarm
    • Thông thường chỉ có 1 Manager Node trong Swarm
    • Thực hiện các chức năng
      • Phân phối công việc (Nhiệm vụ) cho các node worker
      • Quản lý trạng thái của swarm mà nó thuộc về
  • Worker Node: Node thuộc Swarm nhưng không phải Node Manager.
    • Các Node Worker chạy các tác vụ được phân phối bởi node manager
    • Mỗi Node Worker chạy một agent (Tác nhân) báo cáo lại cho node master về trạng thái của các tác vụ được gán cho nó
    • Node Manager có thể theo dõi các dịch vụ và tác vụ đang chạy trong swarm

8.4.3. Service

  • Sử dụng Service definition để khai báo thông tin về Image, số lượng Containers - replicas, network, ports và storages
  • Dựa trên khai báo này, manager nodes chia tách service thành các đơn vị tasks. phân phối đến work nodes
  • Nếu một worker node không hoạt động vì lí do nào đó, manager node sẽ điều hướng tasks sang những worker node khác để đảm bảo trạng thái yêu cầu dịch vụ

8.4.4. Task

Untitled

  • Swarm định nghĩa task là một container đang thực thi một phần công việc yêu cầu trong swarm service, và đặt dưới sự quản lí của Manager Nodes
  • Các node manager gán các task cho các node worker, và sau khi việc gán này, task không thể chuyển sang cho một worker khác, nếu task thất bại trong bộ bản sao, người quản lý sẽ chỉ định một phiên bản mới của tác vụ đó cho một node có sẵn khác trong swarm
  • Swarm định nghĩa Task là một container đang thực thi một phần công việc yêu cầu trong swarm service, và đặt dưới sự quản lý của manager node
  • Các node manager gán các task cho các node worker, và sau khi việc gán này, task không thể chuyển sang một worker khác. Nếu task thất bại trong bộ bản sao, người quản lý sẽ chỉ định một phiên bản mới của tác vụ đó cho một node có sẵn khác trong swarm

8.5. Tính năng của Docker Swarm

  • Quản lí Cluster được tích hợp với Docker Engine
    • Sử dụng Docker CLI để tạo ra swarm để triển khai dịch vụ

Untitled

Untitled

  • Triển khai phân tán
    • Thay vì xử lí các khác biệt giữa vai trò của các node trong thời gian triển khai
    • Docker Engine sẽ xử lí bất kỳ tác vụ nào đang chạy
    • Có thể triển khai cả manager node và worker node sử dụng Docker Engine
    • Có thể tạo ra một Docker Swarm hoàn chỉnh chỉ từ một image duy nhất

Untitled

Untitled

  • Scaling
    • Đối với mỗi dịch vụ triển khai trong Docker Swarm, bạn có thể khai báo số lượng task muốn chạy
    • Khi bạn mở rộng quy mô hoặc ngược lại, Docker Swarm sẽ tự động điều chỉnh bằng cách thêm hoặc xóa task để duy trì trạng thái mong muốn - tình trạng hệ thống ta cần đạt được
  • Đảm bảo tính ổn định
    • Docker Swarm liên tục giám sát trạng thái của cluster và giải quyết bất kỳ sự thay đổi nào giữa trạng thái thực tế và trạng thái mong muốn dự trên các quyết định của bạn
  • Multi-host networking
    • Có thể khai báo overlay network cho các dịch vụ trong Swarm
    • Docker Swarm sẽ tự động quản lý và gán địa chỉ IP cho mỗi Container trên Overlay Network khi nó khởi tạo hoặc update ứng dụng
  • Service Discovery
    • Swarm Manager Node sẽ chỉ định mỗi dịch vụ trong Docker Swarm ứng với một trên DNS duy nhất và cân bằng tải các containers đang chạy
    • Ta có thể thực hiện truy vấn tất cả các Containers đang chạy trong Swarm thông qua một DNS Server được nhúng vào Swarm
  • Cân bằng tải: Bạn có thể expose ports cho các dịch vụ tới một load balancer bên ngoài. Trong Swarm, cho phép bạn chỉ định làm thế nào để phân phối Services giữua các node
    • Swarm Manager sử dụng Network ingress load balancing để đưa các service ra bên ngoài Swarm. Swarm Manager có thể tự động đưa các service lên các Port chưa sử dụng. Hoặc người dùng cũng có thể tự động xác định Port mà service sẽ được gán vào
    • Các ứng dụng bên ngoài có thể truy cập vào service thông qua các Published Port ở bất kỳ node nào trong cluster kể cả node đó có service này hay không. Tất cả các node trong Swarm đều sẽ kết nối đến Router Ingress để kết nối đến các task đang hoạt động
    • Bên trong Swarm Mode mỗi một service đều sẽ được gán cho một DNS nội bộ để truy cập, Swarm Manager sẽ sử dụng khả năng load balancing nội bộ để gửi các yêu cầu đến các service trong cluster dựa theo DNS của Service đó
  • Rolling Update
    • Tại một thời điểm, ta có thể áp dụng việc cập nhật ứng dụng (Chủ yếu là phiên bản images). Nếu có lỗi phát sinh xảy ra, ta có thể quay lại phiên bản trước của services
  • Tính khả dụng cao, cho phép sao chép trạng thái
    • Docker Swarm cho phép nhân bản trạng thái của Docker node trong Swarm

Untitled

  • Với Docker Swarm thay vì có một manager và manager node có thể bị lỗi khiến Swarm không được cung cấp thì ta có thể triển khai nhiều Manager Node cùng một lúc

Untitled

  • Khi một Manager Node đang hoạt động bị crash

Untitled

  • Manager Node sẽ được tự động chuyển chức năng quản lí sang node backup

Untitled

9. Kubernetes

9.1. Giới thiệu

  • Kubernetes là nền tảng mã nguồn mở, có thể mở rộng để quản lí các container và service, giúp thuận lợi trong việc cấu hình và tự động hóa việc triển khai ứng dụng
  • Kubernetes cung cấp một framework để chạy các hệ thống phân tán một cách mạnh mẽ, đảm nhận việc nhân bản và chuyển đổi dự phòng cho ứng dụng của bạn, cung cấp các deployment template

9.2. Các tính năng được cung cấp

  • Service Discovery và cân bằng tải
    • Kubernetes có thể cho phép truy cập ở ngoài ào một container sử dụng DNS hoặc địa chỉ IP
    • Nếu Traffic truy cập tới một Container cao, có thể cân bằng tải hoặc phân phối lưu lượng mạng để việc triển khai được ổn định
  • Điều phối bộ nhớ
    • Kubernetes cho phép bạn tự động mount một hệ thống lưu trữ mà bạn chọn
  • Tự động rollouts và rollbacks
    • Bạn có thể mô tả trạng thái mong muốn cho các container được triển khai và có thể thay đổi trạng thái thực tế sang một trạng thái mong muốn với tần suất được kiểm soát
  • Đóng gói tự động
    • Bạn cung cấp cho Kubernetes một cluster gồm các node mà nó có thể sử dụng để chạy các tác vụ được đóng gói
    • Cung cấp thông tin mỗi container cần bao nhiêu CPU và RAM và Kubernetes có thể điều phối container đến các node để tận dụng tài nguyên
  • Tự phục hồi
    • Kubernetes có thể khởi động lại các container bị lỗi, thay thế các container, xóa các container không phản hồi lại các cấu hình health check do người dùng xác định
  • Quản lý cấu hình và bảo mật
    • Kubernetes cho phép bạn lưu trữ và quản lý các thông tin nhạy cảm như: password, OAuth token và SSH key. Bạn có thể triển khai và cập nhật lại secret và cấu hình ứng dụng mà không cần build lại các container image và không lộ secret key trong cấu hình

9.3. Kiến trúc của Kubernetes

  • K8s Cluster bao gồm nhiều node, trên mỗi node sẽ cần chạy một kubelet (Chương trình chạy k8s)
  • Cần một máy để làm chủ cluster, trên đó sẽ triển khai API server, scheduler
  • Các máy còn lại sẽ chạy kubelet để sinh ra các Container

Untitled

9.3.1. Master Server

Untitled

  • Etcd: Có thể liên kết cài đặt với từng node thông qua etcd
  • API Server
    • Server cung cấp Kubernetes API
    • Có nhiệm vụ đặt Pod vào Node
    • Đồng bộ hóa thông tin của Pod bằng REST API tiếp nhận cài đặt của pod/service/replicationController
  • Controller Manager Service
    • Quản lí tất cả các bộ điều khiển xử lý các tác vụ thông thường trong cluster
    • Bao gồm
      • Node Controller, Replication Controller, Endpoints Controller, Service Account and Token Controller
    • Chi tiết hoạt động này được ghi vào etcd, nơi controller manager theo dõi sự thay đổi thông qua API Server
  • Scheduler Service
    • Giám sát việc sử dụng tài nguyên trên mỗi máy chủ để đảm bảo rằng hệ thống không bị quá tải
    • Nắm được tổng tài nguyên có sẵn trên mỗi máy chủ, cũng như các tài nguyên được phân bổ cho các khối lượng công việc hiện có được gán trên mỗi máy chủ
  • Dashboard (Optional)
    • Giao diện web Kubernetes giúp đơn giản hóa các tương tác của người dùng Kubernetes cluster với máy chủ API

9.3.2. Node Server

Untitled

  • Pod là 1 nhóm các container thực hiện một mục đích nào đó
    • Nhóm này chia sẻ khôn 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
  • Service
    • Do Pod tuổi thọ ngắn, không đảm bảo địa chỉ IP cố định, việc giao tiếp trở nên khó khăn
    • K8s giới thiệu về dịch vụ, nó là một lớp nằm trên một số nhóm Pod. Được gán IP tĩnh và có thể trỏ Domain
    • Có thể thực hiện cân bằng tải
    • Mỗi service gán một domain do người dùng lựa chọn, Domain được quản lí bởi hẹ ethống name server SkyDNS nội bộ của k8s

Untitled

  • Persistent Volumes

    • K8s sử dụng hệ thống lưu trữ network, lưu vào hệ thống storage khác (NFS, GlusterFS,…)

    Untitled

  • Namespaces

    • Công cụ dùng để nhóm, tách nhóm các đối tượng
    • Công cụ để kiểm soát truy cập, kiểm soát truy cập network, quản lý resource và quoting

Untitled

  • Ingress rules
    • Dùng để quản lý network ra và vào các service và pod

Untitled

  • Network policies
    • Định nghĩa các quy tắc truy cập mạng giữa các Pod bên trong Cluster
  • ConfigMaps and Secrets
    • ConfigMap là giải pháp để đưa 1 file config & đặt các ENV hay set các argument khi gọi câu lệnh
    • ConfigMap là một cục config, mà pod nào cần thì chỉ định, giúp dễ dàng chia sẻ file cấu hình
  • Controller
    • Deployment: Khi ta muốn Deploy một dịch vụ nào đó, ta tạo ra Pod bằng cách tạo ra một deployment (hoặc statefulSets, hoặc khái niệm tương đương)
      • statefulSets dùng khi ta cần các service bật lên theo thứ tự nhất định
    • DaemonSet thường dành cho các dịch vụ cần chạy trên tất cả các node
      • Ví dụ fluentd để collect log trên tất cả các node
    • statefulSets: Một file “manifest” đặt trong thư mục chỉ định bởi kubelet, các pod này sẽ được chạy khi kubelet chạy, không thể điều khiển chúng bằng kubectl
  • Helm
    • Package Manager của k8s

9.3.3. Pods

  • Pod là thành phần đơn vị nhỏ nhất để Kubernetes thực hiện việc nhân bản (replication)
  • Kubernetes có thể nhân bản ra nhiều Pod giống nhau để tránh quá tải hoặc để đảm bảo tính sẵn sàng (High availability)
  • Pod có thể có nhiều Container với sự phối hợp chặt chẽ và sự chia sẻ tài nguyên ổ đĩa, mạng cho nhau

9.3.4. Deployment

  • Trong thực tế ít khi triển khai ứng dụng bằng cách tạo Pod trực tiếp
  • Ứng dụng thường được triển khai dưới dạng Deployment, StatefulSet, DaemonSet hay Job/Cronjob.
  • Deployment là một tài nguyên K8S giúp ta quản lý các Pod và ReplicaSet
  • ReplicaSet là một tài nguyên trên K8S có mục đích là duy trì một trạng thái ổn định của một bộ các Pod ở một thời điểm nhất định
    • Có 2 thôgn tin quan trọng là : Thông tin cấu hình và số lượng Pod
    • ReplicaSet Controller đảm bảo số lượng Pod được khai báo trong ReplicaSet này luôn đảm bảo đúng bằng số lượng Pod mong muốn
  • Ứng dụng của Deployment
    • Tạo Deployment để triển khai một ReplicaSet
    • Khai báo trạng thái mới của Pod
    • Scale up/down số lượng Pod của một ứng dụng
    • Rollout/Rollback một ứng dụng

9.3.5. Service

  • Service giúp chúng ta giải quyết các vấn đề
    • Expose dịch vụ ra bên ngoài k8s
    • Client có thể kết nối trực tiếp tới service qua NodePort hoặc qua Ingress
    • Đóng vai trò LoadBalancer cho các Pod ứng dụng mà Service quản lí. Khi các Pod thay đổi thì Client chỉ cần quan tâm tới đối tượng Service.
  • Service là một cách định nghĩa các bộ Pod và cách thức truy cập vào Pod

9.3.6. Ingress

  • Sử dụng NodePort có một số hạn chế
    • Service được expose hoàn toàn ra ngoài
    • Phải dùng qua port NodePort, thay vì Port HTTP/HTTPS
    • Số lượng Port hạn chế (30000-32767)
  • Sử dụng Ingress
    • Service ứng dụng được Expose dạng ClusterIP, sau đó expose ra bên ngoài qua Ingress
      • Người dùng chỉ thực sự kết nối tới Ingress Controller
    • Có thể dùng thêm External LoadBalancer bên ngoài để trỏ tới Ingress Controller
    • Không bị hạn chế bởi số lượng Port mà NodePort có thể cung cấp
  • Ingress là gì
    • Ingress mở và phân lường các kết nối HTTP và HTTPS từ bên ngoài k8s cluster vào các services bên trong cluster
    • Việc phân luồng được quản lý bởi các rule
    • Việc thực thi được thực hiện bởi Ingress Controller

Untitled

  • Cơ chế hoạt động
    • Ingress Controller: Thành phần điều khiển chính làm nhiệm vụ điều hướng các request tới các service bên trong k8s. Ingress Controller được cài đặt trên K8s và được expose ra ngoài dưới dạng NodePort
    • Ingress Rule: Chứa nội dung khai báo rule để điều hướng từ một Request tới một service cụ thể trên trong K8s

9.3.7. Namespace

  • Namespace là cơ chế để tách biệt các nhóm tài nguyên (Pod, Deployment, Service) trong cùng một Cluster
  • Tên tài nguyên là duy nhất trong Namespace đó, nhưng có thể được sử dụng ở một Namespace khác
  • Thường sử dụng trong trường hợp trên một Cluster có nhiều Team khác nhau cùng sử dụng, hoặc triển khai nhiều Project khác nhau
  • Các namespace mặc định của k8s
    • default: Khi thao tác với các tài nguyên ở mức namespace mà không chỉ định cụ thể Namespace nào thì mặc định hiểu là thao tác trên Namespace default này.
    • kube-system: Các thành phần Control Plane của K8S được triển khai ở namespace này. Thường thì chúng ta không triển khai các ứng dụng hay workload gì vào namespace này.
    • kube-public: Các tài nguyên được triển khai ở Namespace kube-public có thể được truy cập công khai trong toàn bộ cụm Kubernetes này.
    • kube-node-lease:

9.4. Container Runtime Interface (CRI)

  • CRI là một plugin cho phép kubelet sử dụng một cách rộng rãi các container runtimes, thay vì phải biên dịch lại các thành phần của cluster
  • Bạn cần một container runtime ở mỗi node trong cluster, để kubelet có thể khởi tạo pods và các Containers trong đó
  • CRI là giao thức chính để giao tiếp giữa kublet và Container Runtime

10. Docker Registry

  • Docker Registry là nơi lưu trữ tập trung các Docker Image. Có thể public hoặc private
  • Docker HUB là một registry public mà ai cũng có thể dùng, và mặc định Docker sẽ tìm kiếm image trên Docker Hub
    • Một số Registry phổ biến khác
    • Amazon Elastic Container Registry (ECR)
    • Harbor
    • Azure Container Registry
    • GitHub Container Registry
    • Google Container Registry
  • Các câu lệnh liên quan tới Docker Registry
    • docker pull hoặc docker run: Docker lấy image được yêu cầu từ registry đã cấu hình
    • docker push: Docker đẩy image lên registry
  • Reigstry và Repository
    • Registry là một nơi tập trung lưu trữ và quản lí các container images
    • Repository là tập hợp các container images có liên quan nằm trong một registry

11. Docker Lab

11.1. Chạy Container từ Registry

docker run -i -t ubuntu /bin/bash
  • Câu lệnh trên sẽ thực hiện những công việc sau

    • Nếu không có image “ubuntu” trong máy, Docker sẽ pull từ Registry đã được cấu hình về (Tương đương câu lệnh docker pull ubuntu)
    • Docker tạo một container mới (Tương đương câu lệnh docker container create)
    • Docker đưa vào container một hệ thống file read-write. Điều này cho phép Container đang chạy có thể tạo hoặc sửa file trong hệ tống local
    • Docker tạo một Network Interface để kết nối container vào hệ thống mạng mặc định, bao gồm gán cho nó một địa chỉ IP
    • Docker chạy container và thực thi câu lệnh /bin/bash để có thể giao tiếp với Terminal của Container
    • Khi gõ exit để ngắt câu lệnh /bin/bash, container dừng hoạt động nhưng không bị xóa bỏ, bạn có thể chạy lại hoặc xóa nó

    Untitled

11.2. Build và chạy Container trên local

  • Bước 1: Tải về ứng dụng mẫu
git clone https://github.com/docker/welcome-to-docker
  • Bước 2: Đọc nội dung của Dockerfile
cd welcome-to-docker
cat Dockerfile

Untitled

  • Bước 3: Build image bằng câu lệnh
docker build -t welcome-to-docker .
  • -t : Đánh dấu container bằng mộ tên
  • .: Vị trí của Dockerfile

Untitled

  • Bước 4: Chạy Container
docker run -p 8082:3000 welcome-to-docker

Untitled

Untitled

11.3. Chạy ứng dụng nhiều Containers

  • Bước 1: Clone code mẫu
git clone https://github.com/docker/multi-container-app
cd multi-container-app
  • Bước 2: Xem nội dung file compose.yaml
    • Đây là file định nghĩa cho Docker nên chạy file như thế nào

Untitled

  • Bước 3. Khởi chạy ứng dụng
docker compose up -d

Untitled

Untitled

  • Bước 5: Sửa đổi phần mềm trong tương lai
    • Chạy câu lệnh
docker compose watch

Untitled

  • Chỉnh sửa Source Code

Untitled

  • Thay đổi được đồng bộ

Untitled

Untitled

11.4. Lưu trữ lại dữ liệu của Container

  • Xóa Multi-Container App vừa thực hiện ở Lab 3, mở file compose.yaml và bỏ comment ở 2 dòng
volumes: 
     - database:/data/db
     
volumes:
  database:
  • Khi đó một volume được tạo ra, và dữ liệu sẽ được lưu lại kể cả khi chúng ta xóa Container

Untitled

11.5. Truy cập dữ liệu local từ container

  • Bước 1: Clone code mẫu
git clone https://github.com/docker/bindmount-apps
cd bindmount-apps
  • Bước 2: Bỏ Comment đoạn code sau
    • Mount local folder ./app vào folder /usr/src/app trong container
    • Dòng 2: /usr/src/app/node_modules để tránh việc thư mục node_modules bị ghi đè để giữ lại các package đã được cài đặt
todo-app:
    # ...
    volumes:
      - ./app:/usr/src/app
      - /usr/src/app/node_modules
  • Bước 3: Chạy ứng dụng
docker compose up -d

Untitled

11.6. Tạo Container từ ứng dụng của mình bằng docker init

  • Bước 1: Chuẩn bị một Project cơ bản
    • Ở đây em sử dụng Django

Untitled

  • Bước 2: Gõ lệnh docker init
  • Chọn ngôn ngữ lập trình Python

Untitled

  • Phiên Python bản muốn sử dụng là 3.9.6 (Để mặc định)

Untitled

  • Port khởi chạy, để mặc định là 8000

Untitled

  • Câu lệnh để khởi chạy app
python manage.py runserver 8000

Untitled

  • Cảnh báo không tìm thấy file requirements.txt

Untitled

  • Tạo một file requirements.txt mới chứa các Package dependecies cần cài

Untitled

  • Bước 3: Thử khởi chạy ứng dụng
docker compose up

Untitled

Untitled

11.7 Push Image vừa rồi lên Docker Hub

  • Login vào Docker Hub
  • Tạo một Repository mới

Untitled

  • Gõ 2 câu lệnh sau để Push lên Docker Hub
docker tag khaibut2024-web:latest kietna/khaibut2024:latest
docker push kietna/khaibut2024:latest
  • Trong đó
    • khaibut2024-web: Tên Image ở Local
    • latest: tag
    • kietna/khaibut2024: Tên repo ở Docker Hub

Untitled

Untitled

  • Thử Pull và chạy ở máy khác

Untitled

Untitled

Untitled

Untitled

11.8. Docker Compose Lab

  • Yêu cầu: Dùng Docker Compose dựng một ứng dụng WordPress (Tách DB, WebApp ra 2 Container riêng). Thư mục chứa DB và Source Code phải dùng Volume
  • Tạo thư mục dự án
mkdir wordpress
cd wordpress/
  • Tạo file cấu hình của Nginx
mkdir nginx-conf
nano nginx-conf/nginx.conf
server {
        listen 80;
        listen [::]:80;

        server_name localhost;

        index index.php index.html index.htm;

        root /var/www/html;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}
  • Tạo file .env chứa các biến môi trường quan trọng
nano .env

MYSQL_ROOT_PASSWORD=NguyenAnhKiet@@123
MYSQL_USER=wordpress
MYSQL_PASSWORD=Linuxteam123@
  • Tạo file .dockerignore loại trừ các file trong quá trình build container
nano .dockerignore

.env
docker-compose.yml
.dockerignore
  • Tạo file docker-compose.yml
nano docker-compose.yml

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
    networks:
      - app-network

volumes:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge
  • Bắt đầu quá trình tạo Container
docker-compose up -d

Untitled

Untitled

  • Các Container đang chạy

Untitled

  • Các Volume đã được tạo

Untitled

  • Kiểm tra volume wordpress_wordpress

Untitled

Untitled

  • Kiểm tra Volume wordpress_dbdata

Untitled

Untitled

  • Truy cập vào Website và thiết lập cơ bản

Screenshot 2024-05-13 at 13.12.07.png

Screenshot 2024-05-13 at 13.13.07.png

Screenshot 2024-05-13 at 13.14.42.png

12. Docker Swarm Lab

Mô hình: 3 máy ảo Ubuntu

  • Máy Manager: 192.168.154.130
  • Máy Worker1: 192.168.154.131
  • Máy Worker2: 192.168.154.132

Cấu hình như nhau: 1 Core - 8GB RAM và đều kết nối vào một Switch mạng, đã cài sẵn Docker trên 3 máy

  • Tại Node Manager, tạo cluster
docker swarm init --advertise-addr 192.168.154.130

Untitled

  • Copy câu lệnh Join Worker 1 và Worker 2 vào Cluster
docker swarm join --token SWMTKN-1-2c88tuwjlfw0a0js8pv0a3od2ww083krwzt4ehbhyxlsxi0jby-0bx48fn2u4yjvobmz4arvh6l7 192.168.154.130:2377

Untitled

Untitled

  • Từ Manager, kiểm tra các node
docker node ls

Untitled

  • Run Services
  • Tạo file docker-compose.yml
    • Replicas: 3 tức là tạo ra 3 container
version: '3'
services:
   web:
     image: cosy294/swarm:1.0
     ports:
       - "9000:80"
     deploy:
       mode: replicated
       replicas: 3
  • Chạy lệnh deploy
docker stack deploy -c docker-compose.yml kietna

Untitled

Untitled

Untitled

  • Thử scale số container lên 5
docker service scale kietna_web=5

Untitled

Untitled

  • Test tính năng autoscaling. Ở đây chúng ta thấy trong 5 node đang chạy
    • 2 node ở manager
    • 1 node ở worker1
    • 1 node ở worker2
  • Thử stop service docker ở worker2

Untitled

  • Docker Swarm tự tạo thêm 2 node mới ở Worker1 để đảm bảo luôn có 5 node được chạy

Untitled

13. k8s lab

13.1. Lab 1: Cài đặt k8s với kubespary

  • Chuẩn bị 4 máy với các thông tin như sau
    • master1: 192.168.10.11
    • worker1: 192.168.10.12
    • worker2: 192.168.10.13
    • kubespray: 192.168.10.8

Untitled

  • Thông số cấu hình từng máy

Untitled

  • Cài đặt AlmaLinux 9 lên từng máy

    • Tạo 2 User
      • User: root, Password: 123456@abc
      • User: sysadmin, Password: 123456@abc
    • Cài đặt hostname cho từng máy
    sudo hostnamectl set-hostname newhostname
    sudo service restart systemd-hostnamed
    • Cài đặt IP tĩnh cho từng máy
    nmcli d # Lay danh sach Interface (ens160)
    sudo nmcli con mod [interface_name] ipv4.method manual # Chuyen qua che do IP tinh
    sudo nmcli con mod [interface_name] ipv4.addresses [your_static_ip]/[subnet_mask] ipv4.gateway [gateway_ip] ipv4.dns [dns_servers] # Cai dat IP tinh, gateway, DNS Server
    sudo nmcli con up [interface_name] # Apply Setting
    • Cấu hình cho user sysadmin có quyền sudo không cần pass
    sudo vi /etc/sudoers
    sysadmin        ALL=(ALL)       NOPASSWD: ALL
    • Tắt Swap
    sudo swapoff -a
    free -h
    sudo vi /etc/fstab
    #/dev/mapper/centos-swap swap                    swap    defaults        0 0
    • Cài Docker lên từng máy
    sudo dnf --refresh update
    sudo dnf upgrade
    sudo dnf install yum-utils -y
    sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    sudo dnf install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
    sudo systemctl start docker
    sudo systemctl enable docker
    sudo usermod -aG docker sysadmin
    sudo chmod 666 /var/run/docker.sock
  • Cài dặt trên máy kubespray

    • Download Script cài đặt
    cd ~
    mkdir kubernetes_installation/
    cd /home/sysadmin/kubernetes_installation
    git clone https://github.com/kubernetes-sigs/kubespray.git --branch release-2.16
    • Tạo inventory mới là kietna-cluster
    cd /home/sysadmin/kubernetes_installation/kubespray
    cp -rf inventory/sample inventory/kietna-cluster
    • Tạo file hosts.yaml định nghĩa các master, worker
    cd /home/sysadmin/kubernetes_installation/kubespray/
    cd inventory/kietna-cluster
    vi hosts.yaml
    
    [all]
    master1  ansible_host=192.168.10.11      ip=192.168.10.11
    worker1  ansible_host=192.168.10.12      ip=192.168.10.12
    worker2  ansible_host=192.168.10.13      ip=192.168.10.13
    
    [kube-master]
    master1
    
    [kube-node]
    worker1
    worker2
    
    [etcd]
    master1
    
    [k8s-cluster:children]
    kube-node
    kube-master
    
    [calico-rr]
    
    [vault]
    master1
    worker1
    worker2
    
    • Sửa đổi Kube Network Plugin từ calico thành flannel
    cd /home/sysadmin/kubernetes_installation/kubespray/
    sed -i "/kube_network_plugin:/c\kube_network_plugin: flannel" inventory/kietna-cluster/group_vars/k8s_cluster/k8s-cluster.yml
    
    • Cài đặt Kubernetes cluster
    docker run --rm -it --mount type=bind,source=/home/sysadmin/kubernetes_installation/kubespray/inventory/viettq-cluster,dst=/inventory quay.io/kubespray/kubespray:v2.16.0 bash
    ansible-playbook -i /inventory/hosts.yaml cluster.yml --user=sysadmin --ask-pass --become --ask-become-pass
    
  • Kiểm tra các node bằng kubectl trên máy master1

mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

Untitled

  • Xem thông tin chi tiết của node worker1
kubectl describe node worker1

Untitled

Untitled

Untitled

Untitled

  • Ý nghĩa các thông số phần Condition
    • MemoryPressure: True nếu node bị cao tải memory (RAM)
    • DiskPressure: True nếu node bị đầy ổ cứng
    • PIDPressure: True nếu node có quá nhiều process
    • Ready: True nếu node vẫn đang hoạt động và được quản lý bởi kubelet

13.2. Lab 2: Làm việc với pods trong K8s

  • Tạo một pod bằng lệnh kubectl
    • Tạo một pod trên nginx-pod
    • Từ image: nginx
    • Lắng nghe ở cổng 80
kubectl run nginx-pod --image=nginx --port=80

Untitled

  • Liệt kê các pod đang chạy
kubectl get pod -o wide

Untitled

  • Xem thông tin chi tiết một pod
kubectl describe pod/nginx-pod

Untitled

  • Theo dõi log của pod
kubectl logs pod/nginx-pod

Untitled

  • Xoá pod
kubectl delete pod/nginx-pod

Untitled

14. Container Runtime

14.1. Giới thiệu

  • Container Runtime là một công cụ đóng vai trò quản lý tất cả quá trình running của một container. Chia thành hai loại
    • Low-level container runtime: Nhiệm vụ chính là tạo và xóa Container
    • High-level container runtime:
      • Quản lí Container, tải Container Image sau đó xả nén và truyền vào trong Low Level Container Runtime để nó tạo và chạy Container
      • Một số còn có chức năng đóng gói Container thành Container image và chuyển lên Container Registry

Untitled

14.2. Low-level container runtime

Untitled

  • Nhiệm vụ chính của low-level container runtime là tạo và xóa container
  • Những công việc mà low-level container runtime sẽ làm
    • Tạo cgroup
    • Chạy CLI trong cgroup
    • Chạy câu lệnh Unshare để tạo namespaces riêng
    • Cấu hình root filesystem
    • Clean up cgroup sau khi câu lệnh hoàn tất

14.3. High-level container runtime

Untitled

  • High level container runtime sẽ tập trung cho việc
    • Quản lý nhiều container
    • Vận chuyển và quản lý container images
    • Tải và giải nén container image để chuyển xuống cho low level container runtime.
  • High level container runtime phổ biến là containered, cung cấp các tính năng
    • Tải container image từ container registry.
    • Quản lý container image.
    • Chạy container từ container image đó.
    • Quản lý nhiều container.
  • Các high level container runtime mà docker sử dụng là dockerd, docker-containerd, docker-runc
    • dockerd cung cấp tính năng build image
    • docker-containerd tính năng tương tự containered
    • dockerd-runc giống với runc

Untitled

Share this article

Related Posts