웹사이트 검색

Kubernetes 네트워킹을 검사하는 방법


소개

Kubernetes는 서버 노드 클러스터에서 컨테이너화된 애플리케이션을 관리할 수 있는 컨테이너 오케스트레이션 시스템입니다. 클러스터의 모든 컨테이너 간에 네트워크 연결을 유지하려면 몇 가지 고급 네트워킹 기술이 필요합니다. 이 기사에서는 이 네트워킹 설정을 검사하기 위한 몇 가지 도구와 기술을 간략하게 다룹니다.

이러한 도구는 연결 문제를 디버깅하거나, 네트워크 처리량 문제를 조사하거나, 작동 방식을 알아보기 위해 Kubernetes를 탐색하는 경우에 유용할 수 있습니다.

일반적인 Kubernetes에 대해 자세히 알아보려면 Kubernetes Networking Under the Hood 가이드를 참조하세요.

시작하기

이 튜토리얼에서는 kubectl이 로컬에 설치되고 클러스터에 연결하도록 구성된 Kubernetes 클러스터가 있다고 가정합니다.

다음 섹션에는 Kubernetes 노드에서 실행하기 위한 많은 명령이 포함되어 있습니다. 다음과 같이 표시됩니다.

  1. echo 'this is a node command'

로컬 시스템에서 실행해야 하는 명령은 다음과 같이 표시됩니다.

  1. echo 'this is a local command'

참고: 이 자습서에 있는 대부분의 명령은 루트 사용자로 실행해야 합니다. 대신 Kubernetes 노드에서 sudo 사용 사용자를 사용하는 경우 sudo를 추가하여 필요할 때 명령을 실행하십시오.

포드의 클러스터 IP 찾기

Kubernetes 포드의 클러스터 IP 주소를 찾으려면 로컬 시스템에서 -o wide 옵션과 함께 kubectl get pod 명령을 사용합니다. 이 옵션은 포드가 상주하는 노드 및 포드의 클러스터 IP를 포함하여 추가 정보를 나열합니다.

  1. 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

IP 열에는 각 포드의 내부 클러스터 IP 주소가 포함됩니다.

찾고 있는 팟(Pod)이 표시되지 않으면 올바른 네임스페이스에 있는지 확인하십시오. --all-namespaces 플래그를 추가하여 모든 네임스페이스의 모든 포드를 나열할 수 있습니다.

서비스의 IP 찾기

kubectl을 사용하여 서비스 IP를 찾을 수도 있습니다. 이 경우 모든 네임스페이스의 모든 서비스를 나열합니다.

  1. 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는 CLUSTER-IP 열에서 찾을 수 있습니다.

포드 네트워크 네임스페이스 찾기 및 입력

각 Kubernetes 포드에는 자체 네트워크 네임스페이스가 할당됩니다. 네트워크 네임스페이스(또는 netns)는 네트워크 장치 간에 격리를 제공하는 Linux 네트워킹 기본 요소입니다.

포드의 netns 내에서 명령을 실행하여 DNS 확인 또는 일반 네트워크 연결을 확인하는 것이 유용할 수 있습니다. 이를 위해서는 먼저 포드에 있는 컨테이너 중 하나의 프로세스 ID를 조회해야 합니다. Docker의 경우 일련의 두 가지 명령으로 이를 수행할 수 있습니다. 먼저 노드에서 실행 중인 컨테이너를 나열합니다.

  1. 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 . . .

관심 있는 팟(Pod)에서 컨테이너 ID 또는 컨테이너 이름을 찾으십시오. 위의 출력에는 두 개의 컨테이너가 표시됩니다.

  • 첫 번째 컨테이너는 hello-world 포드에서 실행되는 hello-world 앱입니다
  • 두 번째는 hello-world 포드에서 실행되는 pause 컨테이너입니다. 이 컨테이너는 포드의 네트워크 네임스페이스를 유지하기 위해서만 존재합니다.

두 컨테이너의 프로세스 ID를 가져오려면 컨테이너 ID 또는 이름을 기록하고 다음 docker 명령에서 사용합니다.

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

프로세스 ID(또는 PID)가 출력됩니다. 이제 nsenter 프로그램을 사용하여 해당 프로세스의 네트워크 네임스페이스에서 명령을 실행할 수 있습니다.

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

자신의 PID를 사용하고 ip addr을 포드의 네트워크 네임스페이스 내에서 실행하려는 명령으로 바꾸십시오.

참고: nsenter를 사용하여 포드의 네임스페이스에서 명령을 실행하는 것의 한 가지 이점은 docker exec와 같은 것을 사용하는 것과 비교하여 노드에서 사용 가능한 모든 명령에 액세스할 수 있다는 것입니다. , 컨테이너에 설치된 일반적으로 제한된 명령 세트 대신.

포드의 가상 이더넷 인터페이스 찾기

각 포드의 네트워크 네임스페이스는 가상 이더넷 파이프를 통해 노드의 루트 netns와 통신합니다. 노드 측에서 이 파이프는 일반적으로 veth로 시작하고 veth77f2275 또는 veth01과 같은 고유 식별자로 끝나는 장치로 나타납니다. 포드 내에서 이 파이프는 eth0로 나타납니다.

