[EKS] nginx-ingress-controller, NLB 사용해보기
테스트 목표
- Nginx-ingress-controller 사용하여 AWS NLB 생성합니다
- ingress 규칙 사용하여 호스트 foo.bar.com에서 /foo는 nginx-app이 배포된 pod로 요청하고, /bar는 apache-app이 배포된 pod로 요청합니다
- service 생성합니다
- hostPath 사용하여 node와 pod 간 volume 생성합니다
- 결과 확인
1. eksctl create cluster
1
2
3
4
|
eksctl create cluster --name <CLUSTER_NAME> --version 1.18 --region ap-northeast-2 \
--nodegroup-name <NODE_NAME> --nodes 2 \
--ssh-access --ssh-public-key <KEYNAME> --node-type t3.medium --managed --spot \
--vpc-public-subnets=<SUBNET_ID>
|
cs |
저는 AWS CLI를 이용하여 클러스터를 구축하였습니다 eksctl을 사용하면 콘솔에서 할 때보다 쉽고 편리하게 생성할 수 있습니다
node는 public subnet을 지정하여 생성하도록 하였습니다
자세한 옵션은 eksctl --help를 하면 나옵니다
cloudformation을 보면 클러스터 구축, 워커 노드 생성을 위한 두 개의 스택 파일이 생성됩니다
CREATE_COMPLETE이 되면 성공입니다 간혹 eksctl create cluster에서 에러가 뜬다면 스택 파일의 이벤트를 확인해보세요
$ kubectl get node
노드가 성공적으로 생성되었습니다
2. Nginx-ingress-controller 다운로드
1
|
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.49.0/deploy/static/provider/aws/deploy.yaml
|
cs |
저는 NLB를 생성하는 컨트롤러를 다운로드하였습니다
설치 방법
https://kubernetes.github.io/ingress-nginx/deploy/#network-load-balancer-nlb
위의 사진을 보면 namespace가 ingress-nginx로 생성된 것이 보입니다
그러므로 앞으로 리소스들의 namespace를 ingress-nginx으로 붙여야 합니다
$ kubectl get svc -n ingress-nginx
확인해보면 nlb가 생성이 된 것이 보입니다
3. Ingress 생성
Ingress Controller는 Ingress 규칙을 관리하기 위한 서버일 뿐이고, 실제 Ingress 규칙을 생성해줘야 합니다
Ingress 규칙이라 하면, Layer 7 라우팅을 의미합니다
위의 사진을 예로 들면, 인그레스 규칙이 178.91.123.132/foo 경로로 들어온 요청은 service1 객체로 전송하고, 178.91.123.132/bar 경로로 들어온 요청은 service2 객체로 전송하는 것입니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
namespace: ingress-nginx
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
|
cs |
제가 만든 인그레스 규칙입니다
배포 명령어
$ kubectl apply -f ingress.yml
인그레스 확인 명령어
$ kubectl get ing -n ingress-nginx
host와 address에 값이 알맞게 들어간 것이 보입니다
4. service 생성
두 개의 service 객체를 생성하고 그를 위한 deployment를 생성해야 합니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
# apache.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: apache-deployment
namespace: ingress-nginx
labels:
app: httpd
spec:
replicas: 2
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: apache
image: httpd
volumeMounts:
- mountPath: /data
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /root/data
type: Directory
---
apiVersion: v1
kind: Service
metadata:
name: svc1
namespace: ingress-nginx
spec:
selector:
app: httpd
ports:
- port: 80
targetPort: 80
protocol: TCP
|
cs |
apache-app을 배포할 yaml파일입니다
여기서 유의할 점은 두 가지는 1. hostPath는 미리 노드에 디렉터리가 생성되어 있어야 합니다
2. ingress.yml의 /foo의 serviceName과 apache.yml 파일의 Service의 name이 같아야 합니다
규칙에 해당하는 서비스 객체를 매핑해 주는 것입니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
# nginx.yml
apiVersion: apps/v1 kind: Deployment
metadata:
name: nginx-deployment
namespace: ingress-nginx
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: /data
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /root/data
type: Directory
---
apiVersion: v1
kind: Service
metadata:
name: svc2
namespace: ingress-nginx
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
protocol: TCP
|
cs |
nginx-app을 배포할 yaml파일도 동일하게 만들어 줍니다
foo.bar.com/bar는 nginx를 요청할 것입니다
$ kubectl apply -f nginx.yml
두 개의 파일을 배포해 줍니다
$ kubectl get all -n ingress-nginx
4개의 파드와 2개의 서비스가 생성되었습니다
상세 출력 명령어
kubectl describe <리소스 이름> -n ingress-nginx
로그 확인 명령어
kubectl logs -f <리소스 이름> -n ingress-nginx
5. 볼륨 마운트 확인
미리 노드에 디렉터리를 만들고 volume-test.txt을 넣어놨습니다
$ kubectl exec -it pod/apache-deployment-565fd957f9-h9x6c -n ingress-nginx -- bash
파드 안에 들어가 보니 만들지도 않은 /data 디렉터리가 생성이 되어있었고 테스트 파일이 들어가 있습니다
6. 결과 확인
마지막으로 결과만 확인하면 되겠군요
$ curl -I http://<NLB>
-h 옵션으로 Host를 넣어주지 않으면 404번 에러가 뜹니다
$ curl -I -H "Host: foo.bar.com" http://<NLB>/foo
$ curl -I -H "Host: foo.bar.com" http://<NLB>/bar
200번 성공 코드가 나오는군요!
수고하셨습니다
참고
https://kubernetes.github.io/ingress-nginx/deploy/#contents
https://aws.amazon.com/premiumsupport/knowledge-center/eks-access-kubernetes-services/?nc1=h_ls
https://5equal0.tistory.com/entry/Kubernetes-Nginx-Ingress-Controller