AKS(Azure Kubernetes Service)에 대한 Container Network Observability 설정 - Azure 관리형 Prometheus 및 Grafana
이 문서에서는 관리되는 Prometheus 및 Grafana 및 BYO Prometheus 및 Grafana를 사용하여 AKS(Azure Kubernetes Service)에 대한 Container Network Observability를 설정하고 긁힌 메트릭을 시각화하는 방법을 보여 줍니다.
Container Network Observability를 사용하여 AKS 클러스터의 네트워크 트래픽에 대한 데이터를 수집할 수 있습니다. 네트워크 가시성을 사용하면 중앙 집중식 플랫폼에서 애플리케이션 및 네트워크 상태를 모니터링할 수 있습니다. 현재 메트릭은 Prometheus에 저장되고 Grafana를 사용하여 시각화할 수 있습니다. 컨테이너 네트워크 관찰성은 허블을 사용하도록 설정하는 기능도 제공합니다. 이러한 기능은 Cilium 및 비 Cilium 클러스터 모두에서 지원됩니다.
Container Network Observability는 고급 컨테이너 네트워킹 서비스의 기능 중 하나입니다. AKS(Azure Kubernetes Service)용 고급 컨테이너 네트워킹 서비스에 대한 자세한 내용은 AKS(Azure Kubernetes Service)용 고급 컨테이너 네트워킹 서비스란?을 참조하세요.
필수 조건
- 활성 구독이 있는 Azure 계정. 구독이 없으면 시작하기 전에 계정을 만드세요.
Azure Cloud Shell에서 Bash 환경을 사용합니다. 자세한 내용은 Azure Cloud Shell의 Bash에 대한 빠른 시작을 참조하세요.
CLI 참조 명령을 로컬에서 실행하려면 Azure CLI를 설치합니다. Windows 또는 macOS에서 실행 중인 경우 Docker 컨테이너에서 Azure CLI를 실행하는 것이 좋습니다. 자세한 내용은 Docker 컨테이너에서 Azure CLI를 실행하는 방법을 참조하세요.
로컬 설치를 사용하는 경우 az login 명령을 사용하여 Azure CLI에 로그인합니다. 인증 프로세스를 완료하려면 터미널에 표시되는 단계를 수행합니다. 다른 로그인 옵션은 Azure CLI를 사용하여 로그인을 참조하세요.
메시지가 표시되면 처음 사용할 때 Azure CLI 확장을 설치합니다. 확장에 대한 자세한 내용은 Azure CLI에서 확장 사용을 참조하세요.
az version을 실행하여 설치된 버전과 종속 라이브러리를 찾습니다. 최신 버전으로 업그레이드하려면 az upgrade를 실행합니다.
- 이 문서의 단계에 필요한 Azure CLI의 최소 버전은 2.56.0입니다.
az --version
을 실행하여 버전을 찾습니다. 설치 또는 업그레이드해야 하는 경우 Azure CLI 설치를 참조하세요.
aks-preview Azure CLI 확장 설치
az extension add
또는 az extension update
명령을 사용하여 Azure CLI 미리 보기 확장을 설치하거나 업데이트합니다.
# Install the aks-preview extension
az extension add --name aks-preview
# Update the extension to make sure you have the latest version installed
az extension update --name aks-preview
고급 컨테이너 네트워킹 서비스 사용
계속하려면 고급 컨테이너 네트워킹 서비스를 사용하도록 설정된 AKS 클러스터 가 있어야 합니다.
az aks create
고급 컨테이너 네트워킹 서비스 플래그--enable-acns
가 있는 명령은 모든 고급 컨테이너 네트워킹 서비스 기능을 사용하여 새 AKS 클러스터를 만듭니다. 이러한 기능은 다음을 포함합니다.
컨테이너 네트워크 관찰 가능성: 네트워크 트래픽에 대한 인사이트를 제공합니다. 자세한 내용은 Container Network Observability를 방문 하세요.
컨테이너 네트워크 보안: FQDN 필터링과 같은 보안 기능을 제공합니다. 자세한 내용은 Container Network Security를 방문하세요.
참고 항목
Cilium 데이터 평면을 사용하는 클러스터는 Kubernetes 버전 1.29부터 Container Network Observability 및 Container Network 보안을 지원합니다.
# Set an environment variable for the AKS cluster name. Make sure to replace the placeholder with your own value.
export CLUSTER_NAME="<aks-cluster-name>"
# Create an AKS cluster
az aks create \
--name $CLUSTER_NAME \
--resource-group $RESOURCE_GROUP \
--generate-ssh-keys \
--location eastus \
--max-pods 250 \
--network-plugin azure \
--network-plugin-mode overlay \
--network-dataplane cilium \
--node-count 2 \
--pod-cidr 192.168.0.0/16 \
--kubernetes-version 1.29 \
--enable-acns
기존 클러스터에서 고급 컨테이너 네트워킹 서비스 사용
az aks update
고급 컨테이너 네트워킹 서비스 플래그--enable-acns
가 있는 명령은 컨테이너 네트워크 관찰 기능 및 컨테이너 네트워크 보안 기능을 포함하는 모든 고급 컨테이너 네트워킹 서비스 기능으로 기존 AKS 클러스터를 업데이트합니다.
참고 항목
Cilium 데이터 평면이 있는 클러스터만 고급 컨테이너 네트워킹 서비스의 Container Network Security 기능을 지원합니다.
az aks update \
--resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME \
--enable-acns
클러스터 자격 증명 가져오기
명령을 사용하여 클러스터 자격 증명을 az aks get-credentials
가져옵니다.
az aks get-credentials --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP
Azure 관리형 Prometheus 및 Grafana
BYO Prometheus 및 Grafana를 사용하는 경우 이 섹션 건너뛰기
다음 예제를 사용하여 AKS 클러스터에 대해 Prometheus 및 Grafana를 설치하고 사용하도록 설정합니다.
Azure Monitor 리소스 만들기
#Set an environment variable for the Grafana name. Make sure to replace the placeholder with your own value.
export AZURE_MONITOR_NAME="<azure-monitor-name>"
# Create Azure monitor resource
az resource create \
--resource-group $RESOURCE_GROUP \
--namespace microsoft.monitor \
--resource-type accounts \
--name $AZURE_MONITOR_NAME \
--location eastus \
--properties '{}'
Azure Managed Grafana 인스턴스 만들기
az grafana create를 사용하여 Grafana 인스턴스를 만듭니다. Grafana 인스턴스의 이름은 고유해야 합니다.
# Set an environment variable for the Grafana name. Make sure to replace the placeholder with your own value.
export GRAFANA_NAME="<grafana-name>"
# Create Grafana instance
az grafana create \
--name $GRAFANA_NAME \
--resource-group $RESOURCE_GROUP
변수에 Azure Managed Grafana 및 Azure Monitor 리소스 ID 배치
az grafana show를 사용하여 Grafana 리소스 ID를 변수에 배치합니다. az resource show를 사용하여 Azure Monitor 리소스 ID를 변수에 배치합니다. myGrafana를 Grafana 인스터스의 이름으로 바꿉니다.
grafanaId=$(az grafana show \
--name $GRAFANA_NAME \
--resource-group $RESOURCE_GROUP \
--query id \
--output tsv)
azuremonitorId=$(az resource show \
--resource-group $RESOURCE_GROUP \
--name $AZURE_MONITOR_NAME \
--resource-type "Microsoft.Monitor/accounts" \
--query id \
--output tsv)
AKS 클러스터에 Azure Monitor 및 Azure Managed Grafana 연결
az aks update를 사용하여 Azure Monitor 및 Grafana 리소스를 AKS 클러스터에 연결합니다.
az aks update \
--name $CLUSTER_NAME \
--resource-group $RESOURCE_GROUP \
--enable-azure-monitor-metrics \
--azure-monitor-workspace-resource-id $azuremonitorId \
--grafana-resource-id $grafanaId
시각화
Azure Managed Grafana를 사용한 시각화
BYO Grafana를 사용하는 경우 이 단계를 건너뜁니다.
참고 항목
대규모 클러스터의 높은 메트릭 카디널리티로 인해 hubble_flows_processed_total
메트릭은 기본적으로 스크랩되지 않습니다.
이로 인해 Pods Flows 대시보드에는 데이터가 누락된 패널이 있습니다. 이를 변경하려면 메트릭 유지 목록에 hubble_flows_processed_total
을 포함하도록 ama 메트릭 설정을 수정하면 됩니다. 이를 수행하는 방법을 알아보려면 최소 수집 문서를 참조하세요.
kubectl get pods
명령을 사용하여 Azure Monitor Pod가 실행되고 있는지 확인합니다.kubectl get pods -o wide -n kube-system | grep ama-
출력은 다음 예제 출력과 비슷하게 됩니다.
ama-metrics-5bc6c6d948-zkgc9 2/2 Running 0 (21h ago) 26h ama-metrics-ksm-556d86b5dc-2ndkv 1/1 Running 0 (26h ago) 26h ama-metrics-node-lbwcj 2/2 Running 0 (21h ago) 26h ama-metrics-node-rzkzn 2/2 Running 0 (21h ago) 26h ama-metrics-win-node-gqnkw 2/2 Running 0 (26h ago) 26h ama-metrics-win-node-tkrm8 2/2 Running 0 (26h ago) 26h
샘플 대시보드를 만들었습니다. 대시보드 > Azure 관리형 Prometheus 폴더에서 찾을 수 있습니다. 이름은 "Kubernetes / Networking /
<name>
"과 같습니다. 대시보드 도구 모음에는 다음이 포함됩니다.- 클러스터: 클러스터에 대한 노드 수준 메트릭을 표시합니다.
- DNS(클러스터): 클러스터 또는 선택한 노드에 대한 DNS 메트릭을 표시합니다.
- DNS(워크로드): 지정된 워크로드(예: CoreDNS와 같은 DaemonSet 또는 배포의 Pod)에 대한 DNS 메트릭을 표시합니다.
- 삭제(워크로드): 지정된 워크로드(예: 배포 또는 DaemonSet의 Pod)와의 삭제를 표시합니다.
- Pod 흐름(네임스페이스): 지정된 네임스페이스(즉, 네임스페이스의 Pod)와의 L4/L7 패킷 흐름을 표시합니다.
- Pod 흐름(워크로드): 지정된 워크로드(예: 배포 또는 DaemonSet의 Pod)와의 L4/L7 패킷 흐름을 보여 줍니다.
BYO Grafana를 사용한 시각화
Azure 관리형 Grafana를 사용하는 경우 이 단계를 건너뜁니다.
기존 Prometheus 구성에 다음 스크랩 작업을 추가하고 Prometheus 서버를 다시 시작합니다.
- job_name: networkobservability-hubble kubernetes_sd_configs: - role: pod relabel_configs: - target_label: cluster replacement: myAKSCluster action: replace - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_pod_label_k8s_app] regex: kube-system;(retina|cilium) action: keep - source_labels: [__address__] action: replace regex: ([^:]+)(?::\d+)? replacement: $1:9965 target_label: __address__ - source_labels: [__meta_kubernetes_pod_node_name] target_label: instance action: replace metric_relabel_configs: - source_labels: [__name__] regex: '|hubble_dns_queries_total|hubble_dns_responses_total|hubble_drop_total|hubble_tcp_flags_total' # if desired, add |hubble_flows_processed_total action: keep
Prometheus의 대상에서 network-obs-pods가 있는지 확인합니다.
Grafana에 로그인하고 다음 ID를 사용하여 다음 예제 대시보드를 가져옵니다.
- 클러스터: 클러스터에 대한 노드 수준 메트릭을 보여 줍니다. (ID: 18814)
- DNS(클러스터): 클러스터 또는 노드 선택 영역에 DNS 메트릭을 표시합니다.(ID: 20925)
- DNS(워크로드): 지정된 워크로드에 대한 DNS 메트릭을 표시합니다(예: DaemonSet의 Pod 또는 CoreDNS와 같은 배포). (ID: [20926] https://grafana.com/grafana/dashboards/20926-kubernetes-networking-dns-workload/)
- 삭제(워크로드): 지정된 워크로드(예: 배포 또는 DaemonSet의 Pod)에 대한 삭제를 표시합니다.( ID: 20927).
- Pod 흐름(네임스페이스): 지정된 네임스페이스(즉, 네임스페이스의 Pod)를 오가는 L4/L7 패킷 흐름을 보여 줍니다. (ID: 20928)
- Pod 흐름(워크로드): 지정된 워크로드(예: 배포 또는 DaemonSet의 Pod)를 오가는 L4/L7 패킷 흐름을 보여 줍니다.( ID: 20929)
참고 항목
- Prometheus/Grafana 인스턴스의 설정에 따라 일부 대시보드 패널에서 모든 데이터를 표시하기 위해 조정이 필요할 수 있습니다.
- Cilium은 현재 DNS 메트릭/대시보드를 지원하지 않습니다.
Hubble CLI 설치
다음 명령을 사용하여 수집된 데이터에 액세스하려면 Hubble CLI를 설치합니다.
# Set environment variables
export HUBBLE_VERSION=v1.16.3
export HUBBLE_ARCH=amd64
#Install Hubble CLI
if [ "$(uname -m)" = "aarch64" ]; then HUBBLE_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-${HUBBLE_ARCH}.tar.gz{,.sha256sum}
sha256sum --check hubble-linux-${HUBBLE_ARCH}.tar.gz.sha256sum
sudo tar xzvfC hubble-linux-${HUBBLE_ARCH}.tar.gz /usr/local/bin
rm hubble-linux-${HUBBLE_ARCH}.tar.gz{,.sha256sum}
Hubble 흐름 시각화
Hubble Pod가
kubectl get pods
명령을 사용하여 실행 중인지 확인합니다.kubectl get pods -o wide -n kube-system -l k8s-app=hubble-relay
출력은 다음 예제 출력과 비슷하게 됩니다.
hubble-relay-7ddd887cdb-h6khj 1/1 Running 0 23h
kubectl port-forward
명령을 사용하여 Hubble Relay에 대한 포트 전달을 수행합니다.kubectl port-forward -n kube-system svc/hubble-relay --address 127.0.0.1 4245:443
mTLS(상호 TLS)는 Hubble Relay 서버의 보안을 보장합니다. Hubble 클라이언트가 흐름을 검색할 수 있도록 하려면 적절한 인증서를 가져와서 클라이언트를 구성해야 합니다. 다음 명령을 사용하여 인증서를 적용합니다.
#!/usr/bin/env bash set -euo pipefail set -x # Directory where certificates will be stored CERT_DIR="$(pwd)/.certs" mkdir -p "$CERT_DIR" declare -A CERT_FILES=( ["tls.crt"]="tls-client-cert-file" ["tls.key"]="tls-client-key-file" ["ca.crt"]="tls-ca-cert-files" ) for FILE in "${!CERT_FILES[@]}"; do KEY="${CERT_FILES[$FILE]}" JSONPATH="{.data['${FILE//./\\.}']}" # Retrieve the secret and decode it kubectl get secret hubble-relay-client-certs -n kube-system \ -o jsonpath="${JSONPATH}" | \ base64 -d > "$CERT_DIR/$FILE" # Set the appropriate hubble CLI config hubble config set "$KEY" "$CERT_DIR/$FILE" done hubble config set tls true hubble config set tls-server-name instance.hubble-relay.cilium.io
kubectl get secrets
명령을 사용하여 비밀이 생성되었는지 확인합니다.kubectl get secrets -n kube-system | grep hubble-
출력은 다음 예제 출력과 비슷하게 됩니다.
kube-system hubble-relay-client-certs kubernetes.io/tls 3 9d kube-system hubble-relay-server-certs kubernetes.io/tls 3 9d kube-system hubble-server-certs kubernetes.io/tls 3 9d
Hubble Relay Pod가
hubble observe
명령을 사용하여 실행 중인지 확인합니다.hubble observe --pod hubble-relay-7ddd887cdb-h6khj
Hubble UI를 사용하여 시각화
Hubble UI를 사용하려면 다음을 hubble-ui.yaml에 저장합니다.
apiVersion: v1 kind: ServiceAccount metadata: name: hubble-ui namespace: kube-system --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: hubble-ui labels: app.kubernetes.io/part-of: retina rules: - apiGroups: - networking.k8s.io resources: - networkpolicies verbs: - get - list - watch - apiGroups: - "" resources: - componentstatuses - endpoints - namespaces - nodes - pods - services verbs: - get - list - watch - apiGroups: - apiextensions.k8s.io resources: - customresourcedefinitions verbs: - get - list - watch - apiGroups: - cilium.io resources: - "*" verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: hubble-ui labels: app.kubernetes.io/part-of: retina roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: hubble-ui subjects: - kind: ServiceAccount name: hubble-ui namespace: kube-system --- apiVersion: v1 kind: ConfigMap metadata: name: hubble-ui-nginx namespace: kube-system data: nginx.conf: | server { listen 8081; server_name localhost; root /app; index index.html; client_max_body_size 1G; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # CORS add_header Access-Control-Allow-Methods "GET, POST, PUT, HEAD, DELETE, OPTIONS"; add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 1728000; add_header Access-Control-Expose-Headers content-length,grpc-status,grpc-message; add_header Access-Control-Allow-Headers range,keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout; if ($request_method = OPTIONS) { return 204; } # /CORS location /api { proxy_http_version 1.1; proxy_pass_request_headers on; proxy_hide_header Access-Control-Allow-Origin; proxy_pass http://127.0.0.1:8090; } location / { try_files $uri $uri/ /index.html /index.html; } # Liveness probe location /healthz { access_log off; add_header Content-Type text/plain; return 200 'ok'; } } } --- kind: Deployment apiVersion: apps/v1 metadata: name: hubble-ui namespace: kube-system labels: k8s-app: hubble-ui app.kubernetes.io/name: hubble-ui app.kubernetes.io/part-of: retina spec: replicas: 1 selector: matchLabels: k8s-app: hubble-ui template: metadata: labels: k8s-app: hubble-ui app.kubernetes.io/name: hubble-ui app.kubernetes.io/part-of: retina spec: serviceAccountName: hubble-ui automountServiceAccountToken: true containers: - name: frontend image: mcr.microsoft.com/oss/cilium/hubble-ui:v0.12.2 imagePullPolicy: Always ports: - name: http containerPort: 8081 livenessProbe: httpGet: path: /healthz port: 8081 readinessProbe: httpGet: path: / port: 8081 resources: {} volumeMounts: - name: hubble-ui-nginx-conf mountPath: /etc/nginx/conf.d/default.conf subPath: nginx.conf - name: tmp-dir mountPath: /tmp terminationMessagePolicy: FallbackToLogsOnError securityContext: {} - name: backend image: mcr.microsoft.com/oss/cilium/hubble-ui-backend:v0.12.2 imagePullPolicy: Always env: - name: EVENTS_SERVER_PORT value: "8090" - name: FLOWS_API_ADDR value: "hubble-relay:443" - name: TLS_TO_RELAY_ENABLED value: "true" - name: TLS_RELAY_SERVER_NAME value: ui.hubble-relay.cilium.io - name: TLS_RELAY_CA_CERT_FILES value: /var/lib/hubble-ui/certs/hubble-relay-ca.crt - name: TLS_RELAY_CLIENT_CERT_FILE value: /var/lib/hubble-ui/certs/client.crt - name: TLS_RELAY_CLIENT_KEY_FILE value: /var/lib/hubble-ui/certs/client.key livenessProbe: httpGet: path: /healthz port: 8090 readinessProbe: httpGet: path: /healthz port: 8090 ports: - name: grpc containerPort: 8090 resources: {} volumeMounts: - name: hubble-ui-client-certs mountPath: /var/lib/hubble-ui/certs readOnly: true terminationMessagePolicy: FallbackToLogsOnError securityContext: {} nodeSelector: kubernetes.io/os: linux volumes: - configMap: defaultMode: 420 name: hubble-ui-nginx name: hubble-ui-nginx-conf - emptyDir: {} name: tmp-dir - name: hubble-ui-client-certs projected: defaultMode: 0400 sources: - secret: name: hubble-relay-client-certs items: - key: tls.crt path: client.crt - key: tls.key path: client.key - key: ca.crt path: hubble-relay-ca.crt --- kind: Service apiVersion: v1 metadata: name: hubble-ui namespace: kube-system labels: k8s-app: hubble-ui app.kubernetes.io/name: hubble-ui app.kubernetes.io/part-of: retina spec: type: ClusterIP selector: k8s-app: hubble-ui ports: - name: http port: 80 targetPort: 8081
다음 명령을 사용하여 Hubble-ui.yaml 매니페스트를 클러스터에 적용합니다.
kubectl apply -f hubble-ui.yaml
kubectl port-forward
명령을 사용하여 Hubble UI에 대한 포트 전달을 설정합니다.kubectl -n kube-system port-forward svc/hubble-ui 12000:80
웹 브라우저에
http://localhost:12000/
을 입력하여 Hubble UI에 액세스합니다.
리소스 정리
이 애플리케이션을 사용할 플랜이 없는 경우 az group delete
명령을 사용하여 이 문서에서 만든 다른 리소스를 삭제합니다.
az group delete --name $RESOURCE_GROUP
다음 단계
이 방법 문서에서는 AKS 클러스터에 대해 Container Network Observability를 설치하고 사용하도록 설정하는 방법을 알아보았습니다.
AKS(Azure Kubernetes Service)용 고급 컨테이너 네트워킹 서비스에 대한 자세한 내용은 AKS(Azure Kubernetes Service)용 고급 컨테이너 네트워킹 서비스란?을 참조하세요.
Container Network Security 및 해당 기능에 대한 자세한 내용은 Container Network Security란?을 참조하세요.
Azure Kubernetes Service