Ssoon
[5주차] LoadBalancer - MetalLB 본문
CloudNet@ 가시다님이 진행하는 쿠버네티스 네트워크 스터디 3기
✅ 기본 구성 환경
🧿 실습을 위해 pod 를 생성합니다.
(⎈|kind-myk8s:N/A) root@kind:~# cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: webpod1
labels:
app: webpod
spec:
nodeName: myk8s-worker
containers:
- name: container
image: traefik/whoami
terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
name: webpod2
labels:
app: webpod
spec:
nodeName: myk8s-worker2
containers:
- name: container
image: traefik/whoami
terminationGracePeriodSeconds: 0
EOF
pod/webpod1 created
pod/webpod2 created
🧿 pod 의 정보를 확인합니다.
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
webpod1 1/1 Running 0 30s 10.10.1.2 myk8s-worker <none> <none>
webpod2 1/1 Running 0 30s 10.10.2.4 myk8s-worker2 <none> <none>
🧿 pod 접속을 확인합니다.
(⎈|kind-myk8s:N/A) root@kind:~# WPOD1=$(kubectl get pod webpod1 -o jsonpath="{.status.podIP}")
(⎈|kind-myk8s:N/A) root@kind:~# WPOD2=$(kubectl get pod webpod2 -o jsonpath="{.status.podIP}")
(⎈|kind-myk8s:N/A) root@kind:~# echo $WPOD1 $WPOD2
10.10.1.2 10.10.2.4
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it myk8s-control-plane ping -i 1 -W 1 -c 1 $WPOD1
PING 10.10.1.2 (10.10.1.2) 56(84) bytes of data.
64 bytes from 10.10.1.2: icmp_seq=1 ttl=63 time=0.108 ms
--- 10.10.1.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.108/0.108/0.108/0.000 ms
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it myk8s-control-plane ping -i 1 -W 1 -c 1 $WPOD2
PING 10.10.2.4 (10.10.2.4) 56(84) bytes of data.
64 bytes from 10.10.2.4: icmp_seq=1 ttl=63 time=0.104 ms
--- 10.10.2.4 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.104/0.104/0.104/0.000 ms
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it myk8s-control-plane curl -s --connect-timeout 1 $WPOD1 | grep Hostname
Hostname: webpod1
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it myk8s-control-plane curl -s --connect-timeout 1 $WPOD2 | grep Hostname
Hostname: webpod2
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it myk8s-control-plane curl -s --connect-timeout 1 $WPOD1 | egrep 'Hostname|RemoteAddr|Host:'
Hostname: webpod1
RemoteAddr: 172.18.0.4:45058
Host: 10.10.1.2
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it myk8s-control-plane curl -s --connect-timeout 1 $WPOD2 | egrep 'Hostname|RemoteAddr|Host:'
Hostname: webpod2
RemoteAddr: 172.18.0.4:35188
Host: 10.10.2.4
✅ MetalLB - Layer 2 모드
🧿 Kubernetes 클러스터에 MetalLB를 설치합니다.
(⎈|kind-myk8s:N/A) root@kind:~# kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/refs/heads/main/config/manifests/metallb-native-prometheus.yaml
namespace/metallb-system created
customresourcedefinition.apiextensions.k8s.io/bfdprofiles.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io created
...
🧿 Kubernetes 클러스터에서 MetalLB와 관련된 Custom Resource Definitions (CRDs)를 조회합니다.
- bfdprofiles.metallb.io:
- BFD (Bidirectional Forwarding Detection) 프로파일을 정의합니다. 이는 MetalLB가 네트워크 장애를 감지하는 데 사용됩니다.
- bgpadvertisements.metallb.io:
- BGP (Border Gateway Protocol) 광고를 정의합니다. MetalLB가 클러스터의 IP 주소를 BGP를 통해 광고하는 데 필요한 정보를 담고 있습니다.
- bgppeers.metallb.io:
- BGP 피어를 정의합니다. BGP를 사용하여 다른 라우터와 연결하기 위해 설정하는 피어 정보를 포함합니다.
- communities.metallb.io:
- BGP 커뮤니티를 정의합니다. BGP 라우팅에 추가적인 메타데이터를 첨부하는 데 사용됩니다.
- ipaddresspools.metallb.io:
- MetalLB가 할당할 수 있는 IP 주소 풀을 정의합니다. 이를 통해 LoadBalancer 서비스에 사용할 수 있는 IP 주소 범위를 설정할 수 있습니다.
- l2advertisements.metallb.io:
- Layer 2 광고를 정의합니다. L2 모드에서 MetalLB가 IP 주소를 어떻게 광고할지를 설정하는 데 사용됩니다.
- servicel2statuses.metallb.io:
- L2 서비스의 상태를 추적하는 리소스입니다. MetalLB가 L2 모드에서 서비스를 처리할 때의 상태 정보를 포함합니다.
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get crd | grep metallb
bfdprofiles.metallb.io 2024-10-02T11:24:17Z
bgpadvertisements.metallb.io 2024-10-02T11:24:17Z
bgppeers.metallb.io 2024-10-02T11:24:17Z
communities.metallb.io 2024-10-02T11:24:17Z
ipaddresspools.metallb.io 2024-10-02T11:24:17Z
l2advertisements.metallb.io 2024-10-02T11:24:17Z
servicel2statuses.metallb.io 2024-10-02T11:24:17Z
🧿 MetalLB 시스템 네임스페이스에서 실행 중인 모든 Kubernetes 리소스를 조회합니다.
- Pods
- pod/controller-679855f7d7-ftx5h:
- MetalLB의 컨트롤러로, MetalLB의 관리 및 상태를 유지하는 역할을 합니다.
- pod/speaker-4dp2q, pod/speaker-5l6nl, pod/speaker-g9sw7, pod/speaker-lfvgl:
- MetalLB의 스피커로, 실제로 IP 주소를 클러스터 외부로 광고하는 역할을 수행합니다.
- pod/controller-679855f7d7-ftx5h:
- Services
- service/controller-monitor-service:
- MetalLB 컨트롤러의 모니터링을 위한 서비스입니다.
- service/metallb-webhook-service:
- MetalLB의 웹후크 서비스로, API 서버와의 통신을 위해 사용됩니다.
- service/speaker-monitor-service:
- 스피커의 모니터링을 위한 서비스입니다.
- service/controller-monitor-service:
- DaemonSet
- daemonset.apps/speaker:
- MetalLB 스피커를 모든 노드에 배포하기 위한 DaemonSet입니다. 현재 4개의 스피커가 실행되고 있습니다.
- Node Selector: kubernetes.io/os=linux로, 리눅스 노드에서만 실행됩니다.
- daemonset.apps/speaker:
- Deployment
- deployment.apps/controller:
- MetalLB 컨트롤러의 배포 상태를 나타내며, 현재 1개가 실행 중입니다.
- deployment.apps/controller:
- ReplicaSet
- replicaset.apps/controller-679855f7d7:
- 위의 컨트롤러와 연결된 ReplicaSet으로, 컨트롤러의 복제본을 관리합니다.
- replicaset.apps/controller-679855f7d7:
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get all -n metallb-system
NAME READY STATUS RESTARTS AGE
pod/controller-679855f7d7-ftx5h 2/2 Running 0 90s
pod/speaker-4dp2q 2/2 Running 0 90s
pod/speaker-5l6nl 2/2 Running 0 90s
pod/speaker-g9sw7 2/2 Running 0 90s
pod/speaker-lfvgl 2/2 Running 0 90s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/controller-monitor-service ClusterIP None <none> 9120/TCP 90s
service/metallb-webhook-service ClusterIP 10.200.1.222 <none> 443/TCP 90s
service/speaker-monitor-service ClusterIP None <none> 9120/TCP 90s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/speaker 4 4 4 4 4 kubernetes.io/os=linux 90s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/controller 1/1 1 1 90s
NAME DESIRED CURRENT READY AGE
replicaset.apps/controller-679855f7d7 1 1 1 90s
🧿 MetalLB 시스템 네임스페이스에서 ConfigMap, Secret, 및 Endpoint 리소스를 조회합니다.
- ConfigMaps
- configmap/kube-root-ca.crt:
- Kubernetes 클러스터의 루트 CA 인증서가 저장된 ConfigMap입니다. 이 인증서는 클러스터의 보안 통신에 필요합니다.
- Kubernetes 클러스터의 루트 CA 인증서가 저장된 ConfigMap입니다. 이 인증서는 클러스터의 보안 통신에 필요합니다.
- configmap/metallb-excludel2:
- MetalLB의 L2 모드에서 제외할 IP 주소 범위를 정의하는 ConfigMap입니다. 이를 통해 특정 IP 주소가 MetalLB의 관리를 받지 않도록 설정할 수 있습니다.
- MetalLB의 L2 모드에서 제외할 IP 주소 범위를 정의하는 ConfigMap입니다. 이를 통해 특정 IP 주소가 MetalLB의 관리를 받지 않도록 설정할 수 있습니다.
- configmap/kube-root-ca.crt:
- Secrets
- secret/memberlist:
- MetalLB의 멤버리스트 구성 요소에 관련된 비밀 정보가 포함된 Secret입니다. 이는 스피커가 서로 소통할 수 있도록 하는 데 필요합니다.
- MetalLB의 멤버리스트 구성 요소에 관련된 비밀 정보가 포함된 Secret입니다. 이는 스피커가 서로 소통할 수 있도록 하는 데 필요합니다.
- secret/metallb-webhook-cert:
- MetalLB의 웹후크 서비스에 대한 인증서와 관련된 Secret입니다. 이 인증서는 HTTPS 통신을 위한 것으로, MetalLB의 API 서버와의 안전한 연결을 보장합니다.
- MetalLB의 웹후크 서비스에 대한 인증서와 관련된 Secret입니다. 이 인증서는 HTTPS 통신을 위한 것으로, MetalLB의 API 서버와의 안전한 연결을 보장합니다.
- secret/memberlist:
- Endpoints
- endpoints/controller-monitor-service:
- MetalLB의 컨트롤러 모니터링 서비스의 엔드포인트로, 10.10.2.3:9120에서 서비스가 제공됩니다.
- MetalLB의 컨트롤러 모니터링 서비스의 엔드포인트로, 10.10.2.3:9120에서 서비스가 제공됩니다.
- endpoints/metallb-webhook-service:
- MetalLB 웹후크 서비스의 엔드포인트로, 10.10.2.3:9443에서 서비스가 제공됩니다.
- MetalLB 웹후크 서비스의 엔드포인트로, 10.10.2.3:9443에서 서비스가 제공됩니다.
- endpoints/speaker-monitor-service:
- MetalLB 스피커의 모니터링 서비스 엔드포인트입니다.
- 172.18.0.2, 172.18.0.3, 172.18.0.4에서 각각 9120 포트를 통해 서비스가 제공됩니다.
- endpoints/controller-monitor-service:
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get configmap,secret,ep -n metallb-system
NAME DATA AGE
configmap/kube-root-ca.crt 1 64m
configmap/metallb-excludel2 1 64m
NAME TYPE DATA AGE
secret/memberlist Opaque 1 64m
secret/metallb-webhook-cert Opaque 4 64m
NAME ENDPOINTS AGE
endpoints/controller-monitor-service 10.10.2.3:9120 64m
endpoints/metallb-webhook-service 10.10.2.3:9443 64m
endpoints/speaker-monitor-service 172.18.0.2:9120,172.18.0.3:9120,172.18.0.4:9120 + 1 more... 64m
🧿 MetalLB 관련 Pod의 정보를 조회하여 각 컨테이너의 이름과 이미지를 출력합니다.
- controller-679855f7d7-ftx5h:
- kube-rbac-proxy:
- 이 컨테이너는 RBAC(역할 기반 접근 제어)를 위한 프록시로 사용됩니다. Kubernetes API 서버와의 안전한 통신을 보장합니다.
- controller:
MetalLB의 컨트롤러 컨테이너입니다. 클러스터의 서비스 리소스를 모니터링하고, 이를 외부 IP 주소에 매핑하는 역할을 합니다.
- 이 컨테이너는 RBAC(역할 기반 접근 제어)를 위한 프록시로 사용됩니다. Kubernetes API 서버와의 안전한 통신을 보장합니다.
- kube-rbac-proxy:
- speaker-4dp2q, speaker-5l6nl, speaker-g9sw7, speaker-lfvgl: 각 스피커 Pod에는 동일한 두 개의 컨테이너가 있습니다.
- kube-rbac-proxy:
- 위와 동일하게 RBAC를 위한 프록시입니다.
- 위와 동일하게 RBAC를 위한 프록시입니다.
- speaker:
- MetalLB의 스피커 컨테이너입니다. 이 컨테이너는 MetalLB의 IP 주소를 노드에 배포하고, 해당 IP 주소를 서비스와 연결하여 실제 트래픽을 처리합니다.
- kube-rbac-proxy:
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get pods -n metallb-system -l app=metallb -o jsonpath="{range .items[*]}{.metadata.name}{':\n'}{range .spec.containers[*]}{' '}{.name}{' -> '}{.image}{'\n'}{end}{end}"
controller-679855f7d7-ftx5h:
kube-rbac-proxy -> gcr.io/kubebuilder/kube-rbac-proxy:v0.12.0
controller -> quay.io/metallb/controller:main
speaker-4dp2q:
kube-rbac-proxy -> gcr.io/kubebuilder/kube-rbac-proxy:v0.12.0
speaker -> quay.io/metallb/speaker:main
speaker-5l6nl:
kube-rbac-proxy -> gcr.io/kubebuilder/kube-rbac-proxy:v0.12.0
speaker -> quay.io/metallb/speaker:main
speaker-g9sw7:
kube-rbac-proxy -> gcr.io/kubebuilder/kube-rbac-proxy:v0.12.0
speaker -> quay.io/metallb/speaker:main
speaker-lfvgl:
kube-rbac-proxy -> gcr.io/kubebuilder/kube-rbac-proxy:v0.12.0
speaker -> quay.io/metallb/speaker:main
🧿 MetalLB 시스템 네임스페이스에서 실행 중인 Pod들의 상태를 확인합니다.
- controller Pod은 myk8s-worker2에 배포되었고, 스피커 Pod들은 myk8s-control-plane, myk8s-worker, myk8s-worker3에 배포되었습니다.
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get pod -n metallb-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
controller-679855f7d7-ftx5h 2/2 Running 0 3m27s 10.10.2.3 myk8s-worker2 <none> <none>
speaker-4dp2q 2/2 Running 0 3m27s 172.18.0.4 myk8s-control-plane <none> <none>
speaker-5l6nl 2/2 Running 0 3m27s 172.18.0.2 myk8s-worker <none> <none>
speaker-g9sw7 2/2 Running 0 3m27s 172.18.0.5 myk8s-worker3 <none> <none>
speaker-lfvgl 2/2 Running 0 3m27s 172.18.0.3 myk8s-worker2 <none> <none>
🧿 MetalLB에 IP 주소 풀을 생성하여 Kubernetes 서비스에 외부 IP를 자동으로 할당합니다.
- IPAddressPool
- 클러스터 내 서비스에 할당할 수 있는 IP 주소 범위를 정의합니다
- MetalLB는 서비스를 위한 외부 IP 주소를 관리하고, 서비스가 생성될 때 해당 IP 주소를 동적으로 할당할 수 있습니다.
(⎈|kind-myk8s:N/A) root@kind:~# cat <<EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: my-ippool # IP 주소 풀의 이름
namespace: metallb-system
spec:
addresses:
- 172.18.255.200-172.18.255.250 #사용 가능한 IP 주소 범위
EOF
ipaddresspool.metallb.io/my-ippool created
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get ipaddresspools -n metallb-system
NAME AUTO ASSIGN AVOID BUGGY IPS ADDRESSES
my-ippool true false ["172.18.255.200-172.18.255.250"]
🧿 MetalLB가 지정된 IP 주소 풀을 L2 방식으로 광고하도록 설정합니다.
- L2Advertisement
- Kubernetes 클러스터 내의 서비스가 외부 네트워크에 IP 주소를 광고하는 방식을 정의합니다.
- MetalLB는 브로드캐스트 프로토콜을 통해 클러스터 내의 서비스 IP 주소를 광고하여 클라이언트가 해당 IP 주소에 접근할 수 있도록 합니다.
(⎈|kind-myk8s:N/A) root@kind:~# cat <<EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: my-l2-advertise #L2Advertisement의 이름
namespace: metallb-system
spec:
ipAddressPools: #광고할 IP 주소 풀의 이름
- my-ippool
EOF
l2advertisement.metallb.io/my-l2-advertise created
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get l2advertisements -n metallb-system
NAME IPADDRESSPOOLS IPADDRESSPOOL SELECTORS INTERFACES
my-l2-advertise ["my-ippool"]
🧿세 개의 Service 리소스 (svc1, svc2, svc3) 을 생성합니다.
- 세 개의 서비스는 LoadBalancer 타입으로 설정되어 있으며, app: webpod 레이블을 가진 파드로 트래픽을 전달합니다
(⎈|kind-myk8s:N/A) root@kind:~# cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: svc1 #서비스의 이름
spec:
ports:
- name: svc1-webport
port: 80 #서비스가 외부에 노출할 포트
targetPort: 80 #클러스터 내 파드의 실제 포트입니다. 이 포트로 트래픽이 전달됩니다.
selector:
app: webpod #서비스가 트래픽을 전달할 파드를 선택하는 기준입니다. app: webpod 레이블을 가진 파드가 이 서비스의 대상입니다.
type: LoadBalancer #서비스의 유형을 지정
---
apiVersion: v1
kind: Service
metadata:
name: svc2
spec:
ports:
- name: svc2-webport
port: 80
targetPort: 80
selector:
app: webpod
type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
name: svc3
spec:
ports:
- name: svc3-webport
port: 80
targetPort: 80
selector:
app: webpod
type: LoadBalancer
EOF
service/svc1 created
service/svc2 created
service/svc3 created
🧿 현재 클러스터의 서비스와 엔드포인트 정보를 확인합니다.
- service/kubernetes
- Kubernetes API 서버에 접근하기 위한 서비스입니다. 외부 접근은 지원하지 않으며, 클러스터 내부에서만 사용할 수 있습니다.
- service/svc1 / service/svc2 / service/svc3
- 외부에서 접근 가능한 LoadBalancer 유형의 서비스입니다. 172.18.255.200/201/202의 외부 IP를 통해 접근할 수 있습니다.
- endpoints/kubernetes
- Kubernetes API 서버의 엔드포인트입니다.
- Kubernetes API 서버의 엔드포인트입니다.
- endpoints/svc1 / endpoints/svc2 / endpoints/svc3
- 서비스가 연결된 파드의 엔드포인트입니다. 이 IP들로 요청이 전달됩니다.
service/svc3 created
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get service,ep
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.200.1.1 <none> 443/TCP 166m
service/svc1 LoadBalancer 10.200.1.145 172.18.255.200 80:31692/TCP 8s
service/svc2 LoadBalancer 10.200.1.229 172.18.255.201 80:32461/TCP 8s
service/svc3 LoadBalancer 10.200.1.152 172.18.255.202 80:32366/TCP 7s
NAME ENDPOINTS AGE
endpoints/kubernetes 172.18.0.4:6443 166m
endpoints/svc1 10.10.1.2:80,10.10.2.4:80 8s
endpoints/svc2 10.10.1.2:80,10.10.2.4:80 7s
endpoints/svc3 10.10.1.2:80,10.10.2.4:80 7s
🧿 svc1 서비스에 대한 자세한 정보를 확인합니다.
- LoadBalancer 유형으로, 외부에서 접근할 수 있는 IP와 클러스터 IP를 가지고 있으며, 특정 파드로 트래픽을 라우팅합니다.
- Assigned IP ["172.18.255.200"]
- MetalLB가 서비스에 할당한 IP 주소입니다. 이 IP 주소는 외부에서 접근 가능한 LoadBalancer IP로 사용됩니다.
- announcing from node "myk8s-worker" with protocol "layer2"
- myk8s-worker 노드에서 서비스를 Layer 2 프로토콜을 통해 발표하고 있음을 나타냅니다. 이는 MetalLB가 이 노드가 서비스의 IP를 사용할 수 있도록 설정했음을 의미합니다. Layer 2는 MAC 주소를 통해 네트워크 내에서 IP 주소를 알리는 방법입니다.
(⎈|kind-myk8s:N/A) root@kind:~# kubectl describe svc svc1
Name: svc1
Namespace: default
Labels: <none>
Annotations: metallb.io/ip-allocated-from-pool: my-ippool #MetalLB에서 IP 주소가 my-ippool 풀에서 할당되었음을 나타냅니다.
Selector: app=webpod #서비스가 연결될 파드를 선택하는 기준
Type: LoadBalancer #서비스의 유형
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.200.1.145
IPs: 10.200.1.145
LoadBalancer Ingress: 172.18.255.200 (VIP) #외부에서 접근할 수 있는 LoadBalancer의 IP 주소
Port: svc1-webport 80/TCP #서비스가 수신하는 포트
TargetPort: 80/TCP #이 포트로 트래픽이 전달될 파드의 포트
NodePort: svc1-webport 31692/TCP #노드 포트로, 클러스터의 모든 노드에서 접근할 수 있는 포트입니다. (즉, NodeIP:31692로 접근 가능)
Endpoints: 10.10.1.2:80,10.10.2.4:80 #이 서비스와 연결된 파드의 IP와 포트입니다. 서비스는 이 엔드포인트로 트래픽을 라우팅합니다.
Session Affinity: None #클라이언트의 요청이 항상 동일한 파드로 전송되지 않습니다.
External Traffic Policy: Cluster #외부 트래픽이 클러스터 내 모든 노드로 라우팅됨을 나타냅니다.
Internal Traffic Policy: Cluster #클러스터 내부 트래픽이 모든 노드로 라우팅됨을 나타냅니다.
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal IPAllocated 51s metallb-controller Assigned IP ["172.18.255.200"]
Normal nodeAssigned 51s metallb-speaker announcing from node "myk8s-worker" with protocol "layer2"
🧿 각 서비스에서 MetalLB의 IP 할당 및 노드 관련 이벤트를 확인합니다.
(⎈|kind-myk8s:N/A) root@kind:~# kubectl describe svc | grep Events: -A5
Events: <none>
Name: svc1
Namespace: default
Labels: <none>
--
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal IPAllocated 82s metallb-controller Assigned IP ["172.18.255.200"]
Normal nodeAssigned 82s metallb-speaker announcing from node "myk8s-worker" with protocol "layer2"
--
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal IPAllocated 81s metallb-controller Assigned IP ["172.18.255.201"]
Normal nodeAssigned 81s metallb-speaker announcing from node "myk8s-worker" with protocol "layer2"
--
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal IPAllocated 81s metallb-controller Assigned IP ["172.18.255.202"]
Normal nodeAssigned 81s (x2 over 81s) metallb-speaker announcing from node "myk8s-worker3" with protocol "layer2"
🧿 Kubernetes의 svc1 서비스에 대한 상세 정보를 JSON 형식으로 가져와 jq를 사용하여 포맷팅한 결과를 확인합니다.
- 서비스는 LoadBalancer 유형으로 설정되어 있으며, MetalLB를 사용하여 외부 IP를 할당받았습니다. 파드 선택 기준은 app: webpod이며, 외부 트래픽은 클러스터의 모든 노드로 분산됩니다.
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get svc svc1 -o json | jq
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"annotations\":{},\"name\":\"svc1\",\"namespace\":\"default\"},\"spec\":{\"ports\":[{\"name\":\"svc1-webport\",\"port\":80,\"targetPort\":80}],\"selector\":{\"app\":\"webpod\"},\"type\":\"LoadBalancer\"}}\n",
"metallb.io/ip-allocated-from-pool": "my-ippool"
},
"creationTimestamp": "2024-10-02T12:02:28Z",
"name": "svc1",
"namespace": "default",
"resourceVersion": "16502",
"uid": "f2419528-cf25-45ce-97aa-f249a0dd152a"
},
"spec": {
"allocateLoadBalancerNodePorts": true, #LoadBalancer 유형 서비스에 대해 노드 포트를 할당할지 여부입니다.
"clusterIP": "10.200.1.145", #서비스에 할당된 클러스터 내부 IP
"clusterIPs": [ #클러스터에서 사용할 수 있는 IP 주소 목록
"10.200.1.145"
],
"externalTrafficPolicy": "Cluster", #외부 트래픽을 처리하는 정책. 여기서는 Cluster로 설정되어 있어, 트래픽이 클러스터의 모든 노드로 분산됩니다.
"internalTrafficPolicy": "Cluster", #내부 트래픽을 처리하는 정책
"ipFamilies": [
"IPv4"
],
"ipFamilyPolicy": "SingleStack",
"ports": [
{
"name": "svc1-webport",
"nodePort": 31692, #노드에서 사용할 포트
"port": 80, #클라이언트가 접근하는 포트
"protocol": "TCP",
"targetPort": 80 #실제 서비스에 전달될 포트
}
],
"selector": {
"app": "webpod" #이 서비스가 연결할 파드를 선택하는 기준
},
"sessionAffinity": "None", #세션 유지 정책. 여기서는 None으로 설정되어 있어 세션이 유지되지 않습니다.
"type": "LoadBalancer"
},
"status": {
"loadBalancer": {
"ingress": [
{
"ip": "172.18.255.200", #외부에서 접근할 수 있는 IP 주소 목록
"ipMode": "VIP" #IP 모드. VIP는 Virtual IP를 의미합니다.
}
]
}
}
}
🧿 MetalLB에서 특정 서비스에 대한 Layer 2 상태 정보를 확인합니다.
- ServiceL2Status 리소스는 svc2라는 서비스가 myk8s-worker 노드에 배포되어 있음을 나타냅니다. 이 리소스는 MetalLB의 speaker Pod에 의해 관리되며, 해당 서비스의 상태 정보를 추적합니다.
- ServiceL2Status
- MetalLB에서 제공하는 Kubernetes 리소스의 일종으로, 특정 서비스에 대한 Layer 2(L2) 상태 정보를 기록합니다.
- 이 리소스는 MetalLB가 LoadBalancer 타입의 서비스를 위해 IP를 할당하고, 해당 IP가 실제로 노드에서 어떻게 관리되고 있는지를 보여주는 데 사용됩니다.
(⎈|kind-myk8s:N/A) root@kind:~# kubectl describe servicel2status -n metallb-system
Name: l2-58zlp
Namespace: metallb-system
Labels: metallb.io/node=myk8s-worker #이 상태가 할당된 노드의 이름
metallb.io/service-name=svc2 #관련된 서비스의 이름
metallb.io/service-namespace=default #서비스가 속한 네임스페이스
Annotations: <none>
API Version: metallb.io/v1beta1
Kind: ServiceL2Status
Metadata:
Creation Timestamp: 2024-10-02T12:02:29Z
Generate Name: l2-
Generation: 1
Owner References:
API Version: v1
Kind: Pod
Name: speaker-5l6nl
UID: eeb32840-4453-4ffb-8395-6c3ea4a212db
Resource Version: 16534
UID: 421ebbb4-7bfc-4b6d-8941-f9ecf630a6a7
Spec:
Status:
Node: myk8s-worker #이 서비스가 배포된 노드의 이름
Service Name: svc2 #이 상태가 관련된 서비스의 이름
Service Namespace: default #서비스가 위치한 네임스페이스
Events: <none>
...
🧿 Kubernetes 서비스의 외부 IP를 가져와서 변수에 저장합니다.
- -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
- JSON 형식으로 출력된 결과에서 LoadBalancer의 ingress IP 주소를 추출합니다
- 172.18.255.200 172.18.255.201 172.18.255.202
- 각각의 서비스에 할당된 LoadBalancer 외부 IP 주소입니다. 이 IP를 사용하여 클러스터 외부에서 각 서비스에 접근할 수 있습니다.
(⎈|kind-myk8s:N/A) root@kind:~# SVC1EXIP=$(kubectl get svc svc1 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
SVC2EXIP=$(kubectl get svc svc2 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
SVC3EXIP=$(kubectl get svc svc3 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
(⎈|kind-myk8s:N/A) root@kind:~# echo $SVC1EXIP $SVC2EXIP $SVC3EXIP
172.18.255.200 172.18.255.201 172.18.255.202
🧿 arping을 사용하여 서비스 외부 IP 주소에 대한 ARP 요청을 보내고, 해당 IP가 응답하는지 확인하는 작업을 수행합니다
- Unicast reply from 172.18.255.200: 해당 IP 주소에서 응답을 받았음을 의미합니다.
- Sent 1 probes (1 broadcast(s)): 하나의 ARP 요청을 보냈고, 브로드캐스트 방식으로 요청을 전송했음을 나타냅니다.
- Received 1 response(s): 하나의 응답을 수신했음을 나타냅니다.
(⎈|kind-myk8s:N/A) root@kind:~# for i in $SVC1EXIP $SVC2EXIP $SVC3EXIP; do docker exec -it mypc arping -I eth0 -f -c 1 $i; done
ARPING 172.18.255.200 from 172.18.0.100 eth0
Unicast reply from 172.18.255.200 [02:42:AC:12:00:02] 0.725ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)
ARPING 172.18.255.201 from 172.18.0.100 eth0
Unicast reply from 172.18.255.201 [02:42:AC:12:00:02] 0.777ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)
ARPING 172.18.255.202 from 172.18.0.100 eth0
Unicast reply from 172.18.255.202 [02:42:AC:12:00:05] 0.671ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)
🧿 mypc 에서 ip -c neigh 명령을 실행하여 ARP 테이블을 확인합니다.
- 172.18.0.4: ARP 테이블에 저장된 IP 주소입니다. 이는 네트워크 상에서 연결된 장치의 주소입니다.
- dev eth0: 이 IP 주소가 연결된 네트워크 인터페이스를 나타냅니다. eth0는 Docker 컨테이너의 기본 네트워크 인터페이스입니다.
- lladdr 02:42:ac:12:00:04: 해당 IP 주소에 대한 MAC 주소입니다. 02:42:ac:12:00:04는 IP 주소에 대응되는 물리적 주소입니다.
- lladdr: "Link Layer Address"의 약어로, 해당 IP 주소에 매핑된 MAC 주소를 나타냅니다.
- STALE: 이 상태는 해당 IP 주소의 연결이 오래된 것임을 의미합니다.
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it mypc ip -c neigh
172.18.0.4 dev eth0 lladdr 02:42:ac:12:00:04 STALE
🧿 mypc 에서 각 서비스의 외부 IP 주소(SVC1EXIP, SVC2EXIP, SVC3EXIP)에 대해 ping 명령을 실행합니다.
(⎈|kind-myk8s:N/A) root@kind:~# for i in $SVC1EXIP $SVC2EXIP $SVC3EXIP; do docker exec -it mypc ping -c 1 -w 1 -W 1 $i; done
PING 172.18.255.200 (172.18.255.200) 56(84) bytes of data.
--- 172.18.255.200 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
PING 172.18.255.201 (172.18.255.201) 56(84) bytes of data.
--- 172.18.255.201 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
PING 172.18.255.202 (172.18.255.202) 56(84) bytes of data.
--- 172.18.255.202 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
(⎈|kind-myk8s:N/A) root@kind:~# for i in 172.18.0.2 172.18.0.3 172.18.0.4 172.18.0.5; do docker exec -it mypc ping -c 1 -w 1 -W 1 $i; done
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.112 ms
--- 172.18.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.112/0.112/0.112/0.000 ms
PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.160 ms
--- 172.18.0.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.160/0.160/0.160/0.000 ms
PING 172.18.0.4 (172.18.0.4) 56(84) bytes of data.
64 bytes from 172.18.0.4: icmp_seq=1 ttl=64 time=0.134 ms
--- 172.18.0.4 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.134/0.134/0.134/0.000 ms
PING 172.18.0.5 (172.18.0.5) 56(84) bytes of data.
64 bytes from 172.18.0.5: icmp_seq=1 ttl=64 time=0.073 ms
--- 172.18.0.5 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.073/0.073/0.073/0.000 ms
🧿 mypc 에서 ip -c neigh 명령을 실행하여 ARP 테이블을 확인합니다.
- 172.18.0.2: MAC 주소 02:42:ac:12:00:02에 연결된 IP입니다.
- 172.18.0.3: MAC 주소 02:42:ac:12:00:03에 연결된 IP입니다.
- 172.18.0.4: MAC 주소 02:42:ac:12:00:04에 연결된 IP입니다.
- 172.18.0.5: MAC 주소 02:42:ac:12:00:05에 연결된 IP입니다.
- 172.18.255.200: MAC 주소 02:42:ac:12:00:02에 연결된 LoadBalancer IP입니다.
- 172.18.255.201: MAC 주소 02:42:ac:12:00:02에 연결된 LoadBalancer IP입니다.
- 172.18.255.202: MAC 주소 02:42:ac:12:00:05에 연결된 LoadBalancer IP입니다.
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it mypc ip -c neigh | sort
172.18.0.2 dev eth0 lladdr 02:42:ac:12:00:02 STALE
172.18.0.3 dev eth0 lladdr 02:42:ac:12:00:03 STALE
172.18.0.4 dev eth0 lladdr 02:42:ac:12:00:04 STALE
172.18.0.5 dev eth0 lladdr 02:42:ac:12:00:05 STALE
172.18.255.200 dev eth0 lladdr 02:42:ac:12:00:02 STALE
172.18.255.201 dev eth0 lladdr 02:42:ac:12:00:02 STALE
172.18.255.202 dev eth0 lladdr 02:42:ac:12:00:05 STALE
🧿 Kubernetes 클러스터에서 svc1, svc2, svc3라는 LoadBalancer 서비스의 외부 IP 주소를 변수에 저장합니다.
(⎈|kind-myk8s:N/A) root@kind:~# SVC1EXIP=$(kubectl get svc svc1 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
SVC2EXIP=$(kubectl get svc svc2 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
SVC3EXIP=$(kubectl get svc svc3 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $SVC1EXIP $SVC2EXIP $SVC3EXIP
172.18.255.200 172.18.255.201 172.18.255.202
🧿 LoadBalancer 서비스를 통해 외부 IP로 접근하여 서비스가 Pod에 요청을 전달하는지를 확인합니다.
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it mypc curl -s $SVC1EXIP
Hostname: webpod2
IP: 127.0.0.1
IP: ::1
IP: 10.10.2.4
IP: fe80::e0b6:dbff:fe5c:9b4b
RemoteAddr: 172.18.0.2:3334
GET / HTTP/1.1
Host: 172.18.255.200
User-Agent: curl/8.7.1
Accept: */*
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it mypc curl -s $SVC1EXIP | grep Hostname
Hostname: webpod1
(⎈|kind-myk8s:N/A) root@kind:~# for i in $SVC1EXIP $SVC2EXIP $SVC3EXIP; do docker exec -it mypc curl -s $i | grep Hostname ; done
Hostname: webpod1
Hostname: webpod1
Hostname: webpod1
(⎈|kind-myk8s:N/A) root@kind:~# for i in $SVC1EXIP $SVC2EXIP $SVC3EXIP; do echo ">> Access Service External-IP : $i <<" ; docker exec -it mypc curl -s $i | grep Hostname ; echo ; done
>> Access Service External-IP : 172.18.255.200 <<
Hostname: webpod2
>> Access Service External-IP : 172.18.255.201 <<
Hostname: webpod2
>> Access Service External-IP : 172.18.255.202 <<
Hostname: webpod1
🧿 Kubernetes 클러스터에서 각 LoadBalancer 서비스의 외부 IP에 접근하여 응답을 확인합니다.
- 각 서비스의 외부 IP에 대해 HTTP 요청을 보냈으며, 모두 Hostname이 webpod2로 응답하고 있습니다.
- RemoteAddr은 요청이 도착한 Pod의 IP와 포트를 나타내고, Host는 요청의 목적지 IP를 나타냅니다.
(⎈|kind-myk8s:N/A) root@kind:~# for i in $SVC1EXIP $SVC2EXIP $SVC3EXIP; do echo ">> Access Service External-IP : $i <<" ;docker exec -it mypc curl -s $i | egrep 'Hostname|RemoteAddr|Host:' ; echo ; done
>> Access Service External-IP : 172.18.255.200 <<
Hostname: webpod2
RemoteAddr: 172.18.0.2:8015
Host: 172.18.255.200
>> Access Service External-IP : 172.18.255.201 <<
Hostname: webpod2
RemoteAddr: 172.18.0.2:12601
Host: 172.18.255.201
>> Access Service External-IP : 172.18.255.202 <<
Hostname: webpod2
RemoteAddr: 172.18.0.5:30519
Host: 172.18.255.202
🧿 각각의 서비스에 대해 100번의 요청을 보내고, 응답에서 Hostname의 빈도를 계산하여 정렬합니다
- 각 서비스의 로드 밸런싱 전략이 어떻게 작동하는지, 그리고 트래픽이 어떻게 분배되는지를 확인할 수 있습니다.
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it mypc zsh -c "for i in {1..100}; do curl -s $SVC1EXIP | grep Hostname; done | sort | uniq -c | sort -nr"
52 Hostname: webpod2
48 Hostname: webpod1
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it mypc zsh -c "for i in {1..100}; do curl -s $SVC2EXIP | grep Hostname; done | sort | uniq -c | sort -nr"
55 Hostname: webpod2
45 Hostname: webpod1
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it mypc zsh -c "for i in {1..100}; do curl -s $SVC3EXIP | grep Hostname; done | sort | uniq -c | sort -nr"
53 Hostname: webpod2
47 Hostname: webpod1
🧿 svc1 서비스에 대한 정보를 확인합니다.
- TYPE: LoadBalancer
- 이 서비스는 LoadBalancer 타입으로 설정되어 있으며, 외부 트래픽을 수신할 수 있습니다.
- 이 서비스는 LoadBalancer 타입으로 설정되어 있으며, 외부 트래픽을 수신할 수 있습니다.
- CLUSTER-IP: 10.200.1.145
- 클러스터 내부에서 이 서비스에 접근하기 위한 IP 주소입니다.
- 클러스터 내부에서 이 서비스에 접근하기 위한 IP 주소입니다.
- EXTERNAL-IP: 172.18.255.200
- 외부에서 이 서비스에 접근하기 위한 IP 주소입니다. MetalLB에 의해 할당된 IP입니다.
- 외부에서 이 서비스에 접근하기 위한 IP 주소입니다. MetalLB에 의해 할당된 IP입니다.
- PORT(S): 80:31692/TCP
- 80: 클라이언트가 접속할 포트
- 31692: 클러스터 내부에서 노드 포트로 매핑되는 포트
- 80: 클라이언트가 접속할 포트
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get svc svc1
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc1 LoadBalancer 10.200.1.145 172.18.255.200 80:31692/TCP 10m
🧿 NodePort 와 ClusterIP 로 접속을 확인합니다.
- svc1의 노드 포트(31692)로 들어가고, 해당 포트에서 실행 중인 웹 애플리케이션이 webpod1에서 처리한 결과
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it myk8s-control-plane curl -s 127.0.0.0:31692
Hostname: webpod1
IP: 127.0.0.1
IP: ::1
IP: 10.10.1.2
IP: fe80::e0e6:2ff:fe0a:db7a
RemoteAddr: 172.18.0.4:30468
GET / HTTP/1.1
Host: 127.0.0.0:31692
User-Agent: curl/7.88.1
Accept: */*
- 클러스터 IP(10.200.1.145)로 들어갔고, 해당 IP에서 실행 중인 웹 애플리케이션이 webpod1에서 처리한 결과
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it myk8s-control-plane curl -s 10.200.1.145
Hostname: webpod1
IP: 127.0.0.1
IP: ::1
IP: 10.10.1.2
IP: fe80::e0e6:2ff:fe0a:db7a
RemoteAddr: 172.18.0.4:4833
GET / HTTP/1.1
Host: 10.200.1.145
User-Agent: curl/7.88.1
Accept: */*
'쿠버네티스 네트워크 스터디 3기' 카테고리의 다른 글
[6주차] Ingress (0) | 2024.10.07 |
---|---|
[5주차] IPVS (0) | 2024.10.03 |
[5주차] 실습기본환경구성 (3) | 2024.10.02 |
[4주차] NodePort (0) | 2024.09.24 |
[4주차] ClusterIP (0) | 2024.09.23 |
Comments