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高可用方案

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM