HomeBlogKubernetes DaemonSet là gì? Hướng dẫn cấu hình chi tiết cho DaemonSet

Kubernetes DaemonSet là gì? Hướng dẫn cấu hình chi tiết cho DaemonSet

Locker blog reading time7 phút để đọc
Locker Avatar

anhtp

18/07/2024
Copy

Winston is a highly experienced digital marketing professional, specializing in Cybersecurity, IT services, and Software as a Service (SaaS).

Reading Time: 7 minutes

Trong thế giới Kubernetes rộng lớn, việc đảm bảo các tiến trình (Pod) hoạt động trơn tru và đồng bộ trên mọi node là một thách thức không nhỏ. DaemonSet chính là giải pháp đắc lực giúp bạn giải quyết bài toán này một cách hiệu quả.

Kubernetes DaemonSet

DaemonSet là gì?

DaemonSet là một tài nguyên trong Kubernetes đảm bảo tất cả (hoặc một số) Node (nút) chạy một bản sao của Pod. Khi các Node được thêm vào cụm, Pod sẽ được thêm vào các Node đó. Khi các Node bị xóa khỏi cụm, các Kubernetes Pods đó sẽ bị dọn dẹp. Việc xóa DaemonSet sẽ xóa sạch các Pod mà nó tạo ra.

Các trường hợp sử dụng điển hình của Kubernetes DaemonSet:

  • Chạy một daemon lưu trữ cụm trên mọi Node
  • Chạy một daemon thu thập nhật ký trên mọi Node
  • Chạy một daemon giám sát Node trên mọi Node

Trong trường hợp đơn giản, một DaemonSet, bao gồm tất cả các Node, sẽ được sử dụng cho mỗi loại daemon. Thiết lập phức tạp hơn có thể sử dụng nhiều DaemonSet cho một loại daemon duy nhất, nhưng với các cờ khác nhau hoặc yêu cầu CPU và bộ nhớ khác nhau cho các loại phần cứng khác nhau.

Xem thêm: Cách triển khai Kubernetes Deployment

Viết cấu hình cho DaemonSet

Tạo một DaemonSet

Bạn có thể mô tả một DaemonSet trong tệp YAML. Ví dụ, tệp daemonset.yaml bên dưới mô tả một DaemonSet chạy image Docker fluentd-elasticsearch:

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# these tolerations are to have the daemonset runnable on control plane nodes
# remove them if your control plane nodes should not run pods
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
# it may be desirable to set a high priority class to ensure that a DaemonSet Pod
# preempts running Pods
# priorityClassName: important
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log

Các Trường Bắt Buộc của DaemonSet

Cũng như tất cả các cấu hình Kubernetes khác, DaemonSet cần các trường apiVersion, kindmetadata.

Tên của một đối tượng DaemonSet phải là một tên miền phụ DNS hợp lệ.

DaemonSet cũng cần một phần .spec.

Mẫu Pod

.spec.template là một trong những trường bắt buộc trong .spec.

.spec.template là một mẫu Pod. Nó có cùng một lược đồ chính xác như một Pod, ngoại trừ việc nó được lồng nhau và không có apiVersion hoặc kind.

Ngoài các trường bắt buộc cho Pod, một mẫu Pod trong DaemonSet phải chỉ định những label thích hợp.

Mẫu Pod trong DaemonSet phải có RestartPolicy bằng Always hoặc không được chỉ định, mặc định là Always.

Bộ Chọn Pod

Trường .spec.selector là một bộ chọn pod. Nó hoạt động giống như .spec.selector của Job.

Bạn phải chỉ định một bộ chọn pod khớp với label của .spec.template. Ngoài ra, sau khi một DaemonSet được tạo, .spec.selector của nó không thể bị thay đổi. Việc thay đổi bộ chọn pod có thể dẫn đến việc các Pod bị đứt đoạn ngoài ý muốn và điều này gây khó hiểu cho người dùng.

.spec.selector là một đối tượng bao gồm 2 trường:

  • matchLabels – hoạt động giống như .spec.selector của ReplicationController.
  • matchExpressions – cho phép xây dựng các bộ chọn giá trị phức tạp hơn bằng cách chỉ định khóa, danh sách các giá trị và toán tử liên quan đến khóa và giá trị. Khi cả hai được chỉ định, kết quả sẽ được AND.

