k8s

Kubernetes Resource Summary (2)

Joon0464 2022. 10. 25. 11:20

1. Service

Service 정의


  • Pod에서 실행되고 있는 어플리케이션을 네트워크에 노출시키기 위한 리소스
  • Kubernetes 리소스들이 어플리케이션과 또는 다른 외부 어플리케이션이나 사용자가 어플리케이션에 연결할 수 있도록 하는 리소스
  • Pod는 쿠버네티스에서 어플리케이션을 구동중인 상태를 유지하기 위한 일회성 리소스로써 언제든 Pod가 재생성되어 IP주소가 변경될 수 있기 때문에 고정적인 IP를 가지는 Service 리소스를 사용하여 클러스터 내/외부와 어플리케이션간에 네트워크 통신이 가능하도록 한다.
  • Service 에서 반드시 정의되어야 할 포트
    • targetPort : Pod의 어플리케이션쪽에서 열려있는 포트를 의미(파드의 인바운드), Service로 들어온 트래픽은 어플리케이션이 동작중인 파드의 <클러스터 내부 IP>:<targetPort> 로 넘어가게 된다.
    • port : 서비스에서 해당 Pod를 향해 열려있는 포트를 의미(서비스의 아웃바운드) 

 

서비스 유형


1) ClusterIP

출처 : https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0

  • Kubernetes Service의 기본 형태
  • Pod와 클러스터 내부의 다른 리소스들이 통신할 수 있도록 해주는 가상의 클러스터 전용 IP
  • ClusterIP를 통해 들어온 클러스터 내부 트래픽을 해당 파드의 <Pod IP>:<targetPort>로 넘겨주도록 동작
  • Kubernetes 클러스터 내부에서만 접근 가능

예시 yaml 파일)

apiVersion: v1
kind: Service
metadata:
  name: service
spec:
  type: ClusterIP		# ClusterIP가 Service의 기본값이므로 생략 가능
  ports:
  - targetPort: 9376		# 애플리케이션(Pod)을 노출하는 포트
    port: 80			# 어플리케이션(Pod)쪽으로 서비스를 노출하는 포트
  selector:			# 서비스가 적용될 Pod의 라벨 정보를 지정
    app: myapp

spec.selector에서 label을 지정하여 노드에 존재하는 여러 Pod들 중 서비스가 트래픽을 전달할 Pod를 결정하게 된다.

spec.selector에 지정된 label을 가진 Pod가 여러개 존재하는 경우에는 서비스는 해당 파드들을 트래픽은 전달할 앤드포인트로 지정하여 트래픽을 분배한다. 이러한 점 때문에 하나의 노드에 여러 Pod, 여러 노드의 여러 Pod가 존재하여도 동일한 서비스를 적용할 수 있다.

 

2) NodePort

출처 : https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0

  • NodePort 외부에서 노드 IP의 특정 포트(<NodeIP>:<NodePort>)로 들어오는 요청을 해당 포트와 연결된 Pod로 트래픽을 전달하는 서비스
  • 클러스터 내부로 들어온 트래픽을 특정 파드로 연결하기 위한 ClusterIP 는 자동 생성
  • spec.ports  nodePort를 지정할 수 있으며, nodePort는 외부에서 노드 안의 특정 서비스로 접근할 수 있도록 지정된 노드의 특정 포트를 의미
  • nodePort로 할당 가능한 포트 범위는 30000에서 32767 사이이며, 미지정시 해당 범위 안에서 랜덤하게 부여됨

예시 yaml 파일)

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: NodePort
  ports:
  - targetPort: 9376		# 애플리케이션(Pod)을 노출하는 포트
    port: 80			# 어플리케이션(Pod)쪽으로 서비스를 노출하는 포트
    nodePort: 31234		# 외부 사용자가 애플리케이션에 접근하기 위한 포트번호(미 지정시 랜덤 부여)
  selector:			# 서비스가 적용될 Pod의 라벨 정보를 지정
    app: myapp

NodePort spec.selector에서 설정된 label을 가진 Pod들에게 동일한 로드 밸런싱이 적용된다. 만약 같은 레이블의 Pod들이 다른 여러 노드에 걸쳐 존재하면, 해당 노드들에도 같은 서비스가 자동으로 생성되어 같은 NodePort를 통한 해당 Pod의 접근이 허용된다.

ex) 192.168.100.2 노드와 192.168.100.3 노드에 각각 같은 레이블의 파드가 존재할 경우

-> NodePort 서비스를 통해 192.168.100.2:<nodePort> 또는 192.168.100.3:<nodePort> 중 어떤 경로를 통하든 해당 Pod들에 연결이 가능하다.

 

3) LoadBalancer 

출처 : https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0

  • 외부 로드 밸런서를 제공하는 클라우드(AWS 등)의 환경을 고려하여, 로드 밸런서를 Kubernetes의 서비스로 프로비저닝할 수 있는 LoadBalancer 유형이 제공됨
  • 서비스를 클라우드 제공자 측의 자체 로드 밸런서로 노출시키며, NodePort ClusterIP는 자동 생성된다.
  • 프로비저닝된 로드 밸런서의 정보는 서비스의 status.loadBalancer 필드에 작성된다.

예시 yaml 파일)

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      targetPort: 9376		# 애플리케이션(Pod)을 노출하는 포트
      port: 80			# 어플리케이션(Pod)쪽으로 서비스를 노출하는 포트
  clusterIP: 10.0.171.239	# 클러스터 IP
  selector:
    app: myapp
    type: frontend
status:
  loadBalancer:			# 프로비저닝된 로드 밸런서 정보
    ingress:
    - ip: 192.0.2.127

4) ExternalName

  • 서비스에 selector 대신 DNS name을 직접 명시할 때 사용
  • spec.externalName 항목에 필요한 DNS 주소를 기입하면, 클러스터의 DNS 서비스가 해당 주소에 대한 CNAME 레코드를 반환한다.

예시 yaml 파일)

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

2. Ingress

Ingress 정의


출처 :&nbsp;https://kubernetes.io/ko/docs/concepts/services-networking/ingress/

  • Ingress는 외부에서 쿠버네티스 클러스터 내부로 들어오는 네트워크 요청(트래픽)을 어떻게 처리할지 정의
  • 인그레스는 아래와 같은 기능들을 제공한다.
    • 외부에서 접속가능한 URL 사용
    • 트래픽 로드밸런싱
    • SSL 인증서 처리
    • 도메인 기반 가상 호스팅 제공
  • Ingress는 위와 같은 기능들을 사용하기 위해 쿠버네티스 클러스터에 정의해둔 리소스이고, 이를 실제 동작은 Ingress controller가 쿠버네티스 클러스터에 정의된 Ingress 리소스를 참고하여 수행한다.
  • Ingress Controller : Ingress Controller는 쿠버네티스 클러스터에서 실행되고 수신 리소스에 따라 HTTP 로드 밸런서를 구성하는 응용 프로그램

예시 yaml 파일)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-fanout-example
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo			# foo.bar.com/foo 로 접근하는 요청에 대한 정의
        pathType: Prefix
        backend:
          service:
            name: service1		# service1로 네트워크 요청을 보내준다.
            port:
              number: 4200		# service1에서 Pod로 트래픽을 보낼 포트(targetPort)를 정의
      - path: /bar			# foo.bar.com/bar 로 접근하는 요청에 대한 정의
        pathType: Prefix
        backend:
          service:
            name: service2		# service2로 네트워크 요청을 보내준다.
            port:
              number: 8080		# service2에서 Pod로 트래픽을 보낼 포트(targetPort)를 정의