[Kubernetes] Nginx Ingress Controller 사용하기

2020. 6. 12. 17:30Engineering/Container&Kubernetes

Content

1. Nginx-ingress controller 다운로드
2. Ingress 생성
3. Service 생성
4. 결과 확인

 


Nginx Ingress Controller를 직접 사용해 Service 객체를 생성합니다. 


 

 

1. Nginx-ingress controller 다운로드

 

Nginx-ingress controller 깃헙 주소는 아래를 참고하시기 바랍니다.

(https://github.com/kubernetes/ingress-nginx)

 

Readme 파일에서 getting start 링크로 이동하시면, 설치방법이 나와있습니다.

https://kubernetes.github.io/ingress-nginx/deploy/

 

 

다운로드 받는 방법은 어떤 CSP사의 퍼블릭 클라우드를 사용하고 있느냐에 따라 달라 집니다.

글에서는 VM으로 클러스터를 구성한 환경을 다룹니다.

쿠버네티스가 보기에 VM bare-metal 이나 동일합니다.

따라서 가이드에 나온 bare-metal 경우의 가이드를 따르겠습니다.

 

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.32.0/deploy/static/provider/baremetal/deploy.yaml

 

 

 

실행 로그를 보면 알겠지만,

Ingress-nginx라는 namespace 가장 먼저 생성 되었습니다.

그리고 ingress-nginx 네임스페이스 안에 ingress controller 관련된 객체들이 설치 되었습니다.

 

이해할 필요는 없고,

중요한 자원인 ingress controller 봅시다.

실행 로그에 서비스 자원으로 배포된것을 확인 있습니다.

정상적으로 실행중인지 볼까요?

 

$ kubectl get svc --namespace=ingress-nginx

 

 

 

 

NodePort 타입으로 노출 되었네요.

NodePort 32289 입니다.

포트번호를 기억해두실 필요가 있습니다.

왜냐면, ingress 통해 노출되는 서비스가{DOMAIN}:{INGRESS_CONTROLLER_PORT}   노출되기 때문입니다.

 

 

 

2. Ingress 생성

Ingress Controller Ingress 규칙을 관리하기 위한 서버일 뿐이고,

실제 Ingress 규칙을 생성 해주셔야 합니다.

Ingress 규칙이라 하면, Layer 7 라우팅을 의미합니다.

 

예시 상황을 들어 봅시다.

우리가 foo.bar.com 이라는 도메인을 가지고 있다고 합시다.

foo.bar.com/foo 경로로 들어온 요청은 svc1 라는 서비스 객체에 연결,

foo.bar.com/bar 경로로 들어온 요청은 svc2 라는 서비스 객체에 연결

하는 ingress 규칙을 만들고 싶습니다.

 

ingress 규칙을 명시하는 ingress.yaml 파일을 작성하면 아래와 같습니다.

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: test

  annotations:

    nginx.ingress.kubernetes.io/rewrite-target: /

spec:

  rules:

  - host: foo.bar.com

    http:

      paths:

      - path: /foo

        backend:

          serviceName: svc1

          servicePort: 80

      - path: /bar

        backend:

          serviceName: svc2

          servicePort: 80

 

 

 

, 그럼 ingress 배포해 봅시다.

namsepace ingress-nginx 하셔야 합니다!

$ kubectl apply -f ingress.yaml --namespace=ingress-nginx

 

 

정상적으로 배포되었는지 확인해보시고요.

배포가 완료되기 전까지는 ADDRESS값이 노출되지 않습니다.

ADDRESS값이 노출되지 않는다면 잠시 기다려 보세요.

$ kubectl get ing --namespace=ingress-nginx

 

 

, 그러면 ingress 규칙까지는 생성이 되었고,

실제로 ingress 규칙에 맞게 동작을 서비스들을 만들어 보겠습니다.

 

 

3. Service 생성

예시에서 말했듯이 저희는 svc1, svc2 해당하는 서비스 객체 2개가 필요합니다.

서비스 모두 nginx 서비스로 가정하겠습니다.

 

먼저 서비스를 위한 deployment부터 만들어 보겠습니다.

$ kubectl run nginx1 --image=nginx:latest --replicas=1 --namespace=ingress-nginx

 

제대로 생성 되었나 확인하시구요.

 

 

이제, 해당 deployment 서비스로 노출시킵니다.

주의하실점은 bare-metal환경에서 (VM환경도 동일) 서비스를 Nodeport형태로 노출하셔야 된다는 것입니다.

자세한 내용은 아래 내용을 참고하세요.

https://kubernetes.github.io/ingress-nginx/deploy/baremetal/

 

$ kubectl expose deployment nginx1 --name=svc1 --port=80 --type=NodePort --namespace=ingress-nginx

 

svc2 같은 방법으로 생성하겠습니다.

$ kubectl run nginx2 --image=nginx:latest --replicas=1 --namespace=ingress-nginx

$ kubectl expose deployment nginx2 --name=svc2 --port=80 --type=NodePort --namespace=ingress-nginx

 

 

모두 정상적으로 배포되었는지 확인해보시고요.

$ kubectl get all --namespace=ingress-nginx

 

 

4. 결과확인

 

이제 ingress 규칙이 제대로 동작하는지 확인해보겠습니다.

전에, foo.bar.com IP 호스트파일에 등록해야 합니다.

NodePort타입이기 때문에, 클러스터 아무 VM IP 등록해주시면 됩니다.

 

 

저는 master 노드의 IP foo.bar.com으로 등록해주었습니다

$ vi /etc/hosts

파일 끝에 127.27.0.107 foo.bar.com

추가합니다.

 

 

, 그럼 모든 준비가 완료 되었습니다.

서비스를 호출해 봅시다.

 

말씀드렸듯이, ingress-controller 서비스의 node-port 도매인이 노출 되며,

저희가 설정해준 ingress 규칙 대로 서비스가 반응합니다.

svc1 호출하기 위해서는 /foo 경로로,

svc2 호출하기 위해서는 /bar 경로로 요청을 보내야 합니다.

 

$ curl foo.bar.com:32289/foo

 

 

$ curl foo.bar.com:32289/bar

 

 

경로마다 nginx 서비스가 제대로 호출 것을 있습니다.

/foo, /bar 경로 각각 서로 다른 서비스가 동작하는지 확인을 원하시면

하나의 svc nginx index.html 수정해보셔도 좋을 같네요 !

 

 

말이 나온김에 바로 해보겠습니다. ㅋㅋ

Svc2 index.html 수정해보겠습니다.

 

먼저 svc2 구동중인 container 접속합니다.

$ kubectl exec --namespace=ingress-nginx -it {PODNAME} /bin/bash

 

 

그리고 index.html 수정합니다.

$ echo This is from svc2! > /usr/share/nginx/html/index.html

 

파일을 수정하였으면,

컨테이너에서 나옵니다.

$ exit

 

 

다시 서비스 경로로 요청을 보내 봅니다.

$ curl foo.bar.com:32289/foo

 

/foo 경로는 svc1 호출되며,

Svc1 index.html nginx default html 사용하였기 때문에,

Nginx 초기 화면 페이지가 출력됩니다.

 

 

$ curl foo.bar.com:32289/bar

 

 

/bar경로는 svc2 호출되며,

Svc2 경우  저희가 방금 수정한 문구가 출력됨을 확인할 있습니다.