在多區域部署中執行升級

在多區域部署中,系統會逐一升級各個區域,且彼此獨立。升級作業不會跨時區進行全球協調。如果 IO 要將機構升級至新版本,必須在每個區域執行升級作業。因此,不同區域的機構在特定時間可能使用不同版本。

本頁列出的升級順序,是先升級一個區域中的根機構,以及所有租戶機構,再移至另一個區域。所有可用區升級完畢後,系統最後會升級全域資源。

本頁說明如何提供下列類型的資訊,以繼續進行多區域 Google Distributed Cloud (GDC) 實體隔離環境升級:

  • 必要存取權和取得方式。
  • 所需工具。
  • 升級前應採取的步驟。
  • 如何以及依何種順序升級各種 Distributed Cloud 元件。

以下清單定義了升級的各個元件:

目標版本:所有區域都使用相同的目標版本。

一次一個:一次升級一個可用區。在某個區域觸發升級前,請確認其他區域未執行升級。

全域資源:定義為部署在全域 kube-apiserver 上的 Kubernetes 資源,而非每個區域各有一份的區域資源。全球資源的生命週期不同。請注意,他們只需要在最後升級一次。

準備

這些網址可供您在氣隙環境以外存取。

開始升級前,請先備妥下列項目:

產生法規遵循報表

法規遵循報告會列出下列機構:

  • 已停止支援
  • 錯過重要的安全性修補程式

產生法規遵循報表是選用步驟,且必須由已通過驗證並具備organization-admin role的 IO 執行。如要產生報表,請執行下列指令:

  gdcloud system upgrade report-compliance

如要進一步瞭解準備工作規定,請參閱「必要條件」一節。

Identity and Access Management

開始升級前,請在每個可用區執行下列操作:

  1. 執行 gdcloud auth login,取得根管理員叢集和所有機構管理員叢集的 kubeconfig 檔案。

  2. 請按照「Access and privilege elevation process」IAM-R0005 執行手冊中的操作說明,新增下列項目:

    1. ClusterRoleBinding,並在每個區域的根管理員叢集中使用 cluster-admin ClusterRole
    2. 機構管理員叢集,以便取得臨時管理員存取權。

暫停所有可用區的全球資源升級

使用取得的 kubeconfig 檔案,暫停每個區域中的所有全域資源升級作業。

# 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

升級全域根機構

升級全域根機構單位大致包含下列步驟:

  1. 在所有可用區升級根機構。每個區域都會個別升級。

    檢查目前的區域是否為主要區域。下列指令會在主要區域中傳回「true」,在非主要區域中則不會傳回任何內容。

    kubectl get ObjectStorageAdminNode -o jsonpath='{.items[*].status.isPrimary}' --kubeconfig=ROOT_ADMIN_KUBECONFIG; echo
    
  2. 升級需要跨區域協調的元件。

  3. 升級全域根管理員資源。

升級前檢查

一次升級一個可用區。在一個區域中升級機構前,請先連線至所有其他區域,然後執行下列指令,確認所有區域的指令都傳回「ready」。如有任何區域報告尚未準備就緒,請勿繼續升級。請檢查該區域中的機構,以診斷問題。

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. 下載並複製更新套件

以下說明如何開始使用:

  • 將更新套件下載至可連上網際網路的裝置,然後複製到 USB 隨身碟。
  • 將更新套件從 USB 隨身碟複製到與網際網路隔離的環境。

如需其他背景資訊,請參閱「下載檔案」一文,瞭解如何下載 Distributed Cloud 發布詳細資料;以及「轉移下載」一文,瞭解如何使用可攜式儲存裝置將檔案轉移至與網際網路隔離的環境。

  1. 與 Google POC 合作,決定升級是否適用於合作夥伴營運的 Distributed Cloud 部署作業,因此應使用合作夥伴模型發布檔案。

    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. 從可連上網際網路的電腦下載更新套件到 USB 隨身碟。請使用 Google 合作商家業務聯絡人 (POC) 提供的版本和摘要詳細資料。

    1. 執行 gcloud auth login 存取 Cloud Storage bucket。
    2. 使用 --skip-unzip 執行指令碼,將更新套件和下載器指令碼擷取至目前目錄,例如 /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. 如要使用合作夥伴機型發布檔案升級,請按照操作說明準備合作夥伴機型發布用的軟體套件。

  3. 將下載器指令碼和 gdch 目錄複製到 USB 隨身碟。

  4. 從 USB 隨身碟將更新複製到 OCIT。將檔案放在類似的位置,例如 /home/download/

  5. 在 OCIT 上重新定義這些變數,然後擷取更新:

    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. 下載器會將發行內容解壓縮至 gdch/full-release-1.2.0-gdch.243 (例如 /home/download/gdch/full-release-1.2.0-gdch.243)。將這個變數指派給完整路徑:

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

2. 設定構件登錄檔升級

如要順利升級,請完成下列步驟:

