Faça uma atualização numa implementação de várias zonas

Numa implementação multizonal, as zonas são atualizadas individualmente e de forma independente. Não existe uma orquestração global das atualizações em todas as zonas. Um IO tem de fazer uma atualização em todas as zonas da organização que quer atualizar para uma nova versão. Como resultado, as organizações em zonas diferentes podem estar em versões diferentes num determinado momento.

A ordem de atualização descrita nesta página consiste em atualizar a organização raiz, bem como todas as organizações inquilinas numa zona, antes de passar para outra zona. Os recursos globais são atualizados no final, após a atualização de todas as zonas.

Esta página descreve os passos para avançar com uma atualização isolada do ar do Google Distributed Cloud (GDC) multizona, fornecendo os seguintes tipos de informações:

  • Acesso necessário e formas de o obter.
  • As ferramentas de que precisa.
  • Que passos deve seguir antes de fazer uma atualização.
  • Como e em que sequência realizar atualizações para vários componentes da Distributed Cloud.

A lista seguinte define cada um dos componentes de uma atualização:

Versão de destino: use a mesma versão de destino para todas as zonas.

Uma de cada vez: atualize uma zona de cada vez. Antes de acionar uma atualização numa zona, certifique-se de que nenhuma outra zona está a executar uma atualização.

Recursos globais: definidos como recursos do Kubernetes implementados no kube-apiserver global, em oposição aos recursos zonais que têm uma cópia por zona. Os recursos globais seguem um ciclo de vida diferente. Tenha em atenção que têm de ser atualizados no final, apenas uma vez.

Prepare

Os URLs são fornecidos para acesso fora do seu ambiente isolado.

Antes de iniciar uma atualização, certifique-se de que tem o seguinte:

Gere um relatório de conformidade

O relatório de conformidade apresenta as organizações que:

  • estão fora do apoio técnico
  • Perder patches de segurança críticos

A geração do relatório de conformidade é um passo opcional e requer uma OI autenticada que tenha organization-admin role. Para gerar o relatório, execute o seguinte comando:

  gdcloud system upgrade report-compliance

Para mais informações sobre os requisitos de preparação, consulte a secção Pré-requisitos.

Gestão de identidade e de acesso

Antes de iniciar uma atualização, em cada zona:

  1. Obtenha um ficheiro kubeconfig executando gdcloud auth login no cluster de administrador raiz, bem como em todos os clusters de administrador da organização.

  2. Siga as instruções no manual de procedimentos IAM-R0005 do processo de elevação de acesso e privilégios para adicionar:

    1. ClusterRoleBinding com o cluster-admin ClusterRole no cluster de administrador raiz de cada zona
    2. clusters de administrador da organização para obter acesso de administrador temporário.

Pause as atualizações de recursos globais em todas as zonas

Use o ficheiro kubeconfig obtido para pausar todas as atualizações de recursos globais em 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

Atualize a organização raiz global

A atualização da organização raiz global a um nível elevado inclui os seguintes passos:

  1. Atualize a organização raiz em todas as zonas. Cada zona é atualizada individualmente.

    Verifique se a zona atual é a zona principal. O comando seguinte devolve "true" na zona principal e não devolve nada nas zonas não principais.

    kubectl get ObjectStorageAdminNode -o jsonpath='{.items[*].status.isPrimary}' --kubeconfig=ROOT_ADMIN_KUBECONFIG; echo
    
  2. Atualize os componentes que requerem coordenação entre zonas.

  3. Atualize os recursos de administrador principal global.

Verificação pré-atualização

Atualize as zonas uma de cada vez. Antes de iniciar uma atualização de uma organização numa zona, estabeleça ligação a todas as outras zonas e execute o seguinte para se certificar de que o comando devolve o estado pronto em todas as zonas. Se alguma zona indicar que não está pronta, não avance para a atualização. Verifique a organização nessa zona para diagnosticar o 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. Transfira e copie o pacote de atualização

Estas instruções descrevem como começar:

  • Transfira um pacote de atualização para um dispositivo acessível através da Internet para copiar para uma unidade USB.
  • Copie o pacote de atualização da unidade USB para o seu ambiente isolado.

Para contexto adicional, consulte Transferir ficheiros para transferir detalhes de distribuição da nuvem distribuída e Transferência de transferências para ver informações sobre o dispositivo de armazenamento portátil que usa para transferir ficheiros para o seu ambiente isolado.

  1. Colabore com o seu POC da Google para decidir se a atualização se destina a uma implementação da Distributed Cloud operada por um parceiro e, por isso, deve usar ficheiros de lançamento do modelo de parceiro.

    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. Transfira o pacote de atualização para a unidade USB a partir de um computador com acesso à Internet. Use os detalhes da versão e do resumo fornecidos pelo seu ponto de contacto (POC) da Google.

    1. Execute gcloud auth login para aceder ao contentor do Cloud Storage.
    2. Execute o script com --skip-unzip para obter o pacote de atualização e o script de transferência para o diretório atual, 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. Se estiver a fazer a atualização com ficheiros de lançamento de modelos de parceiros, siga as instruções para preparar os pacotes de software para a distribuição de modelos de parceiros.

  3. Copie o script de transferência e o diretório gdch para a unidade USB.

  4. Copie a atualização para o OCIT a partir da unidade USB. Coloque os ficheiros num local semelhante, como /home/download/.

  5. Redefina estas variáveis na OCIT e extraia a atualização:

    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. O programa de transferência terá descompactado o lançamento para gdch/full-release-1.2.0-gdch.243 (por exemplo, /home/download/gdch/full-release-1.2.0-gdch.243). Atribua esta variável ao caminho completo:

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

2. Configure a atualização do Artifact Registry

Para fazer uma atualização com êxito, tem de concluir o seguinte:

