提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
K8s-Ingress介绍
通过Service可以将Kubernetes集群中的服务以IP:Port的方式暴露出来,我们称之为4层的负载均衡,因为这个是OSI七层模型中传输层的功能。
那么如何实现像Nginx那样,可以灵活的进行反向代理的设置,根据不同的URL进行转发Kubernetes提供了解决方案就Ingress。 Ingress就是从kubernetes集群外访问集群的入口,将用户的URL请求转发到不同的service上。ingress相当于nginx反向代理服务器,它包括的规则定义就是URL的路由信息
本文采用的ingress就是Traefik,目前也作为K3s的默认ingress
直接看官网:
Traefik Kubernetes 入门 - Traefik
1. 快速开始
当前测试环境:
K8s:v1.30.2
Traefik:3.2.1
MetalLB:v0.14.3
1.1 权限和访问权限
Traefik 使用 Kubernetes API 来发现正在运行的服务。
要使用 Kubernetes API,Traefik 需要一些权限。 此权限机制基于群集管理员定义的角色。
然后,该角色将绑定到应用程序使用的帐户,在本例中创建了一个角色traefik-role。
00-role.yml
第一步是创建角色。 ClusterRole 资源可用于该角色的资源和操作。 在名为00-role.yml
的文件中,放置以下内容:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-role
rules:
- apiGroups:
- ""
resources:
- services
- secrets
- nodes
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
- apiGroups:
- traefik.io
resources:
- middlewares
- middlewaretcps
- ingressroutes
- traefikservices
- ingressroutetcps
- ingressrouteudps
- tlsoptions
- tlsstores
- serverstransports
- serverstransporttcps
verbs:
- get
- list
- watch
- apiGroups:api组,指的是具有相同功能或主题的API资源的集合;
- resources:资源,指的是在这个api组中,需要用的资源;
- verbs:操作权限,指的是对前面指定资源有哪些操作权限。
00-account.yml
下一步是为 Traefik 创建一个专用服务账户。 在名为00-account.yml
的文件中,放置以下 ServiceAccount 资源:
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-account
01-role-binding.yml
然后,在账户上绑定角色以将权限和规则应用于这个账户,创建01-role-binding.yml
文件:
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-role
subjects:
- kind: ServiceAccount
name: traefik-account
namespace: default # This tutorial uses the "default" K8s namespace.
-
roleRef: 指出要绑定权限
- kind:权限类型{
ClusterRole
集群权限;Role
命名空间权限},要和00-role
定义一致,不然无法识别。 - name:
00-role
中定义的名称
- kind:权限类型{
-
subjects: 指定账号
- namespace:在k8s中ServiceAccount为命名空间级别的资源,需要指定一个命名空间
1.2 Traefik部署
采用deployment方式部署,可以保证同时存活的traefik应用数量
02-traefik.yml
kind: Deployment
apiVersion: apps/v1
metadata:
name: traefik-deployment
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-account
containers:
- name: traefik
image: traefik:v3.2
args:
- --api.insecure
- --providers.kubernetesingress
ports:
- name: web
containerPort: 80
- name: dashboard
containerPort: 8080
-
metadata(元数据):
- name:定义这个deployment名称为
traefik-deployment
; - labels:给deployment打上一个
app: traefik
标签,用于后续的选择器。
- name:定义这个deployment名称为
-
spec(具体功能配置):
-
replicas: 1 (同时存在1个副本)
-
selector: 标签选择器,对有
app: traefik
标签的资源生效 -
template: 用于描述pod模板
-
metadata: pod基本数据,pod标签就在这里定义,这里定义为
app: traefik
-
spec:pod具体功能配置
-
serviceAccountName: pod使用的账号为
traefik-account
,使其拥有前面所定义的权限; -
containers: pod中每个容器的配置
- name:容器名
- image:使用镜像
- args:传递到容器的命令行参数
- ports:容器开放暴露的端口,这里开放了80(web应用)和8080(traefik控制面板)两个端口提供后续使用
-
-
-
1.3 Traefik服务部署
由于pod在集群中时刻漂移不固定,所以要创建一个服务对外提供固定的访问通道
02-traefik-services.yml
apiVersion: v1
kind: Service
metadata:
name: traefik-dashboard-service
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: dashboard
selector:
app: traefik
---
apiVersion: v1
kind: Service
metadata:
name: traefik-web-service
spec:
type: LoadBalancer
ports:
- targetPort: web
port: 80
selector:
app: traefik
这个yml中同时配置了两个服务traefik-dashboard-service和traefik-web-service:
-
traefik-dashboard-service
-
metadata(元数据): 定义了
traefik-dashboard-service
为服务名 -
spec(功能描述):
-
type(复杂均衡类型):采用
LoadBalancer
类型,这会使用一个集群外部的稳定IP地址用于访问,还有ClusterIP
、NodePort
、ExternalName
等多种类型,以后再说; -
ports(端口列表):
- port: 8080
- targetPort:
dashboard
这需要和前面pod模板中的name:
对应,不然无法匹配
-
selector: 标签选择器,这个服务指向带有
app: traefik
标签的pod。
-
-
-
traefik-web-service
-
metadata(元数据): 定义了
traefik-web-service
为服务名 -
spec(功能描述):
-
type(复杂均衡类型):采用
LoadBalancer
类型, -
ports(端口列表):
- port: 80
- targetPort: web 这需要和前面pod模板中的
name:
对应,不然无法匹配
-
selector: 标签选择器,这个服务指向带有
app: traefik
标签的pod。
-
-
1.4 业务程序部署
在 80 上运行的 HTTP 服务,也用deployment+service方式部署
03-whoami.yml
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoami
labels:
app: whoami
spec:
replicas: 1
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- name: web
containerPort: 80
这里要换个标签app: whoami
,不然就会被别的资源操控!
03-whoami-services.yml
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- name: web
port: 80
targetPort: web
selector:
app: whoami
这里的服务没有设置type类型,那么这个服务采用的就是默认类型ClusterIP
,它为服务分配一个集群内部的IP地址,只能在集群内部访问;适用于只需要在集群内部通信的服务
04-whoami-ingress.yml
将任何以 /
开头的传入请求重定向到服务。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whoami-ingress
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: whoami
port:
name: web
1.5 验证
-
查看服务
kubectl get service
可以看出来集群随机给我们分配了两个端口32165和30325两个端口,
-
web打开
http://:32165
http://:30325
经过测试,使用集群任意一个节点IP+端口均可访问到服务,可以见得在LoadBalancer
模式下集群内部依然具有NodePort
模式的特性!
1.6 验证LoadBalancer
在前文中可以看到,当我们配置服务为LoadBalancer
模式时,集群服务中的EXTERNAL-IP
属性为<pending>
,并没有外部IP生成
LoadBalancer 官方解释是:
使用云提供商的负载均衡器向外部暴露服务。外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。
MetalLB 介绍
MetalLB :: MetalLB,适用于 Kubernetes 的裸机负载均衡器
MetalLB 是裸机 Kubernetes 集群的负载均衡器实现,使用标准路由协议。
Kubernetes 官方并没有提供 LoadBalancer 的实现。各家云厂商有提供实现,但假如不是运行在这些云环境上,创建的 LoadBalancer Service 会一直处于 Pending 状态(见下文 Demo 部分)。
MetalLB可以解决这个问题
检查集群是否开启ARP模式
官网解释:
[root@linux-node1 MetalLB]# kubectl edit configmap -n kube-system kube-proxy
# 搜索ipvs
ipvs:
excludeCIDRs: null
minSyncPeriod: 0s
scheduler: ""
strictARP: true # 这里配置为true
syncPeriod: 0s
tcpFinTimeout: 0s
tcpTimeout: 0s
udpTimeout: 0s
kubectl apply -f https://github.com/metallb/metallb/blob/main/config/manifests/metallb-native.yaml
注意将内部的镜像替换为自己的docker仓库
[root@linux-node1 MetalLB]# kubectl get po -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-86c4d97ffd-n4vfs 0/1 Running 0 34s
speaker-d7v74 0/1 Running 0 33s
speaker-jqgp6 0/1 Running 0 33s
speaker-rmgqt 0/1 Running 0 33s
此时再检查 LoadBalancer Service 的状态仍然是 Pending 的,嗯?因为,MetalLB 要为 Service 分配 IP 地址,但 IP 地址不是凭空来的,而是需要预先提供一个地址库。
要 Layer2 模式进行配置,需要创建一个 IPAddressPool 资源对象,用来指定用于分配的 IP 池,比如我们这里创建如下所示的一个分配给 LB 的 IP 池对象:
[root@linux-node1 MetalLB]# cat ip-pool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: ip-pool
namespace: metallb-system
spec:
addresses:
- 192.168.56.170-192.168.56.179 #分配给LB的IP池
[root@linux-node1 MetalLB]# cat advertise.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: l2adver
namespace: metallb-system
spec:
ipAddressPools: # 如果不配置则会通告所有的IP池地址
- ip-pool
kubectl apply -f ip-pool.yaml
kubectl apply -f advertise.yaml
提供的 IP 段可以参考上面的网络环境,本例中配置在k8s集群同网段下,因为其他网段未作相应的配置,宿主机浏览器访问不到
查看效果:
kubectl get svc
浏览器:
完美!!!
标签:name,Traefik,app,whoami,traefik,亲妈,yml,LoadBalancer,metadata From: https://blog.csdn.net/youmiqianyue/article/details/144174973