본문 바로가기

⭐ Kubernetes & EKS/EKS

컨테이너를 외부로 공개하기 위한 리소스

728x90
반응형

# 컨테이너를 외부로 공개하는 방법

- 파드를 서비스로 묶기
쿠버네티스에서는 서비스 리소스를 이용하여 파드 여러개를 묶어 하나의 DNS 이름으로 접속 할 수 있다. 
또한 서비스를 이용하면 대상 리소스에서 정상적으로 동작하는 파드에만 요청을 할당할 수있다.

1. 서비스 리소스 타입

ClusterIP : 서비스에 대해 내부에서 유요한 IP 주소를 부여, 클러스터 외부에서 는 접속 불가
NodePort : 각 노드에서 해당 서비스를 접속하기 위해 포트를 열고 외부에서 접속 가능하도록 한다
LoadBalancer : Nodeport에서 열린 각각의 서비스 공개용  포트를 묶는 형태로 클러스터 외부에 로드밸런서를 구축한다. (EKS의 경우 기본으로 CLB가 생성되고 설정에 따라 NLB로 변경 가능하다. ALB는 사용할 수 없다.)
ExternalName : 클러스터 외부의 엔드포인트를 클러스터 내부에 공개하기 위한 서비스 리소스 타입, 로드밸런서 이름이 ExternalName 으로 할당된다.
* EKS LoadBalancer 타입의 서비스를 생성하면 클러스터 외부에 로드밸런서가 생성이 되는데 이는 클라우드 서비스 제공자의 특성에 따른 동작이다. EKS의 경우 CLB(Classic LoadBalancer) 또는 NLB(NetworkLoadBalancer) 가 생성이 된다.

2. 서비스 리소스의 생성

- 해당 YAML 파일을 이용하여 서비스를 새성해보자. (service_backend-app_k8s.yaml)

apiVersion: v1 # 정의한 리소스가 따르는 버전
kind: Service # 매니페스트가 서비스 리소스를 정의
metadata:
  name: backend-app-service # 서비스 리소스의 이름, 이 이름이 DNS 이름으로 등록되어 클러스터 내부에서 참조할 수 있게 된다.
spec:
  type: LoadBalancer # 서비스 종류이다. 로드밸런서로 정의하면 서비스로 동작하는 로드밸런서가 생성되고 로드밸런서를 통해 접속이 가능해 진다.
  selector:
    app: backend-app #이 서비스가 대상으로 하는 파드를 선택하기 위한 셀렉터 정의(여기서는 app에서 backend-app이라는 파드를 정의한다.)
  ports:
  - protocol: TCP # 이 서비스에 접속하기 위한 프로토콜 정의
    port: 8080 # 이 서비스에 접속하기 위한 포트번호 정의
    targetPort: 8080 # pod쪽 포트번호, TCP 프로토콜을 사용하고 서비스에 8080포트를 할당하고 pod에 8080번 포트에 매핑한다는 의미이다.

- 생성한 YAML 파일을 실행하자.

kubectl apply -f service_backend-app_k8s.yaml

- 생성한 서비스를 확인하자.

seungkim:~/environment $ kubectl get svc
NAME                  TYPE           CLUSTER-IP      EXTERNAL-IP                                                                   PORT(S)          AGE
backend-app-service   LoadBalancer   10.100.147.70   a66c9becdd3d04dd7bcb7aadda0936a5-739702734.ap-northeast-2.elb.amazonaws.com   8080:32638/TCP   11m

3. 생성된 리소르를 확인한다. (로드밸런서, 상태검사)
- 서비스를 생성하면 아래와 같이 로드밸런서가 생성이되고 인스터스와 가용영역이 설정되어 자동으로 설정해 준다.
- 로드밸런서의 이름은 ExternalName의 값으로 설정된다.

- 상태검사 탭에서 정보를 확인하자.
- 여기서 생성된 서비스 타입은 LoadBalancer 이지만 NodePort 타입이 할당되는 이유는 로드밸런서가 노드 포트를 각 인스턴스(노드)의 접속 경로로 설정하기 때문이다.

- 서비스의  NodePort 항목을 살펴보자.
- 노드포트 설정값을 보면 32638로 설정되어 있는것을 확인 할 수 있다.

seungkim:~/environment $ kubectl describe service backend-app-service
Name:                     backend-app-service
Namespace:                kube-example-zzanggu
Labels:                   <none>
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"backend-app-service","namespace":"kube-example-zzanggu"},"spec":{...
Selector:                 app=backend-app
Type:                     LoadBalancer
IP:                       10.100.147.70
LoadBalancer Ingress:     a66c9becdd3d04dd7bcb7aadda0936a5-739702734.ap-northeast-2.elb.amazonaws.com
Port:                     <unset>  8080/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  32638/TCP # 노드포트로 32638이 할당된것을 볼 수 있다.
Endpoints:                <none>
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason                Age   From                Message
  ----    ------                ----  ----                -------
  Normal  EnsuringLoadBalancer  23m   service-controller  Ensuring load balancer
  Normal  EnsuredLoadBalancer   23m   service-controller  Ensured load balancer

4. 컨테이너를 외부로 공개하는 또 하나의 방법

- EKS를 LoadBalancer 타입으로 공개를 할 경우 2가지의 문제점이 발생한다.
첫째, 서비스 단위로 ELB가 생성되기 때문에 효율성이 떨어진다. (다수의 ELB를 생성할 경우 그만큼의 비용이 증가한다.)
둘째, HTTP/HTTPS 로드밸런서로 더많은 기능이 있는 ALB를 사용할 수 없다.

- 문제점의 대안
> 로드밸런서 타입 서비스를 사용하는 방법 외에 인그레스를 사용하는 방법이 있다.
인그레스는 쿠버네티스 클러스터로 접근하는 입구를 만들기 위한 리소스라고 볼 수 있다.
인그레스 컨트롤러를 같이 사용하면 보다 효율적인 서비스 제공이 가능하다. EKS에서는 인그레스 컨트롤러로 AWS ALB 인그레스 컨트롤러가 제공된다. 추후에 AWS ALB 인그레스 컨트롤러에 대해서 알아보자.

- 끝 -

728x90
반응형