k8s保姆级教程:K8s高可用集群教程-02-Load Balancer和Ingress Controller

2026-04-13 12:011阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:

关注的小伙伴久等了,因为工作的变动,关于k8s的教程一直没有更新,最近稍微有点时间,这就继续更新了,新刷到的小伙伴可以先看上一篇:k8s保姆级教程:K8s高可用集群教程-01-使用 Kubespray 快速搭建集群(有手就行)
废话不多说,下面开始正文

第四部分:流量入口与可视化 (Load Balancer, Traefik & Dashboard)

在我们拥有了一个健康的高可用集群后,首要任务是打通集群内外的网络流量。在本地/裸机环境中,Kubernetes 原生并不提供负载均衡器的实现。因此,我们需要先部署一个 Load Balancer,这里使用 HAProxy),为后续的流量网关(Traefik)分配外部 IP,最后再部署 Dashboard 进行可视化管理。

提示:接下来的所有操作,都将在我们配置好 kubectl操作机上执行(任何一台master节点)。

4.1 部署前置依赖:配置 HAProxy 外置负载均衡器(Load Balancer)

在上一篇文章中,我们设计的架构中第一台机器为LB(172.16.5.194),我们将使用这台独立的服务器部署 HAProxy,作为整个集群的统一流量入口。它将承担两个核心职责:

  1. 控制平面高可用 (四层负载):将 6443 端口的请求代理到 3 台 Master 节点,实现 API Server 的高可用。
  2. 业务流量网关 (四层负载):将 80/443 端口的外部请求转发给运行了 Traefik Ingress 的 Worker 节点。

操作节点:登录 Load Balancer 服务器 (172.16.5.194) 执行以下操作。

1. 系统环境初始化

在安装软件前,我们需要对服务器进行基础的环境配置,包括时区同步、开启 IP 转发以及关闭 Swap。

# 1. 设置时区为亚洲/上海并验证 timedatectl set-timezone Asia/Shanghai # 2. 开启内核 IPv4 路由转发功能 (LB 节点必须开启) echo 'net.ipv4.ip_forward=1' | tee -a /etc/sysctl.conf sysctl -p # 3. 永久关闭 Swap 分区 (注释掉 /etc/fstab 中的 swap 行并立即生效) sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab && swapoff -a

2. 安装与配置 HAProxy

Ubuntu 系统自带的包管理器可以非常方便地安装 HAProxy。

# 更新软件源并安装 HAProxy apt update apt install -y haproxy # 备份原始默认配置文件 cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

接下来,编辑 HAProxy 的核心配置文件。

vim /etc/haproxy/haproxy.cfg

这是我的配置,请注意替换为你真实的节点 IP

global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners stats timeout 30s user haproxy group haproxy daemon # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http frontend kubernetes-api bind *:6443 mode tcp option tcplog default_backend kube-apiservers backend kube-apiservers mode tcp balance roundrobin option tcp-check default-server inter 3s fall 3 rise 2 server k8s-master-01 172.16.5.195:6443 check server k8s-master-02 172.16.5.196:6443 check server k8s-master-03 172.16.5.197:6443 check frontend traefik-http bind *:80 mode http option httplog default_backend traefik-http-backend frontend traefik-https bind *:443 mode tcp option tcplog default_backend traefik-https-backend # traefik 负载均衡 backend traefik-http-backend mode http balance roundrobin option httpchk GET /ping server k8s-master-01 172.16.5.195:80 check server k8s-master-02 172.16.5.196:80 check server k8s-master-03 172.16.5.197:80 check backend traefik-https-backend mode tcp balance roundrobin option tcp-check server k8s-master-01 172.16.5.195:443 check server k8s-master-02 172.16.5.196:443 check server k8s-master-03 172.16.5.197:443 check frontend traefik-dashboard bind *:9000 mode http option httplog default_backend traefik-dashboard-backend backend traefik-dashboard-backend mode http balance roundrobin server k8s-master-01 172.16.5.195:9000 check server k8s-master-02 172.16.5.196:9000 check server k8s-master-03 172.16.5.197:9000 check listen stats bind *:8404 mode http stats enable stats uri /stats stats refresh 10s

3. 校验并重启服务

配置完成后,先进行语法检查,确认无误后再重启服务。