將構件推送到容器登錄檔

  1. KUBECONFIG 設為根管理員叢集的 kubeconfig 檔案。

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    
  2. 建立所需的 ClusterRoleBindings

    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. 建立所需的 RoleBindings

    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. 建立 RoleBindings,以便推送 OCI 組合:

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

    輸出內容如下所示:

    rolebinding.rbac.authorization.k8s.io/infrastructure-operator-sar-harbor-admin created
    
  5. 請按照「調整 Artifact Registry 儲存空間大小」一文中的說明,執行下列操作:

    1. 檢查管理員叢集中 Artifact Registry 的儲存空間用量,確認有足夠空間可推送構件。
    2. 如要增加可用空間,請按照「調整 Artifact Registry 儲存空間大小」一文中的步驟操作。
  6. 設定 Docker 設定:

    cp ${ARTIFACTS_ROOT}/docker-credential-gdcloud /usr/bin
    
  7. 設定 Docker 信任信任儲存區套件。

    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. 將構件載入根管理員叢集的構件登錄檔:

    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
    

    更改下列內容:

    • VERSION:Distributed Cloud 版本。例如:1.x.y-gdch.z
    • KUBECONFIG_PATH:您在根管理員叢集中執行 gdcloud auth login 時取得的 kubeconfig 檔案路徑
    • PACKAGE_VALIDATION_ROOT_CERT_PATH:套件驗證根憑證的路徑。您必須使用預設路徑 ${ARTIFACTS_ROOT}/staging_root_ca_certificate.crt。加入這個路徑可驗證套件驗證作業使用的發布金鑰憑證。

    如果指令執行成功,輸出內容結尾會類似於下列範例:

    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
    

    如果輸出內容與這個範例不同,請按照下列步驟解決最常見的問題:

    • 如果輸出內容包含 Package validation root certificate requires upgrade! 訊息,請按照「輪換套件驗證憑證」一文詳述的步驟輪換根憑證。
    • 如果 load-oci 失敗,請再次執行作業。如果錯誤仍未解決,請參考這份清單中的其他解決方案。
    • 如果輸出內容包含 Error: unable to create k8sclient: Unauthorized 訊息,請重新驗證。重複準備步驟,驗證 kubeconfig 檔案或執行 ${ARTIFACTS_ROOT}/gdcloud auth login 指令,然後重試 load-oci 作業。
    • 如果輸出內容包含 UNAUTHORIZED: unauthorized to access repository 訊息,表示您沒有執行 load-oci 指令的必要權限。請將這個問題提報給相關人員,取得執行這項指令所需的角色,或請具備必要角色的使用者代為執行這項指令。
  9. 僅限使用合作夥伴機型發布檔案升級:請按照操作說明載入合作夥伴機型發布的軟體套件。

  10. 確認新發布版本的 ReleaseMetadata 物件位於根管理叢集:

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

    請將 VERSION 改成 Distributed Cloud 發布版本。例如:1.x.y-gdch.z

    輸出內容範例:

    NAME             AGE
    1.x.y-gdch.z     2m
    
  11. 確認新版本位於要升級的根機構可用的升級清單中:

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

    舉例來說,如果輸入 1.x.y-gdch.z,預期輸出內容如下:

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

根機構升級至新版本後,租戶機構就能升級至該版本。

3. 升級根機構

3.1. 升級前

  1. KUBECONFIG 設為根管理員叢集的 kubeconfig 檔案。

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    
  2. 建立所需的 ClusterRoleBindings

    kubectl create clusterrolebinding io-organization-admin --clusterrole=organization-admin --user=USER_EMAIL
    
  3. 確認根機構處於正常狀態,回應會顯示 True

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

    輸出內容範例:

    True
    
  4. 按照 runbook HSM-P0003 中的操作說明,重新啟動所有 HSM。

3.2. 執行根機構的自動升級

升級作業必須經過 IaC 程序。如要觸發升級,請更新區域中對應機構的 OrganizationZonalConfig 物件中的版本欄位。

  1. 更新 OrganizationZonalConfig YAML 檔案中的版本。如果檔案中存在 spec.capacities.workloadServers 區段,請刪除該區段。

    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. 暫存並提交檔案變更。

    git add "IAC_REPO_PATH/iac/infrastructure"
    git commit
    
  3. 建立合併要求。

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

升級開始時,系統會建立 OrganizationUpgrade 物件。確認根 OrganizationUpgrade 物件已在區域的根管理員叢集中建立。

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

如果找不到 OrganizationUpgrade,請按照 IAC-R0001 執行手冊進行疑難排解。

3.3. 升級後檢查

  1. 確認升級結果:

    1. 檢查根機構的 Organization 物件。確認您看到狀態條件 READYTrue

      kubectl -n gpc-system get organization root
      

      輸出內容範例:

      NAME   READY
      root   True
      
    2. 確認 Organization.Status.Version 顯示的字串完全符合 1.x.y-gdch.z

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

      驗證輸出內容範例:

      1.13.3-gdch.5548
      
  2. 檢查根機構中的子元件故障情形:

    1. 檢查顯示 ReconciliationErrorReconciling 狀態的子元件。將 kubeconfig 指向 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. 如要瞭解錯誤,請參閱版本資訊已知問題,尋找解決方法。如果找不到解決方法,請與 Distributed Cloud 聯絡,以利進行疑難排解。

  3. 如果略過預檢或後檢,請在升級完成後移除註解:

    範例:

    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 到 3。所有區域的根機構升級後,請繼續進行下一個步驟。

4. 升級全域資源

全域資源應位於所有區域的最低版本。連線至錨定區域並執行下列指令,啟動全域資源升級程序。

# 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

這項程序可能需要幾分鐘才能完成。執行下列指令,確認全域資源升級作業是否完成。指令不應回報失敗。

# 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. 跨可用區元件升級

在 GDC 多區域環境中,某些可運作的元件需要區域間的協調作業,才能完成升級。

在這個步驟中,可操作的元件會升級如下。

範圍 可操作的元件
基礎架構 IAC
基礎架構 SIEM

如要升級 IAC 可操作元件,請按照 Runbook IAC-R0016 操作。

如要升級 SIEM 可操作元件,請按照 Runbook SIEM-G0008 操作。

6. Anycast 子網路的手動升級

執行下列指令碼,將必要標籤新增至全域根 API 伺服器中的任播子網路:

#!/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 "$@"

指令碼順利執行後,如果先前已套用解決方法,請還原手動任播 解決方法

7. 手動升級 SyncServer

在這個步驟中,可操作的元件會升級如下。

範圍 可操作的元件
基礎架構 NTP

這項韌體升級作業不需依賴任何其他步驟,隨時都能進行。

叢集只有一個 SyncServer,因此無法在高可用性模式下運作。升級期間,SyncServer 會暫時無法使用。叢集會繼續使用自己的較不準確時鐘來維持時間,但不會有任何明顯影響。

建議您一次完成這項程序 (不要留到隔夜或週末),以免時間偏移。

7.1. SyncServer 升級程序

