前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Spiderpool为Pod添加Underlay网卡

使用Spiderpool为Pod添加Underlay网卡

原创
作者头像
DifficultWork
修改2024-01-16 10:14:39
5190
修改2024-01-16 10:14:39
举报
文章被收录于专栏:阶梯计划阶梯计划

前言

本文介绍在一个 Calico 作为缺省 CNI 的集群,通过 Spiderpool 这一完整的 Underlay 网络解决方案,通过 Multus 为 Pod 额外附加一张由 Macvlan 创建的网卡,为集群提供Underlay数据面。

1 环境介绍

  • 集群环境:3个宿主机节点,已经使用Calico作为CNI,CIDR是197.166.0.0/16,k8s版本v1.23.6。
  • Spiderpool 版本:v0.8.3
  • Multus-CNI 版本:v3.9.3
  • 预留的 Underlay IP:100.10.22.210~100.10.22.218

2 安装步骤

由于集群在一个内网环境,所以无法按照官网的指导进行操作。只能把helm的charts和依赖镜像下载到本地操作。

2.1 下载 cni charts 和镜像

  • CNI 因为需要用到macvlan的CNI插件,所以要手动下载,这里下载的是v1.3.0
  • Spiderpool charts 在 github spidernet-io/spiderpool 的 github_pages 这个分支,在 docs/charts/ 下找到对应版本——spiderpool-0.8.3.tgz。
  • Spiderpool-controller 镜像 docker pull ghcr.io/spidernet-io/spiderpool/spiderpool-controller:v0.8.3
  • Spiderpool-agent 镜像 docker pull ghcr.io/spidernet-io/spiderpool/spiderpool-agent:v0.8.3
  • Multus-cni 镜像 docker pull ghcr.io//k8snetworkplumbingwg/multus-cni:v3.9.3

下载完成后将镜像使用docker save -o xxx.tar保存成文件,和spiderpool-0.8.3.tgz一并拷贝到环境的宿主机上(集群所有宿主机都要有),并使用docker load -i xxx.tar加载好镜像(注意加载后要恢复docker tag)。CNI解压后把macvlan的二进制放到集群所有宿主机的/opt/cni/bin下面。

2.2 检查 kube-system/kubeadm-config ConfigMap

spiderpool 默认从 kubeadm-config 中获取 service 的子网信息,如果没有这个ConfigMap需要手动创建一个,简单的文件(kubeadm-config.yaml)如下:

代码语言:yaml
复制
networking:
  podSubnet: 197.166.0.0/16
  serviceSubnet: 169.169.0.0/16

注意里面的子网信息要和集群创建时的保持一致。

使用如下命令创建:

代码语言:bash
复制
kubectl create configmap kubeadm-config -n kube-system --from-file=./kubeadm-config.yaml

PS:目前 spiderpool v0.8.3 的版本还有这个依赖,已经给社区提了issue,后续版本可能会解除这个依赖。

2.3 安装

需要确保环境宿主机上已经有了helm。

  • 解压缩 charts 并使用 Helm 更新依赖tar -xvf spiderpool-0.8.3.tgz
代码语言:bash
复制
helm dep update ./spiderpool
  • 安装Spiderpool
代码语言:bash
复制
helm install spiderpool ./spiderpool --namespace kube-system  --set coordinator.mode=overlay --wait

参数介绍

参数

作用

coordinator.mode

这里指定overlay才是作为第二个网卡

multus.multusCNI.defaultCniCRName

指定 multus 默认使用的 CNI 的 NetworkAttachmentDefinition(NAD) 实例名。如果参数选项不为空,则安装后会自动生成一个数据为空的 NAD 对应实例。如果参数选项为空,会尝试通过 /etc/cni/net.d 目录下的第一个 CNI 配置来创建对应的 NAD 实例,否则会自动生成一个名为 default 的 NAD 实例

multus.install

默认是自动安装multus,如果已经安装multus,先要显式设置为false

  • 安装完成后,查看 Spiderpool 组件状态
代码语言:bash
复制
~# kubectl get pod -n kube-system | grep spiderpool
spiderpool-agent-9ffcc                                 1/1     Running            0                  64s
spiderpool-agent-jq6sq                                 1/1     Running            0                  64s
spiderpool-agent-kz8m4                                 1/1     Running            0                  64s
spiderpool-controller-59bcd9985b-hz42m                 1/1     Running            0                  86s
spiderpool-init                                        1/1     Running            0                  86s
  • 检查 Spidercoordinator.status 中的 Phase 是否为 Synced, 并且 overlayPodCIDR 是否与集群中 Calico 的子网保持一致
代码语言:bash
复制
~# calicoctl get ippools
NAME                  CIDR                  SELECTOR   
default-ipv4-ippool   197.166.0.0/16        all()      
default-ipv6-ippool   fd97:6fea:542f::/48   all() 

