1. 程式人生 > >K8s Ingress筆記

K8s Ingress筆記

K8s Ingress

一 要理解一個概念,首先要明白它是幹什麽用的,然後再去理解它是怎麽實現的。Ingress的作用就是提供一個集群外部訪問集群內部的入口。那麽它是怎麽實現的呢,我們知道,集群內部的Cluster IP外部是無法直接訪問到的,而在 K8s集群中,集群外部訪問內部pod中的應用大概有以下幾種形式:
 1.  通過開啟proxy模式訪問Cluster IP。這種方式要求我們運行 kubectl 作為一個未認證的用戶,因此我們不能用  
 這種方式把服務暴露到 internet 或者在生產環境使用。
 2.  直接訪問pod,pod中定義hostPort,並設置pod級別的hostwork=true,直接將pod中的端口映射到pod所在的物  
 理主機或者虛擬機上。通過訪問主機ip:hostPort即可訪問集群內部pod;這種方式只能非常少量使用,否則和直接  
 使用docker沒多大區別。
 3.  先訪問Service,Service可以直接通過集群內部負載均衡至pod中的應用,而外部訪問集群中的Service可以通  
 過在Service中定義NodePort實現;這種方式在集群中的每臺主機上開放一個隨機的或指定的端口,且每個端口  
 只能提供一個服務,它是通過端口不同來區分不同應用,而不是通過域名,管理不便,不適合在大規模集群中部  
 署。
 4.   通過LoadBlancer Service訪問Service,這個需要接入雲服務,每個服務都會由雲服務提供一個IP作為入口,  
 轉發相應的流量,但每個LoadBlancer Service都會產生費用,成本比較高。
 5.   Ingress,K8s中的API對象,定義了一組規則。Ingress本身只是定義了一組規則,需要配合Ingress controllor  
 才有意義,不理解Ingress controllor沒關系,繼續往下。

  二 如果不通過Ingress,我們也可以手動在Service前部署一個反向代理,比如nginx或者haproxy。

  1. nginx運行在集群中,所以可以訪問到集群內部的Service,只需在nginx配置中proxy_pass指向相應的Service   
  Cluster IP或者dns即可,多一個服務也就是多配置一個nginx中的虛擬機主機。
  2. 通過設置hostPort即可從外部訪問nginx,再通過nginx反向代理至後端應用的Service;或者不通過hostPort,  
  再在nginx前端再加一個Service,通過設置Service的NodePort來訪問nginx。

  三 通過自己部署nginx反向代理這種方式好像就OK了啊,那一直說的Ingress又是什麽?

            Ingress是K8s中的API對象,定義了一組規則,對應於nginx(或者haproxy,traefik等)的一段配置,可以  
    近似成一段虛擬主機的配置,其實Ingress和自己部署反向代理思路都是一樣的,只不過自己部署反向代理時,  
    如果新增加一個服務,你自己需要去增加nginx中的配置並重新加載配置,而在Ingress中你增加一個服務,你需  
    要增加一個Ingress的配置並運行,Ingress會自己去請求K8s的api以獲得新增應用的nds或者Cluster Ip,然後將  
    你寫的Ingress規則轉換成nginx配置,並修改到ngixn中,然後自動reload nginx。
            簡單來說,兩者的區別就是:當新增後端應用時,一種需要增加nginx配置,另外一種需要增加Ingress規  
    則。你可以簡單的把Ingress理解為一段類似nginx虛擬主機的配置,因為它會自動為你轉換。

四 說道這裏,部署Ingress就很簡單了,不過在Ingress中有它自己的一些術語。一個完整的Ingress有以下幾個組件:

    1.  反向代理,可以是nginx、traefik、Haproxy等。
    2.  Ingress controllor,即Ingress控制器,監聽apiserver,獲取服務新增,刪除等變化,並結合ingress規則動  
    態更新到反向代理負載均衡器上,並重載配置使其生效。
    3.  Ingress,K8s的一個資源對象,定義了一組規則,你可以簡單理解為一段對應nginx虛擬機主機的配置。而  
    實際上,Ingress controllor和反向代理,也就是上面的1,2兩個組件,都是結合在一起的。比如traefik,它同時  
    具備反向代理和Ingress controllor的功能;如果使用nginx,那麽你需要部署專用的nginx,它也集成了Ingress   
    controllor。
    本文采用traefik來部署反向代理和Ingress controllor,有關traefik的詳細介紹可以參考官網。

五 實際部署。

       本文從開始到現在,已經覆蓋了很多的背景和知識。你可能擔心現在會是最難的部分,但實際上它最簡單,    
