아이엠 !나이롱맨😎
article thumbnail
반응형

Istio 는 흔히 K8S 클러스터 내에서 서비스 메시 역할을 해줍니다. 서비스 메시 뿐만 아니라 Nginx Ingress, ELB Ingress 처럼 Ingress 역할 또한 해줍니다.

 

Istio Ingress Gateway 가 정식 명칭이나 쉽게 Istio Ingress 로 지칭하도록 하죠 🤟

 

EKS 와 같은 퍼블릭 클라우드를 이용해서 Load Balancer Service 를 생성해주면 자동으로 CLB 가 할당됩니다. 따라서 Istio Ingress 또한 CLB 로 할당이 됩니다.

 

CLB 는 앞으로 AWS 에서 deprecated 되기 때문에 Network Load Balancer(이하 NLB) 나 Application Load Balancer(이하 ALB) 로 대체되어야 합니다.

 

그래서 이번 글에서는 Istio 가 CLB 가 아닌 Elastic Load Balancer(이하 ELB) 중 하나인 ALB 를 사용할 수 있도록 하겠습니다.

 

Istio 는 뭘까? 


들어가기 앞서 Istio 에 대해 알아보죠.

 

Istio 는 AWS App Mesh 와 같은 서비스 메시를 제공할 수 있도록 도와줍니다.


Istio 는 사실 Envoy 라는 서비스를 쿠버네티스 환경에서 사용자들이 조금 더 쉽게 Envoy 를 사용할 수 있도록 해주는 CNCF 졸업작품입니다.

 

즉, Envoy == Istio 입니다. 다만 Envoy 는 C++ 로 되어있고, 매우 저수준의 툴이라서 진입장벽이 어렵습니다. 따라서 이를 쉽게 구현하고자 해주는 것이 바로 Istio 라고 이해하면 됩니다.

100% 맞는 말은 아니지만 Istio 는 Envoy 위에 있는 추상화 레이어라고 생각할 수 있습니다. 🙂

 

또한 Istio 는 파드 디자인 패턴 중 SideCar Container Pattern 을 사용합니다.

 

파드 안에 SideCar 로 Proxy 가 생기게 되는 데 이 Proxy 가 곧 Istio 입니다. 그리고 Proxy 는 Istiod 에 의해 관리됩니다.

 

Istio 를 이용하면 다음과 같은 기능들을 사용할 수 있습니다.

  • 프록시로부터 원격 측정 결과 수집
  • 프록시를 이용한 정책을 구현
  • 카나리아 배포, A/B 배포, 다크 배포 등 여러가지 배포 방법이 가능
  • 테스트 소프트웨어를 라이브 프로덕션 환경에 배포 가능
  • 이외 결합 주입, 서킷 브레이킹, mTLS 등이 가능

 

이외에도 여러가지 기능이 있지만 이에 대해서는 다른 글에서 다루도록 하겠습니다.

 

Istio 를 설치해보자 


MAC m1 기준입니다 🍎

 

  1. brew 를 이용하여 istioctl 을 설치합니다
$ brew install istioctl

 

 

2. 프로필을 지정해서 istio 를 설치합니다.
Istio 는 다양한 프로필을 제공하는 데 여기선 default 로 설치하겠습니다.

$ istioctl install --set profile=default

프로필에 대한 추가적인 정보를 드리자면...

  • default 와 demo 가 가장 많이 사용되는 프로필입니다. (나머진 딱히..)
  • production 환경이라면 default 가 가장 적합합니다.
  • demo 는 mini kube 와 같이 추적이 많이 필요한 곳에 필요합니다.

 

3. 설치가 완료됩니다. 명령어를 통해 확인해봅시다!!

$ kubectl get all -n istio-system
NAME                       READY   STATUS    RESTARTS   AGE
pod/istio-ingressgateway   1/1    Running   0          3d4h
pod/istiod                 1/1     Running   0          3d4h

NAME                           TYPE           CLUSTER-IP       EXTERNAL-IP                              PORT(S)                                      AGE
service/istio-ingressgateway   LoadBalancer   172.20.147.69    xxxxx.ap-northeast-2.elb.amazonaws.com   15021:30098/TCP,80:30361/TCP,443:31567/TCP   3d4h
service/istiod                 ClusterIP      172.20.131.157   <none>                                   15010/TCP,15012/TCP,443/TCP,15014/TCP        3d4h

NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/istio-ingressgateway   1/1     1            1           3d4h
deployment.apps/istiod                 1/1     1            1           3d4h

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/istio-ingressgateway   1         1         1       3d4h
replicaset.apps/istiod                 1         1         1       3d4h

NAME                                                       REFERENCE                         TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
horizontalpodautoscaler.autoscaling/istio-ingressgateway   Deployment/istio-ingressgateway   <unknown>/80%   1         5         1          3d4h
horizontalpodautoscaler.autoscaling/istiod                 Deployment/istiod                 <unknown>/80%   1         5         1          3d4h

 

성공적으로 설치를 마쳤습니다.

 

간단히 짚고 넘어가보자!


pods 를 보면 istio-ingressgateway 와 istiod 가 생성된 걸 확인할 수 있는데요, 아까 프로필을 default 를 주었기 때문입니다.

