Configurar un servidor de registros central

En esta página se describe cómo configurar un servidor de registros central para dispositivos de appliance aislados de Google Distributed Cloud (GDC) a través de la organización del centro de datos aislado de Google Distributed Cloud.

Para crear una ubicación de registro central, el dispositivo de GDC debe tener los siguientes componentes en la organización del centro de datos de GDC:

  • proyecto único
  • del segmento de los registros de auditoría
  • contenedor de registros operativos

Crear un proyecto

Los pasos siguientes deben realizarse en la organización del centro de datos de GDC a la que se exportarán los registros.

  1. Define KUBECONFIG en la API Org Management:

    export KUBECONFIG=ORG_MANAGEMENT_API_KUBECONFIG_PATH
    
  2. Para obtener los permisos que necesitas para exportar registros, pide al administrador de gestión de identidades y accesos de tu organización que te conceda el rol ClusterRole Project Creator (ClusterRole project-creator). Para obtener más información sobre estos roles, consulta Preparar permisos de gestión de identidades y accesos.

  3. Aplica el recurso personalizado del proyecto para crear un proyecto único para el dispositivo de GDC desde el que se exportarán los registros:

    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
    
  4. Comprueba si el nuevo proyecto está disponible en el dispositivo de GDC:

    kubectl get namespace APPLIANCE_PROJECT_NAME
    
  5. Vincula tu nuevo proyecto a una cuenta de facturación. Para hacer un seguimiento de los costes de los recursos de un proyecto, debe tener una cuenta de facturación asociada vinculada al proyecto.

  6. Para obtener los permisos que necesitas para exportar registros, pide al administrador de gestión de identidades y accesos de tu organización que te conceda el rol de administrador de gestión de identidades y accesos de proyecto (project-iam-admin) en el espacio de nombres APPLIANCE_PROJECT_NAME.

Crear un segmento

El administrador de la plataforma debe seguir los pasos que se indican a continuación en la organización del centro de datos de GDC a la que se exportarán los registros.

  1. Define KUBECONFIG en la API Org Management:

    export KUBECONFIG=ORG_MANAGEMENT_API_KUBECONFIG_PATH
    
  2. Para obtener los permisos que necesitas para exportar registros, pide al administrador de gestión de identidades y accesos de tu organización que te conceda el rol Administrador de segmentos de proyecto (project-bucket-admin) en el espacio de nombres APPLIANCE_PROJECT_NAME.

  3. Aplica el recurso personalizado de segmento para crear un segmento:

    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
    
  4. Una vez creado el contenedor, ejecuta el siguiente comando para confirmar y comprobar los detalles del contenedor:

    kubectl describe buckets BUCKET_NAME -n APPLIANCE_PROJECT_NAME
    
  5. Crea un ProjectServiceAccount para acceder a los objetos del segmento.

    kubectl apply -f - <<EOF
    ---
    apiVersion: resourcemanager.gdc.goog/v1
    kind: ProjectServiceAccount
    metadata:
      name: BUCKET_NAME-read-write-sa
      namespace: APPLIANCE_PROJECT_NAME
    spec: {}
    EOF
    
  6. Verifica que se haya propagado ProjectServiceAccount:

    kubectl get projectserviceaccount BUCKET_NAME-read-write-sa -n APPLIANCE_PROJECT_NAME -o json | jq '.status'
    
  7. Asegúrate de que se hayan añadido los permisos ServiceAccount, read y write al segmento.

    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
    
  8. Obtén el secreto que contiene las credenciales de acceso al segmento:

    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'
    

    La salida debe tener el siguiente aspecto, donde se muestra el nombre secreto del contenedor:

    "object-storage-key-sysstd-sa-olxv4dnwrwul4bshu37ikebgovrnvl773owaw3arx225rfi56swa"
    
  9. Exporta el valor a una variable:

    export BUCKET_RW_SECRET_NAME=BUCKET_RW_SECRET_NAME
    
  10. Obtén el ID de la clave para acceder al bucket:

    kubectl get secret $BUCKET_RW_SECRET_NAME -n appliance-xyz -o json | jq -r '.data."access-key-id"' | base64 -di
    

    La salida debe tener el siguiente aspecto:

    PCEW2HU47Y8ACUWQO4SK
    
  11. Obtén la clave de acceso secreta del segmento:

    kubectl get secret $BUCKET_RW_SECRET_NAME -n appliance-xyz -o json | jq -r '.data."secret-access-key"' | base64 -di
    

    La salida debe tener el siguiente aspecto:

    TzGdAbgp4h2i5UeiYa9k09rNPFQ2tkYADs67+65E
    
  12. Obtén el endpoint del contenedor:

    kubectl get bucket BUCKET_NAME -n APPLIANCE_PROJECT_NAME -o json | jq '.status.endpoint'
    

    La salida debe tener el siguiente aspecto:

    https://objectstorage.org-1.zone1.google.gdch.test
    
  13. Obtén el nombre completo del segmento:

    kubectl get bucket BUCKET_NAME -n APPLIANCE_PROJECT_NAME -o json | jq '.status.fullyQualifiedName'
    

    La salida debe tener el siguiente aspecto:

    aaaoa9a-logs-bucket
    

Transferir datos de GDC

Sigue los pasos que se indican en Exportar registros a un segmento remoto para transferir los registros del dispositivo de GDC al segmento creado anteriormente en el centro de datos aislado de GDC mediante el endpoint del segmento, el nombre completo, el ID de clave de acceso y la clave de acceso secreta.

Configurar Loki y Grafana en un centro de datos aislado de Google Distributed Cloud

El operador de infraestructura debe seguir los pasos que se indican a continuación en la organización del centro de datos aislado de GDC al que se han exportado los registros.

Obtener roles de gestión de identidades y accesos

Para obtener los permisos que necesitas para exportar registros, pide a tu administrador de gestión de identidades y accesos de la organización que te conceda el rol Administrador de restauración de registros (logs-restore-admin) en el espacio de nombres obs-system del clúster de infraestructura y los roles Lector de fuentes de datos (datasource-viewer) y Editor de fuentes de datos (datasource-editor) en el espacio de nombres obs-system del plano de gestión.

Configurar Loki

  1. Define KUBECONFIG en el clúster de infraestructura de la organización:

    export KUBECONFIG=ORG_INFRA_CLUSTER_KUBECONFIG_PATH
    
  2. Obtén el ID de clave de acceso y la clave de acceso secreta del segmento de registros del dispositivo de la PA y crea un secreto que contenga las credenciales en el espacio de nombres 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
    
  3. Obtén el endpoint y el nombre completo del segmento de registros del dispositivo desde el PA y crea un 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
    
  4. Crea un statefulset y un servicio de Loki:

    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
    

Configurar Grafana DataSource

  1. Define KUBECONFIG en la API Org Management:

    export KUBECONFIG=ORG_MANAGEMENT_API_KUBECONFIG_PATH
    
  2. Crea DataSources para los registros de infraestructura y plataforma:

    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
    

Ver registros en Grafana de un centro de datos aislado de Google Distributed Cloud

Los registros exportados al segmento del centro de datos aislado de Google Distributed Cloud se pueden ver en la instancia de Grafana del proyecto del dispositivo GDC.