728x90
반응형
###Overview

브라우저에서 많이 사용되는 HTTPS의 경우에도 공식적으로 발급한 인증키를 이용하여 데이터를 암호화하여 전달 하도록 구성되어 있다.

위와 같은 방식으로 데이터를 전달하면 중간에 해커 등이 데이터를 가로채도(MITM 공격) 데이터를 복호화 할수가 없게 된다. (서버만이 이를 해석할 수 있는 Private Key를 가지므로)

하지만 웹브라우저에서 Istio Ingress Gateway 까지는 안전하게 데이터가 보호되지만, k8s 클러스터 내부에서는 통신 같은 경우 변조되거나 손실 될 수도 있다.

그러나 수많은 마이크로서비스 간 통신에 https 적용하는 것은 복잡하고 많은 시간/자원 소요, 상대적으로 느린 처리속도가 발생한다.

특히 클라우드 같은 경우 하나의 서버 또는 하나의 존으로 구성되지 않으며 다수의 노드들 간의 연결로 구성되는 복잡한 형태로 되어 있다. (ap-northeast-2a, ap-northeast-2b 등등)

Istio를 이용해서 mTLS(Mutual TLS)를 적용하게 되면, TLS가 아닌 모든 통신은 차단하여 불법적인 접근을 막아준다.

Pod 내부의 통신은 localhost에서 동작한다 즉 네트워크 카드를 통하지 않으므로 외부에서 접근 자체가 불가능 따라서 Pod 내부적으로 Container 간에는 http 사용 가능하다

다른 Pod 끼리의 통신은 Istio-proxy container가 대신하여 통신하는데 이때 proxy container 끼리는 TLS 통신으로 안전하게 통신한다.

istio 1.5부터는 자동으로 proxy 간 통신에 TLS가 적용되었다. kiali를 통해 확인 가능

해당 자물쇠 모양이 TLS 적용 되었다는 것을 뜻한다.

  1. Permissive mTLS

위와 같이 Istio가 제어할 수 없는 Pod에서 Http 전송하는 경우가 있다면 Permissive mTLS 이용 해야 한다.

서비스의 http 접근을 위해 노드포트로 개방

apiVersion: v1
kind: Service
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"fleetman-position-tracker","namespace":"default"},"spec":{"ports":[{"name":"http","port":8080}],"selector":{"app":"position-tracker"},"type":"ClusterIP"}}
  creationTimestamp: "2023-11-13T05:17:01Z"
  name: fleetman-position-tracker
  namespace: default
  resourceVersion: "5307171"
  uid: 1e1771d6-8714-4f3e-bace-828a5e052d19
spec:
  clusterIP: 10.233.37.37
  clusterIPs:
  - 10.233.37.37
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: http
    nodePort: 32000
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: position-tracker
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

fleetman-position-tracker 서비스의 32000포트를 노드포트로 열었다.

root # kubectl get pod -o wide
NAME                                           READY   STATUS    RESTARTS      AGE   IP               NODE                NOMINATED NODE   READINESS GATES
api-gateway-57b8dc6b6d-trdhf                   2/2     Running   0             15m   10.233.125.173   mng-kube-dev1   <none>           <none>
details-v1-7745b6fcf4-scgmn                    2/2     Running   2 (13d ago)   13d   10.233.119.77    mng-kube-dev3   <none>           <none>
dnsutils                                       2/2     Running   2 (13d ago)   13d   10.233.119.87    mng-kube-dev3   <none>           <none>
position-simulator-d76977c-vttbj               2/2     Running   0             15m   10.233.94.107    mng-kube-dev2   <none>           <none>
position-tracker-5fc869955f-xmvzq              2/2     Running   0             15m   10.233.125.174   mng-kube-dev1   <none>           <none>
productpage-v1-6f89b6c557-27cpp                2/2     Running   2 (13d ago)   13d   10.233.119.75    mng-kube-dev3   <none>           <none>
ratings-v1-77bdbf89bb-j84zk                    2/2     Running   2 (13d ago)   13d   10.233.119.78    mng-kube-dev3   <none>           <none>
reviews-v1-667b5cc65d-v6bgm                    2/2     Running   2 (13d ago)   13d   10.233.119.79    mng-kube-dev3   <none>           <none>
reviews-v2-6f76498fc8-bq6lq                    2/2     Running   2 (13d ago)   13d   10.233.119.88    mng-kube-dev3   <none>           <none>
reviews-v3-5d8667cc66-kwmk4                    2/2     Running   2 (13d ago)   13d   10.233.119.81    mng-kube-dev3   <none>           <none>
staff-service-549787d74-g9qzp                  2/2     Running   0             15m   10.233.94.106    mng-kube-dev2   <none>           <none>
staff-service-risky-version-67fc49944c-lrlcs   2/2     Running   0             15m   10.233.119.118   mng-kube-dev3   <none>           <none>
vehicle-telemetry-5b8cb65d5-jlnkz              2/2     Running   0             15m   10.233.119.114   mng-kube-dev3   <none>           <none>
webapp-5c79796df5-6cc7c                        2/2     Running   0             15m   10.233.119.119   mng-kube-dev3   <none>           <none>

fleetman-position-tracker 서비스의 파드가 어느 노드에 떳는지 확인

position-tracker-5fc869955f-xmvzq              2/2     Running   0             15m   10.233.125.174   mng-kube-dev1   <none>           <none> 

