Realiza una actualización en una implementación multizona

En una implementación multizona, las zonas se actualizan de a una y de forma independiente entre sí. No hay una organización global de las actualizaciones en las zonas. Un IO debe realizar una actualización en cada zona de la organización que quiera actualizar a una versión nueva. Como resultado, las organizaciones en diferentes zonas pueden tener versiones diferentes en un momento determinado.

El orden de actualización que se describe en esta página consiste en actualizar la organización raíz y todas las organizaciones de inquilinos en una zona antes de pasar a otra. Los recursos globales se actualizan al final, después de que se actualizan todas las zonas.

En esta página, se describen los pasos para realizar una actualización aislada de Google Distributed Cloud (GDC) en varias zonas. Para ello, se proporciona la siguiente información:

  • Acceso requerido y formas de obtenerlo
  • Qué herramientas necesitas
  • Qué pasos debes seguir antes de realizar una actualización
  • Cómo y en qué secuencia realizar las actualizaciones de los distintos componentes de Distributed Cloud

En la siguiente lista, se define cada uno de los componentes de una actualización:

Versión de destino: Usa la misma versión de destino para todas las zonas.

Una zona a la vez: Actualiza una zona a la vez. Antes de que se active una actualización en una zona, asegúrate de que no se esté ejecutando ninguna actualización en otras zonas.

Recursos globales: Se definen como recursos de Kubernetes implementados en el kube-apiserver global, a diferencia de los recursos zonales que tienen una copia por zona. Los recursos globales siguen un ciclo de vida diferente. Ten en cuenta que solo se deben actualizar al final y una sola vez.

Prepárate

Se proporcionan las URLs para acceder fuera de tu entorno aislado.

Antes de comenzar una actualización, ten en cuenta lo siguiente:

Genera un informe de cumplimiento

En el informe de cumplimiento, se enumeran las organizaciones que cumplen con las siguientes condiciones:

  • no son compatibles
  • No se aplican parches de seguridad críticos.

La generación del informe de cumplimiento es un paso opcional y requiere un IO autenticado que tenga organization-admin role. Para generar el informe, ejecuta el siguiente comando:

  gdcloud system upgrade report-compliance

Para obtener más información sobre los requisitos de preparación, consulta la sección Requisitos previos.

Identity and Access Management

Antes de comenzar una actualización, en cada zona, haz lo siguiente:

  1. Ejecuta gdcloud auth login en el clúster de administrador raíz y en todos los clústeres de administrador de la organización para obtener un archivo kubeconfig.

  2. Sigue las instrucciones del manual de ejecución del proceso de acceso y elevación de privilegios IAM-R0005 para agregar lo siguiente:

    1. ClusterRoleBinding con el ClusterRole de cluster-admin en el clúster de administrador raíz de cada zona
    2. clústeres de administrador de la organización para obtener acceso de administrador temporal.

Pausa las actualizaciones de recursos globales en todas las zonas

Usa el archivo kubeconfig obtenido para pausar todas las actualizaciones de recursos globales en cada zona.

# Pause upgrades to global root admin resources.
kubectl patch kubeapiserver global-root-admin -n global-kube-system -p='{"spec":{"deploymentPolicy":"LocalOnly"}}' --type=merge --kubeconfig=ROOT_ADMIN_KUBECONFIG

# Pause upgrades to global org admin resources.
kubectl patch kubeapiserver global-org-admin -n global-kube-system -p='{"spec":{"deploymentPolicy":"LocalOnly"}}' --type=merge --kubeconfig=ORG_MGMT_API_KUBECONFIG

Actualiza la organización raíz global

A un nivel general, la actualización de la organización raíz global incluye los siguientes pasos:

  1. Actualiza la organización raíz en todas las zonas. Cada zona se actualiza de forma individual.

    Verifica si la zona actual es la principal. El siguiente comando devuelve "true" en la zona principal y no devuelve nada en las zonas no principales.

    kubectl get ObjectStorageAdminNode -o jsonpath='{.items[*].status.isPrimary}' --kubeconfig=ROOT_ADMIN_KUBECONFIG; echo
    
  2. Actualiza los componentes que requieren coordinación entre zonas.

  3. Actualiza los recursos de administrador raíz global.

Verificación previa a la actualización

Actualiza las zonas de a una por vez. Antes de iniciar la actualización de una organización en una zona, conéctate a todas las demás zonas y ejecuta el siguiente comando para asegurarte de que devuelva el estado listo en todas las zonas. Si alguna zona informa que no está lista, no continúes con la actualización. Verifica la organización en esa zona para diagnosticar el problema.

ORG_NAME=root

[[ $(kubectl --kubeconfig=ROOT_ADMIN_KUBECONFIG get org ${ORG_NAME} -n gpc-system -ojsonpath='{.status.conditions[?(@.type=="Ready")].status}') == 'True' ]] && echo ready || echo not ready

1. Descarga y copia el paquete de actualización

En estas instrucciones, se describe cómo comenzar:

  • Descarga un paquete de actualización en un dispositivo con acceso a Internet para copiarlo en una unidad USB.
  • Copia el paquete de actualización de la unidad USB a tu entorno aislado.

Para obtener más contexto, consulta Descarga archivos para descargar los detalles de una distribución de Distributed Cloud y Transferencia de descarga para obtener información sobre el dispositivo de almacenamiento portátil que usas para transferir archivos a tu entorno aislado.

  1. Trabaja con tu PDG de Google para decidir si la actualización es para una implementación de Distributed Cloud operada por un socio y, por lo tanto, debe usar archivos de lanzamiento del modelo del socio.

    PARTNER_OPERATED="IS_PARTNER_OPERATED"
    if [[ ${PARTNER_OPERATED:?} == "true" ]]; then
      RELEASE_SUFFIX="_partner"
      export GCS_BUCKET=private-cloud-release-partner
    else
      RELEASE_SUFFIX=""
      export GCS_BUCKET=private-cloud-release
    fi
    
  2. Descarga el paquete de actualización en tu unidad USB desde una máquina con acceso a Internet. Usa los detalles de la versión y el resumen que te proporcione tu punto de contacto (POC) de Google.

    1. Ejecuta gcloud auth login para acceder al bucket de Cloud Storage.
    2. Ejecuta la secuencia de comandos con --skip-unzip para recuperar el paquete de actualización y la secuencia de comandos de descarga en el directorio actual, como /home/download.

      VERSION=VERSION
      DOWNLOADER=gdch-downloader-prod${RELEASE_SUFFIX}-$VERSION.sh
      gcloud storage cp "gs://${GCS_BUCKET:-private-cloud-release}/$VERSION/$DOWNLOADER*" .
         PUBLIC_KEY=$(cat <<-PUBEND
      -----BEGIN PUBLIC KEY-----
      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEn46iVSyFXsvuKLZ4dVOr2AqlXDnR
      5cKztkpraexHDxn/ozq03EvrdkRmZkSACFfcaEFyitpraidgAx8sPjvzXQ==
      -----END PUBLIC KEY-----
      PUBEND
      )
      echo "${PUBLIC_KEY}" > "key.pub" openssl dgst -sha256 -verify "key.pub" -signature "${DOWNLOADER}.sig" ${DOWNLOADER} && chmod +x $DOWNLOADER && ./$DOWNLOADER --skip-unzip
      
    3. Si vas a realizar la actualización con archivos de lanzamiento del modelo de socio, sigue las instrucciones para preparar los paquetes de software para la distribución del modelo de socio.

  3. Copia la secuencia de comandos del descargador y el directorio gdch en tu unidad USB.

  4. Copia la actualización en la OCIT desde la unidad USB. Coloca los archivos en un lugar similar, como /home/download/.

  5. Vuelve a definir estas variables en el OCIT y extrae la actualización:

    cd /root
    VERSION=VERSION
    DOWNLOADER=gdch-downloader-prod${RELEASE_SUFFIX}-$VERSION.sh
    PUBLIC_KEY=$(cat <<-PUBEND
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEn46iVSyFXsvuKLZ4dVOr2AqlXDnR
    5cKztkpraexHDxn/ozq03EvrdkRmZkSACFfcaEFyitpraidgAx8sPjvzXQ==
    -----END PUBLIC KEY-----
    PUBEND
    )
    echo "${PUBLIC_KEY}" > "key.pub" openssl dgst -sha256 -verify "key.pub" -signature "${DOWNLOADER}.sig" ${DOWNLOADER} && chmod +x $DOWNLOADER && ./$DOWNLOADER --skip-download
    
  6. El descargador habrá desempaquetado la versión en gdch/full-release-1.2.0-gdch.243 (p. ej.,/home/download/gdch/full-release-1.2.0-gdch.243). Asigna esta variable a la ruta completa:

    export ARTIFACTS_ROOT='/home/download/gdch/full-release-RELEASE_VERSION'-gdch.BUILD_NUMBER'
    

2. Configura la actualización de Artifact Registry

Para realizar una actualización correctamente, debes completar lo siguiente:

