作者: Colin Jao 饒康立 – VMware資深技術顧問,主要負責VMware NSX產品線,目前致力於網路虛擬化、分散式安全防護技術與新應用遞送方案的介紹與推廣。

在一個標準的Kubernetes環境內,基本上AKO (Avi Kubernetes Operator) 需要處理的就是LB Service以及Ingress這兩種配置,另外在Openshift內還有專屬的Route型態。在本篇內,我想說明AKO是如何處理各種應用遞送服務要求,轉譯為NSX Advanced Load Balancer內的Virtual Service。這邊會用與前一篇相同的環境來進行舉例,因此這邊把前篇的兩張圖再抓回來如下。

我們在標準Kubernetes內要讓外部用戶可存取應用時,會採用下列這幾種方法:

1. Service Type: LoadBalancer

在此型態內,AKO會要求Avi Controller建立一個L4 Application型態的Virtual Service。直接以下面的YAML檔舉例,這是上圖內應用2號:KUARD裡的Load Balancer配置:


## Kuard LB                                    
                                               
apiVersion: v1                                 
kind: Service                                  
metadata:                                      
  name: kuard-lb-svc                           
  labels:                                      
    Application: kuard                         
  namespace: kuard-ns                          
spec:                                          
  type: LoadBalancer                           
  ports:                                       
  – port: 80                                   
    protocol: TCP                              
    targetPort: 8080                           
  selector:                                    
    Application: kuard

上面的配置內,

  • AKO要求啟用一個L4 Application型態的Virtual Service,對外聽取TCP 80 port
  • Virtual IP會由Avi Controller內預先配置的Pool內動態選取,在此範例內,拿到的是172.20.14.237這個IP
  • 往後會送到有標籤 Application: kuard的pod上的8080 port

下面兩張圖內我們看到對應到這個應用的Virtual Service以及相關的Pool,可看到這是一個標準的L4 Load Balancing機制。

其次在LB Service內,應用管理者是可以指定 IP 的。下面是前面應用1號:Yelb內的LoadBalancer配置。透過加上”loadBalancerIP”設定,我們指定了這個Load Balancer Service的對外IP必須是172.20.14.249

—                                            
apiVersion: v1                                 
kind: Service                                  
metadata:                                      
  name: yelb-ui                                
  labels:                                      
    Application: yelb                          
    Tier: yelb-ui                              
  namespace: yelb-app                          
spec:                                          
  type: LoadBalancer                           
 
loadBalancerIP: 172.20.14.249
                
  ports:                                       
  – port: 80                                   
    protocol: TCP                              
    targetPort: 80                             
  selector:                                    
    Application: yelb                          
    Tier: yelb-ui                              

Service Type: Load Balancer內的配置三個重點很快與大家提醒一下:

  • 每個Load Balancer服務都會取得一個獨立的VIP,是1:1的關係
  • 如果要明確指定Load Balancer VIP,這個IP必須是在VIP Pool範圍內。以上面例子舉例,應用管理者要求172.20.14.249,是在我們預先配置的172.20.14.231~172.20.14.250範圍內。只要這個IP尚未被使用,就可以正常派發運作
  • 接上條,但如果這個指定的IP沒有在VIP Pool範圍內,比如說指定了172.20.14.100 (不在231~250範圍),或是雖然在範圍內,Avi內的IPAM機制發現這個IP已經被其他服務使用了,此時Avi就不會派發IP給這個Load Balance服務。

2. Ingress

AKO可以支持在K8S 1.18版前的networking.k8s.io/v1beta1,以及1.19版後的networking.k8s.io/v1兩種API resource,Ingress要用哪種版本的語法撰寫都可以。當AKO看到應用管理員配置一個Ingress出來時,

  • 如果此Ingress內沒有tls宣告,代表要啟用一個L7 HTTP (80 port) 的七層服務
  • 如果此Ingress內有tls宣告,代表要啟用一個L7 HTTPS (443 port) 的七層服務

在Ingress配置內,預設是多個Ingress服務會共享Virtual IP,在AKO內稱其為Shard機制。當初之所以這樣設計是因為希望節省對外IP,在公有雲內可以省點錢。但如果管理者要求,我們仍然可以配置讓一個Ingress自己有一個獨享的Virtual IP。

很快速解釋Ingress內的Shard / Virtual IP取用機制:

  • 多個Ingress,包含HTTP / HTTPS不同型態,會共享Virtual IP
  • 一個Virtual IP可以對應到多少個Ingress (FQDN Host),可以在AKO的配置內設定,如Large / Medium / Small / Dedicated。
  • 每個Ingress會基於本身的FQDN Host做hash後,決定要放到哪個Virtual IP內。因此只要Host沒有改動,對外使用的Virtual IP都會一致
  • 目前的版本,應用管理者無法指定Ingress要採用的Virtual IP

用前面環境內應用4號:DVWA的Ingress配置來做舉例

 
# Ingress Rule for N/S Load-Balancing         
apiVersion: networking.k8s.io/v1               
kind: Ingress                                  
metadata:                                      
  name: dvwa-ingress                           
  namespace: dvwa-ns                           
spec:                                          
  tls:                                         
  – hosts:                                     
      – dvwa.tkgm.sysage.com                   
    secretName: dvwa-secret                    
  rules:                                       
  – host: dvwa.tkgm.sysage.com                 
    http:                                      
      paths:                                   
      – pathType: Prefix                       
        path: /                                
        backend:                               
          service:                             
            name: dvwa-svc                     
            port:                              
              number: 80

上述例子的YAML配置內,

  • 採用新版networking.k8s.io/v1的API Resource
  • 配置tls,憑證內容建於dvwa-secret內,對應dvwa.tkgm.sysage.com這個host
  • 往後是轉送給在dvwa-svc這個service內pod的80 Port

當AKO讀取此要求,行為則是告知Avi Controller:

  • 這個Ingress對應的Hosts (FQDN) 是dvwa.tkgm.sysage.com,做Hash運算後,Avi Controller會在上層的gc-01–Shared-L7-7這個Parent Virtual Service內,建立一個Child Service來對應dvwa.tkgm.sysage.com這個ingress服務(簡而言之,就是SNI: Server Name Indication機制)
  • 因此這個Ingress服務會使用的是gc-01–Shared-L7-7這個Parent Service的Virtual IP: 172.20.14.233。這個IP當然也是由前面VIP Pool範圍內所動態派送出來的
  • 因為有配置tls,當然這個Virtual Service必須是L7 HTTPS,提供SSL Termination的作業
  • 同時,AKO會自行抓取對應此Ingress服務的憑證,送往此Virtual Service內。
  • AKO會要求Avi Controller建立對應的Datascript,來建立Ingress Virtual Service與後端Pool的對應。

上面的相關機制如果大家有興趣做進一步研究,可以到Avi網站內” Handling of Kubernetes/ OpenShift and Avi Objects“這個頁面 ( https://avinetworks.com/docs/ako/1.4/handling-objects/ ) 有更完整的討論。反正呢,這裡想讓大家知道的重點是:

  • 應用管理者使用Kubernetes標準的LoadBalancer Service / Ingress機制建立應用遞送要求。
  • 基於上述配置,AKO會自行要求Avi Controller建立對應的Virtual Service。
  • 各個對應Virtual Service使用的Virtual IP會在指定的VIP Pool範圍內自動配置。

先打住。這邊還有一個問題沒有說明:AVI內是怎麼做Ingress Host與IP間的管理維運呢?下一篇網誌來討論這個議題。