Ingress之所以比較復雜,唯一原因是因為“其他的一切”,而我們已經很好地學完了這些東西。

1. 如果K8s使用了rbac,而Ingress controllor需要訪問apiserver,所以需要先為traefik配置一個Service Account。
cat > traefik-ingress-rbac.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress
  namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress
subjects:
  - kind: ServiceAccount
    name: traefik-ingress
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
EOF
kubectl apply -f traefik-ingress-rbac.yaml
        第一段配置定義了一個Service Account,第二段配置將定義的Service Account綁定到cluster-admin這個已經  
存在的ClusterRole上,cluster-admin是具有訪問apiserver的權限的。 

2. 然後需要部署一個traefik,並且將它暴露到集群外,它既是反向代理也是Ingress controllor。
cat > traefik-ingress-controller.yaml << EOF
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: traefik-ingress-lb
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      terminationGracePeriodSeconds: 60
      serviceAccountName: traefik-ingress
      containers:
      - image: traefik
        name: traefik-ingress-lb
        resources:
          limits:
            cpu: 200m
            memory: 30Mi
          requests:
            cpu: 100m
            memory: 20Mi
        ports:
        - containerPort: 80
          hostPort: 80
        - containerPort: 8080
        args:
        - --web
        - --kubernetes
EOF
kubectl apply -f traefik-ingress-controller.yaml
         這是traefik官方文檔的部署文件,我只是在它裏面加了個Service Account,可以看到,它采用設置pod的  
hostPort方式來將80端口暴露到集群外,80端口可以看做是反向代理http的端口,接收並轉發所有的定義到Ingress  
的流量。而它在pod中還對集群內部有一個8080端口,8080端口一個後端應用,提供了traefik-web-ui。8080端口  
是traefik默認的webUI端口,8080端口定義為Pod的端口,集群外部是無法直接訪問到的,所以我們還需要部署一  
個Service+Ingress。  

3. 部署Service+Ingress
cat > traefik-web-ui.yaml << EOF
apiVersion: v1
kind: Service
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
  - port: 80
    targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  rules:
  - host: traefik-ui.com
    http:
      paths:
      - backend:
          serviceName: traefik-web-ui
          servicePort: 80
EOF
kubectl apply -f  traefik-web-ui.yaml
       當你真正要訪問該traefik-ui.com時,你還需要將這個域名綁定到它對應的IP地址,也就是hostPort所在的主  
  機的IP。配置好hosts文件後,訪問traefik-ui.com。OK

       1. 可以看到Ingress中,當訪問traefik-ui.com這個域名時,對應會訪問到名為traefik-web-ui的Service的80  
端口中。而Service的80端口對應後端的traefik web UI的8080端口。到此為止,一個完整的Ingress就部署完成  
了,它的訪問流程是這樣的:
       集群外部訪問traefik-ui.com-->請求會到達traefik所在的主機的IP:hostPort上,也就是IP:80-->由於Ingress規  
則此時被轉換成traefik中的反向代理配置,根據Ingress規則會被轉發往traefik-web-ui這個Service:80上-->  
Service轉發到後端標簽為 traefik-ingress-lb的pod的8080端口中,實際上又回到了traefik,不過是8080端口。
       簡單來說:請求域名---->traefik:80---->Ingress(只是Ingerss規則,實際還是由traefik完成)---->  
後端Service:80---->traefik:8080

       2. 部署其他後端服務時也是一樣,把上面的後端Service和應用換成相應的就行了。比如部署一個tomcat,那  
麽 需要再部署3個K8s資源,分別是tomcat-deployment.yaml、tomcat-service.yaml、tomcat-Ingress.yaml,  
你請求的域名為Ingress中的host配置的域名,你請求流程為:
       請求域名---->traefik:80---->Ingress(只是Ingerss規則,實際還是由traefik完成)---->tomcat-Service  
---->tomcat-deployment中的Pod。

      3. 上面是通過hostPort暴露traefik,可以直接訪問80端口,如果需要在多臺node上部署,可以通過給相應  
的node 設置lable,然後部署時指定nodeSelector。
      我們同樣可以通過Service的NodePort暴露traefik,需要在traefik前再加一個Service,默認NodePort端口  
範圍 為30000-32767,如果想直接暴露80端口,需要修改apiserver的配置,tomcat采用該方式的請求流程為:
      請求---->traefik-service的Nodeport---->traefik---->Ingress(只是Ingerss規則,實際還是由traefik完成)  
---->tomcat-Service---->tomcat-deployment中的Pod。

K8s Ingress筆記