.spec.selector phải khớp với .spec.template.metadata.labels. Cấu hình không khớp với hai giá trị này sẽ bị API từ chối.

Chạy Pod trên Các Node Được Chọn

Nếu bạn chỉ định spec.template.spec.nodeSelector, bộ điều khiển DaemonSet sẽ tạo Pod trên các Node khớp với bộ chọn Node đó. Tương tự, nếu bạn chỉ định spec.template.spec.affinity, bộ điều khiển DaemonSet sẽ tạo Pod trên các Node khớp với node affinity đó. Nếu bạn không chỉ định bất kỳ tùy chọn nào, bộ điều khiển DaemonSet sẽ tạo Pod trên tất cả các Node.

Cách Lên Lịch cho Daemon Pod

DaemonSet có thể được sử dụng để đảm bảo tất cả các Node đủ điều kiện chạy một bản sao của Pod. Bộ điều khiển DaemonSet tạo một Pod cho mỗi Node đủ điều kiện và thêm trường spec.affinity.nodeAffinity của Pod để khớp với host mục tiêu. Sau khi Pod được tạo, bộ lập lịch mặc định thường tiếp quản và sau đó ràng buộc Pod với host đích bằng cách đặt trường .spec.nodeName. Nếu Pod mới không thể phù hợp trên Node, bộ lập lịch mặc định có thể chiếm chỗ trước (đẩy ra) một số Pod hiện có dựa trên độ ưu tiên của Pod mới.

Nếu điều quan trọng là Pod của DaemonSet chạy trên mỗi Node, thì thường nên đặt spec.template.spec.priorityClassName của DaemonSet thành một PriorityClass có mức độ ưu tiên cao hơn để đảm bảo việc chiếm chỗ trước này xảy ra.

Người dùng có thể chỉ định một bộ lập lịch khác cho các Pod của DaemonSet bằng cách đặt trường spec.template.spec.schedulerName của DaemonSet.

Node affinity ban đầu được chỉ định tại trường .spec.template.spec.affinity.nodeAffinity (nếu được chỉ định) được bộ điều khiển DaemonSet tính đến khi đánh giá các Node đủ điều kiện, nhưng nó được thay thế trên Pod được tạo bằng node affinity khớp với tên của Node đủ điều kiện.

Taints và Tolerations

Bộ điều khiển DaemonSet tự động thêm một tập hợp các giới hạn vào các Pod của DaemonSet:

Khóa toleration Hiệu ứng Miêu tả
node.kubernetes.io/not-ready NoExecute Các Pod của DaemonSet có thể được lên lịch trên các node không hoạt động bình thường hoặc chưa sẵn sàng chấp nhận Pod. Bất kỳ Pod DaemonSet nào chạy trên các node như vậy sẽ không bị loại bỏ.
node.kubernetes.io/unreachable NoExecute Các Pod của DaemonSet có thể được lên lịch trên các node không thể truy cập được từ bộ điều khiển node. Bất kỳ Pod DaemonSet nào chạy trên các node như vậy sẽ không bị loại bỏ.
node.kubernetes.io/disk-pressure NoSchedule Các Pod của DaemonSet có thể được lên lịch trên các node có vấn đề về dung lượng đĩa.
node.kubernetes.io/memory-pressure NoSchedule Các Pod của DaemonSet có thể được lên lịch trên các node có vấn đề về bộ nhớ.
node.kubernetes.io/pid-pressure NoSchedule Các Pod của DaemonSet có thể được lên lịch trên các node có vấn đề về tài nguyên process (quá trình).
node.kubernetes.io/unschedulable NoSchedule Các Pod của DaemonSet có thể được lên lịch trên các node không thể lên lịch (unschedulable).
node.kubernetes.io/network-unavailable NoSchedule Chỉ được thêm cho các Pod DaemonSet yêu cầu mạng host, tức là các Pod có spec.hostNetwork: true. Các Pod DaemonSet như vậy có thể được lên lịch trên các node có mạng không khả dụng.

Bạn cũng có thể thêm các giới hạn của riêng bạn vào các Pod của DaemonSet bằng cách định nghĩa chúng trong mẫu Pod của DaemonSet.

