如何在使用kubeadm部署的Kubernetes集群中扩大Pod CIDR范围?

5
我使用了 --pod-network-cidr 参数部署了我的集群,并使用 calicoctl 创建了新的 IP 池来将 Pod 转换到此范围。我遇到的问题是需要在 Kubernetes 方面进行哪些更改以使 Pod 的 CIDR 范围发生变化?我需要在 API 服务器、控制器管理器和调度器中进行更改,还是只需要更改特定的部分。我尝试仅更改控制器管理器,在 yaml 中更改了--cluster-cidr 后,这些控制平面的 Pod 陷入了崩溃循环。
下面是控制器管理器日志的输出: controllermanager.go:235] 启动控制器时发生错误:无法标记 cidr[192.168.0.0/24] 在索引 [0] 上为 node 占用:cidr 192.168.0.0/24 超出了集群 cidr 10.0.0.0/16 的范围。
2个回答

14

更改集群CIDR并不是一项简单的任务。我成功重现了您的情况,并使用以下步骤进行了更改:

更改IP池

步骤如下:

  1. 安装calicoctl作为Kubernetes pod (来源)。
  2. 添加一个新的IP池 (来源)。
  3. 禁用旧的IP池。这可以防止从旧的IP池分配新的IPAM地址,而不会影响现有工作负载的网络。
  4. 更改节点的podCIDR参数 (来源)。
  5. 在主节点上的kube-controller-manager.yaml上更改--cluster-cidr。(感谢OP)。
  6. 重新创建所有已分配旧IP池地址的现有工作负载。
  7. 删除旧IP池。

让我们开始吧。

在本示例中,我们将把192.168.0.0/16更改为10.0.0.0/8

  1. 将calicoctl安装为Kubernetes pod
