kubernetes Ingress详解

什么是Ingress

 阿里云称之为ingress路由!在Kubernetes集群中,主要用于接入外部请求到k8s内部,Ingress是授权入站连接到达集群服务的规则集合,为您提供七层负载均衡能力。您可以给 Ingress 配置提供外部可访问的URL、负载均衡、SSL、基于名称的虚拟主机等。

Service缺点

 定义service以后,尤其是NodePort集群访问,需要经过2级转换调度,而且是4层调度,无论是iptables还是ipvs。4调度自身无法实现卸载https会话。
 ingress----k8s还有一种引入集群外部流量的方式,叫ingress。基于7层调度器。利用7层pod,将外部流量引入到内部。

回顾-Service:

工作三种方式模型:

  • userspace(效率低、各种空间转换)
  • iptables
  • ipvs (1.11版之后,部署时需要额外配置先关参数)

Service集群类型:

  • ClusterIP (集群内部通信)
  • NodePort (集群内外互通,工作逻辑:client-->nodeip:nodeport-->clusterip:serviceip--->podiip:containerport),可以在前面加个nginx,代理后端各个nodeport的时候,压力得到释放。
  • LoadBalancer
  • ExternerName

Ingress支持的调度方式

  1. url路径映射调度: location /aa ; location /bb。可以参考nginx。
  2. 主机调度:l例如server aaa; server bbb

Ingress类型:

  1. url映射
  2. 虚拟主机

Ingress-controller: (提供特定功能的pod,nginx-ingress-controller-pod):提供接入外部流量的特定pod。例如有3个节点,在这3个节点打上污点,在每个上面运行特定的daemonset pod,实现外部流量接入,为后面pod提供7层调度。众多控制器都是master节点的controllermanager的子件运行的。而ingree controller自己独立运行,通常是一组pod资源。具有7层代理功能。

支持的代理工具: nginx、Traefik、Evoy(微服务)、HAproxy
watch: Service始终watch着后端pod变化。只要pod发生变化,api-server立刻检测到

Ingress实现原理

  1. 正常是用service去调度后面的适配label的pods,当pods增加,因为有labels,会自动识别后端添加的pods,如果用nginx怎么实现?把nginx运行在pod里面,配置文件在pod内部。这种pod叫ingress controller随时观察着后端的pod的改变。ingress controler自己没有这种能力,借助于service去实现。所以nginx-ingress-controller后端还得建立service。这种service仅仅帮忙分类后端的pods资源。pods的配置在nignx里upstream面。service不会进行调度,仅仅分组。因此可以使用headless service,直接调度至后端pods。关键pods变化,怎么自动nginx的upstream以及其他配置,这种就通过ingress路由实现!
  2. ingress需要建一个前端接入层,前端有可能是虚拟主机nginx配置的server,或者是location url映射,同时也要定义一个后端upstream-server。 upstream有几个主机。通过service来获取的。
  3. ingress有个特点:作为资源来讲,直接通过编辑注入到nginx-ingress-controller,并保存为nginx的配置文件。而且ingress一旦发现service 后端的pods改变,ingress直接注入更新nginx配置文件,而且需要重载配置文件(traefik支持自动重载)。

实现ingress步骤(7层调度):

  1. 部署一个nginx-ingress-controller-pod。部署一个特殊pod。
  2. 给nginx-ingress-controller-pod创建前端service1。用来接入外部请求!
  3. 创建nginx-ingress-controller-pod后端service2,以及service关联的pods。
  4. 创建ingress、自动实现路由规则,自动实现service2自动注入到nginx-ingress-controller-pod规则(nginx.conf)
  5. 总结就是首先部署外部请求<------ingress-service<-----nginx-ingress-controller-pod<--------ingress<------service(headless、daemonset)<------pods

Ingress原理图

原理:外部负载均衡器externalLB请求调至到 nodeport 里面service服务--->调度到内部pod(ingress controller里面)----->根据ingree定义,是虚拟主机,还是url代理---->假设是主机名,一组主机名对应后端的pod资源pod1,pod2,pod3。pod怎么分组通过service进行分组。才能被ingress引用。

先安装ingress controller pod。然后定义ingress。再定义pod生成service。

