본문 바로가기

⭐ Kubernetes & EKS/Ingress (잉그레스)

Ingress와 ALB 사용시 한개의 ALB에 여러 서비스 맵핑하기

# Ingress와 ALB를 연동하여 사용 시 한개의 ALB에 여러 서비스를 맵핑하는 방법을 알아본다.

1. 문제점

Ingress는 특성상 Namespace별로 리소스를 구분하여 생성한다. 그리고 ingress-alb 사용시 인그레스를 개별로 생성할때마다 alb가 생성이 되므로 비용관리나 리소스 관리 측면에서 매우 비효율적이다.

2. 대안 - 해결방법

1개의 alb 주소로 여러개의 서비스를 Namespace 구분없이 설정할 수 있다면 매우 효율적으로 운영이 가능하다.

3. 적용전 확인사항

- 아래는 AWS LoadBalancer를 적용 시 사용할 수 있는 다양한 옵션들을 제공한다.

https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/ingress/annotations/

 

Annotations - AWS Load Balancer Controller

Ingress annotations You can add annotations to kubernetes Ingress and Service objects to customize their behavior. Annotation keys and values can only be strings. Advanced format should be encoded as below: boolean: 'true' integer: '42' stringList: s1,s2,s

kubernetes-sigs.github.io

- 적용 옵션 예시, 해당 코드를 ingress.yaml 파일에 적용시켜 주면 된다.

추가로, 그룹 이름은 아래와 같아야 한다.

63자 이하의 길이, 소문자, 숫자, - 및 .으로 구성가능. 글자나 숫자로 시작하고 끝난다.

컨트롤러는 동일한 수신 그룹에 있는 모든 수신에 대한 수신 규칙을 자동으로 병합하고 하나의 ALB로 적용된다.

alb.ingress.kubernetes.io/group.name: my-group

4. 리소스 확인하기

- 나는 여기서 4개의 서비스를 로드밸런서로 생성하여 사용중이다.

첫번째는 argocd이고, 두번째는 jenkins, 세번째는 jenkins의 Agent 서비스이고, 네번째는 Sonarqube이다.

해당 서비스들은 모두 서비스를 LoadBalancer로 생성하여 현재 CLB 형태로 서비스가 생성 되었다.

- 해당 서비스들이 사용하는 포트는 아래와 같다.

argocd : 80 / jenkins: 8080 / jenkins-agent: 50000 / Sonarqube : 9000 이다.

- 해당 서비스들을 모두 하나의 ALB에 적용하기 위해서는 현재 생성된 서비스를 모두 NodePort로 변경해 줘야 한다.

변경 명령어는 아래와 같다.

- 변경 대상 : svc 이름 / namespace 이름

argocd-server / argocd

jenkins / default

jenkins-jnlp / default

demo-sonarqube-sonarqube / sonar-demo

kubectl patch svc {svc_name} -n {namespace_name} -p '{"spec": {"type": "NodePort"}}'

kubectl patch svc mynginx -n nginx -p '{"spec": {"type": "NodePort"}}'

- ingress.yaml 파일 작성하기 (기본 리소스 형태)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: instance
  namespace: namespace-01
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: "web-service"
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: "api-service"
                port:
                  number: 8080

5. 실제 리소스 반영하기

- 위의 ingress.yaml 파일의 기본 항목을 보게되면 svc 서비스 명과 포트명 그리고 해당 path만 입력하게끔 되어 있다. 여기에 위에서 확인한 alb group 옵션을 적용해 보자. 그리고 서비스도 함게 맵핑해보자.

- 모두 맵핑을 하면 아래와 같은 결과가 나올 것이다.

해당 파일을 ingress.yaml과같이 원하는 이름으로 저장 후 반영을 해보자.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-alb
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/group.name: ci-cd-group
    alb.ingress.kubernetes.io/group.order: '1'
spec:
  rules:
    - http:
        paths:
          - path: /argocd
            pathType: Prefix
            backend:
              service:
                name: "argocd-server"
                port:
                  number: 80
          - path: /jenkins
            pathType: Prefix
            backend:
              service:
                name: "jenkins"
                port:
                  number: 8080
          - path: /jenkins-jnlp
            pathType: Prefix
            backend:
              service:
                name: "jenkins-jnlp"
                port:
                  number: 50000
          - path: /sonarqube
            pathType: Prefix
            backend:
              service:
                name: "demo-sonarqube-sonarqube"
                port:
                  number: 9000

- 반영하기

명령어 : kubectl apply -f ingress-alb.yaml

- 서비스 확인

kubectl get ingress -A
NAMESPACE   NAME                       CLASS    HOSTS   ADDRESS                                                                   PORTS   AGE
default     ingress-alb                <none>   *       k8s-cicdgroup-da0000000000000000000.ap-northeast-2.elb.amazonaws.com      80      32s

결국 아래와 같이 동작한다고 보면 됨

https://may9noy.tistory.com/950

 

Ingress와 api의 관계에 대한 설명

# Ingress와 api의 관계데 대한 정리 (그림) - 잉그레스의 사전적 정의 : 입장, 권리, 입장권 - 간단하게 설명하면 아래와 같다. Ingress에 설정된 path 주소화 백엔드 api의 주소의 정보가 일치해야 한다.

may9noy.tistory.com

6. 다른 애플리케이션을 하나의 ingress로 적용하기

Ingress는 각 애플리케이션마다 적용 할 수 있다.

아래의 내용을 보면 알기쉽게 정리가 된다.

각 애플리케이션의 Ingress마다 어노테이션을 추가하고 적용하면 된다.

어노테이션은 2개를 추가한다.

alb.ingress.kubernetes.io/group.name
alb.ingress.kubernetes.io/group.order

애플리케이션을 연결하는 방법으로는 labels를 동일하게 적용하였다.

A 애플리케이션과 B애플리케이션 별도로 Ingress를 생성하고 연결은 labels를 통해서 수행된다.

아래의 코드를 보면 이해가 쉽다.

- ingress-api.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  namespace: api
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/group.name: api-group
    alb.ingress.kubernetes.io/group.order: '1'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/certificate-arn: {acm 정보 입력}
    alb.ingress.kubernetes.io/actions.redirect-to-https: '{"Type":"redirect","RedirectConfig":{"Port":"443","Protocol":"HTTPS","StatusCode":"HTTP_301"}}'
    external-dns.alpha.kubernetes.io/hostname: {dns 정보 입력}
    service.beta.kubernetes.io/aws-load-balancer-ip-address-type: dualstack
  labels:
    app: app-01-ingress
spec:
  rules:      
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-svc
                port:
                  number: 80

- ingress-auth.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: auth-ingress
  namespace: auth
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/group.name: api-group
    alb.ingress.kubernetes.io/group.order: '2'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
  labels:
    app: app-01-ingress
spec:
  rules:      
    - http:
        paths:          
          - path: /v1/auth
            pathType: Prefix
            backend:
              service:
                name: auth-svc
                port:
                  number: 80
          - path: /v1/verification
            pathType: Prefix
            backend:
              service:
                name: verification-svc
                port:
                  number: 80

- ALB 확인하기

- 끝 -