# 检查配置文件语法是否正确 (输出 Configuration file is valid 为正常) haproxy -c -f /etc/haproxy/haproxy.cfg # 重启 HAProxy 服务应用最新配置 systemctl restart haproxy # 设置开机自启 systemctl enable haproxy

至此,我们的高可用负载均衡器已经就绪。所有的集群 API 请求以及后续域名的外网访问,都将通过这台机器的大门安全地分发到后端的 K8s 节点中。

4.2 部署 Traefik Ingress Controller

在 Kubespray 部署阶段,我特意禁用了默认的 Nginx Ingress,以便完全使用 Traefik 作为Ingress Controller。Traefik 作为一个云原生的边缘路由,与 Kubernetes 的集成非常平滑,且原生支持动态配置和自动 HTTPS(Let’s Encrypt) 。

1. 创建基础资源

  1. 我们有3个master节点,所以可以在3个节点上都打上标签,使 IngressProxy: "true" 生效,使用标签选择器的方式将pod固定到指定的节点上,防止服务漂移到其他节点,我这里使用master节点作为流量出入口

    #查看节点名 kubectl get nodes # 打标签 kubectl label nodes k8s-master-01 k8s-master-02 k8s-master-03 IngressProxy=true # 查看标签 kubectl get nodes --show-labels

  2. 01-configmap.yml注意配置,按需修改

    apiVersion: v1 kind: ConfigMap metadata: name: traefik-config namespace: default data: traefik.yaml: |- ping: {} # 启用 Ping global: checkNewVersion: false # 周期性的检查是否有新版本发布 sendAnonymousUsage: false # 周期性的匿名发送使用统计信息 # serversTransport: # insecureSkipVerify: true # Traefik忽略验证代理服务的TLS证书,如果内网的ssl证书为自己签发的,就打开这个 api: insecure: true # 允许HTTP 方式访问API dashboard: true # 启用Dashboard debug: false # 启用Debug调试模式 metrics: prometheus: # 配置Prometheus监控指标数据,并使用默认配置 addRoutersLabels: true # 添加routers metrics entryPoint: "metrics" # 指定metrics监听地址 entryPoints: web: address: ":80" # 配置80端口,并设置入口名称为 web forwardedHeaders: insecure: true # 信任所有的forward headers websecure: address: ":443" # 配置443端口,并设置入口名称为 websecure forwardedHeaders: insecure: true traefik: address: ":9000" # 配置9000端口为 dashboard 的端口,不设置默认值为 8080 metrics: address: ":9101" # 配置9101端口,作为metrics收集入口 tcpep: address: ":9200" # 配置9200端口,作为tcp入口 udpep: address: ":9300/udp" # 配置9300端口,作为udp入口 providers: kubernetesCRD: # 启用Kubernetes CRD方式来配置路由规则 # ingressClass: "traefik" # 指定traefik的ingressClass名称 allowCrossNamespace: true #允许跨namespace allowEmptyServices: true #允许空endpoints的service allowExternalNameServices: true # 是否允许使用 ExternalName 的服务 kubernetesIngress: ## 启用 Kubernetes Ingress 方式来配置路由规则 allowExternalNameServices: true # 是否允许使用 ExternalName 的服务 # kubernetesGateway: {} ## 启用 Kubernetes Gateway API experimental: plugins: traefik-plugin-query-modification: moduleName: "github.com/kingjan1999/traefik-plugin-query-modification" version: "v1.0.0" # kubernetesGateway: true ## 允许使用 Kubernetes Gateway API log: filePath: "/etc/traefik/logs/traefik.log" # 设置调试日志文件存储路径,如果为空则输出到控制台 level: "info" # 设置调试日志级别 format: "common" # 设置调试日志格式 accessLog: filePath: "/etc/traefik/logs/access.log" # 设置访问日志文件存储路径,如果为空则输出到控制台 format: "common" # 设置访问调试日志格式 bufferingSize: 0 # 设置访问日志缓存行数 filters: # statusCodes: ["200"] # 设置只保留指定状态码范围内的访问日志 retryAttempts: true # 设置代理访问重试失败时,保留访问日志 minDuration: 20 # 设置保留请求时间超过指定持续时间的访问日志 fields: # 设置访问日志中的字段是否保留(keep保留、drop不保留) defaultMode: keep # 设置默认保留访问日志字段 names: # 针对访问日志特别字段特别配置保留模式 ClientUsername: drop StartUTC: drop # 禁用日志timestamp使用UTC headers: # 设置Header中字段是否保留 defaultMode: keep # 设置默认保留Header中字段 names: # 针对Header中特别字段特别配置保留模式 User-Agent: redact # 可以针对指定agent Authorization: drop Content-Type: keep

  3. 02-kubernetes-crd-definition-v1.yml此文件为官方下载,不要改动,这里我直接提供文件
    02-kubernetes-crd-definition-v1.yml.zip (18.7 KB)

  4. 03-kubernetes-crd-rbac.yml,此文件中出现了很多个name,分别表示不同层级的资源,为了避免新手对这些name混淆,我统一都使用了同一个名字

    apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: # ClusterRole 的名称(权限集合的名字) # 后面会被 ClusterRoleBinding 引用 name: traefik-ingress-controller rules: - apiGroups: - "" resources: - services # Service 资源 - secrets # Secret(用于 TLS 等) - nodes # Node(节点信息) verbs: - get # 获取单个资源 - list # 列出资源 - watch # 监听变化(控制器必须) - apiGroups: - discovery.k8s.io resources: - endpointslices verbs: - list - watch - apiGroups: - extensions - networking.k8s.io resources: - ingresses - ingressclasses verbs: - get - list - watch - apiGroups: - extensions - networking.k8s.io resources: - ingresses/status verbs: - update # 访问 Traefik 自定义资源(CRD) - apiGroups: - traefik.io resources: - middlewares # HTTP 中间件 - middlewaretcps # TCP 中间件 - ingressroutes # HTTP 路由 - traefikservices # Traefik 自定义 Service - ingressroutetcps # TCP 路由 - ingressrouteudps # UDP 路由 - tlsoptions # TLS 配置 - tlsstores # TLS 存储 - serverstransports # HTTP 传输配置 - serverstransporttcps # TCP 传输配置 verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: # 绑定对象的名字(随意,但通常和 ClusterRole 同名方便管理) name: traefik-ingress-controller roleRef: # 指定要绑定的权限(ClusterRole) apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: traefik-ingress-controller # ← 必须对应上面定义的 ClusterRole 名字 subjects: # 指定“谁”来使用这些权限 - kind: ServiceAccount name: traefik-ingress-controller # ← ServiceAccount 名称 namespace: default # ← 所在命名空间

  5. 04-serviceaccount.yml对应上面权限的使用者

    apiVersion: v1 kind: ServiceAccount metadata: namespace: default name: traefik-ingress-controller

