728x90
반응형

결론부터 말하면

Istio와 Cilium 서비스 메시 중 어떤 것을 선택할지는 애플리케이션 아키텍처의 특정 요구 사항, 성능 고려 사항, 보안 요구 사항에 따라 달라집니다. 각 서비스 메시에서는 마이크로서비스 통신을 관리하고, 상호 작용을 보호하고, 통합 가시성을 보장하는 데 필수적인 도구를 제공합니다. Istio의 사이드카 프록시 기반 아키텍처는 풍부한 트래픽 관리와 고급 라우팅이 필요한 시나리오에 적합합니다. 반면, Cilium의 eBPF 기반 접근 방식은 커널에 직접 통합된 효율적인 네트워킹 및 보안 기능을 제공하므로 엄격한 보안 요구 사항이 있는 고성능 애플리케이션에 적합한 선택이 될 수 있습니다. 이 서비스 메시 간의 유사점과 차이점을 이해하면 프로젝트의 목표와 제약 조건에 맞는 정보에 입각한 결정을 내릴 수 있습니다.

 

소개

빠르게 발전하는 클라우드 네이티브 기술 환경에서 서비스 메시는 마이크로서비스 기반 애플리케이션을 관리하고 보호하기 위한 필수 도구로 등장했습니다. 이 분야에서 두 가지 주요 경쟁자는 Istio와 Cilium 서비스 메시입니다. 두 가지 모두 마이크로서비스 간의 통신을 간소화하는 것을 목표로 하지만 서로 다른 기능과 접근 방식을 가지고 있습니다. 이 기사에서는 Istio와 Cilium의 유사점과 차이점을 자세히 살펴보고 이들의 기능을 조명하고 애플리케이션 아키텍처에 가장 적합한 것을 선택하는 데 도움을 줄 것입니다.

 

비슷한 점

1. 마이크로서비스 커뮤니케이션

Istio와 Cilium은 모두 컨테이너화된 환경 내에서 마이크로서비스 간의 원활한 통신을 촉진하도록 설계되었습니다. 네트워크 트래픽 및 상호 작용을 관리하기 위한 플랫폼 독립적인 계층을 제공하여 마이크로서비스 애플리케이션을 보다 쉽게 ​​개발하고 배포할 수 있습니다.

2. 교통관리

각 서비스 메시는 트래픽 라우팅, 로드 밸런싱, 트래픽 분할 기능을 제공합니다. 이를 통해 개발자는 다양한 서비스 간의 요청 흐름을 제어 및 관리할 수 있어 유연성이 향상되고 A/B 테스트 및 점진적 출시가 가능해집니다.

3. 보안 및 권한 부여

Istio와 Cilium은 모두 상호 TLS(mTLS) 암호화 및 인증과 같은 보안 기능을 제공하여 마이크로서비스 간의 통신을 안전하게 유지합니다. 또한 세분화된 액세스 제어 정책을 시행하여 무단 액세스 및 잠재적인 보안 침해로부터 보호하는 메커니즘도 제공합니다.

4. 관찰 가능성 및 모니터링

각 서비스 메시는 원격 측정 데이터 수집, 서비스 상태 모니터링 및 요청 추적을 위한 도구를 제공합니다. 이러한 기능은 성능 병목 현상을 식별하고, 문제를 진단하고, 전체 애플리케이션을 최적화하는 데 도움이 됩니다.

5. 서비스 발견

Istio와 Cilium은 모두 서비스 검색을 위한 메커니즘을 제공하므로 마이크로서비스가 하드 코딩된 IP 주소가 아닌 논리적 서비스 이름을 사용하여 서로 찾고 통신할 수 있습니다.

6. 재시도 및 서킷 브레이커

Istio와 Cilium은 재시도 및 회로 차단을 처리하는 기능을 제공합니다. 이러한 메커니즘은 실패한 요청을 지능적으로 다시 시도하고 비정상 서비스를 격리함으로써 서비스 복원력을 관리하는 데 도움이 됩니다.

7. 분산 추적

각 서비스 메시는 분산 추적을 지원하므로 개발자는 다양한 마이크로서비스를 탐색하면서 요청을 추적할 수 있습니다. 이는 병목 현상을 진단하고 요청의 엔드 투 엔드 흐름을 이해하는 데 중요합니다.

8. 카나리아 배포

Istio와 Cilium은 모두 작은 트래픽 하위 집합이 서비스의 새 버전으로 전달되는 카나리아 배포를 허용합니다. 이를 통해 새 릴리스를 전체 사용자 기반에 출시하기 전에 테스트하고 검증할 수 있습니다.

728x90

차이점

1. 아키텍처 및 프록시

Istio는 사이드카 프록시 아키텍처(Envoy)를 활용하여 서비스 간 통신을 관리합니다. 반면 Cilium은 Linux 커널과 통합되고 eBPF(확장 버클리 패킷 필터) 기술을 사용하여 네트워크 가시성과 보안을 향상시킵니다.

2. 데이터 플레인 및 제어 플레인

Istio는 데이터 플레인(네트워크 트래픽이 흐르는 곳)과 제어 플레인(구성 및 정책 결정을 관리하는 곳)을 분리합니다. 반면 Cilium은 eBPF를 사용하여 데이터 플레인과 제어 플레인 기능을 결합하여 잠재적으로 성능을 향상하고 복잡성을 줄입니다.

3. 성능 및 확장성

Cilium의 eBPF 기반 접근 방식은 낮은 수준의 커널 통합을 제공하므로 잠재적으로 오버헤드가 줄어들고 성능이 향상됩니다. Istio의 프록시 기반 아키텍처에서는 사이드카 프록시를 통한 추가 홉으로 인해 약간의 대기 시간이 발생할 수 있습니다.

4. 네트워크 정책

Cilium은 eBPF를 사용하여 강력한 네트워크 분할 및 보안 기능을 제공하므로 커널 수준에서 시행되는 고급 네트워크 정책이 가능합니다. Istio는 제어 플레인을 통해 네트워크 정책을 제공하지만 Cilium과 동일한 수준의 세분성을 갖지 않을 수 있습니다.

5. 통합과 생태계

Istio는 서비스 메시 공간에서 더 오랫동안 존재하기 때문에 더 넓은 생태계와 통합을 갖추고 있습니다. Kubernetes와 잘 통합되며 관찰 가능성, 보안 및 트래픽 관리를 위한 다른 도구와 쉽게 결합할 수 있습니다. Cilium은 네트워킹과 보안에 중점을 두지만 통합 범위가 더 좁을 수 있습니다.

6. Policy

Cilium의 eBPF 기반 접근 방식은 네트워크 트래픽에 대한 심층적인 가시성을 제공하여 보다 세밀한 정책 시행을 가능하게 합니다. 이는 복잡한 보안 정책을 구현하고 잠재적인 위협을 완화하는 데 특히 유용할 수 있습니다.

7. 복잡성과 학습 곡선

사이드카 프록시와 별도의 제어 플레인을 포함하는 Istio의 아키텍처는 개발자와 운영자에게 추가적인 복잡성과 학습 곡선을 도입할 수 있습니다. 커널에 직접 통합된 Cilium의 아키텍처는 일부 사용자의 경우 이해하고 관리하기가 더 간단할 수 있습니다.

8. 자원 소비

Cilium과 커널 및 eBPF 기술의 통합은 특정 시나리오에서 리소스 소비를 낮추고 성능을 향상시킬 수 있습니다. Istio의 프록시 기반 접근 방식은 추가 사이드카 프록시로 인해 리소스 오버헤드가 약간 더 높아질 수 있습니다.

9. 커뮤니티 및 개발 속도

Istio는 더 큰 커뮤니티와 더 긴 개발 기록의 이점을 활용하여 더 성숙하고 기능이 풍부한 플랫폼을 제공합니다. Cilium은 빠르게 성장하고 있지만 더 집중된 기능 세트와 더 작은 커뮤니티를 가질 수 있습니다.

10. 사용자 정의 및 확장성

– Istio는 여러 확장 지점을 갖춘 유연한 플랫폼을 제공하므로 사용자는 서비스 메시의 다양한 측면을 맞춤 설정할 수 있습니다. 이는 고급 사용 사례에 유용할 수 있지만 복잡성이 발생할 수도 있습니다.
– Cilium의 eBPF 기반 아키텍처는 다른 형태의 확장성을 제공합니다. 이를 통해 사용자는 Linux 커널 내에서 직접 맞춤형 네트워킹 및 보안 정책을 정의할 수 있어 잠재적으로 효율적이고 고도로 맞춤화된 솔루션을 얻을 수 있습니다.