Envía los artefactos al registro de contenedores

  1. Establece KUBECONFIG en el archivo kubeconfig del clúster de administrador raíz.

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    
  2. Crea el ClusterRoleBindings necesario:

    kubectl create clusterrolebinding io-upgrade-admin --clusterrole=upgrade-admin-dc --user=USER_EMAIL
    
    kubectl create clusterrolebinding io-upgrade-debugger --clusterrole=upgrade-debugger --user=USER_EMAIL
    
  3. Crea el RoleBindings necesario:

    kubectl create rolebinding io-system-artifact-management-secrets-admin --role=system-artifact-management-secrets-admin --user=USER_EMAIL -n anthos-creds
    
    kubectl create rolebinding io-system-artifact-management-admin --role=system-artifact-management-admin --user=USER_EMAIL -n gpc-system
    
    kubectl create rolebinding io-dnssuffix-viewer --role=dnssuffix-viewer --user=USER_EMAIL -n gpc-system
    
  4. Crea RoleBindings necesario para enviar el paquete de OCI:

    kubectl create rolebinding infrastructure-operator-sar-harbor-admin --user=gdch-infra-operator-USER_EMAIL --role=sar-harbor-admin -n gpc-system
    

    El resultado se verá así:

    rolebinding.rbac.authorization.k8s.io/infrastructure-operator-sar-harbor-admin created
    
  5. Sigue las instrucciones que se indican en Cómo cambiar el tamaño del almacenamiento de Artifact Registry para realizar las siguientes acciones:

    1. Verifica el uso de almacenamiento de Artifact Registry en un clúster de administrador y comprueba que haya espacio suficiente para los artefactos que deseas enviar.
    2. Si necesitas aumentar el espacio disponible, sigue los pasos que se indican en Cómo cambiar el tamaño del almacenamiento de Artifact Registry.
  6. Configura Docker:

    cp ${ARTIFACTS_ROOT}/docker-credential-gdcloud /usr/bin
    
  7. Configura Docker para que confíe en el paquete del almacén de confianza.

    REGISTRY=$(kubectl get harborcluster harbor -n harbor-system -o jsonpath='{.spec.externalURL}' 2>/dev/null);
    if [[ -z "$REGISTRY" ]]; then echo "Harbor external URL not found" >&2; exit 1; fi;
    
    HOST=$(echo "$REGISTRY" | sed 's#https://##');
    if [[ -z "$HOST" ]]; then echo "Invalid registry URL" >&2; exit 1; fi;
    
    DIR="/etc/docker/certs.d/$HOST"; FILE="$DIR/ca.crt"; mkdir -p "$DIR"; chmod 755 "$DIR";
    if [[ ! -f "$FILE" ]]; then
       CERT=$(kubectl get secret trust-store-internal-only -n istio-system -o jsonpath='{.data.ca\.crt}' 2>/dev/null);
       if [[ -z "$CERT" ]]; then echo "Certificate secret not found" >&2;
       exit 1;
       fi;
       echo "$CERT" | base64 -d > "$FILE"; chmod 644 "$FILE";
    else echo "Certificate $FILE already exists"; fi
    
  8. Carga los artefactos en el registro de artefactos del clúster de administrador raíz:

    export VERSION=VERSION
    export KUBECONFIG=KUBECONFIG_PATH
    export ARTIFACTS_ROOT=/home/download/gdch/full-release-VERSION
    export PACKAGE_VALIDATION_ROOT_CERT=PACKAGE_VALIDATION_ROOT_CERT_PATH
    
    ${ARTIFACTS_ROOT}/gdcloud auth configure-docker
    ${ARTIFACTS_ROOT}/gdcloud system container-registry load-oci ${ARTIFACTS_ROOT}/oci --pv-root-cert-path=PACKAGE_VALIDATION_ROOT_CERT_PATH --kubeconfig=KUBECONFIG_PATH --use-ip-port=true --show-progress=false
    

    Reemplaza lo siguiente:

    • VERSION: Es la versión de lanzamiento de Distributed Cloud. Por ejemplo, 1.x.y-gdch.z
    • KUBECONFIG_PATH: Es la ruta de acceso al archivo kubeconfig que obtuviste cuando ejecutaste gdcloud auth login en el clúster de administrador raíz.
    • PACKAGE_VALIDATION_ROOT_CERT_PATH: Es la ruta de acceso al certificado raíz de validación del paquete. Debes usar la ruta de acceso predeterminada ${ARTIFACTS_ROOT}/staging_root_ca_certificate.crt. La inclusión de esta ruta de acceso valida los certificados de claves de lanzamiento que se usan para la validación de paquetes.

    Si el comando se ejecutó correctamente, el resultado final será similar al siguiente ejemplo:

    I0911 04:05:01.755927 3463529 monitor.go:94] Monitoring ManualDistribution 10.5.23.4-1.12.4.96-bg4ck, starting time: 04:05:01.                                                  │·······
    I0911 04:05:02.002637 3463529 monitor.go:100] [2/2] artifacts distributed and [0/0/0] inProgress/failed/stopped after 246.689693ms                                              │·······
    I0911 04:05:02.002723 3463529 monitor.go:38] Monitoring DistributionPolicy 10.5.23.4-1.12.4.96-jv5p9, starting time: 04:05:02.                                                  │·······
    I0911 04:05:02.039545 3463529 monitor.go:44] Created after 36.820059ms.                                                                                                         │·······
    I0911 04:05:02.039599 3463529 monitor.go:94] Monitoring ManualDistribution 10.5.23.4-1.12.4.96-jv5p9, starting time: 04:05:02.                                                  │·······
    I0911 04:05:02.045964 3463529 monitor.go:100] [3/3] artifacts distributed and [0/0/0] inProgress/failed/stopped after 6.360571ms                                                │·······
    I0911 04:05:02.045997 3463529 monitor.go:38] Monitoring DistributionPolicy 10.5.23.4-1.12.4.96-bhckh, starting time: 04:05:02.                                                  │·······
    I0911 04:05:02.077418 3463529 monitor.go:44] Created after 31.408176ms.                                                                                                         │·······
    I0911 04:05:02.077464 3463529 monitor.go:94] Monitoring ManualDistribution 10.5.23.4-1.12.4.96-bhckh, starting time: 04:05:02.                                                  │·······
    I0911 04:05:02.239086 3463529 monitor.go:100] [2/2] artifacts distributed and [0/0/0] inProgress/failed/stopped after 161.610475ms                                              │·······
    I0911 04:05:02.239138 3463529 monitor.go:38] Monitoring DistributionPolicy 10.5.23.4-1.12.4.96-xvlbt, starting time: 04:05:02.                                                  │·······
    I0911 04:05:02.248366 3463529 monitor.go:44] Created after 9.220575ms.                                                                                                          │·······
    I0911 04:05:02.248415 3463529 monitor.go:94] Monitoring ManualDistribution 10.5.23.4-1.12.4.96-xvlbt, starting time: 04:05:02.                                                  │·······
    I0911 04:05:02.532191 3463529 monitor.go:100] [1/1] artifacts distributed and [0/0/0] inProgress/failed/stopped after 283.756574ms                                              │·······
    I0911 04:05:02.532236 3463529 monitor.go:38] Monitoring DistributionPolicy 10.5.23.4-1.12.4.96-7k4s4, starting time: 04:05:02.                                                  │·······
    I0911 04:05:02.544529 3463529 monitor.go:44] Created after 12.282657ms.                                                                                                         │·······
    I0911 04:05:02.544579 3463529 monitor.go:94] Monitoring ManualDistribution 10.5.23.4-1.12.4.96-7k4s4, starting time: 04:05:02.                                                  │·······
    I0911 04:05:02.641252 3463529 monitor.go:100] [1/1] artifacts distributed and [0/0/0] inProgress/failed/stopped after 96.652179ms                                               │·······
    I0911 04:05:02.641332 3463529 monitor.go:38] Monitoring DistributionPolicy 10.5.23.4-1.12.4.96-dpj7n, starting time: 04:05:02.                                                  │·······
    I0911 04:05:02.645509 3463529 monitor.go:44] Created after 4.169293ms.                                                                                                          │·······
    I0911 04:05:02.645575 3463529 monitor.go:94] Monitoring ManualDistribution 10.5.23.4-1.12.4.96-dpj7n, starting time: 04:05:02.                                                  │·······
    I0911 04:05:02.839587 3463529 monitor.go:100] [3/3] artifacts distributed and [0/0/0] inProgress/failed/stopped after 194.004999ms                                              │·······
    I0911 04:05:02.839639 3463529 monitor.go:38] Monitoring DistributionPolicy 10.5.23.4-1.12.4.96-fn94p, starting time: 04:05:02.                                                  │·······
    I0911 04:05:02.844001 3463529 monitor.go:44] Created after 4.361378ms.                                                                                                          │·······
    I0911 04:05:02.844034 3463529 monitor.go:94] Monitoring ManualDistribution 10.5.23.4-1.12.4.96-fn94p, starting time: 04:05:02.                                                  │·······
    I0911 04:05:03.041615 3463529 monitor.go:100] [2/2] artifacts distributed and [0/0/0] inProgress/failed/stopped after 197.567981ms                                              │·······
    I0911 04:05:03.041675 3463529 monitor.go:38] Monitoring DistributionPolicy 10.5.23.4-1.12.4.96-4cxxf, starting time: 04:05:03.                                                  │·······
    I0911 04:05:03.047192 3463529 monitor.go:44] Created after 5.499407ms.                                                                                                          │·······
    I0911 04:05:03.047292 3463529 monitor.go:94] Monitoring ManualDistribution 10.5.23.4-1.12.4.96-4cxxf, starting time: 04:05:03.                                                  │·······
    I0911 04:05:03.241688 3463529 monitor.go:100] [76/76] artifacts distributed and [0/0/0] inProgress/failed/stopped after 194.395913ms
    

    Si tu resultado no se parece a este ejemplo, sigue estos pasos para resolver los problemas más habituales:

    • Si el resultado incluye el mensaje Package validation root certificate requires upgrade!, rota el certificado raíz siguiendo los pasos que se detallan en Cómo rotar el certificado de validación de paquetes.
    • Si falla load-oci, vuelve a ejecutar la operación. Si el error persiste, consulta las otras soluciones que se ofrecen en esta lista.
    • Si el resultado incluye el mensaje Error: unable to create k8sclient: Unauthorized, deberás volver a autenticarte. Repite el paso de preparación para verificar el archivo kubeconfig o ejecuta el comando ${ARTIFACTS_ROOT}/gdcloud auth login y vuelve a intentar la operación load-oci.
    • Si el resultado incluye el mensaje UNAUTHORIZED: unauthorized to access repository, significa que no tienes los permisos necesarios para ejecutar el comando load-oci. Deriva este problema para obtener los roles necesarios para ejecutar este comando o pídele a un usuario que tenga los roles necesarios que lo ejecute en tu nombre.
  9. SOLO para la actualización con archivos de lanzamiento de modelos de socios, sigue las instrucciones para cargar los paquetes de software para la distribución de modelos de socios.

  10. Verifica que el objeto ReleaseMetadata para la nueva versión esté en el clúster de administrador raíz:

    kubectl get releasemetadata.artifact.private.gdc.goog VERSION
    

    Reemplaza VERSION por la versión de la versión de Distributed Cloud. Por ejemplo, 1.x.y-gdch.z

    Resultado de ejemplo:

    NAME             AGE
    1.x.y-gdch.z     2m
    
  11. Verifica que la versión nueva esté en la lista de actualizaciones disponibles para la organización raíz que se actualizará:

    ROOT_NAME=root
    kubectl get organization -n gpc-system ${ROOT_NAME} -ojsonpath='{.status.availableUpgrades}{"\n"}'
    

    Por ejemplo, 1.x.y-gdch.z, esperamos el siguiente resultado:

    ["1.x.y-gdch.z"]
    

Después de que la organización raíz se actualiza a una versión nueva, esa versión está disponible para las actualizaciones de una organización arrendataria.

3. Actualiza la organización raíz

3.1. Antes de la actualización

  1. Establece KUBECONFIG en el archivo kubeconfig del clúster de administrador raíz.

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    
  2. Crea el ClusterRoleBindings necesario:

    kubectl create clusterrolebinding io-organization-admin --clusterrole=organization-admin --user=USER_EMAIL
    
  3. Verifica que la organización raíz esté en buen estado, como se muestra en la respuesta True:

    kubectl get organization -n gpc-system root \
        -ojsonpath='{.status.conditions[?(@.type=="Ready")].status}{"\n"}'
    

    Resultado de ejemplo:

    True
    
  4. Sigue las instrucciones del runbook HSM-P0003 para reiniciar todos los HSM.

3.2. Realiza actualizaciones automáticas de la organización raíz

La actualización debe pasar por el proceso de IaC. La actualización se activa cuando se actualiza el campo de versión en el objeto OrganizationZonalConfig correspondiente de la organización en la zona.

  1. Actualiza la versión en el archivo YAML OrganizationZonalConfig. Borra la sección spec.capacities.workloadServers del archivo si existe.

    ORG_NAME=root
    ZONE=$(kubectl --kubeconfig ROOT_ADMIN_KUBECONFIG get controlplane cp -n mz-system -ojsonpath='{.spec.zone}')
    sed -i 's/version: .*$/version: VERSION/' IAC_REPO_PATH/iac/infrastructure/global/orgs/${ORG_NAME}/${ORG_NAME}-${ZONE}.yaml
    
  2. Agrega los cambios del archivo a una etapa previa y confírmalos.

    git add "IAC_REPO_PATH/iac/infrastructure"
    git commit
    
  3. Crea una solicitud de combinación.

    git checkout -b ${USERNAME1}-branch
    git -c http.sslVerify=false push -o merge_request.create origin ${USERNAME1}-branch
    

Cuando comienza la actualización, se crea un objeto OrganizationUpgrade. Verifica que el objeto OrganizationUpgrade raíz se haya creado en el clúster de administración raíz de la zona.

kubectl get -n gpc-system organizationupgrade root -o yaml --kubeconfig ROOT_ADMIN_KUBECONFIG

Si no se encuentra el OrganizationUpgrade, sigue el manual de ejecución IAC-R0001 para solucionar el problema.

3.3. Verificaciones posteriores a la actualización

  1. Verifica los resultados de la actualización:

    1. Verifica el objeto Organization de la organización raíz. Verifica que veas la condición de estado READY como True:

      kubectl -n gpc-system get organization root
      

      Resultado de ejemplo:

      NAME   READY
      root   True
      
    2. Verifica que Organization.Status.Version muestre la cadena exacta 1.x.y-gdch.z:

      kubectl -n gpc-system get organization root -o jsonpath='{.status.version}{"\n"}'
      

      Ejemplo de resultado para la verificación:

      1.13.3-gdch.5548
      
  2. Verifica si hay fallas en los subcomponentes de la organización raíz:

    1. Verifica los subcomponentes que muestran el estado ReconciliationError o Reconciling. Apunta el kubeconfig a ROOT_ADMIN_KUBECONFIG:

      export KUBECONFIG=/root/release/root-admin/root-admin-kubeconfig
      export CLUSTER_NAMESPACE=root
      echo "Subcomponents with failures"
      kubectl get subcomponent -n ${CLUSTER_NAMESPACE} -o json | jq -r '.items[] |  select(.status.conditions[]?.reason == "ReconciliationError") | select(.status.featureDisabled != true) |  "Sub-Component: \(.metadata.name) - \(.status.conditions[]?.message)"'
      echo "Subcomponents still reconciling"
      kubectl get subcomponent -n ${CLUSTER_NAMESPACE} -o json | jq -r '.items[] |  select(.status.conditions[]?.reason == "Reconciling") | select(.status.featureDisabled != true) | select( "\(.status)" | contains("PreinstallPending") | not) | "Sub-Component: \(.metadata.name) - \(.status.conditions[]?.message)"'
      
    2. Si se producen errores, consulta las notas de la versión y los problemas conocidos para encontrar una solución alternativa. De lo contrario , comunícate con Distributed Cloud para solucionar el problema.

  3. Si se omitió la verificación previa o posterior al vuelo, quita las anotaciones después de que finalice la actualización:

    Ejemplos:

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl annotate -n gpc-system organization ORG_NAME \
        upgrade.private.gdc.goog/skip-preflight-check-
    
    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl annotate -n gpc-system organization ORG_NAME \
        upgrade.private.gdc.goog/skip-postflight-check-
    

Finaliza la actualización de la organización raíz en todas las zonas

Después de que se complete una actualización en una zona, se recomienda verificar que la zona siga funcionando correctamente antes de continuar con la actualización de la siguiente zona.

Repite los pasos del 1 al 3 para la organización raíz en el resto de las zonas. Cuando todas las zonas tengan actualizada su organización raíz, continúa con los siguientes pasos.

4. Actualiza los recursos globales

Los recursos globales deben estar en la versión más baja de todas las zonas. Para iniciar el proceso de actualización de recursos globales, conéctate a la zona de anclaje y ejecuta los siguientes comandos.

# Annotate appropriate versions for all the operable components.
MAP=$(kubectl get kubeapiserver root-admin -n root -ojsonpath='{.metadata.annotations}' --kubeconfig ROOT_ADMIN_KUBECONFIG | jq -r 'to_entries | map("\(.key) \(.value)") | .[] | select(startswith("lcm.private.gdc.goog/oc-version-"))')

echo "${MAP}" | while read KV; do
   SPLIT=(${KV}); KEY=${SPLIT[0]}; VALUE=${SPLIT[1]}
   echo "Annotating global KubeAPIServer with ${KEY}: ${VALUE}"
   kubectl annotate kubeapiserver global-root-admin -n global-kube-system --overwrite ${KEY}=${VALUE} --kubeconfig ROOT_ADMIN_KUBECONFIG
done

# Trigger the global resource upgrade on global root admin.
kubectl annotate kubeapiserver global-root-admin -n global-kube-system --overwrite lcm.private.gdc.goog/paused-remote=false --kubeconfig ROOT_ADMIN_KUBECONFIG
kubectl patch kubeapiserver global-root-admin -n global-kube-system -p='{"spec":{"deploymentPolicy":"AllowAll"}}' --type=merge --kubeconfig ROOT_ADMIN_KUBECONFIG

Este proceso puede tardar unos minutos. Ejecuta los siguientes comandos para verificar que se completaron las actualizaciones de los recursos globales. El comando no debería informar ningún error.

# Verify that Components are all successfully rolled out on global root admin.
echo "${MAP}" | while read KV; do
   SPLIT=(${KV}); VALUE=${SPLIT[1]}; OC=$(echo ${VALUE} | cut -d- -f1)
   [[ -n ${OC} ]] || continue
   ROLLOUT=$(kubectl get componentrollout ${OC} -n global-kube-system -o json --ignore-not-found --kubeconfig ROOT_ADMIN_KUBECONFIG)
   [[ -n ${ROLLOUT} ]] || continue
   if [[ $(echo ${ROLLOUT} | jq -r '.spec.componentRef.name') != ${VALUE} ]] ; then
      echo "${OC} rollout trigger failed"; continue
   fi
   if [[ $(echo ${ROLLOUT} | jq -r '.status.allSubcomponentsReady') != 'true' ]] ; then
      echo "${OC} rollout completion failed. Use 'kubectl describe componentrollout ${OC} -n global-kube-system --kubeconfig ROOT_ADMIN_KUBECONFIG' to check for error messages."
   fi
done && echo "Global component rollout check finished."

5. Actualizaciones de componentes entre zonas

En un universo multizona de GDC, ciertos componentes operables requieren coordinación entre las zonas para completar sus actualizaciones.

En este paso, se actualizan los siguientes componentes operativos.

Alcance Componentes operativos
Infraestructura IAC
Infraestructura SIEM

Para actualizar el componente operable del IAC, sigue el runbook IAC-R0016.

Para actualizar el componente operable del SIEM, sigue el manual de operaciones SIEM-G0008.

6. Actualización manual de la subred de Anycast

Ejecuta la siguiente secuencia de comandos para agregar las etiquetas necesarias a las subredes de Anycast en el servidor de la API raíz global:

#!/bin/bash

# Description:
# This script ensures that specific Subnet resources in Kubernetes have the
# correct label applied. This is necessary for anycast features to function correctly.
#
# The script is idempotent and can be run multiple times safely.
# It requires the path to a valid global root kubeconfig file as a command-line argument.

# --- Configuration ---
set -o nounset

# The names of the Subnet resources to update.
readonly SUBNET_NAMES=(
  "infra-vpc-anycast-cidr"
  "data-global-anycast-cidr"
  "admin-global-anycast-cidr"
)

# The label that will be applied to the subnets.
readonly LABEL_KEY="ipam.gdc.goog/usage"
readonly LABEL_VALUE="global-anycast-root-range"

# The Kubernetes resource type for the subnets.
readonly SUBNET_RESOURCE_TYPE="subnets"

# Timeout for kubectl commands in seconds.
readonly KUBECTL_TIMEOUT="30s"

log_error() {
  echo "[ERROR] $(date +'%Y-%m-%dT%H:%M:%S%z'): $*" >&2
}

