Oh My Iron man post - day ten

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

  • 目錄
    • 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 💎
    • Service Debugging
    • How to install Traefik
    • Nginx-ingress vs Traefik

今天會簡單介紹一下:

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

NodePort, LoadBalancer的比較

NodePort LoadBalancer
優點 設定很方便 1.如果所使用的公有雲有支援,使用起來就跟NodePort一樣方便 2.支援HTTP, TCP, UDP, Websockets, gRPC等Protocol
缺點 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

先來張跟上面一樣的圖壓壓驚:

![](https://i.imgur.com/52du1dJ.png =500x)

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是否寫入

1
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內部有錯:

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

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

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

來增加一些服務看看

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
---
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指到這個服務

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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,要驗證的話可以用以下方式:

1
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