2023. 6. 12. 23:15ㆍ쿠버네티스 (Kubernetes)
Service Discovery
쿠버네티스는 우리가 원하는 서비스를 위해 다양한 형태로 Pod을 생성하고 실행하며, 때로는 재스케줄링도 해줍니다.
여기서 어떤 것이 어떤 서비스를 하고 있는 지 알아내는 게 중요한 데, 이를 서비스 디스커버리(service discovery)라고 합니다.
다른 장소에서 서비스 디스커버리의 전통적인 예시로는 도메인 이름 시스템, 즉 Domain Name System(DNS)이 있습니다.
간단하게는 서버의 IP 주소 및 포트를 우리가 이해하기 쉬운 주소로 바꿔주는 데 가령 https://www.google.com/ 는 원래
nslookup
> google.com
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: google.com
Address: 172.217.24.110
Name: google.com
Address: 2404:6800:4005:80d::200e
이지만 우리가 웹에서 google을 방문할 때 DNS가 해당 이름으로 찾아서 적절한 IP주소로 변환해줍니다.
이를 쿠버네티스의 세계로 접목시키면 되는데, 컨테이너 또는 Pod에 대해서 서비스 디스커버리를 한다고 이해하면 됩니다.
Service Object
서비스 오브젝트(service object)는 검색 가능한 이름을 생성해줍니다.
이러한 서비스를 만드려면 expose 명령어를 사용하면 됩니다.
먼저 Pod을 만들어봅니다.
kubectl run alpaca-prod \
--image=gcr.io/kuar-demo/kuard-amd64:blue \
--port=8080 \
--labels="ver=1,app=alpaca,env=prod"
kubectl run bandicoot-prod \
--image=gcr.io/kuar-demo/kuard-amd64:green \
--port=8080 \
--labels="ver=2,app=bandicoot,env=prod"
kubectl get pods
NAME READY STATUS RESTARTS AGE
alpaca-prod 1/1 Running 0 20s
bandicoot-prod 1/1 Running 0 10s
두 Pod이 제대로 실행되고 있는 걸 확인했으면, 아래 expose 명령어를 실행합니다.
kubectl expose pod alpaca-prod
kubectl expose pod bandicoot-prod
그리고 서비스를 검색해보면
kubectl get services -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
alpaca-prod ClusterIP 10.96.192.222 <none> 8080/TCP 43s app=alpaca,env=prod,ver=1
bandicoot-prod ClusterIP 10.96.91.177 <none> 8080/TCP 31s app=bandicoot,env=prod,ver=2
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h47m <none>
처럼 두 서비스의 IP와 포트 정보를 확인할 수 있습니다.
여기서 SELECTOR 컬럼을 보면 우리가 일전에 주었던 레이블(label)이 적용되었는데, 이를 이용하여 Pod을 검색할 수 있습니다.
kubectl get pods -l app=alpaca
NAME READY STATUS RESTARTS AGE
alpaca-prod 1/1 Running 0 7m1s
검색 결과에 따라 port-forward 명령어를 구성해보면
ALPACA_POD=$(kubectl get pods -l app=alpaca -o jsonpath='{.items[0].metadata.name}')
kubectl port-forward $ALPACA_POD 48858:8080
http://localhost:48858/ 로 접속할 수 있습니다.
Service DNS
클러스터의 IP 주소는 임의로 주든 랜덤으로 주든 그 자체로 파악하기는 어렵지만,
반대로 우리가 쉽게 이해하는 네임스페이스 또는 이름으로 검색하면 쉽습니다.
일전 사이트에 접속하고 DNS Query 탭을 방문해서 Name에 alpaca-prod를 작성 후 QUERY 버튼을 눌러봅니다.
;; opcode: QUERY, status: NOERROR, id: 11117
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;alpaca-prod.default.svc.cluster.local. IN A
;; ANSWER SECTION:
alpaca-prod.default.svc.cluster.local. 30 IN A 10.96.117.196
쿠버네티스 DNS 서비스는 방금 우리가 검색했듯 서비스 이름으로 IP 정보를 제공합니다.
alpaca-prod.default.svc.cluster.local. 에 대해서 조금 더 자세히 알아보면
- alpaca-prod : 서비스 이름입니다.
- default : 서비스가 위치한 네임스페이스입니다.
- svc : 서비스 타입임을 명시합니다.
- cluster.local. : 클러스터의 기본 도메인 이름입니다.
Advance Details
서비스 오브젝트는 IP 주소를 포함하는 엔드포인트 오브젝트(endpoint object)를 가지고 있습니다.
엔드포인트 오브젝트를 확인하려면 describe 명령어를 사용하면 됩니다.
kubectl describe endpoints alpaca-prod
Name: alpaca-prod
Namespace: default
Labels: app=alpaca
env=prod
ver=1
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2023-06-12T13:03:37Z
Subsets:
Addresses: 10.244.0.5
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
<unset> 8080 TCP
Events: <none>
서비스를 이용하기 위해서, API를 통해 엔드포인트를 직접 조회하여 접근할 수 있습니다.
쿠버네티스 API는 서비스의 IP 정보가 변경되면 즉각 반영해주기 때문에 클라이언트는 변화에 잘 대처할 수 있습니다.
두 개의 터미널을 준비하고 한 개 터미널에는 다음과 같이 --watch 옵션을 넣어 엔드포인트를 확인합니다.
kubectl get endpoints alpaca-prod --watch
NAME ENDPOINTS AGE
alpaca-prod 10.244.0.5:8080 25m
그리고 다른 하나는 해당 pod을 제거하고 다시 생성해줍니다.
kubectl delete pod alpaca-prod
kubectl run alpaca-prod \
--image=gcr.io/kuar-demo/kuard-amd64:blue \
--port=8080 \
--labels="ver=1,app=alpaca,env=prod"
NAME ENDPOINTS AGE
alpaca-prod 10.244.0.5:8080 25m
alpaca-prod <none> 28m
alpaca-prod 10.244.0.7:8080 28m
결과를 보면 엔드포인트의 변화를 확인할 수 있습니다.
Manual Service Discovery
아래처럼 --show-labels 옵션을 붙여 팟 정보를 확인해봅니다.
kubectl get pods -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP ... LABELS
alpaca-prod 1/1 Running 0 3m6s 10.244.0.7 ... app=alpaca,env=prod,ver=1
bandicoot-prod 1/1 Running 0 31m 10.244.0.6 ... app=bandicoot,env=prod,ver=2
LABELS는 우리가 일전에 pod을 만들 때 작성했던 labels와 동일합니다.
이를 라벨 셀렉터(label selector) 또는 그냥 셀렉터라고 합니다.
존재 이유는 오롯히 검색인데, 예를 들어 app이 alpaca고 env가 prod인 것을 찾고 싶으면 아래처럼 만들면 됩니다.
kubectl get pods -o wide --selector=app=alpaca,env=prod
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
alpaca-prod 1/1 Running 0 7m7s 10.244.0.7 kind-control-plane <none> <none>
--selector 옵션을 활용해 셀렉터를 이용하면 아무리 팟을 많이 만들어도 검색을 쉽게 빠르게 할 수 있도록 해줍니다.
kube-proxy and Cluster IPs
쿠버네티스에서 트래픽과 관련된 중요한 개념 중 하나는 kube-proxy입니다.
여기서 Cluster IP는 각 백엔드 서버의 IP 주소를 가지고 있어 클라이언트의 트래픽을 분산시켜줄 수 있도록 합니다.
이를 다른 말로는 iptables 규칙을 만든다고 합니다.
kube-proxy 서비스는 이러한 Cluster IP를 만들어줍니다.
예를 들어 새로운 백엔드 서비스를 만들었다고 했을 때, kube-proxy는 이를 감지하여 Cluster IP를 업데이트 해주는 것입니다.
주의할 점은 서비스를 생성하거나 삭제했을 때만 동작하기 때문에 기존에 있는 IP를 수정하지는 못합니다.
Cleanup
이번 장을 통해 만들었던 팟과 서비스들은 레이블을 통해 제거할 수 있습니다.
kubectl delete services,pods -l app
이는 app 레이블 이름이 있는 팟과 서비스를 제거해달라는 의미입니다.
일전에 가볍게 넘어갔지만, 사실 레이블은 팟과 서비스의 구조를 설계하는 가장 효과적인 방법입니다.
그러므로 항상 무언가를 배포할 때는 레이블(label)을 잘 만드는 습관을 가지도록 합니다.
'쿠버네티스 (Kubernetes)' 카테고리의 다른 글
[Kubernetes] 7. 배포 (0) | 2023.06.19 |
---|---|
[Kubernetes] 6. 레플리카 (0) | 2023.06.13 |
[Kubernetes] 4. POD (0) | 2023.06.03 |
[Kubernetes] 3. 팁 (0) | 2023.06.01 |
[Kubernetes] 2. 클러스터 배포하기 (0) | 2023.06.01 |