main() {
  # --- Argument Validation ---
  if [[ $# -ne 1 ]]; then
    echo "Usage: $0 <path-to-kubeconfig-file>"
    echo "Example: $0 /root/release/root-admin/global-root-admin-kubeconfig"
    exit 1
  fi

  local KUBECONFIG_PATH="$1"

  if [[ ! -f "${KUBECONFIG_PATH}" ]]; then
      log_error "Kubeconfig file not found at: ${KUBECONFIG_PATH}"
      exit 1
  fi

  if ! command -v kubectl &> /dev/null; then
    log_error "kubectl command not found. Please ensure it is installed and in your system's PATH."
    exit 1
  fi

  if ! command -v timeout &> /dev/null; then
    log_error "timeout command not found. Please ensure 'coreutils' is installed."
    exit 1
  fi

  if ! command -v jq &> /dev/null; then
    log_error "jq command not found. Please ensure it is installed and in your system's PATH."
    exit 1
  fi

  echo "Starting Subnet labeling process using kubeconfig: ${KUBECONFIG_PATH}"

  # --- Pre-flight Check and Data Fetch ---
  echo "Verifying access and fetching all Subnet resources (timeout in ${KUBECTL_TIMEOUT})..."
  local all_subnets_json

  if ! all_subnets_json=$(timeout "${KUBECTL_TIMEOUT}" kubectl get --kubeconfig="${KUBECONFIG_PATH}" "${SUBNET_RESOURCE_TYPE}" --all-namespaces -o json 2>/dev/null); then
      log_error "Failed to list Subnet resources. The command timed out or returned an error. Please check cluster connectivity and permissions."
      exit 1
  fi

  if [[ -z "${all_subnets_json}" ]] || [[ $(jq '.items | length' <<< "${all_subnets_json}") -eq 0 ]]; then
      echo "No subnet resources found in the cluster. Exiting."
      exit 0
  fi
  echo "Access verified. Processing subnets..."

  local processed_count=0
  local found_count=0
  local subnet_regex
  subnet_regex=$(printf "|%s" "${SUBNET_NAMES[@]}")
  subnet_regex="^(${subnet_regex:1})$"

  # jq query to output: namespace  name  label_value (or null)
  echo "${all_subnets_json}" | jq -r ".items[] | [.metadata.namespace, .metadata.name, (.metadata.labels | .[\"${LABEL_KEY}\"] // \"\")] | @tsv" |
  while IFS=$'\t' read -r namespace name current_value; do
    if [[ -z "${name}" ]]; then continue; fi

    if [[ ! "${name}" =~ ${subnet_regex} ]]; then
        continue
    fi

    ((found_count++))
    echo "Found target subnet: '${name}' in namespace '${namespace}'"

    if [[ "${current_value}" == "${LABEL_VALUE}" ]]; then
        echo "  - Subnet already has the correct label. Skipping."
        ((processed_count++))
        continue
    fi

    echo "  - Applying label '${LABEL_KEY}=${LABEL_VALUE}'..."
    if ! timeout "${KUBECTL_TIMEOUT}" kubectl label --kubeconfig="${KUBECONFIG_PATH}" --namespace="${namespace}" "${SUBNET_RESOURCE_TYPE}" "${name}" "${LABEL_KEY}=${LABEL_VALUE}" --overwrite > /dev/null; then
        log_error "Failed to apply label to subnet '${name}' in namespace '${namespace}'. The command timed out or returned an error."
    else
        echo "  - Successfully labeled subnet."
        ((processed_count++))
    fi
  done

  # --- Final Summary ---
  echo "---"
  if [[ ${found_count} -eq 0 ]]; then
    echo "No target anycast subnets were found in the cluster."
  else
    echo "Finished processing. Found ${found_count} and validated ${processed_count} target subnet(s)."
  fi

  echo "Subnet labeling process completed."
}

# Execute the main function with command-line arguments.
main "$@"

Después de que el script se ejecute correctamente, revierte la solución alternativa de transmisión por unidifusión manual si se aplicó anteriormente.

7. Actualización manual de SyncServer

En este paso, se actualizan los siguientes componentes operativos.

Alcance Componentes operativos
Infraestructura NTP

Esta actualización de firmware no depende de ningún otro paso y se puede realizar en cualquier momento.

El clúster solo tiene un SyncServer, por lo que no puede operar en modo de alta disponibilidad. La actualización hará que SyncServer no esté disponible durante un período. El clúster seguirá registrando el tiempo con sus propios relojes menos precisos, lo que no tendrá efectos notables.

Se recomienda completar este proceso de una sola vez (no dejarlo para la noche o el fin de semana) para evitar la desviación del tiempo.

7.1. Proceso de actualización de SyncServer

Los siguientes comandos se deben ejecutar desde el directorio de la versión del paquete de actualización extraído.

  1. Busca el firmware más reciente para la extracción:

    ${ARTIFACTS_ROOT}/gdcloud artifacts tree ${ARTIFACTS_ROOT}/oci/ | grep syncserver | grep -v .sig$
    

    El nombre del archivo contiene la versión del firmware.

    Resultado de ejemplo:

    │   ├── gdch-syncserver-firmware/syncserver:5.1.2
    
  2. Copia solo los nombres de los archivos y asígnalos a estas variables:

    export SYNCSERVER_VERSION=syncserver:5.1.2
    
  3. Extrae el firmware de la imagen de OCI:

    ${ARTIFACTS_ROOT}/gdcloud artifacts extract ${ARTIFACTS_ROOT}/oci syncserver_firmware --image-name=gdch-syncserver-firmware/${SYNCSERVER_VERSION:?}
    
  4. Extrae el firmware:

    tar -xvzf syncserver_firmware/gdch-syncserver-firmware/syncserver.tar.gz
    

    Deberías ver un archivo *.dat y un archivo *updater.zip en el directorio de salida.

  5. Sigue el runbook NTP-P0002: Accede a la IU de SyncServer.

    1. Navega a Help -> About -> Software Version. Si el software instalado es igual o posterior al firmware proporcionado, no es necesario actualizar el firmware y se pueden omitir los siguientes pasos.

    2. Navega a Admin -> Upgrade en la IU de SyncServer. Sube syncserver_s650_license.dat en Authorization File y syncserver_s650_updater.zip en Upgrade File. Luego, haz clic en Instalar.

    Verifica en el panel

Actualiza una organización de inquilino global

A grandes rasgos, la actualización de una organización de inquilino global incluye los siguientes pasos:

  1. Actualiza la organización del arrendatario en todas las zonas. Cada zona se actualiza de forma individual.

    Verifica si la zona actual es la principal. El siguiente comando devuelve "true" en la zona principal y no devuelve nada en las zonas no principales.

    kubectl get ObjectStorageAdminNode -o jsonpath='{.items[*].status.isPrimary}' --kubeconfig=ROOT_ADMIN_KUBECONFIG; echo
    
  2. Actualiza los recursos de la organización del arrendatario global.

Verificación previa a la actualización

Actualiza las zonas de a una por vez. Antes de iniciar la actualización de una organización en una zona, conéctate a todas las demás zonas y ejecuta el siguiente comando para asegurarte de que devuelva el estado listo en todas las zonas. Si alguna zona informa que no está lista, no continúes con la actualización. Verifica la organización en esa zona para diagnosticar el problema.

ORG_NAME=ORG_NAME

[[ $(kubectl --kubeconfig=ROOT_ADMIN_KUBECONFIG get org ${ORG_NAME} -n gpc-system -ojsonpath='{.status.conditions[?(@.type=="Ready")].status}') == 'True' ]] && echo ready || echo not ready

Asegúrate de que todos los clústeres estén en estado de ejecución y que todos los grupos de nodos estén en estado listo. De lo contrario, corrígelos antes de iniciar la actualización.

ORG_NAME=ORG_NAME
kubectl get nodepools -n ${ORG_NAME} --kubeconfig ROOT_ADMIN_KUBECONFIG -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,READY:.status.conditions[?(@.type=="Ready")].status'
# Example output
# NAMESPACE   NAME                                        READY
# org1        admin-control-plane-node-pool               True
# org1        data-plane-pool-o2-standard1-96-gdc-metal   True

kubectl get cluster -n mks-system --kubeconfig ORG_MGMT_API_KUBECONFIG
# Example output
# NAME                    STATE     K8S VERSION
# g-org1-perimeter        Running   1.30.6-gke.300
# g-org1-shared-service   Running   1.30.6-gke.300

kubectl get nodepool -A --kubeconfig ORG_INFRA_KUBECONFIG -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,READY:.status.conditions[?(@.type=="Ready")].status'
# Example output
# NAMESPACE                       NAME                                                     READY
# g-org1-perimeter-cluster        control-plane-node-pool                                  True
# g-org1-perimeter-cluster        perimeter-admin-node-pool                                True
# g-org1-perimeter-cluster        perimeter-data-node-pool                                 True
# g-org1-shared-service-cluster   control-plane-node-pool                                  True
# g-org1-shared-service-cluster   dbs-billing-system-billing-dbcluster-n2-standard-4-gdc   True
# g-org1-shared-service-cluster   shared-service-default-worker                            True

1. Actualiza una organización de arrendatario

En este paso, se actualizan la versión de Kubernetes, los complementos y los componentes operativos en los clústeres del plano de administración de una organización de inquilino: clústeres de administrador de la organización, del sistema y de servicio.

La duración general de la actualización depende de la cantidad de etapas que incluye. La actualización automática de la organización del arrendatario puede ser perjudicial y requiere un período de mantenimiento.

1.1. Preparación

Para configurar períodos de mantenimiento, sigue los pasos que se indican en Configura períodos de mantenimiento para la actualización de la organización del arrendatario.

Se proporcionan instrucciones para iniciar una actualización de la organización del arrendatario con los comandos de la CLI de kubectl o los comandos de infraestructura como código (IaC). Para usar los comandos de IaC, primero debes configurar la IaC:

  • Configuración de infraestructura como código
  • Configura la infraestructura como código.

    Para usar nomos y verificar el estado como se menciona en los pasos basados en IaC como una opción, debes tener instalada la herramienta de línea de comandos de nomos. Para obtener instrucciones de instalación y uso de nomos, visita https://cloud.google.com/anthos-config-management/docs/how-to/nomos-command desde una computadora con acceso a Internet.

IaC

Configura el enlace de ClusterRole antes de iniciar la actualización de la organización del arrendatario con IaC

  1. Ve al directorio iac/infrastructure/zonal/zones/ZONE_NAME/{ORG}.
  2. Ve al directorio IO que ya se creó. Si el directorio no existe, crea uno nuevo.
  3. Agrega un archivo YAML para asignar el rol de clúster io-organization-admin a la IO. Por ejemplo:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: iac-binding-$USER-io-organization-admin
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: io-organization-admin
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: User
      name: USER_EMAIL
    
  4. Actualiza el archivo kustomatization.yaml para incluir el nuevo archivo creado. Si el archivo kustomatization.yaml no existe, crea uno nuevo:

    kind: Kustomization
    metadata:
      name: org-1-admin-kustomization
    resources:
    - FILE_NAME.yaml
    
  5. Envía los cambios en la IAC

kubectl

Configura el enlace de ClusterRole antes de iniciar la actualización de la organización del arrendatario con kubectl

  1. Establece KUBECONFIG en el archivo kubeconfig del clúster de administrador raíz.

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG`
    
  2. Crea el ClusterRoleBindings necesario:

    kubectl create clusterrolebinding io-organization-admin --clusterrole=organization-admin --user=USER_EMAIL`
    
  3. Antes de completar una actualización de una versión anterior de Distributed Cloud a la versión 1.13.x o posterior, sigue las instrucciones del runbook BIL-R0014 para generar manualmente una factura de los costos de este mes desde el comienzo del mes hasta el comienzo de la fecha actual. Perderás los datos de costos creados durante el proceso de actualización de la organización de Distributed Cloud.

1.2. Inicia la actualización

La actualización de la organización del arrendatario también se activa a través de la IaC actualizando el campo de versión en el objeto OrganizationZonalConfig correspondiente de la organización en la zona. A continuación, se incluyen los detalles:

  1. Actualiza la versión en el archivo YAML OrganizationZonalConfig.

    ORG_NAME=ORG_NAME
    ZONE=$(kubectl --kubeconfig ROOT_ADMIN_KUBECONFIG get controlplane cp -n mz-system -ojsonpath='{.spec.zone}')
    sed -i 's/version: .*$/version: VERSION/' IAC_REPO_PATH/iac/infrastructure/global/orgs/root/${ORG_NAME}-${ZONE}.yaml
    
  2. Agrega los cambios del archivo a una etapa previa y confírmalos.

    git add "IAC_REPO_PATH/iac/infrastructure"
    git commit
    
  3. Crea una solicitud de combinación.

    git checkout -b ${USERNAME1}-branch
    git -c http.sslVerify=false push -o merge_request.create origin ${USERNAME1}-branch
    

Si se inicia la actualización, se crea un objeto OrganizationUpgrade. Verifica que el objeto OrganizationUpgrade se haya creado en el clúster de administración raíz de la zona.

kubectl get -n gpc-system organizationupgrade ORG_NAME -o yaml --kubeconfig ROOT_ADMIN_KUBECONFIG

Si no se encuentra el OrganizationUpgrade, sigue el manual de ejecución IAC-R0001 para solucionar el problema.

1.3. Actualizar

  1. La actualización se realiza cuando tiene un timeWindow que se encuentra dentro del período de mantenimiento que especifica un usuario administrador, también llamado PA. Sigue estos pasos para ver el timeWindow programado:

    kubectl -n gpc-system get organizationupgrade ORG_NAME -o yaml
    

    A continuación, se muestra una respuesta típica al comando anterior:

    apiVersion: upgrade.private.gdc.goog/v1alpha1
    kind: OrganizationUpgrade
    metadata:
      creationTimestamp: "2022-08-22T01:09:03Z"
      generation: 1
      name: org-1
      namespace: gpc-system
      ownerReferences:
      - apiVersion: resourcemanager.gdc.goog/v1alpha1
        blockOwnerDeletion: true
        controller: true
        kind: Organization
        name: org-1
        uid: 6998cfc1-bee4-4f6d-baf2-9c0a90ef93bb
      resourceVersion: "1214182"
      uid: 1affc1df-b9ac-4343-8e61-18736781a990
    spec:
      currentVersion: 1.8.0-gdch.476
      organizationRef:
        name: org-1
      targetVersion: 1.8.1-gdch.0
      timeWindow:
        end: "2022-08-28T04:00:00Z"
        start: "2022-08-28T00:00:00Z"
    

    En el ejemplo anterior, el programa de actualización a 1.8.1-gdch.0 se encuentra entre "2022-08-28T00:00:00Z" y "2022-08-28T04:00:00Z".

    Cuando comienza la actualización, se crea un objeto OrganizationUpgrade, que se muestra como kind: OrganizationUpgrade en el ejemplo de salida anterior.

    kind: OrganizationUpgrade
    
  2. Supervisa el estado general de la actualización con el objeto de actualización correspondiente. Para ello, agrega -w al comando del paso 1. Por ejemplo, para consultar continuamente ORG_NAME sobre el estado de la actualización, ejecuta el siguiente comando:

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl get -n gpc-system organizationupgrade ORG_NAME -o yaml -w
    
  3. Puedes ver las etapas de la actualización y su estado con lo siguiente:

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl get -n gpc-system organizationupgrade ORG_NAME -o jsonpath='{.status.conditions}' | \
    jq -r '["Stage", "Status", "Reason", "Message"], ["---", "---", "---", "---"], (.[] | [.type, .status, .reason, .message]) | @tsv' | column -ts $'\t'
    

    La etapa Succeeded hace referencia al estado general de la actualización. La etapa Expired se usa para indicar que la actualización superó la hora programada original. Todas las demás etapas hacen referencia a los pasos de la actualización en curso. El estado True hace referencia a los pasos completados, y el estado Unknown, al paso actual de la actualización.

    Si falló una verificación previa y tienes la certeza de que se trata de un falso positivo, anula y omite las opciones de verificación previa:

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl annotate -n gpc-system organization ORG_NAME \
        upgrade.private.gdc.goog/skip-preflight-check=ok
    

    Si falló una verificación posterior a la implementación y tienes la certeza de que el error es un falso positivo, anula y omite las verificaciones posteriores a la implementación:

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl annotate -n gpc-system organization ORG_NAME \
        upgrade.private.gdc.goog/skip-postflight-check=ok
    
  4. Si se usó IAC para actualizar la organización del arrendatario y el estado de organizationupgrade muestra que la operación se realizó correctamente, y Organization para la organización del arrendatario no está en estado Listo, aplica la siguiente solución alternativa.

    Agrega esta anotación: configmanagement.gke.io/managed: disabled usando IAC a la organización. El estado del monitor Organization es Listo.

  5. La actualización de la organización ahora debería pasar a la siguiente etapa, y el estado del servicio o el nodo se completará:

    Last Transition Time: 2024-08-27T22:44:09Z
      Message:             observed the following reason: [JobRunning]
      Observed Generation: 614
      Reason:              Complete
      Status:              True
      Type:                service/Node
    

    La actualización de la organización puede tardar 15 minutos en continuar.

1.4. Verificaciones posteriores a la actualización

  1. Verifica el objeto Organization de la organización. La condición READY debe mostrarse como True.

    kubectl -n gpc-system get organization ORG_NAME
    

    Resultado de ejemplo:

    NAME   READY
    org-1  True
    
  2. Verifica Organization.Status.Version. Debe mostrar la cadena exacta de la versión de destino:

    kubectl -n gpc-system get organization ORG_NAME -o jsonpath='{.status.version}{"\n"}'
    

    Resultado de ejemplo:

    1.13.3-gdch.5548
    

    Para revertir la anotación y que ignore los períodos de mantenimiento, haz lo siguiente:

    kubectl annotate organization ORG_NAME -n=gpc-system  \
        "upgrade.private.gdc.goog/ignore-maintenance-window-" \
        --kubeconfig=ROOT_ADMIN_KUBECONFIG
    
  3. Verifica si hay fallas en los subcomponentes de la organización del arrendatario actualizada :

    1. Verifica los subcomponentes que muestran el estado ReconciliationError o Reconciling. Apunta el kubeconfig a ORG_MGMT_API_KUBECONFIG:

      export KUBECONFIG=ORG_MGMT_API_KUBECONFIG
      
      echo "Subcomponents with failures"
      kubectl get subcomponent -A -o json | jq -r '.items[] |  select(.status.conditions[]?.reason == "ReconciliationError") |  "Sub-Component: \(.metadata.name) - \(.status.conditions[]?.message)"'
      echo "Subcomponents still reconciling"
      kubectl get subcomponent -A -o json | jq -r '.items[] |  select(.status.conditions[]?.reason == "Reconciling") | select( "\(.status)" | contains("PreinstallPending") | not) | "Sub-Component: \(.metadata.name) - \(.status.conditions[]?.message)"'
      
    2. Si se producen errores, consulta las notas de la versión y los problemas conocidos para encontrar una solución alternativa. De lo contrario, comunícate con Distributed Cloud para solucionar el problema.

  4. Si se omitió la verificación previa o posterior al vuelo, quita las anotaciones después de que finalice la actualización:

    Ejemplos:

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl annotate -n gpc-system organization ORG_NAME \
        upgrade.private.gdc.goog/skip-preflight-check-
    
    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl annotate -n gpc-system organization ORG_NAME \
        upgrade.private.gdc.goog/skip-postflight-check-
    

1.5. Cómo iniciar una actualización no programada

Activa una actualización instantánea de la organización del arrendatario fuera de un maintenanceWindow si tienes una necesidad urgente, como un parche de seguridad urgente. Esto solo es necesario en la organización del arrendatario, ya que la organización raíz ya activa la actualización de forma instantánea.

Ejecuta este comando con el kubeconfig de administrador raíz. El recurso personalizado de la organización que debes anotar solo está presente en el clúster de administrador raíz. No programes un período para este proceso.

  1. Aplica parches a la organización spec/version para la organización del arrendatario:

    export VERSION=$(kubectl get releasemetadata -ojson | jq -r '.items[] | select(.metadata.name | contains("1.13.3")) | .metadata.name')
    echo $VERSION
    
    # Example output
    # 1.13.3-gdch.5548
    
    kubectl patch -n gpc-system organization ORG_NAME --type='json' \
      -p='[{"op":"replace","path":"/spec/version","value":"'${VERSION}'"}]' \
        --kubeconfig=ROOT_ADMIN_KUBECONFIG
    
  2. Inicia un tenant-org upgrade instantáneo aplicando la anotación ignore-maintenance-window y reiniciando organizationupgrade.

  3. Supervisa el estado de la actualización:

    # kubectl -n gpc-system get organizationupgrade org-1 -o yaml
    
  4. Realiza las verificaciones posteriores a la actualización.

  5. Cuando se complete la actualización urgente, vuelve a usar los períodos programados:

    kubectl annotate organization ORG_NAME -n=gpc-system  \
          "upgrade.private.gdc.goog/ignore-maintenance-window-" \
          --kubeconfig=ROOT_ADMIN_KUBECONFIG
    

2. Actualización de DNS

2.1 Crea zonas de reenvío

  1. Exporta kubeconfig para el clúster de administrador raíz:

    export KUBECONFIG=/root/release/root-admin/root-admin-kubeconfig
    
  2. Configura OCIT_DOMAIN con una zona de reenvío. Reemplaza OCIT_DOMAIN por el nombre de tu dominio de OCIT y los extremos por las direcciones IP de DNS de OC:

    kubectl apply -f - <<EOF
    apiVersion: network.private.gdc.goog/v1alpha1
    kind: DNSZone
    metadata:
      namespace: dns-system
      name: ocit-domain
    spec:
      domainName: OCIT_DOMAIN
      forwardingConfig:
        # Set to OC DNS IPs (the AD domain controllers)
        endpoints:
          - 192.0.2.0
          - 192.0.2.1
        replicateToTenantOrg: true
    EOF
    

    El resultado se ve como en el siguiente ejemplo:

    dnszone.network.private.gdc.goog/ocit-domain created
    
  3. Si no se aplican los cambios, reinicia la implementación:

    kubectl rollout restart deployment -n dns-system gpc-coredns-forwarder
    

    Este cambio de DNS se propaga a todos los clústeres de GDC.

  4. Con el kubeconfig del administrador raíz, valida que la resolución del dominio de OCIT funcione según lo previsto:

    NAMESERVER=$(kubectl -n dns-system get service gpc-coredns-forwarder-udp | \
      awk '/[0-9]\./ {print $4}')
    dig +short @${NAMESERVER} fs.OCIT_DOMAIN
    
  5. Exporta kubeconfig para el clúster de administrador de la organización:

    export KUBECONFIG=/root/release/org-admin/org-admin-kubeconfig
    
  6. Aplica el kubeconfig del administrador de la organización y valida que la resolución del dominio de OCIT funcione según lo previsto:

    NAMESERVER=$(kubectl -n dns-system get service gpc-coredns-infra-forwarder | \
      awk '/[0-9]\./ {print $4}')
    dig +short @${NAMESERVER} fs.OCIT_DOMAIN
    

2.2 Habilita el solucionador recursivo

Habilita el solucionador recursivo en el clúster de administrador de la organización solo para las organizaciones de la versión 1 siguiendo los pasos del manual de ejecución DNS-R0027.

Finaliza la actualización de la organización del arrendatario en todas las zonas

Después de que se complete una actualización en una zona, se recomienda verificar que la zona siga funcionando correctamente antes de continuar con la actualización de la siguiente zona.

Repite los pasos 1 y 2 para la organización del arrendatario en el resto de las zonas. Cuando todas las zonas tengan actualizada su organización de arrendatario, continúa con los siguientes pasos.

3. Actualiza los recursos globales

Los recursos globales deben estar en la versión más baja de todas las zonas. Para iniciar el proceso de actualización de recursos globales, conéctate a la zona de anclaje y ejecuta los siguientes comandos.

# Annotate appropriate versions for all the operable components.
ORG_NAME=ORG_NAME
MAP=$(kubectl get kubeapiserver ${ORG_NAME}-admin -n ${ORG_NAME} -ojsonpath='{.metadata.annotations}' --kubeconfig ROOT_ADMIN_KUBECONFIG | jq -r 'to_entries | map("\(.key) \(.value)") | .[] | select(startswith("lcm.private.gdc.goog/oc-version-"))')

# Trigger the global resource upgrade on global org admin.
kubectl annotate kubeapiserver global-org-admin -n global-kube-system --overwrite lcm.private.gdc.goog/paused-remote=false --kubeconfig ORG_MGMT_API_KUBECONFIG
kubectl patch kubeapiserver global-org-admin -n global-kube-system -p='{"spec":{"deploymentPolicy":"AllowAll"}}' --type=merge --kubeconfig ORG_MGMT_API_KUBECONFIG

Este proceso puede tardar unos minutos. Ejecuta los siguientes comandos para verificar que se completaron las actualizaciones de los recursos globales. El comando no debería informar ningún error.

# Verify that Components are all successfully rolled out on global org admin.
echo "${MAP}" | while read KV; do
   SPLIT=(${KV}); VALUE=${SPLIT[1]}; OC=$(echo ${VALUE} | cut -d- -f1)
   [[ -n ${OC} ]] || continue
   ROLLOUT=$(kubectl get componentrollout ${OC} -n global-kube-system -o json --ignore-not-found --kubeconfig ORG_MGMT_API_KUBECONFIG)
   [[ -n ${ROLLOUT} ]] || continue
   if [[ $(echo ${ROLLOUT} | jq -r '.spec.componentRef.name') != ${VALUE} ]] ; then
      echo "${OC} rollout trigger failed"; continue
   fi
   if [[ $(echo ${ROLLOUT} | jq -r '.status.allSubcomponentsReady') != 'true' ]] ; then
      echo "${OC} rollout completion failed. Use 'kubectl describe componentrollout ${OC} -n global-kube-system --kubeconfig ORG_MGMT_API_KUBECONFIG' to check for error messages."
   fi
done && echo "Global component rollout check finished."

4. Actualiza Tenable SC

  1. Ejecuta GDCH doctor para determinar si se requiere una actualización:

      gdcloud system doctor diagnose instance --include-ocs=vuln --root-admin-kubeconfig=${ROOT_ADMIN_CLUSTER_KUBECONFIG:?}
    
  2. En caso de que el validador tenable_sc_upgrade_readiness falle, la imagen debe actualizarse. Para ello, sigue estos pasos para actualizar Tenable SC en la organización de servicios de OI:

    1. Obtén el nombre de la máquina virtual:

       VIRTUAL_MACHINE_NAME=$(kubectl --kubeconfig ${OI_SERVICES_ORG_INFRA_KUBECONFIG:?} get virtualmachine -n tenablesc-system -o custom-columns=NAME:.metadata.name | sort -r -k 1 | head -1)
      
    2. Marca el runningState de la máquina virtual como Stopped:

       kubectl --kubeconfig ${OI_SERVICES_ORG_MGMT_KUBECONFIG:?} patch virtualmachines.virtualmachine.gdc.goog ${VIRTUAL_MACHINE_NAME:?} -n tenablesc-system --type merge --patch '{"spec":{"runningState":"Stopped"}}'
      
    3. Desinstala el gráfico de Helm existente para la VM:

       VIRTUAL_MACHINE_NAME=$(kubectl --kubeconfig ${OI_SERVICES_ORG_INFRA_KUBECONFIG:?} get virtualmachine -n tenablesc-system -o custom-columns=NAME:.metadata.name | sort -r -k 1 | head -1)
       kubectl --kubeconfig ${OI_SERVICES_ORG_MGMT_KUBECONFIG:?} patch virtualmachines.virtualmachine.gdc.goog ${VIRTUAL_MACHINE_NAME:?} -n tenablesc-system --type merge --patch '{"spec":{"runningState":"Stopped"}}'
       helm uninstall tenablesc-vms -n tenablesc-system --kubeconfig ${ORG_MGMT_KUBECONFIG:?}
      
    4. Realiza una configuración nueva de Tenable SC siguiendo Instala Tenable.SC

Limpieza posterior a la actualización

Quita los recursos de ClusterRoleBinding creados en la sección Identity and Access Management.

Configura períodos de mantenimiento para la actualización de la organización del arrendatario

Para actualizar una organización (org.) de inquilino, verifica que se te hayan asignado los roles correctos de administrador y visualizador, como se detalla en las páginas Descripciones de roles predefinidos y Definiciones de roles para proyectos para acceder a la interfaz de línea de comandos (CLI) de kubectl y a la interfaz de usuario (IU) de la consola. Si no los tienes, sigue las instrucciones de la página Otorga acceso a los recursos del proyecto para otorgarlos o solicitar que te los otorguen.

Para configurar tu período de mantenimiento, debes tener los roles necesarios. Asegúrate de tener asignados los siguientes roles predefinidos:

De forma predeterminada, hay un MaintenanceWindow para las actualizaciones secundarias y un MaintenanceWindow para las actualizaciones de parches. Las actualizaciones secundarias mejoran la función o realizan cambios desde la revisión anterior, lo que es una actualización del paquete (por ejemplo, para corregir errores). Las actualizaciones de parches abordan problemas o vulnerabilidades específicos. Configura el parche predeterminado MaintenanceWindow para iniciar las actualizaciones de parches según un programa definido.

Para configurar el período de mantenimiento, usa los comandos de la CLI y kubectl para modificar los campos RRULE y TimeWindow de los recursos MaintenanceWindow. Esto programa tus actualizaciones. Para obtener información sobre RRULE, visita https://pkg.go.dev/github.com/teambition/rrule-go.

Para usar los comandos de la CLI de kubectl, haz clic en la pestaña kubectl. Para ver instrucciones basadas en la IU, haz clic en la pestaña Consola.

Console

  1. Accede a la IU de la organización.

  2. Edita el programa del período de mantenimiento. Ve a la pestaña Mantenimiento y haz clic en Editar.

    Período de mantenimiento

    Figura 1. Período de mantenimiento

  3. Se abrirá la pantalla Editar períodos de mantenimiento. Usa la ventana para reconfigurar los períodos Patch y Minor:

    Cómo volver a configurar las actualizaciones de parches y secundarias

    Figura 2. Reconfigura las actualizaciones secundarias y de parches

  4. Especifica o edita la Versión del parche, la Hora de inicio y la Duración, así como el día de la semana.

    Edita la Versión secundaria, la Hora de inicio, la Duración, la Recurrencia y el Día.

    Cómo guardar la reconfiguración

    Figura 3. Cómo guardar la reconfiguración

  5. Haz clic en Guardar para aplicar los cambios.

  6. Si los cambios guardados afectan la recurrencia (por ejemplo, si implementaste un cambio en el día de la semana o en el mes), verás un diálogo. Para confirmar los cambios, haz clic en CONTINUAR.

    Haz clic en Continuar.

    Figura 4. Haz clic en Continuar.

  7. En el siguiente ejemplo, se muestran las actualizaciones programadas actualizadas según los cambios de configuración. Observa el vínculo Omitir junto a cada estado pendiente. Usa este parámetro para omitir una actualización pendiente programada.

    Vista de actualizaciones programadas con botón para omitir
    Figura 5: Vista de las actualizaciones programadas, con una opción para omitir cada

kubectl

  1. Accede a la CLI de kubectl. Ubica estas instrucciones en la pestaña de la CLI. Antes de continuar, asegúrate de tener el acceso correcto al clúster de administrador de la organización.

  2. Puedes modificar tres campos en MaintenanceWindow para configurar el timeWindow en el que se produce la actualización de la organización del arrendatario. En los siguientes comandos, se muestra una modificación en el período de mantenimiento de la actualización con parches. La modificación de las actualizaciones secundarias es similar.

    # 1. The first change is to the RRULE
    # For patch-upgrades to happen, for example, every Thursday instead of Sunday:
    kubectl patch -n gpc-system maintenancewindow patch-upgrade \
      --type='json' \
      -p='[{"op":"replace","path":"/spec/recurrence","value":"FREQ=WEEKLY;BYDAY=TH"}]'
    
    # 2. Modify the start time of the upgrade in UTC.
    export S_TIME = 2022-04-03T04:00:00Z
    kubectl patch -n gpc-system maintenancewindow patch-upgrade \
      --type='json' \
      -p='[{"op":"replace","path":"/spec/timeWindow/start","value":"'${S_TIME}'"}]'
    
    # 3. Modify the end time of the upgrade in UTC.
    export E_TIME = 2022-04-03T04:00:00Z
    kubectl patch -n gpc-system maintenancewindow patch-upgrade \
      --type='json' \
      -p='[{"op":"replace","path":"/spec/timeWindow/end","value":"'${E_TIME}'"}]'
    

    La hora de inicio y la hora de finalización, /spec/timeWindow/start y /spec/timeWindow/end, respectivamente, deben tener una fecha, un mes y un año que hayan ocurrido en el pasado. El período se calcula en función de los valores que ingresas.

Asigna al menos la duración mínima que se muestra para cada uno de los tipos de actualización. Puedes asignar una duración más larga, como se indica en las siguientes recomendaciones:

  • Actualizaciones secundarias: Requieren al menos 12 horas en un período de 32 días.
  • Actualizaciones de parches: Requieren al menos 48 horas en un período móvil de 32 días, con 1 o más bloques de tiempo. Aunque la consola muestra una especificación de un período mínimo de 4 horas, Google recomienda que asignes al menos 6 horas a cada bloque de tiempo.

Actualización manual del núcleo de la infraestructura de Operations Suite

Este proceso de actualización solo se aplica a la actualización de la versión 1.13.x a la 1.14.3.

Asegúrate de que todas las cuentas locales y de dominio administradas tengan contraseñas habilitadas que no hayan vencido. Las cuentas que no estén en buen estado pueden causar errores en este proceso.

Realiza copias de seguridad de directorios y puntos de control de la VM

  1. Realiza puntos de control de la VM.

    1. En el host BM01, abre una consola de PS como administrador.
    2. Ejecuta el siguiente comando para cada host de Hyper-V en el clúster.

      $servername = "<*hyperv-server-name*>"
      Get-VM -CimSession $servername  | ForEach-Object {
      $myargs = @{
      VMName = $_.Name
      SnapshotName = "Checkpoint_$($_.Name)_$(Get-Date -Format 'yyyyMMddHHmmss')"
      ComputerName = $servername
      }
      Checkpoint-VM @myargs
      }
      

      Mantén abierta la ventana de PowerShell para los próximos pasos.

  2. Habilita las rutas de acceso largas a archivos

      $path = 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem'
      Set-ItemProperty -Path $path -Name 'LongPathsEnabled' -Value 1
    
  3. Copia de seguridad de la unidad H:\operations_center. (Esta acción admite la reversión de la actualización).

      Rename-Item -Path H:\operations_center -NewName operations_center_backup
    
  4. Directorios de configuración de copias de seguridad en CONFIG1. (Esta copia de seguridad proporciona una referencia cuando se compila la nueva configuración de config.ps1).

    1. En el host BM01, usa el protocolo de escritorio remoto (RDP) para conectarte a la dirección IP de la VM CONFIG1 y accede con una cuenta de administrador del sistema. Ejemplo: mstsc /v 192.168.100.99

    2. Abre una consola de PS con la opción Ejecutar como administrador.

      • Crea la carpeta de copia de seguridad
      mkdir c:\config1_backup
      
      • Copia de seguridad de C:\dsc
      Move-Item -Path "C:\dsc\" -Destination "C:\config1_backup"
      
      • Copia de seguridad de C:\config
      Move-Item -Path "C:\config\" -Destination "C:\config1_backup"
      
      • Copia de seguridad de C:\operations_center
      Move-Item -Path "C:\release\operations_center\" -Destination "C:\config1_backup"
      
      • Asegúrate de que las rutas de acceso de archivos largos estén habilitadas
      $path = 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem'
      Set-ItemProperty -Path $path -Name 'LongPathsEnabled' -Value 1
      

Carga software de terceros

Realiza las tareas en software de terceros.

Actualiza las máquinas virtuales existentes

  1. Obtén el directorio de instalación.

    1. Descarga el paquete de componentes de OIC siguiendo las instrucciones de la sección Descargar archivos.

    2. En el host BM01, extrae el directorio operations_center del archivo prod_IT_component_bundle.tar.gz descargado.

      Set-Location H:
      tar -zxvf prod_IT_component_bundle.tar.gz
      

      Al extraer el archivo TAR, se debería crear una carpeta release en la raíz de H:.

    3. Mueve operations_center a la raíz de H:

      Move-Item -Path H:\release\operations_center -Destination H:\
      
  2. Actualiza config.ps1 con datos específicos del sitio

    El archivo de configuración config.ps1 proporciona toda la información necesaria para compilar y configurar el entorno de la infraestructura de Operations Suite (OI). Para actualizar el archivo de configuración, debes recopilar toda la siguiente información. La copia de seguridad del archivo config.ps1 existente es una buena referencia para proteger el reemplazo no intencional de la configuración existente. Importante: No continúes hasta que config.ps1 esté completo y sea correcto.

    • El resultado de la configuración de red de la herramienta occonfigtool, en especial el archivo ocinfo.common.opscenter.local.txt Los nombres de red, por ejemplo, OCCORE-SERVERS, a los que se hace referencia en los siguientes pasos, hacen referencia a la columna Name de ese documento.
    • El nombre de dominio y la dirección IP del servidor DNS de cada celda de GDC que administra este OI. Estos datos están disponibles en los resultados del Cuestionario de admisión del cliente (CIQ).

    Realiza todos los cambios en el host BM01 como Administrator.

  3. Copia el código de ejemplo de configuración correcto para el tipo de implementación:

    1. Copia H:\operations_center\dsc\config.example.ps1 en H:\operations_center\config\config.ps1.
  4. Con VSCode o Powershell ISE, valida y actualiza los valores en config.ps1.

    1. Si la OIC se implementa como multisitio, haz lo siguiente:

      1. Cómo encontrar comentarios etiquetados como ### Multi-Site:
      2. Realiza las acciones que se describen en los comentarios que encontraste.
    2. Actualiza HardwareVersion, a menos que el valor predeterminado (3.0) sea correcto.

    3. Actualiza PrimarySiteCode, a menos que el valor predeterminado (DC1) sea correcto.

    4. El código del sitio se usa en muchos nombres. Busca y reemplaza todas las instancias de DC1 por el código del sitio correcto. Usa una búsqueda en la que no se distingue entre mayúsculas y minúsculas. Revisa cada cambio, ya que es posible que algunos no sean necesarios. Por ejemplo, si el código del sitio es AB1, el nombre de host DC1-DC1 debe cambiar a AB1-DC1, no a AB1-AB1.

    5. Actualiza DnsDomain si el valor predeterminado no es correcto. Si se cambia este valor, busca y reemplaza opscenter.local en todo el archivo config.ps1. Hay varias ubicaciones en las que ese valor predeterminado está codificado.

    6. Actualiza los objetos en DnsConditionalForwarder con información específica del sitio. Debe haber al menos un objeto de reenvío. Quita los ejemplos innecesarios.

      Este paso se puede realizar en WSL en CONFIG1 si se instalaron las CLI de gdcloud y kubectl.

      Para extraer información específica del sitio del clúster de administrador raíz, usa el siguiente comando:

      export KUBECONFIG=/root/release/root-admin/root-admin-kubeconfig
      kubectl get -n dns-system service gpc-coredns-external-udp \
                  -o jsonpath='{.status.loadBalancer.ingress[0].ip}{"\n"}'
      
      1. Domain: Es el nombre de dominio DNS de la celda de GDC, por ejemplo, dns.delegatedSubdomain en ciq.yaml.
      2. Master: Es una lista de IPs de servidores DNS (por lo general, solo una). Busca en cellcfg el tipo DNSReservation. Si se implementó la celda de GDC, busca en el espacio de nombres dns-system del clúster de administración raíz la EXTERNAL-IP del servicio gpc-coredns-external-udp y el FQDN de la celda bert.sesame.street.

      3. En las implementaciones en varios sitios, hay un objeto de tabla hash por celda.

    7. No cambies el contenido de los objetos Users, Groups y GroupPolicy.

    8. Actualiza DNSServers para que contenga las 2 direcciones IP asignadas a los controladores de dominio principal y secundario, como <SITE>-DC1 y <SITE>-DC2.

    9. Actualiza NTPServers para que sea una lista de las direcciones IP de SyncServer de los recursos personalizados TimeServer de root-admin. Puedes recuperar este conjunto de direcciones IP con el siguiente comando:

      kubectl get timeserver -A -o json | jq '.items[].address'
      

      Debes darles a estas direcciones IP el formato NTPServers, como se muestra en el siguiente ejemplo:

      NtpServers = @(
        '10.251.80.2',
        '10.251.80.3',
        '10.251.80.4',
        '10.251.80.5'
      )
      
    10. Actualiza el valor predeterminado de SubnetPrefix, es decir, 24, con el valor del prefijo de subred proporcionado por el cliente para la subred OCCORE-SERVERS si es necesario.

    11. Actualiza el valor predeterminado de DefaultGateway con la puerta de enlace predeterminada proporcionada por el cliente para la subred OCCORE-SERVERS.

    12. Busca y actualiza el valor predeterminado de WorkstationCider con el valor proporcionado por el cliente para la subred OC-WORKSTATIONS en notación CIDR de IPv4.

    13. Actualiza el valor de WorkstationAllowRemote a $true si el cliente optó por permitir el acceso remoto a sus estaciones de trabajo.

    14. Busca y reemplaza el prefijo de subred de ejemplo 172.21.0. por el prefijo de subred OCCORE-SERVERS proporcionado por el cliente.

    15. Busca y reemplaza el prefijo de subred de ejemplo 172.21.2. por el prefijo de subred OCCORE-JUMPHOSTS proporcionado por el cliente.

    16. Busca y reemplaza el prefijo de subred de ejemplo 172.21.32. por el prefijo de subred OC-WORKSTATIONS proporcionado por el cliente.

    17. Busca y reemplaza el mensaje del día de ejemplo legalnoticecaption con el valor Pref caption proporcionado por el cliente.

    18. Busca y reemplaza el valor del mensaje del día de ejemplo legalnoticetext de Pref text por el texto proporcionado por el cliente.

    19. Valida cada objeto "nodo" y actualízalo si es necesario.

      1. NodeName: Asegúrate de que el nombre de host sea correcto. Algunos nombres se usan en muchos lugares, por ejemplo, los controladores de dominio. Si cambias un nombre aquí, verifica si también debes cambiarlo en otro lugar de la configuración.
      2. IPv4Addr: Debe ser la dirección IP del host. Por lo general, el último octeto se puede dejar como está. Es posible que algunos de ellos se hayan actualizado durante la búsqueda y el reemplazo de la red que se realizaron en pasos anteriores.

      3. HyperVHost: Este valor debe ser la dirección IP del servidor de Hyper-V que aloja esta VM. Puedes obtener la dirección IP de cada servidor BM?? en la sección "Servidores Hyper-V" de la configuración. No cambies la asignación del host de Hyper-V en este campo, ya que no todos los hosts de Hyper-V pueden admitir todos los tipos de VM. Solo cambia el nombre de host de Hyper-V por su dirección IP correspondiente.

    20. Valida los detalles de la segunda interfaz de red en todos los nodos con Role=jumphost. Usa los detalles de la subred OCCORE-JUMPHOSTS para esta interfaz. Comprobar:

      1. JumphostIPv4Cidr
      2. JumphostDefaultGateway
    21. Actualiza la estrofa específica de ADFS en el nodo donde Role=adfs.

      1. Busca la línea Name = 'SplunkTrust' # Must be unique to the farm. Append "Trust".
      2. Reemplaza las tres ocurrencias de opscenter.local después de esta línea por tu dominio de DNS.
    22. Actualiza los rangos de DHCP para que coincidan con el plan de IP del cliente según sea necesario. Para cada alcance, valida que los siguientes valores sean correctos. Los nombres de los alcances coinciden con los nombres que se usan en el plan de red de ocinfo.common.opscenter.local.txt, por lo que debes usar lo siguiente en la validación:

      1. ScopeId
      2. IpStartRange
      3. IpEndRange
      4. Router
      5. SubnetMask
    23. Confirma que los valores coincidan con los valores de config1.ps1 de la copia de seguridad.

    24. Asegúrate de guardar el archivo.

Preparación de la VM de CONFIG1

La preparación de CONFIG1 se realiza en BM01. Todas las demás actualizaciones se realizan mientras se accede a la VM CONFIG1.

  1. Copia el directorio operations_center en la VM CONFIG1.

    1. En el host BM01, abre una consola de PS como administrador.

    2. Copia operations_center para preparar los archivos que necesita la máquina virtual (VM) CONFIG1.

      # Change name to match your config host
      $config = "DC1-CONFIG1"
      # Stage files for CONFIG1 VM
      Copy-Item  -Path H:\operations_center -Destination "\\$config\c$\" -Recurse -Force
      
    3. Inhabilita la sincronización de hora de Hyper-V

      1. Accede al host BM01 como administrador.

      2. Abre PowerShell en Windows como administrador y ejecuta el siguiente comando:

      # Disabling Hyper-V Time Sync
      Disable-VMIntegrationService -VMName `<SITE>-CONFIG1` -Name 'Time Synchronization'
      
    4. Preparación y validación de la VM CONFIG1

      1. Desde el host BM01, accede a la VM CONFIG1 con tu cuenta de -SA. Conéctate a la dirección IP de la VM con el escritorio remoto (RDP). Ejemplo: mstsc /v 192.168.100.99

      2. Abre una ventana de PowerShell con el menú "Ejecutar como otro usuario" para ejecutarla como el usuario Marvin.

      3. En la nueva ventana de PowerShell, inicia una sesión administrativa:

        Start -Verb runas -FilePath powershell.exe
        

        Cierra la ventana anterior de PowerShell y deja abierta la ventana del administrador.

      4. Verifica que la ventana administrativa de PowerShell se ejecute como Marvin

        whoami
        
      5. Organiza los archivos que se prepararon desde el host BM01.

        Move-Item -Path c:\operations_center -Destination c:\release
        C:\release\operations_center\dsc\Initialize-ConfigHostFiles.ps1
        
      6. Valida que existan c:\dsc y c:\config.

      7. Copia los archivos de credenciales y certificados desde la copia de seguridad

        Copy-Item -Path "C:\config1_backup\config\creds\" -Destination "C:\config\creds\" -Recurse
        Copy-Item -Path "C:\config1_backup\config\certs\" -Destination "C:\config\certs\" -Recurse
        
      8. Compila los datos de MECM necesarios para compilar los MOF

        C:\dsc\Build-MecmFiles.ps1
        
      9. Para validar que el entorno de compilación esté listo, ejecuta Build-Mof.ps1, que genera archivos MOF para todas las máquinas de OI.

        C:\dsc\Build-Mof.ps1
        
    5. Propaga variables de credenciales

      Estas variables se usan durante todo el proceso de actualización. Complétalos una vez en la ventana de Marvin PowerShell que se abrió como administrador.

      . 'c:\config\config.ps1'
      
      $da_creds = (Get-Credential -Message "Provide domain admin credentials")
      $sa_creds = (Get-Credential -Message "Provide system admin credentials")
      
      $sa_args = @{
      Credential = $sa_creds
      SetLcm = $true
      RemoveExisting = $true
      CopyModules = $true
      }
      
      $da_args = @{
      Credential = $da_creds
      SetLcm = $true
      RemoveExisting = $true
      CopyModules = $true
      }
      
    6. Verifica que DSC se esté ejecutando y que se pueda acceder a los servidores.

      $role = 'domain_controller'
      $ca = 'ca_root'
      $dcs = $config.AllNodes | Where-Object {$_.role -eq $role}
      $non_dcs = $config.AllNodes | Where-Object {$_.role -ne $role -and $_.role -ne $ca -and $_.NodeName -ne "*"}
      
      $dcs | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $da_creds
      Get-DscConfigurationStatus -CimSession $session | select HostName,Status,NumberOfResources,ResourcesNotInDesiredState}
      
      $non_dcs | ForEach-Object {
      Write-Output "Checking $($_.NodeName)"
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session | select HostName,Status,NumberOfResources,ResourcesNotInDesiredState | ft -AutoSize}
      

Soluciona problemas de conectividad.

  1. Si New-CimSession falla, verifica que el valor de NodeName sea correcto en config.ps1. También confirma que el servidor esté en línea y que se pueda acceder a él.

    El error comenzará con Get-CimSession: WinRM cannot process the request.

Actualiza los controladores de dominio

  1. Mientras accedes a CONFIG1, actualiza el controlador de dominio principal.

    Propaga variables, quita los GPO antiguos y vincula los GPO nuevos.

    $dc2 = $dcs | Where-Object {$_.NodeName -like "*-DC2"}
    $dc1 = $dcs | Where-Object {$_.NodeName -like "*-DC1"}
    
    Invoke-Command -Computername $dc1.NodeName -Credential $da_creds -ScriptBlock {
    Remove-DscConfigurationDocument -Stage Current,Pending,Previous
    get-gpo -All | Where-Object { $_.DisplayName -like "OIC*" } | Remove-GPO
    get-gpo -All | Where-Object { $_.DisplayName -like "SITE*" -and $_.DisplayName -notlike "*SCCM*" } | Remove-GPO
    Get-Item "C:\config\domain_controller\oic_gpos"| Remove-Item -Recurse -Force
    Get-Item "C:\config\domain_controller\site_gpo*"| Remove-Item -Recurse -Force
    }
    

    Desvincula los objetos de política de grupo. Se vincularán al final de la actualización.

    $gpolinks = (Get-Content C:\dsc\data\GpoLinkMapping.yaml -Raw).Replace("LinkEnabled: 'Yes'", "LinkEnabled: 'No'")
    $gpolinks | Out-File C:\dsc\data\GpoLinkMapping.yaml -Force
    

    Actualiza el controlador de dominio principal.

    .\Update-RemoteHost.ps1 @da_args -ComputerName $DC1.NodeName
    
    New-PSDrive -Name DC1 -PsProvider FileSystem -Root "\\$($DC1.NodeName)\c$" -Credential $da_creds
    Invoke-Command -ComputerName $DC1.NodeName -Credential $da_creds -Scriptblock {Remove-DscConfigurationDocument -Stage Current,Pending}
    Remove-Item -Path DC1:\config\domain_controller\site_gpos -Recurse -Force
    Remove-Item -Path DC1:\config\domain_controller\site_gpos_source -Recurse -Force
    Copy-Item -Path C:\config\domain_controller\ -Destination DC1:\config\ -Verbose -Force -Recurse
    C:\dsc\Build-Mof.ps1 -Computername $DC1.NodeName
    Start-DscConfiguration -ComputerName $DC1.NodeName -Path 'c:\config\mofs' -Credential $da_creds -Verbose -Wait -Force
    Remove-PsDrive -Name DC1
    
    1. Valida la sincronización de hora con el SyncServer

    2. Accede a DC1 con RDP como administrador de dominio.

      1. Abre una ventana de Powershell como administrador.
      2. Ejecuta el siguiente comando para validar la configuración de la hora.

        w32tm /query /status /verbose
        
    1. Ejecuta los siguientes comandos para probar la resincronización de la hora:

       # Testing time resyncronization
       w32tm /resync
      
       # Desired output
       Sending resync command to local computer
       The command completed successfully.
      
    2. Vuelve a validar que la configuración de tiempo sea correcta y no tenga errores.

       w32tm /query /status /verbose
      
  2. Actualiza el segundo controlador de dominio.

    1. Usa la ventana de PowerShell CONFIG1 existente para ejecutar la siguiente secuencia de comandos.

      .\Update-RemoteHost.ps1 @da_args -ComputerName $dc2.NodeName
      
  3. Valida la replicación de Active Directory.

    1. Una vez que el segundo DC esté en funcionamiento, ejecuta los siguientes comandos desde uno de los controladores de dominio para validar la replicación de Active Directory:

      repadmin /replsummary
      

      El resultado debe ser similar al siguiente:

      PS C:\Users\Administrator.OpsCenter> repadmin /replsummary
      Replication Summary Start Time: 2023-11-29 19:16:59
      
      Beginning data collection for replication summary, this may take awhile:
      ......
      
      Source DSA          largest delta    fails/total %%   error
      OC1-DC1                   01m:49s    0 /  5    0
      
      Destination DSA     largest delta    fails/total %%   error
      OC1-DC2                   01m:49s    0 /  5    0
      

Actualiza CA-ISSUING1 y CA-WEB

  1. Usa la terminal de PowerShell existente en CONFIG1 para actualizar CA-ISSUING1.

      $ca_iss = $config.AllNodes | Where-Object {$_.role -eq "ca_issuing"}
      c:\dsc\Update-RemoteHost.ps1 @sa_args -ComputerName $ca_iss.NodeName
    
  2. Usa la terminal de PowerShell existente en CONFIG1 para actualizar CA-WEB.

      $ca_web = $config.AllNodes | Where-Object {$_.role -eq "ca_web"}
      c:\dsc\Update-RemoteHost.ps1 @sa_args  -Computername $ca_web.NodeName
    
  3. Valida la actualización

      $ca_iss,$ca_web | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session}
    