下列指令應從解壓縮更新套件的發布目錄執行。

  1. 找出要擷取的最新韌體:

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

    檔案名稱包含韌體版本。

    輸出內容範例:

    │   ├── gdch-syncserver-firmware/syncserver:5.1.2
    
  2. 只複製檔案名稱,並指派給下列變數:

    export SYNCSERVER_VERSION=syncserver:5.1.2
    
  3. 從 OCI 映像檔擷取韌體:

    ${ARTIFACTS_ROOT}/gdcloud artifacts extract ${ARTIFACTS_ROOT}/oci syncserver_firmware --image-name=gdch-syncserver-firmware/${SYNCSERVER_VERSION:?}
    
  4. 解壓縮韌體:

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

    輸出目錄中必須有一個 *.dat 和一個 *updater.zip 檔案。

  5. 按照 runbook NTP-P0002 的步驟操作,存取 SyncServer UI。

    1. 依序前往「說明」->「關於」->「軟體版本」。如果已安裝的軟體版本等於或晚於提供的韌體版本,則不需要更新韌體,可以略過後續步驟。

    2. 在 SyncServer 使用者介面中,依序前往「Admin」->「Upgrade」。上傳 Authorization File 中的 syncserver_s650_license.datUpgrade File 中的 syncserver_s650_updater.zip。然後按一下「安裝」。

    在資訊主頁中驗證

升級全域租戶機構

升級全域租戶機構單位大致包含下列步驟:

  1. 在所有可用區升級租戶機構。每個區域都會個別升級。

    檢查目前的區域是否為主要區域。下列指令會在主要區域中傳回「true」,在非主要區域中則不會傳回任何內容。

    kubectl get ObjectStorageAdminNode -o jsonpath='{.items[*].status.isPrimary}' --kubeconfig=ROOT_ADMIN_KUBECONFIG; echo
    
  2. 升級全域租戶機構資源。

升級前檢查

一次升級一個可用區。在一個區域中升級機構前,請先連線至所有其他區域,然後執行下列指令,確認所有區域的指令都傳回「ready」。如有任何區域報告尚未準備就緒,請勿繼續升級。請檢查該區域中的機構,以診斷問題。

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

確認所有叢集都處於執行中狀態,且所有節點集區都處於就緒狀態。如果沒有,請先修正問題再開始升級。

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. 升級租戶機構

這個步驟會升級租戶機構 (org-admin、系統和服務叢集) 中管理層叢集的 Kubernetes 版本、外掛程式和可操作元件。

升級的總時間取決於升級階段的數量。 租戶機構的自動升級可能會造成中斷,因此需要維護期間。

1.1. 準備

如要設定維護期間,請按照「為租戶機構升級設定維護期間」一文的說明操作。

我們提供使用 kubectl CLI 指令或基礎架構即程式碼 (IaC) 指令,啟動租戶機構升級的說明。如要使用 IaC 指令,請先設定 IaC:

  • 基礎架構即程式碼設定
  • 設定基礎架構即程式碼

    如要使用 nomos 驗證狀態 (如 IaC 步驟所述),您必須安裝 nomos 指令列工具。如要取得 nomos 安裝和使用說明,請透過可連上網際網路的電腦前往 https://cloud.google.com/anthos-config-management/docs/how-to/nomos-command

IaC

使用 IAC 啟動租戶機構升級作業前,請先設定 clusterrolebinding

  1. 進入 iac/infrastructure/zonal/zones/ZONE_NAME/{ORG} 目錄。
  2. 進入已建立的 IO 目錄。如果該目錄不存在,請建立新目錄。
  3. 新增 YAML 檔案,將 io-organization-admin 叢集角色指派給 IO。例如:

    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. 更新 kustomatization.yaml,加入新建立的檔案。如果 kustomatization.yaml 不存在,請建立新檔案:

    kind: Kustomization
    metadata:
      name: org-1-admin-kustomization
    resources:
    - FILE_NAME.yaml
    
  5. 在 IAC 中提交變更

kubectl

使用 kubectl 啟動租戶機構升級前,請先設定 clusterrolebinding

  1. KUBECONFIG 設為根管理員叢集的 kubeconfig 檔案。

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG`
    
  2. 建立所需的 ClusterRoleBindings

    kubectl create clusterrolebinding io-organization-admin --clusterrole=organization-admin --user=USER_EMAIL`
    
  3. 從舊版 Distributed Cloud 升級至 1.13.x 以上版本前,請按照 Runbook BIL-R0014 中的操作說明,手動產生本月帳單,列出本月初到今天為止的費用。在 Distributed Cloud 機構升級過程中建立的費用資料將會遺失。

1.2. 啟動升級程序

透過 IaC 觸發租戶機構升級時,請更新區域中機構相應 OrganizationZonalConfig 物件的版本欄位。詳情如下:

  1. 更新 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. 暫存並提交檔案變更。

    git add "IAC_REPO_PATH/iac/infrastructure"
    git commit
    
  3. 建立合併要求。

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

如果啟動升級程序,系統會建立 OrganizationUpgrade 物件。確認 OrganizationUpgrade 物件已在該可用區的根管理員叢集中建立。

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

如果找不到 OrganizationUpgrade,請按照 IAC-R0001 執行手冊進行疑難排解。

