개요
파드 내부의 컨테이너 통신과 파드 외부의 컨테이너 간 통신.
쿠버네티스 클러스터 내부에 구축된 파드 네트워크
파드에 트래픽 로드 밸런싱
- 서비스는 수신한 트래픽을 여러 파드에 로드 밸런싱하는 기능을 제공.
- 파드는 기동될 때마다 각각 다른 IP 주소를 할당받기 때문에 로드 밸런싱하는 구조를 자체적으로 구현하려면 각 파드의 IP 주소를 매번 조회하거나 전송 대상의 목적지를 설정해야 함.
- 서비스를 사용하면 여러 파드에 대한 로드 밸런싱을 자동으로 구성할 수 있음.
- 서비스는 로드 밸런싱의 접속 창구가 되는 앤드포인트도 제공.(외부 로드 밸런서가 할당하는 가상 IP 주소나 클러스터 내부에서만 사용할 수 있는 가상 IP 주소 등 여러 가지 종류를 제공.)
sample-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.16
출력 시 특정 JSON Path 값만을 출력
[root@k8s-master service]# k get pods
NAME READY STATUS RESTARTS AGE
sample-deployment-7c67dd9675-jggr7 1/1 Running 0 99s
sample-deployment-7c67dd9675-mqc7v 1/1 Running 0 99s
sample-deployment-7c67dd9675-x5vnc 1/1 Running 0 99s
[root@k8s-master service]# kubectl get pods sample-deployment-7c67dd9675-jggr7 -o jsonpath='{.metadata.labels}'
map[app:sample-app pod-template-hash:7c67dd9675]
엔드포인트의 서비스 종류에 ClusterIP를 사용하는 서비스 생성.
※ ClusterIP: 클러스터 내부에서만 사용 가능한 가상 IP를 가진 엔드포인트를 제공하는 로드 밸런서를 구성.
※ 서비스는 spec.slector에 정의할 셀렉터 조건에 따라 트래픽을 전송.
sample-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: sample-clusterip
spec:
type: ClusterIP
ports:
- name: "http-port"
protocol: "TCP"
port: 8080
targetPort: 80
selector:
app: sample-app
서비스 생성 후, 생성된 로드 밸런서의 트래픽이 전송되는 파드를 확인.
# 지정한 레이블을 가진 파드 정보 중 특정 JSON Patch를 컬럼으로 출력
[root@k8s-master service]# k get pods -l app=sample-app -o custom-columns="NAME:{metadata.name},IP:{status.podIP}"
NAME IP
sample-deployment-7c67dd9675-jggr7 172.30.194.67
sample-deployment-7c67dd9675-mqc7v 172.30.194.68
sample-deployment-7c67dd9675-x5vnc 172.30.194.66
생성된 서비스 상세 정보를 출력하면 Endpoints 항목에서 트래픽의 목적지 IP 주소와 포트를 확인할 수 있음.
# 서비스 생성
[root@k8s-master service]# k apply -f sample-clusterip.yaml
service/sample-clusterip created
# 서비스 정보 확인
[root@k8s-master service]# k get services sample-clusterip
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
sample-clusterip ClusterIP 10.97.91.208 <none> 8080/TCP 13s
# 서비스 상세 정보 확인
[root@k8s-master service]# k describe service sample-clusterip
Name: sample-clusterip
Namespace: default
Labels: <none>
Annotations: Selector: app=sample-app
Type: ClusterIP
IP: 10.97.91.208
Port: http-port 8080/TCP
TargetPort: 80/TCP
Endpoints: 172.30.194.66:80,172.30.194.67:80,172.30.194.68:80
Session Affinity: None
Events: <none>
생성한 로드 밸런서가 각 파드에 트래픽을 로드 밸런싱하여 전송하고 있는지 확인.
※ 엔드포인트 서비스 종류에 ClusterIP를 지정했기 때문에 엔드포인트 가상IP는 클러스터 내부에서만 접속 가능한 IP 주소.
클러스터 내 별도 컨테이너를 기동하고 그 컨테이너에서 엔드포인트로 HTTP 요청을 보내 동작을 확인.
HTTP 요청은 로드 밸런싱되어 어느 하나의 파드에서 요청을 처리하고 처리한 파드의 호스트명을 포함한 HTTP 응답이 반환.
※ HTTP 응답을 보면 어떤 파드에서 요청을 처리했는지 확인할 수 있음.
# 일시적으로 파들를 시작하여 서비스 엔드포인트로 요청
# (여러번 실행하면 비슷한 빈도로 세 개의 파드명이 표시됨.)
[root@k8s-master service]# k run --image=amsy810/tools:v2.0 --restart=Never --rm -i testpod --command -- curl -s http://10.97.91.208:8080
Host=10.97.91.208 Path=/ From=sample-deployment-7c67dd9675-x5vnc ClientIP=172.30.194.69 XFF=
pod "testpod" deleted
[root@k8s-master service]# k run --image=amsy810/tools:v2.0 --restart=Never --rm -i testpod --command -- curl -s http://10.97.91.208:8080
Host=10.97.91.208 Path=/ From=sample-deployment-7c67dd9675-jggr7 ClientIP=172.30.194.71 XFF=
pod "testpod" deleted
[root@k8s-master service]# k run --image=amsy810/tools:v2.0 --restart=Never --rm -i testpod --command -- curl -s http://10.97.91.208:8080
Host=10.97.91.208 Path=/ From=sample-deployment-7c67dd9675-mqc7v ClientIP=172.30.194.77 XFF=
pod "testpod" deleted
여러 포트 할당
하나의 서비스에 여러 포트를 할당할 수도 있음.
※ http와 https에서 ClusterIP가 다르면 불편한 경우가 많으므로, 하나의 서비스에서 여러 포트를 가질 수 있도록 설정하는 것이 바람직핢.
sample-clusterip-multi.yaml
apiVersion: v1
kind: Service
metadata:
name: sample-clusterip-multi
spec:
type: ClusterIP
ports:
- name: "http-port"
protocol: "TCP"
port: 8080
targetPort: 80
- name: "https-port"
protocol: "TCP"
port: 8443
targetPort: 443
selector:
app: sample-app
이름을 사용한 포트 참조
서비스에 targetPort를 직접 지정할 수 있지만, 파드의 포트 정의에 이름을 지정해 놓으면 이름을 사용하여 참조할 수 있음.
이름이 붙여진 포트를 가진 두 개의 파드 예제
sample-named-port-pods.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: sample-named-port-pod-80
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: amsy810/echo-nginx:v2.0
ports:
- name: http # assign name to port
containerPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: sample-named-port-pod-81
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: amsy810/echo-nginx:v2.0
env:
- name: NGINX_PORT
value: "81"
ports:
- name: http # assign name to port
containerPort: 81
이름이 붙여진 포트를 참조하는 서비스 예제
sample-named-port-service.yaml
apiVersion: v1
kind: Service
metadata:
name: sample-named-port-service
spec:
type: ClusterIP
ports:
- name: "http-port"
protocol: "TCP"
port: 8080
targetPort: http # refer to the port as a specific name
selector:
app: sample-app
80번, 81번 포트가 모두 http라는 이름으로 참조되기 때문에 서비스 목적지가 되는 엔드포인트는 각각의 포트를 등록한다.
# 서비스 목적지 엔드포인트 확인
[root@k8s-master service]# k describe service sample-named-port-service
Name: sample-named-port-service
Namespace: default
Labels: <none>
Annotations: Selector: app=sample-app
Type: ClusterIP
IP: 10.98.79.151
Port: http-port 8080/TCP
TargetPort: http/TCP
Endpoints: 172.30.194.79:81,172.30.194.78:80
Session Affinity: None
Events: <none>
# 파드 IP 주소 확인
[root@k8s-master service]# k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
sample-named-port-pod-80 1/1 Running 0 4m36s 172.30.194.78 k8s-worker1 <none> <none>
sample-named-port-pod-81 1/1 Running 0 115s 172.30.194.79 k8s-worker1 <none> <none>
'클라우드,가상화 > K8S' 카테고리의 다른 글
k8s - DemonSet (1) | 2023.10.23 |
---|---|
k8s - ClusterIP (0) | 2023.07.17 |
k8s - Deployment (0) | 2023.07.02 |
k8s - ReplicaSet (0) | 2023.07.02 |
k8s - Pod (0) | 2023.07.02 |