Bài viết này chúng ta sẽ tìm hiểu khái niệm về POD, cách khai báo tạo ra các POD manifest từ cấu hình yaml, chạy các POD và quản lý các POD tronng Kubernetes, xem log của POD, xóa POD,…
Để tương tác với Kubernetes ta sử dụng command chính là kubectl
Cú pháp: kubectl [action] [type] [name]
Trong đó:
action: hành động, ví dụ delele, get, apply,…
type: kiểu tài nguyên như ns, no, po, svc …
name: tên đối tượng
flags: các thiết lập tùy chọn tùy vào loại lệnh
1. Node trong Kubernetes.
Trong Kubernetes Node là một máy vật lý hay máy ảo (VPS) trong cụm máy (cluster). Xem các nút (node) trong cụm (cluster) chạy lệnh:
root@k8s-standalone:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-standalone Ready control-plane,master 10h v1.23.8
Để lấy thông tin tài nguyên bộ nhớ, CPU, các container, … ở một node nào đó sử dụng lệnh dưới, với k8s-standalone là tên node
root@k8s-standalone:~# kubectl describe node k8s-standalone
Name: k8s-standalone
Roles: control-plane,master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=k8s-standalone
kubernetes.io/os=linux
node-role.kubernetes.io/control-plane=
node-role.kubernetes.io/master=
node.kubernetes.io/exclude-from-external-load-balancers=
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /run/containerd/containerd.sock
node.alpha.kubernetes.io/ttl: 0
projectcalico.org/IPv4Address: 192.168.13.238/23
projectcalico.org/IPv4IPIPTunnelAddr: 10.244.20.128
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Sat, 01 Oct 2022 03:21:24 +0000
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: k8s-standalone
AcquireTime: <unset>
RenewTime: Sat, 01 Oct 2022 14:08:39 +0000
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
NetworkUnavailable False Sat, 01 Oct 2022 03:46:58 +0000 Sat, 01 Oct 2022 03:46:58 +0000 CalicoIsUp Calico is running on this node
MemoryPressure False Sat, 01 Oct 2022 14:05:34 +0000 Sat, 01 Oct 2022 03:21:21 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Sat, 01 Oct 2022 14:05:34 +0000 Sat, 01 Oct 2022 03:21:21 +0000 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Sat, 01 Oct 2022 14:05:34 +0000 Sat, 01 Oct 2022 03:21:21 +0000 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Sat, 01 Oct 2022 14:05:34 +0000 Sat, 01 Oct 2022 03:46:33 +0000 KubeletReady kubelet is posting ready status. AppArmor enabled
Addresses:
InternalIP: 192.168.13.238
Hostname: k8s-standalone
Capacity:
cpu: 4
ephemeral-storage: 205310952Ki
hugepages-2Mi: 0
memory: 8167940Ki
pods: 110
Allocatable:
cpu: 4
ephemeral-storage: 189214573050
hugepages-2Mi: 0
memory: 8065540Ki
pods: 110
System Info:
Machine ID: e0f5d56beeac489e9c86516cd48c2c04
System UUID: 73F61242-4830-AC1E-B9D2-EAF353E15F1A
Boot ID: 55610892-1dd5-4573-b791-757493eda6d5
Kernel Version: 4.15.0-193-generic
OS Image: Ubuntu 18.04.6 LTS
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.6.8
Kubelet Version: v1.23.8
Kube-Proxy Version: v1.23.8
PodCIDR: 10.244.0.0/24
PodCIDRs: 10.244.0.0/24
Non-terminated Pods: (9 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
kube-system calico-kube-controllers-7f76d48f74-kb5lk 0 (0%) 0 (0%) 0 (0%) 0 (0%) 10h
kube-system calico-node-nz4zd 250m (6%) 0 (0%) 0 (0%) 0 (0%) 10h
kube-system coredns-64897985d-2vvw5 100m (2%) 0 (0%) 70Mi (0%) 170Mi (2%) 10h
kube-system coredns-64897985d-cd274 100m (2%) 0 (0%) 70Mi (0%) 170Mi (2%) 10h
kube-system etcd-k8s-standalone 100m (2%) 0 (0%) 100Mi (1%) 0 (0%) 10h
kube-system kube-apiserver-k8s-standalone 250m (6%) 0 (0%) 0 (0%) 0 (0%) 10h
kube-system kube-controller-manager-k8s-standalone 200m (5%) 0 (0%) 0 (0%) 0 (0%) 10h
kube-system kube-proxy-zhx9f 0 (0%) 0 (0%) 0 (0%) 0 (0%) 10h
kube-system kube-scheduler-k8s-standalone 100m (2%) 0 (0%) 0 (0%) 0 (0%) 10h
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1100m (27%) 0 (0%)
memory 240Mi (3%) 340Mi (4%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events: <none>
Một số thông tin chúng ta cần để ý như sau:
- Ready: giá trị true chấp nhận triển khai chạy các Pod trên master
- MemoryPressure: giá trị true nếu gần hết bộ nhớ
- DiskPressure: giá trị true nếu gần dung lượng lưu trữ
- NetworkUnavailable: giá trị true nếu network lỗi cấu hình
- Capacity, Allocatable: cho biết tài nguyên có hiệu lực như CPU, bộ nhớ, số pod có thể chạy …
- System Info: thông tin phần mềm trên hệ thống
- Addresses: thông tin hostname và ip address của node
- Labels: các nhãn của node
Để thiết lập nhãn cho node ta dùng lệnh
root@k8s-standalone:~# kubectl label node k8s-standalone nhanmoi=tencuanhan
node/k8s-standalone labeled
Verify lại ta thấy đã có nhãn mới như dưới
root@k8s-standalone:~# kubectl label --list nodes k8s-standalone
node-role.kubernetes.io/master=
node-role.kubernetes.io/control-plane=
nhanmoi=tencuanhan
kubernetes.io/os=linux
beta.kubernetes.io/os=linux
node.kubernetes.io/exclude-from-external-load-balancers=
kubernetes.io/hostname=k8s-standalone
beta.kubernetes.io/arch=amd64
kubernetes.io/arch=amd64
Hoặc
root@k8s-standalone:~# kubectl get node -l "nhanmoi=tencuanhan"
NAME STATUS ROLES AGE VERSION
k8s-standalone Ready control-plane,master 11h v1.23.8
Để xóa nhãn của node ta sử dụng lệnh
root@k8s-standalone:~# kubectl label node k8s-standalone nhanmoi-
node/k8s-standalone unlabeled
Verify lại ta thấy nhãn không tồn tại
root@k8s-standalone:~# kubectl get node -l "nhanmoi=tencuanhan"
No resources found
2. Pod trong Kubernetes.
Kubernetes không chạy các container một cách trực tiếp, thay vào đó nó bọc một hoặc nhiều container vào với nhau trong một cấu trúc gọi là POD. Các container cùng một pod thì chia sẻ với nhau tài nguyên và mạng cục bộ của pod.
Pod là thành phần mà Kubernetes sẽ thực hiện việc nhân bản (replication), khi cần thiết thì Kubernetes có thể cấu hình để triển khai nhân bản ra nhiều pod có chức năng giống nhau để tránh quá tải, thậm chí nó vẫn tạo ra nhiều bản copy của pod khi không quá tải nhằm phòng lỗi (ví dụ node bị die).
Pod có thể có nhiều container mà pod là đơn vị để scale (có nghĩa là tất cả các container trong pod cũng scale theo) nên nếu có thể thì cấu hình ứng dụng sao cho một Pod có ít container nhất càng tốt.
Cách sử dụng hiệu quả và thông dụng là dùng loại Pod trong nó chỉ chạy một container.
Pod loại chạy nhiều container trong đó thường là đóng gọi một ứng dụng xây dựng với sự phối hợp chặt chẽ từ nhiều container trong một khu vực cách ly, chúng chia sẻ tài nguyên ổ đĩa, mạng cho nhau.
Mỗi POD được gán một địa chỉ IP, các container trong Pod chia sẻ cùng địa chỉ IP này. Các container trong cùng một Pod có thể liên lạc với nhau qua localhost.
Một Pod có thể có nhiều ổ đĩa được chia sẻ để các container có thể truy cập đọc/ghi dữ liệu.
– Làm việc với Pod trong Kubernetes
- Bạn có thể tạo ra Pod một cách trực tiếp (thực tế ít dùng) hoặc qua triển khai Deployment để Controller thực hiện, khi Pod được tạo ra nó được lên kế hoạch chạy trong một Node nào đó của cụm máy, nó tồn tại cho đến khi tiến trình chạy kết thúc hoặc bị xóa, bị lỗi Node …
- Controller: Khi bạn tạo các Pod không trực tiếp, tức thông qua cấu hình Deployment thì có một Controller thực hiện việc tạo quản lý các Pod cho bạn, thực hiện cách này nó cung cấp khả năng cập nhật giám sát, phục hồi …
3. Hướng dẫn tạo Pod trong Kubernetes
Mình sẽ tạo 1 pod chứa 1 container ứng dụng monitor Prometheus như sau
cat > ./prometheus_deployment.yaml << OEF
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
spec:
selector:
matchLabels:
run: prometheus
replicas: 1
template:
metadata:
labels:
run: prometheus
spec:
containers:
- name: prometheus
image: prom/prometheus
ports:
- containerPort: 9090
resources:
limits:
memory: "150M"
cpu: "100m"
OEF
File trên khai báo một Pod, đặt tên là prometheus, gán nhãn run: prometheus trong Pod chạy một Container từ image prom/prometheus, cổng của Container 9090
Triển khai tạo Pod từ file này, thực hiện lệnh sau
root@k8s-standalone:~# kubectl apply -f ./prometheus_deployment.yaml
deployment.apps/prometheus created
Mặc định Kubernetes không tạo và chạy POD ở Node Master để đảm bảo yêu cầu an toàn, bạn xem lại bài 2 để biết cách thiết lập cho phép tạo POD ở master node.
Sau khi triển khai xong, ta sử dụng lệnh kubectl get pod để list pod, ta thấy đã có 1 Pod mới như dưới.
root@k8s-standalone:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
prometheus-697f49c94b-r9cq9 1/1 Running 0 6s
Chúng ta có thể xem chi tiết thông tin của Pod vừa triển khai bằng lệnh dưới
root@k8s-standalone:~# kubectl describe prometheus-697f49c94b-r9cq9
error: the server doesn't have a resource type "prometheus-697f49c94b-r9cq9"
root@k8s-standalone:~# kubectl describe pod/prometheus-697f49c94b-r9cq9
Name: prometheus-697f49c94b-r9cq9
Namespace: default
Priority: 0
Node: k8s-standalone/192.168.13.238
Start Time: Sat, 01 Oct 2022 14:46:02 +0000
Labels: pod-template-hash=697f49c94b
run=prometheus
Annotations: cni.projectcalico.org/containerID: bb4fb80769615ed29955e0234a9adb98fc6e9ff593891a82cc6d28cc63c165d0
cni.projectcalico.org/podIP: 10.244.20.134/32
cni.projectcalico.org/podIPs: 10.244.20.134/32
Status: Running
IP: 10.244.20.134
IPs:
IP: 10.244.20.134
Controlled By: ReplicaSet/prometheus-697f49c94b
Containers:
prometheus:
Container ID: containerd://0af788c4837a025cc7030fb0945feb6e6a63bb3c1a697f53f05032e4ee7ee187
Image: prom/prometheus
Image ID: docker.io/prom/prometheus@sha256:b591915dad4ee2375fbb24cd019c50a546aae561bc63510516efec70d69b4292
Port: 9090/TCP
Host Port: 0/TCP
State: Running
Started: Sat, 01 Oct 2022 14:46:06 +0000
Ready: True
Restart Count: 0
Limits:
cpu: 100m
memory: 150M
Requests:
cpu: 100m
memory: 150M
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-rgqpm (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-rgqpm:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: Guaranteed
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m27s default-scheduler Successfully assigned default/prometheus-697f49c94b-r9cq9 to k8s-standalone
Normal Pulling 2m26s kubelet Pulling image "prom/prometheus"
Normal Pulled 2m23s kubelet Successfully pulled image "prom/prometheus" in 2.287419066s
Normal Created 2m23s kubelet Created container prometheus
Normal Started 2m23s kubelet Started container prometheus
Để tra cứu logs của Pod sử dụng lệnh
root@k8s-standalone:~# kubectl logs pod/prometheus-697f49c94b-r9cq9
ts=2022-10-01T14:46:06.854Z caller=main.go:491 level=info msg="No time or size retention was set so using the default time retention" duration=15d
ts=2022-10-01T14:46:06.854Z caller=main.go:535 level=info msg="Starting Prometheus Server" mode=server version="(version=2.37.1, branch=HEAD, revision=1ce2197e7f9e95089bfb95cb61762b5a89a8c0da)"
ts=2022-10-01T14:46:06.855Z caller=main.go:540 level=info build_context="(go=go1.18.6, user=root@3caaaea7ba87, date=20220912-12:42:39)"
ts=2022-10-01T14:46:06.855Z caller=main.go:541 level=info host_details="(Linux 4.15.0-193-generic #204-Ubuntu SMP Fri Aug 26 19:20:21 UTC 2022 x86_64 prometheus-697f49c94b-r9cq9 (none))"
ts=2022-10-01T14:46:06.855Z caller=main.go:542 level=info fd_limits="(soft=1048576, hard=1048576)"
ts=2022-10-01T14:46:06.855Z caller=main.go:543 level=info vm_limits="(soft=unlimited, hard=unlimited)"
ts=2022-10-01T14:46:06.945Z caller=web.go:553 level=info component=web msg="Start listening for connections" address=0.0.0.0:9090
ts=2022-10-01T14:46:06.946Z caller=main.go:972 level=info msg="Starting TSDB ..."
ts=2022-10-01T14:46:07.042Z caller=tls_config.go:195 level=info component=web msg="TLS is disabled." http2=false
ts=2022-10-01T14:46:07.046Z caller=head.go:493 level=info component=tsdb msg="Replaying on-disk memory mappable chunks if any"
ts=2022-10-01T14:46:07.046Z caller=head.go:536 level=info component=tsdb msg="On-disk memory mappable chunks replay completed" duration=43.584µs
ts=2022-10-01T14:46:07.046Z caller=head.go:542 level=info component=tsdb msg="Replaying WAL, this may take a while"
ts=2022-10-01T14:46:07.047Z caller=head.go:613 level=info component=tsdb msg="WAL segment loaded" segment=0 maxSegment=0
ts=2022-10-01T14:46:07.047Z caller=head.go:619 level=info component=tsdb msg="WAL replay completed" checkpoint_replay_duration=99.148µs wal_replay_duration=392.146µs total_replay_duration=755.939µs
ts=2022-10-01T14:46:07.048Z caller=main.go:993 level=info fs_type=EXT4_SUPER_MAGIC
ts=2022-10-01T14:46:07.048Z caller=main.go:996 level=info msg="TSDB started"
ts=2022-10-01T14:46:07.048Z caller=main.go:1177 level=info msg="Loading configuration file" filename=/etc/prometheus/prometheus.yml
ts=2022-10-01T14:46:07.049Z caller=main.go:1214 level=info msg="Completed loading of configuration file" filename=/etc/prometheus/prometheus.yml totalDuration=818.381µs db_storage=825ns remote_storage=2.188µs web_handler=403ns query_engine=888ns scrape=277.963µs scrape_sd=33.361µs notify=37.919µs notify_sd=14.586µs rules=1.586µs tracing=6.812µs
ts=2022-10-01T14:46:07.049Z caller=main.go:957 level=info msg="Server is ready to receive web requests."
ts=2022-10-01T14:46:07.049Z caller=manager.go:941 level=info component="rule manager" msg="Starting rule manager..."
Để thi hành 1 lệnh trong Pod ta sử dụng lệnh dưới
root@k8s-standalone:~# kubectl exec pod/prometheus-697f49c94b-r9cq9 ls /etc
group
hostname
hosts
localtime
network
nsswitch.conf
passwd
prometheus
resolv.conf
services
shadow
ssl
Để truy cập vào 1 Pod ta sử dụng lệnh dưới, nếu Pod có nhiều container thì ta thêm tham số -c <container_name>
root@k8s-standalone:~# kubectl exec -it pod/prometheus-697f49c94b-r9cq9 sh
/prometheus $ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1480 qdisc noqueue
link/ether 6a:44:71:aa:f8:05 brd ff:ff:ff:ff:ff:ff
inet 10.244.20.134/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::6844:71ff:feaa:f805/64 scope link
valid_lft forever preferred_lft forever
Truy cập vào Pod từ bên ngoài Cluster ta sử dụng Proxy lý do là trong thông tin của Pod ta thấy có IP của Pod và cổng lắng nghe, tuy nhiên Ip này là nội bộ, chỉ các Pod trong Cluster liên lạc với nhau. Nếu bên ngoài muốn truy cập cần tạo một Service để chuyển traffic bên ngoài vào Pod mà chúng ta sẽ tìm hiểu ở bài sau, ở bài này để tạm thời truy cập kiểm tra bằng cách chạy proxy.
root@k8s-standalone:~# kubectl proxy --address="0.0.0.0" --accept-hosts='^*$'
Starting to serve on [::]:8001
Hoặc
root@k8s-standalone:~# kubectl proxy
Starting to serve on 127.0.0.1:8001
Ta thấy ở master node đang lắng nghe cổng 8001, ta sử dụng link dưới và thay đổi một số thông tin liên quan để truy cập như sau. Bạn dùng 1 máy tính có thể kết nối được đến master node để test nhé
http://192.168.13.238:8001/api/v1/namespaces/default/pods/prometheus-697f49c94b-r9cq9:8001/proxy/
Và đây là kết quả
Để xóa Pod, sử dụng command dưới
root@k8s-standalone:~# kubectl delete -f ./prometheus_deployment.yaml
deployment.apps "prometheus" deleted
Hoặc
root@k8s-standalone:~# kubectl delete pod/prometheus-697f49c94b-89lsc
pod "prometheus-697f49c94b-89lsc" deleted
Lưu ý cách xóa thứ 2 chỉ áp dụng cho Pod triển khai trực tiếp nhé (với type là Pod)
Với Pod có nhiều container, file yaml có định dạng như dưới, ở dưới mình triển khai thêm ứng dụng Pushgateway.
cat > ./prometheus_deployment.yaml << OEF
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
spec:
selector:
matchLabels:
run: prometheus
replicas: 1
template:
metadata:
labels:
run: prometheus
spec:
containers:
- name: prometheus
image: prom/prometheus
ports:
- containerPort: 9090
resources:
limits:
memory: "150M"
cpu: "100m"
- name: pushgateway
image: prom/pushgateway
ports:
- containerPort: 9091
resources:
limits:
memory: "150M"
cpu: "100m"
OEF
Sa khi triển khai xong chúng ta thấy Pod này có 2 container đang runing
root@k8s-standalone:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
prometheus-8f6c467bd-ssx25 2/2 Running 0 2m25s
Đến đây mình đã hướng dẫn các lệnh cơ bản về node, pod và cách triển khai các pods, phần sau mình sẽ nói về lưu trữ trong Kubernetes nhé.