1.3. 升級

  1. 升級會在 timeWindow 落在維護期間時執行,而維護期間是由管理員使用者 (也稱為 PA) 指定。查看已排定時間的timeWindow

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

    以下是上述指令的一般回應:

    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"
    

    在上述範例中,升級至 1.8.1-gdch.0 的時間表介於 "2022-08-28T00:00:00Z""2022-08-28T04:00:00Z" 之間。

    升級開始時,系統會建立 OrganizationUpgrade 物件,如先前的輸出範例所示為 kind: OrganizationUpgrade

    kind: OrganizationUpgrade
    
  2. 使用對應的升級物件,透過附加步驟 1 中的指令-w,監控升級作業的整體狀態。舉例來說,如要持續查詢 ORG_NAME 的升級狀態,請執行下列指令:

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl get -n gpc-system organizationupgrade ORG_NAME -o yaml -w
    
  3. 您可以使用下列方式查看升級階段和狀態:

    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'
    

    Succeeded 階段是指整體升級狀態。Expired 階段表示升級作業已超過原定時間。其他階段則是指升級作業的進行步驟。 「狀態」True 代表已完成的步驟,「狀態」Unknown 則代表升級的目前步驟。

    如果預檢失敗,但您確定是誤判,請覆寫並略過預檢選項:

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

    如果後續檢查失敗,但您確定失敗是誤判,請覆寫並略過後續檢查:

    export KUBECONFIG=ROOT_ADMIN_KUBECONFIG
    kubectl annotate -n gpc-system organization ORG_NAME \
        upgrade.private.gdc.goog/skip-postflight-check=ok
    
  4. 如果使用 IAC 升級租戶機構,且 organizationupgrade 狀態顯示「成功」,但租戶機構並未處於「就緒」狀態,請套用下列解決方法。organizationupgradeOrganization

    將這個註解:configmanagement.gke.io/managed: disabled使用 IAC 新增至機構。 「監控」Organization狀態為「就緒」。

  5. 機構升級作業現在應會進入下一個階段,服務或節點的狀態將為「完成」:

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

    組織升級作業最多可能需要 15 分鐘才能繼續。

1.4. 升級後檢查

  1. 檢查機構的 Organization 物件。條件 READY 必須顯示為 True

    kubectl -n gpc-system get organization ORG_NAME
    

    輸出內容範例:

    NAME   READY
    org-1  True
    
  2. 請檢查 Organization.Status.Version。必須顯示目標版本的確切字串:

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

    輸出內容範例:

    1.13.3-gdch.5548
    

    將註解還原為忽略維護期間:

    kubectl annotate organization ORG_NAME -n=gpc-system  \
        "upgrade.private.gdc.goog/ignore-maintenance-window-" \
        --kubeconfig=ROOT_ADMIN_KUBECONFIG
    
  3. 檢查升級後的租戶機構是否有子元件故障:

    1. 檢查顯示 ReconciliationErrorReconciling 狀態的子元件。將 kubeconfig 指向 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. 如要查看錯誤,請參閱版本資訊已知問題,瞭解解決方法。如果沒有解決方法,請與 Distributed Cloud 聯絡以進行疑難排解。

  4. 如果略過預檢或後檢,請在升級完成後移除註解:

    範例:

    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. 啟動未排定的升級

如有緊急需求 (例如需要緊急安全性修補程式),請在 maintenanceWindow 以外的時間觸發即時租戶機構升級。只有在租戶機構中才需要這麼做,因為根機構會立即觸發升級。

使用根管理員 kubeconfig 執行這項指令。您需要註解的機構自訂資源只會出現在根管理員叢集中。您不必為這項程序安排時間範圍。

  1. 修補租戶機構的機構 spec/version

    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. 套用 ignore-maintenance-window 註解並重新啟動 organizationupgrade,即可立即啟動 tenant-org upgrade

  3. 監控升級狀態:

    # kubectl -n gpc-system get organizationupgrade org-1 -o yaml
    
  4. 執行升級後檢查

  5. 緊急升級完成後,請恢復使用排定的時間範圍:

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

2. DNS 升級

2.1 建立轉送區域

  1. 匯出根管理員叢集的 kubeconfig

    export KUBECONFIG=/root/release/root-admin/root-admin-kubeconfig
    
  2. 使用正向區域設定 OCIT_DOMAIN。 將 OCIT_DOMAIN 替換為您的 OCIT 網域名稱,並將端點替換為 OC DNS IP 位址:

    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
    

    輸出結果如下所示:

    dnszone.network.private.gdc.goog/ocit-domain created
    
  3. 如果變更未套用,請重新啟動部署作業:

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

    這項 DNS 變更會傳播至 GDC 中的所有叢集。

  4. 使用根管理員 kubeconfig,驗證 OCIT 網域解析是否正常運作:

    NAMESERVER=$(kubectl -n dns-system get service gpc-coredns-forwarder-udp | \
      awk '/[0-9]\./ {print $4}')
    dig +short @${NAMESERVER} fs.OCIT_DOMAIN
    
  5. 為機構管理員叢集匯出 kubeconfig

    export KUBECONFIG=/root/release/org-admin/org-admin-kubeconfig
    
  6. 套用機構管理員 kubeconfig,並驗證 OCIT 網域解析是否正常運作:

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

2.2 啟用遞迴解析器

僅適用於第 1 版機構,請按照 DNS-R0027 執行手冊中的步驟,在機構管理員叢集中啟用遞迴解析器。

完成所有區域的租戶機構升級

在一個區域完成升級後,建議先檢查該區域是否仍正常運作,再繼續升級下一個區域。

針對其餘區域的租戶機構重複執行步驟 1 和 2。所有區域的租戶機構升級完成後,請繼續進行下一個步驟。

3. 升級全域資源

全域資源應位於所有區域的最低版本。連線至錨定區域並執行下列指令,啟動全域資源升級程序。

# 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

這項程序可能需要幾分鐘才能完成。執行下列指令,確認全域資源升級作業是否完成。指令不應回報失敗。

# 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."
back-lancer-agent-user-cp

4. 升級 Tenable SC

  1. 執行 GDCH 醫生,判斷是否需要升級 -

      gdcloud system doctor diagnose instance --include-ocs=vuln --root-admin-kubeconfig=${ROOT_ADMIN_CLUSTER_KUBECONFIG:?}
    
  2. 如果 tenable_sc_upgrade_readiness 驗證器無法通過驗證,表示圖片需要升級,請按照下列步驟在 OI 服務機構中升級 Tenable SC:

    1. 取得虛擬機器名稱:

       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. 將虛擬機器的 runningState 標示為 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. 解除安裝 VM 的現有 Helm 資訊套件:

       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. 按照「安裝 Tenable.SC」一文的說明,重新設定 Tenable SC

升級後清理

移除在「身分與存取權管理」部分建立的 ClusterRoleBinding 資源。

設定租戶機構升級的維護期間