Vì bộ điều khiển DaemonSet tự động đặt toleration node.kubernetes.io/unschedulable:NoSchedule, Kubernetes có thể chạy các Pod của DaemonSet trên các node được đánh dấu là unschedulable (không thể lên lịch).

Điều này đặc biệt hữu ích khi bạn sử dụng DaemonSet để cung cấp một chức năng quan trọng ở cấp độ node, chẳng hạn như mạng cluster. Kubernetes có thể đặt các Pod của DaemonSet lên các node trước khi chúng sẵn sàng. Ví dụ, nếu không có toleration đặc biệt này, bạn có thể rơi vào tình trạng bế tắc. Trong đó, node không được đánh dấu là sẵn sàng vì plugin mạng chưa chạy trên đó, nhưng đồng thời plugin mạng lại không chạy trên node vì node chưa sẵn sàng.

Có thể bạn quan tâm: Cách sử dụng Statefulset trong Kubernetes

Giao tiếp với Pod trong DaemonSet

Có một số cách thức phổ biến để giao tiếp với các Pod trong một DaemonSet:

1. Push (Đẩy dữ liệu):

Các Pod trong DaemonSet được cấu hình để gửi cập nhật đến một dịch vụ khác, chẳng hạn như cơ sở dữ liệu lưu trữ thông tin trạng thái (stats database). Các Pod này không có client riêng.

2. NodeIP và Port đã biết:

  • Các Pod trong DaemonSet có thể sử dụng hostPort, cho phép truy cập Pod thông qua địa chỉ IP của node.
  • Client cần biết danh sách địa chỉ IP của các node và biết cổng truy cập theo quy ước.

3. DNS:

  • Tạo một headless service với cùng bộ chọn Pod (pod selector) như DaemonSet.
  • Khám phá các DaemonSet bằng cách sử dụng tài nguyên endpoints hoặc truy xuất nhiều bản ghi A từ DNS.

4. Service:

  • Tạo một service với cùng bộ chọn Pod như DaemonSet.
  • Sử dụng service để truy cập một daemon trên một node ngẫu nhiên (không thể truy cập cụ thể đến một node).

Bài viết liên quan: Tổng quan về Kubernetes Architecture

Cập nhật DaemonSet

  • Nếu label của node thay đổi, DaemonSet sẽ nhanh chóng thêm Pod vào các node mới khớp và xóa Pod khỏi các node không còn khớp.
  • Bạn có thể sửa đổi các Pod do DaemonSet tạo ra. Tuy nhiên, không phải tất cả các trường trong Pod đều cho phép cập nhật. Ngoài ra, bộ điều khiển DaemonSet sẽ sử dụng mẫu ban đầu (original template) vào lần tiếp theo khi một node mới (ngay cả với tên giống nhau) được tạo.
  • Bạn có thể xóa DaemonSet. Nếu bạn sử dụng -cascade=orphan với kubectl, thì các Pod sẽ được giữ lại trên các node. Nếu sau đó bạn tạo một DaemonSet mới với cùng bộ chọn Pod, DaemonSet mới sẽ tiếp quản các Pod hiện có. Bất kỳ Pod nào cần thay thế, DaemonSet sẽ thay thế chúng theo chiến lược cập nhật (updateStrategy).
  • Bạn có thể thực hiện cập nhật theo kiểu rolling update trên một DaemonSet.

Nếu bạn là một lập trình viên đang làm việc với Kubernetes, việc xử lý và bảo mật nhiều thông tin dữ liệu như SSH key, port, API key chắc chắn là vấn đề cần lưu tâm. Những phương pháp thông thường được sử dụng là lưu secrets trong file config, hardcode hoặc lưu bên offline. Tuy nhiên, phương pháp tiện lợi thì lại không đủ bảo mật, phương pháp lưu an toàn thì lại tốn nhiều công sức và thời gian quản lý. Locker Secrets Manager là giải pháp triệt để cho vấn đề này, giúp dev lưu trữ và quản lý các thông tin bí mật trong vòng đời phát triển sản phẩm.

Tin mới nhất

Locker blog

Mẹo, tin tức, hướng dẫn và các best practice độc quyền của Locker

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của Locker sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.