k8s ingress


為什么需要ingress

一組pod 對外暴露服務通過service 有兩種方式一個是nodeport 另一個是loadbalancer。但是它們都是有弊端。

nodeport 必須知道節點服務器的地址和端口,如果此節點掛了那么就需要更換其他節點地址,而且每個服務都會對應一個node上的端口配置維護麻煩。而且odeport 實現的是四層轉發

loadbalancer  每個 LoadBalancer 服務都需要自己的負載均衡器, 以及獨有的公有 IP 地址,一個loadbalancer 只對應一組pod , 而 Ingress 只需要一個公網 IP 就能為許多服務提供訪問。使得所有的Pod 都具有統一的入口

ingress控制器和ingress資源

ingress 控制器實際上就是運行在kube-system 空間的一組pod ,可以簡單把它理解為一個負責均衡器例如nginx ,ingress 資源可以理解為配置在nginx 上面的conf.d下面的配置文件,定義的是基於后端一個服務的轉發規則。

ingress 控制器有很多種,其中  NGINX Ingress Controller 是比較常用的一種,pod 里面運行的就是nginx ,所有的ingress 資源的創建最后都會在此控制器對應的pod 里面生成對應的nginx 配置,另外整個控制器的配置是通過一個configmap實現的,可以查看一下與控制器相同命名空間內是否有一個ingress 命名的configmap,這是控制器的全局配置文件。

 

Ingress 實現原理

簡單理解為在service 基礎上加入了一個負載代理。

實現原理

分為ingress 控制器和ingress 資源。ingress是一個負載代理規則,它是通過ingress-controller 實現的。它通過統一的端口(80/443)可實現4/7層負載,為每個服務創建一個域名,ingress 通過域名來識別訪問的服務,所有的域名配置解析到這一個唯一的ingress 的IP ,實際與pod 通訊還是會經過service。它的底層實際就是nginx或者其他的負載軟件,每一個服務做代理的過程即使為這個服務的pod 創建一個upstream和proxy.

 

客戶端訪問流程圖

 

 

 

Igress 的創建

只有Ingress控制器在集群中運行,Ingress 資源才能正常工作。 不同的 Kubernetes 環境使用不同的控制器實現, 但有些並不提供默認控制器
查看是否存在ingress 控制器
$ kubectl get  po  --all-namespaces
   NAMESPACE     NAME                READY  STATUS  RESTARTS  AGE
 ...      ...
 kube-system  nginx-ingress-controller-gdts  1/1  Running  0    18m
View Code

如果沒有,需要先創建ingress 控制器,再創建ingress 規則

創建ingress 控制器

通過編寫yaml 文件或者命令方式,在yaml 中可以定義對外提供的統一端口。

kubectl  apply  -f  ingress.yaml

kubectl  get pods   -n   ingress-nginx  #查看創建的ingress,必須在它自己的命名空間ingress-nginx 中查看

創建Ingress 規則

vi  ingress.yaml

apiVersion: extensions/vlbetal
kind: Ingress 
metadata:
    name: kubia
spec: 
  rules: 
  - host: kubia.example.com                 #將此域名映射為你的服務
    http: 
      paths 
      - path: /                             #域名后的路徑
        backend: 
          serviceName: kubia-asdf           #對應的是service 名稱
          servicePort:80                   #service 對外端口
View Code
定義了一個單一規則的 Ingress ,確保 Ingress 控制器收到的所有請求主機 kubia example.com HTTP 請求,將被發送到service 的80 端口 

獲取ingress 地址

kubectl  get ingresses -n kzf

可以同一個ingress 暴露多個服務

類比nginx 同一個server name 下面多個location 轉發不同的后端服務

apiVersion: extensions/vlbetal
kind: Ingress 
metadata:
    name: kubia