어떤 veth 장치가 특정 포드와 페어링되었는지 상관시키는 것이 유용할 수 있습니다. 이를 위해 노드의 모든 네트워크 장치를 나열한 다음 포드의 네트워크 네임스페이스에 있는 장치를 나열합니다. 그런 다음 두 목록 사이의 장치 번호를 연관시켜 연결할 수 있습니다.

먼저 nsenter를 사용하여 포드의 네트워크 네임스페이스에서 ip addr을 실행합니다. 이전 섹션 Pod 네트워크 네임스페이스 찾기 및 입력을 참조하십시오.

  1. 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

이 명령은 포드의 인터페이스 목록을 출력합니다. 예제 출력에서 eth0@ 뒤에 있는 if11 번호에 유의하십시오. 이는 이 포드의 eth0이 노드의 11번째 인터페이스에 연결되어 있음을 의미합니다. 이제 노드의 기본 네임스페이스에서 ip addr을 실행하여 인터페이스를 나열합니다.

  1. 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

이 예제 출력에서 11번째 인터페이스는 veth4f7342d입니다. 이것은 우리가 조사하고 있는 포드에 대한 가상 이더넷 파이프입니다.

Conntrack 연결 추적 검사

버전 1.11 이전에 Kubernetes는 iptables NAT 및 conntrack 커널 모듈을 사용하여 연결을 추적했습니다. 현재 추적 중인 모든 연결을 나열하려면 conntrack 명령을 사용하십시오.

  1. conntrack -L

새로운 연결을 지속적으로 감시하려면 -E 플래그를 사용하십시오.

  1. conntrack -E

특정 대상 주소에 대한 conntrack 추적 연결을 나열하려면 -d 플래그를 사용하십시오.

  1. conntrack -L -d 10.32.0.1

노드가 서비스에 안정적으로 연결하는 데 문제가 있는 경우 연결 추적 테이블이 가득 차서 새 연결이 끊어질 수 있습니다. 이 경우 시스템 로그에 다음과 같은 메시지가 표시될 수 있습니다.

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

추적할 최대 연결 수에 대한 sysctl 설정이 있습니다. 다음 명령을 사용하여 현재 값을 나열할 수 있습니다.

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

새 값을 설정하려면 -w 플래그를 사용하십시오.

  1. sysctl -w net.netfilter.nf_conntrack_max=198000

이 설정을 영구적으로 만들려면 sysctl.conf 파일에 추가하십시오.

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

Iptables 규칙 검사

버전 1.11 이전에 Kubernetes는 iptables NAT를 사용하여 서비스 IP에 대한 가상 IP 변환 및 로드 밸런싱을 구현했습니다.

노드의 모든 iptables 규칙을 덤프하려면 iptables-save 명령을 사용하십시오.

  1. iptables-save

출력이 길 수 있으므로 파일(iptables-save > output.txt) 또는 페이저(iptables-save | less)로 파이프하여 규칙을 쉽게 검토할 수 있습니다.

Kubernetes Service NAT 규칙만 나열하려면 iptables 명령과 -L 플래그를 사용하여 올바른 체인을 지정합니다.

  1. 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 . . .

클러스터 DNS 쿼리

클러스터 DNS 확인을 디버깅하는 한 가지 방법은 필요한 모든 도구와 함께 디버그 컨테이너를 배포한 다음 kubectl을 사용하여 nslookup을 실행하는 것입니다. 이는 공식 Kubernetes 문서에 설명되어 있습니다.

클러스터 DNS를 쿼리하는 또 다른 방법은 노드에서 dignsenter를 사용하는 것입니다. dig가 설치되지 않은 경우 Debian 기반 Linux 배포판에 apt를 사용하여 설치할 수 있습니다.

  1. apt install dnsutils

먼저 kube-dns 서비스의 클러스터 IP를 찾습니다.

  1. 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는 위에 강조 표시되어 있습니다. 다음으로 nsenter를 사용하여 컨테이너 네임스페이스에서 dig를 실행합니다. 이에 대한 자세한 내용은 파드 네트워크 네임스페이스 찾기 및 입력 섹션을 참조하십시오.

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

dig 명령은 서비스의 전체 도메인 이름인 service-name.namespace.svc.cluster.local을 조회하고 클러스터의 IP를 지정합니다. DNS 서비스 IP(@10.32.0.10).

IPVS 세부 정보 보기

Kubernetes 1.11부터 kube-proxy는 가상 서비스 IP를 포드 IP로 변환하는 작업을 처리하도록 IPVS를 구성할 수 있습니다. ipvsadm을 사용하여 IP 변환 테이블을 나열할 수 있습니다.

  1. 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

단일 서비스 IP를 표시하려면 -t 옵션을 사용하고 원하는 IP를 지정합니다.

  1. 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

결론

이 기사에서는 Kubernetes 클러스터 네트워킹의 세부 정보를 탐색하고 검사하기 위한 몇 가지 명령과 기술을 검토했습니다. Kubernetes에 대한 자세한 내용은 공식 Kubernetes 설명서를 참조하십시오.