2. Traefik 部署清单

  1. 05-traefik-deploy.yml上面的配置都是声明资源,接下来就是服务本身了

    apiVersion: v1 kind: Service metadata: labels: app: traefik-ingress-controller name: traefik-ingress-controller namespace: default spec: selector: app: traefik-ingress-controller ports: - name: web port: 80 - name: websecure port: 443 - name: dashboard port: 9000 - name: tcpep port: 9200 protocol: TCP - name: udpep protocol: UDP port: 9300 --- apiVersion: apps/v1 kind: DaemonSet metadata: name: traefik-ingress-controller namespace: default labels: app: traefik-ingress-controller spec: selector: matchLabels: app: traefik-ingress-controller template: metadata: name: traefik-ingress-controller labels: app: traefik-ingress-controller spec: serviceAccountName: traefik-ingress-controller terminationGracePeriodSeconds: 5 # 等待容器优雅退出的时长 containers: - name: traefik image: traefik:v3.1.7 env: - name: KUBERNETES_SERVICE_HOST # 手动指定k8s api,避免网络组件不稳定,这里使用了Load Balancer的地址 value: "172.16.5.194" - name: KUBERNETES_SERVICE_PORT_HTTPS # API server端口 value: "6443" - name: KUBERNETES_SERVICE_PORT # API server端口 value: "6443" - name: TZ # 指定时区 value: "Asia/Shanghai" ports: - name: web containerPort: 80 hostPort: 80 # 将容器端口绑定所在服务器的 80 端口 - name: websecure containerPort: 443 hostPort: 443 # 将容器端口绑定所在服务器的 443 端口 - name: dashboard containerPort: 9000 # Traefik Dashboard 端口 - name: metrics containerPort: 9101 hostPort: 9101 # metrics 端口,由于 node_exporter 占据了 9100 端口,改到 9101 - name: tcpep containerPort: 9200 # tcp端口 - name: udpep containerPort: 9300 # udp端口 securityContext: # 只开放网络权限 capabilities: drop: - ALL add: - NET_BIND_SERVICE args: - --configfile=/etc/traefik/config/traefik.yaml volumeMounts: - mountPath: /etc/traefik/config name: config - mountPath: /etc/traefik/logs name: logdir - mountPath: /etc/localtime name: timezone readOnly: true resources: requests: memory: "5Mi" cpu: "10m" limits: memory: "256Mi" cpu: "1000m" readinessProbe: httpGet: path: /ping port: 9000 failureThreshold: 3 initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 livenessProbe: httpGet: path: /ping port: 9000 failureThreshold: 3 initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 volumes: - name: config # traefik配置文件 configMap: name: traefik-config - name: logdir # traefik日志目录 hostPath: path: /var/log/traefik type: "DirectoryOrCreate" - name: timezone # 挂载时区文件 hostPath: path: /etc/localtime type: File tolerations: # 设置容忍所有污点,防止节点被设置污点 - operator: "Exists" hostNetwork: true # 开启host网络,提高网络入口的网络性能 nodeSelector: # 设置node筛选器,在特定label的节点上启动 IngressProxy: "true" # 调度至IngressProxy: "true"的节点

  2. 06-tlsoption.yml

    apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: # TLSOption 名称 # 可以被 IngressRoute / Ingress 引用 name: default # 所在命名空间(必须和引用它的资源一致,或显式指定) namespace: default spec: # 最低 TLS 版本限制 # VersionTLS12 表示拒绝 TLS 1.0 / 1.1,只允许 1.2 及以上 minVersion: VersionTLS12 # 指定允许的加密套件(cipher suites) # 控制 HTTPS 连接的加密强度和算法 cipherSuites: - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # TLS 1.2(高强度,推荐) - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 # TLS 1.2(移动设备性能好) - TLS_AES_256_GCM_SHA384 # TLS 1.3(默认推荐) - TLS_CHACHA20_POLY1305_SHA256 # TLS 1.3(高性能) # 椭圆曲线优先级(用于 ECDHE 密钥交换) # 顺序表示优先级(从高到低) curvePreferences: - CurveP521 # 安全性最高,但性能稍低 - CurveP384 # 平衡安全与性能(常用) # 是否启用严格 SNI 检查 sniStrict: true

    07-middleware.yml

    # Redirect to https apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: redirect-https-middleware spec: redirectScheme: scheme: https permanent: true

