Thứ hai, 23/07/2018 | 00:00 GMT+7

Cách kiểm tra mạng Kubernetes

Kubernetes là một hệ thống điều phối containers có thể quản lý các ứng dụng được chứa trong một cụm các node server . Duy trì kết nối mạng giữa tất cả các containers trong một cụm đòi hỏi một số kỹ thuật mạng nâng cao. Trong bài viết này, ta sẽ trình bày ngắn gọn một số công cụ và kỹ thuật để kiểm tra cài đặt mạng này.

Những công cụ này có thể hữu ích nếu bạn đang gỡ lỗi các sự cố kết nối, điều tra các vấn đề về thông lượng mạng hoặc khám phá Kubernetes để tìm hiểu cách nó hoạt động.

Nếu bạn muốn tìm hiểu thêm về Kubernetes nói chung, hướng dẫn của ta Giới thiệu về Kubernetes bao gồm những điều cơ bản. Để biết tổng quan về mạng cụ thể của Kubernetes, vui lòng đọcKubernetes Networking Under the Hood .

Bắt đầu

Hướng dẫn này sẽ giả định bạn có một cụm Kubernetes, với kubectl được cài đặt local và được cấu hình để kết nối với cụm.

Các phần sau chứa nhiều lệnh nhằm chạy trên nút Kubernetes. Chúng sẽ trông như thế này:

  • echo 'this is a node command'

Các lệnh sẽ được chạy trên máy local của bạn sẽ có giao diện sau:

  • echo 'this is a local command'

Lưu ý: Hầu hết các lệnh trong hướng dẫn này cần được chạy với quyền user root . Thay vào đó, nếu bạn sử dụng user đã bật sudo trên các node Kubernetes của bạn , hãy thêm sudo để chạy các lệnh khi cần thiết.

Tìm IP cụm của Pod

Để tìm địa chỉ IP cụm của một group Kubernetes, hãy sử dụng lệnh kubectl get pod trên máy local của bạn, với tùy chọn -o wide . Tùy chọn này sẽ liệt kê nhiều thông tin hơn, bao gồm nút mà group nằm trên đó và IP cụm của group .

  • kubectl get pod -o wide
Output
NAME READY STATUS RESTARTS AGE IP NODE hello-world-5b446dd74b-7c7pk 1/1 Running 0 22m 10.244.18.4 node-one hello-world-5b446dd74b-pxtzt 1/1 Running 0 22m 10.244.3.4 node-two

Cột IP sẽ chứa địa chỉ IP cụm nội bộ cho mỗi group .

Nếu bạn không thấy group bạn đang tìm kiếm, hãy đảm bảo bạn đang ở đúng vùng tên. Bạn có thể liệt kê tất cả các group trong tất cả các không gian tên bằng cách thêm cờ --all-namespaces tất cả các không --all-namespaces .

Tìm IP của Dịch vụ

Ta cũng có thể tìm thấy một IP dịch vụ bằng cách sử dụng kubectl . Trong trường hợp này, ta sẽ liệt kê tất cả các dịch vụ trong tất cả các không gian tên:

  • kubectl get service --all-namespaces
Output
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.32.0.1 <none> 443/TCP 6d kube-system csi-attacher-doplugin ClusterIP 10.32.159.128 <none> 12345/TCP 6d kube-system csi-provisioner-doplugin ClusterIP 10.32.61.61 <none> 12345/TCP 6d kube-system kube-dns ClusterIP 10.32.0.10 <none> 53/UDP,53/TCP 6d kube-system kubernetes-dashboard ClusterIP 10.32.226.209 <none> 443/TCP 6d

IP dịch vụ có thể được tìm thấy trong cột CLUSTER-IP .

Tìm và nhập không gian tên mạng Pod

Mỗi group Kubernetes được gán không gian tên mạng riêng. Không gian tên mạng (hoặc mạng) là một mạng nguyên thủy của Linux cung cấp sự cách ly giữa các thiết bị mạng.

Có thể hữu ích khi chạy các lệnh từ bên trong lưới của một pod, để kiểm tra độ phân giải DNS hoặc kết nối mạng chung. Để làm như vậy, trước tiên ta cần tra cứu ID tiến trình của một trong các containers trong một group . Đối với Docker, ta có thể làm điều đó với một loạt hai lệnh. Đầu tiên, liệt kê các containers đang chạy trên một nút:

  • docker ps
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 173ee46a3926 gcr.io/google-samples/node-hello "/bin/sh -c 'node se…" 9 days ago Up 9 days k8s_hello-world_hello-world-5b446dd74b-pxtzt_default_386a9073-7e35-11e8-8a3d-bae97d2c1afd_0 11ad51cb72df k8s.gcr.io/pause-amd64:3.1 "/pause" 9 days ago Up 9 days k8s_POD_hello-world-5b446dd74b-pxtzt_default_386a9073-7e35-11e8-8a3d-bae97d2c1afd_0 . . .