Tip.
프로필을 default 로 했다고 egress 를 설치 못하는 것은 아닙니다.

$ kubectl edit istiooperators.install.istio.io -n istio-system

명령어를 사용해 설정을 바꿀 수 있습니다.

 

그리고 가장 주목할 것이 바로 service/istio-ingressgateway 입니다. 뒤에 EXTERNAL-IP 를 보시면 AWS Domain 이 할당된 것을 확인할 수 있는데 이것이 바로 CLB 입니다.

aws elb describe-load-balancers

 

생성된 LB 가 출력되는 것을 확인할 수 있습니다.

 

 

사실 이렇게만 구성되어도 충분히 Ingress 역할을 할 수 있습니다.

Istio 의 CRD 인 Gateway, VirtualService, DestinationRule 를 이용해서 말이죠 😎

 

하지만 CLB 는 앞에서도 말씀드렸다시피 더 이상 서비스되지 않기 때문에 NLB, ALB 로 바꾸어야 합니다.

 

ALB 로 바꾸어보자 !


CLB 로 ALB 로 바꾸는 것은 그림에서 보이는 것처럼 CLB 대신 ALB 로 교체하면 됩니다. 하지만 ALB 는 CLB 와 다르게 AWS Load Balancer Controller 라는 것을 필요로 합니다.

 

AWS Load Balancer Controller 를 설치하는 것만으로도 많은 분량이 필요하니 여기선 다루지 않겠습니다. 분량이 많을 뿐 사실 AWS 공식문서를 보면 쉽게 따라하실 수 있을 겁니다.

 

AWS Load Balancer Controller 는 Nginx Ingress Controller 와 완전히 똑같은 역할을 합니다. 다만 AWS 에서 제공해주는 것이라고 보시면 됩니다.

 

 

 

그럼 AWS LB Controller 가 잘 설치되었는지 확인해보죠! 🙏

$ kubectl get all -n kube-system
NAME                                               READY   STATUS    RESTARTS   AGE
pod/aws-load-balancer-controller-794f85d67-6jncw   1/1     Running   0          176m
pod/aws-load-balancer-controller-794f85d67-bhlmq   1/1     Running   0          176m

NAME                                        TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)         AGE
service/aws-load-balancer-webhook-service   ClusterIP   172.20.82.65   <none>        443/TCP         176m

 

문제 없이 잘 작동하네요 😀

 

그럼 한번 연결해보죠!

  1. service/istio-ingressgateway 를 수정합니다.
$ kubectl edit -n istio-system service istio-ingressgateway

 

 

 

아래와 같이 수정해줍니다.

spec:
  ...
  type: NodePort
  ...

 

이렇게 하는 이유는 CLB 를 사용하지 않기 위해서입니다. type: Loadbalancer 로 되어있으면 자동으로 CLB 가 생성되고, 우리는 이것을 사용하지 않을 거기 때문에 type 을 NodePort 를 바꿔줍니다. (참고)

 

그러면 이전에 Istio 에서 생성한 CLB 는 삭제되고, ALB 만 남아있습니다.

 

 

Tip.
ClusterIP 로도 가능할거라 생각해서 바꿔봤는데.. 작동하지 않았습니다. 생각해보면 당연합니다.

ALB 입장에서 타겟그룹으로 각 인스턴스에게 통신을 보내주게 되는데 ALB 는 EKS Cluster 내에 존재하는 것이 아니니 당연히 노드 포트로 접근을 할 수 밖에 없습니다.

 

2. Ingress 를 생성합니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: common-external-ingress
  namespace: istio-system
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/actions.ssl-redirect: '443'
    alb.ingress.kubernetes.io/load-balancer-name: common-external-ingress
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/subnets: subnet-031c06XXXXXXXXXXX, subnet-03444dXXXXXXXXXXX, subnet-0360f0XXXXXXXXXXX
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:123456789011:certificate/26cec536-5d01-4140-890d-XXXXXXXXXXXX
    alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:us-west-2:123456789011:regional/webacl/prod-common-alb-acl/ae2e63f9-02f4-44b8-9d25-XXXXXXXXXXXX
  labels:
    app: common-external-ingress
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: istio-ingressgateway
                port:
                  number: 443

 

어노테이션들이 많은데 매우 직관적이라 보시면 어느 것인지 쉽게 파악하실 수 있습니다.

그래도 그 중 중요한 것들에 대해 말씀드리겠습니다.

 

alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '443'

"http, https 리스너를 사용하고, http 로 통신이 온다면 https 로 리다이렉션 하라!"

 

alb.ingress.kubernetes.io/target-type: instance

"ip mode 와 instance 가 있는 데 instance 를 사용하겠다! 참고"

 

alb.ingress.kubernetes.io/scheme: internet-facing

"ALB 를 퍼블릭으로 지정하라! 만약 프라이빗으로 하고 싶다면 internal 을 주거라"

 

이 정도가 있을 거 같고, 더 자세히 알고 싶다면 여기를 참고해주세요!

 

이로써 모든 설정이 끝이 났습니다.

 

대략 아래와 같이 동작한다고 보시면 될 것 같습니다 👍

 

긴 글 읽어주셔서 감사합니다 🙂

반응형

article prev thumbnail
article next thumbnail
profile on loading

Loading...