Envie os artefactos para o registo de contentores

  1. Defina KUBECONFIG para o ficheiro kubeconfig do cluster de administrador raiz.

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    
  2. Crie o ClusterRoleBindings necessário:

    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. Crie o RoleBindings necessário:

    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. Crie o RoleBindings necessário para enviar o pacote de OCI:

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

    O resultado tem o seguinte aspeto:

    rolebinding.rbac.authorization.k8s.io/infrastructure-operator-sar-harbor-admin created
    
  5. Siga as instruções em Redimensione o armazenamento do Artifact Registry para fazer o seguinte:

    1. Verifique a utilização do armazenamento do Artifact Registry num cluster de administrador e confirme se existe espaço adequado para os artefactos que quer enviar.
    2. Se precisar de aumentar o espaço disponível, siga os passos indicados em Redimensione o armazenamento do Artifact Registry.
  6. Configure as configurações do Docker:

    cp ${ARTIFACTS_ROOT}/docker-credential-gdcloud /usr/bin
    
  7. Configure o Docker para confiar no pacote de repositório de confiança.

    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. Carregue os artefactos no registo de artefactos no cluster de administrador raiz:

    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
    

    Substitua o seguinte:

    • VERSION: a versão do Distributed Cloud. Por exemplo, 1.x.y-gdch.z.
    • KUBECONFIG_PATH: o caminho para o ficheiro kubeconfig que obteve executando gdcloud auth login no cluster de administrador raiz.
    • PACKAGE_VALIDATION_ROOT_CERT_PATH: o caminho para o certificado de raiz de validação do pacote. Tem de usar o caminho predefinido ${ARTIFACTS_ROOT}/staging_root_ca_certificate.crt. A inclusão deste caminho valida os certificados da chave de lançamento que são usados pela validação de pacotes.

    Se o comando for bem-sucedido, o resultado final é semelhante ao seguinte exemplo:

    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
    

    Se o resultado não for semelhante a este exemplo, siga estes passos para resolver os problemas mais comuns:

    • Se o resultado incluir a mensagem Package validation root certificate requires upgrade!, rode o certificado de raiz seguindo os passos detalhados no artigo Rode o certificado de validação de pacotes.
    • Se load-oci falhar, execute a operação novamente. Se o erro persistir, verifique as outras soluções oferecidas nesta lista.
    • Se o resultado incluir a mensagem Error: unable to create k8sclient: Unauthorized, tem de se autenticar novamente. Repita o passo de preparação para validar o ficheiro kubeconfig ou execute o comando ${ARTIFACTS_ROOT}/gdcloud auth login e tente novamente a operação load-oci.
    • Se o resultado incluir a mensagem UNAUTHORIZED: unauthorized to access repository, não tem as autorizações necessárias para executar o comando load-oci. Encaminhe este problema para obter as funções necessárias para executar este comando ou peça a um utilizador que possua as funções necessárias para executar este comando em seu nome.
  9. Para a atualização APENAS com ficheiros de lançamento de modelos de parceiros, siga as instruções para carregar os pacotes de software para a distribuição de modelos de parceiros.

  10. Verifique se o objeto ReleaseMetadata para a nova versão de lançamento está no cluster de administrador raiz:

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

    Substitua VERSION pela versão do Distributed Cloud. Por exemplo, 1.x.y-gdch.z.

    Exemplo de saída:

    NAME             AGE
    1.x.y-gdch.z     2m
    
  11. Verifique se a nova versão está na lista de atualizações disponíveis para a organização raiz que vai ser atualizada:

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

    Por exemplo, 1.x.y-gdch.z, esperamos o seguinte resultado:

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

Depois de a organização raiz ser atualizada para uma nova versão, essa versão fica disponível para atualizações para uma organização inquilina.

3. Atualize a organização raiz

3.1. Pré-atualização

  1. Defina KUBECONFIG para o ficheiro kubeconfig do cluster de administrador raiz.

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    
  2. Crie o ClusterRoleBindings necessário:

    kubectl create clusterrolebinding io-organization-admin --clusterrole=organization-admin --user=USER_EMAIL
    
  3. Verifique se a organização raiz está num estado normal, conforme indicado pela resposta True:

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

    Exemplo de saída:

    True
    
  4. Siga as instruções no manual de procedimentos HSM-P0003 para reiniciar todos os HSMs.

3.2. Realize atualizações automáticas da organização principal

A atualização tem de passar pelo processo de IaC. A atualização é acionada pela atualização do campo de versão no objeto OrganizationZonalConfig correspondente da organização na zona.

  1. Atualize a versão no ficheiro YAML OrganizationZonalConfig. Elimine a secção spec.capacities.workloadServers no ficheiro, se existir.

    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. Prepare e confirme as alterações ao ficheiro.

    git add "IAC_REPO_PATH/iac/infrastructure"
    git commit
    
  3. Crie um pedido de união.

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

Quando a atualização começa, é criado um objeto OrganizationUpgrade. Verifique se o objeto OrganizationUpgrade raiz foi criado no cluster de administrador raiz na zona.

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

Se o OrganizationUpgrade não for encontrado, siga o manual de procedimentos IAC-R0001 para resolver problemas.

3.3. Verificações pós-atualização

  1. Valide os resultados da atualização:

    1. Verifique o objeto Organization para a organização raiz. Verifique se vê a condição de estado READY é True:

      kubectl -n gpc-system get organization root
      

      Exemplo de saída:

      NAME   READY
      root   True
      
    2. Verifique se Organization.Status.Version apresenta a string exata 1.x.y-gdch.z:

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

      Exemplo de resultado da validação:

      1.13.3-gdch.5548
      
  2. Verifique se existem falhas de subcomponentes na organização raiz:

    1. Verifique os subcomponentes que mostram o estado ReconciliationError ou Reconciling. Aponte o kubeconfig para 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. Para erros, consulte as notas de lançamento e os problemas conhecidos para encontrar uma solução alternativa. Caso contrário , contacte o Distributed Cloud para resolução de problemas.

  3. Se a verificação pré-voo ou pós-voo foi ignorada, remova as anotações após a conclusão da atualização:

    Exemplos:

    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-
    

Conclua a atualização da organização raiz em todas as zonas

Após a conclusão de uma atualização numa zona, recomenda-se que verifique se a zona continua a funcionar corretamente antes de avançar para a atualização da zona seguinte.

Repita os passos 1 a 3 para a organização raiz nas restantes zonas. Quando todas as zonas tiverem a respetiva organização raiz atualizada, avance para os passos seguintes.

4. Atualize recursos globais

Os recursos globais devem estar na versão mais baixa de todas as zonas. Inicie o processo de atualização de recursos globais ligando-se à zona de ancoragem e executando os seguintes 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 processo pode demorar alguns minutos. Valide a conclusão das atualizações de recursos globais executando os seguintes comandos. Não deve ser comunicado nenhum erro do comando.

# 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. Atualizações de componentes entre zonas

Num universo multizonal do GDC, determinados componentes operáveis requerem coordenação entre zonas para concluir as respetivas atualizações.

Os seguintes componentes operáveis são atualizados neste passo.

Âmbito Componentes operáveis
Infraestrutura IAC
Infraestrutura SIEM

Para atualizar o componente operável da IAC, siga o manual de procedimentos IAC-R0016.

Para atualizar o componente acionável do SIEM, siga o manual de procedimentos SIEM-G0008.

6. Atualização manual para sub-rede Anycast

Execute o seguinte script para adicionar as etiquetas necessárias às sub-redes de anycast no servidor da API de raiz 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 "$@"

