Skip to content

运维与维护 ​

< 上一页:节点生命周期管理 | 目录 | 下一页:裸机操作系统设置 >

验证基线:nodeadm 1.0.20;Cilium 1.18.3 CRD;Prometheus Operator 0.94.1;kube-prometheus-stack 92.9.0;Harbor 2.15.4。这些是经过审查的参考版本,并非通用的受支持版本矩阵。 最后更新:October 18, 2026

本文介绍 EKS Hybrid Nodes 环境的日常运维和维护任务,包括监控、备份流程和故障排查。

Harbor 漏洞扫描自动化 ​

使用 Harbor 内置的全量扫描计划任务,而不要使用携带管理员密码且只枚举最新标签的 CronJob。在系统管理员 UI 中,打开 Administration → Interrogation Services → Vulnerability → Schedule to scan all。支持 Hourly/Daily/Weekly/Custom 计划;文档所述 UI 中,Daily 表示午夜。对于 02:00 维护时段,请确认已部署版本的 Custom 计划语法、时区和下次执行时间。

Harbor 2.15.4 提供 GET/POST/PUT /api/v2.0/system/scanAll/schedule。请使用 UI,或使用经批准的 API 集成,并进行受信任 CA 验证、保护凭证且具备所需的系统级权限。项目 robot 权限并不意味着有权配置全局扫描。不要将管理员密码放在 Pod 环境变量/命令参数中,也不要禁用 TLS 验证。

记录扫描器可用性、漏洞数据库新鲜度、实际扫描完成情况和失败情况。提交请求或收到空 API 响应并不代表漏洞评估成功。不受支持的制品需要单独处理,全局扫描会消耗资源。针对选定制品的自动化必须枚举所有所需分页和摘要、正确编码仓库路径并检查每个响应;仅扫描最新标签的循环无法覆盖整个 registry。

请参阅 Harbor 指南和官方计划流程。

数据库备份流程 ​

在复制数据之前,先确定恢复目标并编制清单。Harbor 恢复需要兼容的数据库元数据、registry blob/对象存储、配置以及受保护的机密/加密密钥。仅转储 PostgreSQL 并不是完整备份。现代 Harbor 已不再包含 Notary v1;不要假设 notarysigner/notaryserver 数据库存在。

官方 Harbor Velero 流程使用仓库只读模式和选定的 Kubernetes 资源/PV。其备份是崩溃一致性,而非应用一致性,不包括 Redis,可能丢失未同步的元数据/会话,并可能留下需要修复的任务。它涵盖内部数据库,不涵盖外部托管数据库。请选择受支持的快照/文件备份/数据移动插件,并确认恢复站点能够访问所有所需的卷/对象数据;仅有快照引用不一定是可移植副本。

以下仅为已验证的内部 PostgreSQL Pod 的数据库组件转储示例,其中 pg_dump/pg_restore 和本地身份验证已配置完成。外部数据库应使用各自经过身份验证的备份/恢复流程。命令参数中不会传递凭证。发生错误时立即停止并妥善保护部分输出;不要将其作为已完成的转储发布。

bash
set -euo pipefail
umask 077
: "${KUBE_CONTEXT:?Set the approved cluster context}"
: "${HARBOR_NAMESPACE:?Set the Harbor namespace}"
: "${HARBOR_DB_POD:?Set the verified internal PostgreSQL Pod}"
: "${HARBOR_DB_USER:?Set the approved backup database user}"
: "${HARBOR_DB_NAME:?Set the actual Harbor database name}"
: "${PRIVATE_BACKUP_ROOT:?Set an existing protected durable directory}"
BACKUP_DIR=$(mktemp -d "$PRIVATE_BACKUP_ROOT/harbor-db.XXXXXX")
kubectl --context "$KUBE_CONTEXT" -n "$HARBOR_NAMESPACE" exec "$HARBOR_DB_POD" -- \
  pg_dump --format=custom --username "$HARBOR_DB_USER" --dbname "$HARBOR_DB_NAME" \
  > "$BACKUP_DIR/registry.dump.partial"
test -s "$BACKUP_DIR/registry.dump.partial"
kubectl --context "$KUBE_CONTEXT" -n "$HARBOR_NAMESPACE" exec -i "$HARBOR_DB_POD" -- \
  pg_restore --list < "$BACKUP_DIR/registry.dump.partial" > "$BACKUP_DIR/archive-toc.private.txt"
mv "$BACKUP_DIR/registry.dump.partial" "$BACKUP_DIR/registry.dump"
printf 'Database archive created: %s; full Harbor recovery requires separate evidence.\n' "$BACKUP_DIR"

归档列表不能证明恢复成功。请使用兼容的 PostgreSQL/Harbor 版本测试恢复,并验证制品拉取、元数据、权限和集成。保护/校验完整的备份清单,并协调只读模式、任务及上传/GC 活动。操作失败后,不要未经状态评估就自动取消只读模式。

Redis BGSAVE 是异步的;立即复制 dump.rdb 可能会捕获较旧的版本。如果单独设计中包含 Redis 持久化,请由其运维人员验证完成情况、状态和版本。不要悄然将该自定义设计与不包含 Redis 的官方教程混用。本章未执行任何备份或恢复。

Prometheus 指标采集 ​

请分别处理主机、kubelet/容器和 GPU 指标。node_cpu_seconds_total 和 node_memory_* 来自 Node Exporter,而非 kubelet 端点。使用已安装且经过审查的 Node Exporter/DCGM 配置文件,并验证实际主机挂载、权限、节点放置和指标可用性。Container Insights 不会通过 EC2 IMDS 提供 Hybrid 主机级指标。

以下发现示例使用 kube-prometheus-stack 92.9.0 中 Node Exporter Service 的标签/端口,release 为 monitoring 中的 kube-prom。DCGM 部分假设已验证的 Pod 位于 gpu-operator 中,标签为 app: nvidia-dcgm-exporter,且包含名为 metrics 的容器端口;请根据已安装的 exporter 进行调整。这两种资源都不会安装 exporter。请匹配 Prometheus 资源的 monitor/namespace 选择器,并避免通过现有 monitor 对同一个 exporter 重复抓取。

attachMetadata.node 会使 Node 发现元数据可用;它不会自动将标签复制到指标上。它要求 ServiceMonitor 使用 Prometheus >=2.37,或 PodMonitor 使用 Prometheus >=2.35,并要求 Prometheus 具有对 Node 的 list/watch 权限。重标记会保留实际的 eks.amazonaws.com/compute-type=hybrid 节点,并创建稳定的 node/compute_type 目标标签。不要根据 SSM Node 名称前缀推断 Hybrid 放置位置。

这些示例使用 exporter 受保护的 HTTP 指标端点,而不是 kubelet HTTPS 端点。请限制采集器的连接范围。如果流量经过不受信任的边界,请配置 exporter TLS/身份验证,或使用经过审查的代理及相应的 CA/授权设置;不要使用 insecureSkipVerify。kubelet 抓取应保留在单独配置且经过身份验证和 CA 验证的配置中。

yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: hybrid-node-exporter
  namespace: monitoring
  labels:
    release: kube-prom
spec:
  attachMetadata:
    node: true
  selector:
    matchLabels:
      app.kubernetes.io/name: prometheus-node-exporter
      app.kubernetes.io/instance: kube-prom
  namespaceSelector:
    matchNames: [monitoring]
  endpoints:
  - port: http-metrics
    interval: 30s
    relabelings:
    - sourceLabels: [__meta_kubernetes_node_label_eks_amazonaws_com_compute_type]
      regex: hybrid
      action: keep
    - sourceLabels: [__meta_kubernetes_pod_node_name]
      targetLabel: node
    - targetLabel: compute_type
      replacement: hybrid
---
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: hybrid-gpu-metrics
  namespace: monitoring
  labels:
    release: kube-prom
spec:
  attachMetadata:
    node: true
  selector:
    matchLabels:
      app: nvidia-dcgm-exporter
  namespaceSelector:
    matchNames: [gpu-operator]
  podMetricsEndpoints:
  - port: metrics
    interval: 30s
    relabelings:
    - sourceLabels: [__meta_kubernetes_node_label_eks_amazonaws_com_compute_type]
      regex: hybrid
      action: keep
    - sourceLabels: [__meta_kubernetes_pod_node_name]
      targetLabel: node
    - targetLabel: compute_type
      replacement: hybrid

Grafana 仪表板查询示例 ​

这些查询需要上述目标标签和兼容的 exporter 指标。请验证单位、GPU/MIG 标识、不受支持值/错误哨兵值、抓取缺失情况和重复序列。GPU framebuffer 使用量应除以总容量(used + free),而非空闲容量;零容量序列会被排除。这些查询是可在本地测试的表达式,并非来自此环境的测量结果。

promql
# Host CPU utilization percent
100 * (1 - avg by (node) (rate(node_cpu_seconds_total{mode="idle",compute_type="hybrid"}[5m])))

# Host memory utilization percent
100 * (1 - node_memory_MemAvailable_bytes{compute_type="hybrid"} / node_memory_MemTotal_bytes{compute_type="hybrid"})

# GPU utilization: this metric is already a percentage
DCGM_FI_DEV_GPU_UTIL{compute_type="hybrid"}

# GPU framebuffer usage: used / (used + free), excluding zero capacity
(100 * DCGM_FI_DEV_FB_USED{compute_type="hybrid"} /
 (DCGM_FI_DEV_FB_USED{compute_type="hybrid"} + DCGM_FI_DEV_FB_FREE{compute_type="hybrid"}))
and
((DCGM_FI_DEV_FB_USED{compute_type="hybrid"} + DCGM_FI_DEV_FB_FREE{compute_type="hybrid"}) > 0)

Direct Connect 性能验证 ​

请将测试计划与 AWS 服务保证区分开。之前提到的 RTT <5ms、变化 <2ms、丢包 <0.01% 和吞吐量 >1Gbps 只是示例性规划目标,不是实测结果,也不是 Direct Connect 的普遍承诺。请根据实际位置、电路、端点、工作负载和合同容量选择目标;确认测量流量经过 Direct Connect,而非 VPN 或其他路径。

ping 会报告 ICMP RTT;在 Linux iputils 上还会报告 RTT mdev。该离散度与单向延迟变化或 iperf3 的 UDP 抖动不是同一统计量。ICMP 过滤/降优先级可能不同于应用流量。1000 个数据包的测试中,丢包率每次递增 0.1%;观测到零丢包并不能证明长期丢包率低于 0.01%。

请使用经批准且已运行 iperf3 的私有测试服务器,在协调好的时间窗口内进行测试,设置明确的流量上限,并妥善保存结果。不要对 EKS API 端点运行 iperf3。以下受限示例需要 Bash、Python3、iputils ping、GNU timeout 和支持所示选项的 iperf3。发生故障时会停止后续步骤;缺少工具、JSON 无效或 iperf3 出错均不代表性能测试通过。

bash
set -euo pipefail
umask 077
: "${PROBE_HOST:?Set the approved private test host}"
: "${TEST_BITRATE:?Set an approved traffic cap, for example 10M}"
: "${PRIVATE_RESULTS_ROOT:?Set an existing protected results directory}"
if [[ ! "$TEST_BITRATE" =~ ^[1-9][0-9]*[KMGT]?$ ]]; then
  printf 'TEST_BITRATE must be a positive integer with an optional K/M/G/T suffix.\n' >&2
  exit 2
fi
RUN_DIR=$(mktemp -d "$PRIVATE_RESULTS_ROOT/dx-check.XXXXXX")
date -u +%FT%TZ > "$RUN_DIR/started-at.txt"
LC_ALL=C ping -n -c 100 -W 2 "$PROBE_HOST" > "$RUN_DIR/ping.txt"
timeout 45s iperf3 --client "$PROBE_HOST" --connect-timeout 3000 \
  --time 10 --bitrate "$TEST_BITRATE" --json > "$RUN_DIR/iperf-tcp.json"
python3 - "$RUN_DIR/iperf-tcp.json" <<'PY'
import json, math, sys
with open(sys.argv[1]) as stream:
    result = json.load(stream)
if result.get("error") or not isinstance(result.get("end"), dict):
    raise SystemExit("iperf3 result is incomplete or reports an error")
received = result["end"].get("sum_received", {})
for field in ("bits_per_second", "bytes", "seconds"):
    value = received.get(field)
    if isinstance(value, bool) or not isinstance(value, (int, float)) or not math.isfinite(value) or value < 0:
        raise SystemExit("Missing or invalid TCP receiver statistics")
if received["seconds"] <= 0:
    raise SystemExit("Invalid TCP test duration")
print("Saved a completed iperf3 result; compare receiver statistics with the approved test plan.")
PY
printf 'Private observations: %s; this does not establish an AWS latency/throughput guarantee.\n' "$RUN_DIR"

此限速 TCP 测试无法证明链路的最大容量。请检查接收端吞吐量、重传、方向、持续时间和拥塞情况。对于另行批准的 UDP 测试,请使用 --udp 和明确的比特率,然后保存并解读该版本 JSON 中接收端的丢包/抖动数据。应将失败/跳过的探测记录为失败/跳过。本次审计未执行网络负载测试。

证书续期管理 ​

请明确要检查的是哪种证书:Harbor TLS 服务器证书、其 CA 链、kubelet 服务证书、EKS 控制平面 CA,还是 IAM Roles Anywhere 主机证书。CA 证书有效并不能证明服务器叶证书有效,Node Ready 心跳也不能作为证书到期的证据。EKS 控制平面证书由 AWS 管理;不要将 kubeadm 续期命令作为 EKS 修复流程。

如果证书缺失/不可读/无效,或将在示例中的 30 天警告期限内到期,此本地到期检查会失败。它不会验证证书链、主机名、吊销状态,也不会确认服务实际提供了该证书。请使用下方的已验证 TLS 连接检查服务端点,并参阅凭证生命周期流程续期主机证书。

bash
set -euo pipefail
: "${CERT_PATH:?Set the actual certificate file to inspect}"
test -r "$CERT_PATH"
openssl x509 -in "$CERT_PATH" -checkend 2592000 -noout

跟踪实际颁发者/所有者、配置的证书路径、到期时间和告警投递情况。kubelet 服务端/客户端凭证路径取决于配置;仅启用 serverTLSBootstrap 并不会批准服务证书 CSR,也不会轮换 IAM Roles Anywhere 证书。

Ingress 配置 ​

ALB Ingress(ip 目标模式) ​

自主管理的 AWS Load Balancer Controller 可以通过 alb.ingress.kubernetes.io/target-type: ip 注册可路由的 Hybrid Pod IP。路由、返回流量、安全组/防火墙和 EKS 远程 Pod 网络配置必须保持一致。

AWS 的混合模式 webhook 配方会将 controller 放置在云节点上。这是该设计的放置建议,并不意味着 webhook 一概不能在 Hybrid Nodes 上运行:当控制平面能够访问已配置的远程 Pod CIDR 时,附加组件指南允许将其放置在 Hybrid 节点上。应优先使用肯定式管理放置标签,而不要使用 compute-type NotIn [hybrid],后者也会匹配没有此类标签的节点。以下示例标签只能分配给经过验证的合格云节点。

yaml
# Fragment under the controller Deployment's spec.template.spec:
nodeSelector:
  infrastructure.example.com/location: aws

Cilium Ingress Controller ​

本节中的 Cilium Ingress 和 Gateway API 示例要求启用 L7 的 Cilium 配置。这些示例不适用于配置为 EKS Hybrid Nodes Gateway 的同一 Cilium 安装:其 AWS 要求的 VTEP 配置会设置 vtep.enabled=true 和 l7Proxy=false。启用这些功能前,请先选择网络设计。此限制针对 Cilium 的 L7 代理功能;并不禁止 HTTP 应用使用网关的路由网络路径。

Cilium 1.18.3 上游 Ingress 的先决条件包括 NodePort 支持(或 kube-proxy 替代方案)、L7 代理支持和可用的负载均衡器暴露路径。以下片段并不授权在混合集群中更改云节点的 CNI。请保留经过审查的 Hybrid Cilium 配置,并确认 AWS 对附加功能的支持边界。更改专用/共享模式可能改变地址并中断现有连接。

yaml
# Merge into the reviewed Cilium release values, not a full installation:
nodePort:
  enabled: true
l7Proxy: true
ingressController:
  enabled: true
  loadbalancerMode: dedicated

Cilium Gateway API ​

请安装所选 controller 版本支持的 Gateway API CRD 和资源版本,验证其 NodePort/kube-proxy 替代方案及 L7 先决条件,并检查 GatewayClass/Gateway/Route 状态条件。仅设置一个 Helm 标志既不会安装这些 CRD,也无法建立外部可达性。

yaml
# Required Gateway API CRDs and controller prerequisites must already be met:
gatewayAPI:
  enabled: true

LoadBalancer IPAM(Cilium) ​

以下地址池使用 cilium.io/v2 API,并已根据 1.18.3 CRD 验证,且只选择明确标记的 Service。请将示例 CIDR 替换为网络清单中预留且不重叠的地址范围。IP 分配不会向路由器通告该地址,也不能保证数据路径正常。

yaml
apiVersion: cilium.io/v2
kind: CiliumLoadBalancerIPPool
metadata:
  name: on-prem-pool
