iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 22
0
DevOps

Docker獸 究極進化 ~~ Kubernetes獸系列 第 22

Day-22 活用LoadBalancer and Ingress

前言

上個章節我們學習了Service的運用,並且也了解了kube-proxy、kube-dns的原理與運作。那在這章節中我們將學習如何使用loadBalancer與Ingress與外界溝通。

Communicate with External

我們先來複習一下這個圖,從外界要與Pod溝通必經1與2兩條路。

也就是我們需要

  1. NodePort: 與External IP 對接
  2. TargetPort: 與Pod IP對接
  3. 從Cluster外到Cluster內的接口

https://ithelp.ithome.com.tw/upload/images/20201007/20129737duSC5gJ1iL.jpg

What is LoadBalancer ?

LoadBalancer屬於Service type的一種,也是其中一種暴露接口到Cluster外部的方式,他可以進行TCP/UDP的流量負載平衡與轉發,那並且LoadBalancer有著以下幾種特點:

  1. LoadBalancer能夠將進入的流量轉發到多處
  2. 支援TCP/UDP Protocol
  3. 支援HTTP/HTTPS
  4. 若無指定ip,會在cloud上創立一個新的臨時靜態ip對外暴露。若有指定的話,則會使用指定的ip
  5. 屬於簡便型外暴接口,與Service屬於一對一mapping

https://ithelp.ithome.com.tw/upload/images/20201007/20129737QLCxTol6Li.png

Parse loadBalancer yaml

那我們一樣,先寫好yaml再來解析它吧!

apiVersion: v1
kind: Service
metadata:
  name: ironman
  labels:
    app: ironman
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector:
    app: ironman

我們再來看一下建置好的結果吧!

  • 先刪除原有的service ironman
$ kubectl delete service ironman
service/ironman deleted
  • 再來,我們透過loadbalancer來建立service!
$ kubectl apply -f loadbalancer.yaml
service/ironman created
  • 並且看一下建立後的資訊
$ kubeclt get service ironman
NAME      TYPE           CLUSTER-IP   EXTERNAL-IP      PORT(S)        AGE
ironman   LoadBalancer   10.4.9.104   35.185.174.250   80:30445/TCP   5m58s

這邊可以看到我們建立了Service且

  1. Service Name為ironman
  2. TYPE為LoadBalancer
  3. Cluster IP為10.4.9.104
  4. External IP為35.185.174.250
  5. PORT(S)為 TargetPort 80 : NodePort 30445,這邊因為NodePort並沒有定義,因此會從 30000-32767中隨機挑選一個尚未使用的端口

若想指定nodePort則像下方的寫法

apiVersion: v1
kind: Service
metadata:
  name: ironman
  labels:
    app: ironman
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      targetPort: 80
      nodePort: 32000
  selector:
    app: ironman

最後我們來GKE上看一下loadbalancer

https://ithelp.ithome.com.tw/upload/images/20201007/20129737DX6DTSttbb.png

最後也確認了能夠透過外部ip去與pod溝通。

$ curl -X GET http://35.185.174.250/v1/hc
{"message": "This endpoint for web service health check"}

What is Ingress ?

Ingress公布了cluster外部至內部的http與https routing。藉由ingress來定義routing rules。

所以Ingress能提供給我們

  1. Ingress能夠做到負載平衡,並轉發requests
  2. 支援HTTP/HTTPS
  3. 做SSL CERTIFICATION
  4. 若無指定靜態IP的話,一樣會創造一個臨時的靜態IP提供Ingress做使用
  5. 能夠撰寫自己的routing rules,並與service做到一對多mapping

https://ithelp.ithome.com.tw/upload/images/20201007/20129737ozZtTgQfGt.png

Parse Ingress yaml

因為Ingress並不屬於service的一種,而是一種虛擬的託管物件,幫助service做負載平衡與ssl認證與黑白名單過濾...等功能。也因此在這個練習當中會有ingress與service兩個yaml

  • service一樣用Day-20的service為例子,nodePort為80。

service.yaml

kind: Service
apiVersion: v1
metadata:
  name: ironman
  labels:
    app: ironman
spec:
  type: ClusterIP
  ports:
    - name: ironman
      protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: ironman
  • 接下來我們建立一個ingress,並且把該url上prefix有v1的request都導到上面的service當中

ingress.yaml

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ironman-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: ironman
    nginx.ingress.kubernetes.io/use-regex: "true"