sri-mng-kube-dev1에 떠있는 것을 확인 했다.

root # curl http://192.168.2.124:32000/vehicles/
[{"name":"Huddersfield Truck A","lat":53.6099460,"lng":-1.8139280,"timestamp":"2023-11-13T05:31:22.565+0000","speed":24.7517309806046603544},{"name":"London Riverside","lat":51.5112820,"lng":-0.1003120,"timestamp":"2023-11-13T05:31:22.139+0000","speed":17.2594644682047764384},{"name":"City Truck","lat":53.37262733839452266693115234375,"lng":-1.484639234840869903564453125,"timestamp":"2023-11-13T05:31:33.279+0000","speed":7.4770534017002185024},{"name":"Village Truck","lat":53.2844950,"lng":-1.6663290,"timestamp":"2023-11-13T05:31:09.810+0000","speed":25.3164561038853680528},{"name":"Huddersfield Truck B","lat":53.6204240,"lng":-1.8052050,"timestamp":"2023-11-13T05:31:34.307+0000","speed":6.02688378286800533520}]

curl로 노드포트로 호출 해보면 호출이 된다.

kiali에서도보면 fleetman-position-tracker로 호출 되지만 자물쇠가 없는 것으로 보인다.

  1. Strict mTLS

이 옵션은 어떤 외부의 접속이라도 TLS가 적용 되지 않으면 접속을 완전히 차단하는 방식이다.

PeerAuthentication 이라는 리소스를 사용하여 모드를 설정한다.

apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
metadata:
  name: "default"
  namespace: "istio-system"
spec:
  mtls:
    mode: STRICT

확인

root # kubectl get peerauthentication -A
NAMESPACE      NAME      MODE     AGE
istio-system   default   STRICT   94s

잘 생성 되었고 curl 호출 해보면

root # curl http://192.168.2.124:32000/vehicles/
curl: (56) Recv failure: Connection reset by peer



root # curl https://192.168.2.124:32000/vehicles/
curl: (60) SSL certificate problem: self signed certificate in certificate chain
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

호출이 막힌 것으로 보인다.

728x90
300x250

'IT > Istio' 카테고리의 다른 글

Istio Traffic Management 트래픽 통제하기  (0) 2023.11.10
서킷 브레이킹  (0) 2023.11.10
728x90
반응형

Overview

Istio를 통해 Traffic을 제어 할 수 있다.

다음은 Istio를 통해서도 Canary를 구현 할 수 있다. Canary 또한 Traffic을 통제하여 신버전으로 Traffic을 적게 가져가는 식으로 하면 된다.

