[k8s] 5. 서비스 - 파드를 연결하고 외부에 노출
SightStudio
·2020. 10. 11. 10:52
지난 시간엔 디플로이먼트를 통해 레플리카 셋, 파드를 편리하게 관리하는 법을 배웠습니다.
이번 시간에는 파드를 외부에 노출하는 서비스에 대해 알아봅니다.
1. 이전까지
이전 글에서는 다른 파드에 접근하기 위해 임시로 테스트 파드를 만든 뒤
테스트 파드에서 해당 파드로 접근을 했었습니다. 즉, 클러스터 내부에서만 사용할 수 있었습니다.
또한 더 큰 문제는 파드의 IP는 계속 변한다는 부분입이다. 여러개의 디플로이먼트를 연동하려면
파드의 IP가 아닌 다른 걸로 서로를 발견할 수 있는 방법이 필요합니다. (Discovery)
여담이지만, 이 내용을 보니 Spring Cloud의 디스커버리 서비스인 Eureka가 떠오르네요.
2. 서비스 란
서비스의 주요기능은 다음과 같습니다.
1. 여러 개의 파드에 고유한 도메인 이름 부여
2. 여러 개의 파드 접근 시 , 요청을 로드벨런싱
3. 클라우드 플랫폼의 로드 벨런서, 클러스터 노드의 파드 등을 통해 파드 외부에 노출
Docker에서는 -p 옵션을 통해 포트를 외부로 노출시키거나
docker run --link, 오버레이 네트워크 등으로 컨테이너들이 서로 접근 할 수 있었습니다.
3. 서비스의 종류
kubernetes.io/docs/concepts/services-networking/
서비스의 종류는 여러가지가 있지만 주로 3개의 서비스 타입을 자주 사용하게됩니다.
1. ClusterIP : k8s 내부에서만 파드들을 접근 할 때 사용합니다. | private
2. NodePort : 파드에 접근할 수 있는 포트를 클러스터의 모든 노드에 동일하게 개방합니다. | public
3. LoadBalancer : AWS, GCP와 같은 클라우드 플랫폼 환경에서만 사용할 수 있습니다.
클라우드 플랫폼에서 제공하는 LB들을 동적으로 프로비저닝해서 파드에 연결합니다.
실습)
먼저 디플로이먼트를 생성합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: hostname-deployment
spec:
replicas: 3
selector:
matchLabels:
app: webserver
template:
metadata:
name: my-webserver
labels:
app: webserver
spec:
containers:
- name: my-webserver
image: alicek106/rr-test:echo-hostname
ports:
- containerPort: 80
kubectl apply -f deployment-hostname.yaml
실습 1. ClusterIP
hostname-svc-clusterip.yaml을 만들고 다음과 같이 서비스를 생성합니다.
apiVersion: v1
kind: Service
metadata:
name: hostname-svc-clusterip
spec:
ports:
- name: web-port
port: 8080
targetPort: 80
selector:
app: webserver
type: ClusterIP
kubectl apply -f hostname-svc-clusterip.yaml
이번에도 테스트 파드를 만들어서 접근해보겠습니다.
kubectl run -i --tty --rm debug --image=alicek106/ubuntu:curl --restart=Never bash
# 접속 후
curl hostname-svc-clusterip:8080
이번에는 IP가 아니라 컨테이너 이름 자체로 접근할 수 있습니다. 이는 k8s가 내부 DNS 를 구동하고 있어 파드들이
자동으로 DNS를 사용하도록 설정되기 때문입니다. 이 덕분에 파드의 IP를 몰라도 서비스 명을 통해 통신할 수 있습니다.
실습 2. NodePort
NodePort 타입의 서비스를 통해 외부에서 클러스터로 접근할 수 있습니다.
단, 이름과 같이 모든 노드의 특정 포트를 개방해서 서비스에 접근하는 방식입니다.
위의 hostname-svc-clusterip.yaml 파일에서 타입만 바꾼
hostname-svc-nodeport.yaml를 생성합니다.
apiVersion: v1
kind: Service
metadata:
name: hostname-svc-clusterip
spec:
ports:
- name: web-port
port: 8080
targetPort: 80
selector:
app: webserver
type: NodePort
kubectl apply -f hostname-svc-nodeport.yaml
서비스 목록을 확인하면 NodePort 타입은 30068 포트가 붙어있는것을 알 수 있습니다.
클러스터의 모든 노드에 내부 IP또는 외부 IP를 통해 30068포트에 접근하면 해당 서비스에 접근 할 수 있습니다.
포트는 환경마다 다를 수 있습니다.
이번엔 테스트 컨테이너가 아닌 호스트 환경에서 curl로 요청을 보내보았습니다.
이전과는 다르게 잘 연결되는걸 확인 할 수 있습니다.
NodePort타입은 ClusterIP의 기능을 포함하고 있기 때문에
ClusterIP처럼 파드 내에서 내부 IP와 DNS를 사용해서 접근할 수 있습니다.
하지만 실제 운영환경에서는 NodePort로 서동동비스를 외부에 제공하는 경우는 많지 않고,
인그래스(Ingress)라고 부르는 k8s 오브젝트에 간접적으로 사용되는 경우가 많습니다.
kubernetes.io/docs/concepts/workloads/controllers/deployment/
www.yes24.com/Product/Goods/84927385
'개발 > devops' 카테고리의 다른 글
로드밸런서에 대해 알아보자 (3) | 2021.10.13 |
---|---|
프로메테우스에 대해 알아보자 (0) | 2021.08.07 |
[k8s] 4. 디플로이먼트 - 레플리카셋, 파드 배포 관리 (0) | 2020.10.11 |
[k8s] 2. 파드 - 컨테이너의 기본 단위 (0) | 2020.10.10 |