Kubernetes/06. 쿠버네티스 네트워크

[쿠버네티스] 클러스터 외부 서비스 / loadBalancer

Jaden Park 2021. 6. 20. 21:47

들어가며

외부 서비스용 레플리카셋 생성 및 확인

NodePort 서비스 생성 및 확인

LoadBalancer 서비스 생성 및 확인

ExternalName 서비스 생성 및 확인


들어가며:

쿠버네티스 클러스터에서 웹의 프론트엔드 서비스를 실행하는 파드의 경우 쿠버네티스 클러스터의 외부로 노출시켜 접근 가능하도록 구성해야 합니다.

ClusterIP는 클러스터 내부에서 DB와 같이 외부로의 노출이 없어야하는 경우에 사용하기 위함이였습니다.

쿠버네티스 클러스터 외부에서 접근 가능한 서비스 리소스 출력의 필드를 살펴보겠습니다.

 

NodePort

NodePort + ClusterIP

쿠버네티스 모든 노드(호스트)에 외부 접근용 포트를 할당

노드의 포트를 사용하여 외부에서 접근 가능

노드의 포트로 접근하면 서비스에 의해 파드로 리다이렉션

파드를 실행하지 있지 않는 노드에도 포트가 할당되고, 접근 가능

 

LoadBalancer

LoadBalancer + NodePort + ClusterIP

NodePort의 확장

클러스터 외부의 로드 밸런서를 사용하여 외부에서 접근 가능

외부 로드 밸런서로 접근하면 서비스를 통해 파드로 리다이렉션

클라우드 공급업체(AWS, GCP 등)나 MetalLB에서 지원

 

ExternalName

외부에서 접근하기 위한 종류가 아님

외부의 특정 FQDN에 대한 CNAME 매핑을 제공

파드가 CNAME을 이용해 특정 FQDN과 통신하기 위함


 

외부 서비스용 레플리카셋 생성 및 확인

기존에 작성했던 myapp-rs 파일을 이용하여 컨트롤러 및 파드를 생성 및 확인을 합니다


 

NodePort 서비스 생성 및 확인

//myapp-svc-np.yaml

---
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc-np
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 31111
  selector:
    app: myapp-rs

.spec.type: 서비스 타입 (default값: ClusterIP)

.spec.ports.nodePort: 포트를 지정하지 않으면 랜덤한 포트 지정(범위 30000-32767 포트)

노드의 31111 포트로 접근하면 서비스의 80포트로 리다이렉션 됩니다.

서비스의 80포트는 파드의 8080 포트로 리다이렉션 됩니다.

생성 후 service,endpoint,pod를 확인해보겠습니다.

노드의 ip를 확인하고 노드의 포트에 접근해보겠습니다.

외부에서 192.168.100.X:31111 로 접근하면, 서비스 포트인 80번 포트로 리다이렉션되며, 이는 다시 내부 파드의 8080번 포트로 리다이렉션 됩니다.


 

LoadBalancer 서비스 생성 및 확인

클라우드 인프라에서 LoadBalancer 서비스를 생성하면 클라우드 인프라의 로드 밸런서를 자동으로 프로비저닝 하게 되며, 이 로드 밸런서를 통해 서비스와 파드에 접근할 수 있습니다.

클라우드의 관리형 쿠버네티스 서비스 및 MetalLB를 사용하지 않는 경우, 외부 로드 밸런서가 프로비저닝 되지 않기 때문에 외부 IP(로드밸랜서IP)가 할당되지 않고 상태로 보고됩니다.

 

MetalLB 설치하기

설치에 대한 자세한 사항은 위의 링크를 참고하시기 바랍니다.

 

1. Manifest 로 MetalLB 설치하기.

$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml

 

 

L2 모드

  • 개념 증명 작업 또는 매우 작은 배포를 위한 layer 2.
  • 모든 트래픽이 확장되지 않는 단일 노드로 이동

 

 

BGP 모드

  • ECMP (Equal-Cost Multi-Path)를 사용하여 트래픽을 여러 노드에 분산할 수 있음.
  • 다만 ECMP를 지원하는 BGP 기능 라우터가 있어야함.

 

 

지금은 라우터가 없고 가상환경이기 때문에 L2 모드로 실습하겠습니다.