Weighted 기반 라우팅

  1. Demo Application 구성

     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: position-simulator
     spec:
       selector:
         matchLabels:
           app: position-simulator
       replicas: 1
       template:
         metadata:
           labels:
             app: position-simulator
         spec:
           containers:
           - name: position-simulator
             image: richardchesterwood/istio-fleetman-position-simulator:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             command: ["java","-Xmx50m","-jar","webapp.jar"]
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: position-tracker
     spec:
       selector:
         matchLabels:
           app: position-tracker
       replicas: 1
       template:
         metadata:
           labels:
             app: position-tracker
         spec:
           containers:
           - name: position-tracker
             image: richardchesterwood/istio-fleetman-position-tracker:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             command: ["java","-Xmx50m","-jar","webapp.jar"]
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: api-gateway
     spec:
       selector:
         matchLabels:
           app: api-gateway
       replicas: 1
       template:
         metadata:
           labels:
             app: api-gateway
         spec:
           containers:
           - name: api-gateway
             image: richardchesterwood/istio-fleetman-api-gateway:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             command: ["java","-Xmx50m","-jar","webapp.jar"]
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: webapp
     spec:
       selector:
         matchLabels:
           app: webapp
       replicas: 1
       template:
         metadata:
           labels:
             app: webapp
         spec:
           containers:
           - name: webapp
             image: richardchesterwood/istio-fleetman-webapp-angular:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: vehicle-telemetry
     spec:
       selector:
         matchLabels:
           app: vehicle-telemetry
       replicas: 1
       template:
         metadata:
           labels:
             app: vehicle-telemetry
         spec:
           containers:
           - name: vehicle-telemtry
             image: richardchesterwood/istio-fleetman-vehicle-telemetry:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: staff-service
     spec:
       selector:
         matchLabels:
           app: staff-service
       replicas: 1
       template:
         metadata:
           labels:
             app: staff-service
             version: safe      # 구버전에 대한 Application Label이다. Safe가 기존 운영하던 Stable한 버전이라고 친다.
         spec:
           containers:
           - image: richardchesterwood/istio-fleetman-staff-service:6-placeholder
             name: staff-service
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
             ports:
             - containerPort: 8080
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: staff-service-risky-version
     spec:
       selector:
         matchLabels:
           app: staff-service
       replicas: 1
       template:
         metadata:
           labels:
             app: staff-service
             version: risky       # 신버전에 대한 Application에 대한 Deploy이다. 신버전에 대해서 version: risky 라는 Label로 지정하였다.
         spec:
           containers:
           - name: staff-service
             image: richardchesterwood/istio-fleetman-staff-service:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
             ports:
             - containerPort: 8080
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-webapp
     spec:
       selector:
         app: webapp
       ports:
         - appProtocol: http
           name: http
           port: 80
           protocol: TCP
           targetPort: 80
       type: ClusterIP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-position-tracker
     spec:
       selector:
         app: position-tracker
       ports:
         - name: http
           port: 8080
       type: ClusterIP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-api-gateway
     spec:
       selector:
         app: api-gateway
       ports:
         - name: http
           port: 8080
       type: ClusterIP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-vehicle-telemetry
     spec:
       selector:
         app: vehicle-telemetry
       ports:
         - name: http
           port: 8080
       type: ClusterIP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-staff-service
     spec:
       selector:
         app: staff-service
       ports:
         - name: http
           port: 8080
       type: ClusterIP
    

    1. Demo Application 웹 접속을 위한 GW, VS 구성

      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
      name: fleetman-gw
      spec:
      selector:
       istio: ingressgateway
      servers:
      - hosts:
       - "kiali-mng-dev.test.co.kr"
       port:
         number: 80
         name: http
         protocol: HTTP

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
    name: fleetman-vs
    spec:
    hosts:

    • "kiali-mng-dev.test.co.kr"
      gateways:

    • fleetman-gw
      http:

    • match:

      • port: 80
        route:
      • destination:
        host: fleetman-webapp
        port:
        number: 80

      Kiali 에서보면 구조는 아래와 같다.

      staff-service에 보면 Risky 버전과 Safe 버전 2가지가 공존하는 것을 볼 수 있다.

      1. Demo Web 접속
      • 해당 웹어플리케이션은 배송 추적 시스템이다.
  2. 신버전과 구버전간의 트래픽 비율 조정

     kind: VirtualService
     apiVersion: networking.istio.io/v1alpha3
     metadata:
       name: canary-vs  # 이 부분은 그냥 이름 넣어주면 된다.
       namespace: default
     spec:
       hosts:
         - fleetman-staff-service.default.svc.cluster.local  # 라우팅 규칙을 적용할 서비스 DNS 이름 입니다. (내부 용 FQDN으로 처리)
       http:
         - route:
             - destination:
                 host: fleetman-staff-service.default.svc.cluster.local # 타겟 DNS 이름
                 subset: safe-group  # Destination Rule의 이름
               weight: 90   # 비율 지정
             - destination:
                 host: fleetman-staff-service.default.svc.cluster.local # 타겟 DNS 이름
                 subset: risky-group  # Destination Rule의 이름
               weight: 10
     ---
     kind: DestinationRule       # 각 Subset에 포함될 파드 정의
     apiVersion: networking.istio.io/v1alpha3
     metadata:
       name: canary-dr
       namespace: default
     spec:
       host: fleetman-staff-service # 서비스
       subsets:
         - labels:   # Selector
             version: safe # 파드를 Label과 함께 찾는다.
           name: safe-group
         - labels:
             version: risky
           name: risky-group

  3. 확인

  4. 실제 City Truck의 운전자 사진이 Risk 버전에서는 제대로 표시가 안되는 것을 확인

  5. 브라우저에서는 Caching 때문에 제대로 확인이 안될 수 있는데 curl로 확인 해보자

     root # while true; do curl http://kiali-mng-dev.test.co.kr/api/vehicles/driver/City%20Truck; echo; sleep 0.5; done
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
     {"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}

    "1.jpg" 가 10% 확율 치고는 자주 나온거 같긴하지만 얼추 그래도 맞는 것 같다.

Session Affinity

Istio에서 Consistent Hash 라는 것을 이용하여 Session을 유지 해주는 기능을 제공한다.

LB에서 Hash 알고리즘을 이용하여 Client로부터 받은 데이터를 Hashing 한 후 데이터를 파드에 전송하는데 Hash 값을 이용하여 Sticky Session을 유지한다

Session 관리로 여러가지 방식을 지원한다. Header, Cookie, SourceIP 등

여기서는 SourceIP를 통해 테스트 진행 해 보았다.

위에 테스트한 데모 어플리케이션이 Version에 따라 safe와 risky 버전을 나눠서 90:10 비율로 처리 했는데, Consistent Hash를 사용하여 처음 접근 했던 세션이 그대로 유지 되는지 테스트

kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: session-vs
  namespace: default
spec:
  hosts:
    - fleetman-staff-service.default.svc.cluster.local
  http:
    - route:
        - destination:
            host: fleetman-staff-service.default.svc.cluster.local
            subset: all-staff-service-pods
          # weight: weight 옵션을 같이 사용 할 수 없다.
---
kind: DestinationRule
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: session-dr
  namespace: default
spec:
  host: fleetman-staff-service
  trafficPolicy:
    loadBalancer:
      consistentHash:
        useSourceIp: true   # useSourceIp: true로 설정하면 접속한 SourceIP으로 세션을 유지 해준다.
  subsets:
    - labels:
        app: staff-service
      name: all-staff-service-pods

처음 접속 했을 때 Stable 버전으로 접속되서 다른 Truck들도 사진이 잘 나온다. 반면에 Risky 버전으로 접속이 됐으면 계속 사진이 없는 Truck만 조회 된다.

Prefix기반 라우팅

  1. Demo Application 구성

     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: position-simulator
     spec:
       selector:
         matchLabels:
           app: position-simulator
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: position-simulator
         spec:
           containers:
           - name: position-simulator
             image: richardchesterwood/istio-fleetman-position-simulator:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             command: ["java","-Xmx50m","-jar","webapp.jar"]
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: position-tracker
     spec:
       selector:
         matchLabels:
           app: position-tracker
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: position-tracker
         spec:
           containers:
           - name: position-tracker
             image: richardchesterwood/istio-fleetman-position-tracker:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             command: ["java","-Xmx50m","-jar","webapp.jar"]
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: api-gateway
     spec:
       selector:
         matchLabels:
           app: api-gateway
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: api-gateway
         spec:
           containers:
           - name: api-gateway
             image: richardchesterwood/istio-fleetman-api-gateway:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             command: ["java","-Xmx50m","-jar","webapp.jar"]
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: webapp
     spec:
       selector:
         matchLabels:
           app: webapp
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: webapp
             version: original
         spec:
           containers:
           - name: webapp
             image: richardchesterwood/istio-fleetman-webapp-angular:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: webapp-experimental
     spec:
       selector:
         matchLabels:
           app: webapp
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: webapp
             version: experimental     # labels로 version: experimental 이름으로 canary와 동일한 신규버전을 만들었다.
         spec:
           containers:
           - name: webapp
             image: richardchesterwood/istio-fleetman-webapp-angular:6-experimental
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: vehicle-telemetry
     spec:
       selector:
         matchLabels:
           app: vehicle-telemetry
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: vehicle-telemetry
         spec:
           containers:
           - name: vehicle-telemtry
             image: richardchesterwood/istio-fleetman-vehicle-telemetry:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: staff-service
     spec:
       selector:
         matchLabels:
           app: staff-service
       replicas: 0
       template: # template for the pods
         metadata:
           labels:
             app: staff-service
             version: safe               # version: safe로 기존 stable 버전이다.
         spec:
           containers:
           - name: staff-service
             image: richardchesterwood/istio-fleetman-staff-service:6-placeholder
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
             ports:
             - containerPort: 8080
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: staff-service-risky-version
     spec:
       selector:
         matchLabels:
           app: staff-service
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: staff-service
             version: risky              # version: risky가 신규 버전의 Canry 이다.
         spec:
           containers:
           - name: staff-service
             image: richardchesterwood/istio-fleetman-staff-service:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
             ports:
             - containerPort: 8080
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-webapp
     spec:
       # This defines which pods are going to be represented by this Service
       # The service becomes a network endpoint for either other services
       # or maybe external users to connect to (eg browser)
       selector:
         app: webapp
       ports:
         - name: http
           port: 80
           nodePort: 30080
       type: NodePort
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-position-tracker
     spec:
       # This defines which pods are going to be represented by this Service
       # The service becomes a network endpoint for either other services
       # or maybe external users to connect to (eg browser)
       selector:
         app: position-tracker
       ports:
         - name: http
           port: 8080
       type: ClusterIP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-api-gateway
     spec:
       selector:
         app: api-gateway
       ports:
         - name: http
           port: 8080
       type: ClusterIP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-vehicle-telemetry
     spec:
       selector:
         app: vehicle-telemetry
       ports:
         - name: http
           port: 8080
       type: ClusterIP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-staff-service
     spec:
       selector:
         app: staff-service
       ports:
         - name: http
           port: 8080
       type: ClusterIP

  2. Virtaul Service, Gateway, Destination Rule

     apiVersion: networking.istio.io/v1alpha3
     kind: Gateway
     metadata:
       name: ingress-gateway-configuration
     spec:
       selector:
         istio: ingressgateway
       servers:
       - port:
           number: 80
           name: http
           protocol: HTTP
         hosts:
         - "*"
     ---
     kind: VirtualService
     apiVersion: networking.istio.io/v1alpha3
     metadata:
       name: fleetman-webapp
       namespace: default
     spec:
       hosts:
         - "*"
       gateways:
         - ingress-gateway-configuration
       http:
         - match:  # Prefix에 대한 설정
           - uri:  # IF /experimental 이거나
               prefix: "/experimental"
           - uri:  # OR /canary 이면
               prefix: "/canary"
           route: # THEN destination rule의 experimental로 라우팅 해라.
           - destination:
               host: fleetman-webapp
               subset: experimental
         - match:  # / Prefix면 DR의 original로 기존 버전으로 라우팅
           - uri :
               prefix: "/"
           route:
           - destination:
               host: fleetman-webapp
               subset: original
     ---
     kind: DestinationRule
     apiVersion: networking.istio.io/v1alpha3
     metadata:
       name: fleetman-webapp
       namespace: default
     spec:
       host: fleetman-webapp
       subsets:
         - labels:
             version: original # labels.version: original로 라우팅
           name: original     # Subset Name이 Original이면
         - labels:
             version: experimental # labels.version: experimental로 라우팅
           name: experimental # Subset Name이 experimental이면

  3. 테스트

     root # while true; do curl -s http://kiali-mng-dev.test.co.kr/experimental | grep title; sleep 0.5; done
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>

    /experimental로 하면 신규버전으로 "Fleet Management Istio Premium Enterprise Edition" 만 표시되어야 하는데 라운드로빈으로 왔다갔다 호출 되는거 같다.

    이 부분은 Istio-Ingressgateway로 트래픽을 제대로 타지 못했거나 K8s 서비스 오브젝트를 통해 접근 했을 경우 또는 다른 이슈가 있는 듯하다.

    Haproxy와 Ingressgateway service의 설정은 딱히 문제가 없는 듯 하다.

    확인 해보니 기존에 테스트로 생성해둔 GW, VS가 동일한 호스트와 포트로 사용중인게 있어서 문제였다 (관련해서 kiali를 통해 발견했다. 스크린샷은 찍지못함)

    관련해서 제거 한 후 다시 테스트

     root # while true; do curl -s http://kiali-mng-dev.test.co.kr/experimental | grep title; sleep 0.5; done
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>
       <title>Fleet Management Istio Premium Enterprise Edition</title>

     root # while true; do curl -s http://kiali-mng-dev.test.co.kr/ | grep title; sleep 0.5; done
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
       <title>Fleet Management</title>
    

    신규 버전과 구 버전의 Prefix로 라우팅이 잘 되는듯 하다.

SubDomain으로 라우팅

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ingress-gateway-configuration
spec:
  selector:
    istio: ingressgateway #
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "kiali-mng-dev.test.co.kr"
    - "prometheus-mng-dev.test.co.kr"
    #- "*.kiali-mng-dev.test.co.kr"  이런식으로 와일드카드로도 설정 가능
    #- "*.test.co.kr"
---
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: fleetman-webapp
  namespace: default
spec:
  hosts:
    - "kiali-mng-dev.test.co.kr"
  gateways:
    - ingress-gateway-configuration
  http:
    - route:
      - destination:
          host: fleetman-webapp
          subset: original
---
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: fleetman-webapp-experiment
  namespace: default
spec:
  hosts:
    - "prometheus-mng-dev.test.co.kr"
  gateways:
    - ingress-gateway-configuration
  http:
      - route:
        - destination:
            host: fleetman-webapp
            subset: experimental
---
kind: DestinationRule
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: fleetman-webapp
  namespace: default
spec:
  host: fleetman-webapp
  subsets:
    - labels:
        version: original
      name: original
    - labels:
        version: experimental
      name: experimental

JWT 기반 라우팅은 아직 알파단계 조만간 나올 것으로 보인다.

728x90
300x250

'IT > Istio' 카테고리의 다른 글

Mutual TLS(mTLS) with Istio  (1) 2024.01.02
서킷 브레이킹  (0) 2023.11.10
728x90
반응형

Overview

Circuit break를 해결하는 방식은 기존에도 있었으며, 그 중 대표적으로 hystirx라는 라이브러리를 통해서 해결할 수 있었다. (넷플릭스가 개발하였으나 현재는 더 이상 업데이트가 없으며, 기존 기능에 대한 운영만 지원)

그러나 hystrix는 개별 마이크로서비스의 내부 코드에 이를(circuit break 함수) 반영해야만 하는 번거로움이 있으며, JVM기반의 어플리케이션만 지원하므로 go/python 등으로 개발된 마이크로서비스에는 적용할 수 없는 문제가 있다.

Istio는 마이크로서비스 외부의 proxy(envoy)를 이용하여 모든 네트워크를 제어하하는데, curcuit breker도 적용 가능하다. 즉, 마이크로서비스의 코드 변경없이 어떤 마이크로서비스에도 적용할 수 있는 장점이 있다

  1. Demo Applications 배포

     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: position-simulator
     spec:
       selector:
         matchLabels:
           app: position-simulator
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: position-simulator
         spec:
           containers:
           - name: position-simulator
             image: richardchesterwood/istio-fleetman-position-simulator:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             command: ["java","-Xmx50m","-jar","webapp.jar"]
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: position-tracker
     spec:
       selector:
         matchLabels:
           app: position-tracker
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: position-tracker
         spec:
           containers:
           - name: position-tracker
             image: richardchesterwood/istio-fleetman-position-tracker:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             command: ["java","-Xmx50m","-jar","webapp.jar"]
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: api-gateway
     spec:
       selector:
         matchLabels:
           app: api-gateway
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: api-gateway
         spec:
           containers:
           - name: api-gateway
             image: richardchesterwood/istio-fleetman-api-gateway:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             command: ["java","-Xmx50m","-jar","webapp.jar"]
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: webapp
     spec:
       selector:
         matchLabels:
           app: webapp
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: webapp
             version: original
         spec:
           containers:
           - name: webapp
             image: richardchesterwood/istio-fleetman-webapp-angular:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: vehicle-telemetry
     spec:
       selector:
         matchLabels:
           app: vehicle-telemetry
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: vehicle-telemetry
         spec:
           containers:
           - name: vehicle-telemtry
             image: richardchesterwood/istio-fleetman-vehicle-telemetry:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: staff-service
     spec:
       selector:
         matchLabels:
           app: staff-service
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: staff-service
             version: safe
         spec:
           containers:
           - name: staff-service
             image: richardchesterwood/istio-fleetman-staff-service:6
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
             ports:
             - containerPort: 8080
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: staff-service-risky-version
     spec:
       selector:
         matchLabels:
           app: staff-service
       replicas: 1
       template: # template for the pods
         metadata:
           labels:
             app: staff-service
             version: risky
         spec:
           containers:
           - name: staff-service
             image: richardchesterwood/istio-fleetman-staff-service:6-bad    # 해당 소스가 장애가 가지고 있는 소스이고 Risky로 배포 될 예정이다.
             env:
             - name: SPRING_PROFILES_ACTIVE
               value: production-microservice
             imagePullPolicy: Always
             ports:
             - containerPort: 8080
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-webapp
     spec:
       # This defines which pods are going to be represented by this Service
       # The service becomes a network endpoint for either other services
       # or maybe external users to connect to (eg browser)
       selector:
         app: webapp
       ports:
         - name: http
           port: 80
       type: ClusterIP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-position-tracker
     spec:
       # This defines which pods are going to be represented by this Service
       # The service becomes a network endpoint for either other services
       # or maybe external users to connect to (eg browser)
       selector:
         app: position-tracker
       ports:
         - name: http
           port: 8080
       type: ClusterIP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-api-gateway
     spec:
       selector:
         app: api-gateway
       ports:
         - name: http
           port: 8080
       type: ClusterIP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-vehicle-telemetry
     spec:
       selector:
         app: vehicle-telemetry
       ports:
         - name: http
           port: 8080
       type: ClusterIP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: fleetman-staff-service
     spec:
       selector:
         app: staff-service
       ports:
         - name: http
           port: 8080
       type: ClusterIP

  2. Gw, Vs 구성

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ingress-gateway-configuration
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "kiali-mng-dev.saraminhr.co.kr"   # Domain name of the external website
---
# All traffic routed to the fleetman-webapp service
# No DestinationRule needed as we aren't doing any subsets, load balancing or outlier detection.
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: fleetman-webapp
  namespace: default
spec:
  hosts:      # which incoming host are we applying the proxy rules to???
    - "kiali-mng-dev.saraminhr.co.kr"
  gateways:
    - ingress-gateway-configuration
  http:
    - route:
      - destination:
          host: fleetman-webapp

  1. 확인

문제가 있는 Risky와 같이 배포를 했더니 브라우저에서 확인 해보면 한번씩 500에러가 발생한다.

  1. curl로 확인
root # curl -w @curl.txt http://kiali-mng-dev.saraminhr.co.kr/api/vehicles/driver/City%20Truck
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}namelookup:    0.001459
connect:       0.002182
appconnect:    0.000000
pretransfer:   0.002226
redirect:      0.000000
starttransfer: 0.019133
--------------------------------------
total:         0.019139
[SARAMIN] root@sri-mng-kube-dev1:/usr/local/src/istio
04:49 오후
root # curl -w @curl.txt http://kiali-mng-dev.saraminhr.co.kr/api/vehicles/driver/City%20Truck
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}namelookup:    0.001552
connect:       0.002251
appconnect:    0.000000
pretransfer:   0.002260
redirect:      0.000000
starttransfer: 0.019725
--------------------------------------
total:         0.019842
[SARAMIN] root@sri-mng-kube-dev1:/usr/local/src/istio
04:49 오후
root # curl -w @curl.txt http://kiali-mng-dev.saraminhr.co.kr/api/vehicles/driver/City%20Truck
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}namelookup:    0.001496
connect:       0.002103
appconnect:    0.000000
pretransfer:   0.002477
redirect:      0.000000
starttransfer: 0.022399
--------------------------------------
total:         0.022466
[SARAMIN] root@sri-mng-kube-dev1:/usr/local/src/istio
04:49 오후
root # curl -w @curl.txt http://kiali-mng-dev.saraminhr.co.kr/api/vehicles/driver/City%20Truck
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}namelookup:    0.001412
connect:       0.002050
appconnect:    0.000000
pretransfer:   0.002138
redirect:      0.000000
starttransfer: 1.285805
--------------------------------------
total:         1.285837
[SARAMIN] root@sri-mng-kube-dev1:/usr/local/src/istio
04:49 오후
root # curl -w @curl.txt http://kiali-mng-dev.saraminhr.co.kr/api/vehicles/driver/City%20Truck
{"timestamp":"2023-11-07T07:49:21.555+0000","status":500,"error":"Internal Server Error","message":"status 502 reading RemoteStaffMicroserviceCalls#getDriverFor(String)","path":"//vehicles/driver/City%20Truck"}namelookup:    0.001339
connect:       0.001931
appconnect:    0.000000
pretransfer:   0.001974
redirect:      0.000000
starttransfer: 5.003001
--------------------------------------
total:         5.003088

  • 한번씩 실패나기도 하면서 지연도 있는것 같다.
  • 예거에서도 보면 다른 서비스에서도 4초 이상 지연이 발생했다.
  • kiali에서 확인 해보면 Risky 하나로 전체적으로 지연 발생하는 것으로 보인다.
  1. Circuit Breaker 설정
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: circuit-breaker-for-the-entire-default-namespace
spec:
  host: "fleetman-staff-service.default.svc.cluster.local"
  trafficPolicy:
    outlierDetection: # Circuit Breakers가 작동하는 기준 설정
      consecutive5xxErrors: 2
      interval: 10s
      baseEjectionTime: 30s
      maxEjectionPercent: 100

[consecutiveErrors]
연속적인 에러가 몇번까지 발생해야 circuit breaker를 동작시킬 것인지 결정
여기서는 연속 2번 오류가 발생하면 circuit breaker 동작 (테스트 환경으로 횟수를 낮췄다.)

[interval]
interval에서 지정한 시간 내에 consecutiveError 횟수 만큼 에러가 발생하는 경우 circuit breaker 동작
즉, 10초 내에 2번의 연속적인 오류가 발생하면 circuit breaker 동작

[baseEjectionTime]
차단한 호스트를 얼마 동안 로드밸런서 pool에서 제외할 것인가?
즉, 얼마나 오래 circuit breaker를 해당 호스트에게 적용할지 시간을 결정

[maxEjectionPercent]
네트워크를 차단할 최대 host의 비율. 즉, 최대 몇 %까지 차단할 것인지 설정
현재 구성은 2개의 pod가 있으므로, 100%인 경우 2개 모두 차단이 가능하다
10%인 경우 차단이 불가능해 보이는데(1개가 50%이므로),
envoy에서는 circuit breaker가 발동되었으나,
10%에 해당하지 않아서 차단할 호스트가 없으면
강제적으로 해당 호스트를 차단하도록 설정한다

  1. 확인

서킷 브레이커가 동작 중이면 번개 표시로 나타남

  • curl로 동작 확인