Tìm ID vùng chứa hoặc tên của bất kỳ containers nào trong group mà bạn quan tâm. Trong kết quả ở trên, ta hiển thị hai containers :

  • Vùng chứa đầu tiên là ứng dụng hello-world chạy trong hello-world pod
  • Thứ hai là một containers tạm dừng đang chạy trong hello-world pod. Vùng chứa này chỉ tồn tại để giữ vùng tên mạng của group

Để lấy ID tiến trình của một trong hai containers , hãy ghi lại tên hoặc ID containers và sử dụng nó trong lệnh docker sau:

  • docker inspect --format '{{ .State.Pid }}' container-id-or-name
Output
14552

ID quy trình (hoặc PID) sẽ được xuất ra. Bây giờ ta có thể sử dụng chương trình nsenter để chạy một lệnh trong không gian tên mạng của tiến trình đó:

  • nsenter -t your-container-pid -n ip addr

Đảm bảo sử dụng PID của bạn và thay thế ip addr bằng lệnh bạn muốn chạy bên trong không gian tên mạng của group .

Lưu ý: Một lợi thế của việc sử dụng nsenter để chạy các lệnh trong không gian tên của pod - so với việc sử dụng một cái gì đó giống như trình thực thi docker exec - là bạn có quyền truy cập vào tất cả các lệnh có sẵn trên nút, thay vì bộ lệnh giới hạn thường được cài đặt trong containers .

Tìm giao diện Ethernet ảo của Pod

Không gian tên mạng của mỗi group giao tiếp với mạng root của nút thông qua một đường ống ethernet ảo. Ở phía nút, đường ống này xuất hiện dưới dạng một thiết bị thường bắt đầu bằng veth và kết thúc bằng một số nhận dạng duy nhất, chẳng hạn như veth77f2275 hoặc veth01 . Bên trong pod đường ống này xuất hiện dưới dạng eth0 .

Nó có thể hữu ích để tương quan thiết bị veth nào được ghép nối với một group cụ thể. Để làm như vậy, ta sẽ liệt kê tất cả các thiết bị mạng trên nút, sau đó liệt kê các thiết bị trong không gian tên mạng của group . Sau đó, ta có thể tương quan số thiết bị giữa hai danh sách để thực hiện kết nối.

Đầu tiên, chạy ip addr trong không gian tên mạng của group bằng nsenter . Tham khảo phần trước Tìm và nhập không gian tên mạng Pod
để biết chi tiết về cách thực hiện việc này:

  • nsenter -t your-container-pid -n ip addr
Output
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 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 10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default link/ether 02:42:0a:f4:03:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.244.3.4/24 brd 10.244.3.255 scope global eth0 valid_lft forever preferred_lft forever

Lệnh sẽ xuất ra danh sách các giao diện của group . Lưu ý số if11 sau eth0@ trong kết quả ví dụ. Điều này nghĩa là eth0 của group này được liên kết với giao diện thứ 11 của nút. Bây giờ hãy chạy ip addr trong không gian tên mặc định của nút để liệt kê các giao diện của nó:

  • ip addr
Output
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 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 . . . 7: veth77f2275@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default link/ether 26:05:99:58:0d:b9 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::2405:99ff:fe58:db9/64 scope link valid_lft forever preferred_lft forever 9: vethd36cef3@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default link/ether ae:05:21:a2:9a:2b brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::ac05:21ff:fea2:9a2b/64 scope link valid_lft forever preferred_lft forever 11: veth4f7342d@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default link/ether e6:4d:7b:6f:56:4c brd ff:ff:ff:ff:ff:ff link-netnsid 2 inet6 fe80::e44d:7bff:fe6f:564c/64 scope link valid_lft forever preferred_lft forever

Giao diện thứ 11 là veth4f7342d trong kết quả ví dụ này. Đây là đường ống ethernet ảo đến pod mà ta đang điều tra.

Kiểm tra Theo dõi kết nối Conntrack

Trước version 1.11, Kubernetes đã sử dụng iptables NAT và module kernel conntrack để theo dõi các kết nối. Để liệt kê tất cả các kết nối hiện đang được theo dõi, hãy sử dụng lệnh conntrack :

  • conntrack -L

Để xem liên tục các kết nối mới, hãy sử dụng cờ -E :

  • conntrack -E

Để liệt kê các kết nối được theo dõi conntrack đến một địa chỉ đích cụ thể, hãy sử dụng cờ -d :

  • conntrack -L -d 10.32.0.1

Nếu các node của bạn đang gặp sự cố khi tạo kết nối tin cậy với các dịch vụ, có thể bảng theo dõi kết nối của bạn đã đầy và các kết nối mới đang bị loại bỏ. Nếu đúng như vậy, bạn có thể thấy các thông báo như sau trong log hệ thống của bạn :

