kubernetes安装traefik ingress,替换原来的nginx-ingress

一.实施背景

现有环境的k8s集群的ingress控制器,原来使用的是nginx-ingress,现在想替换为traefik ingress,以下是实施步骤

二.实施步骤

1.首先梳理现有 Nginx-Ingress 的关键信息,避免冲突

复制代码
# 查看 Nginx-Ingress 的命名空间、Ingress Class、端口
kubectl get ingressclasses # 查看集群内的 IngressClass(K8s 1.18+ 支持,1.15 需看注解)
kubectl get pods -A -l app=nginx-ingress # 查看 Nginx Pod 所在命名空间
kubectl get svc -A -l app=nginx-ingress # 查看 Nginx 暴露的端口(如 NodePort: 30080/30443 或 HostPort 80/443)

2.部署traefik

  • 创建命名空间

    kubectl create namespace traefik

  • traefik依赖的RBAC 权限配置

Traefik 需要访问 K8s API 来监听 Ingress、Service 等资源,创建 traefik-rbac.yaml

复制代码
# traefik-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: traefik
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingresses
      - ingressclasses # K8s 1.20 新增
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - pods
    verbs:
      - list
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
      - list
      - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: traefik-ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-controller
subjects:
  - kind: ServiceAccount
    name: traefik-ingress-controller
    namespace: traefik
  • 创建traefik的ds

DaemonSet 模式可让 Traefik 运行在每个节点,通过 HostPort 暴露 80/443 端口(如果nginx-ingress已经使用这些端口,修改进行替换其他端口),适合生产环境。创建 traefik-daemonset.yaml

复制代码
# traefik-daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: traefik
  namespace: traefik
  labels:
    app: traefik
spec:
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      hostNetwork: true # 主机网络,便于后续端口切换
      containers:
      - name: traefik
        image: traefik:v2.9.10 # 适配 K8s 1.20 的稳定版本
        args:
          - --api.insecure=true # 测试阶段开启仪表盘(生产关闭)
          - --accesslog=true
          - --entrypoints.web.address=:8080 # 非冲突 HTTP 端口
          - --entrypoints.websecure.address=:8443 # 非冲突 HTTPS 端口
          - --kubernetesIngress=true
          - --kubernetesIngress.ingressClass=traefik # 绑定 IngressClass
          - --providers.kubernetesCRD=false # 暂不启用 CRD,仅用 Ingress
          - --providers.kubernetesIngress=true
        ports:
        - name: web
          containerPort: 8080
          hostPort: 8080 # 主机端口(非冲突)
        - name: websecure
          containerPort: 8443
          hostPort: 8443 # 主机端口(非冲突)
        - name: dashboard
          containerPort: 8081
          hostPort: 8081 # 仪表盘端口
        securityContext:
          capabilities:
            drop: [ALL]
            add: [NET_BIND_SERVICE]
        resources:
          limits:
            cpu: 1000m
            memory: 512Mi
          requests:
            cpu: 100m
            memory: 64Mi
        livenessProbe:
          httpGet:
            path: /ping
            port: 8081
          initialDelaySeconds: 10
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ping
            port: 8081
          initialDelaySeconds: 5
          periodSeconds: 5
      tolerations:
        - key: node-role.kubernetes.io/control-plane
          operator: Exists
          effect: NoSchedule
        - key: node-role.kubernetes.io/master
          operator: Exists
          effect: NoSchedule
---
# Traefik 仪表盘 Service(测试用)
apiVersion: v1
kind: Service
metadata:
  name: traefik-dashboard
  namespace: traefik
spec:
  selector:
    app: traefik
  ports:
  - name: dashboard
    port: 8081
    targetPort: 8081
    nodePort: 30801
  type: NodePort

kubectl apply -f traefik.yaml
  • 验证部署

    kubectl get pods -n traefik

    输出示例(每个节点一个 Pod):

    traefik-ingress-controller-7f557 1/1 Running 0 5m

    在任意节点执行

    netstat -tulpn | grep 80

    应看到 traefik 进程监听 80/443/8080 端口

  • 创建 Traefik IngressClass(K8s 1.20 原生)

    traefik-ingressclass.yaml

    apiVersion: networking.k8s.io/v1
    kind: IngressClass
    metadata:
    name: traefik
    annotations:
    ingressclass.kubernetes.io/is-default-class: "false" # 非默认,避免抢占流量
    spec:
    controller: traefik.containo.us/ingress-controller # Traefik 2.x 标识

  • 全量迁移 Ingress