~# kubectl  get spidercoordinators.spiderpool.spidernet.io default -o yaml
apiVersion: spiderpool.spidernet.io/v2beta1
kind: SpiderCoordinator
metadata:
  creationTimestamp: "2023-12-26T06:04:24Z"
  finalizers:
  - spiderpool.spidernet.io
  generation: 1
  name: default
  resourceVersion: "4407909"
  selfLink: /apis/spiderpool.spidernet.io/v2beta1/spidercoordinators/default
  uid: 64822833-357d-4f41-af81-262d22380a3b
spec:
  detectGateway: false
  detectIPConflict: false
  hijackCIDR:
  - 169.254.0.0/16
  hostRPFilter: 0
  hostRuleTable: 500
  mode: overlay
  podCIDRType: auto
  podDefaultRouteNIC: ""
  podMACPrefix: ""
  tunePodRoutes: true
status:
  overlayPodCIDR:
  - 197.166.0.0/16
  - fd97:6fea:542f::/48
  phase: Synced
  serviceCIDR:
  - 169.169.0.0/16

(如果 phase 不为 Synced, 那么将会阻止 Pod 被创建,如果 overlayPodCIDR 不正常, 可能会导致通信问题)

  • 创建 SpiderIPPool Underlay 的网卡 enp1s0 所在子网为 100.10.22.0/24,以该子网创建 SpiderIPPool:
代码语言:bash
复制
cat << EOF | kubectl apply -f -
apiVersion: spiderpool.spidernet.io/v2beta1
kind: SpiderIPPool
metadata:
  name: underlay-pool
spec:
  disable: false
  gateway: 100.10.22.134
  ips:
  - 100.10.22.210-100.10.22.218
  subnet: 100.10.22.0/24
EOF

subnet 应该与节点网卡 enp1s0 的子网保持一致,并且 ips 不与现有任何 IP 冲突。

  • 创建 SpiderMultusConfig 通过 Spidermultusconfig 创建 Multus 的 NAD 实例:
代码语言:bash
复制
cat << EOF | kubectl apply -f -
apiVersion: spiderpool.spidernet.io/v2beta1
kind: SpiderMultusConfig
metadata:
  name: macvlan-enp1s0
spec:
  cniType: macvlan
  macvlan:
    master:
    - enp1s0
    ippools:
      ipv4:
      - underlay-pool
    vlanID: 0
EOF

spec.macvlan.master 设置为 enp1s0, enp1s0 必须存在于主机上。并且 spec.macvlan.spiderpoolConfigPools.IPv4IPPool设置的子网和 enp1s0 保持一致。

创建成功后, 查看 Multus NAD 是否成功创建:

代码语言:bash
复制
kubectl  get network-attachment-definitions.k8s.cni.cncf.io  macvlan-enp1s0 -o yaml
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"spiderpool.spidernet.io/v2beta1","kind":"SpiderMultusConfig","metadata":{"annotations":{},"name":"macvlan-enp1s0","namespace":"default"},"spec":{"cniType":"macvlan","macvlan":{"ippools":{"ipv4":["underlay-pool"]},"master":["enp1s0"],"vlanID":0}}}
  creationTimestamp: "2023-12-27T02:21:40Z"
  generation: 1
  name: macvlan-enp1s0
  namespace: default
  ownerReferences:
  - apiVersion: spiderpool.spidernet.io/v2beta1
    blockOwnerDeletion: true
    controller: true
    kind: SpiderMultusConfig
    name: macvlan-enp1s0
    uid: daa7e75e-cf40-4112-a7a3-307ce2f94b52
  resourceVersion: "4409741"
  selfLink: /apis/k8s.cni.cncf.io/v1/namespaces/default/network-attachment-definitions/macvlan-enp1s0
  uid: 20c156d0-c326-474c-86bb-21e7de0fdc5f
spec:
  config: '{"cniVersion":"0.3.1","name":"macvlan-enp1s0","plugins":[{"type":"macvlan","master":"enp1s0","mode":"bridge","ipam":{"type":"spiderpool","default_ipv4_ippool":["underlay-pool"]}},{"detectIPConflict":false,"detectGateway":false,"mode":"auto","type":"coordinator"}]}'

3 创建一个带 Underlay 网卡的应用

我这里用go做了一个简单的http应用镜像,默认监听8080端口,收到请求后会返回所有IPv4地址。代码如下:

代码语言:go
复制
package main

import (
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"os"
	"runtime"
)

type Handler struct {
	str []string
}

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s, _ := json.Marshal(h.str)
	w.Write([]byte(s))
}