Actualiza CA-ROOT1

Usa la terminal de PowerShell existente en CONFIG1.

  1. Enciende el CA-ROOT1.

      $ca_root = $config.AllNodes | Where-Object {$_.role -eq "ca_root"}
      $session = New-CimSession -ComputerName $ca_root.HyperVHost -Credential $sa_creds
      Start-VM -CimSession $session  -Name $ca_root.NodeName
    
  2. Actualiza CA-ROOT1.

      $caroot_cred = Get-GeccoCredential -Name "$($ca_root.NodeName)\caadmin" -CredStore "c:\config\creds"
      c:\dsc\Update-RemoteHost.ps1 -Computername $ca_root.NodeName -RemoteHost $ca_root.Ipv4Addr -Credential $caroot_cred
    
  3. Si CA_ROOT1 no se reinició después de la secuencia de comandos anterior, reinícialo de forma manual.

  4. Valida la actualización.

      $ca_root | ForEach-Object {
      $session = New-CimSession -ComputerName $_.Ipv4Addr -Credential $caroot_cred
      Get-DscConfigurationStatus -CimSession $session}
    
  5. Verifica que el parámetro de configuración Peer sea <SITE>-DC1.<DNSDOMAIN> y que State sea Active.

    No continúes si la hora no está sincronizada correctamente.

      w32tm /query /peers
    
      #Peers: 1
    
      Peer: DC1-DC1.domain.local
      State: Active
      Time Remaining: 31.2997107s
      Mode: 3 (Client)
      Stratum: 1 (primary reference - syncd by radio clock)
      PeerPoll Interval: 6 (64s)
      HostPoll Interval: 6 (64s)
    
  6. Apaga la CA-Root.

      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Stop-VM -CimSession $session  -Name $ca_root.NodeName
    

