一.ingress是什么
背景:
NodePort存在的不足,测试环境用用还行,当有成百上千上万个服务在集群总运行时,端口管理将是灾难:
端口有限,一个端口只能一个服务使用,需要提前规划
只支持4层负载均衡(ipvs和iptables)
ClusterIp只能集群内部访问
LoadBalance方式受限于云平台支,且通常在云平台部署ELB还需要额外的费用
Ingress可以简单理解为service的service。它通过独立的Ingress对象来制定转发规则,把客户端请求转发到一个或多个service中,这样就把请求与服务解耦了,可以从业务维度统一考虑业务的暴露,而不用为每个service单独考虑
Ingress对象:
指的是k8s中的一个api对象,一般用yaml配置。作用是定义请求如何转发service的规则。可以理解为配置模板
Ingress Controller:
具体实现反向代理的及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则把请求转发到对应的service上
市面上大多数厂商都提供了ingress controller,具体参考官方说明https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
二.部署Ingress Controller
Ingress Controller有很多实现,我们这里采用官方维护的Nginx控制器 项目地址:https://github.com/kubernetes/ingress-nginx 部署:kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
注意:
ingress controller的镜像仓库在国外:quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0,国内访问不稳定
ingress默认没配置暴露:一般使用宿主机网络(hostNetwork: true)或者使用NodePort
hostNetwork: true
containers:
- name: nginx-ingress-controller
三、使用ingress-nginx暴露一个service
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web1 namespace: web # 注意此处配置:service和ingress必须在同一个namespace spec: rules: - host: web1.k8s.com # 前端请求域名 http: paths: - path: / # 访问的路径 pathType: Prefix # 路径类型 匹配/所有的路径 backend: # 后端service service: name: web1 # service-name port: number: 8080 # service-port 即service里配置的port的参数
# 查看已创建的ingress kubectl get ingress -n namespace-name [root@k8s-master yaml]# kubectl get ingress -n web Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress NAME CLASS HOSTS ADDRESS PORTS AGE web1 <none> web1.k8s.com 80 23m
以上配置类似nginx里配置如下
server { listen 80; server_name web1.k8s.com; location / { root ; proxy_pass http://ClusterIP(此处是service的name):8080; } }
三.基于URL路由多个服务
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web2 namespace: web annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 # 转发到主页资源 spec: rules: - host: kubernetes.gameoo.com http: paths: - path: /foo(/|$)(.*) pathType: Prefix backend: service: name: web1 port: number: 80 - path: /bar(/|$)(.*) # 匹配/或者具体路径的所有资源 /bar/xxx 或者 /bar/xxx/xxx pathType: Prefix backend: service: name: java-daemon port: number: 8080
# 如果不使用annotation,转发不到对应的后端service资源,如下
当访问http://kubernetes.gameoo.com/foo时,ingress是这样转发的:service/foo。实际后端就没有foo这个资源,所有会报404
加了annotation,就是这样转发的:http://kubernetes.gameoo.com/foo 把这个url的整体转发给后端service,从而实现多url路由
四.重定向规则的实现
接第三章,只是实现了主页资源的路由,但实际项目中不仅仅只有主页资源,还有css js image等资源,这些资源也需要被路由到
所以自带的 nginx.ingress.kubernetes.io/rewrite-target就不能实现,此时需要我们自定义重定向规则
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web2 namespace: web annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 # 转发到主页资源 nginx.ingress.kubernetes.io/server-snippet: | # |可以匹配多条自定义规则 rewrite ^/css/(.*)$ /bar/css/$1 redirect; #当客户端请求/css/的资源时,重定向到/bar/css 使用临时重定向 rewrite ^/js/(.*)$ /bar/js/$1 redirect; rewrite ^/images/(.*)$ /bar/images/$1 redirect;
##### 实际项目中有多少资源就在这里添加 spec: rules: - host: kubernetes.gameoo.com http: paths: - path: /foo(/|$)(.*) pathType: Prefix backend: service: name: web1 port: number: 80 - path: /bar(/|$)(.*) # 匹配/或者具体路径的所有资源 /bar/xxx 或者 /bar/xxx/xxx pathType: Prefix backend: service: name: java-daemon port: number: 8080
######nginx正则方式
五、基于名称的虚拟主机
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web3 namespace: web spec: rules: - host: kubernetes.gameoo.com http: paths: - path: "/" pathType: Prefix backend: service: name: web1 port: number: 80 - host: java-demo.gameoo.com http: paths: - path: "/" pathType: Prefix backend: service: name: java-daemon port: number: 8080
#### 与nginx的虚拟主机配置方式类似
六.更多ingress使用方法
七.配置https访问
1.准备证书(测试可以自签,线上最好是权威机构颁发) 2.将证书文件保存到 secret kubectl create secret tls NAME --cert=path/to/cert/file --key=path/to/key/file -n namespace
[root@k8s-master yaml]# kubectl create secret tls kubernetes.gameoo.com --cert=ssl/kubernetes.gameoo.com.pem --key=ssl/kubernetes.gameoo.com.key -n web secret/kubernetes.gameoo.com created [root@k8s-master yaml]# kubectl get secret -n web NAME TYPE DATA AGE default-token-bk4x4 kubernetes.io/service-account-token 3 14d kubernetes.gameoo.com kubernetes.io/tls 2 3s
3.ingress配置规则
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web4 namespace: web spec: tls: - hosts: - kubernetes.gameoo.com secretName: kubernetes.gameoo.com #create secret时指定的NAME 注意create时如果项目不在default命名空间,必须指定-n namespace rules: - host: kubernetes.gameoo.com http: paths: - path: "/" pathType: Prefix backend: service: name: java-daemon port: number: 8080
八.Ingress Controller
Ingress Contronler通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取它,
按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段 Nginx 配置,应用到管理的
Nginx服务,然后热加载生效。
以此来达到Nginx负载均衡器配置及动态更新的问题。
流量包流程:客户端 ->Ingress Controller( nginx) -> 分布在各节点Pod
九.Ingress Controller高可用方案