Anthos clusters on Bare Metal 已知问题

安装

使用多 NIC、containerd 和代理时集群创建失败

当您的情况满足以下条件组合时,集群创建失败:

  • 集群配置为使用 containerd 作为容器运行时(在集群配置文件中,nodeConfig.containerRuntime 设置为 containerd,这是 Anthos clusters on Bare Metal 1.8 版中的默认设置)。

  • 集群配置为可为 pod 提供多个网络接口、多 NIC(在集群配置文件中,spec.clusterNetwork.multipleNetworkInterfaces 设置为 true)。

  • 集群已配置为使用代理(在集群配置文件中指定了 spec.proxy.url)。即使集群创建失败,此设置也会在您尝试创建集群时传播。您可能会在 HTTPS_PROXY 环境变量或 containerd 配置 (/etc/systemd/system/containerd.service.d/09-proxy.conf) 中看到此代理设置。

如需解决此问题,请将服务 CIDR (clusterNetwork.services.cidrBlocks) 附加到所有节点机器上的 NO_PROXY 环境变量。

对照组 v2 不兼容

对照组 v2 (cgroup v2) 与 Anthos clusters on Bare Metal 1.6 不兼容。Kubernetes 1.18 不支持 cgroup v2。此外,Docker 从 20.10 版开始才提供实验性支持。在版本 247.2-2 中,systemd 默认切换为 cgroup v2。如果存在 /sys/fs/cgroup/cgroup.controllers,则表示系统使用的是 cgroup v2。

预检检查会确认 cgroup v2 是在集群机器上使用。

安装期间的良性错误消息

检查集群创建日志时,您可能会看到有关注册集群或调用网络钩子的暂时性故障。您可以放心地忽略这些错误,因为安装过程将重试这些操作,直到操作成功。

预检检查和服务帐号凭据

对于由管理员集群或混合集群触发的安装(也就是不使用 bmctl 创建的集群,例如用户集群),预检检查不会验证 Google Cloud Platform 服务帐号凭据或其相关权限。

预检检查和权限遭拒

在安装过程中,您可能会看到有关 /bin/sh: /tmp/disks_check.sh: Permission denied 的错误。出现这些错误消息的原因是 /tmp 在使用 noexec 选项的情况下装载。要使 bmctl 正常运行,您需要从 /tmp 装载点移除 noexec 选项。

应用默认凭据和 bmctl

bmctl 使用应用默认凭据 (ADC) 验证集群操作在 cluster spec 中的位置值(如果未设置为 global)。

要使 ADC 正常运行,您需要将 GOOGLE_APPLICATION_CREDENTIALS 环境变量指向服务帐号凭据文件,或运行 gcloud auth application-default login

Ubuntu 20.04 LTS 和 bmctl

在 1.8.2 之前的 Anthos clusters on Bare Metal 版本上,某些具有较新 Linux 内核的 Ubuntu 20.04 LTS 发行版(包括 5.8 内核上的 GCP Ubuntu 20.04 LTS 映像)在非 init 网络命名空间中将 /proc/sys/net/netfilter/nf_conntrack_max 设为了只读。这会阻止 bmctl 设置最大连接跟踪表大小,这会阻止引导集群启动。表大小不正确的症状是引导集群中的 kube-proxy pod 将崩溃循环,如以下示例错误日志中所示:

kubectl logs -l k8s-app=kube-proxy -n kube-system --kubeconfig ./bmctl-workspace/.kindkubeconfig
I0624 19:05:08.009565       1 conntrack.go:100] Set sysctl 'net/netfilter/nf_conntrack_max' to 393216
F0624 19:05:08.009646       1 server.go:495] open /proc/sys/net/netfilter/nf_conntrack_max: permission denied

解决方法是手动在主机上将 net/netfilter/nf_conntrack_max 设置为所需的值:sudo sysctl net.netfilter.nf_conntrack_max=393216。请注意,所需的值取决于节点的核心数。使用上述 kubectl logs 命令来确认 kube-proxy 日志中所需的值。

此问题在 Anthos clusters on Bare Metal 1.8.2 和更高版本中已得到修复。

Docker 服务

在集群节点机器上,如果 PATH 环境变量中存在 Docker 可执行文件,但 Docker 服务未处于活动状态,则预检检查将失败并报告 Docker service is not active。如需修复此错误,请移除 Docker 或启用 Docker 服务。

注册表镜像和 Cloud Audit Logging

在 1.8.2 版之前的 Anthos clusters on Bare Metal 上,bmctl 注册表镜像软件包缺少 gcr.io/anthos-baremetal-release/auditproxy:gke_master_auditproxy_20201115_RC00 映像。如需在使用注册表镜像时启用 Cloud Audit Logging 功能,您需要手动下载缺失的映像,并使用以下命令将其推送到您的注册表服务器:

docker pull gcr.io/anthos-baremetal-release/auditproxy:gke_master_auditproxy_20201115_RC00
docker tag gcr.io/anthos-baremetal-release/auditproxy:gke_master_auditproxy_20201115_RC00 REGISTRY_SERVER/anthos-baremetal-release/auditproxy:gke_master_auditproxy_20201115_RC00
docker push REGISTRY_SERVER/anthos-baremetal-release/auditproxy:gke_master_auditproxy_20201115_RC00

Containerd 需要 PATH 中的 /usr/local/bin

具有 containerd 运行时的集群要求 /usr/local/bin 位于 SSH 用户的 PATH 中,以便 kubeadm init 命令查找 crictl 二进制文件。如果找不到 crictl,则创建集群会失败。

如果您未以根用户身份登录,则使用 sudo 运行 kubeadm init 命令。sudo PATH 可能与根配置文件不同,并且不得包含 /usr/local/bin

要修复此错误,请更新 /etc/sudoers 中的 secure_path 来包含 /usr/local/bin。或者,在另一个 /bin 目录中为 crictl 创建符号链接。

从 1.8.2 开始,运行集群时,Anthos clusters on Bare Metal 会将 /usr/local/bin 添加到 PATH 中。但是,以非根用户身份运行快照仍将包含 crictl: command not found(可通过上述解决方法解决此问题)。

在 vSphere 上安装

在 vSphere 虚拟机上安装 Anthos clusters on Bare Metal 时,必须将 tx-udp_tnl-segmentationtx-udp_tnl-csum-segmentation 标志设置为关闭。这些标志与 vSphere 驱动程序 VMXNET3 完成的硬件细分分流相关,它们不适用于 Anthos clusters on Bare Metal 的 GENEVE 隧道。

在每个节点上运行以下命令,以检查这些标志的当前值。ethtool -k NET_INTFC |grep segm ... tx-udp_tnl-segmentation: on tx-udp_tnl-csum-segmentation: on ...NET_INTFC 替换为与节点的 IP 地址关联的网络接口。

有时,在 RHEL 8.4 中,ethtool 显示这些标志为关闭,但其实并未关闭。如需将这些标志明确设置为关闭,请使用以下命令将其设置为开启,然后设置为关闭。

ethtool -K ens192 tx-udp_tnl-segmentation on
ethtool -K ens192 tx-udp_tnl-csum-segmentation on

ethtool -K ens192 tx-udp_tnl-segmentation off
ethtool -K ens192 tx-udp_tnl-csum-segmentation off

此标志更改在重新启动后不会保留。配置启动脚本,以便在系统启动时明确设置这些标志。

节点波动就绪

集群偶尔会显示快速节点就绪性(节点状态在 ReadyNotReady 之间快速变化)。运行状况不佳的 Pod 生命周期事件生成器 (PLEG) 会导致此行为。PLEG 是 kubelet 中的一个模块。

如需确认健康状况不佳的 PLEG 是否导致此行为,请使用以下 journalctl 命令检查 PLEG 日志条目:

journalctl -f | grep -i pleg

如下所示的日志条目表示 PLEG 健康状况不佳:

...
skipping pod synchronization - PLEG is not healthy: pleg was last seen active
3m0.793469
...

已知的 runc 竞争条件是导致 PLEG 运行状况不佳的可能原因。runc 进程卡住是竞争条件的症状。使用以下命令检查 runc init 进程状态:

ps aux | grep 'runc init'

要解决此问题,请按以下步骤操作:

  1. 确定集群运行时。

    您必须先确定您的集群使用的容器运行时,然后才能更新 runc 版本。集群配置文件中的 containerRuntime 字段标识您的集群使用的容器运行时。当 containerRuntime 设置为 containerd 时,您的集群会使用 containerd 运行时。如果该字段设置为 docker 或未设置,则集群将使用 Docker 运行时。

    如需获取该值,请使用您喜爱的编辑器打开集群配置文件;如果您可以访问管理员集群 kubeconfig,请运行以下命令:

    kubctl describe cluster CLUSTER_NAME -n CLUSTER_NAMESPACE | grep -i runtime
    

    替换以下内容:

    • CLUSTER_NAME:要备份的集群的名称。
    • CLUSTER_NAMESPACE:集群的命名空间。默认情况下,Anthos clusters on Bare Metal 的集群命名空间是以 cluster- 开头的集群名称。
  2. 如需安装 containerd.io 或 docker-ce 并提取最新的 runc 命令行工具,请在每个节点上运行与您的操作系统和容器运行时相对应的命令。

    Ubuntu Containerd

    sudo apt update
    sudo apt install containerd.io
    # Back up current runc
    cp /usr/local/sbin/runc ~/
    sudo cp /usr/bin/runc /usr/local/sbin/runc
    # runc version should be > 1.0.0-rc93
    /usr/local/sbin/runc --version
    

    Ubuntu Docker

    sudo apt update
    sudo apt install docker-ce
    # Back up current runc
    cp /usr/local/sbin/runc ~/
    sudo cp /usr/bin/runc /usr/local/sbin/runc
    # runc version should be > 1.0.0-rc93
    /usr/local/sbin/runc --version
    

    CentOS/RHEL Containerd

    sudo dnf install containerd.io
    # Back up current runc
    cp /usr/local/sbin/runc ~/
    sudo cp /usr/bin/runc /usr/local/sbin/runc
    # runc version should be > 1.0.0-rc93
    /usr/local/sbin/runc --version
    

    CentOS/RHEL Docker

    sudo dnf install docker-ce
    # Back up current runc
    cp /usr/local/sbin/runc ~/
    sudo cp /usr/bin/runc /usr/local/sbin/runc
    # runc version should be > 1.0.0-rc93
    /usr/local/sbin/runc --version
    
  3. 如果 runc init 进程卡滞,请重新启动节点。

    或者,您也可以手动清理所有卡滞的进程。

