인프라/Docker&Kubernetes 2019. 11. 20. 01:01

 

이전 포스팅에서 쿠버네티스란 무엇이고, 간단하게 팟,레플리카셋,디플로이먼트를 다루어보았다. 이번 시간은 이렇게 띄운 팟을 외부로 서비스할 수 있게 해주는 서비스,인그레스에 대해 다룰 것이다.

 

2019/11/19 - [인프라/Docker for mac] - Kubernetes - Kubernetes란? (클러스터,노드,파드(pod), 리플리카셋, 디플로이먼트)

 

Kubernetes - Kubernetes란? (클러스터,노드,파드(pod), 리플리카셋, 디플로이먼트)

이번 포스팅은 kubernetes에 대해 다루어본다. 사실 쿠버네티스를 다루기 위해서는 docker(도커)에 대한 지식이 필요하지만 여기에서는 다루지 않는다. 그렇다면 쿠버네티스란 무엇인가? 쿠버네티스란? 쿠버네티..

coding-start.tistory.com

 

서비스(Service)

서비스는 쿠버네티스 클러스터 안에서 파드의 집합에 대한 경로나 서비스 디스커버리를 제공하는 리소스다. 서비스의 대상이 되는 파드는 서비스에서 정의하는 레이플 셀렉터로 정해진다.

 

apiVersion: v1
kind: Service
metadata:
  name: sample-service
spec:
  selector:
    app: springboot-web
  ports:
    - port: 80
      protocol: TCP
      targetPort: 8080

 

위는 Service 매니페스트 파일이다. 셀렉터로 우리가 띄운 팟을 참조하고 있다. 그리고 해당 서비스는 80포트로 노출시키고 프로토콜은 TCP이며, 해당 서비스로 들어온 요청을 8080 포트로 포워딩하고 있다.

 

 

하지만 이 서비스는 아직 외부 서비스에 노출되고 있지 않다. External-ip를 보면 아직 할당되지 않았다. 이 말은 클러스터 내부에서만 이 서비스에 접근 가능하다는 것이다. 그렇다면 이 서비스를 어떻게 노출시킬까? 방법은 2가지가 있다. 바로 다음에 다루어보도록 한다.

 

<서비스의 네임 레졸루션>

쿠버네티스 클러스터의 DNS는 서비스를 서비스명.네임스페이스명.svc.local로 연결해준다.
예를 들어 위 서비스는 

http://sample-service.kube-sample.svc.local로 접근가능하며, svc.local이 생략가능하기에
http://sample-service.kube-sample로 접근이 가능하다.

또한 같은 네임스페이스끼리의 접근이라면 네임스페이스 또한 생략가능하다.
http://sample-service

 

ClusterIP 서비스

서비스에도 여러 가지 종류가 있어서 그 종류를 yaml 파일에서 지정할 수 있다. 종류의 기본값은 ClusterIP 서비스다.

 

ClusterIP를 사용하면 쿠버네티스 클러스터의 내부 IP 주소에 서비스를 공개할 수 있다. 이를 이용해 어떤 파드에서 다른 파드 그룹으로 접근할 때 서비스를 거쳐 가도록 할 수 있으며, 서비스명으로 네임 레졸루션이 가능해진다. 다만, 외부로부터는 접근할 수 없다.

 

NodePort 서비스

NodePort 서비스는 클러스터 외부에서 접근할 수 있는 서비스다. NodePort 서비스는 ClusterIP를 만든다는 점은 ClusterIP 서비스와 같다. 각 노드에서 서비스 포트로 접속하기 위한 글로벌 포트를 개방한다는 점이 차이점이다.

 

apiVersion: v1
kind: Service
metadata:
  name: sample-service
spec:
  type: NodePort
  selector:
    app: springboot-web
  ports:
    - port: 80
      protocol: TCP
      targetPort: 8080

 

외부에서 접근해보자. 접근하기전에 해당 서비스와 연결된 외부에서 접근할 포트를 확인하기 위해 아래 명령을 쳐보자.

 

 

외부에서 localhost:30142로 접근해보면, 아래와 같은 결과값이 반환된다. 여기서 중요한 것은 ClusterIP는 외부에서 접근하는 IP가 아니라는 점이다. 클러스터 내부에서 사용되는 IP이기에 외부에서는 접근되지 않는다.

 

 

인그레스(Ingress)

쿠버네티스 클러스터 외부로 서비스를 공개하려면 서비스를 NodePort로 노출시킨다. 그러나 이 방법은 L4 레벨까지만 다룰 수 있기 때문에 HTTP/HTTPS처럼 경로를 기반으로 서비스를 전환하는 L7 레벨의 제어는 불가능하다.

 

이를 해결하기 위한 리소스가 인그레스다. 서비스를 이용한 쿠버네티스 클러스터 외부에 대한 노출과 가상 호스트 및 경로 기반의 정교한 HTTP 라우팅을 할 수 있다.

 

로컬 쿠버네티스 환경에서는 인그레스를 사용해 서비스를 노출하기 위해서는 몇 가지 설정이 더 필요하다. 클러스터 외부에서 온 HTTP 요청을 서비스로 라우팅하기 위한 nginx_ingress_controller를 다음과 같이 배포한다.

 

> kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.16.2/deploy/mandatory.yaml
> kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.16.2/deploy/provider/cloud-generic.yaml

 

이제는 필요한 Ingress Resource를 작성하면 된다. 여기서 작성되는 Ingress는 어떠한 워커에 팟을 띄우는 행위가 아니다. 지금 작성하는 것은 Nginx-ingress에 Rule을 추가하는 행위인 것이다.

 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress-sample
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: levi.local.com
    http:
      paths:
        - path: /app
          backend:
            serviceName: sample-service
            servicePort: 80

 

> curl http://localhost/app/api -H "Host:levi.local.com"

 

위의 설정으로 nginx에 룰을 추가하고, 해당 룰로 들어온 요청은 sample-service라는 라우팅 룰을 가지는 팟으로 요청이 전달되는 것이다. 그리고 팟이 여러개라면 로드밸런싱을 nginx가 해준다. 여기까지 간단하게 서비스와 인그레스에 대해 다루어보았다. 사실 간단하게 테스트로 띄우는 정도의 예제였지만 추후에 좀더 실무에 가까운 예제를 다루어볼 것이다.

posted by 여성게
: