[k8s集群系列-10]Kubernetes Service暴露方式及Traefik使用
訪問部署在kubernetes集群中服務,有兩種類型:
- 集群內部實現訪問
- 集群外部實現訪問
但是不管是集群內部還是外部訪問都是要經過kube-proxy的
集群內部實現訪問
ClusterIP
Clusterip是集群內部的私有ip,在集群內部訪問服務非常方便,也是kuberentes集群默認的方式,直接通過service的Clusterip訪問,也可以直接通過ServiceName訪問。集群外部則是無法訪問的。
示例
**創建nginx服務,提供web服務z
nginx-ds.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-dm
spec:
replicas: 2
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx
創建一個pod作為client
alpine.yaml
apiVersion: v1 kind: Pod metadata: name: alpine spec: containers: - name: alpine image: alpine command: - sh - -c - while true; do sleep 1; done
應用並測試訪問
kubectl create -f nginx-ds.yaml
kubectl create -f alpine.yaml
> kubectl get svc | grep nginx
nginx-svc ClusterIP 10.254.105.39 <none> 80/TCP 11m
> kubectl exec -it alpine ping nginx-svc
PING nginx-svc (10.254.105.39): 56 data bytes
64 bytes from 10.254.105.39: seq=0 ttl=64 time=0.073 ms
64 bytes from 10.254.105.39: seq=1 ttl=64 time=0.083 ms
64 bytes from 10.254.105.39: seq=2 ttl=64 time=0.091 ms
64 bytes from 10.254.105.39: seq=3 ttl=64 time=0.088 ms
> kubectl exec -it alpine ping 10.254.105.39
PING 10.254.105.39 (10.254.105.39): 56 data bytes
64 bytes from 10.254.105.39: seq=0 ttl=64 time=0.137 ms
64 bytes from 10.254.105.39: seq=1 ttl=64 time=0.106 ms
64 bytes from 10.254.105.39: seq=2 ttl=64 time=0.083 ms
使用curl訪問測試
> kubectl exec -it alpine sh # 默認沒有安裝curl
/ # apk update && apk upgrade
/ # apk add curl
kubectl exec -it alpine curl http://10.254.105.39
kubectl exec -it alpine curl http://nginx-svc # 都可以訪問到nginx默認頁面
集群外部方式訪問
NodePort
NodePort在kubenretes裏是一個早期廣泛應用的服務暴露方式。Kubernetes中的service默認情況下都是使用的ClusterIP
這種類型,這樣的service會產生一個ClusterIP,這個IP只能在集群內部訪問,要想讓外部能夠直接訪問service,需要將service type修改為 nodePort。將service監聽端口映射到node節點。
示例
nginx-ds.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-dm
spec:
replicas: 2
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30004
protocol: TCP
selector:
name: nginx
創建
kubectl create -f nginx-ds.yaml
訪問測試
在集群之外,可以通過任何一個node節點的ip+nodeport
都可以訪問集群中服務
> curl http://192.168.16.238:30004
> curl http://192.168.16.239:30004
....
> curl http://192.168.16.243:30004
> curl http://192.168.16.244:30004
LoadBalancer
LoadBlancer Service 是 kubernetes 深度結合雲平臺的一個組件;當使用 LoadBlancer Service 暴露服務時,實際上是通過向底層雲平臺申請創建一個負載均衡器來向外暴露服務;目前 LoadBlancer Service 支持的雲平臺已經相對完善,比如國外的 GCE、DigitalOcean,國內的 阿裏雲,私有雲 Openstack 等等,由於 LoadBlancer Service 深度結合了雲平臺,所以只能在一些雲平臺上來使用
Ingress
官方文檔
Ingress是自kubernetes1.1版本後引入的資源類型。必須要部署Ingress controller才能創建Ingress資源,Ingress controller是以一種插件的形式提供。
使用 Ingress 時一般會有三個組件:
- 反向代理負載均衡器
- Ingress Controller
- Ingress
組件介紹
反向代理負載均衡器
反向代理負載均衡器很簡單,類似nginx,haproxy;在集群中反向代理負載均衡器可以自由部署,可以使用 Replication Controller、Deployment、DaemonSet 等等,推薦DaemonSet 的方式部署
Ingress Controller
Ingress Controller 實質上可以理解為是個監視器,Ingress Controller 通過不斷地跟 kubernetes API 打交道,實時的感知後端 service、pod 等變化,比如新增和減少 pod,service 增加與減少等;當得到這些變化信息後,Ingress Controller 再結合下文的 Ingress 生成配置,然後更新反向代理負載均衡器,並刷新其配置,達到服務發現的作用
Ingress
Ingress 簡單理解就是個規則定義;比如說某個域名對應某個 service,即當某個域名的請求進來時轉發給某個 service;這個規則將與 Ingress Controller 結合,然後 Ingress Controller 將其動態寫入到負載均衡器配置中,從而實現整體的服務發現和負載均衡
這種方式不需再經過kube-proxy的轉發,比LoadBalancer方式更高效。
Traefik使用
Traefik是一款開源的反向代理與負載均衡工具。它最大的優點是能夠與常見的微服務系統直接整合,可以實現自動化動態配置。目前支持Docker、Swarm、Mesos/Marathon、 Mesos、Kubernetes、Consul、Etcd、Zookeeper、BoltDB、Rest API等等後端模型。
部署Traefik
創建RBAC授權
獲取traefik-rbac.yaml文件並應用,用於service account驗證:
wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-rbac.yaml #不用修改直接應用就行
> kubectl create -f traefik-rbac.yaml
DaemonSet方式部署Traefik
以 Daemon Set 的方式在每個 node 上啟動一個 traefik,並使用 hostPort 的方式讓其監聽每個 node 的 80 端口
獲取yaml文件
wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yaml
> kubectl get pod,svc -n kube-system | grep traefik
> kubectl get pod,svc -n kube-system | grep traefik
pod/traefik-ingress-controller-7fkp7 1/1 Running 0 10m
pod/traefik-ingress-controller-mqnm9 1/1 Running 0 10m
pod/traefik-ingress-controller-tdg77 1/1 Running 0 10m
service/traefik-ingress-service ClusterIP 10.254.179.212 <none> 80/TCP,8080/TCP 22s
Taefik-UI
traefik 本身還提供了一套 UI 供我們使用,其同樣以 Ingress 方式暴露
獲取yaml文件
wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml
> kubectl create -f ui.yaml
- host: traefik-ui.k8s # 可以綁定node節點ip做對應hosts解析
訪問web-ui
hosts
192.168.16.238 traefik-ui.k8s
訪問
http://traefik-ui.k8s/dashboard/
Ingress
創建nginx服務的暴露規則
nginx-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-traefik
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: nginx.svc
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
kubectl create -f nginx-ingress.yaml
訪問測試
hosts
192.168.16.238 nginx.svc
http://nginx.svc
k8s-dahboard的暴露
k8s-dashboard-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dashboard-k8s-traefik
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: dashboard.k8s
http:
paths:
- path: /
backend:
serviceName: kubernetes-dashboard
servicePort: 80 # dashboard使用https則需要改成443
應用並測試
> kubectl create -f k8s-dashboard-ingress.yaml
訪問web-ui
hosts
192.168.16.238 dashboard.k8s
http://dashboard.k8s/#!/login
使用token登錄
> kubectl get secret -n kube-system|grep admin-token
admin-token-4sk8z kubernetes.io/service-account-token 3 7s
> kubectl get secret admin-token-4sk8z -o jsonpath={.data.token} -n kube-system |base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi00c2s4eiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImUwYTc5YzA0LTc3OWQtMTFlOC05MzQwLTAwNTA1Njk4NzU5MCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTphZG1pbiJ9.AiIHiuti7WDU0DWAzy3hYj4R66oUOaBGpyBkG5n2OrYk_LYlYyyLf-0DxavtD8MECpfC6aV0TtTlQsiSGS9RceyF3SIiqxNn0-73dz8w-LFquz-IBidvLq4U-POEQY9DOygW9MBnu82eUrN_qUg5Yf5HUZndIFgWyT_p5w0EGtXUl96S05ULVVAqVoglNdZCDOWxWw_VU6z_HU5DnIomiLFG3Ujtxe1hEk9V-Inxs-Z2pDr-SCUFMPqTn2k8oHJn3wFkLyvDP5DXulTYNp5N40lUkpJzThEi1es5PDGUo-v9dW0w2RJ7YSlb6NNDanbEyA8DbPB4kUvUNjmKNzsw-g
實現Ingress很多service mesh也是可以解決的
[k8s集群系列-10]Kubernetes Service暴露方式及Traefik使用