[Kubernetes] Nginx Ingress Controller 사용하기
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의 경우 저희가 방금 수정한 문구가 출력됨을 확인할 수 있습니다.