如要升級租戶機構 (機構),請確認您已獲派正確的檢視者和管理員角色,詳情請參閱「預先定義的角色說明」和「專案的角色定義」頁面,瞭解如何登入 kubectl 命令列介面 (CLI) 和管理中心使用者介面 (UI)。如果沒有,請按照「授予專案資源的存取權」頁面的操作說明,授予或要求授予這些權限。

如要設定維護期間,您必須具備必要角色。請確認您已獲派下列預先定義的角色:

根據預設,子版本升級和修補程式升級各有一個 MaintenanceWindowMaintenanceWindow次要升級會強化功能或變更先前版本,也就是套件升級,例如修正錯誤。修補程式升級可解決特定問題或安全漏洞。設定預設修補程式 MaintenanceWindow,根據定義的時間表開始修補程式升級。

如要設定維護期間,請使用 CLI 和 kubectl 指令修改 MaintenanceWindow 資源的 RRULETimeWindow 欄位。系統會排定升級時間。如要瞭解 RRULE,請前往 https://pkg.go.dev/github.com/teambition/rrule-go

如要使用 kubectl CLI 指令,請按一下「kubectl」分頁標籤。如要查看以使用者介面為基礎的操作說明,請按一下「控制台」分頁標籤。

主控台

  1. 登入機構使用者介面

  2. 編輯維護期間時間表。前往「維護」分頁,然後按一下「編輯」

    維護期間

    圖 1. 維護期間

  3. 「編輯維護期間」畫面隨即開啟。使用視窗重新設定「修補程式」和「次要」時間範圍:

    重新設定修補程式和次要更新

    圖 2:重新設定修補程式和小幅更新

  4. 指定或編輯修補程式版本開始時間長度, 以及星期幾。

    編輯「次要版本」、「開始時間」、「長度」、「週期」和「日期」

    儲存重新設定

    圖 3:儲存重新設定

  5. 按一下 [Save] (儲存) 套用您的變更。

  6. 如果儲存的變更會影響週期 (例如:變更星期幾或月份),系統會顯示對話方塊。按一下「繼續」確認變更。

    按一下「Continue」(繼續)

    圖 4:按一下「Continue」(繼續)

  7. 以下範例顯示根據設定變更更新的排定升級時間。請注意,每個待處理狀態旁邊都有「Skip」連結。使用這項功能略過排定時間的待處理升級。

    排定升級作業檢視畫面 (含略過按鈕)
    圖 5. 查看升級時間表,並為每個升級選擇略過選項

kubectl

  1. 登入 kubectl CLI。 在 CLI 分頁中找到這些指示。 請先確認您擁有機構管理員叢集的正確存取權,再繼續操作。

  2. 您可以在 MaintenanceWindow 中修改三個欄位,設定租戶機構升級的timeWindow。下列指令顯示修補程式升級維護期間的修改內容。修改次要升級的程序也類似。

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

    開始時間和結束時間 (分別為 /spec/timeWindow/start/spec/timeWindow/end) 的日期/月份/年份必須已過。系統會根據您輸入的值計算時間範圍。

請為每種升級類型分配至少如畫面所示的最低時間長度。您可以按照下列建議分配較長的時間:

  • 次要升級:在連續 32 天的時間範圍內,至少需要 12 小時。
  • 修補程式升級:在連續 32 天的時間範圍內,至少需要 48 小時,且至少有 1 個時間區塊。雖然控制台顯示的最低時間範圍規格為 4 小時,但 Google 建議您為每個時間區塊分配至少 6 小時。

手動升級 Operations Suite Infrastructure Core

這項升級程序僅適用於從 1.13.x 版升級至 1.14.3 版。

請確認所有受管理網域和本機帳戶都已啟用,且密碼未過期。如果帳戶狀態不佳,可能會導致這個程序發生錯誤。

執行 VM 檢查點和目錄備份

  1. 執行 VM 檢查點。

    1. BM01 主機上,以管理員身分開啟 PS 控制台。
    2. 針對叢集中的每個 Hyper-V 主機執行下列指令。

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

      請將 PowerShell 視窗保持開啟,以便執行後續步驟。

  2. 啟用長檔案路徑

      $path = 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem'
      Set-ItemProperty -Path $path -Name 'LongPathsEnabled' -Value 1
    
  3. 備份 H:\operations_center 磁碟機。(這項操作支援復原升級)。

      Rename-Item -Path H:\operations_center -NewName operations_center_backup
    
  4. 備份 CONFIG1 上的設定目錄。(這個備份檔會在建構新的 config.ps1 設定時提供參考資料)。

    1. BM01 主機上,使用遠端桌面通訊協定 (RDP) 連線至 CONFIG1 VM 的 IP 位址,並使用系統管理員帳戶登入。範例:mstsc /v 192.168.100.99

    2. 以「以系統管理員身分執行」開啟 PS 主控台。

      • 建立備份資料夾
      mkdir c:\config1_backup
      
      • Backup C:\dsc
      Move-Item -Path "C:\dsc\" -Destination "C:\config1_backup"
      
      • 備份 C:\config
      Move-Item -Path "C:\config\" -Destination "C:\config1_backup"
      
      • 備份 C:\operations_center
      Move-Item -Path "C:\release\operations_center\" -Destination "C:\config1_backup"
      
      • 確認已啟用長檔案路徑
      $path = 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem'
      Set-ItemProperty -Path $path -Name 'LongPathsEnabled' -Value 1
      

載入第三方軟體

第三方軟體中執行工作。

