前言
在上文完成k8s集羣搭建的基礎上k8s(一)、1.9.0高可用集羣本地離線部署記錄,承接上文,本文簡單介紹一下k8s對外暴露服務
拓撲圖:
一、k8s對外暴露服務方式介紹
1.Load Blance
目前已經有很多主流的公有云平臺已經都提供基於k8s服務的組件,工作的原理本質上是k8s的服務向雲平臺申請一個負載均衡器來對外服務。因此這種方式只適合在雲平臺內部使用,這裏略過.
2.Nodeport
針對某一個k8s service,k8s集羣內的每一個node都將暴露node的一個指定接口,來爲此service提供服務。此方式要求每一個node都提供一個端口,即使此node上沒有承載有該service 的pod服務載體,因此此方式會帶來一定資源的浪費和管理不便。
3.Ingress
Ingress注入方式,有三個組件,來協同完成對外服務的過程:
1.reverse proxy LB
2.ingress controller
3.k8s Ingress組件
1.reverse proxy LB
將服務請求反向代理至後端服務對應的node上,node收到後再由kube-proxy將請求轉交給endpoint pod.
2.ingress controller
監控apiserver上的svc關聯關係的變化,若svc關聯發生變化(例如svc後端對應的pods發生變化),則動態地獲取變化,更新前面反向代理的配置文件和熱重載。
3.k8s ingress
k8s的一種資源類型,可以基於訪問的虛擬主機、字段等進行區別路由映射到後端不同的k8s service上,ingress controller要實時監控每個ingress對象上指定的service來保證LB配置文件的熱更新
在本文,採用traefik作爲ingress工具演示。
### traefik:
由於微服務架構以及 Docker 、 kubernetes 編排工具最近纔開始流行,因此常用的反向代理服務器 nginx並未提供對k8s ingress的支持,所以Ingress Controller 這個中間件的存在就是用來做 kubernetes 和前端LB來做銜接的;Ingress Controller工作的方式是讀取k8s ingress,通過與k8s api交互實時監控service,當serivce映射關係變化時,能重寫 nginx 配置和熱更新。traefik的出現簡化了這個流程,traefik本身是一個輕量級的reverse proxy LB,並且它原生支持跟 kubernetes API 交互,感知後端變化,因此traefik可以取代上面的1、2組件,簡化結構。
traefik官方介紹圖:
二、服務部署
首先來部署一組簡單的nginx應用容器。
準備好yaml文件:
[root@171 nginx]# ls
nginx-deploy.yaml nginx_ingress.yaml nginx_service.yaml
[root@171 nginx]# cat nginx-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "2"
creationTimestamp: 2018-04-09T04:02:02Z
generation: 4
labels:
app: nginx
name: nginx-deploy
namespace: default
resourceVersion: "111504"
selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deploy
uid: c28090c0-3baa-11e8-b75a-000c29858eab
spec:
replicas: 2
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.9.1
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 2
conditions:
- lastTransitionTime: 2018-04-09T04:57:27Z
lastUpdateTime: 2018-04-09T04:57:27Z
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
observedGeneration: 4
readyReplicas: 2
replicas: 2
updatedReplicas: 2
[root@171 nginx]# cat nginx_service.yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: 2018-04-09T11:34:09Z
labels:
run: nginx
name: nginx
namespace: default
resourceVersion: "140236"
selfLink: /api/v1/namespaces/default/services/nginx
uid: eb57a21b-3be9-11e8-b75a-000c29858eab
spec:
clusterIP: 10.99.59.56
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
[root@171 nginx]# cat nginx_ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
creationTimestamp: 2018-04-09T11:39:48Z
generation: 1
name: test
namespace: default
resourceVersion: "140644"
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/test
uid: b54bbda8-3bea-11e8-b75a-000c29858eab
spec:
rules:
- host: test.nginx.com
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
status:
loadBalancer: {}
創建nginx的deploy、svc、ing資源,使用–record命令後面可以看到revision記錄:
kubectl create -f nginx-deploy.yaml --record
kubectl create -f nginx-service.yaml --record
kubectl create -f nginx-ingress.yaml --record
過1分鐘後查看狀態:
[root@171 nginx]# kubectl get pods -o wide | grep nginx
nginx-deploy-5964dfd755-b2xj5 1/1 Running 2 1d 10.244.0.16 170
nginx-deploy-5964dfd755-v6tdq 1/1 Running 1 4h 10.244.0.17 170
[root@171 nginx]# kubectl get ing | grep nginx
test test.nginx.com 80 23h
[root@171 nginx]# kubectl get svc | grep nginx
nginx ClusterIP 10.99.59.56 <none> 80/TCP 23h
在本地curl pod ip和service 的clusterIP測試:
[root@171 nginx]# curl http://10.244.0.16
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@171 nginx]# curl http://10.244.0.17
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@171 nginx]# curl http://10.99.59.56
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
nginx資源已經創建好了,但是目前只能在本地和集羣內訪問,集羣外部無法訪問,需要把網絡路由打通
三、網絡配置
1.vmware網絡配置:(無網絡限制這一步可跳過)
在公司的電腦上搭的wmware虛擬機,公司網絡上網認證限制外網,單人只允許使用單IP訪問外網,因此虛擬機爲了訪問外網,使用的是NAT模式轉接的物理機的網絡,vmware NAT方式虛擬機通信配置:
首先,每臺vm都要配置:
vmware–編輯–虛擬網絡編輯器:
爲了直接訪問vm網段,在windows物理機上配置路由:
打開cmd,輸入:
route add 192.168.0.0 MASK 255.255.255.0 192.168.0.1 IF 9
IF是接口編號,可以使用route print查看自己電腦上vmnet8網卡對應的網卡接口編號
打開windows網絡共享中心,找到物理網卡,右鍵–屬性–共享,勾選開啓網絡連接共享(類似linux內核設置開啓IP forward轉發):
2.k8s服務網段、pods網段路由,dns配置:
步驟1是隻是打通了外部到vm之間的網絡,如果沒有網絡限制,vm跟外部在同一網段的可以跳過上面的步驟1。
步驟2是外部添加k8s的服務網段、pods網段:
windows cmd添加
route add 10.96.0.0 MASK 255.240.0.0 192.168.0.169 IF 9
route add 10.244.0.0 MASK 255.255.0.0 192.168.0.169 IF 9
windows添加dns記錄:
C:\Windows\System32\drivers\etc\hosts打開編輯,添加dns記錄:
192.168.0.169 test.nginx.com
192.168.0.169 ui.traefik.com
打開瀏覽器測試訪問pod ip、服務的cluster ip:
可以直接訪問!
下面開始部署traefik,通過虛擬主機名訪問.
四、traefik部署
[root@171 traefik]# ls
traefik-ds.yaml traefik_ingress.yaml traefik-rbac.yaml
[root@171 traefik]# cat traefik-rbac.yaml
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: kube-system
[root@171 traefik]# cat traefik-ds.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
name: traefik-ingress-controller
namespace: kube-system
labels:
k8s-app: traefik-ingress-lb
spec:
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
hostNetwork: true
containers:
- image: traefik
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
hostPort: 80
- name: admin
containerPort: 8080
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
args:
- --api
- --kubernetes
- --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
name: traefik-ingress-service
namespace: kube-system
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- protocol: TCP
port: 80
name: web
- protocol: TCP
port: 8080
name: admin
type: NodePort
[root@171 traefik]# cat traefik_ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
creationTimestamp: 2018-04-09T11:39:48Z
generation: 1
name: traefik-ui
namespace: default
resourceVersion: "140644"
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/test
uid: b54bbda8-3bea-11e8-b75a-000c29858eab
spec:
rules:
- host: ui.traefik.com
http:
paths:
- backend:
serviceName: traefik-ingress-service
servicePort: 80
status:
loadBalancer: {}
創建資源:
kubectl create -f traefik-rbac.yaml --record
kubectl create -f traefik-ds.yaml --record
kubectl create -f traefik-ingress.yaml --record
1分鐘後查看創建情況:
[root@171 traefik]# kubectl get pods -o wide -n kube-system| grep trae
traefik-ingress-controller-8lht4 1/1 Running 0 3h 192.168.0.171 171
traefik-ingress-controller-ddvws 1/1 Running 0 3h 192.168.0.170 170
[root@171 traefik]# kubectl get ds -n kube-system| grep trae
traefik-ingress-controller 2 2 2 2 2 <none> 3h
[root@171 traefik]# kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
test test.nginx.com 80 1d
traefik-ui ui.traefik.com 80 3h
打開瀏覽器測試:
總結
k8s的各種功能組件、名詞概念、資源類型(pod/svc/ds/rs/ingress/configmap/role….)、工作流程 等頗爲複雜,理解起來不太容易,需要花時間閱讀官方文檔,因爲k8s更新很快,有一些新功能或者即將淘汰的舊功能,官方的中文文檔更新不太及時,建議直接閱讀英文文檔。
另外這裏爲了方便展示,用的windows查看效果,用linux curl工具測試是一樣的,且網絡的限制,使用的是vmware的NAT,需要多配置一步物理機網絡到vm網絡之間打通,再使用靜態路由讓k8s內部集羣網絡進行通信。有時間回家裏電腦嘗試下GNS3模擬路由器,搭建外部bgp,發佈到集羣bgp內部。