DevOps/Kubernetes

[EKS] nginx-ingress-controller, NLB 사용해보기

Jen'_' 2021. 8. 25. 10:19
반응형

테스트 목표

  1. Nginx-ingress-controller 사용하여 AWS NLB 생성합니다
  2. ingress 규칙 사용하여 호스트 foo.bar.com에서 /foo는 nginx-app이 배포된 pod로 요청하고, /bar는 apache-app이 배포된 pod로 요청합니다
  3. service 생성합니다
  4. hostPath 사용하여 node와 pod 간 volume 생성합니다
  5. 결과 확인

 

 

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

 

 

 

반응형