이 페이지에서는 Google Distributed Cloud (GDC) 오프라인 어플라이언스 기기의 중앙 로그 서버를 Google Distributed Cloud 오프라인 데이터 센터 조직을 통해 설정하는 방법을 설명합니다.
중앙 로깅 위치를 만들려면 GDC 어플라이언스에 GDC 데이터 센터 조직에 다음 구성요소가 있어야 합니다.
- 고유 프로젝트
- 감사 로그 버킷
- 운영 로그 버킷
프로젝트 만들기
다음 단계는 로그가 내보내질 GDC 데이터 센터 조직에서 실행해야 합니다.
KUBECONFIG
을 조직 관리 API로 설정합니다.export KUBECONFIG=ORG_MANAGEMENT_API_KUBECONFIG_PATH
로그를 내보내는 데 필요한 권한을 얻으려면 조직 IAM 관리자에게 ClusterRole Project Creator (
ClusterRole project-creator
) 역할을 부여해 달라고 요청하세요. 이러한 역할에 대한 자세한 내용은 IAM 권한 준비를 참고하세요.프로젝트 커스텀 리소스를 적용하여 로그가 내보내질 GDC 어플라이언스용 고유 프로젝트를 만듭니다.
kubectl apply -f - <<EOF apiVersion: resourcemanager.gdc.goog/v1 kind: Project metadata: namespace: platform name: APPLIANCE_PROJECT_NAME labels: object.gdc.goog/tenant-category: user EOF
새 프로젝트가 GDC 어플라이언스에서 사용 가능한지 확인합니다.
kubectl get namespace APPLIANCE_PROJECT_NAME
새 프로젝트를 결제 계정에 연결합니다. 프로젝트 리소스 비용을 추적하려면 프로젝트에 연결된 결제 계정이 있어야 합니다.
로그를 내보내는 데 필요한 권한을 얻으려면 조직 IAM 관리자에게
APPLIANCE_PROJECT_NAME
네임스페이스에서 프로젝트 IAM 관리자 (project-iam-admin
) 역할을 부여해 달라고 요청하세요.
버킷 만들기
다음 단계는 로그가 내보내질 GDC 데이터 센터 조직의 플랫폼 관리자 (PA)가 실행해야 합니다.
KUBECONFIG
을 조직 관리 API로 설정합니다.export KUBECONFIG=ORG_MANAGEMENT_API_KUBECONFIG_PATH
로그를 내보내는 데 필요한 권한을 얻으려면 조직 IAM 관리자에게
APPLIANCE_PROJECT_NAME
네임스페이스에서 프로젝트 버킷 관리자 (project-bucket-admin
) 역할을 부여해 달라고 요청하세요.버킷 커스텀 리소스를 적용하여 버킷을 만듭니다.
apiVersion: object.gdc.goog/v1 kind: Bucket metadata: name: BUCKET_NAME namespace: APPLIANCE_PROJECT_NAME labels: object.gdc.goog/bucket-type: normal object.gdc.goog/encryption-version: v2 object.gdc.goog/tenant-category: user spec: description: Bucket for storing appliance xyz audit logs location: zone1 storageClass: Standard
버킷이 생성된 후 다음을 실행하여 버킷의 세부정보를 확인합니다.
kubectl describe buckets BUCKET_NAME -n APPLIANCE_PROJECT_NAME
버킷의 객체에 액세스하기 위한
ProjectServiceAccount
를 만듭니다.kubectl apply -f - <<EOF --- apiVersion: resourcemanager.gdc.goog/v1 kind: ProjectServiceAccount metadata: name: BUCKET_NAME-read-write-sa namespace: APPLIANCE_PROJECT_NAME spec: {} EOF
ProjectServiceAccount
이 전파되는지 확인합니다.kubectl get projectserviceaccount BUCKET_NAME-read-write-sa -n APPLIANCE_PROJECT_NAME -o json | jq '.status'
ServiceAccount
에read
및write
권한이 버킷에 추가되었는지 확인합니다.kubectl apply -f - <<EOF --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: BUCKET_NAME-read-write-role namespace: APPLIANCE_PROJECT_NAME rules: - apiGroups: - object.gdc.goog resourceNames: - BUCKET_NAME resources: - buckets verbs: - read-object - write-object --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: BUCKET_NAME-read-write-rolebinding namespace: APPLIANCE_PROJECT_NAME roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: BUCKET_NAME-read-write-role subjects: - kind: ServiceAccount name: BUCKET_NAME-read-write-sa namespace: APPLIANCE_PROJECT_NAME EOF
버킷의 액세스 사용자 인증 정보가 포함된 보안 비밀을 가져옵니다.
kubectl get secret -n APPLIANCE_PROJECT_NAME -o json| jq --arg jq_src BUCKET_NAME-read-write-sa '.items[].metadata|select(.annotations."object.gdc.goog/subject"==$jq_src)|.name'
출력은 다음 예시와 같이 버킷의 보안 비밀 이름이 표시되어야 합니다.
"object-storage-key-sysstd-sa-olxv4dnwrwul4bshu37ikebgovrnvl773owaw3arx225rfi56swa"
값을 변수로 내보냅니다.
export BUCKET_RW_SECRET_NAME=BUCKET_RW_SECRET_NAME
버킷 액세스 권한의 키 ID를 가져옵니다.
kubectl get secret $BUCKET_RW_SECRET_NAME -n appliance-xyz -o json | jq -r '.data."access-key-id"' | base64 -di
출력은 다음 예시와 같이 표시되어야 합니다.
PCEW2HU47Y8ACUWQO4SK
버킷의 보안 비밀 액세스 키를 가져옵니다.
kubectl get secret $BUCKET_RW_SECRET_NAME -n appliance-xyz -o json | jq -r '.data."secret-access-key"' | base64 -di
출력은 다음 예시와 같이 표시되어야 합니다.
TzGdAbgp4h2i5UeiYa9k09rNPFQ2tkYADs67+65E
버킷의 엔드포인트를 가져옵니다.
kubectl get bucket BUCKET_NAME -n APPLIANCE_PROJECT_NAME -o json | jq '.status.endpoint'
출력은 다음 예시와 같이 표시되어야 합니다.
https://objectstorage.org-1.zone1.google.gdch.test
버킷의 정규화된 이름을 가져옵니다.
kubectl get bucket BUCKET_NAME -n APPLIANCE_PROJECT_NAME -o json | jq '.status.fullyQualifiedName'
출력은 다음 예시와 같이 표시되어야 합니다.
aaaoa9a-logs-bucket
GDC에서 데이터 전송
원격 버킷으로 로그 내보내기에 따라 버킷의 엔드포인트, 정규화된 이름, 액세스 키 ID, 보안 비밀 액세스 키를 사용하여 GDC 어플라이언스에서 이전에 GDC 에어갭 데이터 센터에서 만든 버킷으로 로그를 전송합니다.
Google Distributed Cloud(에어 갭 적용형) 데이터 센터에서 Loki 및 Grafana 설정
다음 단계는 로그가 내보내진 GDC 오프라인 데이터 센터 조직의 인프라 운영자 (IO)가 수행해야 합니다.
IAM 역할 획득
로그를 내보내는 데 필요한 권한을 얻으려면 조직 IAM 관리자에게 인프라 클러스터의 obs-system
네임스페이스에 로그 복원 관리자 (logs-restore-admin
) 역할을 부여해 달라고 요청하고 관리 평면의 obs-system
네임스페이스에 데이터 소스 뷰어 (datasource-viewer
) 및 데이터 소스 편집자 (datasource-editor
) 역할을 부여해 달라고 요청하세요.
Loki 설정
KUBECONFIG
을 조직 인프라 클러스터로 설정합니다.export KUBECONFIG=ORG_INFRA_CLUSTER_KUBECONFIG_PATH
PA에서 어플라이언스 로그 버킷의 액세스 키 ID와 보안 비밀 액세스 키를 가져오고
obs-system
네임스페이스에 사용자 인증 정보를 포함하는 보안 비밀을 만듭니다.kubectl create secret generic -n obs-system APPLIANCE_LOGS_BUCKET_SECRET_NAME --from-literal=access-key-id=APPLIANCE_LOGS_BUCKET_ACCESS_KEY_ID --from-literal=secret-access-key=APPLIANCE_LOGS_BUCKET_SECRET_ACCESS_KEY
PA에서 어플라이언스 로그 버킷의 엔드포인트와 정규화된 이름을 가져와 Loki
configmap
를 만듭니다.kubectl apply -f - <<EOF --- apiVersion: v1 kind: ConfigMap metadata: name: CONFIGMAP_NAME namespace: obs-system data: loki.yaml: |- auth_enabled: true common: ring: kvstore: store: inmemory compactor: working_directory: /data/loki/compactor compaction_interval: 10m retention_enabled: true retention_delete_delay: 2h retention_delete_worker_count: 150 delete_request_store: s3 ingester: chunk_target_size: 1572864 chunk_encoding: snappy max_chunk_age: 2h chunk_idle_period: 90m chunk_retain_period: 30s autoforget_unhealthy: true lifecycler: ring: kvstore: store: inmemory replication_factor: 1 heartbeat_timeout: 10m wal: enabled: false limits_config: discover_service_name: [] retention_period: 48h reject_old_samples: false ingestion_rate_mb: 256 ingestion_burst_size_mb: 256 max_streams_per_user: 20000 max_global_streams_per_user: 20000 max_line_size: 0 per_stream_rate_limit: 256MB per_stream_rate_limit_burst: 256MB shard_streams: enabled: false desired_rate: 3MB schema_config: configs: - from: "2020-10-24" index: period: 24h prefix: index_ object_store: s3 schema: v13 store: tsdb server: http_listen_port: 3100 grpc_server_max_recv_msg_size: 104857600 grpc_server_max_send_msg_size: 104857600 graceful_shutdown_timeout: 60s analytics: reporting_enabled: false storage_config: tsdb_shipper: active_index_directory: /tsdb/index cache_location: /tsdb/index-cache cache_ttl: 24h aws: endpoint: APPLIANCE_LOGS_BUCKET_ENDPOINT bucketnames: APPLIANCE_LOGS_BUCKET_FULLY_QUALIFIED_NAME access_key_id: ${S3_ACCESS_KEY_ID} secret_access_key: ${S3_SECRET_ACCESS_KEY} s3forcepathstyle: true --- EOF
Loki
statefulset
및 서비스를 만듭니다.kubectl apply -f - <<EOF --- apiVersion: apps/v1 kind: StatefulSet metadata: labels: app: STATEFULSET_NAME name: STATEFULSET_NAME namespace: obs-system spec: persistentVolumeClaimRetentionPolicy: whenDeleted: Retain whenScaled: Retain podManagementPolicy: OrderedReady replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: app: STATEFULSET_NAME serviceName: STATEFULSET_NAME template: metadata: labels: app: STATEFULSET_NAME istio.io/rev: default spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - preference: matchExpressions: - key: node-role.kubernetes.io/control-plane operator: DoesNotExist - key: node-role.kubernetes.io/master operator: DoesNotExist weight: 1 podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - STATEFULSET_NAME topologyKey: kubernetes.io/hostname weight: 100 containers: - args: - -config.file=/etc/loki/loki.yaml - -config.expand-env=true - -target=all env: - name: S3_ACCESS_KEY_ID valueFrom: secretKeyRef: key: access-key-ID name: APPLIANCE_LOGS_BUCKET_SECRET_NAME optional: false - name: S3_SECRET_ACCESS_KEY valueFrom: secretKeyRef: key: secret-access-key name: APPLIANCE_LOGS_BUCKET_SECRET_NAME optional: false image: gcr.io/private-cloud-staging/loki:v3.0.1-gke.1 imagePullPolicy: Always livenessProbe: failureThreshold: 3 httpGet: path: /ready port: loki-server scheme: HTTP initialDelaySeconds: 330 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 name: STATEFULSET_NAME ports: - containerPort: 3100 name: loki-server protocol: TCP - containerPort: 7946 name: gossip-ring protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /ready port: loki-server scheme: HTTP initialDelaySeconds: 45 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 resources: limits: ephemeral-storage: 2000Mi memory: 8000Mi requests: cpu: 300m ephemeral-storage: 2000Mi memory: 1000Mi securityContext: readOnlyRootFilesystem: true terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /etc/loki name: config - mountPath: /data name: loki-storage - mountPath: /tsdb name: loki-tsdb-storage - mountPath: /tmp name: temp - mountPath: /tmp/loki/rules-temp name: tmprulepath - mountPath: /etc/ssl/certs name: trust-bundle readOnly: true dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: fsGroup: 10001 runAsGroup: 10001 runAsUser: 10001 terminationGracePeriodSeconds: 4800 volumes: - emptyDir: {} name: temp - emptyDir: {} name: tmprulepath - configMap: defaultMode: 420 name: trust-store-root-ext optional: true name: trust-bundle - configMap: defaultMode: 420 name: CONFIGMAP_NAME name: config updateStrategy: type: RollingUpdate volumeClaimTemplates: - apiVersion: v1 kind: PersistentVolumeClaim metadata: creationTimestamp: null name: loki-storage spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: standard-rwo volumeMode: Filesystem - apiVersion: v1 kind: PersistentVolumeClaim metadata: creationTimestamp: null name: loki-tsdb-storage spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: standard-rwo volumeMode: Filesystem --- apiVersion: v1 kind: Service metadata: name: STATEFULSET_NAME namespace: obs-system spec: internalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - name: loki-server port: 3100 protocol: TCP targetPort: loki-server selector: app: STATEFULSET_NAME sessionAffinity: None type: ClusterIP --- EOF
Grafana 설정 DataSource
KUBECONFIG
을 조직 관리 API로 설정합니다.export KUBECONFIG=ORG_MANAGEMENT_API_KUBECONFIG_PATH
인프라 및 플랫폼 로그에 대한
DataSources
를 만듭니다.kubectl apply -f - <<EOF --- apiVersion: monitoring.private.gdc.goog/v1alpha1 kind: Datasource metadata: name: INFRA_DATASOURCE_NAME namespace: APPLIANCE_PROJECT_NAME-obs-system spec: datasource: access: proxy isDefault: false jsonData: httpHeaderName1: X-Scope-OrgID name: UI_FRIENDLY_NAME orgId: 1 readOnly: true secureJsonData: httpHeaderValue1: infra-obs type: loki uid: INFRA_DATASOURCE_NAME url: http://STATEFULSET_NAME.obs-system.svc:3100 version: 1 withCredentials: false --- apiVersion: monitoring.private.gdc.goog/v1alpha1 kind: Datasource metadata: name: PLATFORM_DATASOURCE_NAME namespace: APPLIANCE_PROJECT_NAME-obs-system spec: datasource: access: proxy isDefault: false jsonData: httpHeaderName1: X-Scope-OrgID name: UI_FRIENDLY_NAME orgId: 1 readOnly: true secureJsonData: httpHeaderValue1: platform-obs type: loki uid: PLATFORM_DATASOURCE_NAME url: http://STATEFULSET_NAME.obs-system.svc:3100 version: 1 withCredentials: false --- EOF
Google Distributed Cloud(에어 갭 적용형) 데이터 센터 Grafana에서 로그 보기
Google Distributed Cloud 에어 갭 데이터 센터 버킷으로 내보낸 로그는 GDC 어플라이언스 프로젝트의 Grafana 인스턴스에서 볼 수 있습니다.