单Ingress 修改(少量),前期测试

复制代码
kubectl edit ingress <ingress-name> -n <namespace>
# 修改 spec.ingressClassName 为 traefik(替换原 nginx)

批量修改(大量 Ingress)

复制代码
# 批量更新 default 命名空间所有 Ingress 的 ingressClassName
kubectl get ingress -n default -o name | xargs -I {} kubectl patch {} -n default --type='json' -p='[{"op": "replace", "path": "/spec/ingressClassName", "value":"traefik"}]'

# 跨命名空间批量更新(需 jq)
for ns in $(kubectl get ns -o json | jq -r '.items[].metadata.name'); do
  kubectl get ingress -n $ns -o name 2>/dev/null | xargs -I {} kubectl patch {} -n $ns --type='json' -p='[{"op": "replace", "path": "/spec/ingressClassName", "value":"traefik"}]' 2>/dev/null
done
  • 待全量迁移完成后,将 Traefik 设为默认控制器,新创建的 Ingress 会自动使用 Traefik

    编辑 Traefik IngressClass,添加默认注解

    kubectl edit ingressclass traefik
    metadata:
    annotations:
    ingressclass.kubernetes.io/is-default-class: "true" # 设为默认

    同时将 Nginx IngressClass 的该注解改为 "false"

    kubectl edit ingressclass nginx
    metadata:
    annotations:
    ingressclass.kubernetes.io/is-default-class: "false"

  • 下线 Nginx-Ingress(可选)

待 Traefik 稳定运行 24-72 小时后,逐步下线 Nginx-Ingress

复制代码
# 缩容 Nginx DaemonSet/Deployment 为 0
kubectl scale daemonset nginx-ingress-controller -n ingress-nginx --replicas=0
# 或 Deployment 模式:
kubectl scale deployment nginx-ingress-controller -n ingress-nginx --replicas=0

#完全删除
# 删除 Nginx-Ingress 相关资源
kubectl delete ns ingress-nginx
kubectl delete ingressclass nginx
kubectl delete clusterrole nginx-ingress-clusterrole
kubectl delete clusterrolebinding nginx-ingress-clusterrolebinding
  • 回退(紧急情况)

    1. 批量恢复 IngressClassName 为 nginx

    for ns in (kubectl get ns -o json | jq -r '.items[].metadata.name'); do kubectl get ingress -n ns -o name 2>/dev/null | xargs -I {} kubectl patch {} -n $ns --type='json' -p='[{"op": "replace", "path": "/spec/ingressClassName", "value":"nginx"}]' 2>/dev/null
    done

    2. 恢复 Nginx 副本数

    kubectl scale daemonset nginx-ingress-controller -n ingress-nginx --replicas=3

    3. 临时切回 Nginx 端口(按节点恢复 HostPort/LoadBalancer)

相关推荐
忍冬行者2 小时前
kubeadm部署的kubernetes集群的etcd由默认静态pod改为二级制的etcd集群
容器·kubernetes·etcd
爬也要爬着前进2 小时前
zookeeper迁移k8s
zookeeper·kubernetes·debian
篙芷2 小时前
k8s Service 暴露方式详解:ClusterIP、NodePort、LoadBalancer 与 Headless Service
云原生·容器·kubernetes
篙芷2 小时前
k8s节点绑定:nodeName与nodeSelector实战
linux·docker·kubernetes
aashuii2 小时前
k8s POD上RDMA网卡VF不生效问题
云原生·容器·kubernetes
weixin_46682 小时前
K8S-Ingress
云原生·容器·kubernetes
l1t2 小时前
wsl docker安装达梦数据库的过程
数据库·docker·容器·达梦
lbb 小魔仙2 小时前
eBPF+Linux 6.18:云原生环境下的安全监控与故障排查实战
linux·运维·云原生
Wzx1980122 小时前
go聊天室项目docker部署
运维·docker·容器