Depois de o script ser executado com êxito, reverta a solução alternativa de anycast manual se a solução alternativa tiver sido aplicada anteriormente.

7. Atualização manual para o SyncServer

Os seguintes componentes operáveis são atualizados neste passo.

Âmbito Componentes operáveis
Infraestrutura NTP

Esta atualização de firmware não tem dependências de outros passos e pode ser feita em qualquer altura.

O cluster tem apenas um SyncServer, pelo que não pode funcionar no modo de alta disponibilidade. A atualização vai fazer com que o SyncServer fique indisponível durante algum tempo. O cluster vai continuar a manter a hora com os seus próprios relógios menos precisos, que não vão ter efeitos percetíveis.

Recomendamos que conclua este processo de uma só vez (não o deixe para o dia seguinte nem para o fim de semana) para evitar a variação do tempo.

7.1. Processo de atualização do SyncServer

Os seguintes comandos devem ser executados a partir do diretório de lançamento do pacote de atualização extraído.

  1. Localize o firmware mais recente para extração:

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

    O nome do ficheiro contém a versão do firmware.

    Exemplo de saída:

    │   ├── gdch-syncserver-firmware/syncserver:5.1.2
    
  2. Copie apenas os nomes dos ficheiros e atribua-os a estas variáveis:

    export SYNCSERVER_VERSION=syncserver:5.1.2
    
  3. Extraia o firmware da imagem OCI:

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

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

    Tem de ver um ficheiro *.dat e um ficheiro *updater.zip no diretório de saída.

  5. Siga o manual de procedimentos NTP-P0002: aceda à IU do SyncServer.

    1. Navegue para Ajuda -> Acerca de -> Versão do software. Se o software instalado for igual ou posterior ao firmware fornecido, o firmware não precisa de ser atualizado e pode ignorar os passos seguintes.

    2. Navegue para Administração -> Atualizar na IU do SyncServer. Carregar syncserver_s650_license.dat em Authorization File e syncserver_s650_updater.zip em Upgrade File. Em seguida, clique em Instalar.

    Valide no painel de controlo

Atualize uma organização de inquilino global

A atualização de uma organização de inquilino global a um nível elevado inclui os seguintes passos:

  1. Atualize a organização de inquilino em todas as zonas. Cada zona é atualizada individualmente.

    Verifique se a zona atual é a zona principal. O comando seguinte devolve "true" na zona principal e não devolve nada nas zonas não principais.

    kubectl get ObjectStorageAdminNode -o jsonpath='{.items[*].status.isPrimary}' --kubeconfig=ROOT_ADMIN_KUBECONFIG; echo
    
  2. Atualize os recursos da organização do inquilino global.

Verificação pré-atualização

Atualize as zonas uma de cada vez. Antes de iniciar uma atualização de uma organização numa zona, estabeleça ligação a todas as outras zonas e execute o seguinte para se certificar de que o comando devolve o estado pronto em todas as zonas. Se alguma zona indicar que não está pronta, não avance para a atualização. Verifique a organização nessa zona para diagnosticar o 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

Certifique-se de que todos os clusters estão no estado de execução e que todos os conjuntos de nós estão no estado de prontidão. Caso contrário, corrija-os primeiro antes de iniciar a atualização.

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. Atualize uma organização de inquilino

Este passo atualiza a versão do Kubernetes, os suplementos e os componentes operáveis nos clusters do plano de gestão numa organização de inquilino: org-admin, sistema e clusters de serviço.

A duração geral da atualização depende do número de fases na atualização. A atualização automática da organização de inquilinos pode ser disruptiva e requer um período de manutenção.

1.1. Preparação

Para configurar períodos de manutenção, siga o artigo Configure períodos de manutenção para a atualização da organização de inquilinos.

São fornecidas instruções para iniciar uma atualização da organização de inquilinos através de comandos da CLI ou comandos de infraestrutura como código (IaC).kubectl Para usar os comandos de IaC, configure primeiro o IaC:

  • Configuração de infraestrutura como código.
  • Configure a infraestrutura como código.

    Para usar o nomos para validar o estado, conforme referenciado nos passos baseados em IaC, como opção, tem de ter a ferramenta de linha de comandos nomos instalada. Para obter instruções de instalação e utilização do nomos, visite https://cloud.google.com/anthos-config-management/docs/how-to/nomos-command a partir de um computador com acesso à Internet.

IaC

Defina o clusterrolebinding antes de iniciar a atualização da organização de inquilinos através da IAC

  1. Aceda ao diretório iac/infrastructure/zonal/zones/ZONE_NAME/{ORG}.
  2. Aceda ao diretório IO já criado. Se o diretório não existir, crie um novo diretório.
  3. Adicione um ficheiro YAML para atribuir a função de cluster io-organization-admin à IO. Por exemplo:

    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. Atualize o kustomatization.yaml para incluir o novo ficheiro criado. Se o ficheiro kustomatization.yaml não existir, crie um novo:

    kind: Kustomization
    metadata:
      name: org-1-admin-kustomization
    resources:
    - FILE_NAME.yaml
    
  5. Envie as alterações na IAC

kubectl

Defina o clusterrolebinding antes de iniciar a atualização da organização de inquilinos através do kubectl

  1. Defina KUBECONFIG para o ficheiro kubeconfig do cluster de administrador raiz.

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG`
    
  2. Crie o ClusterRoleBindings necessário:

    kubectl create clusterrolebinding io-organization-admin --clusterrole=organization-admin --user=USER_EMAIL`
    
  3. Antes de concluir uma atualização de uma versão anterior da Distributed Cloud para a versão 1.13.x ou superior, siga as instruções no runbook BIL-R0014 para gerar manualmente uma fatura dos custos deste mês desde o início deste mês até ao início da data atual. Perde os dados de custos criados durante o processo de atualização da organização do Distributed Cloud.

1.2. Inicie a atualização

A atualização da organização do inquilino também é acionada através da IaC, atualizando o campo de versão no objeto OrganizationZonalConfig correspondente da organização na zona. Seguem-se os detalhes:

  1. Atualize a versão no ficheiro OrganizationZonalConfig YAML.

    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. Prepare e confirme as alterações ao ficheiro.

    git add "IAC_REPO_PATH/iac/infrastructure"
    git commit
    
  3. Crie um pedido de união.

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

Se a atualização for iniciada, é criado um objeto OrganizationUpgrade. Verifique se o objeto OrganizationUpgrade foi criado no cluster de administrador raiz na zona.

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

Se o OrganizationUpgrade não for encontrado, siga o manual de procedimentos IAC-R0001 para resolver problemas.

1.3. Atualizar

  1. A atualização é realizada quando tem um timeWindow que se enquadra no período de manutenção especificado por um utilizador administrador, também denominado PA. Veja o timeWindow agendado:

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

    Segue-se uma resposta típica ao 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"
    

    No exemplo anterior, o agendamento da atualização para 1.8.1-gdch.0 está entre "2022-08-28T00:00:00Z" e "2022-08-28T04:00:00Z".

    Quando a atualização começa, é criado um OrganizationUpgrade objeto, apresentado como kind: OrganizationUpgrade no exemplo de saída anterior.

    kind: OrganizationUpgrade
    
  2. Monitorize o estado geral da atualização através do objeto de atualização correspondente, anexando o comando no passo 1 com -w. Por exemplo, para consultar continuamente o estado de atualização de ORG_NAME, execute o seguinte:

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl get -n gpc-system organizationupgrade ORG_NAME -o yaml -w
    
  3. Pode ver as fases da atualização e o respetivo estado através do seguinte:

    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'
    

    A fase Succeeded refere-se ao estado geral da atualização. A fase Expired é usada para indicar que a atualização ultrapassou a hora agendada original. Todas as outras fases referem-se aos passos da atualização em curso. O estado True refere-se aos passos concluídos e o estado Unknown refere-se ao passo atual da atualização.

    Se uma verificação prévia falhou e tiver a certeza de que esta falha na verificação prévia é um falso positivo, substitua e ignore as opções de verificação prévia:

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

    Se uma verificação posterior falhou e tiver a certeza de que a falha é um falso positivo, substitua e ignore as verificações posteriores:

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl annotate -n gpc-system organization ORG_NAME \
        upgrade.private.gdc.goog/skip-postflight-check=ok
    
  4. Se o IAC foi usado para atualizar a organização de inquilinos e o estado organizationupgrade mostrar Êxito e o estado Organization da organização de inquilinos não estiver Pronto, aplique a seguinte solução alternativa.

    Adicione esta anotação: configmanagement.gke.io/managed: disabled usando IAC à organização. O estado de monitorização de Organization está no estado Pronto.

  5. A atualização da organização deve avançar para a fase seguinte e o estado do serviço ou do nó vai ficar concluído:

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

    A atualização da organização pode demorar 15 minutos a continuar.

1.4. Verificações pós-atualização

  1. Verifique o objeto Organization da organização. A condição READY tem de ser apresentada como True.

    kubectl -n gpc-system get organization ORG_NAME
    

    Exemplo de saída:

    NAME   READY
    org-1  True
    
  2. Verifique Organization.Status.Version. Tem de apresentar a string exata da versão de destino:

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

    Exemplo de saída:

    1.13.3-gdch.5548
    

    Reverta a anotação para ignorar os períodos de manutenção:

    kubectl annotate organization ORG_NAME -n=gpc-system  \
        "upgrade.private.gdc.goog/ignore-maintenance-window-" \
        --kubeconfig=ROOT_ADMIN_KUBECONFIG
    
  3. Verifique se existem falhas de subcomponentes na organização de inquilino atualizada :

    1. Verifique os subcomponentes que mostram o estado ReconciliationError ou Reconciling. Aponte o kubeconfig para 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. Para erros, consulte as notas de lançamento e os problemas conhecidos para encontrar uma solução alternativa. Caso contrário, contacte o Distributed Cloud para resolução de problemas.

  4. Se a verificação pré-voo ou pós-voo foi ignorada, remova as anotações após a conclusão da atualização:

    Exemplos:

    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. Inicie uma atualização não agendada

Acionar uma atualização instantânea da organização de inquilinos fora de um maintenanceWindow se tiver uma necessidade urgente, como um requisito de patch de segurança urgente. Isto só é necessário na organização de inquilino, uma vez que a organização de raiz já aciona a atualização instantaneamente.

Execute este comando com o administrador principal kubeconfig. O recurso personalizado da organização que tem de anotar só está presente no cluster de administrador principal. Não agende um período para este processo.

  1. Corrija a organização spec/version para a organização inquilina:

    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. Inicie uma tenant-org upgrade instantânea aplicando a anotação ignore-maintenance-window e reiniciando organizationupgrade.

  3. Monitorize o estado da atualização:

    # kubectl -n gpc-system get organizationupgrade org-1 -o yaml
    
  4. Faça verificações pós-atualização.

  5. Quando a atualização urgente estiver concluída, volte a usar os períodos agendados:

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

2. Atualização de DNS

2.1 Crie zonas de encaminhamento

  1. Exporte o kubeconfig para o cluster de administrador raiz:

    export KUBECONFIG=/root/release/root-admin/root-admin-kubeconfig
    
  2. Configure o OCIT_DOMAIN através de uma zona de encaminhamento. Substitua OCIT_DOMAIN pelo nome do domínio do OCIT e os pontos finais pelos endereços IP do DNS do 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
    

    O resultado tem o seguinte aspeto:

    dnszone.network.private.gdc.goog/ocit-domain created
    
  3. Se as alterações não forem aplicadas, reinicie a implementação:

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

    Esta alteração de DNS propaga-se a todos os clusters no GDC.

  4. Com o kubeconfig do administrador raiz, valide se a resolução do domínio OCIT está a funcionar conforme esperado:

    NAMESERVER=$(kubectl -n dns-system get service gpc-coredns-forwarder-udp | \
      awk '/[0-9]\./ {print $4}')
    dig +short @${NAMESERVER} fs.OCIT_DOMAIN
    
  5. Exportar kubeconfig para o cluster de administrador da organização:

    export KUBECONFIG=/root/release/org-admin/org-admin-kubeconfig
    
  6. Aplique o kubeconfig do administrador da organização e valide se a resolução do domínio OCIT está a funcionar conforme 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 Ative o resolvedor recursivo

Ative o resolvedor recursivo no cluster de administrador da organização apenas para organizações v1 seguindo os passos no runbook DNS-R0027.

Conclua a atualização da organização de inquilinos em todas as zonas

Após a conclusão de uma atualização numa zona, recomenda-se que verifique se a zona continua a funcionar corretamente antes de avançar para a atualização da zona seguinte.

Repita os passos 1 e 2 para a organização de inquilino nas restantes zonas. Quando todas as zonas tiverem a respetiva organização de inquilino atualizada, avance para os passos seguintes.

3. Atualize recursos globais

Os recursos globais devem estar na versão mais baixa de todas as zonas. Inicie o processo de atualização de recursos globais ligando-se à zona de ancoragem e executando os seguintes 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 processo pode demorar alguns minutos. Valide a conclusão das atualizações de recursos globais executando os seguintes comandos. Não deve ser comunicado nenhum erro do comando.