spec:
  blocks:
  - cidr: "10.80.100.0/24"
  serviceSelector:
    matchLabels:
      exposure: onprem-bgp

负载均衡 ​

NLB(ip 目标模式) ​

对于自主管理的 AWS Load Balancer Controller,请使用自有的 LoadBalancer Service,设置 spec.loadBalancerClass: service.k8s.aws/nlb 和 service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip;或者对所选 controller 使用文档规定的 aws-load-balancer-type: external 所有权路径。仅有目标类型注解并不能选择 controller。Hybrid Pod 目标和返回路由必须可从 AWS 访问;请谨慎选择内部/公共暴露方式、子网和访问控制。

这不是 EKS Auto Mode 的所有权配置流程。未经审查替换和流量影响,不要将现有 Service 的 class/controller 作为原地迁移来切换。

Cilium LB + BGP ​

请使用已安装的 cilium.io/v2 schema。Service 地址类型应置于 advertisements[].service.addresses 下。该示例仅通告标记为 exposure: onprem-bgp 的 Service 的 LoadBalancer IP;它不会使用实际上会选择所有 Service 的 NotIn 选择器。

yaml
apiVersion: cilium.io/v2
kind: CiliumBGPAdvertisement
metadata:
  name: hybrid-service-advertisement
  labels:
    advertise: hybrid-services
spec:
  advertisements:
  - advertisementType: Service
    service:
      addresses: [LoadBalancerIP]
    selector:
      matchLabels:
        exposure: onprem-bgp

配置 CiliumBGPClusterConfig 节点/对等体选择以及 CiliumBGPPeerConfig 地址族。对等体配置的通告选择器必须匹配 advertise: hybrid-services;Service 选择器必须匹配实际的 Service 标签。启用经过审查的 BGP 控制平面,建立路由器会话,并验证已接受的路由、下一跳、返回路径和流量策略。仅有 IPPool/Advertisement 并不完整。应用更改前,请参阅网络基础配置和已安装版本的 BGP 文档。

附加组件详细设置 ​

CloudWatch Observability Agent ​

使用受支持的 Pod Identity 配置,并验证工作负载实际的 IAM 关联和权限。尽管名称如此,根据当前 AWS 流程,Hybrid 兼容变量 RUN_WITH_IRSA 仍为必需项。将其添加到现有 AmazonCloudWatchAgent 资源的 spec.env 列表中,并保留 K8S_NODE_NAME 等条目;它不是 EKS 附加组件 configurationValues 中任意的顶层 env。

yaml
# Add this item to the existing AmazonCloudWatchAgent.spec.env list:
- name: RUN_WITH_IRSA
  value: "True"

编辑前请检查 amazon-cloud-watch 命名空间中的 amazoncloudwatchagents/cloudwatch-agent,并审查附加组件/operator 如何协调该配置。之后确认 agent 已完成滚动更新并开始采集。Hybrid 集群/工作负载/Pod/容器指标可用,但由于缺少 EC2 IMDS 依赖,无法提供节点级 Container Insights 指标。如果其 operator 在 Hybrid Nodes 上运行,请确保控制平面能够访问 webhook。

EKS Pod Identity Agent ​

主机操作系统文档记录的最低版本Hybrid DaemonSet / 凭证路径
Ubuntu、RHEL、AL2023附加组件 1.3.3-eksbuild.1hybrid;/eks-hybrid/.aws/credentials
Bottlerocket(受支持的 VMware 变体)附加组件 1.3.7-eksbuild.2 和 OS 1.39.0hybrid-bottlerocket;/var/eks-hybrid/.aws/credentials

这些是功能最低版本,并非建议安装旧版本。请选择当前兼容的附加组件版本,并检查其配置 schema。在 Ubuntu/RHEL/AL2023 上,将以下片段合并到每台主机现有的完整 NodeConfig 中:

yaml
# Merge this fragment into each host's complete, protected NodeConfig:
spec:
  hybrid:
    enableCredentialsFile: true

AWS 要求在每台受影响主机上按计划运行 nodeadm init -c file:///path/to/nodeconfig.yaml 进行协调,包括已加入集群的节点。不要盲目地重新初始化每台生产节点:请保留身份/配置,遵循生命周期流程,并逐台验证。Bottlerocket 应使用其文档规定的设置路径,而非此 nodeadm 片段。这些临时凭证文件包含敏感信息;不要打印它们。

对于非 Bottlerocket Hybrid DaemonSet,附加组件配置包括:

json
{
  "daemonsets": {
    "hybrid": {
      "create": true
    }
  }
}

对于 Bottlerocket,请使用所选版本文档规定的 hybrid-bottlerocket 配置。检查并合并现有设置。仅当附加组件不存在时才创建;更新现有附加组件时,应经过审查并妥善处理冲突,不要盲目使用 create 或 OVERWRITE。agent 和凭证文件不会自动创建每个应用的 Pod Identity 关联:请验证命名空间、ServiceAccount、IAM 角色信任/权限、SDK 凭证解析和授权是否成功。

混合模式 Webhook 运维 ​

在 AWS 支持的混合模式方案中,VPC CNI 在云节点上运行,Cilium/Calico 在 Hybrid Nodes 上运行。AWS 建议在此方案中将 webhook 放置于云端。部署在 Hybrid 节点上的 webhook 还需要可路由的远程 Pod CIDR 和控制平面可达性;请检查实际端点,而不要假设每个 webhook 必须或可以在任何位置运行。

CoreDNS 放置 ​

对于此混合模式设计,AWS 建议至少在云节点和 Hybrid Nodes 上各放置一个 CoreDNS 副本。请验证至少有两个期望副本、合格容量、选择器、容忍度和实际端点。单独设置 maxSkew: 1 不会创建两个域,也不能保证每个域都有一个 Pod;云节点也可能没有 eks.amazonaws.com/compute-type 标签。

对于支持 minDomains 的集群,以下 Pod-spec 片段使用明确的管理双域标签。只标记预定的 DNS 节点,并为每个合格节点设置经验证且恰好为 aws 或 onprem 的 location 值。确保现有亲和性/容忍度兼容,验证 CoreDNS Pod 标签,并通过附加组件支持的配置机制协调更改。

yaml
# Fragment under CoreDNS Deployment.spec.template.spec.
# Label eligible nodes with exactly aws or onprem in this administrative domain.
nodeSelector:
  infrastructure.example.com/dns-eligible: "true"
topologySpreadConstraints:
- maxSkew: 1
  minDomains: 2
  topologyKey: infrastructure.example.com/location
  whenUnsatisfiable: DoNotSchedule
  labelSelector:
    matchLabels:
      k8s-app: kube-dns

在两个域都符合条件且至少有两个副本时,严格的分布约束会限制调度,使其分布到这两个域中。如果某个域没有容量,新副本可能会保持 Pending;这是可用性方面的取舍,并不保证故障转移。请测试实际的 DNS Service/EndpointSlices 以及本地/远程解析。在包含 Auto Mode 的集群中,应区分其节点本地 DNS 系统服务和非 Auto 节点仍需要的 Deployment。

各附加组件放置指南 ​

附加组件此设计中的放置位置必需检查项
AWS Load Balancer ControllerAWS 混合模式方案中的云节点Webhook 可达性、肯定式标签、可路由的 Hybrid IP 目标
CloudWatch agent/operatoragent 放置于受支持的目标节点;operator webhook 优先放置于云端IAM/agent 健康状况;排除 Hybrid 节点级指标
cert-managerwebhook 优先放置于云端;也可放置于可路由的 Hybrid 节点控制平面访问和远程 Pod 网络
Metrics Server放置于云端,或使用可访问的 Hybrid Pod 端点控制平面到 Pod,以及 Metrics-Server 到 kubelet 的路径
CoreDNS验证云节点和 Hybrid 节点上的副本合格域、容量和实际 DNS 流量
Cilium/Calico在 AWS 支持的混合 CNI 设计中放置于 Hybrid 节点保留云节点上的 VPC CNI

网络中断时的行为与准备工作 ​

本节介绍 Direct Connect 或 VPN 短暂中断或网络停止响应时,哪些功能会继续运行、哪些会停止。Hybrid Nodes 并非为频繁断连的 DDIL 环境设计,并假定与 AWS 的连接可靠(参见概述)。

中断期间的集群和工作负载 ​

