[Nhập môn Kubernetes P4] - Kubernetes resource và kubectl command
Serial blog Nhập môn Kubernetes
Nội dung
- Giới thiệu
- Kubernetes và Resource
- Kubectl và YAML Manifest
- Cách sử dụng kubectl
- Tổng kết
Giới thiệu
Trong phần 4 này, mình sẽ giới thiệu đến các bạn cơ bản về các thành phần của Kubernetes và kubectl command.
Trên thực tế, K8s được cấu thành từ Kubernetes Master và Kubernetes Node. Kubernetes Master cung cấp API Endpoint, Đảm nhận vai trò Container Scheduling, Container Scaling vv. Còn Kubernetes Node là host để khởi động những container ứng dụng của chúng ta.
Chúng ta cùng xem lại kiến trúc của K8s một lần nữa nhé.
Trong đó cấu trúc của Kubernetes Master gồm:
Chi tiết các thành phần các bạn có thể xem link tham khảo bên dưới hoặc search ở 1 page khác nhé. Mình chỉ nói cái tổng quát trước, không đi vào chi tiết ngay để mọi người khỏi bị loạn. Đại khái thì khi thao tác với kubernetes cluster thông qua CLI tool kubectl thì chúng ta sẽ call đến API của Kubernetes Master, sau đó các thành phần trong Master sẽ scheduling hay scaling container vào các Kubernetes Node.
Tham khảo:
https://techblog.vn/phan-2-kien-truc-cua-kubernetes
Mối quan hệ giữa Kubernetes Master và Kubernetes Nodes
Khi vận hành Kubernetes Cluster, chúng ta đăng ký resource cho Kubernetes Master bằng cách sử dụng công cụ kubectl và một file .yml (manifest) đã chuẩn bị sẵn được viết bằng YAML. Thực tế thì tool kubectl cũng chỉ call đến Kubernetes Master API thông qua mạng nội bộ, nếu chúng ta không sử dụng kubectl thì cũng có thể sử dụng một thư viện khác hoặc là curl command cũng có thể thao tác được.
Kubernetes và Resource
Nãy giờ mình có nhắc nhiều đến khái niệm resource, thì resource trong kubernetes là gì. Có nhiều loại resource như là: container, load balancer, nodes vv.
Resource của kubernetes có rất nhiều loại nhưng mình tạm phân ra làm 5 nhóm lớn sau:
Phân Loại Resource | Nội dung |
---|---|
Workloads | Resource liên quan đến thực thi container |
Discovery&Load balancer | Resource cung cấp Endpoint - cho phép truy cập Container từ bên ngoài Cluster |
Config&Storage | Resources liên quan đến settings, confidential information, persistent volumes vv |
Cluster | Resources liên quan đến security và quota |
Metadata | Resource cho việc quản lý Resource |
Bài viết lần này, để cho mọi người có thể nắm tổng quan nhất, mình sẽ trình bày về 5 loại resource mà user sử dụng (Không bao gồm những resource được sử dụng nội bộ). Từ bài viết sau trở đi, mình sẽ trình bày chi tiết cho mỗi loại resource. Trong 5 loại resource này, Application Developer thường sử dụng đó là 3 loại Workload, Discovery&LB và Config&Storage.
Để có cái nhìn tổng quan về 5 loại resource này, mình thể hiện thông quan hình vẽ sau:
kubectl và YAML Manifest
Cách làm thực tế để khởi động 1 container, pod, deployment vv là sử dụng file Manifest. Bây giờ chúng ta hãy thử khởi động container bằng file YAML Maniefst. Mình sẽ tạo 1 pod chứa 1 container là nginx
# nginx-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx-pod
spec:
containers:
- name: nginx-pod
image: nginx:1.12
imagePullPolicy: "Always"
Khi tạo resource thì chúng ta sử dụng command kubectl create. Trường hợp resource đã tồn tại, sẽ phát sinh lỗi.
# Trường hợp chưa tồn tại resource
$ kubectl create -f nginx-pod.yml
pod "nginx-pod" created
# Trường hợp tồn tại resource
$ kubectl create -f nginx-pod.yml
Error from server (AlreadyExists): error when creating "nginx-pod.yml": pods "nginx-pod" already exists
Muốn xoá resource thì chúng ta dùng lệnh kubectl delete
# Delete pod
$ kubectl delete -f nginx-pod.yml
pod "nginx-pod" deleted
Khi muốn update resource ta sử dụng lệnh kubectl apply. Mình sẽ sử đổi version của docker image. Sửa lại file với nội dung cập nhật như bên dưới.
# Trước update
image: nginx:1.12
#Sau update
image: nginx:1.13
Sau khi thực hiện update file YAML Manifest xong, ta thực hiện update bằng command kubectl apply. Nếu như file Manifest không có thay đổi gì, không có gì xảy ra ở đây cả. Trường hợp nếu resource chưa tồn tại thì lệnh kubectl apply và lệnh kubectl create là như nhau. Chính về vậy về cơ bản, chung ta không cần sử dụng lệnh kubectl create, chỉ cần lệnh kubectl apply là OK rồi, rất tiện lợi phải không.
# Trường hợp có thay đổi
$ kubectl apply -f nginx-pod.yml
pod "nginx-pod" configured
# Trường hợp không có thay đổi
$ kubectl apply -f nginx-pod.yml
pod "nginx-pod" unchanged
# Resource không tồn tại
$ kubectl apply -f nginx-pod.yml
pod "nginx-pod" created
Ngoài ra còn có các command như kubectl set, kubectl replace, kubectl edit vv. Sử dụng các command này cũng có thể thực hiện thay đổi Manifest.
Cách sử dụng kubectl
Nãy giờ thì mình cũng đã giới thiệu qua một số các thao tác với resource sử dụng kubectl command, tuy nhiên còn có rất nhiều command để get thông tin nữa. Ví dụ như để thực hiện lấy danh sách resource, chúng ta sử dụng kubectl get. Bằng cách sử dụng option --output (-o) có thể xuất ra với nhiều định dạng khác nhau như: JSON/YAML/custom-columns/Go Template. Trường hợp xuất ra với định dạng JSON hay YAML, chúng ta có thể confirm thông tin một cách chi tiết. Với câu lệnh kubectl get all có thể lấy tất cả thông tin resource.
Một số command thường dùng
# Get list node
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kube-master Ready controlplane,etcd 18d v1.10.3
kube-node1 Ready worker 18d v1.10.3
kube-node2 Ready worker 18d v1.10.3
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kube-master Ready controlplane,etcd 18d v1.10.3 <none> CentOS Linux 7 (Core) 3.10.0-862.11.6.el7.x86_64 docker://1.13.1
kube-node1 Ready worker 18d v1.10.3 <none> CentOS Linux 7 (Core) 3.10.0-862.11.6.el7.x86_64 docker://1.13.1
kube-node2 Ready worker 18d v1.10.3 <none> CentOS Linux 7 (Core) 3.10.0-862.11.6.el7.x86_64 docker://1.13.1
# Get list pods
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-deployment-69d88649c7-bf592 2/2 Running 0 17d
frontend-deployment-69d88649c7-kz9xf 2/2 Running 0 17d
frontend-deployment-69d88649c7-ql87x 2/2 Running 0 17d
sample-pod 1/1 Running 0 17d
# Get detail list pod info
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
frontend-deployment-69d88649c7-bf592 2/2 Running 0 17d 10.42.1.9 kube-node1
frontend-deployment-69d88649c7-kz9xf 2/2 Running 0 17d 10.42.2.10 kube-node2
frontend-deployment-69d88649c7-ql87x 2/2 Running 0 17d 10.42.2.11 kube-node2
sample-pod 1/1 Running 0 17d 10.42.1.8 kube-node1
# Get service
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend-service NodePort 10.43.134.81 <none> 80:32253/TCP 18d
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 18d
nginx-php-fpm LoadBalancer 10.43.232.121 150.95.176.186 80:30312/TCP 18d
# Exec pod and specific container
$ kubectl exec -it [pod_name] -c nginx /bin/bash
Giới thiệu tiếp đến các bạn một câu lệnh rất hữu ích, đó là kubectl describe. Là command để lấy thông tin chi tiết của một resource nào đó, chẳng hạn như Pods. Ngoài một số thông tin thường thấy như post, image, container, status vv. Thì thông tin để mình có thể debug mỗi khi container không được start hay ở trạng thái lỗi. Thông tin cần quan tâm nhất khi chạy command này đó là Item "Event", nó thể hiện việc setup volume, việc pull image như thế nào và cả container life cycle.
$ kubectl describe pods nginx-pod
Name: nginx-pod
Namespace: default
Node: minikube/10.0.2.15
Start Time: Wed, 15 Aug 2018 22:06:08 +0700
Labels: app=nginx-pod
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"nginx-pod"},"name":"nginx-pod","namespace":"default"},"spec":{"containers...
Status: Running
IP: 172.17.0.4
Containers:
nginx-pod:
Container ID: docker://db2e78e82e835103d95a5538bcdc8fc7f733dd9c89e9e32944ed30efd28d2f1b
Image: nginx:1.12
Image ID: docker-pullable://nginx@sha256:72daaf46f11cc753c4eab981cbf869919bd1fee3d2170a2adeac12400f494728
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 15 Aug 2018 22:06:43 +0700
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-c4qhx (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-c4qhx:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-c4qhx
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 50m default-scheduler Successfully assigned nginx-pod to minikube
Normal SuccessfulMountVolume 50m kubelet, minikube MountVolume.SetUp succeeded for volume "default-token-c4qhx"
Normal Pulling 50m kubelet, minikube pulling image "nginx:1.12"
Normal Pulled 50m kubelet, minikube Successfully pulled image "nginx:1.12"
Normal Created 50m kubelet, minikube Created container
Normal Started 50m kubelet, minikube Started container
Không chỉ lấy thông tin chi tiết của Pod, với Nodes cũng tương tự.
$ kubectl describe nodes minikube
Name: minikube
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/hostname=minikube
node-role.kubernetes.io/master=
Annotations: node.alpha.kubernetes.io/ttl=0
volumes.kubernetes.io/controller-managed-attach-detach=true
CreationTimestamp: Wed, 15 Aug 2018 22:03:04 +0700
Taints: <none>
Unschedulable: false
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
OutOfDisk False Wed, 15 Aug 2018 23:08:49 +0700 Wed, 15 Aug 2018 22:03:00 +0700 KubeletHasSufficientDisk kubelet has sufficient disk space available
MemoryPressure False Wed, 15 Aug 2018 23:08:49 +0700 Wed, 15 Aug 2018 22:03:00 +0700 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Wed, 15 Aug 2018 23:08:49 +0700 Wed, 15 Aug 2018 22:03:00 +0700 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Wed, 15 Aug 2018 23:08:49 +0700 Wed, 15 Aug 2018 22:03:00 +0700 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Wed, 15 Aug 2018 23:08:49 +0700 Wed, 15 Aug 2018 22:03:00 +0700 KubeletReady kubelet is posting ready status
Addresses:
InternalIP: 10.0.2.15
Hostname: minikube
Capacity:
cpu: 2
ephemeral-storage: 16888216Ki
hugepages-2Mi: 0
memory: 2038624Ki
pods: 110
Allocatable:
cpu: 2
ephemeral-storage: 15564179840
hugepages-2Mi: 0
memory: 1936224Ki
pods: 110
System Info:
Machine ID: bec9c88ab8ce41049005c3426ba5a62d
System UUID: 3CA1DD33-875A-4CBB-BDD3-CA31B5EC0CB5
Boot ID: 1914b073-d566-4c12-bf0d-6731688ab339
Kernel Version: 4.15.0
OS Image: Buildroot 2018.05
Operating System: linux
Architecture: amd64
Container Runtime Version: docker://17.12.1-ce
Kubelet Version: v1.10.0
Kube-Proxy Version: v1.10.0
ExternalID: minikube
Non-terminated Pods: (10 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
default nginx-pod 0 (0%) 0 (0%) 0 (0%) 0 (0%)
kube-system etcd-minikube 0 (0%) 0 (0%) 0 (0%) 0 (0%)
kube-system kube-addon-manager-minikube 5m (0%) 0 (0%) 50Mi (2%) 0 (0%)
kube-system kube-apiserver-minikube 250m (12%) 0 (0%) 0 (0%) 0 (0%)
kube-system kube-controller-manager-minikube 200m (10%) 0 (0%) 0 (0%) 0 (0%)
kube-system kube-dns-86f4d74b45-764qh 260m (13%) 0 (0%) 110Mi (5%) 170Mi (8%)
kube-system kube-proxy-zxjnp 0 (0%) 0 (0%) 0 (0%) 0 (0%)
kube-system kube-scheduler-minikube 100m (5%) 0 (0%) 0 (0%) 0 (0%)
kube-system kubernetes-dashboard-5498ccf677-xpq6t 0 (0%) 0 (0%) 0 (0%) 0 (0%)
kube-system storage-provisioner 0 (0%) 0 (0%) 0 (0%) 0 (0%)
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
CPU Requests CPU Limits Memory Requests Memory Limits
------------ ---------- --------------- -------------
815m (40%) 0 (0%) 160Mi (8%) 170Mi (8%)
Events: <none>
Trong trường hợp muốn kiểm tra log của Pod được xuất ra như thế nào, sử dụng kubectl log.
# Xuất log của container bên trong Pod
$ kubectl logs nginx-pod
# Có thể chỉ định cụ thể log của container nào trong pod có nhiều container
$ kubectl logs nginx-pod -c nginx-container
# Lệnh này thì giống kiểu tail -f (follow log)
$ kubectl logs -f nginx-pod
# Xuất log Trong 1 giờ trước、lấy 10 record, hiển thị timestamps
$ kubectl logs --since=1h --tail=10 --timestamps=true nginx-pod
Trường hợp muốn thực thi một container nào cụ thể trong Pod, sử dụng command kubectl exec. /bin/sh là lệnh mà khi container được start sẽ chạy lệnh này, khi chạy xong ta muốn giữ nó ở trạng thái đã truy cập vào container đó thì gõ thêm option -it.
# Thực thi lệnh /bin/sh một container bên trong Pod
$ kubectl exec -it nginx-pod /bin/sh
# Trường hợp có nhiều container trong 1 Pod, thực thi lệnh /bin/sh đối với container được chỉ định.
$ kubectl exec -it nginx-pod -c nginx-container /bin/sh
# Trường hợp muốn thực thi container có parameter thêm param sau dấu 「--」
$ kubectl exec -it nginx-pod -- /bin/ls -l /
Có một trường hợp mà mình nghĩ nó rất hữu ích. Chẳng hạn như mình muốn debug một ứng dụng web chạy trong container từ máy local, hoặc là muốn kết nối mysql container từ một Database client. Trong trường hợp như vậy chúng ta sử dụng kubectl port-forward.
Bây giờ mình sẽ demo command này ở ở browser máy local của mình, truy cập đến nginx container trong nginx-pod. Khi thực thi lệnh bên dưới và gõ lên browser localhost:8888 thì nó sẽ kết nối đến container nginx port 80.
$ kubectl port-forward nginx-pod 8888:80
Forwarding from 127.0.0.1:8888 -> 80
Forwarding from [::1]:8888 -> 80
Khi làm việc với kubectl, sẽ rất hữu ích nếu chúng ta có thể sử dụng tốt các kubectl command một cách thuần thục. Khi đó việc debug các resource của chúng ta dễ dàng hơn. kubectl còn có nhiều command hữu ích khác, các bạn hãy gõ lệnh kubectl get --help, nó sẽ gợi ý cho mình nhiều command hữu ích và ví dụ cụ thể, các bạn cứ thử thoải mái nhé. Ngoài ra các bạn có thể tham khảo thêm link bên dưới:
Kubectl Tips and Tricks
Tips and Tricks of Using Kubectl, the Kubernetes CLI
Tổng kết
Bài viết này mình đã trình bày cho mọi người liên quan đến các thành phần, resource của kubernetes và một số command thường dùng với kubectl. Bài viết cũng khá dài rồi nên mình xin tạm kết thúc ở đây. Các bài viết sau mình sẽ trình bày chi tiết từng resource.