인프라/Docker&Kubernetes 2020. 8. 2. 22:52

 

이번 포스팅에서 다루어볼 내용은 간단하게 쿠버네티스 ingress-nginx를 설치하고, 외부 트래픽을 내부 팟에게 전달해주는 예제이다. 바로 예제로 들어간다.

 

> git clone https://github.com/kubernetes/ingress-nginx.git
> cd ./ingress-nginx/deploy/static/provider/baremetal
> kubectl apply -f .
> kubectl get deploy -n ingress-nginx
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
ingress-nginx-controller   1/1     1            1           60s

 

여기까지 따라왔다면 설치는 완료되었고, ingress-nginx를 위한 서비스 등이 떴을 것이다.

 

kubectl get svc -n ingress-nginx
NAME                                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.97.27.106   <none>        80:30431/TCP,443:31327/TCP   4m35s

 

30431로 접속해보자.

 

> curl levi.local.com:30431
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.19.1</center>
</body>
</html>

 

호스트 설정을 통해 levi.local.com을 localhost로 포워딩하도록 설정하였다. 실습에 localhost는 사용하기 힘들기 때문에 etc/hosts 설정을 통해 로컬을 특정 도메인처럼 할당해보자.

 

> sudo vi /etc/hosts
127.0.0.1 levi.local.com

 

이제 ingress-nginx가 포워딩할 웹어플리케이션 팟을 띄워보자.

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: springboot-web
  template:
    metadata:
      labels:
        app: springboot-web
    spec:
      containers:
        - name: springboot-web
          image: 1223yys/springboot-web:0.2.5
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
          livenessProbe:
            httpGet:
              port: 8080
              path: /api
            initialDelaySeconds: 60
          readinessProbe:
            httpGet:
              port: 8080
              path: /api
            initialDelaySeconds: 60

 

디플로이먼트 컨트롤러로 springboot-web 애플리케이션 팟을 관리하도록 매니페스트를 작성하였다. 해당 매니패스트를 적용해보자.

 

> kubectl apply -f deployment.yaml

 

다음으로는 springboot-web으로 접근할 수 있게 해주는 외부 통로인 서비스를 작성해보자.

 

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

 

해당 서비스도 배포해보자.

 

> kubectl apply -f service.yaml

 

마지막으로 ingress nginx 매니페스트 파일을 작성해보자.

 

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: /
        backend:
          serviceName: springboot-web-service
          servicePort: 80

 

위 매니페스트 파일에서 host를 유의하자. 포스팅 초반에 localhost를 로컬 도메인으로 할당해야한다 했는데, 그 이유가 위 host 때문이다. 위에 보이는 host는 실제로 http 요청이 들어올때 요청 헤어의 "Host : levi.local.com" 을 참조하기 때문이다.

 

이제 요청을 보내보자.

 

> curl http://levi.local.com:30431/api
new api !


 ingress-nginx를 통해 웹앱 팟에 잘 접근되는 것을 확인할 수 있다.

posted by 여성게
:
인프라/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 여성게
: