앰비언트 멀티네트워크용 Kiali 대시보드

앰비언트 멀티네트워크용 Kiali 대시보드 (Kiali Dashboard for Ambient Multi-network)

이 가이드를 따라 멀티네트워크 앰비언트 배포에서 멀티클러스터 인지형 Kiali를 배포해서, 클러스터 사이에서 트래픽이 어떻게 흐르는지 확인해 보세요.

출처: Istio 문서

본문

진행하기 전에 시작하기 전에, 멀티클러스터 설치 가이드, 배포 검증 단계를 완료했는지 확인하세요.

이 가이드에서는 먼저 연합(federated) Prometheus 인스턴스를 배포해서 모든 클러스터의 메트릭을 함께 모을 거예요. 그런 다음 모든 클러스터에 연결해 메시 트래픽의 통합된 보기를 제시하는 커스터마이즈된 Kiali 인스턴스를 배포할 거예요.

Kiali 배포 준비하기 (Prepare for Kiali Deployment)

커스터마이즈된 Prometheus와 Kiali를 별도의 네임스페이스에 설치할 거예요. 두 클러스터 모두에서 네임스페이스를 생성하는 것부터 시작하세요:

$ kubectl --context="${CTX_CLUSTER1}" create namespace kiali
$ kubectl --context="${CTX_CLUSTER2}" create namespace kiali

Kiali를 배포하는 데 helm도 사용할 거예요. 관련 Helm 저장소를 추가하세요:

$ helm repo add kiali https://kiali.org/helm-charts

연합 Prometheus (Federated Prometheus)

Istio는 단일 클러스터 배포에서 Prometheus를 빠르게 올리기 위한 기본 샘플 설치를 제공해요. 이를 사용해 각 클러스터에 Prometheus를 설치할 거예요. 그런 다음 각 클러스터의 Prometheus를 스크레이핑해 메트릭을 함께 모으는 또 다른 Prometheus 인스턴스를 배포할 거예요.

원격 클러스터의 Prometheus를 스크레이핑할 수 있으려면 Prometheus 인스턴스를 Ingress Gateway를 통해 노출할 거예요.

각 클러스터에 Prometheus 배포하기 (Deploy Prometheus in Each Cluster)

$ kubectl --context="${CTX_CLUSTER1}" apply -f https://raw.githubusercontent.com/istio/istio/release-1.31/samples/addons/prometheus.yaml
$ kubectl --context="${CTX_CLUSTER2}" apply -f https://raw.githubusercontent.com/istio/istio/release-1.31/samples/addons/prometheus.yaml

위 명령들은 웨이포인트와 ztunnel에서 로컬 클러스터 메트릭을 수집하는 Prometheus를 설치해요.

Prometheus 노출하기 (Expose Prometheus)

다음 단계는 스크레이핑할 수 있도록 Prometheus 인스턴스를 외부로 노출하는 거예요:

$ cat <<EOF | kubectl --context="${CTX_CLUSTER1}" apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: prometheus-gateway
  namespace: istio-system
spec:
  gatewayClassName: istio
  listeners:
  - name: http
    port: 9090
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: prometheus
  namespace: istio-system
spec:
  parentRefs:
  - name: prometheus-gateway
    port: 9090
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: prometheus
      port: 9090
EOF

두 번째 클러스터에서도 같은 작업을 할 거예요:

$ cat <<EOF | kubectl --context="${CTX_CLUSTER2}" apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: prometheus-gateway
  namespace: istio-system
spec:
  gatewayClassName: istio
  listeners:
  - name: http
    port: 9090
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: prometheus
  namespace: istio-system
spec:
  parentRefs:
  - name: prometheus-gateway
    port: 9090
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: prometheus
      port: 9090
EOF

메트릭 집계하기 (Aggregate Metrics)

클러스터 로컬 Prometheus 인스턴스들이 실행 중이면, 이제 한 곳에서 두 클러스터의 메트릭을 모으기 위해 그것들을 스크레이핑하는 또 다른 Prometheus 인스턴스를 설정할 수 있어요. 먼저 새 Prometheus 인스턴스가 스크레이핑할 클러스터 로컬 Prometheus 인스턴스를 가리키도록 구성(config)을 만들 거예요:

$ TARGET1="$(kubectl --context="${CTX_CLUSTER1}" get gtw prometheus-gateway -n istio-system -o jsonpath='{.status.addresses[0].value}')"
$ TARGET2="$(kubectl --context="${CTX_CLUSTER2}" get gtw prometheus-gateway -n istio-system -o jsonpath='{.status.addresses[0].value}')"
$ cat <<EOF > prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'federate-1'
    honor_labels: true
    metrics_path: '/federate'
    params:
      'match[]':
        - '{job="kubernetes-pods"}'
    static_configs:
      - targets:
        - '${TARGET1}:9090'
        labels:
          cluster: 'cluster1'
  - job_name: 'federate-2'
    honor_labels: true
    metrics_path: '/federate'
    params:
      'match[]':
        - '{job="kubernetes-pods"}'
    static_configs:
      - targets:
        - '${TARGET2}:9090'
        labels:
          cluster: 'cluster2'
EOF
$ kubectl --context="${CTX_CLUSTER1}" create configmap prometheus-config -n kiali --from-file prometheus.yml

이제 이 구성을 사용해 새 Prometheus 인스턴스를 배포할 수 있어요:

$ cat <<EOF | kubectl --context="${CTX_CLUSTER1}" apply -f - -n kiali
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
        - name: prometheus
          image: prom/prometheus
          ports:
            - containerPort: 9090
          volumeMounts:
            - name: config-volume
              mountPath: /etc/prometheus
      volumes:
        - name: config-volume
          configMap:
            name: prometheus-config
            defaultMode: 420
---
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  labels:
    app: prometheus
    service: prometheus
spec:
  ports:
  - port: 9090
    name: http
  selector:
    app: prometheus
EOF

배포되면 새 Prometheus 인스턴스가 두 클러스터에서 메트릭을 스크레이핑하기 시작해요.

연합 Prometheus 검증하기 (Verify Federated Prometheus)

테스트하려면 curl을 여러 번 실행해서 두 클러스터 모두의 백엔드에 도달하는 트래픽을 생성할 수 있어요:

$ kubectl exec --context="${CTX_CLUSTER1}" -n sample -c curl \
    "$(kubectl get pod --context="${CTX_CLUSTER1}" -n sample -l \
    app=curl -o jsonpath='{.items[0].metadata.name}')" \
    -- curl -sS helloworld.sample:5000/hello
Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8
Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv
...

그런 다음 curl로 Prometheus를 조회해서 모든 클러스터에서 메트릭이 보고되는지 확인할 수 있어요:

$ kubectl exec --context="${CTX_CLUSTER1}" -n sample -c curl \
    "$(kubectl get pods ---context="${CTX_CLUSTER1}" -n sample -l \
    app=curl -o jsonpath='{.items[0].metadata.name}')" \
    -- curl -s prometheus.kiali:9090/api/v1/query?query=istio_tcp_received_bytes_total | jq '.'

curl 요청이 두 클러스터 모두의 백엔드에 도달했다면, ztunnel이 보고하는 istio_tcp_received_bytes_total 메트릭에 대해 출력에서 두 클러스터의 값을 볼 수 있어요:

{
  "status": "success",
  "data": {
    "resultType": "vector",
    "result": [
      {
        "metric": {
          "__name__": "istio_tcp_received_bytes_total",
          ...
          "app": "ztunnel",
          ...
          "cluster": "cluster2",
          ...
          "destination_canonical_revision": "v2",
          ...
          "destination_canonical_service": "helloworld",
          ...
        },
        "value": [
          1770660628.007,
          "5040"
        ]
      },
      ...
      {
        "metric": {
          "__name__": "istio_tcp_received_bytes_total",
          ...
          "app": "ztunnel",
          ...
          "cluster": "cluster1",
          ...
          "destination_canonical_revision": "v1",
          ...
          "destination_canonical_service": "helloworld",
          ...
        },
        "value": [
          1770660628.007,
          "4704"
        ]
      },
      ...
    ]
  }
}

멀티클러스터 Kiali 배포하기 (Deploy Multicluster Kiali)

원격 클러스터 준비하기 (Prepare Remote Cluster)

한 클러스터(cluster1)에서만 Kiali를 제대로 배포할 거예요. 하지만 Kiali가 거기서 리소스에 접근할 수 있도록 cluster2도 준비해야 해요. 이를 위해 먼저 Kiali Operator를 배포하는 것부터 시작하세요:

$ helm --kube-context="${CTX_CLUSTER2}" install --namespace kiali kiali-operator kiali/kiali-operator --wait

Kiali Operator가 배포되면 필요한 모든 서비스 계정, 역할 바인딩, 토큰을 준비할 수 있어요. Kiali Operator가 서비스 계정과 역할 바인딩을 만들지만, 서비스 계정의 토큰은 수동으로 만들어야 해요:

$ cat <<EOF | kubectl --context="${CTX_CLUSTER2}" apply -f - -n kiali
apiVersion: kiali.io/v1alpha1
kind: Kiali
metadata:
  name: kiali
spec:
  auth:
    strategy: "anonymous"
  deployment:
    remote_cluster_resources_only: true
EOF
$ kubectl --context="${CTX_CLUSTER2}" wait --timeout=5m --for=condition=Successful kiali kiali -n kiali
$ cat <<EOF | kubectl --context="${CTX_CLUSTER2}" apply -f - -n kiali
apiVersion: v1
kind: Secret
metadata:
  name: kiali
  namespace: kiali
  annotations:
    kubernetes.io/service-account.name: kiali-service-account
type: kubernetes.io/service-account-token
EOF

Kiali 배포하기 (Deploy Kiali)

원격 클러스터가 준비되었으니 이제 Kiali 서버를 배포할 수 있어요. Kiali를 Prometheus 엔드포인트 주소와 원격 클러스터에 접근하는 시크릿으로 구성해야 해요. 이전과 마찬가지로 Kiali Operator를 배포하는 것부터 시작하세요:

$ helm --kube-context="${CTX_CLUSTER1}" install --namespace kiali kiali-operator kiali/kiali-operator --wait

Kiali 프로젝트는 원격 클러스터 리소스에 접근하는 데 필요한 시크릿을 만들기 위해 사용할 수 있는 스크립트를 제공해요:

$ curl -L -o kiali-prepare-remote-cluster.sh https://raw.githubusercontent.com/kiali/kiali/master/hack/istio/multicluster/kiali-prepare-remote-cluster.sh
$ chmod +x kiali-prepare-remote-cluster.sh
$ ./kiali-prepare-remote-cluster.sh \
    --kiali-cluster-context "${CTX_CLUSTER1}" \
    --remote-cluster-context "${CTX_CLUSTER2}" \
    --view-only false \
    --process-kiali-secret true \
    --process-remote-resources false \
    --kiali-cluster-namespace kiali \
    --remote-cluster-namespace kiali \
    --kiali-resource-name kiali \
    --remote-cluster-name cluster2

원격 시크릿이 준비되면 Kiali 서버를 배포할 수 있어요:

$ cat <<EOF | kubectl --context="${CTX_CLUSTER1}" apply -f - -n kiali
apiVersion: kiali.io/v1alpha1
kind: Kiali
metadata:
  name: kiali
spec:
  auth:
    strategy: "anonymous"
  external_services:
    prometheus:
      url: http://prometheus.kiali:9090
    grafana:
      enabled: false
  server:
    web_root: "/kiali"
EOF
$ kubectl --context="${CTX_CLUSTER1}" wait --timeout=5m --for=condition=Successful kiali kiali -n kiali

Kiali 서버가 실행되면 로컬 포트를 Kiali 배포로 포워딩해서 로컬에서 접근할 수 있어요:

$ kubectl --context="${CTX_CLUSTER1}" port-forward svc/kiali 20001:20001 -n kiali

브라우저에서 Kiali 대시보드를 열고 트래픽 그래프로 이동한 다음, "Select Namespaces" 드롭다운에서 "sample" 네임스페이스를 선택하세요. 클러스터 사이에서 트래픽이 어떻게 흐르는지 볼 수 있을 거예요:

축하해요! 멀티클러스터 앰비언트 배포용 Kiali를 성공적으로 설치했어요.

Kiali와 Prometheus 정리하기 (Cleanup Kiali and Prometheus)

Kiali를 삭제하려면 먼저 Kiali 커스텀 리소스를 삭제하는 것부터 시작하세요:

$ kubectl --context="${CTX_CLUSTER1}" delete kiali kiali -n kiali
$ kubectl --context="${CTX_CLUSTER2}" delete kiali kiali -n kiali

Kiali Operator는 커스텀 리소스가 삭제되면 Kiali 서버를 중지해요. Kiali Operator도 추가로 삭제하려면 그렇게 할 수 있어요:

$ helm --kube-context="${CTX_CLUSTER1}" uninstall --namespace kiali kiali-operator
$ helm --kube-context="${CTX_CLUSTER2}" uninstall --namespace kiali kiali-operator

마지막으로 커스텀 리소스 정의를 삭제할 수 있어요:

$ kubectl --context="${CTX_CLUSTER1}" delete crd kialis.kiali.io

클러스터 로컬 Prometheus 인스턴스가 필요 없다면 그것들도 삭제할 수 있어요:

$ kubectl --context="${CTX_CLUSTER1}" delete -f https://raw.githubusercontent.com/istio/istio/release-1.31/samples/addons/prometheus.yaml
$ kubectl --context="${CTX_CLUSTER2}" delete -f https://raw.githubusercontent.com/istio/istio/release-1.31/samples/addons/prometheus.yaml

더 알아보기 (Learn more)