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 기준입니다 🍎
- 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
문제 없이 잘 작동하네요 😀
그럼 한번 연결해보죠!
- 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 을 주거라"
이 정도가 있을 거 같고, 더 자세히 알고 싶다면 여기를 참고해주세요!
이로써 모든 설정이 끝이 났습니다.
대략 아래와 같이 동작한다고 보시면 될 것 같습니다 👍
긴 글 읽어주셔서 감사합니다 🙂
'DevOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] 지난 밤 너가 한 짓을 알고 있다! - Audit (0) | 2023.04.02 |
---|---|
[Kubernetes] 슈뢰딩거의 노드? 노드가 있었는데 없어요 - EKS Fargate (0) | 2023.03.12 |
[Kubernetes] PVC로 마음대로 떼었다 붙이는 AWS EBS (0) | 2023.03.06 |
[Kubernetes] 인증/인가와 ETCD 사이 그 녀석 - Admission Controller (0) | 2023.01.24 |
[Kubernetes] User Account 랑 Service Account 가 다른거였어? (4) | 2022.11.20 |