# 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. Atualize o Tenable SC

  1. Execute o GDCH doctor para determinar se é necessária uma atualização:

      gdcloud system doctor diagnose instance --include-ocs=vuln --root-admin-kubeconfig=${ROOT_ADMIN_CLUSTER_KUBECONFIG:?}
    
  2. Caso o validador tenable_sc_upgrade_readiness falhe, a imagem tem de ser atualizada. Siga os passos abaixo para atualizar o Tenable SC na organização de serviços do OI:

    1. Obtenha o nome da 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. Marque o runningState da 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. Desinstale o gráfico Helm existente para a 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. Faça uma nova configuração do Tenable SC seguindo o artigo Instale o Tenable.SC

Limpeza pós-atualização

Remova os recursos ClusterRoleBinding criados na secção Identity and Access Management.

Configure períodos de manutenção para a atualização da organização de inquilinos

Para atualizar uma organização (org) de inquilino, verifique se lhe foram atribuídas as funções de leitor e administrador corretas, conforme detalhado nas descrições das funções predefinidas e nas páginas Definições de funções para projetos para iniciar sessão na interface de linha de comandos (CLI) kubectl e na interface do utilizador (IU) da consola. Se não os tiver, use as instruções na página Conceda acesso aos recursos do projeto para os conceder ou pedir que lhe sejam concedidos.

Para configurar a janela de manutenção, tem de ter as funções necessárias. Certifique-se de que tem as seguintes funções predefinidas atribuídas:

Por predefinição, existe um MaintenanceWindow para atualizações secundárias e um MaintenanceWindow para atualizações de patches. As atualizações menores melhoram a função ou fazem alterações a partir da revisão anterior, que é uma atualização do pacote, por exemplo, para corrigir erros. As atualizações de patches resolvem problemas ou vulnerabilidades específicos. Configure a atualização de patches predefinida MaintenanceWindow para iniciar as atualizações de patches de acordo com um agendamento definido.

Para configurar o período de manutenção, use a CLI e os comandos kubectl para modificar os campos RRULE e TimeWindow dos recursos MaintenanceWindow. Isto programa as suas atualizações. Para informações sobre RRULE, visite https://pkg.go.dev/github.com/teambition/rrule-go.

Para usar os comandos da CLI kubectl, clique no separador kubectl. Para ver instruções baseadas na IU, clique no separador Consola.

Consola

  1. Inicie sessão na IU da organização.

  2. Edite o horário do período de manutenção. Aceda ao separador Manutenção e clique em Editar.

    Período de manutenção

    Figura 1. Período de manutenção

  3. É aberta a tela Editar janelas de manutenção. Use a janela para reconfigurar os períodos Patch e Minor:

    Reconfigure as atualizações de patches e as atualizações menores

    Figura 2. Reconfigure a correção e as atualizações menores

  4. Especifique ou edite a versão da correção, a hora de início e a duração, bem como o dia da semana.

    Edite a Hora de início, a Duração, a Recorrência e o Dia da Versão secundária.

    Guarde a reconfiguração

    Figura 3. Guarde a reconfiguração

  5. Clique em Guardar para aplicar as alterações.

  6. Se as alterações guardadas afetarem a recorrência, por exemplo, se implementou uma alteração ao dia da semana ou ao mês, é apresentado um diálogo. Para confirmar as alterações, clique em CONTINUAR.

    Clique em Continuar

    Figura 4. Clique em Continuar

  7. O exemplo seguinte mostra as atualizações agendadas atualizadas com base nas alterações de configuração. Repare no link Ignorar junto a cada estado pendente. Use esta opção para ignorar uma atualização pendente agendada.

    Vista de atualizações agendadas com botão ignorar
    Figura 5. Vista das atualizações agendadas, com uma opção para ignorar cada uma

kubectl

  1. Inicie sessão na kubectl CLI. Localize estas instruções no separador CLI. Certifique-se de que tem o acesso correto ao cluster de administrador da organização antes de continuar.

  2. Pode modificar três campos no MaintenanceWindow para configurar o timeWindow no qual ocorre a atualização da organização principal. Os seguintes comandos mostram uma modificação ao período de manutenção de atualização de patches. A modificação de atualizações secundárias é semelhante.

    # 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}'"}]'
    

    A hora de início e a hora de fim, /spec/timeWindow/start e /spec/timeWindow/end, respetivamente, têm de ter cada uma uma data/mês/ano que tenha ocorrido no passado. O período é calculado com base nos valores que introduz.

Atribua pelo menos a duração mínima apresentada para cada um dos tipos de atualização. Pode atribuir uma duração mais longa, conforme indicado nas seguintes recomendações:

  • Atualizações menores: requerem, pelo menos, 12 horas num período contínuo de 32 dias.
  • Atualizações de patches: requerem, pelo menos, 48 horas num período contínuo de 32 dias, com 1 ou mais blocos de tempo. Embora a consola mostre uma especificação de janela mínima de 4 horas, a Google recomenda que atribua, pelo menos, 6 horas a cada bloco de tempo.

Atualização manual da infraestrutura principal do Operations Suite

Este processo de atualização aplica-se apenas à atualização da versão 1.13.x para a 1.14.3.

Certifique-se de que todas as contas locais e de domínio geridas estão ativadas com palavras-passe que não expiraram. As contas que não se encontram num bom estado podem causar erros neste processo.

Faça pontos de verificação de VMs e cópias de segurança de diretórios

  1. Efetue pontos de verificação de VMs.

    1. No anfitrião BM01, abra uma consola do PS como administrador.
    2. Execute o seguinte comando para cada anfitrião do Hyper-V no cluster.

      $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
      }
      

      Mantenha a janela do PowerShell aberta para os passos seguintes

  2. Ative os caminhos de ficheiros longos

      $path = 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem'
      Set-ItemProperty -Path $path -Name 'LongPathsEnabled' -Value 1
    
  3. Fazer uma cópia de segurança da unidade H:\operations_center. (Esta ação suporta a reversão da atualização.)

      Rename-Item -Path H:\operations_center -NewName operations_center_backup
    
  4. Diretórios de configuração de cópia de segurança em CONFIG1. (Esta cópia de segurança fornece uma referência ao criar a nova configuração config.ps1.)

    1. No anfitrião BM01, use o protocolo de ambiente de trabalho remoto (RDP) para estabelecer ligação ao endereço IP da VM CONFIG1 e inicie sessão com uma conta de administrador do sistema. Exemplo: mstsc /v 192.168.100.99

    2. Abra uma consola do PS com a opção Executar como administrador.

      • Crie a pasta de cópia de segurança
      mkdir c:\config1_backup
      
      • Fazer uma cópia de segurança de C:\dsc
      Move-Item -Path "C:\dsc\" -Destination "C:\config1_backup"
      
      • Faça uma cópia de segurança de C:\config
      Move-Item -Path "C:\config\" -Destination "C:\config1_backup"
      
      • Fazer uma cópia de segurança de C:\operations_center
      Move-Item -Path "C:\release\operations_center\" -Destination "C:\config1_backup"
      
      • Certifique-se de que os caminhos de ficheiros longos estão ativados
      $path = 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem'
      Set-ItemProperty -Path $path -Name 'LongPathsEnabled' -Value 1
      

