16/09/2018, 13:10

Làm thế nào để kiểm tra mạng Kubernetes

Giới thiệu Kubernetes là một hệ thống dàn xếp container có thể quản lý các ứng dụng được chứa trong một cụm các nút máy chủ. Duy trì kết nối mạng giữa tất cả các vùng chứa 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, chúng tôi sẽ giới thiệu một số công cụ và kỹ thuật ...

Giới thiệu

Kubernetes là một hệ thống dàn xếp container có thể quản lý các ứng dụng được chứa trong một cụm các nút máy chủ. Duy trì kết nối mạng giữa tất cả các vùng chứa 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, chúng tôi sẽ giới thiệu một số công cụ và kỹ thuật ngắn gọn để kiểm tra thiết lập 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 vấn đề 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 hoạt động của nó.

Nếu bạn muốn tìm hiểu thêm về Kubernetes nói chung, hướng dẫn của chúng tôi Giới thiệu về Kubernetes bao gồm các khái niệm cơ bản. Để biết tổng quan về mạng cụ thể của Kubernetes, vui lòng đọc Kubernetes mạng dưới mui xe.

Bắt đầu

Hướng dẫn này sẽ giả định rằng bạn có một cụm Kubernetes, với kubectl được cài đặt cục bộ 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 được dự định chạy trên nút Kubernetes. Họ sẽ trông như thế này:

echo 'this is a node command'

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

echo 'this is a local command'

Chú thích: Hầu hết các lệnh trong hướng dẫn này sẽ cần phải được chạy như nguồn gốc người dùng. Thay vào đó, nếu bạn sử dụng người dùng kích hoạt sudo trên các nút Kubernetes của mình, vui lòng thêm sudo để chạy các lệnh khi cần thiết.

Tìm IP cụm của cụm

Để tìm địa chỉ IP cụm của một Kubernetes pod, sử dụng kubectl get pod lệnh trên máy cục bộ 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à nhóm nằm trên và IP cụm của nhóm.

kubectl get pod -o wide

OutputNAME                           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ác IP sẽ chứa địa chỉ IP cụm nội bộ cho mỗi nhóm.

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

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

Chúng tôi có thể tìm thấy một IP dịch vụ bằng cách sử dụng kubectl cũng. Trong trường hợp này, chúng tôi 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

OutputNAMESPACE     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 CLUSTER-IP cột.

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

Mỗi Kubernetes pod được gán không gian tên mạng riêng của nó. Các không gian tên mạng (hoặc netns) là một nguyên thủy mạng 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 mạng của một nhóm, để 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, chúng tôi cần tra cứu ID tiến trình của một trong các vùng chứa trong nhóm. Đối với Docker, chúng ta có thể làm điều đó với một loạt hai lệnh. Đầu tiên, liệt kê các thùng chứa đang chạy trên một nút:

docker ps

OutputCONTAINER 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 là Tên của bất kỳ vùng chứa nào trong nhóm bạn quan tâm. Trong kết quả trên, chúng tôi hiển thị hai vùng chứa:

  • Thùng chứa đầu tiên là hello-world ứng dụng đang chạy trong hello-world vỏ trái cây
  • Thứ hai là một tạm ngừng container chạy trong hello-world pod. Vùng chứa này chỉ tồn tại để giữ không gian tên mạng của nhóm

Để có được ID quá trình của một trong hai vùng chứa, hãy lưu ý ID hoặc tên vùng chứa và sử dụng nó trong các mục sau docker chỉ huy:

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

Output
14552

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

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

Hãy chắc chắn sử dụng PID của riêng bạn và thay thế ip addr với lệnh bạn muốn chạy bên trong không gian tên mạng của nhóm.

Chú thích: 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 nhóm - so với sử dụng một cái gì đó như 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ì tập lệnh giới hạn thường được cài đặt trong vùng chứa.

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

Không gian tên mạng của mỗi nhóm giao tiếp với mạng gốc của node thông qua một đường ống ethernet ảo. Ở bên nút, đường ống này xuất hiện dưới dạng 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 là veth01. Bên trong vỏ, đường ống này xuất hiện eth0.

Nó có thể hữu ích để tương quan veth thiết bị được ghép nối với một nhóm cụ thể. Để làm như vậy, chúng tôi 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 nhóm. Sau đó chúng tôi 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, hãy chạy ip addr trong không gian tên mạng của nhóm bằng cách sử dụ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

Output1: 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 một danh sách các giao diện của nhóm. Lưu ý if11 số sau eth0@ trong ví dụ đầu ra. Điều này có nghĩa là eth0 được liên kết với giao diện thứ 11 của nút. Bây giờ 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út đó:

ip addr

Output1: 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 ví dụ này. Đây là ống ethernet ảo cho nhóm chúng tôi đang điều tra.

Kiểm tra theo dõi kết nối conntrack

Trước phiên bản 1.11, Kubernetes đã sử dụng iptables NAT và mô-đun hạt nhân 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 conntrack chỉ huy:

conntrack -L

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

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 -d cờ:

conntrack -L -d 10.32.0.1

Nếu các nút của bạn gặp sự cố khi kết nối đáng 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 sẽ bị loại bỏ. Nếu đó là trường hợp bạn có thể thấy các thông báo như sau trong nhật ký 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 thiết lập 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 mình bằng lệnh sau:

sysctl net.netfilter.nf_conntrack_max

Outputnet.netfilter.nf_conntrack_max = 131072

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

sysctl -w net.netfilter.nf_conntrack_max=198000

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

/etc/sysctl.conf

. . .
net.ipv4.netfilter.ip_conntrack_max = 198000

Kiểm tra quy tắc Iptables

Trước phiên bản 1.11, Kubernetes đã sử dụng iptables NAT để triển khai dịch IP ảo và cân bằng tải cho các Service IP.

Để đổ tất cả các quy tắc iptables trên một nút, hãy sử dụng iptables-save chỉ huy:

iptables-save

Bởi vì đầu ra có thể dài, bạn có thể muốn đường dẫn đến một tệp (iptables-save > output.txt) hoặc máy nhắn tin (iptables-save | less) để dễ dàng xem lại các quy tắc.

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

iptables -t nat -L KUBE-SERVICES

OutputChain 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 Cluster DNS

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

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

apt install dnsutils

Đầu tiên, tìm IP cụm của kube-dns dịch vụ:

kubectl get service -n kube-system kube-dns

OutputNAME       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 tô sáng ở trên. Tiếp theo chúng ta sẽ sử dụng nsenter chạy dig trong vùng tên vùng chứa. Nhìn vào 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

Điều này dig lệnh tra cứu tên miền đầy đủ của Dịch vụ Tên dịch vụ.không gian tên.svc.cluster.local và cụ thể địa chỉ IP của dịch vụ DNS cụm DNS (@10.32.0.10).

Xem chi tiết IPVS

Theo 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 thành các IP nhóm. Bạn có thể liệt kê bảng dịch của các IP với ipvsadm:

ipvsadm -Ln

OutputIP 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ụ duy nhất, hãy sử dụng -t và chỉ định IP mong muốn:

ipvsadm -Ln -t 100.64.0.10:53

OutputProt 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

Phần kết luận

Trong bài viết này, chúng tôi đã 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 chúng tôi và tài liệu chính thức của Kubernetes.

0