Ingress对外暴露应用

一.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://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md

七.配置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高可用方案

原文地址:https://www.cnblogs.com/lichunke/p/14074812.html