升級現有虛擬機器

  1. 取得安裝目錄。

    1. 按照「下載檔案」一節的操作說明,下載 OIC 元件組合。

    2. BM01 主機上,從下載的 prod_IT_component_bundle.tar.gz 中解壓縮 operations_center 目錄。

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

      解壓縮 TAR 檔案後,應該會在 H: 的根目錄中建立 release 資料夾:

    3. operations_center 移至 H: 的根目錄:

      Move-Item -Path H:\release\operations_center -Destination H:\
      
  2. 使用網站專屬資料更新 config.ps1

    config.ps1 設定檔提供建構及設定 Operations Suite 基礎架構 (OI) 環境所需的所有資訊。如要更新設定檔,請務必收集下列所有資訊。備份現有的 config.ps1 檔案,可做為參考,避免不慎覆寫現有設定。 重要事項:請務必先完成並確認 config.ps1 正確無誤,再繼續操作。

    • occonfigtool 工具的網路設定輸出內容,尤其是 ocinfo.common.opscenter.local.txt 檔案。網路名稱 (例如 OCCORE-SERVERS) 是指該文件中 Name 欄的內容,請參閱下列步驟。
    • 每個 OI 管理的 GDC Cell 的網域名稱和 DNS 伺服器 IP 位址。這項資料會顯示在客戶資訊問卷 (CIQ) 的輸出內容中。

    BM01 主機上以 Administrator 進行所有變更。

  3. 複製部署類型適用的正確設定範例程式碼:

    1. H:\operations_center\dsc\config.example.ps1 複製到 H:\operations_center\config\config.ps1
  4. 使用 VSCode 或 Powershell ISE,驗證並更新 config.ps1 中的值。

    1. 如果 OIC 部署為多個網站

      1. 尋找標示為「### Multi-Site:」的留言
      2. 根據找到的註解執行所述動作。
    2. 除非預設值 (3.0) 正確,否則請更新 HardwareVersion

    3. 除非預設值 (DC1) 正確,否則請更新 PrimarySiteCode

    4. 許多名稱都使用網站代碼。搜尋並將所有 DC1 執行個體替換為正確的網站程式碼。使用不區分大小寫的搜尋功能。逐一檢查變更,因為部分變更可能並非必要。舉例來說,如果網站代碼為 AB1,則主機名稱 DC1-DC1 必須變更為 AB1-DC1而非 AB1-AB1

    5. 如果預設值不正確,請更新 DnsDomain如果這個值有所變更,請在整個 config.ps1 檔案中搜尋並取代 opscenter.local。預設值經過硬式編碼,位於多個位置。

    6. 使用網站專屬資訊更新 DnsConditionalForwarder 中的物件。必須至少有一個轉送物件。移除不必要的範例。

      如果已安裝 gdcloudkubectl CLI,這個步驟可以在 CONFIG1 的 WSL 中執行。

      如要從根管理員叢集提取特定網站的資訊,請使用:

      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 - GDC 儲存格 DNS 網域名稱,例如 ciq.yaml 中的 dns.delegatedSubdomain
      2. Master - DNS 伺服器 IP 清單 (通常只有一個)。在 cellcfg 中尋找 DNSReservation 類型。 如果已部署 GDC 儲存格,請在根管理叢集的 dns-system 命名空間中,尋找 gpc-coredns-external-udp 服務的 EXTERNAL-IP 和儲存格的 FQDN bert.sesame.street

      3. 在多網站部署中,每個儲存格都有一個雜湊表物件。

    7. 請勿變更 UsersGroupsGroupPolicy 物件的任何內容。

    8. 更新 DNSServers,使其包含指派給主要和次要網域控制站的 2 個 IP 位址,例如 <SITE>-DC1<SITE>-DC2

    9. NTPServers 更新為來自根管理員 TimeServer 自訂資源的 SyncServer IP 位址清單。您可以使用下列方式擷取這組 IP 位址:

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

      您必須以 NTPServers 格式設定這些 IP 位址,如以下範例所示:

      NtpServers = @(
        '10.251.80.2',
        '10.251.80.3',
        '10.251.80.4',
        '10.251.80.5'
      )
      
    10. 視需要使用客戶提供的 OCCORE-SERVERS 子網路子網路首碼值,更新 SubnetPrefix 預設值 (即 24)。

    11. 使用客戶提供的 OCCORE-SERVERS 子網路預設閘道,更新 DefaultGateway 預設值。

    12. 找出並更新 WorkstationCider 預設值,改為客戶提供的 IPv4 CIDR 標記法值,用於 OC-WORKSTATIONS 子網路。

    13. 如果客戶選擇允許遠端存取工作站,請將 WorkstationAllowRemote 值更新為 $true

    14. 找出並將範例子網路前置字元 172.21.0. 替換為客戶提供的 OCCORE-SERVERS 子網路前置字元。

    15. 找出範例子網路前置字元 172.21.2.,並替換為客戶提供的 OCCORE-JUMPHOSTS 子網路前置字元。

    16. 找出範例子網路前置字元 172.21.32.,並替換為客戶提供的 OC-WORKSTATIONS 子網路前置字元。

    17. 找出並將每日訊息範例 legalnoticecaptionPref caption 替換為顧客提供的說明文字。

    18. 找出並將 Pref text 的每日訊息範例 legalnoticetext 值 替換為顧客提供的文字。

    19. 驗證每個「節點」物件,並視需要更新。

      1. NodeName - 確認主機名稱正確無誤。有些名稱會用於許多地方,例如網域控制站。如果您在此變更名稱,請檢查設定中的其他位置是否也需要變更。
      2. IPv4Addr - 這必須是主機的 IP 位址。通常最後一個八位元組維持原狀即可。在先前的步驟中,系統可能會在網路搜尋和取代期間更新部分八位元組。

      3. HyperVHost - 這個值必須是代管這個 VM 的 Hyper-V 伺服器 IP 位址。您可以在設定的「Hyper-V Servers」部分,取得每個 BM?? 伺服器的 IP 位址。請勿變更這個欄位中的 Hyper-V 主機指派項目,因為並非所有 Hyper-V 主機支援所有 VM 類型,請將 Hyper-V 主機名稱變更為對應的 IP 位址。

    20. 在所有節點上使用 Role=jumphost 驗證第二個網路介面詳細資料。請使用這個介面的 OCCORE-JUMPHOSTS 子網路詳細資料。檢查:

      1. JumphostIPv4Cidr
      2. JumphostDefaultGateway
    21. Role=adfs 所在的節點中,更新 ADFS 專屬的段落。

      1. 找到 Name = 'SplunkTrust' # Must be unique to the farm. Append "Trust" 這行
      2. 將這行後方的三個 opscenter.local 替換成您的 DNS 網域
    22. 視需要更新 DHCP 範圍,以符合客戶的 IP 計畫。請針對每個範圍,驗證下列值是否正確。範圍中的名稱與 ocinfo.common.opscenter.local.txt 網路計畫中使用的名稱相符,因此請在驗證中使用下列項目:

      1. ScopeId
      2. IpStartRange
      3. IpEndRange
      4. Router
      5. SubnetMask
    23. 確認這些值與備份的 config1.ps1 中的值相符

    24. 請務必儲存檔案。