/ var / log / syslog
Jul 12 15:32:11 worker-528 kernel: nf_conntrack: table full, dropping packet. 

Có một cài đặt sysctl cho số lượng kết nối tối đa để theo dõi. Bạn có thể liệt kê giá trị hiện tại của bạn bằng lệnh sau:

  • sysctl net.netfilter.nf_conntrack_max
Output
net.netfilter.nf_conntrack_max = 131072

Để đặt một giá trị mới, hãy sử dụng cờ -w :

  • sysctl -w net.netfilter.nf_conntrack_max=198000

Để làm cho cài đặt này vĩnh viễn, hãy thêm nó vào file sysctl.conf :

/etc/sysctl.conf
. . . net.ipv4.netfilter.ip_conntrack_max = 198000 

Kiểm tra luật Iptables

Trước version 1.11, Kubernetes đã sử dụng iptables NAT để thực hiện dịch IP ảo và cân bằng tải cho các IP dịch vụ.

Để kết xuất tất cả các luật iptables trên một nút, hãy sử dụng lệnh iptables-save :

  • iptables-save

Vì kết quả có thể dài, bạn có thể cần chuyển đến một file ( iptables-save > output.txt ) hoặc một máy nhắn tin ( iptables-save | less ) để dễ dàng xem lại các luật hơn.

Để chỉ liệt kê các luật NAT của Dịch vụ Kubernetes, hãy sử dụng lệnh iptables và cờ -L để chỉ định chuỗi chính xác:

  • iptables -t nat -L KUBE-SERVICES
Output
Chain KUBE-SERVICES (2 references) target prot opt source destination KUBE-SVC-TCOU7JCQXEZGVUNU udp -- anywhere 10.32.0.10 /* kube-system/kube-dns:dns cluster IP */ udp dpt:domain KUBE-SVC-ERIFXISQEP7F7OF4 tcp -- anywhere 10.32.0.10 /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:domain KUBE-SVC-XGLOHA7QRQ3V22RZ tcp -- anywhere 10.32.226.209 /* kube-system/kubernetes-dashboard: cluster IP */ tcp dpt:https . . .

Truy vấn DNS cụm

Một cách để gỡ lỗi phân giải DNS cụm của bạn là triển khai một containers gỡ lỗi với tất cả các công cụ bạn cần, sau đó sử dụng kubectl để thực thi nslookup trên đó. Điều này được mô tả trong tài liệu Kubernetes chính thức .

Một cách khác để truy vấn DNS cụm là sử dụng dignsenter từ một nút. Nếu dig chưa được cài đặt, nó có thể được cài đặt bằng apt trên các bản phân phối Linux dựa trên Debian:

  • apt install dnsutils

Trước tiên, hãy tìm IP cụm của dịch vụ kube-dns :

  • kubectl get service -n kube-system kube-dns
Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.32.0.10 <none> 53/UDP,53/TCP 15d

IP cụm được đánh dấu ở trên. Tiếp theo, ta sẽ sử dụng nsenter để chạy dig trong containers tên containers . Xem phần Tìm và Nhập Không gian Tên Mạng Pod để biết thêm thông tin về điều này:

  • nsenter -t 14346 -n dig kubernetes.default.svc.cluster.local @10.32.0.10

Lệnh dig này tra cứu domain dịch vụ đầy đủ của Dịch vụ . không gian tên .svc.cluster.local và chỉ rõ IP của IP dịch vụ DNS cụm ( @ 10.32.0.10 ).

Xem chi tiết IPVS

Kể từ Kubernetes 1.11, kube-proxy có thể cấu hình IPVS để xử lý việc dịch các IP Dịch vụ ảo sang IP group . Bạn có thể liệt kê bảng dịch các IP bằng ipvsadm :

  • ipvsadm -Ln
Output
IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 100.64.0.1:443 rr -> 178.128.226.86:443 Masq 1 0 0 TCP 100.64.0.10:53 rr -> 100.96.1.3:53 Masq 1 0 0 -> 100.96.1.4:53 Masq 1 0 0 UDP 100.64.0.10:53 rr -> 100.96.1.3:53 Masq 1 0 0 -> 100.96.1.4:53 Masq 1 0 0

Để hiển thị một IP Dịch vụ, hãy sử dụng tùy chọn -t và chỉ định IP mong muốn:

  • ipvsadm -Ln -t 100.64.0.10:53
Output
Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 100.64.0.10:53 rr -> 100.96.1.3:53 Masq 1 0 0 -> 100.96.1.4:53 Masq 1 0 0

Kết luận

Trong bài viết này, ta đã xem xét một số lệnh và kỹ thuật để khám phá và kiểm tra các chi tiết về mạng của cụm Kubernetes của bạn. Để biết thêm thông tin về Kubernetes, hãy xem thẻ hướng dẫn Kubernetes của ta tài liệu Kubernetes chính thức .


Tags:

Các tin liên quan