Carregue software de terceiros

Realizar as tarefas no software de terceiros.

Atualize máquinas virtuais existentes

  1. Obtenha o diretório de instalação.

    1. Transfira o pacote de componentes da OIC seguindo as instruções da secção Transferir ficheiros.

    2. No anfitrião BM01, extraia o diretório operations_center do ficheiro prod_IT_component_bundle.tar.gz transferido.

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

      A extração do ficheiro TAR deve criar uma pasta release na raiz de H:

    3. Mova operations_center para a raiz de H:

      Move-Item -Path H:\release\operations_center -Destination H:\
      
  2. Atualize o ficheiro config.ps1 com dados específicos do site

    O ficheiro de configuração config.ps1 fornece todas as informações necessárias para criar e configurar o ambiente de infraestrutura do Operations Suite (OI). Para atualizar o ficheiro de configuração, tem de recolher todas as seguintes informações. A cópia de segurança do ficheiro config.ps1 existente é uma boa referência para proteger a substituição não intencional das definições existentes. Importante: não avance até que o processo config.ps1 esteja concluído e correto.

    • O resultado da configuração de rede da ferramenta occonfigtool, especialmente o ficheiro ocinfo.common.opscenter.local.txt. Os nomes das redes, por exemplo, OCCORE-SERVERS referidos nos passos seguintes, fazem referência à coluna Name nesse documento.
    • O nome do domínio e o endereço IP do servidor DNS de cada célula do GDC que este OI gere. Estes dados estão disponíveis nos resultados do questionário de admissão de clientes (CIQ).

    Faça todas as alterações no anfitrião BM01 como Administrator.

  3. Copie o código de exemplo de configuração correto para o tipo de implementação:

    1. Copie H:\operations_center\dsc\config.example.ps1 para H:\operations_center\config\config.ps1.
  4. Com o VSCode ou o Powershell ISE, valide e atualize os valores em config.ps1.

    1. Se a OIC for implementada como vários sites:

      1. Encontre comentários etiquetados como ### Multi-Site:
      2. Realize as ações descritas nos comentários que encontrou.
    2. Atualize HardwareVersion, a menos que a predefinição (3.0) esteja correta.

    3. Atualize PrimarySiteCode, a menos que a predefinição (DC1) esteja correta.

    4. O código do site é usado em muitos nomes. Pesquise e substitua todas as instâncias de DC1 pelo código do site correto. Use a pesquisa que não é sensível a maiúsculas e minúsculas. Reveja cada alteração, uma vez que algumas podem não ser necessárias. Por exemplo, se o código do site for AB1, o nome do anfitrião DC1-DC1 tem de mudar para AB1-DC1, e não para AB1-AB1.

    5. Atualize DnsDomain se a predefinição não estiver correta. Se este valor for alterado, pesquise e substitua opscenter.local em todo o ficheiro config.ps1. Existem várias localizações onde esse valor predefinido está codificado.

    6. Atualize os objetos em DnsConditionalForwarder com informações específicas do site. Tem de existir, pelo menos, um objeto de encaminhamento. Remova exemplos desnecessários.

      Este passo pode ser realizado no WSL em CONFIG1 se a CLI gdcloud e kubectl estiver instalada.

      Para extrair informações específicas do site do cluster de administração raiz, use:

      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 – O nome de domínio DNS da célula do GDC, por exemplo, dns.delegatedSubdomain em ciq.yaml.
      2. Master - Uma lista de IPs de servidores DNS (normalmente, apenas um). Procure no cellcfg o tipo DNSReservation. Se a célula GDC estiver implementada, procure no espaço de nomes dns-system do cluster de administração raiz o EXTERNAL-IP do serviço gpc-coredns-external-udp e o FQDN da célula bert.sesame.street.

      3. Nas implementações em vários sites, existe um objeto de tabela hash por célula.

    7. Não altere nenhum conteúdo dos objetos Users, Groups e GroupPolicy.

    8. Atualize DNSServers para conter os 2 endereços IP atribuídos aos controladores de domínio principal e secundário, como <SITE>-DC1 e <SITE>-DC2.

    9. Atualize NTPServers para ser uma lista dos endereços IP do SyncServer dos recursos personalizados TimeServer do administrador principal. Pode obter este conjunto de endereços IP através do seguinte:

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

      Tem de formatar estes endereços IP em NTPServers, conforme mostrado no exemplo seguinte:

      NtpServers = @(
        '10.251.80.2',
        '10.251.80.3',
        '10.251.80.4',
        '10.251.80.5'
      )
      
    10. Atualize o SubnetPrefix valor predefinido, ou seja, 24, com o valor do prefixo da sub-rede fornecido pelo cliente para a sub-rede OCCORE-SERVERS, se necessário.

    11. Atualize o valor predefinido DefaultGateway com o gateway predefinido fornecido pelo cliente para a sub-rede OCCORE-SERVERS.

    12. Encontre e atualize o valor predefinido WorkstationCider com o valor fornecido pelo cliente para a sub-rede OC-WORKSTATIONS na notação CIDR IPv4.

    13. Atualize o valor de WorkstationAllowRemote para $true se o cliente optar por permitir o acesso remoto às respetivas estações de trabalho

    14. Localize e substitua o prefixo de sub-rede de exemplo 172.21.0. pelo prefixo de sub-rede OCCORE-SERVERS fornecido pelo cliente.

    15. Encontre e substitua o prefixo da sub-rede de exemplo 172.21.2. pelo prefixo da sub-rede OCCORE-JUMPHOSTS fornecido pelo cliente.

    16. Localize e substitua o prefixo da sub-rede de exemplo 172.21.32. pelo prefixo da sub-rede OC-WORKSTATIONS fornecido pelo cliente.

    17. Localize e substitua o valor de exemplo da mensagem do dia legalnoticecaption de Pref caption pela legenda fornecida pelo cliente.

    18. Localize e substitua o valor de exemplo da mensagem do dia legalnoticetext de Pref text pelo texto fornecido pelo cliente.

    19. Valide cada objeto "node" e atualize-o, se necessário.

      1. NodeName – Certifique-se de que o nome de anfitrião está correto. Alguns nomes são usados em muitos locais, por exemplo, controladores de domínio. Se alterar um nome aqui, verifique se tem de o alterar noutro local na configuração.
      2. IPv4Addr - Tem de ser o endereço IP do anfitrião. Normalmente, não é necessário alterar o último octeto. Alguns deles podem ter sido atualizados durante a pesquisa e substituição de rede realizadas nos passos anteriores.

      3. HyperVHost - Este valor tem de ser o endereço IP do servidor Hyper-V que aloja esta MV. Pode obter o endereço IP de cada servidor BM?? na secção "Servidores Hyper-V" da configuração. Não altere a atribuição do anfitrião do Hyper-V neste campo, uma vez que nem todos os anfitriões do Hyper-V conseguem suportar todos os tipos de MV. Altere apenas o nome do anfitrião do Hyper-V para o respetivo endereço IP.

    20. Valide os detalhes da segunda interface de rede em todos os nós com Role=jumphost. Use os detalhes da sub-rede OCCORE-JUMPHOSTS para esta interface. Verifique:

      1. JumphostIPv4Cidr
      2. JumphostDefaultGateway
    21. Atualize a secção específica do ADFS no nó onde Role=adfs.

      1. Encontre a linha Name = 'SplunkTrust' # Must be unique to the farm. Append "Trust"
      2. Substitua as três ocorrências de opscenter.local após esta linha pelo seu domínio DNS
    22. Atualize os âmbitos de DHCP para corresponderem ao plano de IP do cliente, conforme necessário. Para cada âmbito, valide se os seguintes valores estão corretos. Os nomes nos âmbitos correspondem aos nomes usados no plano da rede ocinfo.common.opscenter.local.txt, por isso, use o seguinte na validação:

      1. ScopeId
      2. IpStartRange
      3. IpEndRange
      4. Router
      5. SubnetMask
    23. Confirme se os valores correspondem aos valores no ficheiro config1.ps1 com cópia de segurança

    24. Certifique-se de que guarda o ficheiro.

CONFIG1 VM Preparation

A preparação de CONFIG1 é realizada em BM01. Todas as outras atualizações ocorrem enquanto tem sessão iniciada na VM CONFIG1.

  1. Copie o diretório operations_center para a VM CONFIG1

    1. No anfitrião BM01, abra uma consola do PS como administrador.

    2. Copie operations_center para preparar os ficheiros necessários para a 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. Desative a sincronização de tempo do Hyper-V

      1. Inicie sessão no anfitrião BM01 como administrador.

      2. Abra o PowerShell no Windows como administrador e execute o seguinte comando:

      # Disabling Hyper-V Time Sync
      Disable-VMIntegrationService -VMName `<SITE>-CONFIG1` -Name 'Time Synchronization'
      
    4. Preparação e validação da VM CONFIG1

      1. No anfitrião BM01, inicie sessão na VM CONFIG1 com a sua conta -SA. Estabeleça ligação ao endereço IP da VM através do Ambiente de Trabalho Remoto (RDP). Exemplo: mstsc /v 192.168.100.99

      2. Abra uma janela do PowerShell através do menu "Executar como utilizador diferente" para executar como utilizador Marvin.

      3. Na nova janela do PowerShell, inicie uma sessão administrativa:

        Start -Verb runas -FilePath powershell.exe
        

        Feche a janela do PowerShell anterior, deixando a janela do administrador aberta.

      4. Verifique se a janela do PowerShell administrativo está a ser executada como Marvin

        whoami
        
      5. Organize os ficheiros que foram preparados a partir do anfitrião BM01.

        Move-Item -Path c:\operations_center -Destination c:\release
        C:\release\operations_center\dsc\Initialize-ConfigHostFiles.ps1
        
      6. Valide se c:\dsc e c:\config existem.

      7. Copie ficheiros de credenciais e certificados da cópia de segurança

        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. Crie os dados do MECM necessários para compilar MOFs

        C:\dsc\Build-MecmFiles.ps1
        
      9. Valide se o ambiente de compilação está pronto executando Build-Mof.ps1, que gera ficheiros MOF para todas as máquinas OI.

        C:\dsc\Build-Mof.ps1
        
    5. Preencha as variáveis de credenciais

      Estas variáveis são usadas ao longo do processo de atualização. Preencha-os uma vez na janela do Marvin Powershell aberta 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. Verifique se o DSC está em execução e se os servidores estão acessíveis.

      $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}
      

Resolva problemas de conetividade.

  1. Se New-CimSession falhar, verifique se o valor de NodeName está correto em config.ps1. Confirme também que o servidor está online e acessível.

    O erro começa com Get-CimSession: WinRM cannot process the request.

Atualize os controladores de domínio

  1. Enquanto tem sessão iniciada em CONFIG1, atualize o controlador de domínio principal.

    Preencha as variáveis, remova os GPOs antigos e associe novos GPOs.

    $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
    }
    

    Desassocie objetos de política de grupo. A associação é feita no final da atualização.

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

    Atualize o controlador de domínio 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. Valide a sincronização de tempo com o SyncServer

    2. Inicie sessão no DC1 através do RDP como administrador do domínio.

      1. Abra uma janela do Powershell como administrador.
      2. Execute o seguinte comando para validar a configuração de tempo.

        w32tm /query /status /verbose
        
    1. Execute os seguintes comandos para testar a resincronização da hora:

       # Testing time resyncronization
       w32tm /resync
      
       # Desired output
       Sending resync command to local computer
       The command completed successfully.
      
    2. Volide novamente se a configuração de tempo está correta e não tem erros.

       w32tm /query /status /verbose
      
  2. Atualize o segundo controlador de domínio.

    1. Use a janela do PowerShell CONFIG1 existente para executar o seguinte script.

      .\Update-RemoteHost.ps1 @da_args -ComputerName $dc2.NodeName
      
  3. Valide a replicação do Active Directory.

    1. Assim que o segundo DC estiver em funcionamento, execute os seguintes comandos a partir de um dos controladores de domínio para validar a replicação do Active Directory:

      repadmin /replsummary
      

      O resultado tem de ser semelhante ao seguinte:

      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
      

Atualize CA-ISSUING1 e CA-WEB

  1. Use o terminal do PowerShell existente no CONFIG1 para atualizar o CA-ISSUING1.

      $ca_iss = $config.AllNodes | Where-Object {$_.role -eq "ca_issuing"}
      c:\dsc\Update-RemoteHost.ps1 @sa_args -ComputerName $ca_iss.NodeName
    
  2. Use o terminal do PowerShell existente no CONFIG1 para atualizar o CA-WEB.

      $ca_web = $config.AllNodes | Where-Object {$_.role -eq "ca_web"}
      c:\dsc\Update-RemoteHost.ps1 @sa_args  -Computername $ca_web.NodeName
    
  3. Valide a atualização

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