$ kubectl apply -f https://docs.projectcalico.org/manifests/calicoctl.yaml
设置别名:
$ alias calicoctl="kubectl exec -i -n kube-system calicoctl -- /calicoctl "
  • 新增一个IP地址池:

  • calicoctl create -f -<<EOF
    apiVersion: projectcalico.org/v3
    kind: IPPool
    metadata:
      name: new-pool
    spec:
      cidr: 10.0.0.0/8
      ipipMode: Always
      natOutgoing: true
    EOF
    

    我们现在应该有两个启用的IP池,可以在运行calicoctl get ippool -o wide时看到:

    NAME                  CIDR             NAT    IPIPMODE   DISABLED
    default-ipv4-ippool   192.168.0.0/16   true   Always     false
    new-pool              10.0.0.0/8       true   Always     false
    
  • 停用旧的IP池。

    首先将IP池定义保存到磁盘:

  • calicoctl get ippool -o yaml > pool.yaml
    

    pool.yaml应该长这样:

    apiVersion: projectcalico.org/v3
    items:
    - apiVersion: projectcalico.org/v3
      kind: IPPool
      metadata:
        name: default-ipv4-ippool
      spec:
        cidr: 192.168.0.0/16
        ipipMode: Always
        natOutgoing: true
    - apiVersion: projectcalico.org/v3
      kind: IPPool
      metadata:
        name: new-pool
      spec:
        cidr: 10.0.0.0/8
        ipipMode: Always
        natOutgoing: true
    

    注意:为提高可读性,一些特定于集群的额外信息已被省略。

    编辑该文件,在 default-ipv4-ippool IP池中添加 disabled: true

    apiVersion: projectcalico.org/v3
    kind: IPPool
    metadata:5
      name: default-ipv4-ippool
    spec:
      cidr: 192.168.0.0/16
      ipipMode: Always
      natOutgoing: true
      disabled: true
    

    应用更改:

    calicoctl apply -f pool.yaml
    

    我们应该在 calicoctl get ippool -o wide 的输出中看到更改的反映:

    NAME                  CIDR             NAT    IPIPMODE   DISABLED
    default-ipv4-ippool   192.168.0.0/16   true   Always     true
    new-pool              10.0.0.0/8       true   Always     false
    
  • 更改节点的podCIDR参数:

    通过以下命令以理想方式覆盖特定k8s节点资源上的podCIDR参数,使用新的IP源范围:


  • 更改节点的podCIDR参数:

    通过以下命令以理想方式覆盖特定k8s节点资源上的podCIDR参数,使用新的IP源范围:

    $ kubectl get no kubeadm-0 -o yaml > file.yaml; sed -i "s~192.168.0.0/24~10.0.0.0/16~" file.yaml; kubectl delete no kubeadm-0 && kubectl create -f file.yaml
    $ kubectl get no kubeadm-1 -o yaml > file.yaml; sed -i "s~192.168.1.0/24~10.1.0.0/16~" file.yaml; kubectl delete no kubeadm-1 && kubectl create -f file.yaml
    $ kubectl get no kubeadm-2 -o yaml > file.yaml; sed -i "s~192.168.2.0/24~10.2.0.0/16~" file.yaml; kubectl delete no kubeadm-2 && kubectl create -f file.yaml    
    

    我们必须对每个节点执行此操作。注意IP范围,它们在不同节点之间是不同的。

  • 在kubeadm-config ConfigMap和kube-controller-manager.yaml上更改CIDR。

  • 编辑kubeadm-config ConfigMap并将podSubnet更改为新的IP范围:

    kubectl -n kube-system edit cm kubeadm-config
    

    此外,需要在主节点的 /etc/kubernetes/manifests/kube-controller-manager.yaml 文件中更改 --cluster-cidr

    $ sudo cat /etc/kubernetes/manifests/kube-controller-manager.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: null
      labels:
        component: kube-controller-manager
        tier: control-plane
      name: kube-controller-manager
      namespace: kube-system
    spec:
      containers:
      - command:
        - kube-controller-manager
        - --allocate-node-cidrs=true
        - --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
        - --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
        - --bind-address=127.0.0.1
        - --client-ca-file=/etc/kubernetes/pki/ca.crt
        - --cluster-cidr=10.0.0.0/8
        - --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
        - --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
        - --controllers=*,bootstrapsigner,tokencleaner
        - --kubeconfig=/etc/kubernetes/controller-manager.conf
        - --leader-elect=true
        - --node-cidr-mask-size=24
        - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
        - --root-ca-file=/etc/kubernetes/pki/ca.crt
        - --service-account-private-key-file=/etc/kubernetes/pki/sa.key
        - --service-cluster-ip-range=10.96.0.0/12
        - --use-service-account-credentials=true
    
    1. 使用禁用池中的IP重新创建所有现有工作负载。在此示例中,kube-dns是唯一由Calico进行网络连接的工作负载:

    kubectl delete pod -n kube-system kube-dns-6f4fd4bdf-8q7zp
    

    运行calicoctl get wep --all-namespaces命令,检查新工作负载是否在新的IP池中有一个地址:

    NAMESPACE     WORKLOAD                   NODE      NETWORKS            INTERFACE
    kube-system   kube-dns-6f4fd4bdf-8q7zp   vagrant   10.0.24.8/32   cali800a63073ed
    
  • 删除旧的IP池:

  • calicoctl delete pool default-ipv4-ippool
    
    使用Kubeadm和Calico在特定IP范围下部署集群,需要使用--pod-network-cidr=192.168.0.0/24来初始化集群(其中192.168.0.0/24是你想要的范围),然后在新集群中应用之前,需要调整Calico清单。

    为了在应用之前调整Calico,您需要下载其yaml文件并更改网络范围。

  • 下载Kubernetes的Calico网络清单文件。
  • $ curl https://docs.projectcalico.org/manifests/calico.yaml -O
    
  • 如果您正在使用Pod CIDR 192.168.0.0/24,请跳到下一步。 如果您使用的是不同的Pod CIDR,请使用以下命令设置一个名为POD_CIDR的环境变量,其中包含您的Pod CIDR,并在清单中将192.168.0.0/24替换为您的Pod CIDR。
  • $ POD_CIDR="<your-pod-cidr>" \
    sed -i -e "s?192.168.0.0/16?$POD_CIDR?g" calico.yaml
    
    使用以下命令应用清单。
    $ kubectl apply -f calico.yaml
    

    如果我们最初按照上述步骤创建了集群,后来意识到需要扩展范围以包括更多IP地址,是否有办法进行更改?我们已经以这种方式部署,并且有所需求,而不需要重建整个集群。 - mmiara
    1
    我更新了我的答案,包括如何在不需要重建集群的情况下更改它的步骤。 - Mark Watney
    1
    对我来说这很有意义。使用10.0.0.0/16、10.1.0.0/16和10.2.0.0/16可能是一个非常好的主意。 - Mark Watney
    1
    我编辑了我的回答,包括你提到的要点和在kubeadm-config ConfigMap中的额外更改。 - Mark Watney
    1
    我对示例中使用的IP范围感到困惑。Calico中定义的IP池是10.0.0.0/16,但节点正在使用10.1.0.0/16和10.2.0.0/16 - 这些IP不在calico IP池的范围内,那么它们如何用于节点变量的IP范围?您可以确认上述配置是否正确吗? - mmiara
    显示剩余8条评论

    1
    除了接受的答案外,在我的情况下,我必须更改此文件中的calico-ipamipv4_pools参数:/etc/cni/net.d/10-calico.conflist/etc/cni/net.d/calico.conflist.template 总之,在所有节点上:
    vim /etc/cni/net.d/10-calico.conflist
    vim /etc/cni/net.d/calico.conflist.template
    {
      "name": "k8s-pod-network",
      "cniVersion":"0.3.1",
      "plugins":[
        {
          "datastore_type": "kubernetes",
          "nodename": "node-1",
          "type": "calico",
          "log_level": "info",
          "log_file_path": "/var/log/calico/cni/cni.log",
          "ipam": {
            "type": "calico-ipam",
            "ipv4_pools": ["192.168.0.0/24"], #CHANGE HERE!! e.g. 10.0.0.0/8
            "assign_ipv4": "true"
          },
          "policy": {
            "type": "k8s"
          },
          "kubernetes": {
            "kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
          }
        },
    ...
    
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接