升级和更新

如果 .manifests 目录缺失,则 bmctl update cluster 会失败

如果在运行 bmctl update cluster 之前移除了 .manifests 目录,则该命令会失败,并显示如下所示的错误:

Error updating cluster resources.: failed to get CRD file .manifests/1.9.0/cluster-operator/base/crd/bases/baremetal.cluster.gke.io_clusters.yaml: open .manifests/1.9.0/cluster-operator/base/crd/bases/baremetal.cluster.gke.io_clusters.yaml: no such file or directory

如需解决此问题,请先运行 bmctl check cluster,这将重新创建 .manifests 目录。

此问题适用于 Anthos Clusters on Bare Metal 1.10 及更早版本,并在 1.11 版及更高版本中得到修复。

error during manifests operations,导致升级卡住

在某些情况下,集群升级无法完成,并且 bmctl CLI 没有响应。此问题可能是由错误更新的资源引起的。如需确定您是否受到此问题的影响并解决此问题,请按以下步骤操作:

  1. 检查 anthos-cluster-operator 日志并查找类似于以下条目的错误:

    controllers/Cluster "msg"="error during manifests operations" "error"="1 error occurred:
    ...
    {RESOURCE_NAME} is invalid: metadata.resourceVersion: Invalid value: 0x0: must be specified for an update
    

    这些条目是错误更新资源的问题,其中 {RESOURCE_NAME} 是问题资源的名称。

  2. 如果您在日志中找到这些错误,请使用 kubectl edit 从日志消息中包含的资源中移除 kubectl.kubernetes.io/last-applied-configuration 注解。

  3. 保存更改并将更改应用于资源。

  4. 重试集群升级。

维护模式下 1.8 版集群的升级失败

如果有任何节点机器先前已处于维护模式,则尝试将 1.8.x 版集群升级到 1.9.x 版会失败。这是由于这些节点上仍然存在注解。

如需确定您是否受到此问题的影响,请按照以下步骤操作:

  1. 通过运行以下命令获取您要升级的集群版本:

    kubectl --kubeconfig ADMIN_KUBECONFIG get cluster CLUSTER_NAME  \
        -n CLUSTER_NAMESPACE --output=jsonpath="{.spec.anthosBareMetalVersion}"
    

    如果返回的版本值适用于 1.8 次要版本(例如 1.8.3),则继续执行操作。否则,此问题不适合您的情况。

  2. 通过运行以下命令,检查集群是否具有任何先前已处于维护模式的节点:

    kubectl --kubeconfig ADMIN_KUBECONFIG get BareMetalMachines -n CLUSTER_NAMESPACE  \
        --output=jsonpath="{.items[*].metadata.annotations}"
    

    如果返回的注解包含 baremetal.cluster.gke.io/maintenance-mode-duration,则表示您受到这一已知问题的影响。

如需允许集群升级,请为每个受影响的节点机器运行以下命令,以移除 baremetal.cluster.gke.io/maintenance-mode-duration 注解:

kubectl --kubeconfig ADMIN_KUBECONFIG  annotate BareMetalMachine -n CLUSTER_NAMESPACE \
    NODE_MACHINE_NAME baremetal.cluster.gke.io/maintenance-mode-duration-

bmctl update 无法移除维护块

bmctl update 命令无法在集群资源配置中移除或修改 maintenanceBlocks 部分。如需了解详情(包括从维护模式中移除节点的说明),请参阅将节点置于维护模式

针对某些负载均衡器配置从集群 1.7.x 版升级时失败