区域行为
正在运行的 pod会继续在节点上运行。kubelet 无法续订其 Lease,因此 Node 的 Ready 条件会变为 Unknown,并添加 node.kubernetes.io/unreachable 污点(NoSchedule,满足条件时还会有 NoExecute)。
Pod 故障转移没有容忍度的 Pod 会在默认 300 秒后由控制平面驱逐,并在其他节点上创建替代 Pod。DaemonSet Pod 默认容忍此污点,因此会留在节点上。
区域标签如果节点带有 topology.kubernetes.io/zone,当某个区域内的所有节点均不可达时,Kubernetes 会取消该区域的驱逐操作。Hybrid 节点没有 cloud-controller-manager,因此请使用 nodeadm --node-labels 设置每个数据中心的区域。
Ciliumagent 健康状况与控制平面访问相关,因此中断期间 agent 会持续重启,且 Cilium BGP Control Plane 会话可能中断(CFP #31702,Cilium 1.17 中的选择启用改进)。AWS 示例中使用的 MetalLB L2 模式在中断期间保持稳定。
AWS 服务依赖项中断期间,ECR 镜像拉取、CloudWatch 和 Amazon Managed Service for Prometheus、ALB/NLB、S3、RDS 等区域服务将不可用。
本地故障排查API 服务器不可达,因此请在主机上使用 crictl pods、crictl ps 和 crictl logs <container>,而不是使用 kubectl。

凭证和重新连接 ​

项目SSM 混合激活IAM Roles Anywhere
临时凭证固定为一小时(无法更改)。正常运行时会在到期前自动轮换,不影响节点或应用。默认一小时;通过配置文件的 durationSeconds 最长可达 12 小时。节点 IAM 角色的 MaxSessionDuration 必须更长。
中断期间由于无法访问 SSM 区域端点,刷新会失败;长时间中断期间凭证可能到期。无法访问 AWS 时不能获取新凭证。
恢复后重试使用指数退避,在 SSM agent 3.3.808.0 及更高版本中最长间隔为 30 分钟。网络恢复后,节点可能需要最多 30 分钟才会重新连接;各节点的重新连接时间不同,因此 Pod 可能会故障转移到最先重新连接的节点。kubelet 通过 aws_signing_helper credential-process 按需获取凭证,因此通常会在几秒内重新连接。
加快恢复重启 SSM agent 以强制刷新(命令如下)。证书有效时无需操作。请配置证书到期通知。

SSM agent 版本、重启和日志:

bash
# Version (AL2023, RHEL / Ubuntu)
yum info amazon-ssm-agent
snap list amazon-ssm-agent

# Force a credential refresh after the network is restored
systemctl restart amazon-ssm-agent                          # AL2023, RHEL
systemctl restart snap.amazon-ssm-agent.amazon-ssm-agent    # Ubuntu

# Watch the CredentialRefresher lines
tail -f /var/log/amazon/ssm/amazon-ssm-agent.log

中断期间,日志会重复出现 Retrieve credentials produced error: RequestError: send request failed 和 Sleeping for ... before retrying retrieve credentials;刷新成功后会记录 Credentials ready。

准备工作清单 ​

  • **冗余连接:**为 Direct Connect 配置冗余,或保留 Site-to-Site VPN 作为备份。
  • **检测中断:**启用 EKS 控制平面 Controller Manager 日志,并为包含 status="NodeNotReady" 的 Recording status change event message for node 消息创建 CloudWatch 指标筛选条件和告警。当 TGW BytesIn/BytesOut 或 VGW TunnelDataIn/TunnelDataOut 低于正常水平时触发告警。CloudWatch Network Monitor 可显示丢包和延迟。
  • **SSM agent 版本:**使用 3.3.808.0 或更高版本,使重试间隔上限为 30 分钟。
  • **区域标签:**设置每个数据中心的 topology.kubernetes.io/zone。
  • **调整驱逐时间:**对于不易迁移的应用,请增大 tolerationSeconds。值越大,实际发生故障的节点上的 Pod 被迁移的时间也会越晚。
yaml
# Fragment under the Deployment's spec.template.spec
tolerations:
  - key: "node.kubernetes.io/unreachable"
    operator: "Exists"
    effect: "NoExecute"
    tolerationSeconds: 1800
  • **凭证提供程序:**如果中断频繁且快速重新连接很重要,可考虑使用更长 durationSeconds 的 IAM Roles Anywhere。集群内应只使用一个提供程序。
  • **辅助可观测性路径:**配置 ADOT collector 将数据发送到多个后端,以便区域服务不可达时仍能保持可见性。

参考资料:

常见故障排查 ​

ImagePullBackOff 诊断 ​

读取 Pod 事件,并检查所引用 Secret 的名称/类型,但不要解码或打印 registry 凭证。Secret 必须位于 Pod 所在的命名空间。请通过凭证所有者确认 registry 主机名、所需仓库权限和凭证到期时间;仅凭元数据无法证明身份验证成功。

bash
set -euo pipefail
: "${KUBE_CONTEXT:?Set the approved cluster context}"
: "${NAMESPACE:?Set the workload namespace}" "${POD:?Set the affected Pod}"
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" describe pod "$POD"
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pod "$POD" \
  -o jsonpath='{.spec.imagePullSecrets[*].name}{"\n"}'
: "${PULL_SECRET:?Set a referenced imagePullSecret in that namespace}"
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get secret "$PULL_SECRET" \
  -o jsonpath='{.type}{"\n"}'

请从实际主机/网络路径执行 TLS 检查,并启用受信任 CA 和主机名验证。不要使用 curl -k,也不要将未经身份验证的 registry 401 响应误判为 TLS 故障。此示例需要 Bash、OpenSSL 和 GNU timeout。

bash
set -euo pipefail
: "${HARBOR_HOST:?Set the registry DNS name, without scheme or port}"
: "${HARBOR_CA_FILE:?Set the approved CA bundle file}"
timeout 10s openssl s_client -connect "$HARBOR_HOST:443" \
  -servername "$HARBOR_HOST" -verify_hostname "$HARBOR_HOST" \
  -verify_return_error -CAfile "$HARBOR_CA_FILE" </dev/null

如需在 Pod 内测试 DNS/网络,请使用经批准且按摘要固定的诊断镜像、专用命名空间,并明确将其放置在受影响的 Hybrid Node 上。任意未固定的调试 Pod 可能运行在云节点上,从而测试错误的路径。请单独审查 Pod 的创建/删除操作,并保留限定范围的结果。

DNS 解析问题 ​

检查实际的 CoreDNS Deployment/Pods、Service 和 EndpointSlices、云端/本地放置情况、DNS 配置和网络可达性。从受影响的工作负载环境测试 registry 名称和 kubernetes.default.svc.cluster.local。API、DNS 或日志访问失败都属于未知观测结果,并不代表检查成功。

不要默认重启所有 CoreDNS Pod。请先确定故障层级,并在协调冗余和恢复检查后再执行任何重启。包含 Auto Mode 的混合集群可能具有节点本地 DNS 行为;请确认故障 Pod 实际使用的解析器路径。

节点连接问题 ​

使用清单中的实际 Node 名称和对应主机。基于 SSM 的 Node 名称不一定以 hybrid- 开头,也不一定能解析为主机名。

bash
set -euo pipefail
: "${KUBE_CONTEXT:?Set the approved cluster context}" "${NODE:?Set the actual registered Node name}"
kubectl --context "$KUBE_CONTEXT" get node "$NODE" -o wide
kubectl --context "$KUBE_CONTEXT" describe node "$NODE"
bash
# Run on the mapped host, not a hostname guessed from the Node name.
sudo systemctl status kubelet containerd --no-pager
sudo journalctl -u kubelet -u containerd --since '10 minutes ago' \
  --no-pager -n 200

检查凭证提供程序和特定于操作系统的 agent 单元(包括适用时基于 Ubuntu snap 的 SSM 安装)。对于网络/身份验证诊断,请在 root 权限下使用经过验证的 nodeadm debug -c file:///etc/eks/nodeconfig.yaml 流程,并将输出私密保存。此命令会联系 AWS 和集群;不要记录已发放的凭证,也不要禁用 TLS 验证。

经审查的 1.0.20 CLI 中没有 nodeadm reset 子命令。NotReady 并不是盲目注销/重新初始化主机的理由。确定故障原因后,请按照恢复和身份协调流程操作,保留挂载/数据并记录节点/SSM 身份。

验证范围和参考资料 ​

本地检查涵盖固定版本的资源 schema、使用合成样本的四条 PromQL 表达式,以及十一个备份/网络命令模拟案例。未执行任何 AWS/Kubernetes 更改、实际备份/恢复、网络负载测试、BGP 会话、exporter 抓取或生产环境滚动更新。部署前,请从 AWS 当前支持文档中选择 EKS/OS/CNI/附加组件组合。


< 上一页:节点生命周期管理 | 目录 | 下一页:裸机操作系统设置 >

向文档提问

按 Enter 发送,按 Shift+Enter 换行。