使用traefik 负载均衡(本地部署得k8s集群无法实现负载均衡,只能使用ip+nodeport访问单一pod)
1.安装helm
要使用 Helm 安装应用程序,首先需要确保你的 Kubernetes 集群已经配置好,并且 Helm 已经安装在你的环境中。以下是一个基本的安装和使用 Helm 的步骤指南:
-
下载 Helm 二进制文件(请根据你的系统架构选择合适的版本):
wget https://get.helm.sh/helm-v3.12.0-linux-amd64.tar.gz
-
解压并移动到适当的目录:
tar -zxvf helm-v3.12.0-linux-amd64.tar.gz sudo mv linux-amd64/helm /usr/local/bin/helm
-
验证安装:
helm version
2. 使用helm安装traefik
使用 Helm 安装 Traefik 作为你的 Kubernetes 集群中的 Ingress Controller,按照以下步骤进行:
1. 添加 Traefik Helm 仓库
首先,你需要添加 Traefik 的 Helm 仓库:
helm repo add traefik https://helm.traefik.io/traefik
helm repo update
2. 安装 Traefik
接下来,使用 Helm 安装 Traefik:
# 默认安装最新,并且从github下载tgz包
helm install traefik traefik/traefik
注意:默认直接使用helm install traefik traefik/traefik
会有问题,机器无法访问该地址,需要在能访问下面地址的网络环境(科学网络),并且traefik对k8s版本有要求,需要去官网看k8s版本要求,然后安装对应的版本
"https://traefik.github.io/charts/traefik/traefik-30.1.0.tgz": dial tcp 185.199.108.153:443: connect: connection timed out
访问https://doc.traefik.io/,查看各个版本对k8s的支持
我k8s集群版本为v1.21.0,找到支持的最新版本,然后去能科学上网的机器下载tgz包,上传到服务器上
官网找到支持的最新版本为v2.11.2,使用helm search repo traefik --versions查询版本对应的chart version为27.0.2,然后去github上下载对应的tgz包
https://traefik.github.io/charts/traefik/traefik-27.0.2.tgz
解压下载的tgz包,修改traefik-27.0.2.tgz包中的values.yaml文件,修改registry为可用的镜像仓库地址,然后重新打包成tgz包
安装:
kubectl create namespace traefik
helm install traefik ./traefik-27.0.2.tgz --namespace=traefik --set image.name=docker.rainbond.cc/traefik --set image.tag=v2.11.2 --debug
#如果需要修改配置了重新安装可以使用
helm upgrade --install traefik ./traefik-27.0.2.tgz --namespace=traefik --set image.name=docker.rainbond.cc/traefik --set image.tag=v2.11.2 --debug
验证:
kubectl get svc,pod -n traefik
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.103.44.119 <pending> 80:32335/TCP,443:30205/TCP 37m
NAME READY STATUS RESTARTS AGE
pod/traefik-7b5b6c54d6-5v56r 1/1 Running 0 104m
从 kubectl get svc -n traefik
的输出中可以看到,Traefik 服务的 EXTERNAL-IP
状态为 <pending>
,这表明你的集群未能成功分配一个外部 IP 地址。这种情况通常发生在以下两种情况下:
-
本地或裸金属集群:如果你的 Kubernetes 集群是在本地或裸金属环境中部署的,并且没有配置外部负载均衡器,Kubernetes 将无法自动分配外部 IP。
-
未配置 LoadBalancer 插件:在云环境中,如果你的集群未配置或未正确配置 LoadBalancer 插件(如在 AWS 或 GCP 中),也会出现这种情况。
解决方法 使用 NodePort 方式暴露服务
如果你无法使用 LoadBalancer 类型服务,可以考虑修改 Traefik 服务为 NodePort
类型,以便在集群的某个节点上通过特定端口访问 Traefik。
-
修改 Traefik Service 配置:
你可以编辑 Traefik 的
Service
,将其类型改为NodePort
:kubectl edit svc traefik -n traefik
找到
spec.type
,将其从LoadBalancer
改为NodePort
:spec: type: NodePort
然后保存文件。
-
获取 NodePort:
修改完成后,你可以再次检查服务,获取
NodePort
端口号:kubectl get svc -n traefik NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/traefik NodePort 10.103.44.119 <none> 80:32335/TCP,443:30205/TCP 104m
3. 配置 Ingress
在 Traefik 的 IngressRoute
配置中,你可以将多个服务配置到同一个文件中,也可以将它们分开到不同的 IngressRoute
资源中。具体做法取决于你的需求和服务的路由规则。
1. 多个服务在同一个 IngressRoute中
如果这些服务共享相同的入口点和主机名,但不同路径或端口,你可以将它们配置在同一个 IngressRoute
文件中。每个服务会对应一个不同的路径规则。
示例:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: multiple-services-ingress
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`192.168.1.101`) && PathPrefix(`/service1`)
kind: Rule
services:
- name: service1
port: 8080
- match: Host(`192.168.1.101`) && PathPrefix(`/service2`)
kind: Rule
services:
- name: service2
port: 9090
- match: Host(`192.168.1.101`) && PathPrefix(`/service3`)
kind: Rule
services:
- name: service3
port: 7070
在这个示例中,你可以通过以下路径访问不同的服务:
http://192.168.1.101:32335/service1
访问service1
http://192.168.1.101:32335/service2
访问service2
http://192.168.1.101:32335/service3
访问service3
2. 每个服务一个 IngressRoute
如果你希望更灵活地管理不同服务,或者这些服务有不同的主机名或入口点,你可以为每个服务创建单独的 IngressRoute
资源。
示例:
service1-ingress.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: service1-ingress
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`192.168.1.101`) && PathPrefix(`/service1`)
kind: Rule
services:
- name: service1
port: 8080
service2-ingress.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: service2-ingress
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`192.168.1.101`) && PathPrefix(`/service2`)
kind: Rule
services:
- name: service2
port: 9090
3. 组合方式
你也可以将一些服务配置在同一个 IngressRoute
中,而将其他服务配置在单独的 IngressRoute
中,根据你的需求灵活选择。
4. 选择哪种方式
- 单一配置:方便统一管理所有相关的路由规则,适合路径较为简单且路由策略固定的场景。
- 分离配置:适合复杂的服务环境,特别是不同服务有独立的生命周期、不同的路由规则,或者需要更细粒度的管理和调试。
4.给mavenapp配置Ingress
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: mavenapp-ingress
spec:
entryPoints:
- web
routes:
- match: Host(`192.168.13.35`) # ip或域名(使用域名需要配置host)
kind: Rule
services:
- name: mavenapp-service # 与svc的name一致
port: 8888 # 与svc的port一致
kubectl apply -f mavenapp-ingress.yaml
5.路由配置
可以在一个配置文件中配置多个路由规则
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: mavenapp-ingress
spec:
entryPoints:
- web
routes:
- match: Host(`192.168.13.35`)&& PathPrefix(`/mavenapp`) # 域名
kind: Rule
services:
- name: mavenapp-service # 与svc的name一致
port: 8888 # 与svc的port一致
- match: Host(`192.168.13.35`) && PathPrefix(`/golangapp`)
kind: Rule
middlewares:
- name: app-strip-prefix
services:
- name: my-golang-app-service
port: 8088
路径匹配规则说明:
Host(192.168.13.35
)&& PathPrefix(/mavenapp
) 域名为192.168.13.35
,路径为/mavenapp
,即浏览器访问路径为http://192.168.13.35/mavenapp
这样写需要服务/mavenapp路径能访问,比如我使用idea直接启动mavenapp服务,访问http://localhost:8888/mavenapp
是能够直接访问的
但是golangapp服务启动后,访问http://localhost:8088/golangapp
是不能直接访问的,只能访问http://localhost:8088/
,所以需要配置中间件(middleware)来帮我去掉前缀/golangapp
当然,你也可以直接配置Host(
192.168.13.35)
,但是我想使用前缀来路由到不同服务,所以创建一个去除前缀中间件
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: app-strip-prefix
spec:
# stripPrefixRegex:
# regex:
# - /[^/]+/
stripPrefix:
prefixes:
- /golangapp
还有很多功能都可以使用中间件
参考:
https://blog.csdn.net/qq_33816243/article/details/127760665
6. 使用Traefik Dashboard
参考:
https://blog.csdn.net/networken/article/details/85953346
7. traefik相关命令
kubectl get svc -n traefik
kubectl get pod -n traefik
kubectl describe pod <traefik-pod-name> -n traefik
kubectl logs -f <traefik-pod-name> -n traefik
kubectl get ingressroute
kubectl delete ingressroute <ingressroute-name>
kubectl get middleware