Actualiza ADFS

Usa la terminal de PowerShell existente en CONFIG1.

  1. Actualiza la VM de ADFS1.

      $role = 'adfs'
      $adfs = $config.AllNodes | Where-Object {$_.role -eq $role}
    
      $adfs | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session}
    
      $adfs | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args  -Computername $adfs.NodeName}
    
    1. Validate the upgrade.
    
      $adfs | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session}
    

Actualiza los Jumphosts.

Usa la terminal de PowerShell existente en CONFIG1.

  1. Crea un array de Jumphosts.

      $role = 'jumphost'
      $jumps = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. Actualiza los Jumphosts.

      $jumps | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}
    
  3. Valida la actualización.

      $jumps | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session}
    

Actualiza los servidores de archivos.

Usa la terminal de PowerShell existente en CONFIG1.

  1. Crea un array que contenga los servidores de archivos.

      $role = 'file'
      $files = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. Actualiza los servidores de archivos.

      $files | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}
    
  3. Valida la actualización.

      $files | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session}
    

Actualiza los servidores DHCP.

Usa la terminal de PowerShell existente en CONFIG1.

  1. Actualiza DHCP1.

      $role = 'dhcp_primary'
      $dhcp1 = $config.AllNodes | Where-Object {$_.role -eq $role}
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $dhcp1.NodeName
    
  2. Valida la actualización.

      $dhcp1 | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session}
    
  3. Actualiza DHCP2.

      $role = 'dhcp_failover'
      $dhcp2 = $config.AllNodes | Where-Object {$_.role -eq $role}
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $dhcp2.NodeName
    
  4. valida la actualización.

      $dhcp2 | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session}
    

