k8s保姆级教程:K8s高可用集群教程-02-Load Balancer和Ingress Controller
- 内容介绍
- 文章标签
- 相关推荐
关注的小伙伴久等了,因为工作的变动,关于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,作为整个集群的统一流量入口。它将承担两个核心职责:
- 控制平面高可用 (四层负载):将 6443 端口的请求代理到 3 台 Master 节点,实现 API Server 的高可用。
- 业务流量网关 (四层负载):将 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. 创建基础资源
-
我们有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 -
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 -
02-kubernetes-crd-definition-v1.yml此文件为官方下载,不要改动,这里我直接提供文件
02-kubernetes-crd-definition-v1.yml.zip (18.7 KB) -
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 # ← 所在命名空间 -
04-serviceaccount.yml对应上面权限的使用者apiVersion: v1 kind: ServiceAccount metadata: namespace: default name: traefik-ingress-controller
2. Traefik 部署清单
-
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"的节点 -
06-tlsoption.ymlapiVersion: 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: true07-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
访问测试
- 请确保你在本地电脑的
hosts文件或内网 DNS 中,将域名(如traefik.k8s.example.com)解析到了你的负载均衡 (LB) 节点 IP 。 - 打开浏览器,访问
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,作为整个集群的统一流量入口。它将承担两个核心职责:
- 控制平面高可用 (四层负载):将 6443 端口的请求代理到 3 台 Master 节点,实现 API Server 的高可用。
- 业务流量网关 (四层负载):将 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. 创建基础资源
-
我们有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 -
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 -
02-kubernetes-crd-definition-v1.yml此文件为官方下载,不要改动,这里我直接提供文件
02-kubernetes-crd-definition-v1.yml.zip (18.7 KB) -
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 # ← 所在命名空间 -
04-serviceaccount.yml对应上面权限的使用者apiVersion: v1 kind: ServiceAccount metadata: namespace: default name: traefik-ingress-controller
2. Traefik 部署清单
-
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"的节点 -
06-tlsoption.ymlapiVersion: 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: true07-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
访问测试
- 请确保你在本地电脑的
hosts文件或内网 DNS 中,将域名(如traefik.k8s.example.com)解析到了你的负载均衡 (LB) 节点 IP 。 - 打开浏览器,访问
http://traefik.k8s.example.com,此时你就能看到Traefik的可视化界面
--【壹】--:
现在好像都在推gatewayapi和istio,听说ingress要被取代了
--【贰】--:
必须支持
--【叁】--:
教程很硬核
--【肆】--:
只能说各自有各自的用途吧,技术是不断迭代的,我是把一年前的操作复现了一下,写了这个教程,对于绝大多数只能在内网使用的用户都是够用了
--【伍】--:
实际使用的话,我比较习惯实用metallb,不依赖外部,直接集群级别控制lb(LoadBalancer)。
另外Ingress已经被社区淘汰(确切的说,是淘汰中),
建议新的集群,直接使用Gateway API,不要再使用Ingress了.
--【陆】--:
感谢大佬
--【柒】--:
支持前排
--【捌】--:
支持支持
--【玖】--:
感谢大佬教程

