멀티 영역 배포에서는 영역이 하나씩 업그레이드되며 서로 독립적입니다. 영역 간 업그레이드의 전역 조정은 없습니다. IO는 새 버전으로 업그레이드하려는 조직의 모든 영역에서 업그레이드를 실행해야 합니다. 따라서 영역이 다른 조직은 특정 시점에 서로 다른 버전을 사용할 수 있습니다.
이 페이지에 설명된 업그레이드 순서는 한 영역의 루트 조직과 모든 테넌트 조직을 업그레이드한 후 다른 영역으로 이동하는 것입니다. 전역 리소스는 모든 영역이 업그레이드된 후 마지막에 업그레이드됩니다.
이 페이지에서는 다음 유형의 정보를 제공하여 멀티 영역 Google Distributed Cloud (GDC) 오프라인 업그레이드를 진행하는 단계를 설명합니다.
- 필요한 액세스 권한과 액세스 권한을 얻는 방법
- 필요한 도구
- 업그레이드를 실행하기 전에 취해야 할 단계
- 다양한 Distributed Cloud 구성요소의 업그레이드를 수행하는 방법과 순서
다음 목록에서는 업그레이드의 각 구성요소를 정의합니다.
타겟 버전: 모든 영역에 동일한 타겟 버전을 사용합니다.
한 번에 하나씩: 한 번에 하나의 영역을 업그레이드합니다. 한 영역에서 업그레이드가 트리거되기 전에 다른 영역에서 업그레이드가 실행되고 있지 않은지 확인합니다.
전역 리소스: 영역당 사본이 하나인 영역 리소스와 달리 전역 kube-apiserver에 배포된 Kubernetes 리소스로 정의됩니다. 전역 리소스는 다른 수명 주기를 따릅니다. 마지막에 한 번만 업그레이드해야 합니다.
준비
URL은 오프라인 환경 외부에서 액세스할 수 있도록 제공됩니다.
업그레이드를 시작하기 전에 다음 사항을 확인하세요.
gdcloud auth login을 루트 관리자 클러스터에 실행하여 획득한kubeconfig파일의 경로입니다.새 출시 아티팩트가 다운로드되어 머신으로 안전하게 전송됩니다. 아티팩트를 컨테이너 레지스트리로 푸시에 제공된 단계를 따릅니다.
수동 업그레이드를 실행하기 위한 호스트 머신으로, 머신에 루트 관리자 클러스터
kubeconfig파일이 있습니다.업그레이드를 시작하기 전에 이전 버전의 알려진 문제가 해결됩니다. 특히 1.13.1에서 업그레이드하는 경우 다음 문제가 해결되었는지 확인하세요.
규정 준수 보고서 생성
규정 준수 보고서에는 다음 조직이 나열됩니다.
- 지원 기간이 지남
- 중요한 보안 패치를 놓침
규정 준수 보고서 생성은 선택사항이며 organization-admin role이 있는 인증된 IO가 필요합니다. 보고서를 생성하려면 다음 명령어를 실행합니다.
gdcloud system upgrade report-compliance
준비 요구사항에 대한 자세한 내용은 기본 요건 섹션을 참고하세요.
Identity and Access Management
업그레이드를 시작하기 전에 각 영역에서 다음을 수행하세요.
gdcloud auth login을 루트 관리자 클러스터와 모든 조직 관리자 클러스터에 실행하여 kubeconfig 파일을 가져옵니다.
액세스 및 권한 상승 프로세스 IAM-R0005 런북의 안내에 따라 다음을 추가합니다.
- 각 영역의 루트 관리자 클러스터에 있는 cluster-admin
ClusterRoleClusterRoleBinding - 조직 관리자 클러스터에 액세스하여 임시 관리 액세스 권한을 획득합니다.
- 각 영역의 루트 관리자 클러스터에 있는 cluster-admin
모든 영역에서 전역 리소스 업그레이드 일시중지
획득한 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
전역 루트 조직 업그레이드
전역 루트 조직 업그레이드에는 다음과 같은 단계가 포함됩니다.
모든 영역에서 루트 조직을 업그레이드합니다. 각 영역은 개별적으로 업그레이드됩니다.
현재 영역이 기본 영역인지 확인합니다. 다음 명령어는 기본 영역에서 'true'를 반환하고 기본이 아닌 영역에서는 아무것도 반환하지 않습니다.
kubectl get ObjectStorageAdminNode -o jsonpath='{.items[*].status.isPrimary}' --kubeconfig=ROOT_ADMIN_KUBECONFIG; echo크로스존 조정이 필요한 구성요소를 업그레이드합니다.
전역 루트 관리자 리소스를 업그레이드합니다.
업그레이드 전 검사
한 번에 하나의 영역을 업그레이드합니다. 한 영역에서 조직 업그레이드를 시작하기 전에 다른 모든 영역에 연결하고 다음을 실행하여 명령어가 모든 영역에서 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 배포 세부정보 다운로드에 대해 알아보고, 전송 다운로드에서 파일을 에어 갭 환경으로 전송하는 데 사용하는 휴대용 저장 장치에 대해 알아보세요.
Google 담당자와 협력하여 업그레이드가 파트너가 운영하는 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인터넷에 액세스할 수 있는 컴퓨터에서 USB 드라이브로 업데이트 패키지를 다운로드합니다. Google 담당자가 제공한 버전 및 다이제스트 세부정보를 사용합니다.
gcloud auth login를 실행하여 Cloud Storage 버킷에 액세스합니다.--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파트너 모델 출시 파일로 업그레이드하는 경우 안내에 따라 파트너 모델 배포용 소프트웨어 패키지를 준비합니다.
다운로더 스크립트와
gdch디렉터리를 모두 USB 드라이브에 복사합니다.USB 드라이브에서 OCIT로 업데이트를 복사합니다. 파일을
/home/download/와 같은 유사한 위치에 배치합니다.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다운로더가 출시 버전을
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. Artifact Registry 업그레이드 구성
업그레이드를 성공적으로 실행하려면 다음을 완료해야 합니다.
아티팩트를 컨테이너 레지스트리로 푸시
KUBECONFIG를 루트 관리자 클러스터의 kubeconfig 파일로 설정합니다.export KUBECONFIG=ROOT_ADMIN_KUBECONFIG필요한
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필요한
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-systemOCI 번들을 푸시하는 데 필요한
RoleBindings를 만듭니다.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 createdArtifact Registry 스토리지 크기 조절의 안내에 따라 다음 작업을 실행합니다.
- 관리자 클러스터에서 Artifact Registry의 스토리지 사용량을 확인하고 푸시하려는 아티팩트를 위한 공간이 충분한지 확인합니다.
- 사용 가능한 공간을 늘려야 하는 경우 Artifact Registry 스토리지 크기 조절에 제공된 단계를 따르세요.
Docker 구성을 설정합니다.
cp ${ARTIFACTS_ROOT}/docker-credential-gdcloud /usr/bin트러스트 저장소 번들을 신뢰하도록 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루트 관리자 클러스터의 아티팩트 레지스트리에 아티팩트를 로드합니다.
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명령어를 실행하는 데 필요한 권한이 없는 것입니다. 이 명령어를 실행하는 데 필요한 역할을 얻기 위해 이 문제를 에스컬레이션하거나 필요한 역할을 보유한 사용자가 나를 대신하여 이 명령어를 실행하도록 합니다.
파트너 모델 출시 파일로만 업그레이드하는 경우 안내에 따라 파트너 모델 배포용 소프트웨어 패키지를 로드합니다.
새 출시 버전의
ReleaseMetadata객체가 루트 관리자 클러스터에 있는지 확인합니다.kubectl get releasemetadata.artifact.private.gdc.goog VERSIONVERSION을 Distributed Cloud 출시 버전으로 바꿉니다. 예를 들면1.x.y-gdch.z입니다.출력 예시:
NAME AGE 1.x.y-gdch.z 2m업그레이드할 루트 조직의 사용 가능한 업그레이드 목록에 새 버전이 있는지 확인합니다.
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. 업그레이드 전
KUBECONFIG를 루트 관리자 클러스터의 kubeconfig 파일로 설정합니다.export KUBECONFIG=ROOT_ADMIN_KUBECONFIG필요한
ClusterRoleBindings를 만듭니다.kubectl create clusterrolebinding io-organization-admin --clusterrole=organization-admin --user=USER_EMAIL루트 조직이 정상 상태인지 확인합니다(응답
True참고).kubectl get organization -n gpc-system root \ -ojsonpath='{.status.conditions[?(@.type=="Ready")].status}{"\n"}'출력 예시:
True런북 HSM-P0003의 안내에 따라 모든 HSM을 재부팅합니다.
3.2. 루트 조직 자동 업그레이드 실행
업그레이드는 IaC 프로세스를 거쳐야 합니다. 업그레이드는 해당 영역의 조직에 있는 OrganizationZonalConfig 객체의 버전 필드를 업데이트하여 트리거됩니다.
OrganizationZonalConfigYAML 파일에서 버전을 업데이트합니다. 파일에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파일 변경사항을 스테이징하고 커밋합니다.
git add "IAC_REPO_PATH/iac/infrastructure" git commit병합 요청을 만듭니다.
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. 업그레이드 후 검사
업그레이드 결과를 확인합니다.
루트 조직의
Organization객체를 확인합니다. 상태 조건READY이True인지 확인합니다.kubectl -n gpc-system get organization root출력 예시:
NAME READY root TrueOrganization.Status.Version에 정확한 문자열1.x.y-gdch.z이 표시되는지 확인합니다.kubectl -n gpc-system get organization root -o jsonpath='{.status.version}{"\n"}'확인 출력 예:
1.13.3-gdch.5548
루트 조직에서 하위 구성요소 오류를 확인합니다.
ReconciliationError또는Reconciling상태가 표시되는 하위 구성요소를 확인합니다. 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)"'오류가 발생하면 출시 노트 및 알려진 문제에서 해결 방법을 확인하고, 해결 방법이 없으면 Distributed Cloud에 문의하여 문제를 해결하세요.
프리플라이트 검사 또는 포스트플라이트 검사를 건너뛴 경우 업그레이드가 완료된 후 주석을 삭제합니다.
예:
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 작동 가능 구성요소를 업그레이드하려면 런북 IAC-R0016을 따르세요.
SIEM 작동 가능 구성요소를 업그레이드하려면 런북 SIEM-G0008을 따르세요.
6. 애니캐스트 서브넷 수동 업그레이드
다음 스크립트를 실행하여 전역 루트 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 업그레이드 프로세스
다음 명령어는 추출된 업데이트 패키지의 출시 디렉터리에서 실행해야 합니다.
추출할 최신 펌웨어를 찾습니다.
${ARTIFACTS_ROOT}/gdcloud artifacts tree ${ARTIFACTS_ROOT}/oci/ | grep syncserver | grep -v .sig$파일 이름에 펌웨어 버전이 포함됩니다.
출력 예시:
│ ├── gdch-syncserver-firmware/syncserver:5.1.2파일 이름만 복사하여 다음 변수에 할당합니다.
export SYNCSERVER_VERSION=syncserver:5.1.2OCI 이미지에서 펌웨어를 추출합니다.
${ARTIFACTS_ROOT}/gdcloud artifacts extract ${ARTIFACTS_ROOT}/oci syncserver_firmware --image-name=gdch-syncserver-firmware/${SYNCSERVER_VERSION:?}펌웨어를 추출합니다.
tar -xvzf syncserver_firmware/gdch-syncserver-firmware/syncserver.tar.gz출력 디렉터리에
*.dat파일 하나와*updater.zip파일 하나가 표시되어야 합니다.런북 NTP-P0002 - SyncServer UI 액세스를 따릅니다.
도움말 -> 정보 -> 소프트웨어 버전으로 이동합니다. 설치된 소프트웨어가 제공된 펌웨어와 같거나 최신인 경우 펌웨어를 업데이트할 필요가 없으므로 다음 단계를 건너뛸 수 있습니다.
SyncServer UI에서 Admin -> Upgrade로 이동합니다.
Authorization File의syncserver_s650_license.dat와Upgrade File의syncserver_s650_updater.zip를 업로드합니다. 그런 다음 설치를 클릭합니다.

전역 테넌트 조직 업그레이드
전역 테넌트 조직 업그레이드에는 다음과 같은 단계가 포함됩니다.
모든 영역에서 테넌트 조직을 업그레이드합니다. 각 영역은 개별적으로 업그레이드됩니다.
현재 영역이 기본 영역인지 확인합니다. 다음 명령어는 기본 영역에서 'true'를 반환하고 기본이 아닌 영역에서는 아무것도 반환하지 않습니다.
kubectl get ObjectStorageAdminNode -o jsonpath='{.items[*].status.isPrimary}' --kubeconfig=ROOT_ADMIN_KUBECONFIG; echo전역 테넌트 조직 리소스를 업그레이드합니다.
업그레이드 전 검사
한 번에 하나의 영역을 업그레이드합니다. 한 영역에서 조직 업그레이드를 시작하기 전에 다른 모든 영역에 연결하고 다음을 실행하여 명령어가 모든 영역에서 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 설정
- iac/infrastructure/zonal/zones/ZONE_NAME/{ORG} 디렉터리로 이동합니다.
- 이미 생성된 IO 디렉터리로 이동합니다. 디렉터리가 없으면 새 디렉터리를 만듭니다.
io-organization-admin클러스터 역할을 IO에 할당하는 YAML 파일을 추가합니다. 예를 들면 다음과 같습니다.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생성된 새 파일을 포함하도록
kustomatization.yaml를 업데이트합니다.kustomatization.yaml가 없으면 새 파일을 만듭니다.kind: Kustomization metadata: name: org-1-admin-kustomization resources: - FILE_NAME.yamlIAC에서 변경사항 제출
kubectl
kubectl을 사용하여 테넌트 조직 업그레이드를 시작하기 전에 clusterrolebinding 설정
KUBECONFIG를 루트 관리자 클러스터의 kubeconfig 파일로 설정합니다.export KUBECONFIG=ROOT_ADMIN_KUBECONFIG`필요한
ClusterRoleBindings를 만듭니다.kubectl create clusterrolebinding io-organization-admin --clusterrole=organization-admin --user=USER_EMAIL`이전 버전의 Distributed Cloud에서 1.13.x 이상으로 업그레이드하기 전에 런북 BIL-R0014의 안내에 따라 이번 달 초부터 오늘 날짜 초까지의 이번 달 비용에 대한 인보이스를 수동으로 생성하세요. Distributed Cloud 조직 업그레이드 프로세스 중에 생성된 비용 데이터가 손실됩니다.
1.2. 업그레이드 시작
테넌트 조직 업그레이드는 영역의 조직에 있는 해당 OrganizationZonalConfig 객체의 버전 필드를 업데이트하여 IaC를 통해서도 트리거됩니다. 세부정보는 다음과 같습니다.
OrganizationZonalConfigYAML 파일에서 버전을 업데이트합니다.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파일 변경사항을 스테이징하고 커밋합니다.
git add "IAC_REPO_PATH/iac/infrastructure" git commit병합 요청을 만듭니다.
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. 업그레이드
업그레이드는 관리자 사용자(PA라고도 함)가 지정한 유지보수 기간 내에 있는
timeWindow가 있을 때 실행됩니다. 예약된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-w와 함께 1단계의 명령어를 추가하여 해당 업그레이드 객체를 사용하여 업그레이드의 전체 상태를 모니터링합니다. 예를 들어 업그레이드 상태를 위해 ORG_NAME를 지속적으로 쿼리하려면 다음을 실행합니다.export KUBECONFIG=ROOT_ADMIN_KUBECONFIG kubectl get -n gpc-system organizationupgrade ORG_NAME -o yaml -w업그레이드 단계와 상태는 다음을 사용하여 확인할 수 있습니다.
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=okIAC를 사용하여 테넌트 조직을 업그레이드했고
organizationupgrade상태가 '성공'으로 표시되고 테넌트 조직의Organization이 '준비' 상태가 아닌 경우 다음 해결 방법을 적용하세요.IAC를 사용하여 조직에
configmanagement.gke.io/managed: disabled주석을 추가합니다.Organization상태가 준비 상태인지 모니터링합니다.이제 조직 업그레이드가 다음 단계로 진행되고 서비스 또는 노드의 상태가 완료됩니다.
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. 업그레이드 후 검사
조직의
Organization객체를 확인합니다.READY조건은True로 표시되어야 합니다.kubectl -n gpc-system get organization ORG_NAME출력 예시:
NAME READY org-1 TrueOrganization.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업그레이드된 테넌트 조직에서 하위 구성요소 오류를 확인합니다.
ReconciliationError또는Reconciling상태가 표시되는 하위 구성요소를 확인합니다. 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)"'오류가 발생하면 출시 노트 및 알려진 문제에서 해결 방법을 확인하고, 그렇지 않으면 Distributed Cloud에 문의하여 문제를 해결하세요.
프리플라이트 검사 또는 포스트플라이트 검사를 건너뛴 경우 업그레이드가 완료된 후 주석을 삭제합니다.
예:
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를 사용하여 이 명령어를 실행합니다. 주석을 달아야 하는 조직 커스텀 리소스는 루트 관리자 클러스터에만 있습니다. 이 프로세스의 시간대는 예약하지 않습니다.
테넌트 조직의 조직
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_KUBECONFIGignore-maintenance-window주석을 적용하고organizationupgrade를 다시 시작하여 즉각적인tenant-org upgrade시작업그레이드 상태를 모니터링합니다.
# kubectl -n gpc-system get organizationupgrade org-1 -o yaml업그레이드 후 검사를 실행합니다.
긴급 업그레이드가 완료되면 예약된 시간 범위를 다시 사용합니다.
kubectl annotate organization ORG_NAME -n=gpc-system \ "upgrade.private.gdc.goog/ignore-maintenance-window-" \ --kubeconfig=ROOT_ADMIN_KUBECONFIG
2. DNS 업그레이드
2.1 전달 영역 만들기
루트 관리자 클러스터의
kubeconfig를 내보냅니다.export KUBECONFIG=/root/release/root-admin/root-admin-kubeconfig전달 영역을 사용하여 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변경사항이 적용되지 않으면 배포를 다시 시작합니다.
kubectl rollout restart deployment -n dns-system gpc-coredns-forwarder이 DNS 변경사항은 GDC의 모든 클러스터에 전파됩니다.
루트 관리자 kubeconfig를 사용하여 OCIT 도메인 확인이 의도한 대로 작동하는지 확인합니다.
NAMESERVER=$(kubectl -n dns-system get service gpc-coredns-forwarder-udp | \ awk '/[0-9]\./ {print $4}') dig +short @${NAMESERVER} fs.OCIT_DOMAIN조직 관리자 클러스터의
kubeconfig를 내보냅니다.export KUBECONFIG=/root/release/org-admin/org-admin-kubeconfig조직 관리자 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 재귀 리졸버 사용 설정
DNS-R0027 런북의 단계에 따라 v1 조직의 조직 관리자 클러스터에서만 재귀 리졸버를 사용 설정합니다.
모든 영역에서 테넌트 조직 업그레이드 완료
한 영역에서 업그레이드가 완료되면 다음 영역을 업그레이드하기 전에 해당 영역이 여전히 올바르게 작동하는지 확인하는 것이 좋습니다.
나머지 영역의 테넌트 조직에 대해 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."
4. Tenable SC 업그레이드
GDCH doctor를 실행하여 업그레이드가 필요한지 확인합니다.
gdcloud system doctor diagnose instance --include-ocs=vuln --root-admin-kubeconfig=${ROOT_ADMIN_CLUSTER_KUBECONFIG:?}tenable_sc_upgrade_readiness유효성 검사기가 실패하면 이미지를 업그레이드해야 합니다. OI 서비스 조직에서 Tenable SC를 업그레이드하려면 다음 단계를 따르세요.가상 머신 이름을 가져옵니다.
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)가상 머신의
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"}}'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:?}Tenable.SC 설치에 따라 Tenable SC를 새로 설정합니다.
업그레이드 후 정리
Identity and Access Management 섹션에서 생성된 ClusterRoleBinding 리소스를 삭제합니다.
테넌트 조직 업그레이드의 유지보수 기간 구성
테넌트 조직 (org)을 업그레이드하려면 kubectl 명령줄 인터페이스 (CLI) 및 콘솔 사용자 인터페이스 (UI)에 로그인하기 위해 사전 정의된 역할 설명 및 프로젝트의 역할 정의 페이지에 자세히 설명된 대로 올바른 뷰어 및 관리자 역할이 할당되어 있는지 확인합니다. 이러한 권한이 없는 경우 프로젝트 리소스에 대한 액세스 권한 부여 페이지의 안내에 따라 권한을 부여하거나 권한 부여를 요청하세요.
유지보수 기간을 구성하려면 필수 역할이 있어야 합니다. 다음 사전 정의된 역할이 사용자에게 할당되어 있는지 확인합니다.
- 조직 업그레이드 관리자
- 조직 업그레이드 뷰어 참고: 테넌트 조직을 루트 조직보다 낮은 부 버전으로 업그레이드하는 것은 지원되지 않습니다.
기본적으로 마이너 업그레이드용 MaintenanceWindow 하나와 패치 업그레이드용 MaintenanceWindow 하나가 있습니다. 부 버전 업그레이드는 기능을 개선하거나 이전 버전에서 변경사항을 적용합니다(예: 버그 수정). 이는 패키지 업그레이드입니다.
패치 업그레이드는 특정 문제나 취약점을 해결합니다. 정의된 일정에 따라 패치 업그레이드를 시작하도록 기본 패치 MaintenanceWindow를 구성합니다.
유지보수 기간을 구성하려면 CLI와 kubectl 명령어를 사용하여 MaintenanceWindow 리소스의 RRULE 및 TimeWindow 필드를 수정합니다.
이렇게 하면 업그레이드가 예약됩니다. RRULE에 관한 자세한 내용은 https://pkg.go.dev/github.com/teambition/rrule-go를 참고하세요.
kubectl CLI 명령어를 사용하려면 kubectl 탭을 클릭합니다. UI 기반 안내를 보려면 콘솔 탭을 클릭하세요.
콘솔
조직 UI에 로그인합니다.
유지보수 기간 일정을 수정합니다. 유지보수 탭으로 이동하여 수정을 클릭합니다.