对于以下负载均衡器配置,将集群从 1.7.x 版升级到 1.8.y 版可能会失败:

  • 手动配置的外部负载均衡器(loadBalancer.mode 设置为 manual

  • 使用单独节点池(指定 loadBalancer.nodePoolSpec.nodes)进行捆绑式负载均衡(将 loadBalancer.mode 设置为 bundled

此故障的症状是控制平面节点上的 cal-update 作业在执行任务 Check apiserver health 时失败,并发出连接遭拒错误消息。

以下是 cal-update 作业的示例日志:

TASK [cal-update : Check apiserver health] *************************************
Thursday 20 January 2022  13:50:46 +0000 (0:00:00.033)       0:00:09.316 ******
FAILED - RETRYING: Check apiserver health (30 retries left).
FAILED - RETRYING: Check apiserver health (29 retries left).
FAILED - RETRYING: Check apiserver health (28 retries left).
FAILED - RETRYING: Check apiserver health (27 retries left).
FAILED - RETRYING: Check apiserver health (26 retries left).
...
FAILED - RETRYING: Check apiserver health (3 retries left).
FAILED - RETRYING: Check apiserver health (2 retries left).
FAILED - RETRYING: Check apiserver health (1 retries left).
[WARNING]: Consider using the get_url or uri module rather than running 'curl'.
If you need to use command because get_url or uri is insufficient you can add
'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
fatal: [10.50.116.79]: FAILED! => {"attempts": 30, "changed": true, "cmd": "curl
-k https://127.0.0.1/healthz", "delta": "0:00:00.008949", "end": "2022-01-20
19:22:30.381875", "msg": "non-zero return code", "rc": 7, "start": "2022-01-20
19:22:30.372926", "stderr": "  % Total    % Received % Xferd  Average Speed
Time    Time     Time  Current\n                                 Dload  Upload
Total   Spent    Left  Speed\n\r  0     0    0     0    0     0      0      0 --
:--:-- --:--:-- --:--:--     0curl: (7) Failed to connect to 127.0.0.1 port 443:
Connection refused", "stderr_lines": ["  % Total    % Received % Xferd  Average
Speed   Time    Time     Time  Current", "                                 Dload
Upload   Total   Spent    Left  Speed", "", "  0     0    0     0    0     0
0      0 --:--:-- --:--:-- --:--:--     0curl: (7) Failed to connect to
127.0.0.1 port 443: Connection refused"], "stdout": "", "stdout_lines": []}

手动解决方法是在升级之前创建一个从端口 443(用于检查)到端口 6444(由 apiserver 侦听)的端口转发。如需创建端口转发,请在每个控制平面节点上运行以下命令:

sudo iptables -t nat -I OUTPUT -p tcp -o lo --dport 443 -j REDIRECT --to-ports 6444

进行协调并检查端口 443 时运行 cal-update 作业,因此您应该为升级到 1.8.x 的集群保留此端口转发。

升级至 1.9.0 或更高版本后,请通过在每个控制平面节点上运行以下命令来移除此端口转发:

sudo iptables -t nat -D OUTPUT -p tcp -o lo --dport 443 -j REDIRECT --to-ports 6444

到 1.8.0 和 1.8.1 管理员集群、Hybrid 集群和独立集群的升级未完成

管理员、混合集群或独立集群从 1.7.x 版升级到 1.8.0 版或 1.8.1 版有时无法完成。此升级失败适用于您在创建集群后更新的集群。

这一升级问题表明的是控制台输出 Waiting for upgrade to complete ...,并未提及要升级的节点。此症状还表明管理员集群已成功升级到 Kubernetes 版本 v1.20.8-gke.1500,即裸机版本 1.8.0 和 1.8.1 上的 Anthos 集群的 Kubernetes 版本。

此升级问题已在 Anthos clusters on Bare Metal 1.8.2 版中得到修复。

如需确认此问题是否影响您的集群,请升级到 1.8.0 或 1.8.1:

  1. 创建以下 Shell 脚本:

    if [ $(kubectl get cluster <var>CLUSTER\_NAME -n <var>CLUSTER\_NAMESPACE
        --kubeconfig bmctl-workspace/.kindkubeconfig -o=jsonpath='{.metadata.generation}')
        -le $(kubectl get cluster CLUSTER_NAME -n CLUSTER_NAMESPACE
        --kubeconfig bmctl-workspace/.kindkubeconfig
        -o=jsonpath='{{.status.systemServiceConditions[?(@.type=="Reconciling")].observedGeneration}}') ];
        then echo "Bug Detected"; else echo "OK"; fi
    

    请替换以下内容:

    • CLUSTER_NAME:要检查的集群的名称。
    • CLUSTER_NAMESPACE:集群的命名空间。
  2. 在升级过程中运行脚本,但在预检检查完成后运行脚本。

    observedGeneration 值不小于 generation 值时,会将 Bug Detected 写入控制台输出。此输出表示您的集群升级受到影响。

  3. 如需取消升级,请运行以下命令:

    kubectl get --raw=/apis/baremetal.cluster.gke.io/v1/namespaces/CLUSTER_NAMESPACE/clusters/CLUSTER_NAME/status \
        --kubeconfig bmctl-workspace/.kindkubeconfig | \
        sed -e 's/\("systemServiceConditions":\[{[^{]*"type":"DashboardReady"}\),{[^{}]*}/\1/g' | \
        kubectl replace --raw=/apis/baremetal.cluster.gke.io/v1/namespaces/CLUSTER_NAMESPACE/clusters/CLUSTER_NAME/status \
        --kubeconfig bmctl-workspace/.kindkubeconfig -f-
    

    请替换以下内容:

    • CLUSTER_NAME:要检查的集群的名称。
    • CLUSTER_NAMESPACE:集群的命名空间。

升级到 1.8.3 或 1.8.4

将 Anthos clusters on Bare Metal 升级到 1.8.3 或 1.8.4 版有时会失败,并显示 nil 上下文错误。如果您的集群升级失败并显示 nil 上下文错误,请执行以下步骤完成升级:

  1. GOOGLE_APPLICATION_CREDENTIALS 环境变量设置为指向您的服务帐号密钥文件。

    export GOOGLE_APPLICATION_CREDENTIALS=KEY_PATH
    

    KEY_PATH 替换为包含您的服务帐号密钥的 JSON 文件的路径。

  2. 再次运行 bmctl upgrade cluster 命令。

用户集群补丁程序升级限制

由管理员集群管理的用户集群必须位于相同的 Anthos clusters on Bare Metal 版本或更低版本中,并且必须是一个次要版本。例如,可以管理 1.6.2 版用户集群的 1.7.1 版 (anthosBareMetalVersion: 1.7.1) 管理员集群。

当管理员集群使用的发布版本之后发布补丁时,升级限制会阻止您将用户集群升级到新的安全补丁。例如,如果您的管理员集群的版本为 1.7.2,该版本于 2021 年 6 月 2 日发布,则您无法将您的用户集群升级到 1.6.4 版,因为该版本于 2021 年 8 月 13 日发布。

Ubuntu 18.04 和 18.04.1 不兼容

如要升级到 1.8.1 或 1.8.2,运行 bmctl 的集群节点机器和工作站需要拥有 Linux 内核版本 4.17.0 或更高版本。否则,anetd 网络控制器将无法工作。症状是 kube-system 命名空间中带有 anet 前缀的 pod 将继续崩溃,并显示以下错误消息:BPF NodePort services needs kernel 4.17.0 or newer.

此问题会影响 Ubuntu 18.04 和 18.04.1,因为它们的内核版本为 4.15。

此问题已在 Anthos clusters on Bare Metal 1.8.3 中得到修复。

升级使用 containerd 的 1.7.x 集群

对于配置为使用预览版 containerd 功能的 1.7.x 集群,将无法升级到 1.8.x。containerd 预览版使用不正确的控制组 (cgroup) 驱动程序 cgroupfs,而不是推荐的 systemd 驱动程序。报告了使用 cgroupfs 驱动程序的集群面临资源压力的集群不稳定性的情况。1.8.0 版中的 GA containerd 功能使用正确的 systemd 驱动程序。

如果您有使用预览版 containerd 容器运行时功能的现有 1.7.x 集群,我们建议您创建为 containerd 配置的新 1.8.0 集群并迁移任何现有的应用程序和工作负载。这可确保在使用 containerd 容器运行时时的最高集群稳定性。

SELinux 升级失败

升级使用 containerd 容器运行时配置的 1.7.1 集群并在 RHEL 或 CentOS 上运行 SELinux。我们建议您创建新的 1.8.0 集群,该集群配置为使用 containerd 并迁移工作负载。

节点无法覆盖时,无法启动节点排空功能

如果节点从 Anthos clusters on Bare Metal 无法访问,则节点的排空过程不会启动。例如,如果某个节点在集群升级过程中离线,可能会导致升级停止响应。这种情况很少见。为了最大限度地降低遇到此问题的可能性,请确保您的节点在启动升级之前正常运行。

操作

kubeconfig Secret 被覆盖

在用户集群上运行时,bmctl check cluster 命令会使用管理员集群 kubeconfig 覆盖用户集群 kubeconfig Secret。覆盖该文件会导致受影响的用户集群的标准集群操作(例如更新和升级)失败。此问题影响 Anthos clusters on Bare Metal 1.11.1 及更早版本。

要确定用户集群是否受到此问题的影响,请运行以下命令:

kubectl --kubeconfig ADMIN_KUBECONFIG get secret -n cluster-USER_CLUSTER_NAME \
    USER_CLUSTER_NAME -kubeconfig  -o json  | jq -r '.data.value'  | base64 -d

替换以下内容:

  • ADMIN_KUBECONFIG:管理员集群 kubeconfig 文件的路径。
  • USER_CLUSTER_NAME:要检查的用户集群的名称。

如果输出中的集群名称(请参阅以下示例输出中的 contexts.context.cluster)是管理员集群名称,则指定的用户集群会受到影响。

user-cluster-kubeconfig  -o json  | jq -r '.data.value'  | base64 -d
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data:LS0tLS1CRU...UtLS0tLQo=
    server: https://10.200.0.6:443
  name: ci-aed78cdeca81874
contexts:
- context:
    cluster: ci-aed78cdeca81874
    user: ci-aed78cdeca81874-admin
  name: ci-aed78cdeca81874-admin@ci-aed78cdeca81874
current-context: ci-aed78cdeca81874-admin@ci-aed78cdeca81874
kind: Config
preferences: {}
users:
- name: ci-aed78cdeca81874-admin
  user:
    client-certificate-data: LS0tLS1CRU...UtLS0tLQo=
    client-key-data: LS0tLS1CRU...0tLS0tCg==

以下步骤会恢复受影响的用户集群 (USER_CLUSTER_NAME) 的功能:

  1. 找到用户集群 kubeconfig 文件。

    创建集群时,Anthos clusters on Bare Metal 会在管理员工作站上生成 kubeconfig 文件。默认情况下,该文件位于 bmctl-workspace/USER_CLUSTER_NAME 目录中。

  2. 验证该 kubeconfig 是正确的用户集群 kubeconfig:

    kubectl get nodes --kubeconfig PATH_TO_GENERATED_FILE
    

    PATH_TO_GENERATED_FILE 替换为用户集群 kubeconfig 文件的路径。响应会返回用户集群的节点的详细信息。确认集群的机器名称正确无误。

  3. 运行以下命令以删除管理员集群中的损坏的 kubeconfig 文件:

    kubectl delete secret -n USER_CLUSTER_NAMESPACE USER_CLUSTER_NAME-kubeconfig
    
  4. 运行以下命令,将正确的 kubeconfig Secret 保存回管理员集群:

    kubectl create secret generic -n USER_CLUSTER_NAMESPACE USER_CLUSTER_NAME-kubeconfig \
        --from-file=value=PATH_TO_GENERATED_FILE
    

重置/删除

命名空间删除

删除命名空间将阻止在该命名空间中创建新资源,包括用于重置机器的作业。删除用户集群时,您必须先删除集群对象,然后再删除其命名空间。否则,无法创建重置机器的作业,删除过程将跳过机器清理步骤。

containerd 服务

bmctl reset 命令不会删除任何 containerd 配置文件或二进制文件。containerd systemd 服务保持已启动且正在运行状态。该命令会删除调度到节点的容器运行 pod。

安全

升级期间,集群 CA/证书将轮替。按需轮替支持是预览版功能。

Anthos clusters on Bare Metal 自动轮替 kubelet 服务证书。当证书快要过期时,每个 kubelet 节点代理都可以发出证书签名请求 (CSR)。管理员集群中的控制器会验证并批准 CSR。

集群 CA 轮替(预览版功能)

对集群执行用户集群证书授权机构 (CA) 轮替后,所有用户身份验证流程都将失败。之所以发生这种情况,是因为在 CA 轮替期间,身份验证流程中使用的 ClientConfig 自定义资源不会使用新 CA 数据进行更新。如果您已在集群上执行集群 CA 轮替,请检查 kube-public 命名空间的 default ClientConfig 中的 certificateAuthorityData 字段是否包含旧版集群 CA。

如需手动解决此问题,请使用当前集群 CA 更新 certificateAuthorityData 字段。

网络

具有捆绑式第 2 层负载均衡的客户端来源 IP 地址

外部流量政策设置为 Local 可能会导致捆绑式第 2 层负载均衡的路由错误,如 No route to host。外部流量政策默认设置为 Cluster (externalTrafficPolicy: Cluster)。使用此设置时,Kubernetes 会处理集群范围的流量。LoadBalancerNodePort 类型的服务可以使用 externalTrafficPolicy: Local 保留客户端来源 IP 地址。但是,使用此设置时,Kubernetes 仅处理节点本地流量。

如果要保留客户端来源 IP 地址,则可能需要其他配置,以确保服务 IP 地址可供访问。如需了解配置详情,请参阅“配置捆绑式负载均衡”中的保留客户端来源 IP 地址

修改 firewalld 会清除 Cilium iptable 政策链

运行在 CentOS 或 Red Hat Enterprise Linux (RHEL) 上启用了 firewalld 的 Anthos clusters on Bare Metal 时,更改 firewalld 可能会清除主机网络上的 Cilium iptables 链。anetd Pod 在启动时会添加 iptables 链。丢失 Cilium iptables 链会导致节点上的 Pod 丢失节点外部的网络连接。

会导致清除 iptables 链的 firewalld 更改包括但不限于:

  • 使用 systemctl 重启 firewalld
  • 使用命令行客户端 (firewall-cmd --reload) 重新加载 firewalld

您可以通过在节点上重启 anetd 来修复此连接问题。使用以下命令找到并删除 anetd Pod,以重启 anetd

kubectl get pods -n kube-system
kubectl delete pods -n kube-system ANETD_XYZ

ANETD_XYZ 替换为 anetd Pod 的名称。

egressSourceIP 地址重复

使用出口 NAT 网关功能预览时,可以设置流量选择规则,指定已用于另一个 EgressNATPolicy 对象的 egressSourceIP 地址。这可能会导致出站流量路由冲突。在您的 EgressNATPolicy 自定义资源中指定 egressSourceIP 地址之前,请与您的开发团队协调以确定哪些浮动 IP 地址可供使用。

由于 I/O 超时和反向路径过滤而导致的 Pod 连接失败

Anthos clusters on Bare Metal 在节点上配置反向路径过滤以停用源验证 (net.ipv4.conf.all.rp_filter=0)。如果 rp_filter 设置更改为 12,则 Pod 会因节点外通信超时而失败。

如果观察到与 Kubernetes Service IP 地址通信之间的连接失败,就是此问题的症状。以下是您可能会看到的一些错误类型的示例:

  • 如果给定节点的所有 pod 都无法与 Service IP 地址通信,则 istiod pod 可能会报告如下错误:

     {"severity":"Error","timestamp":"2021-11-12T17:19:28.907001378Z",
        "message":"watch error in cluster Kubernetes: failed to list *v1.Node:
        Get \"https://172.26.0.1:443/api/v1/nodes?resourceVersion=5  34239\":
        dial tcp 172.26.0.1:443: i/o timeout"}
    
  • 对于在每个节点上运行的 localpv 守护进程集,日志可能会显示如下超时:

     I1112 17:24:33.191654       1 main.go:128] Could not get node information
    (remaining retries: 2): Get
    https://172.26.0.1:443/api/v1/nodes/NODE_NAME:
    dial tcp 172.26.0.1:443: i/o timeout
    

反向路径过滤通过 IPv4 配置文件夹 (net/ipv4/conf/all) 中的 rp_filter 文件进行设置。sysctl 命令将反向路径过滤设置存储在网络安全配置文件(例如 /etc/sysctl.d/60-gce-network-security.conf)中。sysctl 命令可以替换反向路径过滤设置。

如需恢复 Pod 连接,请手动将 net.ipv4.conf.all.rp_filter 设置回 0,或者重新启动 anetd Pod 以将 net.ipv4.conf.all.rp_filter 设置回 0。如需重启 anetd Pod,请使用以下命令查找并删除 anetd Pod。新的 anetd Pod 会在其位置启动:

kubectl get pods -n kube-system
kubectl delete pods -n kube-system ANETD_XYZ

ANETD_XYZ 替换为 anetd Pod 的名称。

如需手动设置 net.ipv4.conf.all.rp_filter,请运行以下命令:

sysctl -w net.ipv4.conf.all.rp_filter = 0

引导(种类)集群 IP 地址和集群节点 IP 地址重叠

192.168.122.0/2410.96.0.0/27 是引导(种类)集群使用的默认 pod 和服务 CIDR。如果这些地址与集群节点机器 IP 地址重叠,预检检查将失败。为避免冲突,您可以将 --bootstrap-cluster-pod-cidr--bootstrap-cluster-service-cidr 标志传递给 bmctl 以指定不同的值。

不同集群的 IP 地址重叠

在更新期间,系统不会验证不同集群中的 IP 地址重叠。验证仅在创建集群/节点池创建时适用。

操作系统

在 CentOS 上创建或升级集群失败

2020 年 12 月,CentOS 社区和 Red Hat 宣布了 CentOS 停用。2022 年 1 月 31 日,CentOS 8 已达到服务终止 (EOL) 期限。由于服务终止 (EOL),yum 代码库不再适用于 CentOS,从而导致集群创建和集群升级操作失败。这适用于所有受支持的 CentOS 版本,并影响所有 Anthos clusters on Bare Metal 版本。

如需解决此问题,请运行以下命令,让 CentOS 使用归档 Feed:

sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-Linux-*
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' \
    /etc/yum.repos.d/CentOS-Linux-*

作为长期解决方案,请考虑迁移到其他受支持的操作系统

操作系统端点限制

在 RHEL 和 CentOS 中,存在 10 万个端点的集群级层限制。此数字是一个 Kubernetes Service 引用的所有 pod 的总和。如果两个服务引用同一组 pod,则计为两组独立的端点。RHEL 和 CentOS 中的底层 nftable 实现导致了此限制;这不是 Anthos clusters on Bare Metal 的固有限制。

配置

控制层面和负载均衡器规范

控制层面和负载均衡器节点池规范很特别。这些规范声明和控制关键集群资源。这些资源的规范来源是它们在集群配置文件中的相应部分:

  • spec.controlPlane.nodePoolSpec
  • spec.LoadBalancer.nodePoolSpec

因此,请勿直接修改顶层控制层面和负载均衡器节点池资源。请改为修改集群配置文件中的相关部分。

Anthos 虚拟机运行时

  • 重启 pod 会导致 pod 上的虚拟机更改 IP 地址或完全丢失其 IP 地址。如果虚拟机的 IP 地址发生变化,这不会影响作为 Kubernetes 服务公开的虚拟机应用的可达性。如果 IP 地址丢失,您必须从虚拟机运行 dhclient 以获取虚拟机的 IP 地址。

SELinux

创建 pod 期间的 SELinux 错误

当 SELinux 阻止容器运行时在 tmpfs 装载上设置标签时,Pod 创建有时会失败。这种故障很少见,但当 SELinux 处于 Enforcing 模式和某些内核时可能会发生这种情况。

如需验证 SELinux 是否是 pod 创建失败的原因,请使用以下命令检查 kubelet 日志中的错误:

journalctl -u kubelet

如果 SELinux 导致 pod 创建失败,则命令响应中会包含如下错误:

error setting label on mount source '/var/lib/kubelet/pods/
6d9466f7-d818-4658-b27c-3474bfd48c79/volumes/kubernetes.io~secret/localpv-token-bpw5x':
failed to set file label on /var/lib/kubelet/pods/
6d9466f7-d818-4658-b27c-3474bfd48c79/volumes/kubernetes.io~secret/localpv-token-bpw5x:
permission denied

如需验证此问题与 SELinux 强制执行相关,请运行以下命令:

ausearch -m avc

此命令会在审核日志中搜索访问矢量缓存 (AVC) 权限错误。以下示例响应中的 avc: denied 确认 pod 创建失败与 SELinux 强制执行相关。

type=AVC msg=audit(1627410995.808:9534): avc:  denied  { associate } for
pid=20660 comm="dockerd" name="/" dev="tmpfs" ino=186492
scontext=system_u:object_r:container_file_t:s0:c61,c201
tcontext=system_u:object_r:locale_t:s0 tclass=filesystem permissive=0

使用 SELinux 创建此 pod 问题的根本原因是在以下 Linux 映像中发现一个内核错误:

  • 8.3 之前的 Red Hat Enterprise Linux (RHEL) 版本
  • 8.3 之前的 CentOS 版本

重新启动机器有助于从问题中恢复。

为防止 Pod 创建错误发生,请使用 RHEL 8.3 或更高版本,或 CentOS 8.3 或更高版本,因为这些版本已修复内核错误。

快照

以非根用户身份截取快照

对于 Anthos clusters on Bare Metal 1.8.1 版及更早版本,如果您不以根用户身份登录,则无法使用 bmctl 命令截取集群快照。从 1.8.2 版开始,裸机上的 Anthos 集群将遵循集群规范中的 nodeAccess.loginUser。如果管理员集群无法访问,您可以使用 --login-user 标志指定登录用户。

请注意,如果您将 containerd 用作容器运行时,则快照仍会运行 crictl 命令。如需查看解决方法,请参阅 Containerd 需要在 PATH 中使用 /usr/local/bin。用于 SUDO 的 PATH 设置会导致此问题。

GKE Connect

崩溃循环 gke-connect-agent Pod

大量使用 GKE Connect 网关有时可能会导致 gke-connect-agent Pod 内存不足问题。这些内存不足问题的症状包括:

  • gke-connect-agent Pod 表现出大量重启症状,或者最终出现崩溃循环状态。
  • 连接网关停止运行。

如需解决此内存不足问题,请修改 gke-connect 命名空间下前缀为 gke-connect-agent 的部署,并将内存限制提高到 256 MiB 或更高。

kubectl patch deploy $(kubectl get deploy -l app=gke-connect-agent -n gke-connect -o jsonpath='{.items[0].metadata.name}') -n gke-connect --patch '{"spec":{"containers":[{"resources":{"limits":{"memory":"256Mi"}}}]}}'

此问题在 Anthos clusters on Bare Metal 1.8.2 和更高版本中已得到修复。

日志记录和监控

stackdriver-log-forwarder Pod 卡住重启

对于 1.9 之前的 Anthos clusters on Bare Metal,如果节点被强制关停,则 stackdriver-log-forwarder Pod 可能会卡在重启状态。在这种情况下,您可能会看到如下所示的日志条目:

[error] [input:storage_backlog:storage_backlog.7] chunk validation failed, data might
be corrupted. Found 0 valid records, failed content starts right after byte 0.

stackdriver-log-forwarder Pod 卡住时,大多数日志都会被阻止进入 Cloud Logging,任何未刷新的数据都将丢失。要解决此问题,请重置日志记录流水线。

如需重置日志记录流水线,请执行以下操作:

  1. stackdriver-operator 进行纵向缩容。

    kubectl --kubeconfig=KUBECONFIG -n kube-system scale deploy \
        stackdriver-operator --replicas=0
    
  2. 删除 stackdriver-log-forwarder DaemonSet:

    kubectl --kubeconfig KUBECONFIG -n kube-system delete daemonset \
        stackdriver-log-forwarder
    

    在继续下一步之前,先验证 stackdriver-log-forwarder Pod 是否已删除。

  3. 部署以下 DaemonSet 以清理 fluent-bit 缓冲区中的任何损坏数据:

    kubectl --kubeconfig KUBECONFIG -n kube-system apply -f - << EOF
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: fluent-bit-cleanup
      namespace: kube-system
    spec:
      selector:
        matchLabels:
          app: fluent-bit-cleanup
      template:
        metadata:
          labels:
            app: fluent-bit-cleanup
        spec:
          containers:
          - name: fluent-bit-cleanup
            image: debian:10-slim
            command: ["bash", "-c"]
            args:
            - |
              rm -rf /var/log/fluent-bit-buffers/
              echo "Fluent Bit local buffer is cleaned up."
              sleep 3600
            volumeMounts:
            - name: varlog
              mountPath: /var/log
            securityContext:
              privileged: true
          tolerations:
          - key: "CriticalAddonsOnly"
            operator: "Exists"
          - key: node-role.kubernetes.io/master
            effect: NoSchedule
          - key: node-role.gke.io/observability
            effect: NoSchedule
          volumes:
          - name: varlog
            hostPath:
              path: /var/log
    EOF
    
  4. 确保 DaemonSet 已清理所有节点。

    以下命令的输出应等于集群中的节点数。

    kubectl --kubeconfig KUBECONFIG logs -n kube-system -l app=fluent-bit-cleanup | \
        grep "cleaned up" | wc -l
    kubectl --kubeconfig KUBECONFIG -n kube-system get pods -l app=fluent-bit-cleanup \
        --no-headers | wc -l
    
  5. 删除清理 DaemonSet:

    kubectl --kubeconfig KUBECONFIG -n kube-system delete ds fluent-bit-cleanup
    
  6. 对运算符进行扩容,并等待其重新部署日志记录流水线。

    kubectl --kubeconfig=KUBECONFIG -n kube-system scale deploy \
        stackdriver-operator --replicas=1
    

此问题在 Anthos clusters on Bare Metal 1.9.0 和更高版本中已得到修复。