Giới thiệu
Loạt bài tiếp theo chúng ta sẽ đi tiếp qua một loại Pattern khác là Structural Patterns. Trong bài này chúng ta sẽ tìm hiểu về Init Containers.
Structural Patterns bao gồm:
- Init Containers.
- Sidecar.
- Adapter.
- Ambassador.
Init Containers
Init Containers là những Container được thực thi ở quá trình khởi tạo Pod (Initialization Stage), các Container này được thực thi trước khi các Container chứa ứng dụng được tạo. Trong một Pod ta có thể khai báo một hay nhiều Init Containers, và chúng sẽ được thực thi theo thứ tự ta khai báo.
Init Containers được sử dụng để khởi tạo tài nguyên hoặc cấu hình những thứ cần thiết cho Container chứa ứng dụng. Tưởng tượng giống như trong ngôn ngữ JAVA và PHP, khi ta viết một Class và cần cấu hình những giá trị cần thiết cho Class đó khi nó được tạo thì ta sẽ khai báo một Constructors cho nó. Init Containers cũng tượng tự như vậy nhưng sử dụng cho Pod.
Từ hình trên thì một Pod được tách ra thành hai phần là: Init Containers và Application Containers. Tất cả Init Containers sẽ được chạy theo thứ tự và khi tất cả Init Containers được thực thi xong thì Application Containers mới được chạy.
Nếu có nhiều Application Containers thì tất cả Application Containers sẽ được thực thi song song với nhau chứ không phải theo thứ tự như Init Containers.
Ví dụ
Ví dụ ta dùng StatefulSet để tạo một Pod sử dụng cho Database Postgres Replica, tệp tin yaml sẽ như sau:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres-standby
labels:
component: postgres-standby
spec:
selector:
matchLabels:
component: postgres-standby
serviceName: postgres-standby
template:
metadata:
labels:
component: postgres-standby
spec:
initContainers:
- name: busybox
image: busybox
command:
- sh
- -c
- "cp /var/config/postgresql.conf /var/lib/postgresql/data/postgresql.conf && cp /var/config/recovery.conf /var/lib/postgresql/data/recovery.conf"
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgres-data
- mountPath: /var/config/postgresql.conf
subPath: postgresql.conf
name: postgres-standby-cm
- mountPath: /var/config/recovery.conf
subPath: recovery.conf
name: postgres-standby-cm
containers:
- name: postgres
image: postgres:11
ports:
- containerPort: 5432
env:
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
value: postgres
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgres-data
volumes:
- name: postgres-standby-cm
configMap:
name: postgres-standby-cm
volumeClaimTemplates:
- metadata:
name: postgres-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Ta dùng Init Containers để thiết lập cấu hình cho Database Application Container, công việc mà nó thực hiện như sau:
- Ta có một Configmap tên là
postgres-standby-cm
, bên trong nó sẽ có hai tệp tin cấu hình làpostgresql.conf
vàrecovery.conf
chứa những thứ cần thiết để ta thiết lập Database Replica - Khi Init Containers được chạy, ta thực thi câu lệnh sao chép hai tệp tin cấu hình này vào bên trong PVC tên là
postgres-data
được dùng cho Database Container - Khi Database Container chạy nó sẽ có hai tệp tin cấu hình khi nãy mà ta đã dùng Init Containers để sao chép qua
Lý do ta không để thẳng hai tệp tin cấu hình này vào Database Container là vì nó sẽ bị lỗi các bạn làm thử sẽ thấy :)))
. Đó là lý do vì sao ta cần dùng Init Containers.
Các điểm lưu ý
Khi làm việc với Init Containers ta cần lưu ý các điểm sau.
Init Containers cần nhỏ gọn
Các Init Containers bên trong một Pod nên nhẹ nhất có thể và chỉ nên thực thi các công việc không quá phức tạp và nhanh chóng.
Thứ nhất là vì các Init Containers sẽ được chạy tuần tự nên nếu một Init Containers nào đó chạy quá lâu thì nó sẽ làm chậm quá trình chạy ứng dụng chính.
Thứ hai là nếu một Init Containers chạy thất bại thì toàn bộ Pod sẽ bị khởi động lại (nếu ta không thêm thuộc tính RestartNever), lúc này toàn bộ Init Containers sẽ chạy lại.
Do đó để tránh các Init Containers ảnh hưởng tới Application Containers thì ta chỉ nên dùng nó để thực thi các công việc đơn giản.
Init Containers tác động tới tài nguyên
Theo kiến nghị thì khi ta khai báo Pod ta luôn cần định nghĩa thuộc tính resource.request
và resource.limit
cho nó.
Nếu ta có thêm Init Containers thì tài nguyên request
và limit
của Pod được tính như thế nào? Pod request
và limit
sẽ tính theo hai nhóm sau:
- Giá trị
request
vàlimit
lớn nhất của Init Containers - Tổng giá trị
request
vàlimit
của toàn bộ Application Containers
Trong hai số trên số nào lớn hơn thì số đó sẽ được lấy làm giá trị request
và limit
của Pod.
Các từ khóa để tìm hiểu thêm:
- Init Container Example
- Init Containers
- Configuring Pod Initialization
- The Initializer Pattern in JavaScript
- Object Initialization in Swift
- Using Admission Controllers
- Dynamic Admission Control
- How Kubernetes Initializers Work
- Pod Preset
- Inject Information into Pods Using a PodPreset
- Kubernetes Initializer Tutorial
Kết luận
Vậy là ta đã tìm hiểu xong về Init Containers, ta sử dụng nó để khỏi tạo tài nguyên và cấu hình cho Application Containers.
Nếu bài viết có gì sai hoặc cần cập nhật thì liên hệ Admin.
Tham gia nhóm chat của DevOps VN tại Telegram.
Kém tiếng Anh và cần nâng cao trình độ giao tiếp: Tại sao bạn học không hiệu quả?