动态生效:pod一变化,service就变化,service一变化,ingress就变化,ingreess一变化就注入到ingress controller里面。实时动态。 Ingress原理图

部署Ingress-Nginx

git地址:https://github.com/kubernetes/Ingress-nginx
官方网站:https://kubernetes.github.io/ingress-nginx

安装

//下载ingress-nginx yaml初始化安装模板
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.33.0/deploy/static/provider/cloud/deploy.yaml //编辑文件修改Controller的下载地址到国内
vim deploy.yaml containers: - name: controller image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.33.0 imagePullPolicy: IfNotPresent //使用kubectl apply安装 kubectl apply -f deploy.yaml //ingress默认安装在ingress-nginx名称空间内 [root@k8s-master ingress]# kubectl get pod -n ingress-nginx NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-45qcs 0/1 Completed 0 4m12s ingress-nginx-admission-patch-z52jg 0/1 Completed 1 4m12s ingress-nginx-controller-5858f5cdf8-kxfwm 1/1 Running 0 4m12s

通过nodeport方式暴露ingress

//官网下载所需要的yaml文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.33.0/deploy/static/provider/baremetal/deploy.yaml
mv deploy.yaml service-nodeport.yaml
//修改Controller的下载地址到国内。同ingress-controller

//安装
kubectl apply -f service-nodeport.yaml
//查看结果
kubectl get svc -n ingress-nginx
[root@k8s-master ingress]# kubectl get svc -n ingress-nginx
NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.103.86.19    <none>        80:30367/TCP,443:30621/TCP   21m
ingress-nginx-controller-admission   ClusterIP   10.103.210.91   <none>        443/TCP                      21m

创建http的 nginx-ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress    // name
spec:
  rules:
  - host: www.xhyan.com    //domain
    http:
      paths:
      - path: /             //path
        backend:
          serviceName: ngx-svc      //svc name
          servicePort: 80           //svc port

创建的ingress规则生成对应的nginx配置嵌入到nginx-controller中

通过进入ingress controller容器中查看

//查看ingress-controllerpod名称
[root@k8s-master ingress]# kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-45qcs        0/1     Completed   0          101m
ingress-nginx-admission-patch-z52jg         0/1     Completed   1          101m
ingress-nginx-controller-6995cf966b-qs8rc   1/1     Running     0          80m
//进入容器
[root@k8s-master ingress]# kubectl exec -it ingress-nginx-controller-6995cf966b-qs8rc -n ingress-nginx -- /bin/bash
//容器中查看配置
bash-5.0$cat nginx.conf

创建https的 nginx-ingress

  1. 将申请好的https证书放在指定目录
  2. 通过kubectl create secret将证书加入到ingress中
//kubectl create secret将证书加入到ingress中
kubectl create tls tls-secret --key tls.key --cert tls.crt   //证书名为tls-secret

//https ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress    // name
spec:
  tls:
    - hosts:
      - www.xhyan.com
      secretName: tls-secret   //对应kubectl create创建的tls证书名称
  rules:
  - host: www.xhyan.com    //domain
    http:
      paths:
      - path: /             //path
        backend:
          serviceName: ngx-svc      //svc name
          servicePort: 80           //svc port

更新Ingress

假如你想要向已有的ingress中增加一个新的Host,你可以编辑和更新该ingress:

$ kubectl get ing
NAME      RULE          BACKEND   ADDRESS
test      -                       178.91.123.132
          foo.bar.com
          /foo          s1:80
$ kubectl edit ing test  //使用kubectl edit更新
//这会弹出一个包含已有的yaml文件的编辑器,修改它,增加新的Host配置。

spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - backend:
          serviceName: s1
          servicePort: 80
        path: /foo
  - host: bar.baz.com
    http:
      paths:
      - backend:
          serviceName: s2
          servicePort: 80
        path: /foo
..

保存它会更新API server中的资源,会触发ingress controller重新配置loadbalancer。

$ kubectl get ing
NAME      RULE          BACKEND   ADDRESS
test      -                       178.91.123.132
          foo.bar.com
          /foo          s1:80
          bar.baz.com
          /foo          s2:80

在一个修改过的ingress yaml文件上调用kubectl replace -f命令一样可以达到同样的效果。

posted @ 2020-08-31 19:34  純黑色  阅读(7770)  评论(0编辑  收藏  举报