在 Kubernetes 集群中,Ingress是授权入站连接到达集群服务的规则集合,为您提供七层负载均衡能力。您可以给 Ingress 配置提供外部可访问的 URL、负载均衡、SSL、基于名称的虚拟主机等。
目前主要广泛应用的有:Nginx、Traefik、Envoy三种
一、K8S服务暴露介绍
从 kubernetes 1.2 版本开始,kubernetes提供了 Ingress 对象来实现对外暴露服务;到目前为止 kubernetes 总共有三种暴露服务的方式:
- LoadBlancer Service
- NodePort Service
- Ingress
1、LoadBlancer Service
LoadBlancer Service 是 kubernetes 深度结合云平台的一个组件;当使用 LoadBlancer Service 暴露服务时,实际上是通过向底层云平台申请创建一个负载均衡器来向外暴露服务;目前 LoadBlancer Service 支持的云平台已经相对完善,比如国外的 GCE、DigitalOcean,国内的 阿里云,私有云 Openstack 等等,由于 LoadBlancer Service 深度结合了云平台,所以只能在一些云平台上来使用
2、NodePort Service
NodePort Service 顾名思义,实质上就是通过在集群的每个 node 上暴露一个端口,然后将这个端口映射到某个具体的 service 来实现的,虽然每个 node 的端口有很多(0~65535),但是由于安全性和易用性(服务多了就乱了,还有端口冲突问题)实际使用可能并不多
3、Ingress
使用Ingress时一般会有三个组件:
- 反向代理负载均衡器
- Ingress Controller
- Ingress
3.1、反向代理负载均衡器
反向代理负载均衡器很简单,说白了就是 nginx、apache 等中间件,新版k8s已经将Nginx与Ingress Controller合并为一个组件,所以Nginx无需单独部署,只需要部署Ingress Controller即可
在集群中反向代理负载均衡器可以自由部署,可以使用 Replication Controller、Deployment、DaemonSet 等等方式
3.2、Ingress Controller
Ingress Controller 实质上可以理解为是个监视器,Ingress Controller 通过不断地跟 kubernetes API 打交道,实时的感知后端 service、pod 等变化,比如新增和减少 pod,service 增加与减少等;当得到这些变化信息后,Ingress Controller 再结合下文的 Ingress 生成配置,然后更新反向代理负载均衡器,并刷新其配置,达到服务发现的作用
3.3、Ingress
Ingress 简单理解就是个规则定义;比如说某个域名对应某个 service,即当某个域名的请求进来时转发给某个 service;这个规则将与 Ingress Controller 结合,然后 Ingress Controller 将其动态写入到负载均衡器配置中,从而实现整体的服务发现和负载均衡
整体关系如下图所示:
从上图中可以很清晰的看到,实际上请求进来还是被负载均衡器拦截,比如 nginx,然后 Ingress Controller 通过跟 Ingress 交互得知某个域名对应哪个 service,再通过跟 kubernetes API 交互得知 service 地址等信息;综合以后生成配置文件实时写入负载均衡器,然后负载均衡器 reload 该规则便可实现服务发现,即动态映射
二、Ingress是授权入站连接到达集群服务的规则集合
- 从外部流量调度到nodeprot上的service
- 从service调度到ingress-controller
- ingress-controller根据ingress中的定义(虚拟主机或者后端的url)
- 根据虚拟主机名调度到后端的一组pod中
再来一张整体流程图:
Ingress中Nginx-Ingress工作原理:
- ingress controller通过和kubernetes api交互,动态的去感知集群中ingress规则变化,
- 然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置,
- 再写到nginx-ingress-control的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,
- 然后reload一下使配置生效。以此达到域名分配置和动态更新的问题。
三、安装部署
首先说明一下使用Ingress功能的步骤:
1.安装部署Ingress Controller Pod
2.部署后端服务
3.部署Ingress-Nginx service
4.部署Ingress
1、下载yaml文件
部署文件介绍
1. mandatory.yaml
配置部署的主文件,也是以下各yaml文件的合集,一般情况下只需要修改部署此文件即可。
2.namespace.yaml
创建一个独立的命名空间 ingress-nginx
3.configmap.yaml
ConfigMap是存储通用的配置变量的,类似于配置文件,使用户可以将分布式系统中用于不同模块的环境变量统一到一个对象中管理;而它与配置文件的区别在于它是存在集群的“环境”中的,并且支持K8S集群中所有通用的操作调用方式。
从数据角度来看,ConfigMap的类型只是键值组,用于存储被Pod或者其他资源对象(如RC)访问的信息。这与secret的设计理念有异曲同工之妙,主要区别在于ConfigMap通常不用于存储敏感信息,而只存储简单的文本信息。
ConfigMap可以保存环境变量的属性,也可以保存配置文件。
创建pod时,对configmap进行绑定,pod内的应用可以直接引用ConfigMap的配置。相当于configmap为应用/运行环境封装配置。
pod使用ConfigMap,通常用于:设置环境变量的值、设置命令行参数、创建配置文件。
4.rbac.yaml
负责Ingress的RBAC授权的控制,其创建了Ingress用到的ServiceAccount、ClusterRole、Role、RoleBinding、ClusterRoleBinding
5.with-rbac.yaml
是Ingress的核心,用于创建ingress-controller。前面提到过,ingress-controller的作用是将新加入的Ingress进行转化为Nginx的配置
2、部署Ingress-nginx,当前最新版本0.21.0
把上面的mandatory.yaml文件下载好后,先替换里面的image,再进行部署
# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml
# sed -i 's#quay.io/kubernetes-ingress-controller#registry-vpc.cn-beijing.aliyuncs.com/xiaoban#g' mandatory.yaml
# kubectl apply -f mandatory.yaml
namespace/ingress-nginx created
configmap/nginx-configuration created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.extensions/nginx-ingress-controller created
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/configmap.yaml
configmap/tcp-services created
configmap/udp-services created
3、配置自由调度 node
# ingress 有多种方式 1. deployment 自由调度 replicas
2. daemonset 全局调度 分配到所有node里(资源耗费严重)
# deployment 自由调度过程中,由于我们需要 约束 controller 调度到指定的 node 中,所以需要对 node 进行 label 标签
# kubectl label nodes es-61 ingress=proxy
# kubectl get nodes --show-labels
需要对with-rbac.yaml文件部分进行修改
spec: replicas: 2 .... spec: serviceAccountName: nginx-ingress-serviceaccount #hostNetwork: true nodeSelector: ingress: proxy #跟上面设置的label对应好 ....
采用裸机部署的话最好固定NodePort
# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml
# vim service-nodeport.yaml apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: type: NodePort ports: - name: http port: 80 targetPort: 80 protocol: TCP nodePort: 30080 - name: https port: 443 targetPort: 443 protocol: TCP nodePort: 30443 selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx ---
部署一个服务进行验证:
apiVersion: v1 kind: Service metadata: name: myapp namespace: default spec: selector: app: myapp release: canary ports: - name: http targetPort: 80 port: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: myapp-backend-pod namespace: default spec: replicas: 2 selector: matchLabels: app: myapp release: canary template: metadata: labels: app: myapp release: canary spec: containers: - name: myapp image: ikubernetes/myapp:v7 ports: - name: http containerPort: 80
新建ingress规则:
# vim ingress-myapp.yaml
apiVersion: extensions/v1beta1 #api版本 kind: Ingress #清单类型 metadata: #元数据 name: ingress-myapp #ingress的名称 namespace: default #所属名称空间 annotations: #注解信息 kubernetes.io/ingress.class: "nginx" spec: #规格 rules: #定义后端转发的规则 - host: myapp.wjoyxt.com #通过域名进行转发 http: paths: - path: #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/" backend: #配置后端服务 serviceName: myapp servicePort: 80
查看ingress-myapp的详细信息
# kubectl describe ing ingress-myapp
查看nginx-ingress-controller是否注入了nginx的配置
# kubectl exec -n ingress-nginx nginx-ingress-controller-5c84666c56-b7xgz cat /etc/nginx/nginx.conf | less
此时在本地执行 curl -H "Host:myapp.wjoyxt.com" 172.17.213.60:30080 即可看到结果。
使用反向代理的话,修改对应的ingress规则即可,比如:
# vim ingress-app.yaml apiVersion: extensions/v1beta1 #api版本 kind: Ingress #清单类型 metadata: #元数据 name: ingress-myapp #ingress的名称 namespace: default #所属名称空间 annotations: #注解信息 nginx.ingress.kubernetes.io/rewrite-target: / #重写/路径 spec: #规格 rules: #定义后端转发的规则 - host: myapp.wjoyxt.com #通过域名进行转发 http: paths: - path: /app1 #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/" backend: #配置后端服务 serviceName: myapp servicePort: 80
此时,访问 myapp.wjoyxt.com:30080/app1 即可。
4、配置基于域名的 https,ingress
创建基于自身域名的证书
#openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout myapp.wjoyxt.com.key -out myapp.wjoyxt.com.pem -subj "/CN=myapp.wjoyxt.com"
导入域名的证书到集群的secret中,名称自定义
# kubectl create secret tls myapp-ingress-secret --namespace=kube-system --cert myapp.wjoyxt.com.pem --key myapp.wjoyxt.com.key
查看secret
[root@es-60 ~]# kubectl get secret -n kube-system NAME TYPE DATA AGE myapp-ingress-secret kubernetes.io/tls 2 8s
[root@es-60 ~]# kubectl describe secret myapp-ingress-secret -n kube-system
Name: myapp-ingress-secret
Namespace: kube-system
Labels: <none>
Annotations: <none>
Type: kubernetes.io/tls
Data
====
tls.crt: 1115 bytes
tls.key: 1704 bytes
将证书应用到对应的服务中,更新服务的ingress
# vim ingress-app.yaml
apiVersion: extensions/v1beta1 #api版本
kind: Ingress #清单类型
metadata: #元数据
name: ingress-myapp #ingress的名称
namespace: default #所属名称空间
annotations: #注解信息
kubernetes.io/ingress.class: "nginx"
spec: #规格
tls:
- hosts:
- myapp.wjoyxt.com #与secret证书的域名需要保持一致
secretName: myapp-ingress-secret
rules: #定义后端转发的规则
- host: myapp.wjoyxt.com #通过域名进行转发
http:
paths:
- path: #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"
backend: #配置后端服务
serviceName: myapp
servicePort: 80
# kubectl apply -f ingress-app.yaml #重新部署,更新nginx配置
此时可以实现 https://myapp.wjoyxt.com:30443 访问
所有评论(0)