k3s ingress
k8s对外暴露服务,方式有NodePort,LoadBalancer和Ingress等。
NodePort类型的service其实是基于ClusterIP类型的service做的扩展,只需把service的type设置为nodeport即可,同时需要指定nodePort值,端口范围在30000~32767之间,这个值标识主机端口。
LoadBalancer 则是在NodePort之前添加了负载均衡着一层。
具体他们的关系,可以阅读这篇文章。
Ingress
提到ingress,大家会想到ingress,ingress controller这两个东西。
这两个东西,并不是k8s原生的组件,为什么产生他们呢?
开发过程中,暴露服务,大家经常使用nodeport类型,直接通过宿主机和宿主机的端口,访问对应的服务。但是生产中,微服务数量比较多,每个服务都暴露端口的话。那么k8s集群中的node都要暴露出对应的端口。现实中,端口资源比较珍贵,其次暴露出过多端口,给网络安全带来很多隐患。
所以,对应产生了ingress机制。通过暴露两个端口(分别映射80和443),通过path或者其他规则访问对应的服务,较少了端口的使用。
ingress controller 一般分为两种,nginx和traefik。
那么ingress和ingress controller关系是什么?
简单地描述下,在nginx controller中,ingress controller是部署在k8s中的nginx服务。在实际生产中,nginx的映射规则有可能会动态更改,容器外nginx的修改规则之后,执行nginx reload 则可动态加载修改后的规则。
但是,为了方便修改k8s的nginx规则,整出来了ingress。ingress就是nginx的映射规则。ingress修改后,ingress-controller通过k8s的监听机制,动态感知修改,并且动态更新。
ingress-controller可以配置为NodePort和LoadBalancer,不论nginx和traefik默认都是LoadBalancer。
k3s的ingress
k3s默认安装traefik这个控制器,默认使用LoadBalancer。开发者只需要部署一个ingress即可。k3s 默认使用klipper-lb作为负载均衡器。klipper-lb其实就是一个iptales转发规则配置。
架构图
网络拓扑图
这里解释下,traefik配置为LoadBalancer时,他也会暴露对应的端口。当用户通过宿主机ip:80端口访问时,lb时通过转发到traefik k3s的内部地址。
ingress配置为nginx
nginx的yaml地址
需要禁止k3s的traefik,然后重启k3s。当然也可以,手动删除对应的deploy和ds。
架构图和网络拓扑图,只需要把traefik替换为nginx即可。
nginx这里有两个小坑:
- externalTrafficPolicy: Local
每个服务器都需要部署一个ingress-controller,否则,修改为Cluster则解决 - use-proxy-protocol: “true”
修改为false。 - ingress需要的classname需要明确指定为nginx,否则,k3s默认为traefik类型。
最佳实践
controller为traefik:
- 使用k3s的默认traefik作为nginx。只需要新增一个ingress即可。
- 当自己没有外部负载均衡器为traefik分配ip,只是通过ingress少暴露端口,则可以把traefik service修改为nodePort,程序通过访问对应的node地址一样可以访问服务。因为配置为LoadBalancer也要暴露两个端口,其次还要通过Host Port方式占用宿主机的80和443端口。
但是,没有找到启动k3s时,traefik的svc配置为nodePort,目前看了需要手动修改。
controller为nginx:
- 用traefik。nginx controller配置为nodeport。新增一个ingress
其次:
ingress通过hostname区分不同服务。或者通过rewrite机制,区分不同的服务。nginx对rewrite机制支持比较完善,traefik支持不太友好。
最终,建议安装nginx实现controller。
rewrite机制:
- nginx
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-http-path
namespace: test
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /tomcat/(.*)
pathType: Prefix
backend:
service:
name: tomcat-service
port:
number: 8080
- http:
paths:
- path: /nginx
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
- traefik
---
# Middleware
# Strip prefix /overview
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: mw-admin
namespace: ingress
spec:
stripPrefix:
forceSlash: false
prefixes:
- /overview
---
# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: registry-ingress
namespace: ingress
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.middlewares: ingress-mw-admin@kubernetescrd
spec:
tls:
- hosts:
- myhost.com
secretName: tls-secret
rules:
- host: myhost.com
http:
paths:
- path: /overview
pathType: Prefix
backend:
service:
name: overview
port:
number: 8079