CONFIG1 VM 準備作業

CONFIG1 準備作業是在 BM01 上執行。登入 CONFIG1 VM 時,會進行所有其他升級。

  1. 將 operations_center 目錄複製到 CONFIG1 VM

    1. BM01 主機上,以管理員身分開啟 PS 控制台。

    2. 複製 operations_center,暫存 CONFIG1 虛擬機器 (VM) 所需的檔案。

      # 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. 停用 Hyper-V 時間同步

      1. 以管理員身分登入 BM01 主機。

      2. 在 Windows 上以管理員身分開啟 PowerShell,然後執行下列指令:

      # Disabling Hyper-V Time Sync
      Disable-VMIntegrationService -VMName `<SITE>-CONFIG1` -Name 'Time Synchronization'
      
    4. CONFIG1 VM 準備和驗證

      1. BM01 主機上,使用 -SA 帳戶登入 CONFIG1 VM。 使用遠端桌面 (RDP) 連線至 VM IP 位址。示例: mstsc /v 192.168.100.99

      2. 使用「以不同的使用者身分執行」選單開啟 PowerShell 視窗,以 Marvin 使用者身分執行。

      3. 在新 PowerShell 視窗中啟動管理工作階段:

        Start -Verb runas -FilePath powershell.exe
        

        關閉先前的 PowerShell 視窗,但不要關閉系統管理員視窗。

      4. 確認管理員 PowerShell 視窗是以 Marvin 身分執行

        whoami
        
      5. 從 BM01 主機暫存的檔案。

        Move-Item -Path c:\operations_center -Destination c:\release
        C:\release\operations_center\dsc\Initialize-ConfigHostFiles.ps1
        
      6. 確認 c:\dscc:\config 是否存在。

      7. 從備份檔複製憑證和憑證檔案

        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. 建構編譯 MOF 時所需的 MECM 資料

        C:\dsc\Build-MecmFiles.ps1
        
      9. 執行 Build-Mof.ps1,為所有 OI 電腦產生 MOF 檔案,驗證建構環境是否已準備就緒。

        C:\dsc\Build-Mof.ps1
        
    5. 填入憑證變數

      這些變數會用於整個升級程序。以管理員身分開啟 Marvin PowerShell 視窗,並填入這些值。

      . '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. 確認 DSC 正在執行,且伺服器可連線。

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

排解連線問題。

  1. 如果 New-CimSession 失敗,請確認 config.ps1 中的 NodeName 值是否正確。 同時確認伺服器已連線且可連上。

    錯誤訊息開頭為 Get-CimSession: WinRM cannot process the request

升級網域控制器

  1. 登入 CONFIG1 後,升級主要網域控制站。

    填入變數、移除舊的 GPO,然後連結新的 GPO。

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

    取消連結群組原則物件。升級完成後,系統就會連結這些帳戶。

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

    升級主要網域控制站。

    .\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. 驗證與 SyncServer 的時間同步

    2. 網域管理員身分,使用遠端桌面協定登入 DC1

      1. 管理員身分開啟 Powershell 視窗。
      2. 執行下列指令來驗證時間設定。

        w32tm /query /status /verbose
        
    1. 執行下列指令,測試時間重新同步:

       # Testing time resyncronization
       w32tm /resync
      
       # Desired output
       Sending resync command to local computer
       The command completed successfully.
      
    2. 重新驗證時間設定是否正確無誤。

       w32tm /query /status /verbose
      
  2. 升級第二個網域控制站。

    1. 使用現有的 CONFIG1 PowerShell 視窗執行下列指令碼。

      .\Update-RemoteHost.ps1 @da_args -ComputerName $dc2.NodeName
      
  3. 驗證 Active Directory 複寫。

    1. 第二個 DC 啟動並運作後,請從其中一個網域控制器執行下列指令,驗證 Active Directory 複寫:

      repadmin /replsummary
      

      輸出內容應與以下內容類似:

      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
      

升級 CA-ISSUING1CA-WEB

  1. 使用現有的 PowerShell 終端機升級 CONFIG1CA-ISSUING1

      $ca_iss = $config.AllNodes | Where-Object {$_.role -eq "ca_issuing"}
      c:\dsc\Update-RemoteHost.ps1 @sa_args -ComputerName $ca_iss.NodeName
    
  2. 使用現有的 PowerShell 終端機升級 CONFIG1CA-WEB

      $ca_web = $config.AllNodes | Where-Object {$_.role -eq "ca_web"}
      c:\dsc\Update-RemoteHost.ps1 @sa_args  -Computername $ca_web.NodeName
    
  3. 驗證升級

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

升級 CA-ROOT1

使用 CONFIG1 上的現有 PowerShell 終端機

  1. 開啟「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. 更新「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. 如果 CA_ROOT1 在執行上一個指令碼後未重新啟動,請手動重新啟動。

  4. 驗證升級。

      $ca_root | ForEach-Object {
      $session = New-CimSession -ComputerName $_.Ipv4Addr -Credential $caroot_cred
      Get-DscConfigurationStatus -CimSession $session}
    
  5. 確認 Peer 設定為 <SITE>-DC1.<DNSDOMAIN>,且 StateActive

    如果時間未正確同步,請勿繼續操作。

      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. 關閉 CA-Root

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

升級 ADFS

使用 CONFIG1 上的現有 PowerShell 終端機

  1. 升級 ADFS1 VM。

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