spec: 
  rules: 
  - host: kubia.example.com                 #對於http://kubia.example.com/ 的訪問轉發到kubia-asdf服務
    http: 
      paths 
      - path: /                              #域名后的路徑
        backend: 
          serviceName: kubia-asdf            #對應的是service 名稱
          servicePort:80                    
      - path: /foo                  #對於http://kubia.example.com/foo  訪問轉發到 bar 服務
     backend: 
          serviceName : bar 
      servicePort: 80
View Code

dns解析

把任意一個 ingress controler所在的pod 的ip 地址解析為定義的應用程序域名,訪問域名后請求到底controller,控制器通過規則和域名找到應用程序實現負載轉發。

配置 Ingress 處理 TLS 傳輸

客戶端和控制器之間的通信是加密的,而控制器和后端 pod 之間的通信不是 。運行在pod 上的應用程序不需要支持 TLS 例如,如果 pod 運行 web務器,則它只能接HTTP 通信,並讓 Ingress 控制器負責處理與 TLS 關的所有內容。要使控制器能夠這樣做,需要將證書和私鑰附加到 Ingress 。這兩個必 需資源存儲在稱為 Secret的Kubernetes 資源 中,然后在 Ingress manifest 中引用
 
1、創建或者購買一個證書
2、創建一個secret
kubectl create secret tls tls-secret --cert=tls.cert --key=tls.key    #私鑰和證書現在存儲在名為 tls-key 的Secret 中

3、配置ingress  

apiVersion: extensions/vlbetal
kind: Ingress 
metadata:
    name: kubia
spec: 
  tls:                                        #這個屬性下包含了所有的tls 配置
  - hosts:
    - kubia.example.com                        #將接收所有來自kubia.example.com 的TLS 連接
    secretName: tls secret
  rules: 
  - host: kubia.example.com                 
    http: 
      paths 
      - path: /                                
        backend: 
          serviceName: kubia-asdf            
          servicePort:80
View Code
注意 Ingress 功能的支持因不同的 Ingress 拉制器實現而異,因此請檢查特定實現的文檔以確定支持的內容Ingress 個相對較新的 kubemetes 功能,因此可以預期將來會看到許多改進 和新功能。雖然目前僅支持 L7 (網絡第7層)負載平衡,但也計划支持 L4 (網絡第4層)負載平衡
 

ingress-nginx  配置rewrite

 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /kzf/$1$2
#    nginx.ingress.kubernetes.io/rewrite-target: /
  name: {{ .Values.projectName }}
  namespace: {{ .Values.namespace }}
spec:
  rules:
  - host: pay-server.kzf.k8s.asdf.com
    http:
      paths:
      - path: /jtlq/kzf(/|$)(.*)          #訪問的ingress的uri ,此處匹配三種情況/jtlq/kzf或/jtlq/kzf/或/jtlq/kzf/...
        backend: 
       serviceName: pay-server 
      servicePort: 8090

解釋:
  訪問 http://pay-server.kzf.k8s.asdf.com.k8s.asdf.com/jtlq/kzf(/|$)(.*) 轉發到后端service pay-server 的8090 端口並且uri 變為/kzf/$1$2,
  替換了/jtlq/kzf(/|$)(.*)

注意:路徑如果寫成這樣 - path: /jtlq/kzf/(.*) 那么直匹配 /jtlq/kzf/或/jtlq/kzf/...這兩種情況。
View Code

ingress 控制器 配置映射片段

nginx ingress 控制器的使用文檔詳見   https://kubernetes.github.io/ingress-nginx/

如果你想在nginx-controller-pod中生成的nginx.conf文件中添加一些自定義配置,例如配置請求頭,gzip 等等,可以通過 snippet,一共分為 http-snippet,server-snippet和location-snippet 等,例如server-snippet表示會把配置映射到nginx.conf 里面的server 區域,默認情況gzip 是啟動的,如果想要配置某個ingress 資源為關閉,配置如下

 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |
      gzip off;

 

關於gzip 壓縮的驗證,可以通過瀏覽器訪問url ,查看的是響應頭的 Accept-Encoding ,如果沒有此字段表示gzip 關閉了。

 

 

 

 


免責聲明!

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



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