sealos进行k8s安装之后的集群,本身是没有ipv6支持的,为了能外部ipv6访问,我们需要让svc和pod进行一个ipv6支持(当然可以在外部添加nginx等方案解决)

首先我们需要将系统的ipv6转发打开

net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
net.ipv6.conf.all.forwarding=1
sysctl -p

k8s 启用双栈

之后开始配置k8s这边

从 1.21 开始 IPv4/IPv6 双协议栈默认为启用状态。 你可以在必要的时候通过为 kube-apiserver、kube-controller-manager、kubelet 和 kube-proxy 命令行设置 --feature-gates="IPv6DualStack=false" 来禁用 此特性。

在下列组件中多添加一个ipv6 cidr,可以参照这个用例

  • kube-apiserver:
    • --service-cluster-ip-range=<IPv4 CIDR>,fd00::/108
  • kube-controller-manager:
    • --cluster-cidr=<IPv4 CIDR>,fc00::/48
    • --service-cluster-ip-range=<IPv4 CIDR>,fd00::/108
    • --node-cidr-mask-size-ipv4=24
    • --node-cidr-mask-size-ipv6=64
  • kube-proxy:
    • kubectl -n kube-system edit cm kube-proxy
    • data
      • config.conf :
        • featureGates:
          • IPv6DualStack: true
        • clusterCIDR: 172.16.0.0/16,fc00::/48

此时svc已经可以调整ipv6的clusterip了,可以通过.spec.ipFamilyPolicy 设置为 PreferDualStack

然后设定ipFamilies:

ipFamilies:
  - IPv6
  - IPv4

其中第一个ipfamilies为默认值,即.spec.ClusterIP的值

此时设置为仅ipv6,那么endpoints将会匹配不到任何东西,因为pod还没有分配ipv6,我们需要配置cni插件

calico

sealos会默认安装calico,我们这里仅演示calico

kubectl edit configmap calico-config -n kube-system

修改calico的configmap,这里面有个json文件,修改以下内容

"ipam": {
        "type": "calico-ipam",
        "assign_ipv4": "true",
        "assign_ipv6": "true"
    },

修改calico 的 daemonset 的环境变量

    - name: IP
      value: "autodetect"

    - name: IP6
      value: "autodetect"

    - name: CALICO_IPV4POOL_CIDR
      value: "172.16.0.0/16"

    - name: CALICO_IPV6POOL_CIDR
      value: "fc00::/48"

    - name: FELIX_IPV6SUPPORT
      value: "true"

接着重启各种容器就行了

验证:

kubectl get pods pod01 -o go-template --template='{{range .status.podIPs}}{{printf "%s \n" .ip}}{{end}}'

如果pod出现两个ip,说明成功了,可以试着ping一下

我们当然不能把所有pod接入ipv6,很多的镜像对此并没有支持,唯一需要配置的其实是traefik

traefik

在自己helm的traefik配置中添加如下:

service:
  ipFamilyPolicy: PreferDualStack

用如下命令检查

kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .status.addresses}}{{printf "%s: %s \n" .type .address}}{{end}}'

如果节点没有检测到ipv6,建议使用nodeport模式 (以下仅演示)

deployment:
  kind: DaemonSet
ports:
  web:
    nodePort: 80
  websecure:
    nodePort: 443 
service:
  ipFamilyPolicy: PreferDualStack
helm repo add traefik https://helm.traefik.io/traefik
helm repo update
helm install traefik traefik/traefik -f traefik-values.yaml --namespace=traefik-v2 --create-namespace

创建如下yaml

# dashboard.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: dashboard
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`traefik.localhost`) && (PathPrefix(`/dashboard`) || PathPrefix(`/api`))
      kind: Rule
      services:
        - name: api@internal
          kind: TraefikService
kubectl apply -f dashboard.yaml

访问网站若成功即配置成功