3. 安装部署,验证 Traefik 状态

# 将上面的所有文件都保存到本地的同一个目录下,执行从01-05的yml文件 kubectl apply -f 01-configmap.yml -f 02-kubernetes-crd-definition-v1.yml -f 03-kubernetes-crd-rbac.yml -f 04-serviceaccount.yml -f 05-traefik-deploy.yml # 等待一会查看状态,traefik 状态均为ready,继续执行06和07 kubectl get all -n default kubectl apply -f 06-tlsoption.yml -f 07-middleware.yml

4.使用IngressRoute暴漏Traefik Dashboard服务

# traefik-dashboard-route.yaml --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: traefik-dashboard-route namespace: default spec: entryPoints: - web routes: - match: Host(`traefik.k8s.example.com`) kind: Rule services: - name: traefik-ingress-controller port: 9000

访问测试

  1. 请确保你在本地电脑的 hosts 文件或内网 DNS 中,将域名(如 traefik.k8s.example.com)解析到了你的负载均衡 (LB) 节点 IP
  2. 打开浏览器,访问 http://traefik.k8s.example.com,此时你就能看到Traefik的可视化界面
网友解答:
--【壹】--:

现在好像都在推gatewayapi和istio,听说ingress要被取代了


--【贰】--:

必须支持


--【叁】--:

教程很硬核


--【肆】--:

只能说各自有各自的用途吧,技术是不断迭代的,我是把一年前的操作复现了一下,写了这个教程,对于绝大多数只能在内网使用的用户都是够用了


--【伍】--:

实际使用的话,我比较习惯实用metallb,不依赖外部,直接集群级别控制lb(LoadBalancer)。
另外Ingress已经被社区淘汰(确切的说,是淘汰中),
建议新的集群,直接使用Gateway API,不要再使用Ingress了.


--【陆】--:

感谢大佬


--【柒】--:

支持前排


--【捌】--:

