Một node là một worker machine bên trong Kubernetes, trước đó còn được biết như là một minion
. Một node có thể là một VM hoặc một physical machine, điều này phụ thuộc vào cluster. Mỗi node sẽ chứa các service
cần thiết để chạy các pod
và được quản lý bởi các master
component. Các service
trên một node bao gồm container runtime, kubelet
và kube-proxy
.
Status của một node bao gồm các thông tin sau:
- Addresses
- Conditions
- Capacity và Allocatable
- Info
Node status và các thông tin chi tiết khác về một node có thể được hiển thị bằng cách sử dụng lệnh sau:
kubectl describe node <insert-node-name-here>
Cách sử dụng của các trường này sẽ khác nhau tùy thuộc vào cloud provider của bạn hoặc cấu hình vật lý:
-
HostName: hostname được ghi lại bởi kernel của node. Có thể được ghi đè qua tham số kubelet
--hostname-override
-
ExternalIP: địa chỉ IP của node có thể được định tuyến ở bên ngoài
cluster
-
InternalIP: địa chỉ IP của node chỉ có thể được định tuyến bên trong
cluster
Trường conditions
mô tả trạng thái của tất cả các node Running
. Ví dụ, conditions
sẽ bao gồm:
Node Condition | Mô tả |
---|---|
OutOfDisk |
True nếu node không có đủ bộ nhớ để tạo thêm các pod mới, ngược lại là False |
Ready |
True nếu node tình trạng tốt và sẵn sàng chấp nhận thêm pod , False nếu node không tình trạng tốt và không chấp nhận thêm pod , Unknown nếu node controller không nghe thấy được tín hiệu từ node-monitor-grace-period cuối cùng (mặc định là 40 giây) |
MemoryPressure |
True nếu bộ nhớ của node ở mức thấp, ngược lại là False |
PIDPressure |
True nếu có quá nhiều process chạy trong node, ngược lại là False |
DiskPressure |
True nếu dung lượng đĩa cứng thấp, ngược lại là False |
NetworkUnavailable |
True nếu network của node không được cấu hình đúng, ngược lại là False |
Node condition được khai báo như một đối tượng JSON. Ví dụ, response dưới đây mô tả tình trạng của node:
"conditions": [
{
"type": "Ready",
"status": "True",
"reason": "KubeletReady",
"message": "kubelet is posting ready status",
"lastHeartbeatTime": "2019-06-05T18:38:35Z",
"lastTransitionTime": "2019-06-05T11:41:27Z"
}
]
Nếu trạng thái của Ready condition vẫn là Unknown
hoặc False
lâu hơn pod-eviction-timeout
, thì một tham số được truyền đến kube-controller-manager
và tất cả các Pod
trên node được lên lịch để xóa bởi Node Controller. pod-eviction-timeout
mặc định là năm phút. Trong một vài trường hợp khi node không thể truy cập thì apiserver sẽ không thể giao tiếp với kubelet
trên node. Quyết định xóa các pod
không thể được truyền đạt đến kubelet
cho đến khi giao tiếp với apiserver được tái lập. Trong lúc đó, các pod
đã được lên lịch để xóa vẫn có thể tiếp tục chạy trên nod được phân vùng.
Trong các version Kubernetes trước 1.5
, node controller sẽ force delete
các pod
không thể truy cập đến từ apiserver
. Tuy nhiên, từ version 1.5
và các version cao hơn, node controller không force delete
các pod
cho đến khi nó xác nhận rằng chúng đã ngừng chạy trong cluster
. Bạn có thể thấy các pod
có thể đang chạy trên một node không thể truy cập được như đang trong trạng thái Terminating
hoặc Unknown
. Trong các trường hợp Kubernetes không thể suy đoán ra một node đã vĩnh viễn rời khỏi cluster thì người quản trị cluster có thể cần xóa node bằng cách thủ công. Việc xóa đối tượng node từ Kubernetes dẫn đến việc tất cả Pod
đang chạy trên node bị xóa khỏi apiserver và giải phóng tên của chúng.
Trong version 1.12
, tính năng TaintNodesByCondition
trở thành beta vì vậy node lifecycle controller tự động tạo các taint
đại diện cho condition. Tương tự scheduler bỏ qua các điều kiện khi quyết định một node, thay vào đó nó chú ý vào các taint
và toleration
của Pod
.
Mô tả các tài nguyên sẵn có trong node: CPU, memory, và số lượng tối đa pod
có thể được scheduled vào node.
Các trường trong capacity block chỉ ra tổng số tài nguyên mà một Node
sở hữu. Allocatable block chỉ ra lượng tài nguyên trên Node
đang sẵn sàng được tiêu thụ bởi các Pod
thông thường.
Thông tin chung về node như kernel version, Kubernetes version (kubelet
và kube-proxy
version), Docker version (nếu sử dụng), tên của OS. Thông tin được thu thập bởi kubelet
trong node.
Không giống như pod
và service
, một node vốn không được tạo ra bởi Kubernetes: nó được tạo bên ngoài bởi các cloud provider như GCE hoặc nó có sẵn trong nhóm các máy vật lý hoặc máy ảo của bạn. Vì vậy khi Kubernetes tạo một node, nó tạo một đối tượng đại diện cho node. Sau khi tạo, Kubernetes kiểm tra liệu node có hợp lệ hay không. Ví dụ, hãy thử tạo một node theo nội dung như sau:
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "10.240.79.157",
"labels": {
"name": "my-first-k8s-node"
}
}
}
Kubernetes tạo một node nội bộ (đại diện) và xác nhận node bằng cách kiểm tra tình trạng dựa trên trường metadata.name
. Nếu node hợp lệ - tất cả service
cần thiết đều chạy - nó sẽ đủ điều kiện để chạy một pod
. Ngược lại, nó được bỏ qua trong bất kỳ hoạt động nào của cluster
cho đến khi trở thành hợp lệ.
Hiện tại, có ba thành phần tương tác với Kubernetes node interface: node controller, kubelet
và kubectl
.
Node controller là một master component quản lý nhiều khía cạnh khác nhau của các node.
Node controller có nhiều vai trò trong vòng đời của một node. Đầu tiên là việc gán CIDR block cho node khi nó được đăng ký (nếu CIDR assignment được bật).
Thứ hai là giữ danh sách các node nội bộ của node controller luôn cập nhật mới nhất theo danh sách các machine sẵn dùng của cloud provider. Khi chạy trong môi trường cloud, bất cứ khi nào một node trong tình trạng không tốt thì node controller sẽ hỏi cloud provider liệu VM cho node đó có sẵn dùng hay không. Nếu không, node controller xóa node đó khỏi danh sách các node của nó.
Thứ ba là theo dõi tình trạng của các node. Node controller chịu trách nhiệm cập nhật NodeReady condition của NodeStatus thành ConditionUnknown
khi một node trở nên không thể truy cập đến (ví dụ như node bị down), và sau đó thu hồi tất cả pod
khỏi node đó (sử dụng graceful termination) nếu node này tiếp tục không thể truy cập (timeout mặc định là 40s để khởi động báo cáo ConditionUnknown
và 5 phút sau đó để khởi động quá trình thu hồi pod
). Node controller liên tục kiểm tra trạng thái của mỗi node trong khoảng thời gian mỗi --node-monitor-period
giây.
Trong các version Kubernetes trước 1.13
, NodeStatus
chính là tín hiệu theo dõi của node. Bắt đầu từ version 1.13
, tính năng cho thuê node được giới thiệu là một tính năng alpha
(NodeLease
). Khi tính năng NodeLease
được bật, mỗi node sẽ có một đối tượng Lease
được liên kết trong namespace kube-node-lease
, namespace được làm mới định kì; cả NodeStatus
và node lease được coi như tín hiệu từ node. Các node lease được làm mới thường xuyên trong khi NodeStatus
chỉ được báo cáo từ node đến master khi có các thay đổi hoặc đã đủ thời gian (mặc định là 1 phút, lâu hơn thời gian 40s timeout cho các node không thể truy cập). Vì node lease nhẹ hơn nhiều so với NodeStatus
nên tính năng này làm cho tín hiệu của node trở nên rẻ hơn đáng kể từ cả hai khía cạnh là khả năng mở rộng và hiệu suất.
Từ version 1.4
, node controller sẽ xem xét trạng thái của tất cả node trong cluster trước khi đưa ra quyết định thu hồi pod
.
Trong nhiều trường hợp, node controller giới hạn tỉ lệ thu hồi thành --node-eviction-rate
(mặc định là 0.1) mỗi giây, điều này nghĩa là nó sẽ không thu hồi pod
từ hơn một node mỗi 10 giây.
Hành vi thu hồi thay đổi khi một node trong vùng khả dụng đã biết có tình trạng không tốt. Node controller kiểm tra tỉ lệ các node trong vùng tình trạng không tốt (NodeReady
condition là ConditionUnknown
hoặc ConditionFalse
) ở trong cùng thời điểm. Nếu tỉ lệ các node trong tình trạng không tốt ít nhất là --unhealthy-zone-threshold
(mặc định là 0.55) thì tỉ lệ thu hồi sẽ giảm xuống: nếu cluster nhỏ (ví dụ nhỏ hơn hoặc bằng --large-cluster-size-threshold
node, mặc định 50) thì việc thu hồi bị dừng, mặt khác tỉ lệ thu hồi sẽ giảm xuống --secondary-node-eviction-rate
(mặc định 0.01) mỗi giây. Lí do các chính sách này được triển khai trên mỗi vùng khả dụng là vì một vùng khả dụng có thể trở thành phân vùng từ master
trong khi những các vùng còn lại vẫn được kết nối.
Từ version Kubernetes 1.6
, NodeController
cũng chịu trách nhiệm thu hồi các pod
đang chạy trên node có các NoExecute
taint, khi pod
không tolerate các taint. Hơn nữa, vì là tính năng alpha
nên mặc định nó bị disable, NodeContoller
chịu trách nhiêm thêm các taint
tương ứng với các vấn đề của node như node không thể truy cập hay không sẵn sàng (not ready).
Khi flag kubelet --register-node
được thiết lập là true
(giá trị mặc định), kubelet
sẽ cố gắng tự đăng ký với API server. Đây là mô hình được sử dụng bởi hầu hết các distro.
Để tự đăng ký, kubelet
được khởi động với các option sau:
-
--kubeconfig
- Đường dẫn đến các credential để tự xác thực đếnapiserver
. -
--cloud-provider
- cách giao tiếp với một cloud provider để đọc metadata của chính nó. -
--register-node
- tự động đăng ký với API server. -
--register-with-taints
- đăng ký node với dánh sáchtaint
đã cung cấp (phân cách bằng dấu phảy<key>=<value>:<effect>
). Không hoạt động nếuregister-node
làfalse
. -
--node-ip
- địa chỉ IP của node. -
--node-labels
- nhãn của node khi đăng ký node trong cluster -
--node-status-update-frequency
- chỉ định tần suấtkubelet
gửi status của node đếnmaster
.
Khi Node authorization mode và NodeRestriction admission plugin được bật thì các kubelet
chỉ được phép tạo và sửa đổi tài nguyên Node của riêng chúng
Một quản trị viên cluster có thể tạo và sửa đổi các đối tượng node.
Nếu quản trị viên muốn tạo các đối tượng node theo cách thủ công thì cần thiết lập cờ kubelet
là --register-node=false
.
Quản trị viên có thể sửa đổi các tài nguyên của node (kể cả thiết lập --register-node
). Các sửa đổi bao gồm thiết lập các nhãn trên node và đánh dấu nó là unschedulable
.
Nhãn của các node có thể được sử dụng kết hợp với các node selector trên các pod
để điều khiển scheduling, ví dụ như ràng buộc một pod
chỉ đủ điều kiện chạy trên một tập hợp con của các node.
Bằng cách đánh dấu một node là unschedulable
sẽ ngăn chặn các pod
mới được scheduled
tới node đó, nhưng không áp dụng cho các pod
đã tồn tại ở trên node. Việc này sẽ hữu ích vì nó như một bước chuẩn bị trước khi reboot node,... Ví dụ, để đánh dấu một node là unschedulable
, ta cần chạy lệnh sau:
kubectl cordon $NODENAME
Capacity của một node (số lượng CPU và số lượng memory) là một thành phần của node. Thông thường, các node tự đăng ký và báo cáo capacity của chúng khi tạo node. Nếu bạn đang quản lý node theo cách thủ công thì bạn cần thiết lập node capacity khi thêm một node mới.
Kubernetes scheduler đảm bảo có đủ các tài nguyên cho tất cả pod
trên một node. Nó kiểm tra tổng số request của các container trên node không lớn hơn node capacity. Điều này bao gồm tất cả container được khởi động bởi kubelet
, nhưng không bao gồm các container được khởi động trực tiếp bới container runtime cũng như bất kỳ tiến trình nào chạy bên ngoài các container.