layer 2 구성을 하기 위한 디렉토리를 생성해줍니다.

mkdir -p addon/metallb && cp addon/metallb

 

해당 디렉토리에 아래와 같이 파일을 작성합니다.

addresses 는 자신의 ip 대역에서 사용하지 않는 범위를 넣어줍니다.

192.168.100.0 으로 클러스터를 구성하고 있으니 192.168.100.24

$ cat metallb-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.100.200-192.168.100.209

$ kubectl create -f metallb-config.yaml

 

이제 로드밸런서 서비스 오브젝트를 생성합니다.

$ cat myapp-svc-lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc-lb
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
  selector
    app: myapp-rs

$ kubectl create -f myapp-svc-lb.yaml

 

LoadBalancer 서비스를 확인해봅니다. 우선, external-IP가 상태가 아닌 ip를 부여받아야 정상입니다.

$ kubectl get service

 

 

그리고 로드밸런서의 EXTERNAL-IP 로 접근해보면 됩니다.


 

ExternalName 서비스 생성 및 확인

ExternalName 서비스는 NodePort 및 LoadBalancer 다르게 외부에서 접근하기 위한 서비스 종류가 아닌 내부 파드가 외부의 특정 FQDN에 쉽게 접근하기 위한 서비스입니다.

즉, 쿠버네티스 클러스의 coredns 서비스가 특정 FQDN에 대한 CNAME (서비스의 FQDN)을 제공함에 따라 해당 CNAME을 이용하여 쉽게 통신할 수 있습니다. 심지어 접속하기 위한 외부 FDQN 주소가 바뀌더라도, CNAME은 그대로 유지할 수 있어 애플리케이션을 다시 작성하거나 빌드하지 않아도 됩니다.

예를 들어 구글지도 api 주소가 변경된다고 하면 이전 주소를 참조하고 있던 모든 애플리케이션은 주소 수정을 해야하지만

externalName 서비스를 사용했다면 CNAME은 그대로 유지할 수 있어서 애플리케이션을 다시 작성하거나 빌드하지 않아도 됩니다.

 

 

FQDN 이란?

Fully Qualified Domain Name 으로 "전체 도메인 네임" "절대 도메인 네임" 으로 불리는 도메인 전체 이름 표기 방식을 의미합니다.

예를 들어보겠습니다.

www.tistory.com

web01.tistory.com

위 두 주소 중 www web01 부분은 "호스트" 이고, tistory.com 부분이 "도메인" 입니다.

위에 쓴 것처럼 호스트와 도메인을 함께 명시하여 전체 경로를 모두 표기한 것을 FQDN 이라 합니다.

 

FQDN와 달리 전체 경로명이 아닌 하위 일부 경로만으로 식별 가능한 이름을 PQDN(Partially Qualified Domain Name)이라고 합니다.

쿠버네티스의 경우 다른 Pod를 찾을 시 동일 네임스페이스 안에서 찾을 때는 PQDN을 사용할 수 있지만,

네임스페이스 외부에서 찾을 때는 FQDN를 사용해야 합니다.

 

 

 

CNAME 이란?

캐노니컬 네임 레코드(Canonical Name record), 줄여서 CNAME 레코드(CNAME record)는 하나의 도메인 네임(에일리어스)을 다른 이름(표준 형식의 이름)으로 매핑시키는 도메인 네임 시스템(DNS)의 리소스 레코드의 일종입니다.

 

 

//myapp-svc-extname.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc-extname
spec:
  type: ExternalName
  externalName: www.google.com

외부 FQDN은 www.google.com  이며 이에 대한 CNAME은 myapp-svc-extname 이름을 제공하는 서비스 입니다.

파드와 매칭되지 않기 때문에 레이블 셀렉터는 없습니다.

 

외부 이름 서비스를 생성하고 확인해보겠습니다.

서비스 타입은 ExternalName 이며, 외부 IP에는 www.google.com  의 FQDN가 할당되어 있습니다.

즉, 파드는 myapp-svc-extname CNAME을 사용하면 www.google.com 의  주소를 알 수 있습니다.  

 

 

임시 파드를 생성해서 DNS에 질의해보겠습니다.