支持支持


--【玖】--:

感谢大佬教程

问题描述:

关注的小伙伴久等了,因为工作的变动,关于k8s的教程一直没有更新,最近稍微有点时间,这就继续更新了,新刷到的小伙伴可以先看上一篇:k8s保姆级教程:K8s高可用集群教程-01-使用 Kubespray 快速搭建集群(有手就行)
废话不多说,下面开始正文

第四部分:流量入口与可视化 (Load Balancer, Traefik & Dashboard)

在我们拥有了一个健康的高可用集群后,首要任务是打通集群内外的网络流量。在本地/裸机环境中,Kubernetes 原生并不提供负载均衡器的实现。因此,我们需要先部署一个 Load Balancer,这里使用 HAProxy),为后续的流量网关(Traefik)分配外部 IP,最后再部署 Dashboard 进行可视化管理。

提示:接下来的所有操作,都将在我们配置好 kubectl操作机上执行(任何一台master节点)。

4.1 部署前置依赖:配置 HAProxy 外置负载均衡器(Load Balancer)

在上一篇文章中,我们设计的架构中第一台机器为LB(172.16.5.194),我们将使用这台独立的服务器部署 HAProxy,作为整个集群的统一流量入口。它将承担两个核心职责:

  1. 控制平面高可用 (四层负载):将 6443 端口的请求代理到 3 台 Master 节点,实现 API Server 的高可用。
  2. 业务流量网关 (四层负载):将 80/443 端口的外部请求转发给运行了 Traefik Ingress 的 Worker 节点。

操作节点:登录 Load Balancer 服务器 (172.16.5.194) 执行以下操作。

1. 系统环境初始化

在安装软件前,我们需要对服务器进行基础的环境配置,包括时区同步、开启 IP 转发以及关闭 Swap。

# 1. 设置时区为亚洲/上海并验证 timedatectl set-timezone Asia/Shanghai # 2. 开启内核 IPv4 路由转发功能 (LB 节点必须开启) echo 'net.ipv4.ip_forward=1' | tee -a /etc/sysctl.conf sysctl -p # 3. 永久关闭 Swap 分区 (注释掉 /etc/fstab 中的 swap 行并立即生效) sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab && swapoff -a

2. 安装与配置 HAProxy

Ubuntu 系统自带的包管理器可以非常方便地安装 HAProxy。

# 更新软件源并安装 HAProxy apt update apt install -y haproxy # 备份原始默认配置文件 cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

接下来,编辑 HAProxy 的核心配置文件。

vim /etc/haproxy/haproxy.cfg

这是我的配置,请注意替换为你真实的节点 IP

global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners stats timeout 30s user haproxy group haproxy daemon # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http frontend kubernetes-api bind *:6443 mode tcp option tcplog default_backend kube-apiservers backend kube-apiservers mode tcp balance roundrobin option tcp-check default-server inter 3s fall 3 rise 2 server k8s-master-01 172.16.5.195:6443 check server k8s-master-02 172.16.5.196:6443 check server k8s-master-03 172.16.5.197:6443 check frontend traefik-http bind *:80 mode http option httplog default_backend traefik-http-backend frontend traefik-https bind *:443 mode tcp option tcplog default_backend traefik-https-backend # traefik 负载均衡 backend traefik-http-backend mode http balance roundrobin option httpchk GET /ping server k8s-master-01 172.16.5.195:80 check server k8s-master-02 172.16.5.196:80 check server k8s-master-03 172.16.5.197:80 check backend traefik-https-backend mode tcp balance roundrobin option tcp-check server k8s-master-01 172.16.5.195:443 check server k8s-master-02 172.16.5.196:443 check server k8s-master-03 172.16.5.197:443 check frontend traefik-dashboard bind *:9000 mode http option httplog default_backend traefik-dashboard-backend backend traefik-dashboard-backend mode http balance roundrobin server k8s-master-01 172.16.5.195:9000 check server k8s-master-02 172.16.5.196:9000 check server k8s-master-03 172.16.5.197:9000 check listen stats bind *:8404 mode http stats enable stats uri /stats stats refresh 10s

3. 校验并重启服务

配置完成后,先进行语法检查,确认无误后再重启服务。

# 检查配置文件语法是否正确 (输出 Configuration file is valid 为正常) haproxy -c -f /etc/haproxy/haproxy.cfg # 重启 HAProxy 服务应用最新配置 systemctl restart haproxy # 设置开机自启 systemctl enable haproxy

