任务

Edit This Page

Kubefed 搭建联邦集群

Deprecated

强烈建议不要使用联邦 v1 版本联邦 v1 版本从未达到 GA 状态,且不再处于积极开发阶段。文档仅作为历史参考。

有关更多信息,请参阅预期的替代品 Kubernetes 联邦 v2 版本

Kubernetes 1.5及更高版本包括一个名为kubefed的新命令行工具,可帮助您管理联邦集群。 kubefed 可帮助您部署新的 Kubernetes 集群联合控制平面,以及向现有联合控制平面添加集群或从现有联合控制平面删除集群。

本文介绍了如何使用 kubefed 管理 Kubernetes 联邦集群。

说明: kubefed 是 Kubernetes 1.6 中的 beta 功能。

准备开始

你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。 如果你还没有集群,你可以通过 Minikube 构建一 个你自己的集群,或者你可以使用下面任意一个 Kubernetes 工具构建:

为了检查版本, 输入 kubectl version.

前提

本文假设您有一个正在运行的 Kubernetes 集群。 请参阅入门指南获取适用于您平台的安装说明。

获取 kubefed

下载特定发行版相对应的客户端 tarball,并提取 tarball 二进制文件:

Note: 在 Kubernetes 1.8.x 之前,联合项目是作为核心 kubernetes repo的一部分进行维护。在 Kubernetes 1.81.9 之间,联合项目移到了一个单独的联邦 repo中,现在已在其中维护。因此,联合发布信息可在[发行页面]](https://github.com/kubernetes/federation/releases)上找到。

对于 Kubernetes 1.8.x 和更老版本:

curl -LO https://storage.googleapis.com/kubernetes-release/release/${RELEASE-VERSION}/kubernetes-client-linux-amd64.tar.gz
tar -xzvf kubernetes-client-linux-amd64.tar.gz
Note: 应该将 RELEASE-VERSION 变量设置或替换为所需的实际版本。

将提取的二进制文件复制到 $PATH 中的任意目录,并给予二进制文件可执行权限。

sudo cp kubernetes/client/bin/kubefed /usr/local/bin
sudo chmod +x /usr/local/bin/kubefed

对于 Kubernetes 1.9.x 及更高版本:

curl -LO https://storage.cloud.google.com/kubernetes-federation-release/release/${RELEASE-VERSION}/federation-client-linux-amd64.tar.gz
tar -xzvf federation-client-linux-amd64.tar.gz
Note: RELEASE-VERSION 变量应替换为联邦发布页面上可用的发行版本之一。

将提取的二进制文件复制到 $PATH 中的任意目录,并给予二进制文件可执行权限。

sudo cp federation/client/bin/kubefed /usr/local/bin
sudo chmod +x /usr/local/bin/kubefed

安装 kubectl

您可以按照安装 kubectl说明安装匹配的 kubectl 版本。

选择主机集群

您需要选择一个 Kubernetes 集群作为 *host cluster*。主机集群托管组成联邦控制平面的组件。 确保主机集群相对应的本地 kubeconfig 中有一个 kubeconfig 条目。 您可以通过运行以下命令来验证您是否具有必备的 kubeconfig 条目:

kubectl config get-contexts

应输出包含与您的主机集群相对应的条目,类似以下内容:

CURRENT   NAME                                          CLUSTER                                       AUTHINFO                                      NAMESPACE
*         gke_myproject_asia-east1-b_gce-asia-east1     gke_myproject_asia-east1-b_gce-asia-east1     gke_myproject_asia-east1-b_gce-asia-east1

部署联合控制平面时,您需要为主机集群提供 kubeconfig 上下文(上面条目中的名称)。

部署联邦控制平面

要在主机群集上部署联合控制平面,请运行kubefed init命令。 使用 kubefed init 时,您必须提供以下内容:

如果主机集群在非云环境中运行,或者在不支持常见云原语的环境(例如负载平衡器)中运行,则可能需要其他标志。 请参阅下面的本地主机集群部分。

以下示例命令部署名称为 fellowship,主机集群上下文 rivendell 和域名后缀 example.com. 的联合控制平面:

kubefed init fellowship \
    --host-cluster-context=rivendell \
    --dns-provider="google-clouddns" \
    --dns-zone-name="example.com."

--dns-zone-name 中指定的域名后缀必须是您控制的现有域名,并且可以由您的 DNS 提供程序进行编程。它还必须以 . 结尾。

联邦控制平面初始化后,查询命名空间:

kubectl get namespace --context=fellowship

如果您未看到列出的 default 命名空间(这是由于bug)。 使用以下命令自行创建:

kubectl create namespace default --context=fellowship

主机集群中的计算机必须具有适当的权限才能对正在使用的 DNS 服务进行编程。例如,如果您的集群在 Google Compute Engine 上运行,则必须为您的项目启用 Google Cloud DNS API。

默认情况下,创建的 Google Kubernetes Engine 集群中的计算机没有 Google Cloud DNS API 范围。 如果要使用 Google Kubernetes Engine 集群作为联邦身份验证主机,则必须使用 gcloud 字段中具有适当值的 gcloud 命令来创建它。您不能直接修改 Google Kubernetes Engine 集群来添加此范围,但是可以为集群创建一个新的节点池并删除旧的节点池。

Note: 这将导致集群的 Pod 重新安排。

要添加新的节点池,请运行:

scopes="$(gcloud container node-pools describe --cluster=gke-cluster default-pool --format='value[delimiter=","](config.oauthScopes)')"
gcloud container node-pools create new-np \
    --cluster=gke-cluster \
    --scopes="${scopes},https://www.googleapis.com/auth/ndev.clouddns.readwrite"

要删除旧的节点池,请运行:

gcloud container node-pools delete default-pool --cluster gke-cluster

kubefed init 在主机集群中设置联合控制平面,并在本地 kubeconfig 中添加联邦 API 服务器的条目。

Note:

在 Kubernetes 1.6 的 beta 版本中,kubefed init 不会自动将当前上下文设置为新部署的联邦。 您可以通过运行以下命令手动设置当前上下文:

kubectl config use-context fellowship

其中,fellowship 是联邦的名称。

基本和令牌认证支持

默认情况下,kubefed init 仅生成 TLS 证书和密钥与联邦 API 服务器进行身份验证,并将它们写入本地 kubeconfig 文件。 如果您希望出于调试目的启用基本身份验证或令牌身份验证,则可以通过传递 --apiserver-enable-basic-auth 参数或--apiserver-enable-token-auth 参数来启用它们。

kubefed init fellowship \
    --host-cluster-context=rivendell \
    --dns-provider="google-clouddns" \
    --dns-zone-name="example.com." \
    --apiserver-enable-basic-auth=true \
    --apiserver-enable-token-auth=true

将命令行参数传递给联邦组件

kubefed init 引导联邦控制平面使用默认参数传递给联邦 API 服务器和联邦控制器管理器, 其中一些参数是从 kubefed init 参数中派生的。但是您可以通过适当的覆盖参数来覆盖这些命令行参数。

您可以通过将联邦 API 服务器参数传递给 --apiserver-arg-overrides 来覆盖,并通过将联邦控制器管理器参数传递给 --controllermanager-arg-overrides 来覆盖。

kubefed init fellowship \
    --host-cluster-context=rivendell \
    --dns-provider="google-clouddns" \
    --dns-zone-name="example.com." \
    --apiserver-arg-overrides="--anonymous-auth=false,--v=4" \
    --controllermanager-arg-overrides="--controllers=services=false"

配置 DNS 提供商

联合服务控制器对 DNS 提供程序进行编程,以通过 DNS 名称公开联合服务。 如果主机集群的云提供程序与 DNS 提供程序相同,则某些云提供程序会自动提供对 DNS 提供程序进行编程所需的配置。 在所有其他情况下,您必须将 DNS 提供程序配置提供给联合身份验证控制器管理器,然后将其传递给联合身份验证服务控制器。 您可以通过将配置存储在文件中并将文件的本地文件系统路径传递到 kubefed init--dns-provider-config 标志来提供此配置给联合控制器管理器。例如,将以下配置保存在 $HOME/coredns-provider.conf 中。

[Global]
etcd-endpoints = http://etcd-cluster.ns:2379
zones = example.com.

然后将此文件传递给 kubefed init:

kubefed init fellowship \
    --host-cluster-context=rivendell \
    --dns-provider="coredns" \
    --dns-zone-name="example.com." \
    --dns-provider-config="$HOME/coredns-provider.conf"

本地主机集群

API 服务器服务类型

kubefed init 将联合 API 服务器作为主机集群上的 Kubernetes service公开。默认情况下,此服务公开为负载均衡服务。大多数本地和裸机环境,某些云环境缺少对负载均衡服务的支持。kubefed init 允许在此类环境中将联合身份验证 API 服务器公开为NodePort service。这可以通过传递 --api-server-service-type=NodePort 参数来完成。您还可以通过传递 --api-server-advertise-address=<IP-address> 参数来指定用于宣传联邦 API 服务器的首选地址。否则,将选择主机集群的节点地址之一作为默认值。

kubefed init fellowship \
    --host-cluster-context=rivendell \
    --dns-provider="google-clouddns" \
    --dns-zone-name="example.com." \
    --api-server-service-type="NodePort" \
    --api-server-advertise-address="10.0.10.20"

设置 etcd 的存储

联合控制平面将其状态存储在etcdetcd数据必须存储在永久性存储卷中,以确保跨联合控制平面重新启动的正确操作。在支持动态调配存储卷的主机集群上, kubefed init 动态配置PersistentVolume并将其绑定到PersistentVolumeClaim来存储etcd数据。如果您的主机集群不支持动态配置,则还可以静态配置PersistentVolumekubefed init 创建PersistentVolumeClaim具有以下配置:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  annotations:
    volume.alpha.kubernetes.io/storage-class: "yes"
  labels:
    app: federated-cluster
  name: fellowship-federation-apiserver-etcd-claim
  namespace: federation-system
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

要静态设置PersistentVolume,您必须确保创建的PersistentVolume具有匹配的存储类,访问模式,并且容量至少与请求的PersistentVolumeClaim一致。

或者,您可以通过将 --etcd-persistent-storage=false 传递给 kubefed init 来完全禁用持久性存储。 但是,我们不建议您这样做,因为您的联合控制平面在这种模式下无法重启。

kubefed init fellowship \
    --host-cluster-context=rivendell \
    --dns-provider="google-clouddns" \
    --dns-zone-name="example.com." \
    --etcd-persistent-storage=false

kubefed init 仍然不支持将现有的PersistentVolumeClaim附加到它引导的联盟控制平面上。我们计划在 kubefed 的未来版本中对此提供支持。

CoreDNS 支持

联合服务现在支持CoreDNS作为 DNS 提供程序之一。如果您在无法访问基于云的 DNS 提供程序的环境中运行集群和联合身份验证,则可以运行自己的CoreDNS实例并发布联合服务 DNS 名称到该服务器。

您可以通过将合适的值传递给 kubefed init--dns-provider--dns-provider-config 标志来配置联合以使用CoreDNS

kubefed init fellowship \
    --host-cluster-context=rivendell \
    --dns-provider="coredns" \
    --dns-zone-name="example.com." \
    --dns-provider-config="$HOME/coredns-provider.conf"

有关更多信息,请参见将 CoreDNS 设置为联邦集群的 DNS 提供程序

AWS Route53 支持

当联合身份验证控制器管理器在内部运行时,可以将 AWS Route53 用作云 DNS 提供程序。 控制器管理器部署必须配置有 AWS 凭证,因为它无法从 AWS 上运行 VM 隐式收集它们。

当前,kubefed init 不会从 --dns-provider-config 标志中读取 AWS Route53 凭据,因此必须应用补丁。

通过将标志 --dns-provider="aws-route53" 传递给 kubefed init,初始化内部联盟控制器时,将 AWS Route53 指定为 DNS 提供程序。

使用您的 AWS 凭证创建补丁文件:

spec:
  template:
    spec:
      containers:
      - name: controller-manager
        env:
        - name: AWS_ACCESS_KEY_ID
          value: "ABCDEFG1234567890"
        - name: AWS_SECRET_ACCESS_KEY
          value: "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"

补丁部署:

kubectl -n federation-system patch deployment controller-manager --patch "$(cat <patch-file-name>.yml)"

其中 <patch-file-name> 是您在上面创建的文件的名称。

将集群添加到联邦

部署联邦控制平面后,需要使控制平面知道其应管理的集群。

将集群加入联盟:

  1. 更改内容:

    kubectl config use-context fellowship
  1. 如果使用的是托管集群服务,则允许该服务访问集群。为此,请为集群服务关联的帐户创建一个 clusterrolebinding:

    kubectl create clusterrolebinding <your_user>-cluster-admin-binding --clusterrole=cluster-admin --user=<your_user>@example.org --context=<joining_cluster_context>
  1. 使用 kubefed join 将集群加入联盟,并确保您提供以下内容:

    <!– * The name of the cluster that you are joining to the federation

    • --host-cluster-context, the kubeconfig context for the host cluster

    For example, this command adds the cluster gondor to the federation running on host cluster rivendell: –> * 您要加入联邦的集群名称 * --host-cluster-context, 主机集群的 kubeconfig 上下文

    例如, 此命令将集群 gondor 添加到在主机集群 rivendell 上运行的联合身份验证中:

    kubefed join gondor --host-cluster-context=rivendell

现在,已将一个新上下文添加到您的 kubeconfig 中,名为 fellowship (在联邦名称之后)。

Note: 您提供给 join 命令的名称在联合身份验证中用作联接集群的标识。 此名称应遵守identifiers 文档中描述的规则。 如果您加入集群相对应的上下文符合这些规则,则可以在 join 命令中使用相同的名称。否则,您必须为集群的身份选择其他名称。

命名规则和自定义

您提供给 kubefed join 的集群名称必须是有效的RFC 1035标签,并在Identifiers doc中进行枚举。

此外,联合控制平面需要已加入集群的凭据才能在它们上面进行操作。 这些凭证是从本地 kubeconfig 获得的。kubefed join 使用指定的集群名称作为参数在本地 kubeconfig 中寻找集群的上下文。如果找不到匹配的上下文,则会退出并显示错误。

如果联合中每个集群的上下文名称未遵循RFC 1035标签命名规则,则可能会导致问题。 在这种情况下,您可以指定符合RFC 1035标签命名规则的集群名称,并使用 --cluster-context 标志指定集群上下文。例如,如果要加入集群的上下文是 gondor_needs-no_king,则可以通过运行以下命令加入集群:

kubefed join gondor --host-cluster-context=rivendell --cluster-context=gondor_needs-no_king

密钥名称

如上所述,联合身份验证控制平面所需的集群凭据作为秘密存储在主机集群中。密钥名称也从集群名称中派生。

但是,Kubernetes 中的密钥对象的名称应符合RFC 1123中描述的 DNS 子域名规范。 如果不是这种情况,您可以使用 --secret-name 标志将密钥名称传递给 kubefed join。 例如,如果集群名称为 noldor,而秘密名称为 11kingdom,则可以通过运行以下命令加入集群:

kubefed join noldor --host-cluster-context=rivendell --secret-name=11kingdom
Note: 如果您的集群名称不符合 DNS 子域名规范,则您需要做的就是使用 --secret-name 标志提供密钥名称。kubefed join 会自动为您创建密钥。

kube-dns 配置

必须在每个加入群集中更新 kube-dns 配置,以启用联合服务发现。如果加入的 Kubernetes 集群是 1.5 或更高版本,而您的 kubefed 是 1.6 或更高版本,那么当使用 kubefed joinunjoin 命令来加入或者不加入集群时,将自动为您管理此配置。

在所有其他情况下,您必须按照管理指南更新管理指南的 KubeDNS 部分中的说明手动更新 kube-dns 配置。

从联邦中删除集群

要从联合中删除集群,请运行带有集群名称和联邦 --host-cluster-contextkubefed unjoin命令:

kubefed unjoin gondor --host-cluster-context=rivendell

调低联邦控制平面

在 beta 版本的 kubefed 中,没有完全实现对联邦控制平面的正确清理。但是,暂时删除联合系统命令空间应该会删除所有资源,除了为联合控制平面的 etcd 动态提供的持久性存储卷之外。您可以通过运行以下命令来删除联合命名空间:

kubectl delete ns federation-system --context=rivendell
Note: rivendell 是主机集群名称,用您配置中的合适名称替换该名称。

反馈