升級 Jumphost

使用 CONFIG1 上的現有 PowerShell 終端機

  1. 建立 Jumphost 陣列。

      $role = 'jumphost'
      $jumps = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. 升級跳板主機。

      $jumps | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}
    
  3. 驗證升級。

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

升級 Fileservers

使用 CONFIG1 上的現有 PowerShell 終端機

  1. 建立包含 Fileserver 的陣列。

      $role = 'file'
      $files = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. 升級檔案伺服器。

      $files | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}
    
  3. 驗證升級。

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

升級 DHCP 伺服器。

使用 CONFIG1 上的現有 PowerShell 終端機

  1. 升級 DHCP1。

      $role = 'dhcp_primary'
      $dhcp1 = $config.AllNodes | Where-Object {$_.role -eq $role}
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $dhcp1.NodeName
    
  2. 驗證升級。

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

      $role = 'dhcp_failover'
      $dhcp2 = $config.AllNodes | Where-Object {$_.role -eq $role}
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $dhcp2.NodeName
    
  4. 驗證升級。

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

升級 Userlock 伺服器。

使用 CONFIG1 上的現有 PowerShell 終端機

  1. 建立包含 Userlock 伺服器的 PowerShell 陣列。

      $role = 'userlock_primary'
      $ulock1 = $config.AllNodes | Where-Object {$_.role -eq $role}
      $role = 'userlock_backup'
      $ulock2 = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. 移除先前設定中的標記檔案。

      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. 升級主要 Userlock 伺服器。

      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $ulock1.NodeName
    
  4. 升級備份 Userlock 伺服器。

      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $ulock2.NodeName
    
  5. 驗證升級。

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

升級 Nessus 伺服器。

使用 CONFIG1 上的現有 PowerShell 終端機

  1. 建立包含 Nessus 伺服器的 PowerShell 陣列。

      $role = 'nessus_'
      $nessus = $config.AllNodes | Where-Object {$_.role -match $role}
    
  2. 升級 Nessus 伺服器。

      $nessus | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args  -Computername $_.NodeName}
    
  3. 驗證升級。

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

升級 Hyper-V 伺服器。

使用 CONFIG1 上的現有 PowerShell 終端機

  1. 建立包含 Hyper-V 伺服器的 PowerShell 陣列。

      $role = 'hyper_v'
      $hyper = $config.AllNodes | Where-Object {$_.role -eq $role}
    
  2. 升級 Hyper-V 伺服器。

      $hyper | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}
    
  3. 驗證升級。

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

升級工具箱

使用 CONFIG1 上的現有 PowerShell 終端機

  1. 建立包含工具箱伺服器的 PowerShell 陣列。

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

    確認輸出結果顯示指派給 VM 的兩個磁碟。範例:

      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. 升級 Toolbox 伺服器。

      $tools | ForEach-Object {
      c:\dsc\Update-RemoteHost.ps1 @sa_args  -Computername $_.NodeName}
    
  4. 驗證升級。

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

使用 CONFIG1 上的現有 PowerShell 終端機驗證升級。

  1. 確認 DSC 執行時未發生錯誤。

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

升級 Splunk VM

  1. CONFIG1 的 Powershell 視窗中,設定並執行 DSC 設定:

    • 輸入站點代碼。範例:"DC1"

       $sitecode = Read-Host "Enter your site code"
       Set-Location c:\dsc
      
    • 設定重型轉送器:

       $myargs = @{
       Computername = "$sitecode-HEAVYFWD"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • 設定索引器 1:

       $myargs = @{
       Computername = "$sitecode-INDEXER1"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • 設定索引器 2:

       $myargs = @{
       Computername = "$sitecode-INDEXER2"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • 設定索引器 3:

       $myargs = @{
       Computername = "$sitecode-INDEXER3"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • 設定管理員:

       $myargs = @{
       Computername = "$sitecode-SPLUNKMGR"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
    • 設定搜尋標題:

       $myargs = @{
       Computername = "$sitecode-SEARCHHEAD"
       Credential = $sa_creds
       SetLcm = $true
       RemoveExisting = $true
       }
       .\Update-RemoteHost.ps1 @myargs
      
  2. 在「CONFIG1」CONFIG1的 Powershell 視窗中:

      $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. 請按照 SIEM-G0006 設定全域 Pass4SymmKey,並按照 SIEM-G0007 將每個區域附加至 OIC 中的 Splunk。

升級「CONFIG1」CONFIG1主機

  1. 在「CONFIG1」CONFIG1的 Powershell 視窗中:

    Start-DscConfiguration -ComputerName $env:COMPUTERNAME -Path c:\config\mofs -Verbose -Wait -Force
    
  2. 如果電腦重新啟動,請以 Marvin 身分登入並再次啟動 PowerShell,然後提升為管理員。填入後續章節所需的變數。

    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)

由於 MCM 不是可升級的元件,因此唯一的方法是刪除現有的 MCM 主機,然後重新部署 MCM。

  • 確認目前的 MCM 軟體已按照 IT-T0023 進行補水。

  • 如要瞭解重新部署程序,請參閱 IT-R0019

移除 VM 檢查點

升級完成後,請移除檢查點。檢查點可能會導致磁碟使用量隨時間增加。只有在升級失敗而需要還原至檢查點時,才保留這些檔案。

使用 CONFIG1 上的現有 PowerShell 終端機

  1. 移除 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
      }}
    

重新啟用網域的群組原則物件

使用 CONFIG1 上的現有 PowerShell 終端機

  1. 變更網域控制站角色設定,啟用受管理 GPO 的連結

      $gpolinks = (Get-Content C:\dsc\data\GpoLinkMapping.yaml -Raw).Replace("LinkEnabled: 'No'", "LinkEnabled: 'Yes'")
      $gpolinks | Out-File C:\dsc\data\GpoLinkMapping.yaml -Force
    
  2. 使用 ObjectOwner 角色更新網域控制站:

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

聯絡 Google 團隊

如需進一步協助,請參閱「要求支援」頁面,瞭解如何與 Google 聯絡。