728x90

11. 레거시 시스템과의 통합

– 추상적인 통신 및 관리에 초점을 맞춘 Istio는 새로운 마이크로서비스를 기존 레거시 시스템과 통합하는 데 더 적합할 수 있습니다. 이는 이들 사이의 트래픽을 관리하는 통일된 방법을 제공하기 때문입니다.
– Cilium은 네트워킹 및 보안에 중점을 두고 있기 때문에 마이크로서비스 생태계가 기존 네트워크 인프라와 공존하는 환경에 더 적합할 수 있습니다.

12. 트래픽 리디렉션 및 섀도우 트래픽

– Istio는 들어오는 요청의 일부를 미러링하여 프로덕션 트래픽에 영향을 주지 않고 새로운 구성을 테스트하는 카나리아 배포 및 섀도우 트래픽과 같은 고급 트래픽 관리 기능을 제공합니다.
– Cilium은 트래픽 관리 기능을 제공하지만 주요 강점은 보안 및 하위 수준 네트워킹에 있으므로 고급 트래픽 관리보다 이러한 측면을 우선시하는 환경에 더 적합합니다.

13. 다중 클러스터 및 하이브리드 클라우드 시나리오

– Istio에는 여러 Kubernetes 클러스터 및 하이브리드 클라우드 환경 전반에 걸쳐 통신을 연결하고 관리하는 기능이 있습니다. 클러스터 간에 트래픽을 라우팅하는 Istio 게이트웨이와 같은 도구를 제공합니다.
– Cilium의 eBPF 접근 방식은 복잡한 네트워킹 시나리오에서 이점을 가질 수 있지만 다중 클러스터 배포의 경우 더 많은 수동 설정 및 구성이 필요할 수 있습니다.

14. 복잡성 및 학습 곡선

– Istio의 폭넓은 채택과 시장에서의 오랜 존재는 학습 및 문제 해결에 사용할 수 있는 리소스, 튜토리얼 및 커뮤니티 지원이 더 많다는 것을 의미합니다.
– Cilium의 보다 전문적인 초점은 eBPF의 복잡성과 커널과의 통합을 이해해야 하기 때문에 학습 곡선이 더 가파르게 될 수 있습니다.

15. 사용 사례 및 시나리오

– Istio는 풍부한 트래픽 관리, 요청 라우팅 및 고급 정책 시행이 우선순위인 시나리오에 선택되는 경우가 많습니다.
– Cilium은 강력한 보안, 고성능 네트워킹 및 네트워크 트래픽에 대한 심층적인 가시성이 필요한 환경에 일반적으로 선택됩니다.

728x90
300x250
728x90
반응형

개요

Kubernetes API 서버를 KUBECONIFG를 통한 접근을 하기 위해 단일 서버로 설정해서 접근 할 수도 있지만,

API 서버를 LB로 묶어서 접근 관리 할수있도록 하기 위한 설정이다. 이렇게 묶어서 설정 및 관리하면, 여러 관리 도구와의 결합 구성시 고가용성 유지할 수 있도록 해준다.

  • HAproxy서버에서 Kubernetes Master Node에 대해 tcp LB 설정을 해준다.

      #----------------------------------------------
      # test kube-apiserver Settings
      #----------------------------------------------
      defaults kube-tcp
          log global
          mode tcp
          maxconn 65535
          timeout connect  4s
          timeout server  15s
          timeout client  15s
          #timeout tunnel    2m
    
      # ---------------- ea-kube-master-front frontend --------------------
      frontend ea-kube-master-front
          bind 192.168.0.101:6443 name kube-tcp
          description test Kube Apiserver Front
          option tcplog
          default_backend ea-kube-dev-master-backend
      # ---------------- ea-kube-master-backend --------------------
      backend ea-kube-dev-master-backend
      mode tcp
      balance roundrobin
      option tcp-check
      option tcplog
      server sri-ea-kube-dev1 192.168.0.74:6443 check
      server sri-ea-kube-dev2 192.168.0.75:6443 check
      server sri-ea-kube-dev3 192.168.0.76:6443 check

  • bind :6443 포트, Backend 또한 6443 포트로 진행

  • Kubernetes를 컨트롤 할 서버(중앙 관리하는 MNG 서버나, ArgoCD 서버 등등) 에서 KUBECONFIG 설정 진행

      apiVersion: v1
      clusters:
      - cluster:
          certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJek1EZ3hNVEEzTURBek5sb1hEVE16TURnd09EQTNNREF6Tmxvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUV6CnJkTE01Qk10RFI1UXhjUXZ3M0RvVjlHdHRYY3duM2xla0JiaDY1QmdpVUdoa05RajJRa0FNdS9BeWZGZTVPMWoKMUo2STZ3dkl1WUhralJTS040bitoU09ReVlRZ1dBSjFLOWRsZzZpZ3hFS0NhaUpqZm9XUjlpKytheDhFTUNHVQpUM2sxVy8xVmhNOVFWY2JMaWtoSHgyVndUaXlOMWJGRzVGVjlISWNVa0daV3laS2NuRDRrU0RhajU4bkRqNVhTCktqUnprMVlkbnhYSzRuNmQxVVpvS3pyYjFsYmtmdk5sR29PSjRTS2RqcmVvMlpKc1J4dE9YR1o0aHR3dm5ndG0KMFo3VzhoWHMrcmRwOEFXQnYvY2wzMEk0OFVnZzA1U2dKbXN2ZEE1cklkdjJZc01nU2FUTnBnekwwZTgvUEE0UgpxNnZ5SWlRTnk4V2ZpY3NpZytzQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZLeXJ5dHFua2l5Uytqc09YK1AvSFRlemhBZGVNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQ0Y2VjZNczRJSGhieTFuNHp0cgpEcVJZODBjWlBRcjdsVWszUHNMaW5QSlRIT1dwTFdGVkMzYU1TYndpdWNGaUttenVOcUNLWHpwR3g1RzRwLzlhCnM3YVZNbUV3Vjl4NFp0RkNmMkVDUVhXeHkvWVppeFFrdDNpNTBrMU5wT0hmTU5NZ1BXMHhoamt1QS9DMzRXKzUKdUN0RnZUT3NyQ014ZGtuak13bElGWnZ4OHlXTjZLbUsxUWFMRGFtUVBRQk1IQVEvM2l0S2d4Y0ZNQldKQWcxUApmd2ZGZHpQWUVvOVZEbW1LQkI4RnlEYk1wNmd0MDRsVlNJbnFXUDdFcjR3MkZpNnhWYkJadHpJYVNkWFFHNkZRCkl2NTFNc2c4QVFmQ05DSkxkV1c3M3N2dTNGNklZMkVETmUxWVlvOXAvN2Z1ZDRxckNLbGZBdnBTcThFdkRjVzMKL1BjPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
          server: https://ea-kube-dev.test.co.kr:6443
        name: ea.cluster.local
      contexts:
      - context:
          cluster: ea.cluster.local
          user: default
        name: ea-kube
      current-context: ea-kube
      kind: Config
      preferences: {}
      users:
      - name: default
        user:
          token: eyJhbGciOiJSUzI1NiIsImtpZCI6IktxOERHZHdCMFFKSmkxTW9USzBGTndWalZJX2h2NDhVSTI5MEZNdDZPREkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImE4MjE0YWJmLTA0NDctNDhlMC05MjEzLTdkMjFhZDFhOTM0YSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.hOT7Q-lMb_2bV11YQ895DOde2TuWDRnjJOv1H2QYy65tfEdVjZGZmjWzOefVnihxjjhYYP5VKl4G7OfX6GQrDoR0ZW_bB1ABikePblJmCbaf4kL2GlQtrUHQeDwg9BFCXwzUzIPFBzn-6gst_cPJF3XMPMVqbjixrCUe5fJYmouDiKckLjxINNCvUB5wlAon1F20QFeiCU8X5rteJl-GYZApRbPYpuacl3Tea9tmdESBbG17kBjquTSTvwbB6GeTwgPrs4ek8Q_Hs3bIUlGEtCHXeyja8so-kKb7bWr_LThFLxVhqoIuvpi2TACOvAmdLrM-RSknD6HN6ghGCPdVUg

  • Kubernetes Context Swiching 진행 후 kubectl 명령어 수행

      kubectl get pod

  • 하지만 아래와 같이 에러가 발생한다.

      Unable to connect to the server: x509: certificate is valid for ea-kube-dev.test.co.kr

    이 경우는 보통 인증서가 잘못되었거나 아니면 해당 인증서에 대해 유효한 서버가 아니기 때문에 에러가 발생한다.

    우리는 haproxy에서 tcp로 접근하기 때문에 별도 인증서를 세팅 하지 않았기 때문에 서버에 대해 추가해야 한다.

  • 먼저 현재 인증서에 접근하는 서버가 리스트에 있는지 확인

      openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text
    

  • output에서 Alternative Name을 살펴보면 접근 하고자 하는 ea-kube-dev.test.co.kr 서버가 없는 것을 확인 할 수 있다.

       X509v3 Subject Alternative Name:
                      DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.ea-dev.cluster.local, DNS:lb-apiserver.kubernetes.local, DNS:localhost, DNS:sri-ea-kube-dev1, DNS:sri-ea-kube-dev2, DNS:sri-ea-kube-dev3, IP Address:10.233.0.1, IP Address:192.168.0.74, IP Address:127.0.0.1, IP Address:192.168.0.75, IP Address:192.168.0.76

  • 서버를 추가한 후 인증서를 재생성 해야 한다.

      # 인증서 백업
      # 별도 서비스를 내리지 않고 진행한다. 기존 파일이 있으면 반영 되지 않는다.
      mv /etc/kubernetes/pki/apiserver.key /home/hkpark/.
      mv /etc/kubernetes/pki/apiserver.crt /home/hkpark/.
    
      # Config Map 수정
      kubectl -n kube-system edit configmap kubeadm-config
    
      data:
        ClusterConfiguration: |
          apiServer:
            certSANs:
            - kubernetes
            - kubernetes.default
            - kubernetes.default.svc
            - kubernetes.default.svc.ea-dev.cluster.local
            - 10.233.0.1
            - localhost
            - 127.0.0.1
            - sri-ea-kube-dev1
            - sri-ea-kube-dev2
            - sri-ea-kube-dev3
            - lb-apiserver.kubernetes.local
            - 192.168.0.74
            - 192.168.0.75
            - 192.168.0.76
            - ea-kube-dev.test.co.kr
            - 192.168.0.101
    
      # certSANs 리스트에 서버를 추가한다. (도메인 이름 ea-kube-dev.test.co.kr, IP주소까지 해주면 좋을듯)

  • 인증서 재생성

      # 추가 하고자 하는 서버만 파라미터에 추가해서 수행하면 안되고, 현재 등록된 서버 모두 함께 --apiserver-cert-extra-sans 파라미터에 추가하자
    
      kubeadm init phase certs apiserver --apiserver-cert-extra-sans=kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.ea.cluster.local,10.233.0.1,localhost,127.0.0.1,sri-ea-kube-master1,sri-ea-kube-master2,sri-ea-kube-master3,lb-apiserver.kubernetes.local,10.0.2.64,10.0.2.65,10.0.2.66,sri-ea-kube-master1.test.co.kr,sri-ea-kube-master2.test.co.kr,sri-ea-kube-master3.test.co.kr,ea-kube.test.co.kr,10.0.2.190
    
      # 해당 인증서 생성은 Master Node 전체에서 수행 (ex: kube-master1, kube-master2, kube-master3)

  • apiserver pod 리스타트

      kubectl delete pod kube-apiserver-sri-ea-kube-dev1 kube-apiserver-sri-ea-kube-dev2 kube-apiserver-sri-ea-kube-dev3 -n kube-system

  • 정상 확인

      root # kubectl get ns
      NAME                                                STATUS   AGE
      akhq                                                Active   44d
      apigateway-893-review-develop-3zknud                Active   42d
      apigateway-893-review-feature-bl-ltxs10             Active   42d
      apigateway-893-review-v1-x-sdiidw                   Active   42d
      apigateway-893-staging                              Active   41d
      authorization-server-886-review-authorizat-fl7x7y   Active   55d
      authorization-server-886-review-develop-3zknud      Active   42d
      authorization-server-886-review-v1-x-sdiidw         Active   44d
      authorization-server-886-staging                    Active   41d
      bootadmin-server-912-staging                        Active   28d
      cattle-fleet-clusters-system                        Active   56d
      cattle-fleet-local-system                           Active   56d
      cattle-fleet-system                                 Active   56d
      cattle-global-data                                  Active   56d
      cattle-global-nt                                    Active   56d

  • Cert Renew 작업에서 다시 원복 되지 않는 것으로 확인하였다.

      /usr/local/bin/kubeadm certs renew all