while true; do curl http://kiali-mng-dev.saraminhr.co.kr/api/vehicles/driver/City%20Truck; echo; sleep 0.5; done
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/placeholder.png"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"timestamp":"2023-11-07T08:39:50.949+0000","status":500,"error":"Internal Server Error","message":"status 502 reading RemoteStaffMicroserviceCalls#getDriverFor(String)","path":"//vehicles/driver/City%20Truck"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"timestamp":"2023-11-07T08:39:53.483+0000","status":500,"error":"Internal Server Error","message":"status 502 reading RemoteStaffMicroserviceCalls#getDriverFor(String)","path":"//vehicles/driver/City%20Truck"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
{"name":"Pam Parry","photo":"https://rac-istio-course-images.s3.amazonaws.com/1.jpg"}
^C

처음에 2번 에러가 나면서 서킷 브레이커가 동작하게 되면서 더이상 에러가 발생 안하는 모습을 볼수 있었다.

  • 웹브라우저에서도 지연없이 사진도 잘 불러와지는 것을 확인 할 수 있었다.
  • 전체 서비스에 서킷브레이커를 동작 시키고 싶다면 전역 설정이 있다.
728x90
300x250

'IT > Istio' 카테고리의 다른 글

Mutual TLS(mTLS) with Istio  (1) 2024.01.02
Istio Traffic Management 트래픽 통제하기  (0) 2023.11.10
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은 모두 작은 트래픽 하위 집합이 서비스의 새 버전으로 전달되는 카나리아 배포를 허용합니다. 이를 통해 새 릴리스를 전체 사용자 기반에 출시하기 전에 테스트하고 검증할 수 있습니다.