至此,我们的高可用负载均衡器已经就绪。所有的集群 API 请求以及后续域名的外网访问,都将通过这台机器的大门安全地分发到后端的 K8s 节点中。

4.2 部署 Traefik Ingress Controller

在 Kubespray 部署阶段,我特意禁用了默认的 Nginx Ingress,以便完全使用 Traefik 作为Ingress Controller。Traefik 作为一个云原生的边缘路由,与 Kubernetes 的集成非常平滑,且原生支持动态配置和自动 HTTPS(Let’s Encrypt) 。

1. 创建基础资源

  1. 我们有3个master节点,所以可以在3个节点上都打上标签,使 IngressProxy: "true" 生效,使用标签选择器的方式将pod固定到指定的节点上,防止服务漂移到其他节点,我这里使用master节点作为流量出入口

    #查看节点名 kubectl get nodes # 打标签 kubectl label nodes k8s-master-01 k8s-master-02 k8s-master-03 IngressProxy=true # 查看标签 kubectl get nodes --show-labels

  2. 01-configmap.yml注意配置,按需修改

    apiVersion: v1 kind: ConfigMap metadata: name: traefik-config namespace: default data: traefik.yaml: |- ping: {} # 启用 Ping global: checkNewVersion: false # 周期性的检查是否有新版本发布 sendAnonymousUsage: false # 周期性的匿名发送使用统计信息 # serversTransport: # insecureSkipVerify: true # Traefik忽略验证代理服务的TLS证书,如果内网的ssl证书为自己签发的,就打开这个 api: insecure: true # 允许HTTP 方式访问API dashboard: true # 启用Dashboard debug: false # 启用Debug调试模式 metrics: prometheus: # 配置Prometheus监控指标数据,并使用默认配置 addRoutersLabels: true # 添加routers metrics entryPoint: "metrics" # 指定metrics监听地址 entryPoints: web: address: ":80" # 配置80端口,并设置入口名称为 web forwardedHeaders: insecure: true # 信任所有的forward headers websecure: address: ":443" # 配置443端口,并设置入口名称为 websecure forwardedHeaders: insecure: true traefik: address: ":9000" # 配置9000端口为 dashboard 的端口,不设置默认值为 8080 metrics: address: ":9101" # 配置9101端口,作为metrics收集入口 tcpep: address: ":9200" # 配置9200端口,作为tcp入口 udpep: address: ":9300/udp" # 配置9300端口,作为udp入口 providers: kubernetesCRD: # 启用Kubernetes CRD方式来配置路由规则 # ingressClass: "traefik" # 指定traefik的ingressClass名称 allowCrossNamespace: true #允许跨namespace allowEmptyServices: true #允许空endpoints的service allowExternalNameServices: true # 是否允许使用 ExternalName 的服务 kubernetesIngress: ## 启用 Kubernetes Ingress 方式来配置路由规则 allowExternalNameServices: true # 是否允许使用 ExternalName 的服务 # kubernetesGateway: {} ## 启用 Kubernetes Gateway API experimental: plugins: traefik-plugin-query-modification: moduleName: "github.com/kingjan1999/traefik-plugin-query-modification" version: "v1.0.0" # kubernetesGateway: true ## 允许使用 Kubernetes Gateway API log: filePath: "/etc/traefik/logs/traefik.log" # 设置调试日志文件存储路径,如果为空则输出到控制台 level: "info" # 设置调试日志级别 format: "common" # 设置调试日志格式 accessLog: filePath: "/etc/traefik/logs/access.log" # 设置访问日志文件存储路径,如果为空则输出到控制台 format: "common" # 设置访问调试日志格式 bufferingSize: 0 # 设置访问日志缓存行数 filters: # statusCodes: ["200"] # 设置只保留指定状态码范围内的访问日志 retryAttempts: true # 设置代理访问重试失败时,保留访问日志 minDuration: 20 # 设置保留请求时间超过指定持续时间的访问日志 fields: # 设置访问日志中的字段是否保留(keep保留、drop不保留) defaultMode: keep # 设置默认保留访问日志字段 names: # 针对访问日志特别字段特别配置保留模式 ClientUsername: drop StartUTC: drop # 禁用日志timestamp使用UTC headers: # 设置Header中字段是否保留 defaultMode: keep # 设置默认保留Header中字段 names: # 针对Header中特别字段特别配置保留模式 User-Agent: redact # 可以针对指定agent Authorization: drop Content-Type: keep

  3. 02-kubernetes-crd-definition-v1.yml此文件为官方下载,不要改动,这里我直接提供文件
    02-kubernetes-crd-definition-v1.yml.zip (18.7 KB)

  4. 03-kubernetes-crd-rbac.yml,此文件中出现了很多个name,分别表示不同层级的资源,为了避免新手对这些name混淆,我统一都使用了同一个名字

    apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: # ClusterRole 的名称(权限集合的名字) # 后面会被 ClusterRoleBinding 引用 name: traefik-ingress-controller rules: - apiGroups: - "" resources: - services # Service 资源 - secrets # Secret(用于 TLS 等) - nodes # Node(节点信息) verbs: - get # 获取单个资源 - list # 列出资源 - watch # 监听变化(控制器必须) - apiGroups: - discovery.k8s.io resources: - endpointslices verbs: - list - watch - apiGroups: - extensions - networking.k8s.io resources: - ingresses - ingressclasses verbs: - get - list - watch - apiGroups: - extensions - networking.k8s.io resources: - ingresses/status verbs: - update # 访问 Traefik 自定义资源(CRD) - apiGroups: - traefik.io resources: - middlewares # HTTP 中间件 - middlewaretcps # TCP 中间件 - ingressroutes # HTTP 路由 - traefikservices # Traefik 自定义 Service - ingressroutetcps # TCP 路由 - ingressrouteudps # UDP 路由 - tlsoptions # TLS 配置 - tlsstores # TLS 存储 - serverstransports # HTTP 传输配置 - serverstransporttcps # TCP 传输配置 verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: # 绑定对象的名字(随意,但通常和 ClusterRole 同名方便管理) name: traefik-ingress-controller roleRef: # 指定要绑定的权限(ClusterRole) apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: traefik-ingress-controller # ← 必须对应上面定义的 ClusterRole 名字 subjects: # 指定“谁”来使用这些权限 - kind: ServiceAccount name: traefik-ingress-controller # ← ServiceAccount 名称 namespace: default # ← 所在命名空间

  5. 04-serviceaccount.yml对应上面权限的使用者

    apiVersion: v1 kind: ServiceAccount metadata: namespace: default name: traefik-ingress-controller