Actualiza los servidores de Userlock.

Usa la terminal de PowerShell existente en CONFIG1.

  1. Crea un array de PowerShell que contenga los servidores de Userlock.

      $role = 'userlock_primary'
      $ulock1 = $config.AllNodes | Where-Object {$_.role -eq $role}
      $role = 'userlock_backup'
      $ulock2 = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. Quita los archivos de marcador de la configuración anterior.

      Invoke-Command -ComputerName $ulock1.NodeName -Credential $sa_creds -Scriptblock { Remove-item "c:\config\userlock_primary\ServiceImpersonation.log" }
      Invoke-Command -ComputerName $ulock2.NodeName -Credential $sa_creds -Scriptblock { Remove-item "c:\config\userlock_backup\ServiceImpersonation.log" }
    
  3. Actualiza el servidor principal de Userlock.

      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $ulock1.NodeName
    
  4. Actualiza el servidor de Userlock de la copia de seguridad.

      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $ulock2.NodeName
    
  5. Valida las actualizaciones.

      $ulock1,$ulock2 | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session}
    

Actualiza los servidores de Nessus.

Usa la terminal de PowerShell existente en CONFIG1.

  1. Crea un array de PowerShell que contenga los servidores de Nessus.

      $role = 'nessus_'
      $nessus = $config.AllNodes | Where-Object {$_.role -match $role}
    
  2. Actualiza los servidores de Nessus.

      $nessus | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args  -Computername $_.NodeName}
    
  3. Valida la actualización.

      $nessus | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session}
    

