iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 8
2
DevOps

其實我真的沒想過要利用夾縫中求生存的 30 天K8s可以怎麼用系列 第 10

Oh my K8s service ! 談談如何暴露你的服務 - 4

首先要和我的團隊隊友們道歉,因為肥宅我廢到出水,居然在電腦前面睡著忘記發文..
起來的時候已經十二點半,誠心在這邊跟其他三位隊友致歉

這邊是他們三位的鐵人貼文:

Ohmyk8s: https://ithelp.ithome.com.tw/users/20120251/articles
hwchiu: https://ithelp.ithome.com.tw/users/20120317/articles
David Chang: https://ithelp.ithome.com.tw/users/20120327/articles

祝福他們可以順利完賽, 另外我也會繼續PO文, 留言我都有看到噢! 歡迎各位不吝給予指教 :D
只是沒完成新手任務回不了留言...


  • 目錄
    • Introduce K8s service - Kube-proxy
    • Introduce K8s service - 4 ways to apply service(1)
    • Introduce K8s service - 4 ways to apply service(2)
    • @ Service Comparison & Introduce Ingress @
    • Nginx-ingress vs Traefik
    • Service Debugging

今天會簡單介紹一下:

  • [x] NodePort, LoadBalancer的比較
  • [x] 更強大的工具Ingress
  • [x] 介紹Nginx Ingress Controller

NodePort, LoadBalancer的比較

NodePort LoadBalancer
優點 設定很方便 1.如果所使用的公有雲有支援,使用起來就跟NodePort一樣方便 2.支援HTTP, TCP, UDP, Websockets, gRPC等Protocol Text
缺點 1.暴露主機位址2.主機上開洞,增加資安管理負擔3.新增主機時還要重新設定 1.公有雲的loadbalancer很貴2.每個服務都要開一個Load Balancer, 服務一多會非常難管理

我還有什麼方式?

聽起來兩種方式在正式環境上營運都有相當的負擔,那有沒有更好的方法呢?

當然有, 且看Ingress。

![](https://i.imgur.com/Qvx7fRR.png =300x)

Ingress 並不是一種Service type, 他是一種介面。 假設今天你有service1, service2, 設置好了兩個ingress rules:

http://service.test.com/service1
http://service.test.com/service2

用戶就可以透過這兩個url訪問到service1和service2。

根據官方文件的說明,ingress需要搭配ingress controller使用, 這個ingress controller就是為後面的Service提供一個統一的入口,ingress controller以Pod的形式提供服務,並隨時監控api server的services, 如果有變化就會自動更新proxy rules。

介紹Nginx Ingress Controller

先來張圖壓壓驚:

Nginx Ingress Controller是K8s目前有在維護,並且預設的Ingress Controller, 所以我在這邊拿它來做示範。

首先把nginx-stable chart加入local repo端並更新helm repo

安裝中...

確認安裝完成(後來我把它安裝到ingress-nginx這個namespace當中,比較清楚)

由上圖可以看到有ingress-controller和default backend這兩個Pods, 其中ingress-controller會在有新的ingress產生時去抓ingress resources, 並且把ingress rule寫進去nginx.conf

可以透過這個指令確認rule是否寫入

kubectl exec -it -n <namespace-of-ingress-controller> <ingress-controller-pod-name> cat /etc/nginx/nginx.conf

default-backend則會在流量進入時負責根據這些rules, 將流量proxy到正確的services。

要如何確認是否安裝正確?

可以透過打load balancer的方式, 因為現在還沒有設定任何的ingress rule, 所以打根目錄會回404

打 /healthz 則會回200

這邊有個小地方要注意, 如果打load balancer回的是503 error, 可能要下指令看看是不是pod內部有錯:

k logs pod/<ingress-controller-pod-name> -n=ingress-nginx | tail -n 10

或是有可能你的service selector指錯地方, 建議kubectl describe deployment去查。

如果是用AWS ELB可以參考這邊

來增加一些服務看看

以nginx為例,創建一個服務(程式碼範例來源:邱牛的部落格)

---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template: 
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
          - name: html-file
            mountPath: /usr/share/nginx/html
      volumes:  
        - name: html-file 
          configMap:  
            name: nginx-index-v1
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: ingress-nginx
  labels:
    app: nginx
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
---
kind: ConfigMap  
apiVersion: v1  
metadata:  
  name: nginx-index-v1
data:  
  index.html: Nginx V1

然後再創建ingress指到這個服務

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
  name: nginx-demo
  namespace: default
spec:
  rules:
  - http:
      paths:
      - path: /nginx
        backend:
          serviceName: nginx
          servicePort: 80

最後在瀏覽器上查看結果:

大功告成!

同場加映

如果有上網查找範例, 很多都會在ingress加上host,例如:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
  name: nginx-demo
  namespace: default
spec:
  rules:
  - host: nginx.example.com
    http:
      paths:
      - path: /v1
        backend:
          serviceName: nginx
          servicePort: 80
      - path: /v2
        backend:
          serviceName: nginx-v2
          servicePort: 80

但是你真的在瀏覽器上直接打path, 會回傳404,要驗證的話可以用以下方式:

curl -H "Host:nginx.example.com" ${ELB CName}/v1

等到有了domain, 再把他指到ELB。

或是你用NodePort的方式, 就可以直接修改電腦上的 /etc/hosts, 把Cluster nodes的IP後面加上想要測試的domain。


如果你想了解Nginx-controller要如何手工安裝可以參考邱牛的部落格

打完收工。

Reference

  1. 各種比較: https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0
  2. 官方文件Ingress: https://kubernetes.io/docs/concepts/services-networking/ingress/
  3. 官方文件Ingress Controller: https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
  4. Nginx-ingress install trouble-shooting: https://kubernetes.github.io/ingress-nginx/deploy/#aws
  5. 邱牛的部落格: https://www.hwchiu.com/ingress-1.html

上一篇
Oh my K8s service ! 談談如何暴露你的服務 - 3
下一篇
Oh my K8s service ! 談談不錯用的Traefik - 5
系列文
其實我真的沒想過要利用夾縫中求生存的 30 天K8s可以怎麼用12

尚未有邦友留言

立即登入留言