Atualize o CA-ROOT1

Use o terminal do PowerShell existente no CONFIG1

  1. Ligue o 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. Atualize o 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. Se o CA_ROOT1 não tiver sido reiniciado após o script anterior, reinicie-o manualmente.

  4. Valide a atualização.

      $ca_root | ForEach-Object {
      $session = New-CimSession -ComputerName $_.Ipv4Addr -Credential $caroot_cred
      Get-DscConfigurationStatus -CimSession $session}
    
  5. Verifique se a definição Peer está <SITE>-DC1.<DNSDOMAIN> e se State está Active.

    Não avance se a hora não estiver sincronizada corretamente.

      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. Desligue o CA-Root.

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

Atualize o ADFS

Use o terminal do PowerShell existente no CONFIG1

  1. Atualize a VM do 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}
    

Atualize os Jumphosts.

Use o terminal do PowerShell existente no CONFIG1

  1. Crie uma matriz de Jumphosts.

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

      $jumps | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}
    
  3. Valide a atualização.

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

Atualize os servidores de ficheiros.

Use o terminal do PowerShell existente no CONFIG1

  1. Crie uma matriz que contenha os Fileservers.

      $role = 'file'
      $files = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. Atualize os servidores de ficheiros.

      $files | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}
    
  3. Valide a atualização.

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

Atualize os servidores DHCP.

Use o terminal do PowerShell existente no CONFIG1

  1. Atualize o DHCP1.

      $role = 'dhcp_primary'
      $dhcp1 = $config.AllNodes | Where-Object {$_.role -eq $role}
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $dhcp1.NodeName
    
  2. Valide a atualização.

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

      $role = 'dhcp_failover'
      $dhcp2 = $config.AllNodes | Where-Object {$_.role -eq $role}
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $dhcp2.NodeName
    
  4. validar a atualização.

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

Atualize os servidores do Userlock.

Use o terminal do PowerShell existente no CONFIG1

  1. Crie uma matriz do PowerShell que contenha os servidores do Userlock.

      $role = 'userlock_primary'
      $ulock1 = $config.AllNodes | Where-Object {$_.role -eq $role}
      $role = 'userlock_backup'
      $ulock2 = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. Remova os ficheiros de marcadores da configuração 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. Atualize o servidor Userlock principal.

      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $ulock1.NodeName
    
  4. Atualize o servidor Userlock de cópias de segurança.

      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $ulock2.NodeName
    
  5. Valide as atualizações.

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

Atualize os servidores Nessus.

Use o terminal do PowerShell existente no CONFIG1

  1. Crie uma matriz do PowerShell que contenha os servidores Nessus.

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

      $nessus | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args  -Computername $_.NodeName}
    
  3. Valide a atualização.

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

Atualize os servidores Hyper-V.

Use o terminal do PowerShell existente no CONFIG1

  1. Crie uma matriz do PowerShell que contenha os servidores Hyper-V.

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

      $hyper | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}
    
  3. Valide a atualização.

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

Atualize as caixas de ferramentas

Use o terminal do PowerShell existente no CONFIG1

  1. Crie uma matriz do PowerShell que contenha os servidores da caixa de ferramentas.

      $role = 'toolbox'
      $tools = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. Crie uma unidade adicional no 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
         }}}
    

    Verifique se a saída mostra dois discos atribuídos à VM. Exemplo:

      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. Atualize os servidores da caixa de ferramentas.

      $tools | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args  -Computername $_.NodeName}
    
  4. Valide a atualização.

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

Use o terminal do PowerShell existente no CONFIG1 para validar a atualização.

  1. Verifique se o DSC está a ser executado sem erros.

       $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}
    

Atualize as VMs do Splunk

  1. Na janela do Powershell em CONFIG1, configure e execute a configuração do DSC:

    • Introduza o código do local. Exemplo: "DC1"

       $sitecode = Read-Host "Enter your site code"
       Set-Location c:\dsc
      
    • Configure o encaminhador pesado:

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

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

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

       $myargs = @{
       Computername = "$sitecode-INDEXER3"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • Configure o gestor:

       $myargs = @{
       Computername = "$sitecode-SPLUNKMGR"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • Configure o cabeçalho de pesquisa:

       $myargs = @{
       Computername = "$sitecode-SEARCHHEAD"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
  2. Na janela do Powershell em CONFIG1:

      $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. Siga SIEM-G0006 para definir a chave Pass4Symm global e SIEM-G0007 para anexar cada zona ao Splunk no OIC.

Atualize o anfitrião CONFIG1

  1. Na janela do Powershell em CONFIG1:

    Start-DscConfiguration -ComputerName $env:COMPUTERNAME -Path c:\config\mofs -Verbose -Wait -Force
    
  2. Se o computador for reiniciado, inicie sessão novamente e inicie o PowerShell novamente como Marvin e, em seguida, eleve os privilégios a administrador. Preencha as variáveis necessárias para as secções seguintes.

    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)

Uma vez que a MCM não é um componente atualizável, a única opção é destruir os anfitriões da MCM existentes e voltar a implementar a MCM.

  • Certifique-se de que o software da MCM atual foi preenchido de acordo com o documento IT-T0023.

  • O procedimento de reimplementação está abordado no artigo IT-R0019.

Remova pontos de verificação de VMs

Quando as atualizações estiverem concluídas, os pontos de verificação devem ser removidos. Os pontos de verificação podem resultar numa utilização excessiva do disco ao longo do tempo. Só os mantenha se for necessário um restauro ao ponto de verificação devido a uma atualização com falhas.

Use o terminal do PowerShell existente no CONFIG1

  1. Remova os pontos de verificação da 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
      }}
    

Reative os objetos de política de grupo no domínio

Use o terminal do PowerShell existente no CONFIG1

  1. Altere a configuração da função do controlador de domínio para ativar links em GPOs geridos

      $gpolinks = (Get-Content C:\dsc\data\GpoLinkMapping.yaml -Raw).Replace("LinkEnabled: 'No'", "LinkEnabled: 'Yes'")
      $gpolinks | Out-File C:\dsc\data\GpoLinkMapping.yaml -Force
    
  2. Atualize o controlador de domínio com a função ObjectOwner:

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

Contacte a equipa do Google

Consulte a página Pedir apoio técnico para ver os passos para contactar a Google e receber ajuda adicional.