func main() {
	runtime.GOMAXPROCS(2)
	port, ok := os.LookupEnv("SERVER_PORT")
	if !ok {
		port = "8080"
	}

	addrs, err := net.InterfaceAddrs()
	if err != nil {
		fmt.Println(err)
		return
	}
	ips := []string{}
	for _, address := range addrs {
		if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				ips = append(ips, ipnet.IP.String())
			}
		}
	}

	http.Handle("/", &Handler{ips})
	if err = http.ListenAndServe(":"+port, nil); err != nil {
		fmt.Println(err.Error())
	}
}

这里打包成一个httpd:0.0.1的镜像。

使用下面的命令创建测试应用 httpd:

代码语言:bash
复制
cat << EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      annotations:
        k8s.v1.cni.cncf.io/networks: macvlan-enp1s0
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd
        image: httpd:0.0.1
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
EOF

PS:k8s.v1.cni.cncf.io/networks: 该字段指定 Multus 使用 macvlan-enp1s0 为 Pod 附加一张网卡。

等Pod Running状态后查看:

代码语言:bash
复制
kubectl describe pod httpd-85f96ddc76-7tjzt
中间省略...
Events:
  Type     Reason                  Age                 From               Message
  ----     ------                  ----                ----               -------
  Normal   Scheduled               16m                 default-scheduler  Successfully assigned default/httpd-85f96ddc76-7tjzt to 100.10.22.104
  Normal   AddedInterface          6m51s               multus             Add eth0 [197.166.25.41/32] from kube-system/k8s-pod-network
  Normal   AddedInterface          6m51s               multus             Add net1 [100.10.22.213/24] from default/macvlan-enp1s0

然后从同vlan其他主机访问Pod:

代码语言:bash
复制
curl 100.10.22.213:8080
["197.166.25.41","100.10.22.213"]

4 补充 IPv6 双栈

4.1 创建一个 v6 的 IPPool

代码语言:bash
复制
cat << EOF | kubectl apply -f -
apiVersion: spiderpool.spidernet.io/v2beta1
kind: SpiderIPPool
metadata:
  name: underlay-pool-v6
spec:
  disable: false
  ips:
  - 2001:db8::a00:64ff:fe0a:1691-2001:db8::a00:64ff:fe0a:1699
  subnet: 2001:db8::/64
EOF

注意,这里没有加网关。

4.2 重新创建 Mutus 的 NAD 实例

代码语言:bash
复制
cat << EOF | kubectl apply -f -
apiVersion: spiderpool.spidernet.io/v2beta1
kind: SpiderMultusConfig
metadata:
  name: macvlan-enp1s0
spec:
  cniType: macvlan
  macvlan:
    master:
    - enp1s0
    ippools:
      ipv4:
      - underlay-pool
      ipv6:
      - underlay-pool-v6
    vlanID: 0
EOF

这里我们增加了 v6 的IPPool。

4.3 参考 3 重新部署下 http 应用

等Pod Running状态后查看:

代码语言:bash
复制
kubectl describe pod httpd-85d54455d-6xdbw
中间省略...
Events:
  Type    Reason          Age   From               Message
  ----    ------          ----  ----               -------
  Normal  Scheduled       32s   default-scheduler  Successfully assigned default/httpd-85d54455d-6xdbw to 100.10.22.106
  Normal  AddedInterface  31s   multus             Add eth0 [197.166.54.137/32 fd00:c5a6::2a:609/128] from kube-system/k8s-pod-network
  Normal  AddedInterface  31s   multus             Add net1 [100.10.22.213/24 2001:db8::a00:64ff:fe0a:1691/64] from default/macvlan-enp1s0
  Normal  Pulled          31s   kubelet            Container image "http:1.0.0" already present on machine
  Normal  Created         30s   kubelet            Created container httpd
  Normal  Started         30s   kubelet            Started container httpd

可以看到Pod的网卡信息已经是双栈。

然后从同vlan其他主机访问Pod:

代码语言:bash
复制
curl -6 http://[2001:db8::a00:64ff:fe0a:1691]:8080
["197.166.25.41","100.10.22.213"]

总结

整个安装过程还算比较顺利,中间遇到的问题,项目组的同学帮助也非常及时,在此表示感谢@郭奇峰

参考内容:

Calico Quick Start

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 1 环境介绍
  • 2 安装步骤
    • 2.1 下载 cni charts 和镜像
      • 2.2 检查 kube-system/kubeadm-config ConfigMap
        • 2.3 安装
        • 3 创建一个带 Underlay 网卡的应用
        • 4 补充 IPv6 双栈
          • 4.1 创建一个 v6 的 IPPool
            • 4.2 重新创建 Mutus 的 NAD 实例
              • 4.3 参考 3 重新部署下 http 应用
              • 总结
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档