728x90
300x250
728x90
반응형

kubeconfig를 통해 다른서버 접근

개요

Kubernetes를 다른 서버에서 관리해야 할 수도 있고, 다른 서드파티 관리도구에서 자기 클러스터에 올라간 컨테이너가 아니라면 다른서버에서 해당 클러스터에 접근 해야 할 수도 있다.

과거 버전에서는 Authorized Bearer Token이 기본적으로 확인 할 수 있는데, 최근 버전에서는 원하면 생성 해줘야 하는 방식으로 변경 되었다.

  1. k8s Master Node 한 곳에서 Token 생성

     kubectl apply -f - <<EOF
     apiVersion: v1
     kind: Secret
     metadata:
       name: default-token
       annotations:
         kubernetes.io/service-account.name: default
     type: kubernetes.io/service-account-token
     EOF
    

  2. Token 확인

     kubectl describe secret default-token | grep -E '^token'

  3. 접근하기 위한 SA 추가

     kubectl create clusterrolebinding default-cluster-admin --clusterrole cluster-admin --serviceaccount default:default

  4. Other Server에서 KUBECONFIG 생성

     apiVersion: v1
     clusters:
     - cluster:
         certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJek1EY3hPVEE0TURBd01Wb1hEVE16TURjeE5qQTRNREF3TVZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBT08vCmJhQXh3ZEJXVXZqaFBRbjVxTFh4RTZaTmdPWHlXSE8zbUR3OXdRYzRjQkMxaVoveVUrKzAxU2tBOTBSVXpuVEoKYlVGOXBVajdVblBVUEprVTYvY3g4dnBLa2VwSCtPOTJMZXgrTEU0UWNFWnlLTEl1MEREdDY0YmJsejI5NVBVZwp4THRqQml2OFJoeDFXM2dRaWRERURxdXpSMnBBd0lkbnhvMFZ1TWF1c1IvamloZkcxVWw1akYzWFpQTW5KaEt0CnZNR0s1NWVabDhlVlRNR3RCMDc1M1BoU3FBRTVWZ1JDWm96eVBPcllHRVdIV01MNlhXUzhtSmJQaGpaTW5OMDUKQ3dQMEh1TDF5eVRnZlpaaHNoYWowTDRYUi9zT1YwQWsyWUptcGZJLzVuUW9KV2JpSUJ5N0JkUEhUS2RYbFNEeApidVNPYmk2RjZWYVhYS3hMSzIwQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZIMHVTMlM3dWE3RVVVNzVrWXA3azVmRWRmb2pNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBS3MzbWhTNGg5TmN5SEU5Yzd3aQpBOC9qajJMRGl5c2FzcmFNRW9wSjhVOWNreklZSDBNU1JFZGl3WlhhQzc5NDBPd1dBNmltU2JpYi8ydThiSFJBCnhtcE5yWWpFdWE0MGZscmMweU9NRkpWT1dVR2pGd2RkRnlTVmRkYXhrVFZ4RGM3ZWQ2dDdvSm1KWUVHWUlJeEcKeHNLdFZHLzNoeEtwOGlOS2VpbkdXQnNBSWM5RlkyUXN3ellqcjJ5OUY3OUQxWWxOWTZ0RFdjcUFLWFZrOGQ4awp4UUdsTmpZbzI3NVVSblBKZlpOMERMSVBhZW00TEV6RzIzaGx2TjdrK1pOaWlQM3Vabzc3UVZ6b091bitncU9OCjlGRjNQdmlFdXYwRnE3ZmdKYmx6bUJyMG04dzN6cVdwT2RqQWMyK2JhTEpHWld5c0M3ODM2TUFYQlRGaTZsWWEKS2FjPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
         server: https://ea-kube-dev.test.co.kr:6443
       name: ea-dev.cluster.local
     contexts:
     - context:
         cluster: ea-dev.cluster.local
         user: system:serviceaccount:default:default
       name: ea-kube-dev
     current-context: ea-kube-dev
     kind: Config
     preferences: {}
     users:
     - name: system:serviceaccount:default:default
       user:
         token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5RRmZPQUlqRWFvaGtkM0JCRmw4RHVIY2tpbXJDWUoyd3ZlS2ZZT3RCOWMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImRlM2RjNzg4LWRiMmUtNGM1Zi1hMTg3LTZkMWNiNWMwMjM3ZSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.fJ0ixcu6z0LfYTb6IDFyB31CX5bBxWfroAlQWIZelEXAzedTUmjS3Y1eySU-y69513FM-gXZzW67UjgO3-K5VCedkKr2mrMEy6UyqUjnYlRpPFPkaFsJRxQjHATpiGRUNxo9ztKXx2oEX1P3pzQVJmo1ZMe8Ck7eqOWAj278pSGuwfih5dDAw54Znagq_T-v1Ag_8uPT59bUglMPIlMSgjvsYkIicg3BnG-d5lVJA_7Ofzyu2ns8LbewXyLEGWQphQMxP7qPnhX52gDRzArFJWYJ6wweZY9Tj4y8cREWlnRYD_XSg8fXf9OY8clzT5hqg95w1728xIu_VSVgiw1ySg

  5. user부분에 cert 부분은 삭제하고 token을 등록 한 후 user 부분에 sa 계정을 추가한다.

  6. Other Server에서 KUBECONFIG 적용

