Service可以实现四层调度,Ingress配合IngressController可以实现七层调度,Ingress就是一组转发规则,IngressController就是一个可以监听套接字的应用。

Ingress Controller:

        Ingress Controller与宿主机共享网络名称空间直接监听在宿主机的IP地址上,外部流量可以直接到达Ingress Controller,client --> Ingress Controller --> Pods 这样每个节点只能有一个Ingress Controller,使用DaemonSet 控制器在每个节点上运行一个Ingress Controller。这样外部的均衡器就可以调度到任何一个节点上了。如果节点数很多可以打上污点,只在部分节点上运行Pod。

        Ingress Controller 和其他的控制器有些不同,Ingress Controller 就是运行一个Nginx的Pod。而其他的ReplicaSet、deployment、DaemonSet 都是作为Controller-manager 的一部分存在的。


Ingress:

        用 service 的 selector 选择相应的Pod并将Pod的IP返回给 Ingress,Ingress 根据这些IP生成配置注入到 Ingress Controller 中。


Ingress策略


        Ingress是kubernetes的标准资源类型之一,它其实就是一组基于DNS名称(host)或URL路径把请求转发至指定的Service资源的规则,用于将集群外部的流量转发至集群内部完成服务发布。但是Ingress自身并不能进行流量穿透,还需要监听套接字的功能然后根据Ingress定义的这些规则转发流量。这个套接字的功能需要IngressController来实现。


官方文档:

https://v1-18.docs.kubernetes.io/docs/concepts/services-networking/ingress/


创建Ingress:

        annotations 字段必加,多Ingress集群中用来识别Ingress控制器的类别。

        rules和backend必须要有一个。

rules类型的Ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: www.scriptjc.com
    http:
      paths:
      - backend:
          serviceName: myapp-svc
          servicePort: 80

service类型的Ingress:

        Ingress Controller会分配一个IP接收请求,并转发至 backend.serviceName。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-svc
spec:
  backend:
    serviceName: myapp-svc
    servicePort: 80

基于URL路径进行流量转发:

        将domain/wap 的转发到名称为 wap 的service。

        将domain/api 的转发到名称为 api 的service。

        注意:Ingress中path的定义需要与后端真实Service提供的path一致,否者会转发到一个不存在的path上而引发报错。如下例子中的path: /wap 后端提供服务的nginx或tomcat也需要有/wap路径。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-url
  annotations:
    ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: mywebsite.com
    http:
      paths:
      - path: /wap
        backend:
          serviceName: wap
          servicePort: 80
      - path: /api
        backend:
          serviceName: api
          servicePort: 80

基于主机名的虚拟主机:

        将 api.scriptjc.com 转发到名称为 api 的service上。

        将 wap.scriptjc.com 转发到名称为 wap 的service上。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: virtual-host
spec:
  rules:
  - host: api.scriptjc.com
    http:
      paths:
      - backend:
          serviceName: api
          servicePort: 80
  - host: wap.scriptjc.com
    http:
      paths:
      - backend:
          serviceName: wap
          servicePort: 80

TLS类型的Ingress资源:

        包含一个私钥和证书的Secret对象,并卸载HTTPS。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-tls
spec:
  tls:
  - secretName: Secret
  backend:
    serviceName: myapp
    servicePort: 80

HTTP强制跳转HTTPS:80强制跳转443

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  labels:
    serivce: demo
  name: demo
  namespace: default
spec:
  rules:
  - host: www.scriptjc.com
    http:
      paths:
      - backend:
          serviceName: demo
          servicePort: 80
        path: /
  tls:
  - hosts:
    - www.scriptjc.com
    secretName: demo



networking.k8s.io/v1


        新版的apiVersion 为 networking.k8s.io/v1,旧版的extensions/v1beta1 在k8s 1.22+ 就会彻底删除不能用。

命令行创建:

kubectl create ingress php72 --rule="nginx-php72.demo.com/=php72:80"

新版示例:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prometheus-k8s
  namespace: monitoring
  annotations:
    kubernetes.io/ingress.class: nginx # 有些版本需要加上有些不用,如1.22版本需要加上
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: prometheus2.demo.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: prometheus-k8s
            port:
              number: 9090

设置白名单:

  annotations:
    nginx.ingress.kubernetes.io/service-weight: ''
    nginx.ingress.kubernetes.io/whitelist-source-range: 220.191.163.50/32, 120.21.21.3

设置黑名单:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |
      deny 47.93.48.132;
      deny 47.94.5.13;
      allow all;



aws ingress


aws ingress配置:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-1:011111111:certificate/xxxxxxx-c1ae-xxxxxxxx-xxxxxxxx
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/subnets: subnet-05008fbb31930c7c0, subnet-071e07e83dd5146f5
    alb.ingress.kubernetes.io/target-type: ip
  name: admin-api
  namespace: prd
spec:
  ingressClassName: alb
  rules:
  - host: api.scriptjc.com
    http:
      paths:
      - backend:
          service:
            name: api
            port:
              number: 80
        path: /
        pathType: Prefix

ingress demo:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
  name: uat-proxy-nginx
  namespace: prd
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - backend:
          service:
            name: uat-proxy-nginx
            port:
              number: 80
        path: /
        pathType: Prefix

创建ingress:aws创建ingress之后会自动分配一个负载均衡地址,将域名用cname解析到这个地址即可。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: prod
  name: oversea-loan-bi
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  rules:
    - http:
        paths:
          - path: /*
            backend:
              serviceName: oversea-loan-bi
              servicePort: 80
status: # 创建好上面的资源apply后,aws自动分配下面这个地址
  loadBalancer:
    ingress:
    - hostname: k8s-prod-overseal-1111111111-111111111.ap-southeast-1.elb.amazonaws.com

aws Ingress绑定证书:aws中一个证书只能被一个ingress绑定,证书需要申请,申请完后会给一个arn的值,把arn后面的字符串写上去即可;也就是说这个arn值只能写入一个ingress里,写入多ingress里只会有一个生效。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    # 绑定ssl证书
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-southeast-1:00000000839:certificate/0fa69b5c-42ad-4r49-a1a7-4a2896f383a1
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    kubernetes.io/ingress.class: alb
  finalizers:
  - ingress.k8s.aws/resources
  name: prod-demo.com
  namespace: prod
spec:
  rules:
  - host: rest.demo.com
    http:
      paths:
      - backend:
          serviceName: sulu-rest
          servicePort: 80
        path: /*
        pathType: ImplementationSpecific
status:
  loadBalancer:
    ingress:
    - hostname: k8s-prod-demo-xxxxxxxx-974373674.ap-southeast-1.elb.amazonaws.com

参考地址:

kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/ingress/annotations/#annotations



websocket


websocket:支持websocket的配置

apiVersion: networking.k8s.io/v1beta1
kind: Ingressmetadata:
  name: sx-data-server
  namespace: spot-standard 
  annotations:
    kubernetes.io/ingress.class: "nginx"
    # 加入下面这两个指令
    nginx.ingress.kubernetes.io/configuration-snippet: |
       proxy_set_header Upgrade "websocket";
       proxy_set_header Connection "Upgrade";
spec:
  rules:
  - host: websocket.demo.com
    http:
      paths:
      - path: /
        backend:
          serviceName: demo
          servicePort: 61051


部署IngressController:

https://scriptjc.com/article/927