차이점

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
반응형

iowait 원인파악

Rocky Linux 8.8에 올라가있는 k8s 클러스터에서 iowait가 발생하거나 Load가 치는 경우가 발생했다.

원인 파악하기 위한 해결 내용을 정리한다.

  1. iostat 으로 어느 볼륨에서 io를 사용하는지 지켜본다.

     root # iostat -dx -c 1
     Linux 4.18.0-477.10.1.el8_8.x86_64 (dyms-kube-dev2)     2023년 08월 04일     _x86_64_    (16 CPU)
    
     avg-cpu:  %user   %nice %system %iowait  %steal   %idle
                1.13    0.00    1.51    6.10    0.25   91.01
     Device            r/s     w/s     rkB/s     wkB/s   rrqm/s   wrqm/s  %rrqm  %wrqm r_await w_await aqu-sz rareq-sz wareq-sz  svctm  %util
     xvda             0.00   12.00      0.00     32.00     0.00     0.00   0.00   0.00    0.00    0.17   0.00     0.00     2.67   0.33   0.40
     xvdb             0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00
     scd0             0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00

    xvda에서 io를 사용하고 있고 iowait 수치가 올라가 있는 것으로 보인다. xvda는 root 볼륨이다. 현재 k8s가 xvdb 에서 동작하고 있기 때문에 컨테이너의 영향이 아니라고 판단했다.

  2. iotop으로 프로세스별 io 사용율을 본다.

     Total DISK READ :    0.00 B/s | Total DISK WRITE :     101.20 K/s
     Actual DISK READ:    0.00 B/s | Actual DISK WRITE:      97.46 K/s
         PID  PRIO  USER     DISK READ DISK WRITE>    COMMAND
      759729 be/4 root          0.00 B    408.00 K etcd
         949 be/4 root          0.00 B     16.00 K rsyslogd -n
         895 be/4 root          0.00 B      4.00 K containerd
      777256 be/4 root          0.00 B      0.00 B containerd-shim-runc-v2 -namespace k8s.io -id f4f8ff775ec9e2e752adaacafaa5e11ab09e1f5dcfe686712954fc6559a38276 -address /run/containerd/containerd.sock
      803824 be/4 root          0.00 B      0.00 B [kworker/3:1-mm_percpu_wq]

    etcd가 io를 지속적으로 사용하고 있는 것으로 보인다. 그렇다는거는 root 영역에서는 거의 io가 발생하고 있지 않다는 것을 의미하는거 같은데.. 무엇이 문제일까??

  3. 프로세스 상태 체크

     root # ps -eo state,pid,cmd  | grep D
     S     PID CMD
     D     124 [khugepaged]
     S     856 /usr/sbin/sshd -D 
     S  964068 grep --color=auto D
     D 2607233 ps -efL

    프로세스의 S(state)를 보면 D인 프로세스를 발견했다.

    프로세스상태 중 D는 중지되지 않고 계속 wait 하고 있는 상태를 말한다. (아래는 ps의 man page이다)

     PROCESS STATE CODES
            Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a process:
                    D    uninterruptible sleep (usually IO)
                    R    running or runnable (on run queue)
                    S    interruptible sleep (waiting for an event to complete)
                    T    stopped by job control signal
                    t    stopped by debugger during the tracing
                    W    paging (not valid since the 2.6.xx kernel)
                    X    dead (should never be seen)
                    Z    defunct ("zombie") process, terminated but not reaped by its parent
            For BSD formats and when the stat keyword is used, additional characters may be displayed:
                    <    high-priority (not nice to other users)
                    N    low-priority (nice to other users)
                    L    has pages locked into memory (for real-time and custom IO)
                    s    is a session leader
                    l    is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)

  4. 커널에서 사용 중인 PID 124인 khugepaged 프로세스가 계속 D 상태에 있는 것을 확인 하였다.

    lsof도 한번 체크는 해본다.

     root # lsof -p 124
     COMMAND   PID USER   FD      TYPE DEVICE SIZE/OFF NODE NAME
     khugepage 124 root  cwd       DIR  202,6      272  128 /
     khugepage 124 root  rtd       DIR  202,6      272  128 /
     khugepage 124 root  txt   unknown                      /proc/124/exe

  5. hugepaged 프로세스는 THP(Transparent Huge Page)를 사용하기 위한 프로세스인데, 제대로 활용되지 못하고 있는 것으로 보이며, z커널단에서 프로세스가 Hang 걸린 것처럼 보인다. never로 변경 하도록 한다.

     echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
     echo "never" > /sys/kernel/mm/transparent_hugepage/defrag

  6. THP를 비활성화 설정을 하는데 갑자기 서버 세션이 Hang 걸려버림 (해당 프로세스가 원인인 것으로 확실해짐)

  7. 다른 세션에서 확인 해보니 -bash 부분에서 또다시 D 상태로 확인 됨

     root # ps -eo state,pid,cmd | grep D
     S     PID CMD
     D     124 [khugepaged]
     S     856 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc -oMACs=hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512 -oGSSAPIKexAlgorithms=gss-curve25519-sha256-,gss-nistp256-sha256-,gss-group14-sha256-,gss-group16-sha512-,gss-gex-sha1-,gss-group14-sha1- -oKexAlgorithms=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1 -oHostKeyAlgorithms=ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com,ssh-rsa,ssh-rsa-cert-v01@openssh.com -oPubkeyAcceptedKeyTypes=ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com,ssh-rsa,ssh-rsa-cert-v01@openssh.com -oCASignatureAlgorithms=ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rsa
     S  748475 kube-apiserver--allow-privileged=true --anonymous-auth=True --apiserver-count=3 --authorization-mode=Node,RBAC --bind-address=0.0.0.0 --client-ca-file=/etc/kubernetes/ssl/ca.crt --default-not-ready-toleration-seconds=300 --default-unreachable-toleration-seconds=300 --enable-admission-plugins=NodeRestriction --enable-aggregator-routing=False --enable-bootstrap-token-auth=true --endpoint-reconciler-type=lease --etcd-cafile=/etc/ssl/etcd/ssl/ca.pem --etcd-certfile=/etc/ssl/etcd/ssl/node-dyms-kube-dev2.pem --etcd-keyfile=/etc/ssl/etcd/ssl/node-dyms-kube-dev2-key.pem --etcd- --event-ttl=1h0m0s --kubelet-client-certificate=/etc/kubernetes/ssl/apiserver-kubelet-client.crt --kubelet-client-key=/etc/kubernetes/ssl/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalDNS,InternalIP,Hostname,ExternalDNS,ExternalIP --profiling=False --proxy-client-cert-file=/etc/kubernetes/ssl/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/ssl/front-proxy-client.key --request-timeout=1m0s --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/etc/kubernetes/ssl/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6443 --service-account-issuer=https://kubernetes.default.svc.dyms-dev.cluster.local --service-account-key-file=/etc/kubernetes/ssl/sa.pub --service-account-lookup=True --service-account-signing-key-file=/etc/kubernetes/ssl/sa.key --service-cluster-ip-range=10.233.0.0/18 --service-node-port-range=30000-32767 --storage-backend=etcd3 --tls-cert-file=/etc/kubernetes/ssl/apiserver.crt --tls-private-key-file=/etc/kubernetes/ssl/apiserver.key
     D  870132 -bash

  8. ioswait는 수치가 2배로 뛰었다.

     avg-cpu:  %user   %nice %system %iowait  %steal   %idle
                2.08    0.00    1.64   12.04    0.25   83.99
     Device            r/s     w/s     rkB/s     wkB/s   rrqm/s   wrqm/s  %rrqm  %wrqm r_await w_await aqu-sz rareq-sz wareq-sz  svctm  %util
     xvda             0.00   58.00      0.00    206.50     0.00     0.00   0.00   0.00    0.00    0.24   0.01     0.00     3.56   0.28   1.60
     xvdb             0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00
     scd0             0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00

  9. 강제 재부팅 하고 해당 THP를 never 설정을 해주었음

728x90
300x250

'IT > OS' 카테고리의 다른 글

Linux Crontab 명령어로 등록하기  (0) 2022.01.17
물리서버 NVMe SSD 세팅  (0) 2021.08.19
Windows에서 SSH 하는 법  (0) 2021.08.19
네트워크 지연 발생 테스트  (0) 2021.08.19
Linux screen 설정과 사용  (0) 2021.08.19

+ Recent posts