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)

相关推荐
db_cy_206235 分钟前
Docker+Kubernetes企业级容器化部署解决方案(阶段一)
docker·容器·kubernetes·云计算·负载均衡·运维开发
百度Geek说1 小时前
百度流式计算开发平台的降本增效之路
运维·云原生
last demo1 小时前
docker容器
运维·docker·容器
Y.O.U..2 小时前
Kurbenetes-Service(1)
容器·kubernetes
last demo4 小时前
docker镜像
运维·docker·容器
ICT董老师4 小时前
kubernetes中operator与helm有什么区别?部署mysql集群是选择operator部署还是helm chart部署?
linux·运维·mysql·云原生·容器·kubernetes
L1624764 小时前
Prometheus 监控 K8s 集群全指南(适配 K8s 特性 + 实操部署)
docker·容器·kubernetes
王旭晨4 小时前
【高并发架构】从 0 到亿,从单机部署到 K8s 编排:高并发架构的 8 级演进之路
容器·架构·kubernetes
阿方索5 小时前
Kubernetes 1.28 高可用集群安装指南(Docker 运行时)
docker·容器·kubernetes
一个向上的运维者5 小时前
实战解析|EFK 日志系统数据同步问题全解(附核心配置模板)
elasticsearch·云原生