spec:
  rules:
  - http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          serviceName: ironman
          servicePort: 80
  • 接下來就建立service與ingress吧
$ kubectl apply -f service.yaml
service/ironman created
$ kubectl apply -f ingress.yaml
ingress.networking.k8s.io/ironman-ingress created
  • 建立後一樣看一下ingress資訊
$ kubectl describe ingress ironman-ingress
Name:             ironman-ingress
Namespace:        default
Address:          <Address>
Default backend:  default-http-backend:80 (10.0.1.4:8080)
Rules:
  Host  Path  Backends
  ----  ----  --------
  *
        /v1   ironman:80 (10.0.2.11:80)
Annotations:
  ingress.kubernetes.io/backends:                    {"k8s-be-31678--11092c602dd2be06":"Unknown","k8s1-11092c60-default-ironman-80-859c8e3a":"Unknown"}
  ingress.kubernetes.io/forwarding-rule:             k8s2-fr-e6h3ybgi-default-ironman-ingress-7xf4nxua
  ingress.kubernetes.io/target-proxy:                k8s2-tp-e6h3ybgi-default-ironman-ingress-7xf4nxua
  ingress.kubernetes.io/url-map:                     k8s2-um-e6h3ybgi-default-ironman-ingress-7xf4nxua
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"networking.k8s.io/v1beta1","kind":"Ingress","metadata":{"annotations":{},"name":"ironman-ingress","namespace":"default"},"spec":{"rules":[{"http":{"paths":[{"backend":{"serviceName":"ironman","servicePort":80},"path":"/v1","pathType":"Prefix"}]}}]}}

Events:
  Type    Reason  Age    From                     Message
  ----    ------  ----   ----                     -------
  Normal  ADD     5m39s  loadbalancer-controller  default/ironman-ingress
  Normal  CREATE  4m46s  loadbalancer-controller  ip: <Address>

這邊可以看到我們建立了Ingress且

  1. Ingress Name為ironman-ingress
  2. Address為
  3. 因沒設定預設backend,所以會連到預設的default-http-backend:80
  4. 我們所設定的Rules只會過濾url prefix為v1的reques
  5. 創了一個 default的loadbalancer-controller(下章節解說)
  • 最後我們上GKE看一下ingress是否如期創立

https://ithelp.ithome.com.tw/upload/images/20201007/20129737ulr38lEekH.png

  • 用curl來測試一下吧
$ curl -X GET http://34.120.244.91/v1/hc
{"message": "This endpoint for web service health check"}

See more ingress !

我們再來看一個比較艱深的例子吧

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ironman-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: ironman
spec:
  tls:
    - secretName: ironman-tls
  rules:
    - host: ironman2020
      http:
        paths:
          - backend:
              serviceName: ironman
              servicePort: 80
      https:
        paths:
          - backend:
              serviceName: ironman
              servicePort: 443
   

這邊我們多做了幾件事

  1. 我們設定了固定的靜態IP,每次ingress創立時都會mapping到gcp上的ironman這個static ip

(控制台—>VPC控制網路—>外部IP位置),請記得靜態Ip要先創建好否則ingress會mapping不到,這樣的話又會創一個臨時的靜態IP

https://ithelp.ithome.com.tw/upload/images/20201007/20129737g0geIWUnfd.png

  1. 我們做了ssl的認證,使用secret創造ssl certification的方法如下
kubectl create secret tls ironman-tls --cert ironman_cert.pem --key ironmankey.pem

Github Repo

本篇章所有程式碼將放在下面的github project當中的branch day-22

後記

這章節我們學會了如何使用LoadBalancer與Ingress,也讓我們的後端服務成功的與外界溝通,但我們現在使用的只是預設的Ingress Controller,且Ingress還有很多其他東西等著我們去挖掘。有時間的話我再額外開個篇章講述!

https://ithelp.ithome.com.tw/upload/images/20201007/20129737I3fVQP4rYK.png
https://ithelp.ithome.com.tw/upload/images/20201007/20129737aNCsRxRWSM.png

Reference

https://kubernetes.io/zh/docs/concepts/services-networking/ingress/
https://cloud.google.com/load-balancing/docs/network
https://kubernetes.github.io/ingress-nginx/


上一篇
Day-21 尋覓 Service、kube-dns 與 kube-proxy
下一篇
Day-23 抽象的Affinity 與 Anti-Affinity
系列文
Docker獸 究極進化 ~~ Kubernetes獸30

尚未有邦友留言

立即登入留言