Actualiza los servidores de Hyper-V.

Usa la terminal de PowerShell existente en CONFIG1.

  1. Crea un array de PowerShell que contenga los servidores de Hyper-V.

      $role = 'hyper_v'
      $hyper = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. Actualiza los servidores de Hyper-V.

      $hyper | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}
    
  3. Valida la actualización.

      $hyper | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session}
    

Actualiza las cajas de herramientas

Usa la terminal de PowerShell existente en CONFIG1.

  1. Crea un array de PowerShell que contenga los servidores de la caja de herramientas.

      $role = 'toolbox'
      $tools = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. Crea una unidad adicional en el servidor TOOLBOX1

      $tools | ForEach-Object {
         if ($_.ExtraDiskSize) {
         Invoke-Command -ComputerName $_.HyperVHost -Credential $sa_creds -ScriptBlock {
            $additional_disk_path = Join-Path -Path $using:_.ExtraDiskFolder -ChildPath "$($using:_.NodeName)-2.vhdx"
            New-VHD -Path $additional_disk_path -Dynamic -SizeBytes $using:_.ExtraDiskSize
            Add-VMHardDiskDrive -VMName $using:_.NodeName -Path $additional_disk_path
            Get-VMHardDiskDrive -VMName $using:_.NodeName | select VMName,ControllerLocation,Path
         }}}
    

    Verifica que el resultado muestre dos discos asignados a la VM. Ejemplo:

      VMName       ControllerLocation Path
      ------       ------------------ ----
      DC1-TOOLBOX1                  0 H:\Hyper-V\Virtual Hard Disks\DC1-TOOLBOX1.vhdx
      DC1-TOOLBOX1                  1 Z:\Hyper-V\Virtual Hard Disks\DC1-TOOLBOX1-2.vhdx
    
  3. Actualizar los servidores de Toolbox

      $tools | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args  -Computername $_.NodeName}
    
  4. Valida la actualización.

      $tools | ForEach-Object {
      $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
      Get-DscConfigurationStatus -CimSession $session}
    

Usa la terminal de PowerShell existente en CONFIG1 para validar la actualización.

  1. Verifica que DSC se ejecute sin errores.

       $role = 'domain_controller'
       $ca = 'ca_root'
       $dcs = $config.AllNodes | Where-Object {$_.role -eq $role}
       $non_dcs = $config.AllNodes | Where-Object {$_.role -ne $role -and $_.role -ne $ca -and $_.NodeName -ne "*"}
    
       $dcs | ForEach-Object {
       $session = New-CimSession -ComputerName $_.NodeName -Credential $da_creds
       Get-DscConfigurationStatus -CimSession $session | select HostName,Status,NumberOfResources,ResourcesNotInDesiredState}
    
       $non_dcs | ForEach-Object {
       Write-Output "Checking $($_.NodeName)"
       $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds
       Get-DscConfigurationStatus -CimSession $session | select HostName,Status,NumberOfResources,ResourcesNotInDesiredState | ft -AutoSize}
    

Actualiza las VMs de Splunk

  1. En la ventana de PowerShell de CONFIG1, configura y ejecuta la configuración de DSC:

    • Ingresa el código del sitio. Ejemplo: "DC1"

       $sitecode = Read-Host "Enter your site code"
       Set-Location c:\dsc
      
    • Configura el heavy forwarder:

       $myargs = @{
       Computername = "$sitecode-HEAVYFWD"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • Configura el indexador 1:

       $myargs = @{
       Computername = "$sitecode-INDEXER1"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • Configura el indexador 2:

       $myargs = @{
       Computername = "$sitecode-INDEXER2"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • Configura el indexador 3:

       $myargs = @{
       Computername = "$sitecode-INDEXER3"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • Configura el administrador:

       $myargs = @{
       Computername = "$sitecode-SPLUNKMGR"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • Configura el encabezado de búsqueda:

       $myargs = @{
       Computername = "$sitecode-SEARCHHEAD"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
  2. En la ventana de PowerShell de CONFIG1, haz lo siguiente:

      $servers = @()
      $config.AllNodes | Where-Object {$_.role -match "splunk_"} | Foreach { $servers += $_.NodeName }
      Invoke-Command -ComputerName $servers -Credential $sa_creds -ScriptBlock {Restart-Service -Name 'Splunkd'} -ErrorAction Continue
    
  3. Sigue SIEM-G0006 para establecer el Pass4SymmKey global y SIEM-G0007 para adjuntar cada zona a Splunk en OIC.

Actualiza el host CONFIG1

  1. En la ventana de PowerShell de CONFIG1, haz lo siguiente:

    Start-DscConfiguration -ComputerName $env:COMPUTERNAME -Path c:\config\mofs -Verbose -Wait -Force
    
  2. Si la computadora se reinicia, vuelve a acceder y a iniciar PowerShell como Marvin, y luego eleva los privilegios a administrador. Propaga las variables necesarias para las siguientes secciones.

    Set-Location c:\dsc
    . c:\config\config.ps1
    $da_creds = (Get-Credential -Message "Provide domain admin credentials")
    $sa_creds = (Get-Credential -Message "Provide system admin credentials")
    

Microsoft Configuration Manager (MCM)

Debido a que MCM no es un componente actualizable, la única opción es destruir los hosts existentes de MCM y volver a implementarlo.

  • Asegúrate de que el software de MCM actual se haya hidratado según IT-T0023.

  • El procedimiento para la reimplementación se describe en IT-R0019.

Cómo quitar puntos de control de la VM

Una vez que se completen las actualizaciones, se deben quitar los puntos de control. Los puntos de control pueden generar un uso excesivo del disco con el tiempo. Conserva los archivos solo si se requiere una restauración al punto de control debido a una actualización fallida.

Usa la terminal de PowerShell existente en CONFIG1.

  1. Quita los puntos de control de la VM.

      $config.AllNodes | Where-Object {$_.Role -eq "hyper_v"} | Foreach-Object {
      Invoke-Command -ComputerName $_.NodeName -Credential $sa_creds -Scriptblock {
        Get-VM | Get-VMSnapshot | Where-Object {$_.Name -like "Checkpoint_*"} | Remove-VMSnapshot -Verbose
      }}
    

Cómo volver a habilitar los objetos de políticas de grupo en el dominio

Usa la terminal de PowerShell existente en CONFIG1.

  1. Cambia la configuración del rol del controlador de dominio para habilitar vínculos en los GPO administrados

      $gpolinks = (Get-Content C:\dsc\data\GpoLinkMapping.yaml -Raw).Replace("LinkEnabled: 'No'", "LinkEnabled: 'Yes'")
      $gpolinks | Out-File C:\dsc\data\GpoLinkMapping.yaml -Force
    
  2. Actualiza el controlador de dominio con el rol de ObjectOwner:

      c:\dsc\Update-RemoteHost.ps1 -Computername $config.AllNodes.DomainConfig.ObjectOwner -Credential $da_creds
    

Comunícate con el equipo de Google

Consulta la página Solicitar asistencia para conocer los pasos que debes seguir para comunicarte con Google y obtener más ayuda.