2. Traefik 部署清单

  1. 05-traefik-deploy.yml上面的配置都是声明资源,接下来就是服务本身了

    apiVersion: v1 kind: Service metadata: labels: app: traefik-ingress-controller name: traefik-ingress-controller namespace: default spec: selector: app: traefik-ingress-controller ports: - name: web port: 80 - name: websecure port: 443 - name: dashboard port: 9000 - name: tcpep port: 9200 protocol: TCP - name: udpep protocol: UDP port: 9300 --- apiVersion: apps/v1 kind: DaemonSet metadata: name: traefik-ingress-controller namespace: default labels: app: traefik-ingress-controller spec: selector: matchLabels: app: traefik-ingress-controller template: metadata: name: traefik-ingress-controller labels: app: traefik-ingress-controller spec: serviceAccountName: traefik-ingress-controller terminationGracePeriodSeconds: 5 # 等待容器优雅退出的时长 containers: - name: traefik image: traefik:v3.1.7 env: - name: KUBERNETES_SERVICE_HOST # 手动指定k8s api,避免网络组件不稳定,这里使用了Load Balancer的地址 value: "172.16.5.194" - name: KUBERNETES_SERVICE_PORT_HTTPS # API server端口 value: "6443" - name: KUBERNETES_SERVICE_PORT # API server端口 value: "6443" - name: TZ # 指定时区 value: "Asia/Shanghai" ports: - name: web containerPort: 80 hostPort: 80 # 将容器端口绑定所在服务器的 80 端口 - name: websecure containerPort: 443 hostPort: 443 # 将容器端口绑定所在服务器的 443 端口 - name: dashboard containerPort: 9000 # Traefik Dashboard 端口 - name: metrics containerPort: 9101 hostPort: 9101 # metrics 端口,由于 node_exporter 占据了 9100 端口,改到 9101 - name: tcpep containerPort: 9200 # tcp端口 - name: udpep containerPort: 9300 # udp端口 securityContext: # 只开放网络权限 capabilities: drop: - ALL add: - NET_BIND_SERVICE args: - --configfile=/etc/traefik/config/traefik.yaml volumeMounts: - mountPath: /etc/traefik/config name: config - mountPath: /etc/traefik/logs name: logdir - mountPath: /etc/localtime name: timezone readOnly: true resources: requests: memory: "5Mi" cpu: "10m" limits: memory: "256Mi" cpu: "1000m" readinessProbe: httpGet: path: /ping port: 9000 failureThreshold: 3 initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 livenessProbe: httpGet: path: /ping port: 9000 failureThreshold: 3 initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 volumes: - name: config # traefik配置文件 configMap: name: traefik-config - name: logdir # traefik日志目录 hostPath: path: /var/log/traefik type: "DirectoryOrCreate" - name: timezone # 挂载时区文件 hostPath: path: /etc/localtime type: File tolerations: # 设置容忍所有污点,防止节点被设置污点 - operator: "Exists" hostNetwork: true # 开启host网络,提高网络入口的网络性能 nodeSelector: # 设置node筛选器,在特定label的节点上启动 IngressProxy: "true" # 调度至IngressProxy: "true"的节点

  2. 06-tlsoption.yml

    apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: # TLSOption 名称 # 可以被 IngressRoute / Ingress 引用 name: default # 所在命名空间(必须和引用它的资源一致,或显式指定) namespace: default spec: # 最低 TLS 版本限制 # VersionTLS12 表示拒绝 TLS 1.0 / 1.1,只允许 1.2 及以上 minVersion: VersionTLS12 # 指定允许的加密套件(cipher suites) # 控制 HTTPS 连接的加密强度和算法 cipherSuites: - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # TLS 1.2(高强度,推荐) - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 # TLS 1.2(移动设备性能好) - TLS_AES_256_GCM_SHA384 # TLS 1.3(默认推荐) - TLS_CHACHA20_POLY1305_SHA256 # TLS 1.3(高性能) # 椭圆曲线优先级(用于 ECDHE 密钥交换) # 顺序表示优先级(从高到低) curvePreferences: - CurveP521 # 安全性最高,但性能稍低 - CurveP384 # 平衡安全与性能(常用) # 是否启用严格 SNI 检查 sniStrict: true

    07-middleware.yml

    # Redirect to https apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: redirect-https-middleware spec: redirectScheme: scheme: https permanent: true