728x90
300x250
728x90
반응형

Upgrade와 Node 추가

Overview

Kubernetes 업그레이드 시 진행한 절차 및 주의사항 등 기록

  1. 과거 설치한 Kubespray가 k8s 버전을 어디까지 지원하는지 확인

     # 현재 git branch가 kubespray release 몇 버전을 바라보는지 확인
     git branch
     * (HEAD v2.23.0 위치에서 분리됨)
       master
    
     # git tag 명령어로 몇 버전까지 가지고 있는지 확인
     git tag

  2. kubespary의 github으로 가서 release와 k8s 지원되는 버전 확인 (https://github.com/kubernetes-sigs/kubespray/tree/master)

  3. 과거 다운받은 repo에 대해서 업데이트

     # 업데이트 명령
     git remote update
    
     # 현재 branch 확인
     git branch
    
     # 신규 버전의 브랜치로 checkout (전환)
     git checkout v2.23.0
    
     # 현재 branch 확인
     git branch
    
     # remote repo 확인
     git remote -v
    
     # 다운받은 repo에 대해 소스 업데이트
     git pull origin v2.23.0

  4. 파이썬 3.11로 전환

     # 기존 python3.6 버전에 대해서 다른 곳에서 사용중이다.
    
     kube-deploy # sudo update-alternatives --config python
     3 개의 프로그램이 'python'를 제공합니다.
       선택    명령
     -----------------------------------------------
     *  1           /usr/libexec/no-python
        2           /usr/bin/python3
      + 3           /usr/local/Python311/bin/python3.11
    
     # 업데이트 된 requirement 설치
     python3.11 -m pip install -r ~/kubespary/requirements.txt

  5. 업그레이드 명령 수행 전 주의사항

    ㅇ 추후 노드 추가 했을 경우(Sacle-out) 추가한 노드에 대해서도 업그레이드 전에 inventory.ini 업데이트 해주어야 함

    ㅇ 처음에 설치 할 때 설정 했던 group_vars나 addon의 설정 값이 운영하면서 변경 됐을 경우 업그레이드 전에 미리 파일에 맞춰주어야 한다. (실제 운영중인 yaml 내용과 kubespary의 내용) 안 그러면 업그레이드 후에 group_vars 값으로 되돌아 감

    ㅇ containerd의 경로를 실제 운영 중인 경로와 group_vars/containerd yaml 파일안에 경로를 일치 시켜야 함

    ㅇ 업그레이드 전 백업 용도로 Snapshot 찍어야 한다.


  6. 업그레이드 명령 수행

     # inventory에 마스터노드와 워커노드의 리스트들이 있을 것이다.
     # -e flag 로 원하는 버전에 대해 명시
    
     su - kube-deploy
    
     cd kubespary
    
     ansible-playbook upgrade-cluster.yml -b -i inventory/inventory.ini -e kube_version=v1.26.8

  7. 노드 추가 시 진행 절차

     # Inventory.ini 파일에 새로 추가된 노드 정보를 넣어준다.
    
     [all]
     master-dev1 ansible_host=1.2.3.4
     master-dev2 ansible_host=
     master-dev3 ansible_host=
     node-dev1 ansible_host=
     node-dev2 ansible_host=
     node-dev3 ansible_host=
    
    
[kube_control_plane]
master-dev1
master-dev2
master-dev3

[etcd]
master-dev1
master-dev2
master-dev3

[kube_node]
node-dev1
node-dev2
node-dev3
all-node-dev1
all-node-dev2
all-node-dev3
all-node-dev4
all-node-dev5
all-node-dev6
all-node-dev7
all-node-dev8
all-node-dev9

[add_node]
all-node-dev1
all-node-dev2
all-node-dev3
all-node-dev4
all-node-dev5
all-node-dev6
all-node-dev7
all-node-dev8
all-node-dev9

[calico_rr]
[k8s_cluster:children]
kube_control_plane
kube_node
```

---
  1. 명령어 수행
    # 추가할 노드가 많을 경우 -limit flag를 사용하여 새로 추가된 노드만 넘길 때 유용하다.
    

ansible-playbook scale.yml -b -i inventory/inventory.ini --limit add_node -e kube_version=v1.26.8
```

728x90
300x250
728x90
반응형

#1 Cluster Autoscaler 란?

Kubernetes에서 애플리케이션 수요에 맞추려면 워크로드를 실행하는 노드 수를 조정해야 할 수 있습니다. Kubernetes 사용의 가장 큰 장점 중 하나는 사용자 요구에 따라 인프라를 동적으로 확장할 수 있습니다.

(Cluster AutoScaler는 일반적으로 Cluster내 Deployment로 설치됩니다)

Cluster AutoScaler는 리소스 제약 조건으로 인해 예약할 수 없는 즉 Pending 상태의 Pod를 확인할 수 있습니다.

Cluster Autoscaler Process

문제가 발견되면 Pod 수요에 맞게 Worker Node 풀의 노드 수가 증가합니다. 또한 실행 중인 Pod가 부족한지 노드를 주기적으로 확인하고 필요에 따라 노드 수가 감소하여 WorkerNode 수를 자동으로 조정하여 노드 수를 ScaleOut 하거나 ScaleIn을 통해 효율적으로 비용 효과적인 인프라를 구성할 수 있습니다.

여러 종류의 ASG & Auto Scaling Policy

목적에 따라 다양한 ASG를 설정하고 다른 ASG Policy를 적용할 수 있습니다.

기존 Spot Instance는 On-demand 대비 80% 이상 할인률이 적용되었지만 중간에 허가 없이 종료 되지만, EKS의 Spot Interrupt Handler(DaemonSet)에 의해 정상적으로 실행 중인 Pod를 재배치 할 수 있습니다.

# Node 리소스 부족으로 Pod를 예약할 수 없는 경우

Cluster Autoscaler는 클러스터가 확장되어야 한다고 결정합니다. 확장기 인터페이스를 사용하면 다양한 포드 배치 전략을 적용할 수 있습니다. 현재 다음 전략이 지원됩니다.

  • Random – 사용 가능한 노드 그룹을 무작위로 선택합니다.
  • Most Pods – 가장 많은 노드를 예약할 수 있는 그룹을 선택합니다. 이것은 노드 그룹 간에 부하를 분산하는 데 사용할 수 있습니다.
  • Least-waste – cpu, memory가 가장 적게 남는 node group을 선택
  • price – cost가 가장 적은 node group을 선택
  • priority - 우선순위가 높은 node group을 선택

#CA는 다음 옵션에서 노드를 제거불가

  • 제한적인 PDB가 있는 포드.
  • 배포된(즉, 기본적으로 노드에서 실행되지 않거나 PDB가 없는) kube-system 네임스페이스에서 실행되는 파드.
  • 컨트롤러 객체가 지원하지 않는 포드(배포, 복제본 세트, 작업, 상태 저장 세트 등에 의해 생성되지 않음).
  • 로컬 스토리지와 함께 실행되는 포드.
  • 다양한 제약(리소스 부족, 일치하지 않는 노드 선택기 또는 선호도, 일치하는 반선호도 등)으로 인해 다른 곳으로 이동할 수 없는 실행 중인 포드.

#2 Cluster Autoscaler 설치

전제 조건

Cluster Autoscaler를 배포하려면 먼저 다음 사전 조건을 충족해야 합니다.

  • 기존 Amazon EKS 클러스터
  • 클러스터에 대한 기존 IAM OIDC 공급자입니다. 하나가 있는지 또는 생성해야 하는지 여부를 확인하려면 클러스터에 대한 IAM OIDC 공급자 생성 섹션을 참조하세요.
  • Auto Scaling 그룹 태그가 있는 노드 그룹 Cluster Autoscaler에서는 Auto Scaling 그룹에 다음과 같은 태그가 있어야 자동 검색됩니다.
    • eksctl을 사용하여 노드 그룹을 생성한 경우 이 태그는 자동으로 적용됩니다.
    • eksctl을 사용하지 않았다면 다음 태그로 Auto Scaling 그룹에 수동으로 태그를 지정해야 합니다. 자세한 내용은 Linux 인스턴스용 Amazon EC2 사용 설명서에서 Amazon EC2 리소스 태깅을 참조하세요.
    • k8s.io/cluster-autoscaler/<cluster-name> :  owned
      k8s.io/cluster-autoscaler/enabled  : TRUE

IAM 정책 및 역할 생성

  1. IAM 정책을 생성합니다.
  • 다음 콘텐츠를 cluster-autoscaler-policy.json이라는 파일에 저장합니다. 기존 노드 그룹이 eksctl을 사용하여 생성되었고 -asg-access 옵션을 사용했다면 이 정책이 이미 존재하며 2단계로 건너뛸 수 있습니다.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:DescribeAutoScalingInstances",
                "autoscaling:DescribeLaunchConfigurations",
                "autoscaling:DescribeTags",
                "autoscaling:SetDesiredCapacity",
                "autoscaling:TerminateInstanceInAutoScalingGroup",
                "ec2:DescribeLaunchTemplateVersions"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

다음 명령을 사용하여 정책을 생성합니다. policy-name의 값을 변경할 수 있습니다.

aws iam create-policy \
    --policy-name AmazonEKSClusterAutoscalerPolicy \
    --policy-document file://cluster-autoscaler-policy.json
  1. iamserviceaccount 생성

eksctl을 사용하여 Amazon EKS 클러스터를 생성한 경우 다음 명령을 실행합니다. -asg-access 옵션을 사용하여 노드 그룹을 생성한 경우 <AmazonEKSClusterAutoscalerPolicy>eksctl이 생성한 IAM 정책의 이름으로 바꿉니다. 정책 이름은 eksctl-<cluster-name>-nodegroup-ng-<xxxxxxxx>-PolicyAutoScaling과 유사합니다.

eksctl create iamserviceaccount \
  --cluster=<my-cluster> \
  --namespace=kube-system \
  --name=cluster-autoscaler \
  --attach-policy-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:policy/<AmazonEKSClusterAutoscalerPolicy> \
  --override-existing-serviceaccounts \
  --approve
  • asg-access 옵션을 사용하여 노드 그룹을 생성한 경우 eksctl이 생성하여 해당 eksctl이 노드 그룹에 대해 생성한 Amazon EKS 노드 IAM 역할에 연결한 IAM 정책을 분리합니다. Cluster Autoscaler가 제대로 작동하도록 노드 IAM 역할에서 정책을 분리합니다. 정책을 분리해도 노드의 다른 포드에는 정책의 권한이 부여되지 않습니다.
  1. 생성 확인

다음 명령어로 iamserviceaccount 의 생성을 확인하고,
AWS Management Console IAM Role ARN 을 확인합니다. (Cluster Autoscaler에서 사용)

kubectl get sa -n kube-system | grep -i cluster-autoscaler


Cluster Autoscaler 배포

  1. Cluster Autoscaler YAML 파일을 다운로드합니다.
  2. curl -o cluster-autoscaler-autodiscover.yaml https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
  3. YAML 파일을 수정하고 을 클러스터 이름으로 바꿉니다.

  1. YAML 파일을 클러스터에 적용합니다.
kubectl apply -f cluster-autoscaler-autodiscover.yaml
  1. 이전에 생성한 IAM 역할의 ARN을 사용하여 cluster-autoscaler 서비스 계정에 주석을 지정합니다. <example values>를 위에 생성한 역할의 ARN 값으로 바꿉니다.
kubectl annotate serviceaccount cluster-autoscaler \
  -n kube-system \
  eks.amazonaws.com/role-arn=arn:aws:iam::<ACCOUNT_ID>:role/<AmazonEKSClusterAutoscalerRole>

ServiceAccount - cluster-autoscaler Annotation 변경을 확인합니다.

$ kubectl describe sa -n kube-system cluster-autoscaler
========================================================
Name:                cluster-autoscaler
Namespace:           kube-system
Labels:              k8s-addon=cluster-autoscaler.addons.k8s.io
                     k8s-app=cluster-autoscaler
Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::279424994673:role/eksctl-EKS-Project-addon-iamserviceaccount-k-Role1-13DTLSGQPNNJB
Image pull secrets:  <none>
Mountable secrets:   cluster-autoscaler-token-6x8mg
Tokens:              cluster-autoscaler-token-6x8mg
Events:              <none>
  1. 다음 명령으로 배포를 패치하여 cluster-autoscaler.kubernetes.io/safe-to-evict 주석을 Cluster Autoscaler 포드에 추가합니다. CA가 자체 포드가 실행 중인 노드를 제거하는 것을 방지하기 위해 false로 설정합니다. 해당 주석의 값이 True인 경우 ClusterAutoscaler가 노드를 제거할 수 없습니다.
kubectl patch deployment cluster-autoscaler \
  -n kube-system \
  -p '{"spec":{"template":{"metadata":{"annotations":{"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"}}}}}'

  1. 다음 명령을 사용하여 Cluster Autoscaler 배포를 편집합니다.
kubectl -n kube-system edit deployment.apps/cluster-autoscaler

추가할 Flag

  • balance-similar-node-groups
  • skip-nodes-with-system-pods=false
spec:
      containers:
      - command:
        - ./cluster-autoscaler
        - --v=4
        - --stderrthreshold=info
        - --cloud-provider=aws
        - --skip-nodes-with-local-storage=false
        - --expander=least-waste
        - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<YOUR CLUSTER NAME>
        - --balance-similar-node-groups
        - --skip-nodes-with-system-pods=false

파일을 저장한 다음 종료하여 변경 사항을 적용합니다

  1. 웹 브라우저의 GitHub에서 Cluster Autoscaler [릴리스(releases)] 페이지를 열고 클러스터의 Kubernetes 메이저 및 마이너 버전과 일치하는 최신 Cluster Autoscaler 버전을 검색합니다. 예를 들어 클러스터의 Kubernetes 버전이 1.21이라면 1.21로 시작하는 최신 Cluster Autoscaler 릴리스를 검색합니다. 다음 단계에서 사용할 수 있도록 이 릴리스의 의미 체계 버전(1.21.*n*)을 적어 둡니다.

(해당 부분 유의 Version에 따라 호환성)

  1. 다음 명령을 사용하여 Cluster Autoscaler 이미지 태그를 이전 단계에서 적어 둔 버전으로 설정합니다. 1.21.n을 사용자의 고유한 값으로 교체하고 확인합니다.
kubectl set image deployment cluster-autoscaler \
  -n kube-system \
  cluster-autoscaler=k8s.gcr.io/autoscaling/cluster-autoscaler:v1.21.2

#3 동작 검증

테스트용 Nginx Deployment 생성

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 5
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 1
            memory: 1Gi
          limits:
            cpu: 2
            memory: 2Gi
EOF

주목하여야 할 부분은 spec.spec.containers.resource 부분이다.

resources:
requests:
cpu: 1
memory: 1Gi
limits:
cpu: 2
memory: 2Gi

리소스의 요청이 노드의 자원을 초과하므로 ClusterAutocaler는 AWS ASG를 통해 노드를 추가합니다.

Untitled

노드가 추가된 후 Pod의 Pending 상태가 Running으로 변경됩니다.

Untitled

# 4 참고문서

Cluster Autoscaler 배포를 최적화하기 위한 고려 사항

Cluster Autoscaler 공식 가이드

Cluster Autoscaler 에 대한 이해

728x90
300x250
728x90
반응형

AWS LoadBalancer Controller

#1. AWS LoadBalancer Controller 란?

AWS LoadBalancer Controller는 Kubernetes 클러스터의 Elastic Load Balancer(NLB or ALB)를 관리하는 데 Ingress.yaml 템플릿에 명시 된 Rule을 통해 LoadBalancer를 관리하는 컨트롤러 입니다.
(Application Load Balancer & Network Load Balancer를 모두 지원합니다)

Kubernetes Application은 외부 트래픽에 노출 되어야 하며, EKS Client는 ELB를 사용하여 태스크를 수행합니다.

Controller를 통해 External Access Allow

728x90

Controller를 통해 만들면 Ingress Annotation 값 확인하여, Controller가 LoadBalancer를 대신 만들어 주는 형태입니다.

이때 사용되는 인그레스(Ingress) 는 L7 영역의 요청을 처리합니다.

주로 클러스터 외부에서 쿠버네티스 내부로 접근할 때, 요청들을 어떻게 처리할지 정의해놓은 규칙이자 리소스 오브젝트입니다. 한마디로 외부의 요청이 내부로 접근하기 위한 관문의 역할을 하는 것이죠.

Ingress를 AWS Loadbalancer Controller를 통해 ALB로 선언

외부 요청에 대한 로드 밸런싱, TLS/SSL 인증서 처리, HTTP 경로에 대한 라우팅 등을 설정할 수 있습니다.

NLB는 LoadBalancer 유형의 Kubernetes 서비스에 대한 응답으로 생성되며, 초당 수백만 건의 요청으로 확장할 수 있는 고성능 트래픽 서비스를 제공합니다.

EC2 Loadbalancer 항목에서 추가 됨

AWS Loadbalancer Controller는 Kubernetes Ingress 객체에 대한 반응으로 Application Load Balancer를 자동으로 프로비저닝 합니다.

  • TIP과거 "AWS ALB Ingress Controller"로 알려졌으며 "AWS Load Balancer Controller"로 브랜드를 변경했습니다.

Application LoadBalancer 의 Traffic Mode Option

AWS Load Balancer Controller에서 지원하는 Traffic Mode는 Default Instance를 대상으로 Cluster 내 node를 ALB 대상으로 등록하는 방법은 ALB에 도달하는 트래픽은 NodePort로 Routing 된 다음 Pod로 프록시 하거나 IP기반으로 Pod를 IP대상으로 등록하는 방법이 있습니다.

ALB에 도달하는 트래픽은 Pod로 직접 Routing되며, 해당 트래픽 모드를 사용하기 위해 ‘ingress.yaml’파일에 Annotation을 사용하여 지정해야 합니다.

728x90

ALB가 생성되면서 각 Application 별 PATH 기반 트래픽 분기

쿠버네티스에서 서비스 타입 중, NodePort 혹은 LoadBalancer로도 외부로 노출할 수 있지만
인그레스 없이 서비스를 사용할 경우, 모든 서비스에게 라우팅 규칙 및 TLS/SSL 등의 상세한 옵션들을 적용해야합니다. 그래서 인그레스가 필요합니다.

Pod형태로 LoadBalancer Controller의 Running 상태

#2. 설치방법

1. Service Account 에 대한 IAM 역할 설정

  1. AWS Load Balancer 컨트롤러를 배포하기 전,
    클러스터에 대한 IAM OIDC(OpenID Connect identity Provider)를 생성합니다.
    쿠버네티스가 직접 관리하는 사용자 계정을 의미하는 service account에 IAM role을 연결하기 위해, 클러스터에 IAM OIDC provider가 존재해야 합니다.
eksctl utils associate-iam-oidc-provider \
    --region ${AWS_REGION} \
    --cluster CLUSTER-NAME \
    --approve

(참고) 생성한 IAM OIDC 자격 증명 공급자는 IAM 콘솔 Identity providers 메뉴 혹은 아래의 명령어를 통해 확인할 수 있습니다. 클러스터의 OIDC provider URL을 아래의 명령어들을 통해 확인합니다.

aws eks describe-cluster --name CLUSTER-NAME --query "cluster.identity.oidc.issuer" --output text

명령어 결과 나오는 값은 아래와 같은 형식을 가지고 있습니다

https://oidc.eks.ap-northeast-2.amazonaws.com/id/8A6E78112D7F1C4DC352B1B511DD13CF

위의 결과 값에서 /id/ 뒤에 있는 값을 복사한 후, 아래와 같이 명령어를 수행합니다.

aws iam list-open-id-connect-providers | grep 8A6E78112D7F1C4DC352B1B511DD13CF

결과 값이 출력되면 IAM OIDC identity provider가 클러스터에 생성이 된 것이고,
아무 값도 나타나지 않으면 생성 작업을 수행해야 합니다.


b. AWS 로드 밸런서 컨트롤러에 대한 IAM 정책 다운로드

curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.3.1/docs/install/iam_policy.json

c. AWSLoadBalancerControllerIAMPolicy라는 IAM 정책 생성

aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam-policy.json

반환된 정책 ARN을 기록해 둡니다.

d. AWS Load Balancer 컨트롤러에 대한 IAM 역할 및 ServiceAccount를 eksctl를 통해 생성하고
위 단계의 ARN을 붙여 넣습니다.

eksctl create iamserviceaccount \
--cluster=<cluster-name> \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--attach-policy-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:policy/AWSLoadBalancerControllerIAMPolicy \
--override-existing-serviceaccounts \
--region <region-code> \
--approve

또한, 아래의 명령어를 통해, service account가 생성된 것을 확인할 수 있습니다.

kubectl get sa aws-load-balancer-controller -n kube-system -o yaml

2-1 클러스터에 컨트롤러 추가 (helm 사용)

  1. helm에 EKS 차트 리포지토리 추가
helm repo add eks https://aws.github.io/eks-charts

b. helm upgrade 차트를 통해 업그레이드 한다면 TargetGroupBinding CRD를 설치합니다

kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"

c. 서비스 계정에 IAM 역할을 사용하는 helm 차트를 설치합니다.

helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=<cluster-name> --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller

helm을 사용하여 load-balancer-controller를 생성할 경우, 기본값으로 Replicas: 2 desired 이며
두 개의 파드가 작동합니다.

2-2 클러스터에 컨트롤러 추가 (Yaml Manifest 사용)

(Fargate에서 컨트롤러를 실행하려면 cert-manager에 의존하지 않는 Helm 차트를 사용하세요.)

  1. 먼저, 인증서 구성을 웹훅에 삽입할 수 있도록 cert-manager를 설치합니다. Cert-manager는 쿠버네티스 클러스터내에서 TLS인증서를 자동으로 프로비저닝 및 관리하는 오픈 소스입니다.
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml

b. Load balancer controller YAML 다운로드합니다.

wget https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.3.1/v2_3_1_full.yaml

c. 텍스트 편집기를 통해 저장된 YAML 파일을 편집합니다.

Deployment.spec.args의 --cluster-name의 EKS클러스터 이름을 수정합니다.

apiVersion: apps/v1
kind: Deployment
. . .
name: aws-load-balancer-controller
namespace: kube-system
spec:
    . . .
    template:
        spec:
            containers:
                - args:
                    - --cluster-name=<INSERT_CLUSTER_NAME> # 생성한 클러스터 이름을 입력

d. 이전에 ServiceAccount를 생성하였으므로 해당 섹션을 전부 삭제합니다.
이렇게 하면 eksctl에서 생성한 iamserviceaccount가 유지됩니다.

apiVersion: v1
kind: ServiceAccount

e. YAML 파일 적용

kubectl apply -f v2_3_1_full.yaml

3. 검증

전제 조건

ALB에는 가용 영역에 걸쳐 최소 2개의 서브넷이 필요하고 NLB에는 1개의 서브넷이 필요합니다.


Subnet Auto Discovery

자동 검색이 작동하려면 서브넷에 적절하게 태그를 지정해야 합니다.
구성한 서브넷에 다음 태그를 포함해야 합니다.

공통 태그

  • kubernetes.io/cluster/$CLUSTER_NAME프라이빗 서브넷
  • $CLUSTER_NAME 지정한 클러스터 이름과 동일하게 입력합니다.
    AWS LoadBalancer Controller 버전 v2.1.1 이하에서는 퍼블릭 서브넷과 프라이빗 서브넷 모두 다음과 같이 클러스터 이름으로 태그를 지정해야 합니다.
  • kubernetes.io/role/internal-elb1퍼블릭 서브넷
  • 내부 로드 밸런서의 경우 1 또는 빈 태그 값 으로 설정해야 합니다 .
  • kubernetes.io/role/elb1
  • 인터넷 연결 로드 밸런서의 경우 1 또는 빈 태그 값 으로 설정해야 합니다 .

EKS-Project 이름의 클러스터에 대한 올바른 태그가 있는 퍼블릭 서브넷의 예는 다음과 같습니다.

Subnet Discovery에 대한 자세한 내용은 아래 링크에서 확인 하실 수 있습니다.

https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.3/deploy/subnet_discovery/


  1. 모든 echoserver 리소스(네임스페이스, 서비스, 배포) 배포
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.0.0/docs/examples/echoservice/echoserver-namespace.yaml &&\
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.0.0/docs/examples/echoservice/echoserver-service.yaml &&\
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.0.0/docs/examples/echoservice/echoserver-deployment.yaml

각 yaml 파일의 내용은 다음과 같습니다.

echoserver-namespace.yaml
---
apiVersion: v1
kind: Namespace
metadata:
  name: echoserver

---
echoserver-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: echoserver
  namespace: echoserver
spec:
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
  type: NodePort
  selector:
    app: echoserver

---
echoserver-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoserver
  namespace: echoserver
spec:
  selector:
    matchLabels:
      app: echoserver
  replicas: 1
  template:
    metadata:
      labels:
        app: echoserver
    spec:
      containers:
      - image: gcr.io/google_containers/echoserver:1.4
        imagePullPolicy: Always
        name: echoserver
        ports:
        - containerPort: 8080

b. echoserver Ingress 매니페스트를 로컬로 다운로드합니다.

wget https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.0.0/docs/examples/echoservice/echoserver-ingress.yaml

c. echoserver-ingress.yaml 분석

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
    name: echoserver
    namespace: echoserver
    annotations:
        alb.ingress.kubernetes.io/scheme: internet-facing # internal 시 내부 로드 밸런서
        alb.ingress.kubernetes.io/subnets: subnet-05e1c98ed0f5b109e,subnet-07f5bb81f661df61b 두 개 이상의 서브넷을 포함 하도록 Annotation을 편집합니다 .
        alb.ingress.kubernetes.io/tags: Environment=dev,Team=test # LoadBalancer - Target Group에 태그 추가
spec:
    rules:
    - host: echoserver.chnam.link  # 외부 DNS를 사용하려면 해당 필드를 Route 53에서 소유한 도메인으로 변경
        http:
        paths:

## 아래 부분은 경로 설정에 대한 예시입니다. 현재는 입력하지 않습니다.
          - path: /503
            backend:
              serviceName: response-503
              servicePort: use-annotation
          - path: /eks
            backend:
              serviceName: redirect-to-eks
              servicePort: use-annotation
          - path: /path1
            backend:
              serviceName: forward-single-tg
              servicePort: use-annotation
          - path: /path2
            backend:
              serviceName: forward-multiple-tg
              servicePort: use-annotation

ngress annotations에 대한 관련 정보는 아래에서 확인하실 수 있습니다.

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

d. kubectl apply -f echoserver-ingress.yaml 명령어를 통해 Ingress 적용

e. Ingress Event 확인 kubectl describe ing -n echoserver echoserver

Name:             echoserver
Labels:           <none>
Namespace:        echoserver
Address:          k8s-echoserv-echoserv-d6f0e2ff88-151887753.ap-northeast-2.elb.amazonaws.com
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host                   Path  Backends
  ----                   ----  --------
  echoserver.chnam.link
                         /   echoserver:80 (10.0.1.218:8080)
Annotations:             alb.ingress.kubernetes.io/scheme: internet-facing
                         alb.ingress.kubernetes.io/subnets: subnet-060ac246c10fc60bb,subnet-088233ffcd75a6151
                         alb.ingress.kubernetes.io/tags: Environment=dev,Team=test
                         kubernetes.io/ingress.class: alb
Events:
  Type    Reason                  Age                From     Message
  ----    ------                  ----               ----     -------
  Normal  SuccessfullyReconciled  26m (x2 over 35m)  ingress  Successfully reconciled

f. 해당 호스트 도메인에 ingress 작동이 잘 수행되었는지 확인합니다.

검증 과정은 아래의 링크를 참조하였습니다.

https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.3/examples/echo_server/#deploy-ingress-for-echoserver

https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.3/examples/echo_server/#deploy-ingress-for-echoserver

AWS LoadBalancer Controller-Amazon EKS

NLB Target Group Binding 추가

728x90
300x250
728x90
반응형
카오스 엔지니어링은 특정 시스템에 대한 가설(hypothesis)을 만들고 부하(stress)를 주입한 후 결과를 관찰하는 엔지니어링의 한 분야입니다.
이후 관찰된 결과를 바탕으로 시스템의 성능을 향상시킵니다. 그렇기 때문에 이 과정은 아래 그림처럼 끊임 없이 순환됩니다.
계속해서 새로운 가설을 만들고 이를 통해 시스템을 발전시킵니다. 카오스 엔지니어링은 우리 시스템이 복원력(resilience) 있고 성능이 좋은 시스템을 구축할 수 있게 해줍니다.
728x90

1. Tool

1. 카오스 몽키 (for AWS)

-임의의 인스턴스나 Spring Boot에 장애를 일어킴
-카오스 몽키 종류
-Latency monkey: RESTful 클라이언트-서버 통신 계층에 인공적인 지연 유발
-Conformity monkey: 최상의 조건이 아닌 인스턴스를 찾아 종료 (:자동 스케이링 그룹에 속하지 않은 인스턴스를 찾아 재시작)
-Doctor monkey: 인스턴스들의 상태를 점검하고 CPU 부하율 등의 정보들을 모니터링하여 불안정한 인스턴스를 탐지하여 제거
-Janitoy monkey: 클라우드 환경이 잡음으나 낭비 없이 작동하도록 보장, 사용되지 않는 리소스들을 찾아 제거
-Security monkey:  Conformity monkey의 확장으로 보안에 위배되거나 최약점을 찾고 공격하는 인스턴스 종료
-10-18 monkey: 다양한 언어와 문자를 사용하여 여러 지역에서 고객에서 서비스를 제공할 경우 설정 및 런타임 문제 감지
-monkey: AWS의 가용성 영역을 전체적으로 중단

 

2. LitmusChaos 또는 Chaos Mesh (for Kubernetes)

-리트머스는 크게 위와 같이 구성됨
-Chaos Control Plane: 카오스 센터이며 중앙 집중식 카오스 관리 도구 (Workflow정의, 예약 및 시각화)
-Chaos Excution Plane: 카오스 에이전트와 정의된 대상 Kubernetes 환경내에서 실험을 실행 및 모니터링하는 오퍼레이터로 구성됨
728x90

3. Use Case

-Chaos Tests데브옵스 주기의 어느 단계에서나 수행 가능, CI 파이프라인부터 프로덕션까지 다양합니다.
-개발 파이프라인에서는 개발 중인 애플리케이션에 특정한 카오스 Tests를 사용할 수 있습니다.
-운영 또는 프로덕션으로 이동함에 따라 복원력을 확보해야 하는 많은 실패 시나리오가 예상되므로 카오스 테스트의 수가 크게 증가합니다.
-일반적인 사용 사례로는 CI 파이프라인에서의 장애 또는 스테이징 및 프로덕션과 운영 환경, Kubernetes 업그레이드 인증, 업그레이드 후 서비스 검증 등이 있습니다.
-개발자용: 단위 테스트 또는 통합 테스트의 확장으로 애플리케이션 개발 중에 카오스 수행
-SRE: 애플리케이션 및/또는 주변 인프라에 대한 카오스 실험을 계획하고 예약합니다. 이로써 시스템의 약점을 식별하고 복원력을 높입니다.

 

4. 이점
-일반적으로 개발자와 경영진 모두 카오스 도입에 대해 많은 거부감을 느낀다고 합니다.
-카오스 엔지니어링을 실행할 때는 소규모 Chaos Test로 시작하여 개발자와 경영진에게 이점을 보여주면 초기에 신뢰를 얻을 수 있습니다.
-시간이 지남에 따라 테스트 횟수와 관련 복원력도 증가할 것입니다.
-카오스 엔지니어링은 관행입니다.
-위에서 살펴본 바와 같이, 시간이 지남에 따라 SRE의 신뢰도와, IT 투자 기회도 높아지며 이 프로세스를 통해 복원력 지표도 향상됩니다.
728x90
300x250
728x90
반응형

Kubernetes는 복잡한 도구입니다. 대부분의 복잡한 도구의 경우와 마찬가지로 Kubernetes에서 최적의 성능을 얻는 것은 까다로울 수 있습니다. 대부분의 Kubernetes 배포는 성능을 최대화하기 위해 미세 조정되지 않습니다(그렇더라도 사용자 환경에 최적인 방식으로 조정되지 않을 가능성이 높습니다).

이러한 현실을 염두에 두고 Kubernetes 성능 최적화에 대한 팁을 계속 읽으십시오. 이제 막 클러스터 구축을 시작했거나 이미 프로덕션 환경을 실행하고 있는지 여부에 관계없이 Kubernetes 성능을 개선하기 위해 수행할 수 있는 간단한 작업에 중점을 둘 것입니다.

 

 

1새 작업자 노드를 생성하기 전에 기존 작업자 노드에 리소스 추가

아마도 Kubernetes 성능을 개선하는 가장 확실한 방법은 클러스터에 더 많은 작업자 노드를 추가하는 것입니다. 작업자가 많을수록 더 많은 리소스를 사용하여 워크로드를 강화할 수 있습니다. 또한 노드가 많을수록 많은 노드가 실패하여 워크로드가 실패할 가능성이 줄어들기 때문에 가용성이 향상됩니다.

그러나 작업자 노드를 최대한 활용하려는 경우 새 노드를 생성하는 대신 기존 작업자 노드에 메모리 및 CPU 리소스를 추가하여 더 많은 비용을 절감할 수 있습니다. 즉, 각각 8GB의 메모리가 있는 40개의 노드보다 각각 16GB의 메모리가 있는 20개의 노드를 갖는 것이 좋습니다.

이것은 두 가지 이유로 사실입니다. 첫째, 호스트 운영 체제로 인해 각 노드에 일정량의 오버헤드가 있습니다. 노드 수가 적다는 것은 그런 식으로 낭비되는 리소스가 적다는 것을 의미합니다. 둘째, 노드가 많을수록 스케줄러, kube-proxy 및 기타 구성 요소가 모든 것을 추적하기 위해 작동해야 합니다.

당연히 가용성을 고려해야 하며 가용성 목표를 충족하기 위한 최소한의 작업자 노드가 있는지 확인해야 합니다. 그러나 이 임계값을 넘으면 전체 노드 수를 최대화하려고 하기보다 각 노드에 할당된 리소스를 가능한 한 많이 할당하여 전반적인 성능 효율성을 높일 수 있습니다. 극단적으로 가지 마십시오(예를 들어 단일 노드에서 24테라바이트의 메모리를 원하지 않을 것입니다). 노드가 실패할 경우 해당 리소스를 잃을 위험이 있기 때문입니다.

물론 노드의 리소스 할당을 결정하는 데 많은 유연성이 있을 수도 있고 없을 수도 있습니다. 클라우드에서 실행되는 가상 머신인 경우 원하는 만큼 리소스를 할당할 수 있습니다. 온프레미스 가상 머신이나 물리적 서버라면 더 까다롭습니다.

728x90

2여러 마스터 노드 사용

Kubernetes 클러스터에서 여러 마스터를 사용하는 주된 이유는 고가용성을 달성하기 위해서입니다. 마스터가 많을수록 마스터가 모두 실패하여 클러스터가 중단될 가능성이 줄어듭니다.

그러나 더 많은 마스터를 추가하면 마스터에서 호스팅되는 필수 Kubernetes 구성 요소(예: 스케줄러, API 서버 및 기타)에 더 많은 호스팅 리소스를 제공하므로 성능 이점도 제공됩니다. Kubernetes는 모든 마스터 노드의 집합적 리소스를 사용하여 이러한 구성 요소를 구동합니다.

따라서 마스터(또는 2개 또는 4개)를 추가하는 것은 Kubernetes 클러스터의 성능을 향상시키는 쉽고 좋은 방법입니다.

3작업자 노드 점수 제한 설정

Kubernetes 스케줄러가 수행하는 작업의 일부는 작업자 노드를 "점수"하는 것입니다. 즉, 워크로드를 처리하는 데 적합한 작업자 노드를 결정합니다. 수십 개 이상의 작업자 노드가 있는 클러스터에서 스케줄러는 결국 모든 작업자 노드를 확인하는 데 시간을 낭비할 수 있습니다.

이러한 비효율성을 방지하기 위해 percentOfNodesToScore 매개변수를 100보다 낮은 백분율로 설정할 수 있습니다. 그러면 스케줄러는 지정한 노드의 백분율만 확인합니다.

4리소스 할당량 설정

특히 여러 팀이 공유하는 대규모 클러스터에서 Kubernetes 성능을 향상시키는 간단하지만 매우 효과적인 방법은 리소스 할당량을 설정하는 것입니다. 리소스 할당량은 지정된 네임스페이스에서 사용할 수 있는 CPU, 메모리 및 스토리지 리소스의 양에 대한 제한을 설정합니다.

따라서 클러스터를 네임스페이스로 나누고 각 팀에 다른 네임스페이스를 제공하고 각 네임스페이스에 대한 리소스 할당량을 설정하면 모든 워크로드가 리소스를 공평하게 공유하도록 하는 데 도움이 됩니다.

리소스 할당량은 그 자체로 성능 최적화가 아닙니다. 그들은 시끄러운 이웃 문제에 대한 해결책에 가깝습니다. 그러나 각 네임스페이스가 작업을 적절하게 수행하는 데 필요한 리소스를 가지고 있는지 확인하는 데 도움이 됩니다.

728x90

5제한 범위 설정

워크로드에서 사용하는 리소스를 제한하고 싶지만 해당 워크로드가 다른 워크로드와 동일한 네임스페이스에서 실행되는 경우에는 어떻게 해야 합니까? 이것이 한계 범위가 하는 일입니다.

리소스 할당량은 각 네임스페이스가 소비할 수 있는 리소스 수에 대한 제한을 설정하는 반면 제한 범위는 포드당 또는 컨테이너당 기준으로 동일한 작업을 수행합니다.

단순화를 위해 대부분의 경우 모범 사례는 네임스페이스 및 리소스 할당량을 사용하여 워크로드를 분할하는 것입니다. 그러나 이러한 접근 방식이 실용적이지 않은 경우 제한 범위를 사용하면 개별 포드 또는 컨테이너가 원하는 대로 수행하는 데 필요한 리소스를 갖도록 보장할 수 있습니다.

6엔드포인트 슬라이스 설정

엔드포인트 슬라이스는 서비스 및 포트 조합을 기반으로 네트워크 엔드포인트를 함께 그룹화할 수 있는 거의 논의되지 않은 Kubernetes 기능입니다. 설정되면 kube-proxy는 트래픽 라우팅 방법을 결정할 때 이를 참조합니다.

엔드포인트가 많은 환경에서 엔드포인트 슬라이스는 클러스터 내에서 트래픽을 라우팅하기 위해 kube-proxy가 수행해야 하는 작업량을 줄임으로써 성능을 향상시킬 수 있습니다.

7미니멀리스트 호스트 OS 사용

마지막으로 기본적이지만 효과적인 팁입니다. Kubernetes 클러스터를 호스팅하는 운영 체제가 가능한 한 최소인지 확인하십시오. Kubernetes를 실행하는 데 반드시 필요하지 않은 추가 구성 요소는 리소스 낭비로 이어져 클러스터의 성능을 저하시킵니다.

사용하는 Kubernetes 배포에 따라 호스트 OS를 선택할 수도 있고 그렇지 않을 수도 있습니다. 하지만 그렇다면 설치 공간이 최소인 Linux 배포판을 선택하십시오.

결론

Kubernetes는 많은 작업을 자동으로 수행하도록 설계되었습니다. 그러나 자체 성능 관리를 자동화하지는 않습니다. Kubernetes 전용 인프라에서 최고의 성능을 얻으려면 인프라를 설계하는 방법과 특정 Kubernetes 구성 요소를 구성하는 방법에 대해 현명해야 합니다.

728x90
300x250

+ Recent posts