feat: introduce FAQ for installation of Global DR#157
Conversation
WalkthroughRestructures the Global DR installation doc to clarify Primary vs Standby roles and naming, require a user-provisioned load balancer forwarding TCP ports (including 2379), instruct copying Primary ETCD encryption keys to standby control-plane nodes via SSH/SCP, add UI/CLI etcd-synchronizer install and verification steps, expand DR recovery procedures and encryption-key sync FAQ, and add upload/package guidance. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Admin
participant LB as "Load Balancer\n(TCP forward)"
participant Primary as "Primary\nControl Plane"
participant Standby as "Standby\nControl Plane"
participant EtcdSync as "etcd-synchronizer\n(UI / Pod)"
participant Kube as "kube-apiserver / pods"
Note over Admin,LB: Preconfigure LB to forward TCP 80,443,6443,2379,11443 -> control-plane VIPs
Admin->>LB: Configure TCP forwarding for control-plane VIPs
Admin->>Primary: Install Primary cluster (domain -> Primary VIP)
Admin->>Standby: Copy ETCD encryption config (scp user@primary:/path/to/encryption-provider.conf /tmp/)
Admin->>EtcdSync: Install/Enable etcd-synchronizer (Marketplace or CLI)
EtcdSync->>Primary: Read ETCD keys/state
EtcdSync->>Standby: Read ETCD keys/state
EtcdSync-->>Admin: Report key differences / sync status
alt Standby missing keys
Admin->>Primary: Merge/export unique keys
Admin->>Standby: Deploy updated encryption-provider.conf to control planes
Admin->>Kube: Restart kube-apiserver / related pods to apply keys
end
Admin->>EtcdSync: Trigger/force sync (curl / UI)
EtcdSync-->>Admin: Sync result (success / errors)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/en/install/global_dr.mdx (2)
209-217: Harden kubectl selectors to return a single pod name.
--no-headers | head -1can break; use jsonpath or-o name.Apply:
-kubectl get po -n cpaas-system -l app=etcd-sync -kubectl logs -n cpaas-system $(kubectl get po -n cpaas-system -l app=etcd-sync --no-headers | head -1) | grep -i "Start Sync update" +kubectl get po -n cpaas-system -l app=etcd-sync +pod=$(kubectl get po -n cpaas-system -l app=etcd-sync -o jsonpath='{.items[0].metadata.name}') +kubectl logs -n cpaas-system "$pod" | grep -i "Start Sync update"-kubectl delete po -n cpaas-system $(kubectl get po -n cpaas-system -l app=etcd-sync --no-headers | head -1) +pod=$(kubectl get po -n cpaas-system -l app=etcd-sync -o jsonpath='{.items[0].metadata.name}') +kubectl delete po -n cpaas-system "$pod"
268-270: kubectl exec targets a Deployment; exec requires a Pod name.Replace with a pod selector to avoid failures.
Apply:
- kubectl exec -it -n cpaas-system deployments/sentry -- nslookup <platform access domain> + kubectl exec -it -n cpaas-system $(kubectl get pod -n cpaas-system -l app=sentry -o jsonpath='{.items[0].metadata.name}') -- nslookup <platform access domain>
🧹 Nitpick comments (3)
docs/en/install/global_dr.mdx (3)
222-231: Use explicit scheme and fail-fast curl; keep IPv6 handling.Make the check robust and explicit.
Apply:
-curl $mirror_new_svc/check +curl -sS --fail "http://$mirror_new_svc/check"
304-305: Consistent IPv6-safe check (reuse method from Step 3).The Routine Checks curl will break on IPv6-only clusters.
Apply:
-curl $(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}')/check +svc=$(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}') +if [[ $svc =~ ^[0-9a-fA-F:]+$ ]]; then svc="[$svc]"; fi +curl -sS --fail "http://$svc/check"
157-171: State preconditions: run as root or with sudo on all control plane nodes.The steps assume write access to /etc/kubernetes and ability to restart kubelet. Make that explicit to avoid partial updates.
Add:
+Prerequisite: Run the following commands as root (or prefix with sudo) on the indicated nodes.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(2 hunks)
🧰 Additional context used
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
151-151: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
Deploying acp-docs with
|
| Latest commit: |
8d2c6fc
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://8c6cb94f.acp-docs.pages.dev |
| Branch Preview URL: | https://upgrade-doc.acp-docs.pages.dev |
414364d to
27aeb5a
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (7)
docs/en/install/global_dr.mdx (7)
95-101: Harden key copy: fix grammar, require sudo, and set secure perms (600).Copying directly to /etc without sudo and leaving world-readable perms is unsafe; also fix the English in comments.
- # Let the control plane nodes of the primary cluster are 1.1.1.1, 2.2.2.2 & 3.3.3.3 - # the control plane nodes of the standby cluster are 4.4.4.4, 5.5.5.5 & 6.6.6.6 + # Assume the primary cluster control plane nodes are 1.1.1.1, 2.2.2.2 & 3.3.3.3 + # and the standby cluster control plane nodes are 4.4.4.4, 5.5.5.5 & 6.6.6.6 for i in 4.4.4.4 5.5.5.5 6.6.6.6 # Replace with standby cluster control plane node IPs do - ssh "<user>@$i" "mkdir -p /etc/kubernetes/" - scp /etc/kubernetes/encryption-provider.conf "<user>@$i:/etc/kubernetes/encryption-provider.conf" + ssh "<user>@$i" "sudo mkdir -p /etc/kubernetes/" + scp /etc/kubernetes/encryption-provider.conf "<user>@$i:/tmp/encryption-provider.conf" + ssh "<user>@$i" "sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf" done
117-117: Add security caveat for 2379 exposure and LB behavior.Call out “no internet exposure, allow-list only, pure TCP pass-through (no TLS termination at LB).”
-1. Configure the load balancer to forward port `2379` to the control plane nodes of both clusters. ONLY TCP mode is supported; forwarding on L7 is not supported. +1. Configure the load balancer to forward port `2379` to the control plane nodes of both clusters. ONLY TCP mode is supported; forwarding on L7 is not supported. + Security: Never expose 2379 to the public internet. Restrict by network ACLs/firewalls to only the control-plane/load-balancer addresses, and ensure the LB does TCP pass-through (no TLS termination or L7 inspection).
255-266: Replace real-looking base64 secret with explicit placeholder; add disclaimer.- name: key1 - secret: MTE0NTE0MTkxOTgxMA== + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>+> Note: Replace placeholders with your own 32‑byte keys encoded in base64. Do not reuse example values.
270-283: Same issue: placeholders for secrets in merged config; add disclaimer.- name: key1 - secret: My.1415926535897 + secret: <BASE64_32_BYTE_KEY_FROM_PRIMARY_EXAMPLE_ONLY> - name: key2 - secret: MTE0NTE0MTkxOTgxMA== + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>+> Note: Replace placeholders with your own 32‑byte keys encoded in base64. Do not reuse example values.
270-283: Call out key order semantics to avoid dual-write divergence.+Important: The first key in the list is used for writes; all keys are used for reads. Keep the Primary’s active key listed first on both clusters until rotation completes. Reorder/remove keys only during a planned rotation window after verifying re-encryption.
287-310: Fix remote distribution script: sudo, perms, interpolation, and restart sequence.Avoid ${i} inside single-quoted heredoc, copy to /tmp + sudo install 600, and just restart kubelet (static pod will be recreated). This also avoids incorrect crictl usage.
- scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/etc/kubernetes/encryption-provider.conf" - ssh "<user>@${i}" ' - #!/bin/bash - _pod_name="kube-apiserver" - _pod_id=$(crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod 'kube-apiserver' on node ${i}" - exit 1 - fi - crictl rm --force "${_pod_id}" - systemctl restart kubelet.service - ' + scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" + ssh "<user>@${i}" "sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf && sudo systemctl restart kubelet"
312-323: Fix restart on node 1.1.1.1: undefined ${i}, sudo, and crictl misuse.Variable ${i} isn’t defined here; use kubelet restart (static pod). Also require sudo.
- _pod_name="kube-apiserver" - _pod_id=$(crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod 'kube-apiserver' on node ${i}" - exit 1 - fi - crictl rm --force "${_pod_id}" - systemctl restart kubelet.service + # Restart kubelet to recreate the static kube-apiserver pod after config change + sudo systemctl restart kubelet
🧹 Nitpick comments (1)
docs/en/install/global_dr.mdx (1)
245-246: Fix grammar of FAQ lead-in.-* Here are the instructions in case that the ETCD encryption key of the standby cluster has not synced with the one of **primary cluster** before Installing the standby cluster. +* Use this procedure if the standby cluster’s etcd encryption key did not sync with the **Primary Cluster** before installing the standby cluster.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(4 hunks)
🧰 Additional context used
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
280-280: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🔇 Additional comments (1)
docs/en/install/global_dr.mdx (1)
172-187: Add strict error handling and conditional restart
Includeset -euo pipefailand change the block so it only deletes Elasticsearch pods—and reruns the check—when theensure-asm-template.shscript actually returns a 401 error. Manually verify that/root/ensure-asm-template.shexits non-zero on failure and outputs “401” on authentication errors before applying this change.
27aeb5a to
ef89b1e
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (6)
docs/en/install/global_dr.mdx (6)
106-112: Secure copy of encryption config: sudo, atomic install, and perms 600Avoid writing to /etc without privilege; enforce root ownership and 0600. Also tweak the preface lines for grammar.
- # Let the control plane nodes of the primary cluster are 1.1.1.1, 2.2.2.2 & 3.3.3.3 - # the control plane nodes of the standby cluster are 4.4.4.4, 5.5.5.5 & 6.6.6.6 + # Assume the primary control-plane nodes are 1.1.1.1, 2.2.2.2, 3.3.3.3 + # and the standby control-plane nodes are 4.4.4.4, 5.5.5.5, 6.6.6.6 for i in 4.4.4.4 5.5.5.5 6.6.6.6 # Replace with standby cluster control plane node IPs do - ssh "<user>@$i" "mkdir -p /etc/kubernetes/" - scp /etc/kubernetes/encryption-provider.conf "<user>@$i:/etc/kubernetes/encryption-provider.conf" + ssh "<user>@$i" "sudo mkdir -p /etc/kubernetes/" + scp /etc/kubernetes/encryption-provider.conf "<user>@$i:/tmp/encryption-provider.conf" + ssh "<user>@$i" "sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf" done
266-271: Require sudo to read encryption configReading /etc requires root. Use sudo and tighten placeholders.
- ssh <user>@<STANDBY cluster control plane node> cat /etc/kubernetes/encryption-provider.conf + ssh "<user>@<standby_control_plane_node>" "sudo cat /etc/kubernetes/encryption-provider.conf"
306-329: Remote script: quoting, sudo, correct crictl usage, and atomic installSingle-quoted SSH script won’t expand ${i}; commands need sudo; use crictl pods stopp/rmp or just restart kubelet. Also install file with 0600.
- scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/etc/kubernetes/encryption-provider.conf" - ssh "<user>@${i}" ' - #!/bin/bash - _pod_name="kube-apiserver" - _pod_id=$(crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod 'kube-apiserver' on node ${i}" - exit 1 - fi - crictl rm --force "${_pod_id}" - systemctl restart kubelet.service - ' + scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" + ssh "<user>@${i}" " + set -euo pipefail + sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf + _pod_name='kube-apiserver' + _pod_id=\$(sudo crictl pods --name \"\${_pod_name}\" -q || true) + if [[ -z \"\${_pod_id}\" ]]; then + echo 'WARN: kube-apiserver pod not found; restarting kubelet' + sudo systemctl restart kubelet + else + sudo crictl stopp \"\${_pod_id}\" || true + sudo crictl rmp \"\${_pod_id}\" || true + sudo systemctl restart kubelet + fi + "
331-342: Same restart-sequence issues on node 1.1.1.1Mirror sudo + crictl pods fix here as well; or simply restart kubelet.
- _pod_name="kube-apiserver" - _pod_id=$(crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod 'kube-apiserver' on node ${i}" - exit 1 - fi - crictl rm --force "${_pod_id}" - systemctl restart kubelet.service + set -euo pipefail + _pod_name="kube-apiserver" + _pod_id=$(sudo crictl pods --name "${_pod_name}" -q || true) + if [[ -z "${_pod_id}" ]]; then + echo "WARN: kube-apiserver pod not found; restarting kubelet" + sudo systemctl restart kubelet + else + sudo crictl stopp "${_pod_id}" || true + sudo crictl rmp "${_pod_id}" || true + sudo systemctl restart kubelet + fi
136-137: Security caveat for etcd (2379): restrict exposure and require L4 passthroughAdd explicit warning not to expose 2379 publicly; allow-list control-plane/LB IPs only; no TLS termination on LB.
-1. Configure the load balancer to forward port `2379` to the control plane nodes of both clusters. ONLY TCP mode is supported; forwarding on L7 is not supported. +1. Configure the load balancer to forward port `2379` to the control-plane nodes of both clusters. ONLY TCP (L4) is supported; no L7. Security: do NOT expose 2379 publicly—restrict access via network ACLs/firewalls to the specific control-plane and LB addresses, and ensure pure TCP pass-through (no TLS termination) on the LB.
289-303: Use placeholders and call out key-order semantics (writes use first key)Prevent dual-write divergence by keeping Primary key first on both clusters until rotation completes.
@@ - - name: key1 - secret: My4xNDE1OTI2NTM1ODk3 - - name: key2 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_PRIMARY_EXAMPLE_ONLY> + - name: key2 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>Add after the YAML:
+Important: Kubernetes writes with the first key and reads with all keys. Keep the Primary cluster’s active key listed first on both clusters. Rotate by reordering/removing keys only after confirming re-encryption has completed.
🧹 Nitpick comments (6)
docs/en/install/global_dr.mdx (6)
30-31: Grammar fix for node-naming guidance“to indicates” → “to indicate.” Also tighten wording.
-* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicates which cluster the node belongs to (Primary or Standby). +* To facilitate troubleshooting and management, name nodes like `standby-global-m1` to indicate which cluster (Primary or Standby) they belong to.
63-70: Tighten Process Overview phrasing and ownershipClarify subjects and article use; minor grammar.
-2. Point the domain to the **Primary Cluster's** VIP and install the **Primary Cluster**; +2. Point the domain to the **Primary Cluster** VIP and install the **Primary Cluster**; -4. Copy the ETCD encryption key of the **Primary Cluster** to the nodes that will later be the control plane nodes of Standby Cluster; +4. Copy the etcd encryption key from the **Primary Cluster** to the nodes that will be the Standby cluster’s control plane; -5. Install and enable the etcd synchronization plugin; +5. Install and enable the etcd synchronization plugin; -6. Verify sync status and perform regular checks; +6. Verify sync status and schedule regular checks; -7. In case of failure, switch DNS to the standby cluster to complete disaster recovery. +7. In case of failure, switch DNS to the Standby cluster to complete disaster recovery.
73-79: LB bullet: clarity and ports; grammar fixSimplify sentence; make subject/object clear.
-* One domain name used as the `Platform Access Address` for both clusters; -* A set of TLS certificate and private key for that unified domain; -* Two virtual IPs for both clusters (Primary and Standby); +* One domain name used as the `Platform Access Address` for both clusters. +* A TLS certificate and private key for that domain. +* Two virtual IPs (VIPs), one for each cluster (Primary and Standby). - * Pre-configure the Load Balancer to route TCP traffic, which destination port is `80`, `443`, `6443`, `2379` or `11443`, to the control plane nodes of the cluster which endpoint IP is the VIP of LB. + * Preconfigure the Load Balancer to route TCP ports `80`, `443`, `6443`, `2379`, and `11443` to the cluster’s control-plane nodes behind each VIP.
83-93: Step 1 WARNING block: concise language and consistencyReduce verbosity, fix grammar, and keep options consistent.
-While installing the primary cluster of the DR (Disaster Recovery Environment), - -* First of all, documenting all of the parameters set while following the guide of the installation web UI. It is necessary to keep some options the same while installing the standby cluster. +When installing the Primary cluster for DR: + +* First, document all parameters used in the installation UI. You must reuse some of them when installing the Standby cluster. * The `Self-built VIP` option is NOT available. A **User-provisioned** Load Balancer is required for routing traffic sent to the virtual IP. -* The `Platform Access Address` MUST be a domain, while `Cluster Endpoint` MUST be the virtual IP address. +* The `Platform Access Address` MUST be the domain; the `Cluster Endpoint` MUST be the VIP. * The `Self-signed Certificate` option is NOT available. It is NECESSARY for both of the clusters to be configured with `An Existing Certificate`. -* In case the `Image Repository` is set to `Platform Deployment`, the `Username` and `Password` of `Image Repository` MUST NOT be empty; the `IP/Domain` option MUST be set to the unified domain name, which is the `Platform Access Address`. +* If `Image Repository` is `Platform Deployment`, `Username` and `Password` MUST be set; `IP/Domain` MUST be the unified `Platform Access Address` domain. * The `HTTP Port` and `HTTPS Port` options of `Platform Access Address` MUST be 80 and 443. -* The `Other Platform Access Addresses` option, which is at the second page of the installation web UI (Named `Advanced`), MUST include the virtual IP of the primary cluster. +* In `Advanced` (page 2), `Other Platform Access Addresses` MUST include the Primary cluster VIP.
117-127: Step 2 WARNING block: grammar and clarity; fix “same of”Minor English fixes; emphasize sameness.
-While installing the standby cluster of the DR (Disaster Recovery Environment), +When installing the Standby cluster for DR: @@ -* The `Cluster Endpoint` option MUST be the virtual IP address. +* The `Cluster Endpoint` MUST be the VIP. @@ -the following options MUST be set to the same as the **primary cluster**: +Set the following options the same as the **Primary cluster**: @@ -* The options about `Image Repository`. It is IMPORTANT to make sure the credentials of image repository are the same of the **primary cluster**. +* The `Image Repository` options. Ensure the repository credentials are the same as the **Primary cluster**.
259-261: Clarify violet flag and targetTiny tweak for clarity; quote flag and entity.
-When using **`violet`** to upload packages to a standby cluster, you must specify the `--dest-repo` parameter with the VIP of the standby cluster. +When using `violet` to upload packages to the Standby cluster, specify `--dest-repo` with the Standby cluster VIP.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(4 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/en/install/global_dr.mdx
[grammar] ~64-~64: There might be a mistake here.
Context: ...VIP and install the Primary Cluster; 3. Temporarily switch DNS resolution to the...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...ndby VIP to install the Standby Cluster; 4. Copy the ETCD encryption key of the **Pr...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...t will later be the control plane nodes of Standby Cluster; 5. Install and enable ...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ... control plane nodes of Standby Cluster; 5. Install and enable the etcd synchronizat...
(QB_NEW_EN)
[grammar] ~67-~67: There might be a mistake here.
Context: ... enable the etcd synchronization plugin; 6. Verify sync status and perform regular c...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ... sync status and perform regular checks; 7. In case of failure, switch DNS to the st...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...tform Access Address` for both clusters; * A set of TLS certificate and private key...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ...and private key for that unified domain; * Two virtual IPs for both clusters (Prima...
(QB_NEW_EN)
[style] ~86-~86: Often, this adverbial phrase is redundant. Consider using an alternative.
Context: ... DR (Disaster Recovery Environment), * First of all, documenting all of the parameters set ...
(FIRST_OF_ALL)
[style] ~86-~86: Consider removing “of” to be more concise
Context: ...ironment), * First of all, documenting all of the parameters set while following the guid...
(ALL_OF_THE)
[grammar] ~87-~87: There might be a mistake here.
Context: ... routing traffic sent to the virtual IP. * The Platform Access Address MUST be a ...
(QB_NEW_EN)
[grammar] ~88-~88: There might be a mistake here.
Context: ...ndpointMUST be the virtual IP address. * TheSelf-signed Certificate` option is ...
(QB_NEW_EN)
[grammar] ~97-~97: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
[grammar] ~123-~123: There might be a mistake here.
Context: ... to the same as the primary cluster: * The options about `Platform Access Addre...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ...options about Platform Access Address. * The options about Certificate. * The o...
(QB_NEW_EN)
[grammar] ~126-~126: There might be a mistake here.
Context: ... IMPORTANT to make sure the credentials of image repository are the same of the **...
(QB_NEW_EN)
[grammar] ~131-~131: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
299-299: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/en/install/global_dr.mdx (1)
147-156: kubectl name extraction bug: command uses full row, not pod name
kubectl get po --no-headers | head -1returns multiple columns;kubectl logs/deletewill fail. Use-o nameor jsonpath.-kubectl logs -n cpaas-system $(kubectl get po -n cpaas-system -l app=etcd-sync --no-headers | head -1) | grep -i "Start Sync update" +kubectl logs -n cpaas-system "$(kubectl get po -n cpaas-system -l app=etcd-sync -o name | head -1)" | grep -i "Start Sync update" @@ -kubectl delete po -n cpaas-system $(kubectl get po -n cpaas-system -l app=etcd-sync --no-headers | head -1) +kubectl delete po -n cpaas-system "$(kubectl get po -n cpaas-system -l app=etcd-sync -o name | sed 's|.*/||' | head -1)"
♻️ Duplicate comments (6)
docs/en/install/global_dr.mdx (6)
137-137: Security caveat for etcd (2379) exposureRe‑add the warning not to expose 2379 publicly; restrict to allow‑listed peers; ensure pure TCP pass‑through (no TLS termination).
-1. Configure the load balancer to forward port `2379` to the control plane nodes of both clusters. ONLY TCP mode is supported; forwarding on L7 is not supported. +1. Configure the load balancer to forward port `2379` to the control‑plane nodes of both clusters. Use TCP pass‑through only (no L7/TLS termination), and restrict access to the specific peer/load‑balancer addresses. Do not expose 2379 publicly.
192-208: Re-run ES template script after restart (as instructed)You say “then execute the script to check the cluster again,” but you don’t re-run it.
xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" +sleep 5 +# Re-run the check after pods restart +bash /root/ensure-asm-template.sh
290-304: Replace remaining Base64 secrets with placeholders and call out key‑order semanticsAlso document “first key writes, all keys read.”
- - name: key1 - secret: My4xNDE1OTI2NTM1ODk3 - - name: key2 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_PRIMARY_EXAMPLE_ONLY> + - name: key2 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>Add after the YAML:
+Important: Kubernetes writes using the first key and reads with all keys. Keep the Primary’s active key listed first on both clusters until rotation completes to avoid dual‑write divergence.
270-286: Replace Base64 literal secret with explicit placeholder + add disclaimerAvoid secret-scanner hits and accidental reuse.
- - name: key1 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>Add immediately below the YAML:
+> Note: Replace placeholders with your own randomly generated 32‑byte keys encoded in base64. Do not reuse example values.
106-113: Encryption config copy: reduce file permissions to 600Sensitive file; 640 exposes group read. Use 600.
-ssh "<user>@$i" "sudo install -o root -g root -m 640 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf" +ssh "<user>@$i" "sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf"
305-333: Remote restart script: incorrect crictl usage, quoting, and message variable
- Uses
crictl ps/rm(containers) while treating them as pods.- Single‑quoted here‑doc prevents local
${i}expansion; echo references${i}which isn’t defined remotely.- Prefer simple kubelet restart; static pod will be recreated.
- scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" - ssh "<user>@${i}" ' - #!/bin/bash - set -euo pipefail - - sudo install -o root -g root -m 640 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf - _pod_name="kube-apiserver" - _pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod 'kube-apiserver' on node ${i}" - exit 1 - fi - sudo crictl rm --force "${_pod_id}" - sudo systemctl restart kubelet.service - ' + scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" + ssh "<user>@${i}" "bash -s" <<'EOF' +set -euo pipefail +sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf +# For static kube-apiserver, restarting kubelet is sufficient +sudo systemctl restart kubelet.service +EOF
🧹 Nitpick comments (9)
docs/en/install/global_dr.mdx (9)
30-31: Grammar/clarity: tighten node-naming guidance“to indicates” → “to indicate”. Suggest simpler phrasing.
-* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicates which cluster the node belongs to (Primary or Standby). +* To aid troubleshooting and management, name nodes like `standby-global-m1` to indicate which cluster they belong to (Primary or Standby).
63-70: Process wording and parallelismImprove grammar; use “standby control-plane nodes”; avoid repeated semicolons.
-2. Point the domain to the **Primary Cluster's** VIP and install the **Primary Cluster**; -3. Temporarily switch DNS resolution to the standby VIP to install the Standby Cluster; -4. Copy the ETCD encryption key of the **Primary Cluster** to the nodes that will later be the control plane nodes of Standby Cluster; -5. Install and enable the etcd synchronization plugin; -6. Verify sync status and perform regular checks; -7. In case of failure, switch DNS to the standby cluster to complete disaster recovery. +2. Point the domain to the **Primary Cluster** VIP and install the **Primary Cluster**. +3. Temporarily switch DNS to the standby VIP and install the Standby Cluster. +4. Copy the Primary’s ETCD encryption config to the standby control‑plane nodes. +5. Install and enable the etcd synchronization plugin. +6. Verify sync status and perform routine checks. +7. On failure, switch DNS to the standby cluster to complete recovery.
73-77: Resources list grammar and LB sentenceTighten grammar; clarify LB VIP wording.
-* One domain name used as the `Platform Access Address` for both clusters; -* A set of TLS certificate and private key for that unified domain; -* Two virtual IPs for both clusters (Primary and Standby); - * Pre-configure the Load Balancer to route TCP traffic, which destination port is `80`, `443`, `6443`, `2379` or `11443`, to the control plane nodes of the cluster which endpoint IP is the VIP of LB. +* One domain name used as the `Platform Access Address` for both clusters. +* A TLS certificate and private key for that domain. +* Two virtual IPs (Primary and Standby). + * Pre‑configure the Load Balancer to TCP‑forward ports `80`, `443`, `6443`, `2379`, and `11443` to the control‑plane nodes behind each VIP.
83-93: Installation WARNING block: grammar and clarityReduce awkward phrasing; improve imperative wording; tighten certificate/image repo notes.
-While installing the primary cluster of the DR (Disaster Recovery Environment), -* First of all, documenting all of the parameters set while following the guide of the installation web UI. It is necessary to keep some options the same while installing the standby cluster. +When installing the primary cluster for DR: +* Record all parameters set in the installation UI. You must reuse several of them when installing the standby cluster. @@ -* The `Platform Access Address` MUST be a domain, while `Cluster Endpoint` MUST be the virtual IP address. +* The `Platform Access Address` MUST be a domain; the `Cluster Endpoint` MUST be the virtual IP address. @@ -* In case the `Image Repository` is set to `Platform Deployment`, the `Username` and `Password` of `Image Repository` MUST NOT be empty; the `IP/Domain` option MUST be set to the unified domain name, which is the `Platform Access Address`. +* If `Image Repository` is set to `Platform Deployment`, `Username` and `Password` MUST be set; `IP/Domain` MUST be the unified domain (the `Platform Access Address`).
116-129: Step 2 wording and capitalizationSentence case; clarify “same as primary”.
-3. Install the standby cluster in the same way as the primary cluster +3. Install the standby cluster in the same way as the Primary Cluster. @@ -While installing the standby cluster of the DR (Disaster Recovery Environment), +When installing the standby cluster: @@ -the following options MUST be set to the same as the **primary cluster**: +set the following options to match the **Primary Cluster**: @@ -* The options about `Image Repository`. It is IMPORTANT to make sure the credentials of image repository are the same of the **primary cluster**. +* `Image Repository` options. Ensure the credentials are identical to the **Primary Cluster**.
160-169: Add curl timeout and quiet flags; keep IPv6 handlingImprove operability.
-curl $mirror_new_svc/check +curl -fsS --connect-timeout 5 "$mirror_new_svc/check"
252-254: Routine check: IPv6-safe curl like Step 3Inline variant lacks IPv6 bracket logic.
-curl $(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}')/check +ip=$(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}') +[[ $ip =~ ^[0-9a-fA-F:]+$ ]] && ip="[$ip]" +curl -fsS --connect-timeout 5 "$ip/check"
270-271: Placeholder token formattingAvoid spaces inside angle‑bracket placeholders; they’re confusing in CLI.
-ssh <user>@<STANDBY cluster control plane node> sudo cat /etc/kubernetes/encryption-provider.conf +ssh "<user>@<standby_control_plane_node>" "sudo cat /etc/kubernetes/encryption-provider.conf"
213-214: DNS switch wordingClarify exact action.
-5. Switch the platform domain DNS to the standby VIP, which now becomes the Primary Cluster; +5. Update the platform domain’s A/AAAA record from the Primary VIP to the standby VIP (the standby now becomes the Primary).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(4 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/en/install/global_dr.mdx
[grammar] ~64-~64: There might be a mistake here.
Context: ...VIP and install the Primary Cluster; 3. Temporarily switch DNS resolution to the...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...ndby VIP to install the Standby Cluster; 4. Copy the ETCD encryption key of the **Pr...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...t will later be the control plane nodes of Standby Cluster; 5. Install and enable ...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ... control plane nodes of Standby Cluster; 5. Install and enable the etcd synchronizat...
(QB_NEW_EN)
[grammar] ~67-~67: There might be a mistake here.
Context: ... enable the etcd synchronization plugin; 6. Verify sync status and perform regular c...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ... sync status and perform regular checks; 7. In case of failure, switch DNS to the st...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...tform Access Address` for both clusters; * A set of TLS certificate and private key...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ...and private key for that unified domain; * Two virtual IPs for both clusters (Prima...
(QB_NEW_EN)
[style] ~86-~86: Often, this adverbial phrase is redundant. Consider using an alternative.
Context: ... DR (Disaster Recovery Environment), * First of all, documenting all of the parameters set ...
(FIRST_OF_ALL)
[style] ~86-~86: Consider removing “of” to be more concise
Context: ...ironment), * First of all, documenting all of the parameters set while following the guid...
(ALL_OF_THE)
[grammar] ~87-~87: There might be a mistake here.
Context: ... routing traffic sent to the virtual IP. * The Platform Access Address MUST be a ...
(QB_NEW_EN)
[grammar] ~88-~88: There might be a mistake here.
Context: ...ndpointMUST be the virtual IP address. * TheSelf-signed Certificate` option is ...
(QB_NEW_EN)
[grammar] ~97-~97: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ... to the same as the primary cluster: * The options about `Platform Access Addre...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...options about Platform Access Address. * The options about Certificate. * The o...
(QB_NEW_EN)
[grammar] ~127-~127: There might be a mistake here.
Context: ... IMPORTANT to make sure the credentials of image repository are the same of the **...
(QB_NEW_EN)
[grammar] ~132-~132: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
300-300: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/en/install/global_dr.mdx (2)
148-156: kubectl logs/delete selection is wrong; use -o name.
--no-headers | head -1returns multiple columns; commands will fail.-kubectl logs -n cpaas-system $(kubectl get po -n cpaas-system -l app=etcd-sync --no-headers | head -1) | grep -i "Start Sync update" +pod=$(kubectl get po -n cpaas-system -l app=etcd-sync -o name | head -1) +kubectl logs -n cpaas-system "$pod" | grep -i "Start Sync update" @@ -kubectl delete po -n cpaas-system $(kubectl get po -n cpaas-system -l app=etcd-sync --no-headers | head -1) +kubectl delete -n cpaas-system "$(kubectl get po -n cpaas-system -l app=etcd-sync -o name | head -1)"
248-254: IPv6-safe routine check (align with earlier logic).Use the bracketed IPv6 handling as above to avoid curl failures.
-curl $(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}')/check +ip=$(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}') +if [[ "$ip" =~ ^[0-9a-fA-F:]+$ ]]; then svc="[$ip]"; else svc="$ip"; fi +curl "$svc"/check
♻️ Duplicate comments (5)
docs/en/install/global_dr.mdx (5)
137-138: Add security caveat for etcd (2379): restrict access and L4 pass‑through only.Avoid exposing etcd publicly; allow‑list control‑plane/LB IPs; no TLS termination on LB.
-1. Configure the load balancer to forward port `2379` to the control plane nodes of both clusters. ONLY TCP mode is supported; forwarding on L7 is not supported. +1. Configure the load balancer to forward port `2379` to the control plane nodes of both clusters. ONLY TCP (L4) is supported; L7 forwarding is not supported. +> Security: Do NOT expose 2379 publicly. Restrict access via network ACLs/firewalls to control‑plane and LB IPs only, and ensure pure TCP pass‑through (no TLS termination or inspection).
192-208: Re-run ES check after restart (as stated).Doc says “then execute the script again” but snippet doesn’t. Add a second run after pod restarts.
- # In case the script returned the 401 error, restart Elasticsearch - # then execute the script to check the cluster again - bash /root/ensure-asm-template.sh + # If the script returns 401, restart Elasticsearch then re-run the check + bash /root/ensure-asm-template.sh @@ - xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + # Re-run after restart + bash /root/ensure-asm-template.sh
270-286: Replace Base64 key with explicit placeholder + add disclaimer.Avoid secret‑scanner hits and accidental reuse.
- - name: key1 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>+> Note: Replace placeholders with your own 32‑byte keys encoded in base64. Do not reuse example values.
288-304: Replace Base64 literals, and call out key‑order semantics.K8s writes with the first key and reads with all. Keep the Primary’s key first until rotation completes.
- - name: key1 - secret: My4xNDE1OTI2NTM1ODk3 - - name: key2 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_PRIMARY_EXAMPLE_ONLY> + - name: key2 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>+> Important: The first key is used for writes. Keep the Primary’s key first on both clusters to avoid dual‑write divergence. Reorder/remove keys only during a planned rotation window after confirming migration.
335-346: Prefer kubelet restart over crictl pod/ctr manipulation.Simpler, less error‑prone, and consistent with earlier step.
-_pod_name="kube-apiserver" -_pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) -if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod 'kube-apiserver' on current node" - exit 1 -fi -sudo crictl rm --force "${_pod_id}" -sudo systemctl restart kubelet.service +sudo systemctl restart kubelet.service
🧹 Nitpick comments (5)
docs/en/install/global_dr.mdx (5)
30-31: Grammar fix: “to indicates” → “to indicate”.Small readability tweak.
-* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicates which cluster the node belongs to (Primary or Standby). +* To facilitate troubleshooting and management, name standby nodes like `standby-global-m1` to indicate which cluster the node belongs to (Primary or Standby).
64-70: Tighten Process Overview phrasing.Minor grammar/consistency.
-2. Point the domain to the **Primary Cluster's** VIP and install the **Primary Cluster**; -3. Temporarily switch DNS resolution to the standby VIP to install the Standby Cluster; -4. Copy the ETCD encryption key of the **Primary Cluster** to the nodes that will later be the control plane nodes of Standby Cluster; +2. Point the domain to the **Primary Cluster** VIP and install the **Primary Cluster**. +3. Temporarily point DNS to the standby VIP and install the **Standby Cluster**. +4. Copy the ETCD encryption key from the **Primary Cluster** to the future control‑plane nodes of the **Standby Cluster**. -5. Install and enable the etcd synchronization plugin; -6. Verify sync status and perform regular checks; -7. In case of failure, switch DNS to the standby cluster to complete disaster recovery. +5. Install and enable the etcd synchronization plugin. +6. Verify sync status and perform regular checks. +7. If the primary fails, switch DNS to the standby cluster to complete disaster recovery.
73-78: Resource list grammar + LB wording.Clearer phrasing.
-* One domain name used as the `Platform Access Address` for both clusters; -* A set of TLS certificate and private key for that unified domain; +* One domain name used as the `Platform Access Address` for both clusters. +* A TLS certificate and private key for that unified domain. -* Two virtual IPs for both clusters (Primary and Standby); +* Two virtual IPs (VIPs): one per cluster (Primary and Standby). @@ - * Pre-configure the Load Balancer to route TCP traffic, which destination port is `80`, `443`, `6443`, `2379` or `11443`, to the control plane nodes of the cluster which endpoint IP is the VIP of LB. + * Pre‑configure the Load Balancer to TCP‑forward ports `80`, `443`, `6443`, `2379`, and `11443` to the control‑plane nodes behind the cluster VIP.
83-93: Step 1 warning block: tighten language and consistency.Improve clarity; keep MUST/NOT consistent.
-While installing the primary cluster of the DR (Disaster Recovery Environment), -* First of all, documenting all of the parameters set while following the guide of the installation web UI. It is necessary to keep some options the same while installing the standby cluster. +While installing the Primary cluster in the DR environment: +* First, record all parameters used in the installation UI. Some options must match when installing the Standby cluster. @@ -* The `Platform Access Address` MUST be a domain, while `Cluster Endpoint` MUST be the virtual IP address. +* The `Platform Access Address` MUST be a domain; the `Cluster Endpoint` MUST be the virtual IP address (VIP). @@ -* In case the `Image Repository` is set to `Platform Deployment`, the `Username` and `Password` of `Image Repository` MUST NOT be empty; the `IP/Domain` option MUST be set to the unified domain name, which is the `Platform Access Address`. +* If `Image Repository` is `Platform Deployment`, `Username` and `Password` MUST NOT be empty; `IP/Domain` MUST be the unified domain (the `Platform Access Address`). @@ -* The `Other Platform Access Addresses` option, which is at the second page of the installation web UI (Named `Advanced`), MUST include the virtual IP of the primary cluster. +* On the Advanced page, `Other Platform Access Addresses` MUST include the Primary VIP.
118-128: Step 2 warning block: grammar and consistency.Match Primary/Standby capitalization; fix “same of”.
-While installing the standby cluster of the DR (Disaster Recovery Environment), +While installing the Standby cluster in the DR environment: @@ -* The `Cluster Endpoint` option MUST be the virtual IP address. +* The `Cluster Endpoint` MUST be the virtual IP address (VIP). @@ -the following options MUST be set to the same as the **primary cluster**: -* The options about `Platform Access Address`. -* The options about `Certificate`. -* The options about `Image Repository`. It is IMPORTANT to make sure the credentials of image repository are the same of the **primary cluster**. +The following options MUST match the **Primary Cluster**: +* `Platform Access Address`. +* `Certificate`. +* `Image Repository` (use the same credentials as the **Primary Cluster**).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(4 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/en/install/global_dr.mdx
[grammar] ~64-~64: There might be a mistake here.
Context: ...VIP and install the Primary Cluster; 3. Temporarily switch DNS resolution to the...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...ndby VIP to install the Standby Cluster; 4. Copy the ETCD encryption key of the **Pr...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...t will later be the control plane nodes of Standby Cluster; 5. Install and enable ...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ... control plane nodes of Standby Cluster; 5. Install and enable the etcd synchronizat...
(QB_NEW_EN)
[grammar] ~67-~67: There might be a mistake here.
Context: ... enable the etcd synchronization plugin; 6. Verify sync status and perform regular c...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ... sync status and perform regular checks; 7. In case of failure, switch DNS to the st...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...tform Access Address` for both clusters; * A set of TLS certificate and private key...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ...and private key for that unified domain; * Two virtual IPs for both clusters (Prima...
(QB_NEW_EN)
[style] ~86-~86: Often, this adverbial phrase is redundant. Consider using an alternative.
Context: ... DR (Disaster Recovery Environment), * First of all, documenting all of the parameters set ...
(FIRST_OF_ALL)
[style] ~86-~86: Consider removing “of” to be more concise
Context: ...ironment), * First of all, documenting all of the parameters set while following the guid...
(ALL_OF_THE)
[grammar] ~87-~87: There might be a mistake here.
Context: ... routing traffic sent to the virtual IP. * The Platform Access Address MUST be a ...
(QB_NEW_EN)
[grammar] ~88-~88: There might be a mistake here.
Context: ...ndpointMUST be the virtual IP address. * TheSelf-signed Certificate` option is ...
(QB_NEW_EN)
[grammar] ~97-~97: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ... to the same as the primary cluster: * The options about `Platform Access Addre...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...options about Platform Access Address. * The options about Certificate. * The o...
(QB_NEW_EN)
[grammar] ~127-~127: There might be a mistake here.
Context: ... IMPORTANT to make sure the credentials of image repository are the same of the **...
(QB_NEW_EN)
[grammar] ~132-~132: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
300-300: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (6)
docs/en/install/global_dr.mdx (6)
192-208: Re-run the ES verification script after restart, as instructed.
The text says “then execute the script to check the cluster again” but the snippet doesn’t re-run it post-restart.- # In case the script returned the 401 error, restart Elasticsearch - # then execute the script to check the cluster again - bash /root/ensure-asm-template.sh + # If the script returns 401, run it once, then restart Elasticsearch and re-run the check + bash /root/ensure-asm-template.sh @@ - xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + # Re-run after pods are recreated + bash /root/ensure-asm-template.sh
137-138: Add explicit security warning for etcd forwarding (2379).
Call out “no public exposure, L4 pass‑through only.”-1. Configure the load balancer to forward port `2379` to the control plane nodes of both clusters. ONLY TCP mode is supported; forwarding on L7 is not supported. +1. Configure the load balancer to forward port `2379` to the control-plane nodes of both clusters. ONLY TCP (L4) mode is supported; L7 forwarding is not supported. + Security: Do not expose `2379` publicly. Restrict access via network ACLs/allow-lists to control‑plane and LB addresses only, with pure TCP pass‑through (no TLS termination).
270-286: Replace Base64 literals with placeholders and add a disclaimer.
These look like real secrets and will trigger secret scanners or be reused accidentally.- - name: key1 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>Add right below the YAML block:
+> Note: Replace placeholders with your own 32‑byte keys encoded in Base64. Do not reuse example values.
290-303: Use placeholders in both examples and document key-order semantics.
- Swap Base64 strings for explicit placeholders.
- Important: Kubernetes writes with the first key; keep the Primary’s key first on both clusters until rotation completes to avoid dual-writes.
- name: key1 - secret: My4xNDE1OTI2NTM1ODk3 + secret: <BASE64_32_BYTE_KEY_FROM_PRIMARY_EXAMPLE_ONLY> - name: key2 - secret: MTE0NTE0MTkxOTgxMA== + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>Add immediately after the YAML:
+Important: The first key in the list is used for writes, while all keys are used for reads. Keep the Primary cluster’s active key first on both clusters until rotation completes.
305-333: Remote script: fix variable expansion, drop brittle crictl usage, keep perms hardened.
${i}won’t expand inside single quotes on the remote; the message prints literally.crictllogic is brittle and unnecessary for static pod reload; restarting kubelet is sufficient after replacing the file.- Keep
install -m 600.- scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" - ssh "<user>@${i}" ' - #!/bin/bash - set -euo pipefail - - sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf - _pod_name="kube-apiserver" - _pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod 'kube-apiserver' on node ${i}" - exit 1 - fi - sudo crictl rm --force "${_pod_id}" - sudo systemctl restart kubelet.service - ' + scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" + ssh "<user>@${i}" "bash -s" <<'REMOTE' +set -euo pipefail +sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf +# For static pods, kubelet restart is sufficient to pick up the new config +sudo systemctl restart kubelet.service +REMOTE
335-346: Single-node restart: simplify and avoid undefined${i}; prefer kubelet restart.
The crictl path is brittle; restarting kubelet after replacing the file is reliable for static pods.- _pod_name="kube-apiserver" - _pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod 'kube-apiserver' on current node" - exit 1 - fi - sudo crictl rm --force "${_pod_id}" - sudo systemctl restart kubelet.service + sudo systemctl restart kubelet.service
🧹 Nitpick comments (4)
docs/en/install/global_dr.mdx (4)
30-31: Grammar: fix “to indicates” and tighten phrasing.
[建议] Change “to indicates” → “to indicate” and simplify the sentence.-* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicates which cluster the node belongs to (Primary or Standby). +* To simplify troubleshooting and management, name nodes like `standby-global-m1` to indicate which cluster the node belongs to (Primary or Standby).
83-93: Polish the WARNING block for clarity and grammar.
Minor edits improve readability; content unchanged.-While installing the primary cluster of the DR (Disaster Recovery Environment), - -* First of all, documenting all of the parameters set while following the guide of the installation web UI. It is necessary to keep some options the same while installing the standby cluster. +When installing the primary cluster for the DR environment: + +* First, document all parameters configured in the installation UI. You must reuse several of them when installing the standby cluster. @@ -* The `Platform Access Address` MUST be a domain, while `Cluster Endpoint` MUST be the virtual IP address. +* The `Platform Access Address` MUST be a domain, and the `Cluster Endpoint` MUST be the virtual IP address. @@ -* The `Other Platform Access Addresses` option, which is at the second page of the installation web UI (Named `Advanced`), MUST include the virtual IP of the primary cluster. +* On the `Advanced` page, the `Other Platform Access Addresses` option MUST include the primary cluster’s VIP.
118-128: Tighten grammar and ensure “match Primary Cluster” phrasing.-while installing the standby cluster of the DR (Disaster Recovery Environment), +when installing the standby cluster in the DR environment: @@ -the following options MUST be set to the same as the **primary cluster**: +the following options MUST match the **Primary Cluster**: @@ -* The options about `Image Repository`. It is IMPORTANT to make sure the credentials of image repository are the same of the **primary cluster**. +* `Image Repository` options. Ensure the image repository credentials are identical to the **Primary Cluster**.
252-254: IPv6-safe curl in Routine Checks.
Match the IPv6-bracketing logic used earlier to avoid failures with IPv6 ClusterIP.-curl $(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}')/check +mirror_svc=$(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}') +if [[ $mirror_svc =~ ^[0-9a-fA-F:]+$ ]]; then mirror_svc="[$mirror_svc]"; fi +curl "${mirror_svc}/check"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(4 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/en/install/global_dr.mdx
[grammar] ~64-~64: There might be a mistake here.
Context: ...VIP and install the Primary Cluster; 3. Temporarily switch DNS resolution to the...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...ndby VIP to install the Standby Cluster; 4. Copy the ETCD encryption key of the **Pr...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...t will later be the control plane nodes of Standby Cluster; 5. Install and enable ...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ... control plane nodes of Standby Cluster; 5. Install and enable the etcd synchronizat...
(QB_NEW_EN)
[grammar] ~67-~67: There might be a mistake here.
Context: ... enable the etcd synchronization plugin; 6. Verify sync status and perform regular c...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ... sync status and perform regular checks; 7. In case of failure, switch DNS to the st...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...tform Access Address` for both clusters; * A set of TLS certificate and private key...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ...and private key for that unified domain; * Two virtual IPs for both clusters (Prima...
(QB_NEW_EN)
[style] ~86-~86: Often, this adverbial phrase is redundant. Consider using an alternative.
Context: ... DR (Disaster Recovery Environment), * First of all, documenting all of the parameters set ...
(FIRST_OF_ALL)
[style] ~86-~86: Consider removing “of” to be more concise
Context: ...ironment), * First of all, documenting all of the parameters set while following the guid...
(ALL_OF_THE)
[grammar] ~87-~87: There might be a mistake here.
Context: ... routing traffic sent to the virtual IP. * The Platform Access Address MUST be a ...
(QB_NEW_EN)
[grammar] ~88-~88: There might be a mistake here.
Context: ...ndpointMUST be the virtual IP address. * TheSelf-signed Certificate` option is ...
(QB_NEW_EN)
[grammar] ~97-~97: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ... to the same as the primary cluster: * The options about `Platform Access Addre...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...options about Platform Access Address. * The options about Certificate. * The o...
(QB_NEW_EN)
[grammar] ~127-~127: There might be a mistake here.
Context: ... IMPORTANT to make sure the credentials of image repository are the same of the **...
(QB_NEW_EN)
[grammar] ~132-~132: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
300-300: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🔇 Additional comments (1)
docs/en/install/global_dr.mdx (1)
106-113: Secure copy flow LGTM.
Using sudo, temp path, andinstall -m 600is correct. Nice hardening.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (6)
docs/en/install/global_dr.mdx (6)
73-78: Load balancer: add etcd security caveat and wording fixesExplicitly forbid public exposure of 2379 and require pure L4 pass-through. Also fix wording.
-* One domain name used as the `Platform Access Address` for both clusters; -* A set of TLS certificate and private key for that unified domain; -* Two virtual IPs for both clusters (Primary and Standby); +* One domain name used as the `Platform Access Address` for both clusters. +* A TLS certificate and private key for that unified domain. +* Two virtual IPs (VIPs), one per cluster (Primary and Standby). @@ - * Preconfigure the load balancer to route TCP traffic on ports `80`, `443`, `6443`, `2379`, and `11443` to the control-plane nodes behind the corresponding VIP. + * Preconfigure the load balancer to route TCP traffic on ports `80`, `443`, `6443`, `2379`, and `11443` to the control-plane nodes behind the corresponding VIP. + * Security: Never expose port `2379` (etcd) to the public internet. Restrict access to control-plane and LB addresses only via network ACLs/firewalls, and ensure the LB performs TCP pass-through only (no TLS termination or L7 inspection).
137-137: Add security warning for 2379 here tooReinforce that etcd must not be internet-exposed and LB must be L4 pass-through.
-1. Configure the load balancer to forward port `2379` to the control plane nodes of both clusters. ONLY TCP mode is supported; forwarding on L7 is not supported. +1. Configure the load balancer to forward port `2379` to the control-plane nodes of both clusters. Use TCP pass-through only (no L7/TLS termination). Security: do NOT expose `2379` publicly; restrict access to control-plane/LB addresses via ACLs/firewalls.
265-286: Do not publish real-looking Base64 secrets; use placeholders + disclaimerReplace Base64 literals with placeholders and add a note to avoid secret-scanner noise and accidental reuse.
- - name: key1 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>Add immediately below the YAML:
+> Note: Replace placeholders with your own randomly generated 32-byte keys encoded in Base64. Do not reuse example values.
288-304: Merge example: placeholders and key-order semanticsUse placeholders for both secrets and add a note that the first key is used for writes across both clusters until rotation completes.
- - name: key1 - secret: My4xNDE1OTI2NTM1ODk3 - - name: key2 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_PRIMARY_EXAMPLE_ONLY> + - name: key2 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>Add below the YAML:
+Important: Kubernetes writes with the first key and reads with all keys. Keep the Primary’s active key listed first on both clusters to avoid dual-write divergence. Reorder/remove keys only during a planned rotation after confirming re-encryption is complete.
335-346: Single-node restart: avoid crictl; just restart kubeletThis avoids container/pod mismatch and works reliably with static pods.
-_pod_name="kube-apiserver" -_pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) -if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod 'kube-apiserver' on current node" - exit 1 -fi -sudo crictl rm --force "${_pod_id}" -sudo systemctl restart kubelet.service +sudo systemctl restart kubelet.service
305-333: Remote script: ${i} won’t expand; crictl misuse; simplify to kubelet restartThe here-doc or double-quoted script is needed if you reference ${i}. Also, removing containers via crictl is brittle; restarting kubelet is sufficient for static pods.
- scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" - ssh "<user>@${i}" ' - #!/bin/bash - set -euo pipefail - - sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf - _pod_name="kube-apiserver" - _pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod 'kube-apiserver' on node ${i}" - exit 1 - fi - sudo crictl rm --force "${_pod_id}" - sudo systemctl restart kubelet.service - ' + scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" + ssh "<user>@${i}" "bash -s" <<'REMOTE' +set -euo pipefail +sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf +# Static pod will be reconciled by kubelet +sudo systemctl restart kubelet.service +REMOTE
🧹 Nitpick comments (6)
docs/en/install/global_dr.mdx (6)
30-31: Grammar: fix “to indicates …”Prefer “indicate” and tighten the sentence.
-* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicates which cluster the node belongs to (Primary or Standby). +* To simplify troubleshooting and management, name nodes like `standby-global-m1` to indicate which cluster (Primary or Standby) the node belongs to.
64-70: Process overview: minor grammar and consistencyAdd periods and consistent article/capitalization.
-2. Point the domain to the **Primary Cluster's** VIP and install the **Primary Cluster**; +2. Point the domain to the **Primary Cluster’s** VIP and install the **Primary Cluster**. -3. Temporarily switch DNS resolution to the standby VIP to install the Standby Cluster; +3. Temporarily switch DNS to the standby VIP to install the Standby Cluster. -4. Copy the ETCD encryption key of the **Primary Cluster** to the nodes that will later be the control plane nodes of Standby Cluster; +4. Copy the etcd encryption key from the **Primary Cluster** to the nodes that will be the control-plane nodes of the Standby Cluster. -5. Install and enable the etcd synchronization plugin; +5. Install and enable the etcd synchronization plugin. -6. Verify sync status and perform regular checks; +6. Verify sync status and perform regular checks. -7. In case of failure, switch DNS to the standby cluster to complete disaster recovery. +7. If a failure occurs, switch DNS to the standby cluster to complete disaster recovery.
83-93: Step 1 warning: tighten grammar; clarify must/shall; avoid “First of all”Make bullets concise and precise.
-While installing the primary cluster of the DR (Disaster Recovery Environment), - -* First of all, documenting all of the parameters set while following the guide of the installation web UI. It is necessary to keep some options the same while installing the standby cluster. +While installing the primary cluster in the Disaster Recovery Environment: + +* Record all parameters used in the installation UI. Certain options must match when installing the standby cluster. @@ -* The `Platform Access Address` MUST be a domain, while `Cluster Endpoint` MUST be the virtual IP address. +* The `Platform Access Address` MUST be a domain; the `Cluster Endpoint` MUST be the virtual IP address. @@ -* In case the `Image Repository` is set to `Platform Deployment`, the `Username` and `Password` of `Image Repository` MUST NOT be empty; the `IP/Domain` option MUST be set to the unified domain name, which is the `Platform Access Address`. +* If `Image Repository` is `Platform Deployment`, `Username` and `Password` MUST be set; `IP/Domain` MUST be the unified domain (the `Platform Access Address`). @@ -* The `Other Platform Access Addresses` option, which is at the second page of the installation web UI (Named `Advanced`), MUST include the virtual IP of the primary cluster. +* In `Advanced` (page 2), `Other Platform Access Addresses` MUST include the primary cluster VIP.
116-128: Step 2 wording and consistencyMinor grammar and “same as” fixes.
-3. Install the standby cluster in the same way as the primary cluster +3. Install the standby cluster in the same way as the primary cluster. @@ -While installing the standby cluster of the DR (Disaster Recovery Environment), +While installing the standby cluster in the Disaster Recovery Environment: @@ -the following options MUST be set to the same as the **primary cluster**: +set the following options the same as the **Primary Cluster**: @@ -* The options about `Image Repository`. It is IMPORTANT to make sure the credentials of image repository are the same of the **primary cluster**. +* `Image Repository` options. Ensure the image repository credentials are the same as the **Primary Cluster**.
192-208: Elasticsearch flow: re-run the check after restartYou say “then execute the script to check the cluster again,” but the script isn’t re-run post-restart.
- # In case the script returned the 401 error, restart Elasticsearch - # then execute the script to check the cluster again - bash /root/ensure-asm-template.sh + # If the script returns 401, restart Elasticsearch and then re-run the check + bash /root/ensure-asm-template.sh @@ - xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + # Re-run after restart + bash /root/ensure-asm-template.sh
253-254: IPv6-safe check URLMirror the IPv6-bracketing logic used earlier to avoid malformed curl URLs when the Service has an IPv6 ClusterIP.
-curl $(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}')/check +ip=$(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}') +[[ "$ip" =~ : ]] && ip="[$ip]" +curl "$ip/check"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(4 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/en/install/global_dr.mdx
[grammar] ~64-~64: There might be a mistake here.
Context: ...VIP and install the Primary Cluster; 3. Temporarily switch DNS resolution to the...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...ndby VIP to install the Standby Cluster; 4. Copy the ETCD encryption key of the **Pr...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...t will later be the control plane nodes of Standby Cluster; 5. Install and enable ...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ... control plane nodes of Standby Cluster; 5. Install and enable the etcd synchronizat...
(QB_NEW_EN)
[grammar] ~67-~67: There might be a mistake here.
Context: ... enable the etcd synchronization plugin; 6. Verify sync status and perform regular c...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ... sync status and perform regular checks; 7. In case of failure, switch DNS to the st...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...tform Access Address` for both clusters; * A set of TLS certificate and private key...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ...and private key for that unified domain; * Two virtual IPs for both clusters (Prima...
(QB_NEW_EN)
[style] ~86-~86: Often, this adverbial phrase is redundant. Consider using an alternative.
Context: ... DR (Disaster Recovery Environment), * First of all, documenting all of the parameters set ...
(FIRST_OF_ALL)
[style] ~86-~86: Consider removing “of” to be more concise
Context: ...ironment), * First of all, documenting all of the parameters set while following the guid...
(ALL_OF_THE)
[grammar] ~87-~87: There might be a mistake here.
Context: ... routing traffic sent to the virtual IP. * The Platform Access Address MUST be a ...
(QB_NEW_EN)
[grammar] ~88-~88: There might be a mistake here.
Context: ...ndpointMUST be the virtual IP address. * TheSelf-signed Certificate` option is ...
(QB_NEW_EN)
[grammar] ~97-~97: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ... to the same as the primary cluster: * The options about `Platform Access Addre...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...options about Platform Access Address. * The options about Certificate. * The o...
(QB_NEW_EN)
[grammar] ~127-~127: There might be a mistake here.
Context: ... IMPORTANT to make sure the credentials of image repository are the same of the **...
(QB_NEW_EN)
[grammar] ~132-~132: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
300-300: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🔇 Additional comments (1)
docs/en/install/global_dr.mdx (1)
106-113: Secure copy flow looks goodUsing a temp path, sudo install, and mode 600 is correct.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/en/install/global_dr.mdx (1)
145-156: Bug: pod name extraction will pass an entire table row to kubectl.Using
--no-headers | head -1returns the whole line, not just the name. Use jsonpath or-o name.-kubectl get po -n cpaas-system -l app=etcd-sync -kubectl logs -n cpaas-system $(kubectl get po -n cpaas-system -l app=etcd-sync --no-headers | head -1) | grep -i "Start Sync update" +kubectl get po -n cpaas-system -l app=etcd-sync +pod=$(kubectl get po -n cpaas-system -l app=etcd-sync -o jsonpath='{.items[0].metadata.name}') +kubectl logs -n cpaas-system "$pod" | grep -i "Start Sync update" @@ -kubectl delete po -n cpaas-system $(kubectl get po -n cpaas-system -l app=etcd-sync --no-headers | head -1) +kubectl delete po -n cpaas-system "$pod"
♻️ Duplicate comments (4)
docs/en/install/global_dr.mdx (4)
192-208: Re-run ES template check after restart (missing).You mention “then execute the script again” but it isn’t re-run.
# Restart Elasticsearch xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + # Re-run the check after pods restart + bash /root/ensure-asm-template.sh
265-303: Replace Base64 secrets with placeholders and add key-order note.Avoid secret-scanner hits and accidental reuse; document write-key ordering.
```yaml @@ keys: - - name: key1 - secret: MTE0NTE0MTkxOTgxMA== + - name: primary-key + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY> ``` +> Note: Replace placeholders with your own 32‑byte keys encoded in Base64. Do not reuse example values. @@ keys: - - name: key1 - secret: My4xNDE1OTI2NTM1ODk3 - - name: key2 - secret: MTE0NTE0MTkxOTgxMA== + - name: primary-key + secret: <BASE64_32_BYTE_KEY_FROM_PRIMARY_EXAMPLE_ONLY> + - name: standby-key + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY> ``` +Important: Kubernetes writes with the first key and reads with all keys. Keep the Primary’s active key listed first on both clusters until rotation completes to avoid dual-write divergence.
137-138: Call out etcd exposure risks explicitly here.Reinforce the L4-only, non-public requirement in this step.
-1. Configure the load balancer to forward port `2379` to the control plane nodes of both clusters. ONLY TCP mode is supported; forwarding on L7 is not supported. +1. Configure the load balancer to forward port `2379` to the control plane nodes of both clusters. TCP only (no L7), no TLS termination, and NEVER expose `2379` publicly—restrict to control‑plane/LB IPs only.
317-332: Remote SSH script runs bashisms under /bin/sh; simplify and harden.
set -o pipefailneeds bash; the inline shebang won’t apply; also crictl removal is brittle. Use a bash here-doc and just restart kubelet.- scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" - ssh "<user>@${i}" ' - #!/bin/bash - set -euo pipefail - - sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf - _pod_name="kube-apiserver" - _pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod `kube-apiserver` on node $(hostname)" - exit 1 - fi - sudo crictl rm --force "${_pod_id}" - sudo systemctl restart kubelet.service - ' + scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" + ssh "<user>@${i}" "bash -s" <<'REMOTE' +set -euo pipefail +sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf +rm -f /tmp/encryption-provider.conf +# Restart kubelet to pick up the static pod change +sudo systemctl restart kubelet.service +REMOTE
🧹 Nitpick comments (7)
docs/en/install/global_dr.mdx (7)
30-31: Grammar: “to indicates” → “to indicate”.Minor clarity fix.
-* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicates which cluster the node belongs to (Primary or Standby). +* To facilitate troubleshooting and management, name nodes like `standby-global-m1` to indicate which cluster the node belongs to (Primary or Standby).
83-93: Tighten wording in WARNING block.Shorten and fix grammar; keep meaning unchanged.
-While installing the primary cluster of the DR (Disaster Recovery Environment), -* First of all, documenting all of the parameters set while following the guide of the installation web UI. It is necessary to keep some options the same while installing the standby cluster. +While installing the primary cluster in the DR environment: +* First, document all parameters used in the installation UI. Some options must match when installing the standby cluster. * The `Self-built VIP` option is NOT available. A **User-provisioned** Load Balancer is required for routing traffic sent to the virtual IP. * The `Platform Access Address` MUST be a domain, while `Cluster Endpoint` MUST be the virtual IP address. * The `Self-signed Certificate` option is NOT available. It is NECESSARY for both of the clusters to be configured with `An Existing Certificate`. * In case the `Image Repository` is set to `Platform Deployment`, the `Username` and `Password` of `Image Repository` MUST NOT be empty; the `IP/Domain` option MUST be set to the unified domain name, which is the `Platform Access Address`. * The `HTTP Port` and `HTTPS Port` options of `Platform Access Address` MUST be 80 and 443. -* The `Other Platform Access Addresses` option, which is at the second page of the installation web UI (Named `Advanced`), MUST include the virtual IP of the primary cluster. +* On the `Advanced` page, `Other Platform Access Addresses` MUST include the primary cluster VIP.
116-128: Consistency and grammar: capitalize “Primary/Standby Cluster”; fix phrasing.Minor readability improvements.
-3. Install the standby cluster in the same way as the primary cluster +3. Install the Standby Cluster in the same way as the Primary Cluster. @@ -While installing the standby cluster of the DR (Disaster Recovery Environment), +While installing the Standby Cluster in the DR environment: @@ -the following options MUST be set to the same as the **primary cluster**: +the following options MUST match those of the **Primary Cluster**: @@ -* The options about `Image Repository`. It is IMPORTANT to make sure the credentials of image repository are the same of the **primary cluster**. +* The options about `Image Repository`. Ensure the image repository credentials are the same as the **Primary Cluster**.
102-113: Source file read requires root; offer sudo-friendly alternative.If the local session isn’t root, scp will fail to read /etc. Provide a no-root alternative.
for i in 4.4.4.4 5.5.5.5 6.6.6.6 # Replace with standby cluster control plane node IPs do ssh "<user>@$i" "sudo mkdir -p /etc/kubernetes/" - scp /etc/kubernetes/encryption-provider.conf "<user>@$i:/tmp/encryption-provider.conf" + # If not running as root locally, use sudo+stdin to avoid read-permission issues: + # sudo cat /etc/kubernetes/encryption-provider.conf | ssh "<user>@$i" "cat > /tmp/encryption-provider.conf" + scp /etc/kubernetes/encryption-provider.conf "<user>@$i:/tmp/encryption-provider.conf" ssh "<user>@$i" "sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf" done
248-254: IPv6-safe curl like Step 3.Mirror the IPv6 handling used earlier to avoid bracket issues.
-curl $(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}')/check +ip=$(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}') +if [[ $ip =~ ^[0-9a-fA-F:]+$ ]]; then ip="[$ip]"; fi +curl "$ip"/check
335-346: Prefer kubelet restart over crictl container deletion.Static-pod containers are managed by kubelet; deleting containers is unnecessary and runtime-coupled.
-_pod_name="kube-apiserver" -_pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) -if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod `kube-apiserver` on node $(hostname)" - exit 1 -fi -sudo crictl rm --force "${_pod_id}" -sudo systemctl restart kubelet.service +sudo systemctl restart kubelet.service
210-218: DNS cutover ops tip (TTL/negative caching).Optional but helpful during failover.
5. Switch the platform domain DNS to the standby VIP, which now becomes the Primary Cluster; 6. Verify DNS resolution: + - Tip: Lower the DNS TTL ahead of drills/cutovers and clear negative-caching on resolvers if propagation seems slow.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(4 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/en/install/global_dr.mdx
[grammar] ~64-~64: There might be a mistake here.
Context: ...VIP and install the Primary Cluster; 3. Temporarily switch DNS resolution to the...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...ndby VIP to install the Standby Cluster; 4. Copy the ETCD encryption key of the **Pr...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...t will later be the control plane nodes of Standby Cluster; 5. Install and enable ...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ... control plane nodes of Standby Cluster; 5. Install and enable the etcd synchronizat...
(QB_NEW_EN)
[grammar] ~67-~67: There might be a mistake here.
Context: ... enable the etcd synchronization plugin; 6. Verify sync status and perform regular c...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ... sync status and perform regular checks; 7. In case of failure, switch DNS to the st...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...tform Access Address` for both clusters; * A set of TLS certificate and private key...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ...and private key for that unified domain; * Two virtual IPs for both clusters (Prima...
(QB_NEW_EN)
[style] ~86-~86: Often, this adverbial phrase is redundant. Consider using an alternative.
Context: ... DR (Disaster Recovery Environment), * First of all, documenting all of the parameters set ...
(FIRST_OF_ALL)
[style] ~86-~86: Consider removing “of” to be more concise
Context: ...ironment), * First of all, documenting all of the parameters set while following the guid...
(ALL_OF_THE)
[grammar] ~87-~87: There might be a mistake here.
Context: ... routing traffic sent to the virtual IP. * The Platform Access Address MUST be a ...
(QB_NEW_EN)
[grammar] ~88-~88: There might be a mistake here.
Context: ...ndpointMUST be the virtual IP address. * TheSelf-signed Certificate` option is ...
(QB_NEW_EN)
[grammar] ~97-~97: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ... to the same as the primary cluster: * The options about `Platform Access Addre...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...options about Platform Access Address. * The options about Certificate. * The o...
(QB_NEW_EN)
[grammar] ~127-~127: There might be a mistake here.
Context: ... IMPORTANT to make sure the credentials of image repository are the same of the **...
(QB_NEW_EN)
[grammar] ~132-~132: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
300-300: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (7)
docs/en/install/global_dr.mdx (7)
191-207: Re-run the ES template check after restarting pods, as the text promises.Currently the script runs before the restart only. Add a second invocation.
- # In case the script returned the 401 error, restart Elasticsearch - # then execute the script to check the cluster again - bash /root/ensure-asm-template.sh + # If the script returns 401, restart Elasticsearch, then re-run the script + bash /root/ensure-asm-template.sh @@ - xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + # Re-run the check after pods restart + bash /root/ensure-asm-template.sh
304-332: Simplify remote restart; avoid brittle crictl usage and harden quoting.For static pods, restarting kubelet is sufficient. Remove container-runtime coupling and keep perms at 600. Also avoid single-quoted inline script; use a here‑doc.
- scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" - ssh "<user>@${i}" ' - #!/bin/bash - set -euo pipefail - - sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf - _pod_name="kube-apiserver" - _pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod `kube-apiserver` on node $(hostname)" - exit 1 - fi - sudo crictl rm --force "${_pod_id}" - sudo systemctl restart kubelet.service - ' + scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" + ssh "<user>@${i}" "bash -s" <<'REMOTE' +set -euo pipefail +sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf +rm -f /tmp/encryption-provider.conf +sudo systemctl restart kubelet.service +REMOTE
334-345: Apply the same simplified restart on node 1.1.1.1.Mirror the kubelet restart approach and drop crictl dependency.
-_pod_name="kube-apiserver" -_pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) -if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod `kube-apiserver` on node $(hostname)" - exit 1 -fi -sudo crictl rm --force "${_pod_id}" -sudo systemctl restart kubelet.service +sudo systemctl restart kubelet.service
73-77: Add explicit etcd (2379) security caveat and clarify wording.Do not expose 2379 publicly; require pure L4 pass‑through. Matches earlier feedback.
-* A unified domain which will be the `Platform Access Address`, and the TLS certificate plus private key for serving HTTPS on that domain; +* A unified domain to use as the `Platform Access Address`, and a TLS certificate plus private key for serving HTTPS on that domain. * A dedicated virtual IP address for each cluster — one for the **Primary Cluster** and another for the Standby Cluster; - * Preconfigure the load balancer to route TCP traffic on ports `80`, `443`, `6443`, `2379`, and `11443` to the control-plane nodes behind the corresponding VIP. + * Preconfigure the load balancer to route TCP traffic on ports `80`, `443`, `6443`, `2379`, and `11443` to the control-plane nodes behind the corresponding VIP. + * Security: Never expose port `2379` (etcd) to the public internet. Restrict access to control‑plane/LB addresses via ACLs/allow‑lists, and ensure pure L4 TCP pass‑through (no TLS termination or L7 inspection).
136-136: Call out L4 pass‑through and access controls for 2379.Add “no TLS termination/L7” and explicit allow‑lists. Mirrors earlier guidance.
-1. Configure the load balancer to forward port `2379` to control plane nodes of the corresponding cluster. ONLY TCP mode is supported; forwarding on L7 is not supported. +1. Configure the load balancer to forward port `2379` to control plane nodes of the corresponding cluster. ONLY L4/TCP pass‑through is supported (no TLS termination/L7). Restrict access to control‑plane/LB addresses via ACLs/allow‑lists.
274-285: Replace Base64 secret with an explicit placeholder and add a disclaimer.Avoid secret-scanner hits and accidental reuse.
@@ keys: - - name: key1 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>Add immediately below the YAML:
+> Note: Replace placeholders with your own randomly generated 32‑byte keys encoded in base64. Do not reuse example values.
289-303: Use placeholders for all secrets and document key-order semantics.Kubernetes writes with the first key and reads with all. Keep the Primary’s key first across both clusters to avoid dual-write divergence. Replace Base64 literals.
@@ keys: - name: key1 - secret: My4xNDE1OTI2NTM1ODk3 + secret: <BASE64_32_BYTE_KEY_FROM_PRIMARY_EXAMPLE_ONLY> - name: key2 - secret: MTE0NTE0MTkxOTgxMA== + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>Add immediately below the YAML:
+Important: The first key is used for writes, all keys are used for reads. Keep the Primary’s active key listed first on both clusters until rotation completes to prevent each cluster from encrypting with different keys. +> Note: Replace placeholders with your own randomly generated 32‑byte keys encoded in base64. Do not reuse example values.
🧹 Nitpick comments (7)
docs/en/install/global_dr.mdx (7)
30-31: Fix grammar in node-naming guidance.“to indicates” → “to indicate”.
-* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicates which cluster the node belongs to (Primary or Standby). +* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicate which cluster the node belongs to (Primary or Standby).
63-70: Tighten wording in Process Overview.Minor grammar/flow improvements; no behavior change.
-1. Prepare a unified domain name for platform access; -2. Point the domain to the **Primary Cluster's** VIP and install the **Primary Cluster**; -3. Temporarily switch DNS resolution to the standby VIP to install the Standby Cluster; -4. Copy the ETCD encryption key of the **Primary Cluster** to the nodes that will later be the control plane nodes of Standby Cluster; -5. Install and enable the etcd synchronization plugin; -6. Verify sync status and perform regular checks; -7. In case of failure, switch DNS to the standby cluster to complete disaster recovery. +1. Prepare a unified domain for platform access. +2. Point the domain to the **Primary Cluster** VIP and install the **Primary Cluster**. +3. Temporarily switch DNS to the standby VIP to install the Standby Cluster. +4. Copy the etcd encryption key from the **Primary Cluster** to the nodes that will become the Standby control plane. +5. Install and enable the etcd synchronization plugin. +6. Verify sync status and perform regular checks. +7. If the Primary fails, switch DNS to the standby cluster to complete disaster recovery.
82-92: Polish WARNING text; remove “First of all” and tighten phrasing.Improves clarity without changing meaning.
-While installing the primary cluster of the DR (Disaster Recovery Environment), - -* First of all, documenting all of the parameters set while following the guide of the installation web UI. It is necessary to keep some options the same while installing the standby cluster. +While installing the primary cluster of the DR (Disaster Recovery Environment), + +* Record all parameters set in the installation UI. Some options must match when installing the standby cluster. @@ -* The `Self-signed Certificate` option is NOT available. It is NECESSARY for both of the clusters to be configured with `An Existing Certificate`. +* The `Self-signed Certificate` option is NOT available. Both clusters MUST use `An Existing Certificate`. @@ -* The `Other Platform Access Addresses` option, which is at the second page of the installation web UI (Named `Advanced`), MUST include the virtual IP of the primary cluster. +* On the `Advanced` page, the `Other Platform Access Addresses` option MUST include the Primary cluster VIP.
115-116: Add punctuation and consistency.-3. Install the standby cluster in the same way as the primary cluster +3. Install the standby cluster in the same way as the primary cluster.
117-127: Clarify “same as primary” list and tighten grammar.-While installing the standby cluster of the DR (Disaster Recovery Environment), +While installing the standby cluster of the DR (Disaster Recovery Environment), @@ -the following options MUST be set to the same as the **primary cluster**: -* The options about `Platform Access Address`. -* The options about `Certificate`. -* The options about `Image Repository`. It is IMPORTANT to make sure the credentials of image repository are the same of the **primary cluster**. +Set the following options to match the **Primary Cluster** exactly: +* `Platform Access Address` +* `Certificate` +* `Image Repository` (including credentials)
249-253: IPv6-safe Routine Check (align with Step 3).The simple curl against ClusterIP will fail on IPv6 without brackets. Reuse the IPv6-safe snippet used earlier.
-curl $(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}')/check +mirror_svc=$(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}') +if [[ $mirror_svc =~ ^[0-9a-fA-F:]+$ ]]; then mirror_svc="[$mirror_svc]"; fi +curl "$mirror_svc/check"
57-58: Clarify image registry note.If registries differ, explicitly state uploads must target each registry endpoint.
-* If both clusters are set to use built-in image registries, container images must be uploaded separately to each; +* If both clusters use built-in image registries, upload container images to each cluster’s registry separately (they are not shared).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(4 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/en/install/global_dr.mdx
[grammar] ~63-~63: There might be a mistake here.
Context: ...unified domain name for platform access; 2. Point the domain to the **Primary Cluste...
(QB_NEW_EN)
[grammar] ~64-~64: There might be a mistake here.
Context: ...VIP and install the Primary Cluster; 3. Temporarily switch DNS resolution to the...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...ndby VIP to install the Standby Cluster; 4. Copy the ETCD encryption key of the **Pr...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...t will later be the control plane nodes of Standby Cluster; 5. Install and enable ...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ... control plane nodes of Standby Cluster; 5. Install and enable the etcd synchronizat...
(QB_NEW_EN)
[grammar] ~67-~67: There might be a mistake here.
Context: ... enable the etcd synchronization plugin; 6. Verify sync status and perform regular c...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ... sync status and perform regular checks; 7. In case of failure, switch DNS to the st...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...te key for serving HTTPS on that domain; * A dedicated virtual IP address for each ...
(QB_NEW_EN)
[style] ~85-~85: Often, this adverbial phrase is redundant. Consider using an alternative.
Context: ... DR (Disaster Recovery Environment), * First of all, documenting all of the parameters set ...
(FIRST_OF_ALL)
[style] ~85-~85: Consider removing “of” to be more concise
Context: ...ironment), * First of all, documenting all of the parameters set while following the guid...
(ALL_OF_THE)
[grammar] ~86-~86: There might be a mistake here.
Context: ... routing traffic sent to the virtual IP. * The Platform Access Address MUST be a ...
(QB_NEW_EN)
[grammar] ~87-~87: There might be a mistake here.
Context: ...ndpointMUST be the virtual IP address. * TheSelf-signed Certificate` option is ...
(QB_NEW_EN)
[grammar] ~96-~96: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
[grammar] ~123-~123: There might be a mistake here.
Context: ... to the same as the primary cluster: * The options about `Platform Access Addre...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ...options about Platform Access Address. * The options about Certificate. * The o...
(QB_NEW_EN)
[grammar] ~126-~126: There might be a mistake here.
Context: ... IMPORTANT to make sure the credentials of image repository are the same of the **...
(QB_NEW_EN)
[grammar] ~131-~131: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
299-299: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🔇 Additional comments (1)
docs/en/install/global_dr.mdx (1)
269-269: Ensure sudo and quoting on remote read (already correct) — LGTM.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (6)
docs/en/install/global_dr.mdx (6)
331-342: Simplify kube‑apiserver restart on node 1.1.1.1.Avoid force‑removing containers; kubelet restart is enough for static pods.
- _pod_name="kube-apiserver" - _pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod `kube-apiserver` on node $(hostname)" - exit 1 - fi - sudo crictl rm --force "${_pod_id}" - sudo systemctl restart kubelet.service + sudo systemctl restart kubelet.service
133-133: Reinforce etcd exposure risk and L4 requirement.Mention restriction and pass‑through here as well for operators who skim steps.
-1. Configure the load balancer to forward port `2379` to control plane nodes of the corresponding cluster. ONLY TCP mode is supported; forwarding on L7 is not supported. +1. Configure the load balancer to forward port `2379` to control‑plane nodes of the corresponding cluster. Use pure L4 TCP pass‑through (no L7/TLS termination), and never expose `2379` publicly—restrict access to control‑plane/LB addresses only.
188-204: Re-run verification after Elasticsearch restart.The text says “then execute the script again,” but it isn’t re-run post‑restart.
- # In case the script returned the 401 error, restart Elasticsearch - # then execute the script to check the cluster again - bash /root/ensure-asm-template.sh - - # Restart Elasticsearch - xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + # If the script returns 401, restart Elasticsearch and then re-run the script + bash /root/ensure-asm-template.sh + # Restart Elasticsearch + xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + # Re-run the check after pods restart + bash /root/ensure-asm-template.sh
259-299: Replace real-looking Base64 secrets with placeholders and add disclaimers; document key-order semantics.These literals trigger secret scanners and risk accidental reuse; also call out “first key writes” rule.
@@ - - name: key1 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY> @@ - - name: key1 - secret: My.1415926535897 - - name: key2 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_PRIMARY_EXAMPLE_ONLY> + - name: key2 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY> + +> Note: Replace placeholders with your own randomly generated 32‑byte keys encoded in base64. Do not reuse example values. + +Important: The first key in the list is used for writes; all keys are used for reads. Keep the Primary’s active key listed first on both clusters until rotation completes to avoid divergence.
301-329: Harden remote update: avoid brittle crictl usage, fix quoting, keep perms 600, and just restart kubelet.Single‑quoted SSH block is fine here, but the crictl container removal is unnecessary risk. A kubelet restart is sufficient to pick up the updated static‑pod config.
- for i in \ + for i in \ 2.2.2.2 3.3.3.3 \ 4.4.4.4 5.5.5.5 6.6.6.6 \ ; do scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" - ssh "<user>@${i}" ' - #!/bin/bash - set -euo pipefail - - sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf - _pod_name="kube-apiserver" - _pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod `kube-apiserver` on node $(hostname)" - exit 1 - fi - sudo crictl rm --force "${_pod_id}" - sudo systemctl restart kubelet.service - ' + ssh "<user>@${i}" "bash -s" <<'REMOTE' +set -euo pipefail +sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf +rm -f /tmp/encryption-provider.conf +sudo systemctl restart kubelet.service +REMOTE done
73-76: Add explicit etcd (2379) security caveat under LB requirements.Do not expose 2379 publicly; require pure L4 pass‑through.
* Preconfigure the load balancer to route TCP traffic on ports `80`, `443`, `6443`, `2379`, and `11443` to the control-plane nodes behind the corresponding VIP. + * Security: Never expose port `2379` (etcd) to the public internet. Restrict access to control‑plane/LB addresses only and ensure pure L4 TCP pass‑through (no TLS termination/L7 inspection).
🧹 Nitpick comments (3)
docs/en/install/global_dr.mdx (3)
30-31: Fix grammar in node-naming guidance.“to indicates” → “to indicate”.
-* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicates which cluster the node belongs to (Primary or Standby). +* To facilitate troubleshooting and management, name nodes like `standby-global-m1` to indicate which cluster the node belongs to (Primary or Standby).
57-58: Clarify target of “each”.Be explicit that images must be uploaded to each cluster.
-* If both clusters are set to use built-in image registries, container images must be uploaded separately to each; +* If both clusters use built‑in image registries, upload container images to each cluster separately;
115-124: Polish punctuation and consistency; clarify credential parity.Minor grammar fixes and clearer intent.
-3. Install the standby cluster in the same way as the primary cluster +3. Install the standby cluster in the same way as the primary cluster. @@ -* All fields of `Image Repository` -* Important: ensure the credentials of image repository and the ACP admin user match those set on the **Primary Cluster**. +* All fields of `Image Repository`. +* Important: ensure the image‑repository credentials and the ACP admin user credentials match those on the **Primary Cluster**.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(4 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/en/install/global_dr.mdx
[style] ~85-~85: Often, this adverbial phrase is redundant. Consider using an alternative.
Context: ... DR (Disaster Recovery Environment), * First of all, documenting all of the parameters set ...
(FIRST_OF_ALL)
[style] ~85-~85: Consider removing “of” to be more concise
Context: ...ironment), * First of all, documenting all of the parameters set while following the guid...
(ALL_OF_THE)
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
296-296: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/en/install/global_dr.mdx (1)
135-141: Call out access restrictions explicitly for 2379.Add “do not expose publicly” guidance next to the instruction.
-1. Configure the load balancer to forward port `2379` to control plane nodes of the corresponding cluster. ONLY TCP mode is supported; forwarding on L7 is not supported. +1. Configure the load balancer to forward port `2379` to the control‑plane nodes of the corresponding cluster. ONLY TCP (L4) is supported; L7 is not supported. Do NOT expose `2379` publicly—restrict access to control‑plane/LB addresses only.
♻️ Duplicate comments (6)
docs/en/install/global_dr.mdx (6)
190-206: Re-run the ES check after restarting pods.Your text says to re-run, but the snippet doesn’t. Add the second invocation after the delete.
- # In case the script returned the 401 error, restart Elasticsearch - # then execute the script to check the cluster again - bash /root/ensure-asm-template.sh + # If the script returns 401, restart Elasticsearch and then re-run the check + bash /root/ensure-asm-template.sh @@ - xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + # Re-run after pods restart + bash /root/ensure-asm-template.sh
281-301: Replace real-looking Base64 secrets with placeholders and add key-order note.Secret scanners will flag these; avoid accidental reuse. Also call out that the first key is used for writes.
- - name: key1 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>- - name: key1 - secret: My4xNDE1OTI2NTM1ODk3 - - name: key2 - secret: MTE0NTE0MTkxOTgxMA== + - name: key1 + secret: <BASE64_32_BYTE_KEY_FROM_PRIMARY_EXAMPLE_ONLY> + - name: key2 + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>+> Note: Replace placeholders with your own 32‑byte keys encoded in base64. Do not reuse example values. + +Important: The first key in the list is used for writes. Keep the Primary’s key first on both clusters to avoid each cluster encrypting with different keys. Rotate by reordering and re‑encrypting during a planned window only.
73-77: Add mandatory security caveat for etcd (2379) at the LB requirement.Do not expose 2379; require pure L4 pass-through.
* A dedicated virtual IP address for each cluster — one for the **Primary Cluster** and another for the Standby Cluster; * Preconfigure the load balancer to route TCP traffic on ports `80`, `443`, `6443`, `2379`, and `11443` to the control-plane nodes behind the corresponding VIP. + * Security: Never expose `2379` (etcd) to the public internet. Restrict L4 access to control‑plane/LB addresses only and use TCP pass‑through (no TLS termination or L7 inspection).
333-344: Single-node restart: simplify to kubelet restart (avoid crictl).Same rationale as above; kubelet will recreate the apiserver static pod.
-_pod_name="kube-apiserver" -_pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) -if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod `kube-apiserver` on node $(hostname)" - exit 1 -fi -sudo crictl rm --force "${_pod_id}" -sudo systemctl restart kubelet.service +sudo systemctl restart kubelet.service
303-331: Remote restart sequence: drop brittle crictl usage; just restart kubelet.Static pods are recreated by kubelet; removing containers is unnecessary and can fail. Also avoid single-quoted here-script; use a heredoc.
- scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" - ssh "<user>@${i}" ' - #!/bin/bash - set -euo pipefail - - sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf - _pod_name="kube-apiserver" - _pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod `kube-apiserver` on node $(hostname)" - exit 1 - fi - sudo crictl rm --force "${_pod_id}" - sudo systemctl restart kubelet.service - ' + scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" + ssh "<user>@${i}" "bash -s" <<'REMOTE' +set -euo pipefail +sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf +rm -f /tmp/encryption-provider.conf +sudo systemctl restart kubelet.service +REMOTE
82-92: Rewrite WARNING block for grammar and precision.Fix awkward phrasing (“First of all…”, “has be”, “the of the installation guide”).
-<Directive type="warning" title="NOTES OF DR (Disaster Recovery Environment) INSTALLING"> -While installing the primary cluster of the DR Environment, - -* First of all, documenting all of the parameters set while following the guide of the installation web UI. It is necessary to keep some options the same while installing the standby cluster. -* A **User-provisioned** Load Balancer MUST be preconfigured to route traffic sent to the virtual IP. The `Self-built VIP` option is NOT available. -* The `Platform Access Address` field MUST be a domain, while the `Cluster Endpoint` MUST be the virtual IP address. -* Both clusters MUST be configured to use `An Existing Certificate` (has be the same one), request a legit certificate if necessary. The `Self-signed Certificate` option is NOT available. -* When `Image Repository` is set to `Platform Deployment`, both `Username` and `Password` fields MUST NOT be empty; The `IP/Domain` field MUST be set to the domain used as the `Platform Access Address`. -* Both `HTTP Port` and `HTTPS Port` fields of `Platform Access Address` MUST be 80 and 443. -* When coming to the second page the of the installation guide (Step: `Advanced`), the `Other Platform Access Addresses` field MUST include the virtual IP of current Cluster. -</Directive> +<Directive type="warning" title="NOTES FOR INSTALLING DR PRIMARY"> +Record all parameters you set in the installer UI; you will reuse the same values when installing the standby cluster. + +* A **User‑provisioned** Load Balancer MUST be preconfigured to route traffic to the VIP. The `Self‑built VIP` option is NOT available. +* The `Platform Access Address` MUST be a domain, and the `Cluster Endpoint` MUST be the VIP. +* Both clusters MUST use `An Existing Certificate` (the same certificate). Request a valid certificate if necessary. The `Self‑signed Certificate` option is NOT available. +* If `Image Repository` is `Platform Deployment`, `Username` and `Password` MUST be set, and `IP/Domain` MUST be the `Platform Access Address` domain. +* `Platform Access Address` ports MUST be `80` and `443`. +* On the `Advanced` step, the `Other Platform Access Addresses` field MUST include the current cluster’s VIP. +</Directive>
🧹 Nitpick comments (5)
docs/en/install/global_dr.mdx (5)
30-31: Grammar: fix “to indicates” and tighten the sentence.Clearer wording; subject-verb agreement.
-* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicates which cluster the node belongs to (Primary or Standby). +* To facilitate troubleshooting and management, name nodes like `standby-global-m1` to indicate which cluster the node belongs to (Primary or Standby).
63-70: Polish step wording for consistency and clarity.Align tense/grammar; clarify what becomes control plane for Standby.
-2. Point the domain to the **Primary Cluster's** VIP and install the **Primary Cluster**; -3. Temporarily switch DNS resolution to the standby VIP to install the Standby Cluster; -4. Copy the ETCD encryption key of the **Primary Cluster** to the nodes that will later be the control plane nodes of Standby Cluster; -5. Install and enable the etcd synchronization plugin; -6. Verify sync status and perform regular checks; -7. In case of failure, switch DNS to the standby cluster to complete disaster recovery. +2. Point the domain to the **Primary Cluster** VIP and install the **Primary Cluster**. +3. Temporarily switch DNS to the Standby VIP and install the **Standby Cluster**. +4. Copy the ETCD encryption key from the **Primary Cluster** to the nodes that will become the **Standby Cluster** control plane. +5. Install and enable the etcd synchronization plugin. +6. Verify sync status and perform regular checks. +7. If a failure occurs, switch DNS to the **Standby Cluster** to complete disaster recovery.
115-126: Tighten wording in standby install notes.Parallel phrasing; minor grammar polish.
-<Directive type="warning" title="NOTES FOR INSTALLING STANDBY CLUSTER"> -While installing the standby cluster of the DR Environment, -the following options MUST be set to the same as the **primary cluster**: +<Directive type="warning" title="NOTES FOR INSTALLING STANDBY CLUSTER"> +When installing the standby cluster, set the following options to match the **Primary Cluster**: @@ -* All fields of `Image Repository` -* Important: ensure the credentials of image repository and the ACP admin user match those set on the **Primary Cluster**. +* All fields of `Image Repository`. +* Important: ensure image‑repository credentials and the ACP admin user match the **Primary Cluster**. @@ -and MAKE SURE you followed the `NOTES OF DR (Disaster Recovery Environment) INSTALLING` in Step 1. +Also make sure you followed the “NOTES FOR INSTALLING DR PRIMARY” in Step 1. </Directive>
263-271: FAQ intro: grammar and clarity.Tighten wording and casing.
-* Here are the instructions in case that the ETCD encryption key of the standby cluster has not synced with the one of **primary cluster** before Installing the standby cluster. +* If the standby cluster’s ETCD encryption key was not synced with the **Primary Cluster** before installing the standby cluster, follow these steps.
258-259: Minor: show a concrete violet example with --dest-repo.Optional but helpful to prevent misuploads.
-When using **`violet`** to upload packages to a standby cluster, you must specify the `--dest-repo` parameter with the VIP of the standby cluster. +When using **`violet`** to upload packages to a standby cluster, specify `--dest-repo` with the standby VIP, for example: +`violet upload --dest-repo https://<standby_vip> ...`
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(4 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/en/install/global_dr.mdx
[grammar] ~63-~63: There might be a mistake here.
Context: ...unified domain name for platform access; 2. Point the domain to the **Primary Cluste...
(QB_NEW_EN)
[grammar] ~64-~64: There might be a mistake here.
Context: ...VIP and install the Primary Cluster; 3. Temporarily switch DNS resolution to the...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...ndby VIP to install the Standby Cluster; 4. Copy the ETCD encryption key of the **Pr...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...t will later be the control plane nodes of Standby Cluster; 5. Install and enable ...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ... control plane nodes of Standby Cluster; 5. Install and enable the etcd synchronizat...
(QB_NEW_EN)
[grammar] ~67-~67: There might be a mistake here.
Context: ... enable the etcd synchronization plugin; 6. Verify sync status and perform regular c...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ... sync status and perform regular checks; 7. In case of failure, switch DNS to the st...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...te key for serving HTTPS on that domain; * A dedicated virtual IP address for each ...
(QB_NEW_EN)
[style] ~85-~85: Often, this adverbial phrase is redundant. Consider using an alternative.
Context: ...imary cluster of the DR Environment, * First of all, documenting all of the parameters set ...
(FIRST_OF_ALL)
[style] ~85-~85: Consider removing “of” to be more concise
Context: ...vironment, * First of all, documenting all of the parameters set while following the guid...
(ALL_OF_THE)
[grammar] ~89-~89: There might be a mistake here.
Context: ...n used as the Platform Access Address. * Both HTTP Port and HTTPS Port fields...
(QB_NEW_EN)
[grammar] ~91-~91: There might be a mistake here.
Context: ...sses` field MUST include the virtual IP of current Cluster. Refer to...
(QB_NEW_EN)
[grammar] ~96-~96: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
[grammar] ~130-~130: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
298-298: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🔇 Additional comments (1)
docs/en/install/global_dr.mdx (1)
101-112: Copy/perm flow looks solid.Uses sudo, temp path, and 600 perms; good hardening.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (8)
docs/en/install/global_dr.mdx (8)
82-92: Rewrite warning directive for clarity and grammar.Improves readability; keeps semantics unchanged.
-<Directive type="warning" title="NOTES OF DR (Disaster Recovery Environment) INSTALLING"> -While installing the primary cluster of the DR Environment, - -* First of all, documenting all of the parameters set while following the guide of the installation web UI. It is necessary to keep some options the same while installing the standby cluster. -* A **User-provisioned** Load Balancer MUST be preconfigured to route traffic sent to the virtual IP. The `Self-built VIP` option is NOT available. -* The `Platform Access Address` field MUST be a domain, while the `Cluster Endpoint` MUST be the virtual IP address. -* Both clusters MUST be configured to use `An Existing Certificate` (has be the same one), request a legit certificate if necessary. The `Self-signed Certificate` option is NOT available. -* When `Image Repository` is set to `Platform Deployment`, both `Username` and `Password` fields MUST NOT be empty; The `IP/Domain` field MUST be set to the domain used as the `Platform Access Address`. -* Both `HTTP Port` and `HTTPS Port` fields of `Platform Access Address` MUST be 80 and 443. -* When coming to the second page the of the installation guide (Step: `Advanced`), the `Other Platform Access Addresses` field MUST include the virtual IP of current Cluster. +<Directive type="warning" title="DR (Disaster Recovery) installation notes"> +When installing the Primary cluster: + +* Record all parameters set in the installer UI; you will reuse them when installing the Standby cluster. +* A user‑provisioned load balancer MUST route traffic to the VIP. The `Self-built VIP` option is NOT available. +* `Platform Access Address` MUST be a domain; `Cluster Endpoint` MUST be the VIP. +* Both clusters MUST use `An Existing Certificate` (the same certificate). Request a valid certificate if necessary. `Self-signed Certificate` is NOT available. +* If `Image Repository` is `Platform Deployment`, `Username` and `Password` MUST be set; `IP/Domain` MUST be the `Platform Access Address` domain. +* `HTTP Port` and `HTTPS Port` MUST be 80 and 443. +* On the `Advanced` step, `Other Platform Access Addresses` MUST include the Primary cluster VIP. </Directive>
135-141: Add explicit security warning for 2379 here as well.Prevent accidental public exposure; require L4 pass‑through.
-1. Configure the load balancer to forward port `2379` to control plane nodes of the corresponding cluster. ONLY TCP mode is supported; forwarding on L7 is not supported. +1. Configure the load balancer to forward port `2379` to control‑plane nodes of the corresponding cluster. ONLY L4 TCP pass‑through is supported (no TLS termination/L7). + Security: Never expose `2379` publicly; restrict to control‑plane/LB addresses via firewall/ACL allow‑lists.
190-209: Re-run the ES check after restart (missing).Docs say “restart then execute the script again,” but the snippet doesn’t re-run it.
# Restart Elasticsearch xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}" + # Re-run the check after pods restart + bash /root/ensure-asm-template.sh
73-77: Add security caveat for etcd (2379) and clarify LB requirements.Exposing 2379 is high risk; enforce L4 pass‑through and allow‑listing.
-* A unified domain which will be the `Platform Access Address`, and the TLS certificate plus private key for serving HTTPS on that domain; -* A dedicated virtual IP address for each cluster — one for the **Primary Cluster** and another for the Standby Cluster; - - * Preconfigure the load balancer to route TCP traffic on ports `80`, `443`, `6443`, `2379`, and `11443` to the control-plane nodes behind the corresponding VIP. +* A unified domain for the `Platform Access Address`, with a TLS certificate and private key for that domain. +* A dedicated virtual IP address for each cluster — one for the **Primary Cluster** and one for the **Standby Cluster**. + + * Preconfigure the load balancer to route TCP traffic on ports `80`, `443`, `6443`, `2379`, and `11443` to the control‑plane nodes behind the corresponding VIP. + * Security: Never expose port `2379` (etcd) to the public internet. Restrict access to control‑plane/LB addresses via network ACLs/allow‑lists, and use pure L4 TCP pass‑through (no TLS termination or L7 inspection).
276-288: Replace real-looking Base64 secret with a placeholder and add disclaimer.Avoid secret‑scanner hits and accidental reuse.
- name: key1 - secret: MTE0NTE0MTkxOTgxMA== + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>Add immediately below the YAML:
+> Note: Replace placeholders with your own randomly generated 32‑byte keys encoded in base64. Do not reuse example values. +> Important: Kubernetes writes with the first key and reads with all. Keep the Primary’s key listed first on both clusters until rotation completes to avoid dual‑write divergence.
291-304: Replace both Base64 secrets with placeholders and call out key‑order semantics.Two literal secrets remain; also document “first key writes” rule.
- name: key1 - secret: My4xNDE1OTI2NTM1ODk3 + secret: <BASE64_32_BYTE_KEY_FROM_PRIMARY_EXAMPLE_ONLY> - name: key2 - secret: MTE0NTE0MTkxOTgxMA== + secret: <BASE64_32_BYTE_KEY_FROM_STANDBY_EXAMPLE_ONLY>Add immediately below the YAML (if not already added above):
+> Note: Replace placeholders with your own randomly generated 32‑byte keys encoded in base64. Do not reuse example values. +> Important: The first key is used for writes. Keep the Primary’s key first on both clusters until rotation is finalized.
306-334: Remote script: brittle crictl usage, improper backticks, and quoting. Simplify to restart kubelet.Backticks in the echo will try to execute
kube-apiserver. Use a here‑doc, drop crictl, and just restart kubelet after installing the file.- ; do - scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" - ssh "<user>@${i}" ' - #!/bin/bash - set -euo pipefail - - sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf - _pod_name="kube-apiserver" - _pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) - if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod `kube-apiserver` on node $(hostname)" - exit 1 - fi - sudo crictl rm --force "${_pod_id}" - sudo systemctl restart kubelet.service - ' - done + ; do + scp /etc/kubernetes/encryption-provider.conf "<user>@${i}:/tmp/encryption-provider.conf" + ssh "<user>@${i}" "bash -s" <<'REMOTE' +set -euo pipefail +sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf +rm -f /tmp/encryption-provider.conf +# Restart kubelet to reload the static pod +sudo systemctl restart kubelet.service +REMOTE + done
336-347: Single‑node restart: same crictl/backticks issues—restart kubelet only.Mirror the simplified approach; remove backticks.
-_pod_name="kube-apiserver" -_pod_id=$(sudo crictl ps --name "${_pod_name}" --no-trunc --quiet) -if [[ -z "${_pod_id}" ]]; then - echo "FATAL: could not find pod `kube-apiserver` on node $(hostname)" - exit 1 -fi -sudo crictl rm --force "${_pod_id}" -sudo systemctl restart kubelet.service +sudo systemctl restart kubelet.service
🧹 Nitpick comments (4)
docs/en/install/global_dr.mdx (4)
30-31: Grammar: “to indicates” → “to indicate”.Minor fix for readability.
-* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicates which cluster the node belongs to (Primary or Standby). +* In favor of facilitating troubleshooting and management, it is recommended to name nodes in a style like `standby-global-m1`, to indicate which cluster the node belongs to (Primary or Standby).
63-69: Tighten step wording and punctuation.Make the overview steps parallel and concise.
-1. Prepare a unified domain name for platform access; -2. Point the domain to the **Primary Cluster's** VIP and install the **Primary Cluster**; -3. Temporarily switch DNS resolution to the standby VIP to install the Standby Cluster; -4. Copy the ETCD encryption key of the **Primary Cluster** to the nodes that will later be the control plane nodes of Standby Cluster; -5. Install and enable the etcd synchronization plugin; -6. Verify sync status and perform regular checks; -7. In case of failure, switch DNS to the standby cluster to complete disaster recovery. +1. Prepare a unified domain name for platform access. +2. Point the domain to the **Primary Cluster** VIP and install the **Primary Cluster**. +3. Temporarily point the domain to the standby VIP and install the **Standby Cluster**. +4. Copy the **Primary Cluster** ETCD encryption key to the nodes that will become the standby control plane. +5. Install and enable the etcd synchronization plugin. +6. Verify sync status and perform routine checks. +7. On failure, switch DNS to the standby cluster to complete disaster recovery.
115-126: Tone and consistency in standby notes.Normalize emphasis and punctuation; avoid “MAKE SURE”.
-<Directive type="warning" title="NOTES FOR INSTALLING STANDBY CLUSTER"> -While installing the standby cluster of the DR Environment, -the following options MUST be set to the same as the **primary cluster**: +<Directive type="warning" title="Standby cluster installation notes"> +While installing the standby cluster, set the following to match the **Primary Cluster**: @@ -* All fields of `Image Repository` -* Important: ensure the credentials of image repository and the ACP admin user match those set on the **Primary Cluster**. +* All fields of `Image Repository`. +* Important: ensure the image‑repository credentials and the ACP admin user credentials match those on the **Primary Cluster**. @@ -and MAKE SURE you followed the `NOTES OF DR (Disaster Recovery Environment) INSTALLING` in Step 1. +Ensure you followed the DR installation notes in Step 1. </Directive>
270-273: Quote placeholders and use consistent casing.Minor: quote the SSH command and standardize the placeholder name.
-ssh <user>@<STANDBY cluster control plane node> sudo cat /etc/kubernetes/encryption-provider.conf +ssh "<user>@<standby_control_plane_node>" "sudo cat /etc/kubernetes/encryption-provider.conf"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docs/en/install/global_dr.mdx(4 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/en/install/global_dr.mdx
[grammar] ~63-~63: There might be a mistake here.
Context: ...unified domain name for platform access; 2. Point the domain to the **Primary Cluste...
(QB_NEW_EN)
[grammar] ~64-~64: There might be a mistake here.
Context: ...VIP and install the Primary Cluster; 3. Temporarily switch DNS resolution to the...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...ndby VIP to install the Standby Cluster; 4. Copy the ETCD encryption key of the **Pr...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...t will later be the control plane nodes of Standby Cluster; 5. Install and enable ...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ... control plane nodes of Standby Cluster; 5. Install and enable the etcd synchronizat...
(QB_NEW_EN)
[grammar] ~67-~67: There might be a mistake here.
Context: ... enable the etcd synchronization plugin; 6. Verify sync status and perform regular c...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ... sync status and perform regular checks; 7. In case of failure, switch DNS to the st...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...te key for serving HTTPS on that domain; * A dedicated virtual IP address for each ...
(QB_NEW_EN)
[style] ~85-~85: Often, this adverbial phrase is redundant. Consider using an alternative.
Context: ...imary cluster of the DR Environment, * First of all, documenting all of the parameters set ...
(FIRST_OF_ALL)
[style] ~85-~85: Consider removing “of” to be more concise
Context: ...vironment, * First of all, documenting all of the parameters set while following the guid...
(ALL_OF_THE)
[grammar] ~89-~89: There might be a mistake here.
Context: ...n used as the Platform Access Address. * Both HTTP Port and HTTPS Port fields...
(QB_NEW_EN)
[grammar] ~91-~91: There might be a mistake here.
Context: ...sses` field MUST include the virtual IP of current Cluster. Refer to...
(QB_NEW_EN)
[grammar] ~96-~96: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
[grammar] ~130-~130: There might be a mistake here.
Context: ...stallation: * Prepare for Installation * Installing ### Step ...
(QB_NEW_EN)
🪛 Gitleaks (8.27.2)
docs/en/install/global_dr.mdx
301-301: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🔇 Additional comments (1)
docs/en/install/global_dr.mdx (1)
101-113: Secure copy and perms look good.Use of sudo and mode 600 avoids key exposure; temp file cleanup is correct.
* feat: introduce FAQ for installation of Global DR
* chore: instructions on restarting ES
* chore: refine the prerequisites of LB part
* chore: favored style of naming nodes
* feat: Strong warnings about the MUST-DO while installing the DR env
* chore: apply suggestions of coderabbitai
* fix: typo
* security: restrict file permission of encryption-provider.conf
* fix: Wording is awkward 🥹
* fix: ${i} won’t expand
* chore: wordy
* fix: avoid indistinct instructions
* fix: redundant instructions; reword
* fix: ensure the admin usr of standby cluster is set to the same
* fix: bug
* fix: switch to the root user
* fix: notes of etcd backup task when upgrading from 3.16 to 4.0 * chore: preparing for release 4.0.4 * feat: introduce FAQ for installation of Global DR (#157) * feat: introduce FAQ for installation of Global DR * chore: instructions on restarting ES * chore: refine the prerequisites of LB part * chore: favored style of naming nodes * feat: Strong warnings about the MUST-DO while installing the DR env * chore: apply suggestions of coderabbitai * fix: typo * security: restrict file permission of encryption-provider.conf * fix: Wording is awkward 🥹 * fix: ${i} won’t expand * chore: wordy * fix: avoid indistinct instructions * fix: redundant instructions; reword * fix: ensure the admin usr of standby cluster is set to the same * fix: bug * fix: switch to the root user
* feat: introduce FAQ for installation of Global DR
* chore: instructions on restarting ES
* chore: refine the prerequisites of LB part
* chore: favored style of naming nodes
* feat: Strong warnings about the MUST-DO while installing the DR env
* chore: apply suggestions of coderabbitai
* fix: typo
* security: restrict file permission of encryption-provider.conf
* fix: Wording is awkward 🥹
* fix: ${i} won’t expand
* chore: wordy
* fix: avoid indistinct instructions
* fix: redundant instructions; reword
* fix: ensure the admin usr of standby cluster is set to the same
* fix: bug
* fix: switch to the root user
* feat: introduce FAQ for installation of Global DR
* chore: instructions on restarting ES
* chore: refine the prerequisites of LB part
* chore: favored style of naming nodes
* feat: Strong warnings about the MUST-DO while installing the DR env
* chore: apply suggestions of coderabbitai
* fix: typo
* security: restrict file permission of encryption-provider.conf
* fix: Wording is awkward 🥹
* fix: ${i} won’t expand
* chore: wordy
* fix: avoid indistinct instructions
* fix: redundant instructions; reword
* fix: ensure the admin usr of standby cluster is set to the same
* fix: bug
* fix: switch to the root user
Summary by CodeRabbit