3. 安装部署,验证 Traefik 状态

# 将上面的所有文件都保存到本地的同一个目录下,执行从01-05的yml文件 kubectl apply -f 01-configmap.yml -f 02-kubernetes-crd-definition-v1.yml -f 03-kubernetes-crd-rbac.yml -f 04-serviceaccount.yml -f 05-traefik-deploy.yml # 等待一会查看状态,traefik 状态均为ready,继续执行06和07 kubectl get all -n default kubectl apply -f 06-tlsoption.yml -f 07-middleware.yml

4.使用IngressRoute暴漏Traefik Dashboard服务

# traefik-dashboard-route.yaml --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: traefik-dashboard-route namespace: default spec: entryPoints: - web routes: - match: Host(`traefik.k8s.example.com`) kind: Rule services: - name: traefik-ingress-controller port: 9000

访问测试

  1. 请确保你在本地电脑的 hosts 文件或内网 DNS 中,将域名(如 traefik.k8s.example.com)解析到了你的负载均衡 (LB) 节点 IP
  2. 打开浏览器,访问 http://traefik.k8s.example.com,此时你就能看到Traefik的可视化界面
网友解答:
--【壹】--:

现在好像都在推gatewayapi和istio,听说ingress要被取代了


--【贰】--:

必须支持


--【叁】--:

教程很硬核


--【肆】--:

只能说各自有各自的用途吧,技术是不断迭代的,我是把一年前的操作复现了一下,写了这个教程,对于绝大多数只能在内网使用的用户都是够用了


--【伍】--:

实际使用的话,我比较习惯实用metallb,不依赖外部,直接集群级别控制lb(LoadBalancer)。
另外Ingress已经被社区淘汰(确切的说,是淘汰中),
建议新的集群,直接使用Gateway API,不要再使用Ingress了.


--【陆】--:

感谢大佬


--【柒】--:

支持前排


--【捌】--:

支持支持


--【玖】--:

感谢大佬教程