그림 1. 유지보수 기간
유지보수 기간 수정 화면이 열립니다. 창을 사용하여 패치 및 부 버전 기간을 재구성합니다.

그림 2. 패치 및 부 업데이트 재구성
패치 버전, 시작 시간, 길이, 요일을 지정하거나 수정합니다.
부 버전 시작 시간, 길이, 반복, 요일을 수정합니다.

그림 3. 재구성 저장
저장을 클릭하여 변경사항을 적용합니다.
저장된 변경사항이 반복에 영향을 미치는 경우(예: 요일 또는 월을 변경한 경우) 대화상자가 표시됩니다. 변경사항을 확인하려면 계속을 클릭합니다.

그림 4. 계속을 클릭합니다.
다음 예는 구성 변경사항에 따라 업데이트된 예약 업그레이드를 보여줍니다. 대기 중인 각 상태 옆에 있는 건너뛰기 링크를 확인합니다. 예약된 대기 중인 업그레이드를 건너뛰는 데 사용합니다.
그림 5. 각
의 건너뛰기 옵션이 있는 예약 업그레이드 보기
kubectl
kubectlCLI에 로그인합니다. CLI 탭에서 이러한 안내를 찾습니다. 계속하기 전에 조직 관리자 클러스터에 대한 올바른 액세스 권한이 있는지 확인하세요.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시간의 기간 사양이 표시되지만 각 시간 블록에 최소 6시간을 할당하는 것이 좋습니다.
수동 Operations Suite 인프라 핵심 업그레이드
이 업그레이드 프로세스는 버전 1.13.x에서 1.14.3으로 업그레이드하는 경우에만 적용됩니다.
모든 관리 도메인과 로컬 계정이 만료되지 않은 비밀번호로 사용 설정되어 있는지 확인합니다. 상태가 좋지 않은 계정은 이 프로세스에서 오류를 일으킬 수 있습니다.
VM 체크포인트 및 디렉터리 백업 실행
VM 체크포인트를 실행합니다.
- BM01 호스트에서 PS 콘솔을 Administrator로 엽니다.
클러스터의 각 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 창을 열어둡니다.
긴 파일 경로 사용 설정
$path = 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' Set-ItemProperty -Path $path -Name 'LongPathsEnabled' -Value 1H:\operations_center 드라이브를 백업합니다. (이 작업은 업그레이드 롤백을 지원합니다.)
Rename-Item -Path H:\operations_center -NewName operations_center_backupCONFIG1에서 구성 디렉터리를 백업합니다. (이 백업은 새 config.ps1 구성을 빌드할 때 참조를 제공합니다.)
BM01 호스트에서 원격 데스크톱 프로토콜 (RDP)을 사용하여 CONFIG1 VM의 IP 주소에 연결하고 시스템 관리자 계정으로 로그인합니다. 예:
mstsc /v 192.168.100.99관리자 권한으로 실행을 사용하여 PS 콘솔을 엽니다.
- 백업 폴더 만들기
mkdir c:\config1_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
서드 파티 소프트웨어 로드
서드 파티 소프트웨어에서 작업을 실행합니다.
기존 가상 머신 업그레이드
설치 디렉터리를 가져옵니다.
파일 다운로드 섹션의 안내에 따라 OIC 구성요소 번들을 다운로드합니다.
BM01 호스트에서 다운로드한 prod_IT_component_bundle.tar.gz에서 operations_center 디렉터리를 추출합니다.
Set-Location H: tar -zxvf prod_IT_component_bundle.tar.gzTAR 파일을 추출하면 H: 루트에
release폴더가 생성됩니다.operations_center를 H의 루트로 이동합니다.Move-Item -Path H:\release\operations_center -Destination H:\
사이트별 데이터로 config.ps1 업데이트
config.ps1구성 파일은 Operations Suite Infrastructure (OI) 환경을 빌드하고 구성하는 데 필요한 모든 정보를 제공합니다. 구성 파일을 업데이트하려면 다음 정보를 모두 수집해야 합니다. 기존 config.ps1의 백업은 기존 설정이 의도치 않게 덮어쓰여지는 것을 방지하는 데 유용합니다. 중요:config.ps1이 완료되고 올바를 때까지 계속하지 마세요.occonfigtool도구의 네트워크 구성 출력(특히ocinfo.common.opscenter.local.txt파일) 다음 단계에서 언급된 네트워크 이름(예: OCCORE-SERVERS)은 해당 문서의Name열을 참조합니다.- 이 OI가 관리하는 모든 GDC 셀의 도메인 이름과 DNS 서버 IP 주소입니다. 이 데이터는 고객 정보 설문지 (CIQ)의 출력에서 확인할 수 있습니다.
Administrator로 BM01 호스트에서 모든 변경사항을 적용합니다.배포 유형에 맞는 구성 예시 코드를 복사합니다.
H:\operations_center\dsc\config.example.ps1를H:\operations_center\config\config.ps1에 복사합니다.
VSCode 또는 Powershell ISE를 사용하여
config.ps1의 값을 검증하고 업데이트합니다.OIC가 멀티 사이트로 배포된 경우:
### Multi-Site:라벨이 지정된 댓글 찾기- 찾은 댓글에 설명된 작업을 실행합니다.
기본값 (
3.0)이 올바르지 않으면HardwareVersion를 업데이트합니다.기본값 (
DC1)이 올바르지 않으면PrimarySiteCode를 업데이트합니다.사이트 코드는 여러 이름에 사용됩니다.
DC1의 모든 인스턴스를 올바른 사이트 코드로 검색하여 바꿉니다. 대소문자를 구분하지 않는 검색을 사용합니다. 일부 변경사항은 필요하지 않을 수 있으므로 각 변경사항을 검토하세요. 예를 들어 사이트 코드가AB1인 경우 호스트 이름DC1-DC1은AB1-DC1로 변경해야 하며AB1-AB1로 변경하면 안 됩니다.기본값이 올바르지 않으면
DnsDomain를 업데이트합니다. 이 값이 변경되면config.ps1파일 전체에서opscenter.local을 검색하여 바꿉니다. 기본값이 하드 코딩된 위치가 여러 개 있습니다.사이트별 정보로
DnsConditionalForwarder의 객체를 업데이트합니다. 하나 이상의 전달 객체가 있어야 합니다. 불필요한 예 삭제gdcloud및kubectlCLI가 설치된 경우 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"}'Domain- GDC 셀 DNS 도메인 이름입니다(예:ciq.yaml의dns.delegatedSubdomain).Master- DNS 서버 IP 목록입니다 (일반적으로 하나만 있음).DNSReservation유형의cellcfg를 확인합니다. GDC 셀이 배포된 경우 루트 관리 클러스터의dns-system네임스페이스에서gpc-coredns-external-udp서비스의 EXTERNAL-IP와 셀의 FQDN bert.sesame.street를 찾습니다.다중 사이트 배포에서는 셀당 하나의 해시 테이블 객체가 있습니다.
Users,Groups,GroupPolicy객체의 콘텐츠를 변경하면 안 됩니다.<SITE>-DC1및<SITE>-DC2와 같은 기본 및 보조 도메인 컨트롤러에 부여된 2개의 IP 주소를 포함하도록DNSServers를 업데이트합니다.NTPServers를 루트 관리자TimeServer커스텀 리소스의 SyncServer IP 주소 목록으로 업데이트합니다. 다음을 사용하여 이 IP 주소 집합을 가져올 수 있습니다.kubectl get timeserver -A -o json | jq '.items[].address'다음 예와 같이 이러한 IP 주소를
NTPServers로 포맷해야 합니다.NtpServers = @( '10.251.80.2', '10.251.80.3', '10.251.80.4', '10.251.80.5' )필요한 경우 고객이 제공한 OCCORE-SERVERS 서브넷의 서브넷 접두사 값으로
SubnetPrefix기본값(24)을 업데이트합니다.OCCORE-SERVERS 서브넷의 고객 제공 기본 게이트웨이로
DefaultGateway기본값을 업데이트합니다.IPv4 CIDR 표기법으로 OC-WORKSTATIONS 서브넷에 대해 고객이 제공한 값으로
WorkstationCider기본값을 찾아 업데이트합니다.고객이 워크스테이션에 대한 원격 액세스를 허용하도록 선택한 경우
WorkstationAllowRemote값을$true로 업데이트합니다.172.21.0.의 예시 서브넷 접두사를 고객이 제공한 OCCORE-SERVERS 서브넷 접두사로 찾아 바꾸세요.172.21.2.의 예시 서브넷 프리픽스를 고객이 제공한 OCCORE-JUMPHOSTS 서브넷 프리픽스로 찾아 바꾸세요.172.21.32.의 예시 서브넷 접두사를 고객이 제공한 OC-WORKSTATIONS 서브넷 접두사로 찾아 바꾸세요.Pref caption의 일일 메시지 예시legalnoticecaption값을 찾아 고객이 제공한 캡션으로 바꿉니다.Pref text의 예시 오늘의 메시지legalnoticetext값을 찾아 고객이 제공한 텍스트로 바꿉니다.각 '노드' 객체를 검증하고 필요한 경우 업데이트합니다.
NodeName- 호스트 이름이 올바른지 확인합니다. 일부 이름은 도메인 컨트롤러와 같이 여러 곳에서 사용됩니다. 여기에서 이름을 변경하는 경우 구성의 다른 곳에서도 변경해야 하는지 확인하세요.IPv4Addr- 호스트의 IP 주소여야 합니다. 마지막 옥텟은 그대로 두어도 됩니다. 일부는 이전 단계에서 실행한 네트워크 검색 및 바꾸기 중에 업데이트되었을 수 있습니다.HyperVHost- 이 값은 이 VM을 호스팅하는 Hyper-V 서버의 IP 주소여야 합니다. 구성의 'Hyper-V 서버' 섹션에서 각BM??서버의 IP 주소를 확인할 수 있습니다. 모든 Hyper-V 호스트가 모든 VM 유형을 지원할 수 있는 것은 아니므로 이 필드에서 Hyper-V 호스트 할당을 변경하지 말고 Hyper-V 호스트 이름을 해당 IP 주소로만 변경하세요.
Role=jumphost를 사용하여 모든 노드에서 두 번째 네트워크 인터페이스 세부정보를 검증합니다. 이 인터페이스에 OCCORE-JUMPHOSTS 서브넷 세부정보를 사용합니다. 확인:JumphostIPv4CidrJumphostDefaultGateway
Role=adfs인 노드에서 ADFS 관련 스탠자를 업데이트합니다.Name = 'SplunkTrust' # Must be unique to the farm. Append "Trust"행을 찾습니다.- 이 줄 뒤에 나오는
opscenter.local세 개를 DNS 도메인으로 바꿉니다.
필요에 따라 고객의 IP 계획에 맞게 DHCP 범위를 업데이트합니다. 각 범위에서 다음 값이 올바른지 확인합니다. 범위의 이름은
ocinfo.common.opscenter.local.txt네트워크 계획에 사용된 이름과 일치하므로 유효성 검사에서 다음을 사용합니다.ScopeIdIpStartRangeIpEndRangeRouterSubnetMask
값이 백업된 config1.ps1의 값과 일치하는지 확인합니다.
파일을 저장해야 합니다.
CONFIG1 VM 준비
CONFIG1 준비는 BM01에서 실행됩니다. 다른 모든 업그레이드는 CONFIG1 VM에 로그인한 상태에서 발생합니다.
operations_center 디렉터리를 CONFIG1 VM에 복사합니다.
BM01 호스트에서 PS 콘솔을 Administrator로 엽니다.
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 -ForceHyper-V 시간 동기화 사용 중지
관리자로 BM01 호스트에 로그인합니다.
Windows에서 관리자 권한으로 PowerShell을 열고 다음 명령어를 실행합니다.
# Disabling Hyper-V Time Sync Disable-VMIntegrationService -VMName `<SITE>-CONFIG1` -Name 'Time Synchronization'CONFIG1 VM 준비 및 검증
BM01 호스트에서
-SA계정으로 CONFIG1 VM에 로그인합니다. 원격 데스크톱 (RDP)을 사용하여 VM IP 주소에 연결합니다. 예:mstsc /v 192.168.100.99'다른 사용자로 실행' 메뉴를 사용하여 PowerShell 창을 열어 Marvin 사용자로 실행합니다.
새 PowerShell 창에서 관리 세션을 시작합니다.
Start -Verb runas -FilePath powershell.exe이전 powershell 창을 닫고 관리자 창을 열어 둡니다.
관리 PowerShell 창이 Marvin으로 실행되고 있는지 확인
whoamiBM01 호스트에서 스테이징된 파일을 배치합니다.
Move-Item -Path c:\operations_center -Destination c:\release C:\release\operations_center\dsc\Initialize-ConfigHostFiles.ps1c:\dsc및c:\config가 있는지 확인합니다.백업에서 사용자 인증 정보 및 인증서 파일 복사
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\" -RecurseMOF 컴파일에 필요한 MECM 데이터 빌드
C:\dsc\Build-MecmFiles.ps1모든 OI 머신의 MOF 파일을 생성하는
Build-Mof.ps1을 실행하여 빌드 환경이 준비되었는지 확인합니다.C:\dsc\Build-Mof.ps1
사용자 인증 정보 변수 입력
이러한 변수는 업그레이드 프로세스 전체에서 사용됩니다. 관리자 권한으로 열린 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 }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}
연결 문제 해결
New-CimSession가 실패하면config.ps1에서NodeName값이 올바른지 확인합니다. 또한 서버가 온라인 상태이고 연결 가능한지 확인합니다.오류는
Get-CimSession: WinRM cannot process the request로 시작합니다.
도메인 컨트롤러 업그레이드
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.NodeNameNew-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 DC1SyncServer와의 시간 동기화 유효성 검사
RDP를 사용하여 도메인 관리자로
DC1에 로그인합니다.Powershell창을 관리자로 엽니다.다음 명령어를 실행하여 시간 구성을 검증합니다.
w32tm /query /status /verbose
다음 명령어를 실행하여 시간 재동기화를 테스트합니다.
# Testing time resyncronization w32tm /resync# Desired output Sending resync command to local computer The command completed successfully.시간 구성이 올바르고 오류가 없는지 다시 검사합니다.
w32tm /query /status /verbose
두 번째 도메인 컨트롤러를 업그레이드합니다.
기존 CONFIG1 PowerShell 창을 사용하여 다음 스크립트를 실행합니다.
.\Update-RemoteHost.ps1 @da_args -ComputerName $dc2.NodeName
Active Directory 복제를 검증합니다.
두 번째 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-ISSUING1 및 CA-WEB 업그레이드
CONFIG1에서 기존 PowerShell 터미널을 사용하여CA-ISSUING1을 업그레이드합니다.$ca_iss = $config.AllNodes | Where-Object {$_.role -eq "ca_issuing"} c:\dsc\Update-RemoteHost.ps1 @sa_args -ComputerName $ca_iss.NodeNameCONFIG1에서 기존 PowerShell 터미널을 사용하여CA-WEB을 업그레이드합니다.$ca_web = $config.AllNodes | Where-Object {$_.role -eq "ca_web"} c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $ca_web.NodeName업그레이드 검증
$ca_iss,$ca_web | ForEach-Object { $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds Get-DscConfigurationStatus -CimSession $session}
CA-ROOT1 업그레이드
CONFIG1에서 기존 PowerShell 터미널 사용
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.NodeNameCA-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이전 스크립트 후
CA_ROOT1가 재부팅되지 않은 경우 수동으로 재부팅합니다.업그레이드를 검증합니다.
$ca_root | ForEach-Object { $session = New-CimSession -ComputerName $_.Ipv4Addr -Credential $caroot_cred Get-DscConfigurationStatus -CimSession $session}Peer설정이<SITE>-DC1.<DNSDOMAIN>이고State이Active인지 확인합니다.시간이 제대로 동기화되지 않으면 진행하지 마세요.
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)CA-Root전원을 끕니다.$session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds Stop-VM -CimSession $session -Name $ca_root.NodeName
ADFS 업그레이드
CONFIG1에서 기존 PowerShell 터미널 사용
ADFS1VM을 업그레이드합니다.$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}
점프 호스트를 업그레이드합니다.
CONFIG1에서 기존 PowerShell 터미널 사용
점프 호스트 배열을 만듭니다.
$role = 'jumphost' $jumps = $config.AllNodes | Where-Object {$_.role -eq $role}점프호스트를 업그레이드합니다.
$jumps | ForEach-Object { c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}업그레이드를 검증합니다.
$jumps | ForEach-Object { $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds Get-DscConfigurationStatus -CimSession $session}
파일 서버 업그레이드
CONFIG1에서 기존 PowerShell 터미널 사용
Fileserver가 포함된 배열을 만듭니다.
$role = 'file' $files = $config.AllNodes | Where-Object {$_.role -eq $role}파일 서버를 업그레이드합니다.
$files | ForEach-Object { c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}업그레이드를 검증합니다.
$files | ForEach-Object { $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds Get-DscConfigurationStatus -CimSession $session}
DHCP 서버를 업그레이드합니다.
CONFIG1에서 기존 PowerShell 터미널 사용
DHCP1 업그레이드
$role = 'dhcp_primary' $dhcp1 = $config.AllNodes | Where-Object {$_.role -eq $role} c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $dhcp1.NodeName업그레이드를 검증합니다.
$dhcp1 | ForEach-Object { $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds Get-DscConfigurationStatus -CimSession $session}DHCP2 업그레이드
$role = 'dhcp_failover' $dhcp2 = $config.AllNodes | Where-Object {$_.role -eq $role} c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $dhcp2.NodeName업그레이드를 검증합니다.
$dhcp2 | ForEach-Object { $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds Get-DscConfigurationStatus -CimSession $session}
Userlock 서버 업그레이드
CONFIG1에서 기존 PowerShell 터미널 사용
Userlock 서버가 포함된 PowerShell 배열을 만듭니다.
$role = 'userlock_primary' $ulock1 = $config.AllNodes | Where-Object {$_.role -eq $role} $role = 'userlock_backup' $ulock2 = $config.AllNodes | Where-Object {$_.role -eq $role}이전 설정에서 마커 파일을 삭제합니다.
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" }기본 Userlock 서버를 업그레이드합니다.
c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $ulock1.NodeName백업 Userlock 서버 업그레이드
c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $ulock2.NodeName업그레이드를 검증합니다.
$ulock1,$ulock2 | ForEach-Object { $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds Get-DscConfigurationStatus -CimSession $session}
Nessus 서버를 업그레이드합니다.
CONFIG1에서 기존 PowerShell 터미널 사용
Nessus 서버가 포함된 PowerShell 배열을 만듭니다.
$role = 'nessus_' $nessus = $config.AllNodes | Where-Object {$_.role -match $role}Nessus 서버를 업그레이드합니다.
$nessus | ForEach-Object { c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}업그레이드를 검증합니다.
$nessus | ForEach-Object { $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds Get-DscConfigurationStatus -CimSession $session}
Hyper-V 서버를 업그레이드합니다.
CONFIG1에서 기존 PowerShell 터미널 사용
Hyper-V 서버가 포함된 PowerShell 배열을 만듭니다.
$role = 'hyper_v' $hyper = $config.AllNodes | Where-Object {$_.role -eq $role}Hyper-V 서버를 업그레이드합니다.
$hyper | ForEach-Object { c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}업그레이드를 검증합니다.
$hyper | ForEach-Object { $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds Get-DscConfigurationStatus -CimSession $session}
도구 상자 업그레이드
CONFIG1에서 기존 PowerShell 터미널 사용
툴박스 서버를 포함하는 PowerShell 배열을 만듭니다.
$role = 'toolbox' $tools = $config.AllNodes | Where-Object {$_.role -eq $role}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툴박스 서버를 업그레이드합니다.
$tools | ForEach-Object { c:\dsc\Update-RemoteHost.ps1 @sa_args -Computername $_.NodeName}업그레이드를 검증합니다.
$tools | ForEach-Object { $session = New-CimSession -ComputerName $_.NodeName -Credential $sa_creds Get-DscConfigurationStatus -CimSession $session}
CONFIG1에서 기존 PowerShell 터미널을 사용하여 업그레이드를 검증합니다.
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 업그레이드
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
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 ContinueSIEM-G0006에 따라 전역 Pass4SymmKey를 설정하고 SIEM-G0007에 따라 각 영역을 OIC의 Splunk에 연결합니다.
CONFIG1 호스트 업그레이드
CONFIG1의 Powershell 창에서 다음을 실행합니다.
Start-DscConfiguration -ComputerName $env:COMPUTERNAME -Path c:\config\mofs -Verbose -Wait -Force컴퓨터가 재부팅되면 다시 로그인하고 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을 다시 배포하는 방법밖에 없습니다.
IT-T0023에 따라 현재 MCM 소프트웨어가 하이드레이션되었는지 확인합니다.
재배포 절차는 IT-R0019에 설명되어 있습니다.
VM 체크포인트 삭제
업그레이드가 완료되면 체크포인트가 삭제되어야 합니다. 체크포인트로 인해 시간이 지남에 따라 디스크 사용량이 과도해질 수 있습니다. 업그레이드 실패로 인해 체크포인트로 복원해야 하는 경우에만 유지하세요.
CONFIG1에서 기존 PowerShell 터미널 사용
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 터미널 사용
관리 GPO에서 링크를 사용 설정하도록 도메인 컨트롤러 역할 구성 변경
$gpolinks = (Get-Content C:\dsc\data\GpoLinkMapping.yaml -Raw).Replace("LinkEnabled: 'No'", "LinkEnabled: 'Yes'") $gpolinks | Out-File C:\dsc\data\GpoLinkMapping.yaml -ForceObjectOwner 역할로 도메인 컨트롤러를 업데이트합니다.
c:\dsc\Update-RemoteHost.ps1 -Computername $config.AllNodes.DomainConfig.ObjectOwner -Credential $da_creds
Google팀에 문의
Google에 문의하여 추가 지원을 받는 단계는 지원 요청 페이지를 참고하세요.