1. 訪問(wèn)Rest API
直接訪問(wèn)Rest API一般有兩種方式,一種是通過(guò)代理的模式,一種直接的http客戶(hù)端訪問(wèn),比較推薦第一種訪問(wèn)的方式。
1.1 代理模式
首先通過(guò)如下方式把代理運(yùn)行起來(lái):
screen kubectl proxy # 通過(guò)CTL+a+d組合鍵放在后臺(tái)運(yùn)行
然后就可以訪問(wèn)API了,比如:

1.2 非代理模式
這種訪問(wèn)模式是基于ServiceAccount資源并且需要提供認(rèn)證token。
首先,獲取token:
k8s_token=$(kubectl get secret $(kubectl get secrets | grep -i default | awk '{print $1}') -o yaml | grep token: | awk '{print $2}' | base64 -d)
其次,獲取訪問(wèn)API的BaseURL:

最后,通過(guò)如下方式訪問(wèn)API:

不過(guò)這種方式可能有時(shí)需要角色綁定,類(lèi)似下面這樣:
kubectl create clusterrolebinding my_role --clusterrole=cluster-admin --serviceaccount=default:default
2. K8s集群Pod和Service訪問(wèn)策略
這里的訪問(wèn)一般可分為集群內(nèi)部訪問(wèn)(比如Node訪問(wèn)Pod、Pod間互訪等)和集群外部訪問(wèn),下面就從這兩種訪問(wèn)途徑聊聊它們各自的實(shí)現(xiàn)方式。
2.1 集群內(nèi)部訪問(wèn)
簡(jiǎn)單總結(jié)一下,大致會(huì)有下面幾種實(shí)現(xiàn)的方式:
- hostNetwork
通過(guò)設(shè)置Pod的YAML的文件spec區(qū)域字段hostNetwork: true實(shí)現(xiàn),其實(shí)質(zhì)是實(shí)現(xiàn)了Pod和其所在的Node共享網(wǎng)絡(luò)棧,如此就可以通過(guò)Node的任一IP加Pod服務(wù)的端口來(lái)實(shí)現(xiàn)對(duì)Pod服務(wù)的訪問(wèn)。
不過(guò)這種實(shí)現(xiàn)方式會(huì)存在兩個(gè)缺點(diǎn):Pod服務(wù)暴露的端口可能會(huì)與Node某個(gè)服務(wù)端口沖突;由于Pod的生命周期很短比如重啟或者出現(xiàn)故障等原因,Pod經(jīng)常會(huì)被調(diào)度到不同的Node,因此可能需要維護(hù)一個(gè)Pod和Node映射關(guān)系。
- hostPort
這是一種直接定義Pod網(wǎng)絡(luò)的方式,直接將容器的端口與所調(diào)度的節(jié)點(diǎn)上的端口路由,這樣用戶(hù)就可以通過(guò)宿主機(jī)的IP加上來(lái)訪問(wèn)Pod了,如下是這種訪問(wèn)方式的一個(gè)實(shí)現(xiàn)樣例:
...
spec:
containers:
- name: nginx_test
image: nginx:1.9.1
ports:
- containerPort: 80
hostPort: 8900
...
如此就能夠通過(guò)$HOSTIP:8900來(lái)訪問(wèn)該P(yáng)od的服務(wù)了,不過(guò)這種實(shí)現(xiàn)方式仍存在hostNetwork訪問(wèn)實(shí)現(xiàn)的第二個(gè)缺點(diǎn)。
- Kubectl port-forward
在本地設(shè)置端口監(jiān)聽(tīng),實(shí)現(xiàn)對(duì)Pod端口轉(zhuǎn)發(fā),由于這種類(lèi)型的轉(zhuǎn)發(fā)端口是綁定在本地的,這種方式也僅適用于調(diào)試服務(wù)。
- ClusterIP類(lèi)型的Service
這個(gè)是K8s默認(rèn)使用Service的方式,通過(guò)一個(gè)固定的VIP和端口去訪問(wèn)Pod服務(wù),同時(shí)提供負(fù)載均衡能力,不過(guò)僅限K8s內(nèi)部集群訪問(wèn),比如Pod間的訪問(wèn),如下是實(shí)現(xiàn)一個(gè)http service的YAML定義的樣例:
...
spec:
clusterIP: 10.110.14.69
externalTrafficPolicy: Cluster
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: httpd-app
sessionAffinity: None
...
通過(guò)kubectl create命令創(chuàng)建Service之后,我們可以通過(guò)如下命令看一下該Service的Endpoint資源信息:

從上圖不難看出,該Service對(duì)應(yīng)了后端的三個(gè)Pod,我們實(shí)際使用中通過(guò)10.110.14.69:80實(shí)現(xiàn)對(duì)后端HTTP服務(wù)的訪問(wèn)。
2.2 集群外部訪問(wèn)
- NodePort
基于ClusterIP的功能,為Service在K8s集群中的每個(gè)Node綁定一個(gè)端口(即NodePort),這樣就可以通過(guò)每個(gè)Node的IP加上這個(gè)端口去實(shí)現(xiàn)訪問(wèn),kube-proxy會(huì)自動(dòng)將流量以round-robin的方式轉(zhuǎn)發(fā)給該service的每一個(gè)pod。
配置方法基本與ClusterIP類(lèi)型的Service相同,只不過(guò)需要在spec區(qū)域加上字段type: NodePort,當(dāng)然也可以指定具體的nodePort值(默認(rèn)范圍30000-32767)或者任其隨機(jī)分配。
這種服務(wù)暴露方式,無(wú)法讓你指定自己想要的應(yīng)用常用端口,不過(guò)可以在集群上再部署一個(gè)反向代理作為流量入口。
- LoadBalancer
只能在Service內(nèi)定義(作為一種Service type),基于NodePort和公有云提供的負(fù)載均衡器,通過(guò)負(fù)載均衡器把外部請(qǐng)求轉(zhuǎn)發(fā)到NodePort進(jìn)而實(shí)現(xiàn)對(duì)Pod服務(wù)的訪問(wèn)。
kind: Service
apiVersion: v1
metadata:
name: my-nginx
spec:
type: LoadBalancer
ports:
- port: 80
selector:
run: my-nginx
name: my-nginx
創(chuàng)建好Service之后查看一下服務(wù)信息:
root@vinefu-dev:~#kubectl get svc my-nginx
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx 10.97.121.42 10.13.242.236 80:30051/TCP 39s
如此對(duì)內(nèi)可以通過(guò)10.97.121.42:80去訪問(wèn);對(duì)外一方面可以通過(guò)Node IP加上端口30051訪問(wèn),另一方面還可以通過(guò)EXTERNAL-IP 10.13.242.236:80去訪問(wèn)。
- Ingress
Ingress是授權(quán)入站連接到達(dá)集群服務(wù)的規(guī)則集合,提供了外部訪問(wèn)內(nèi)部的入口,Ingress 支持將 Service 暴露到 Kubernetes 集群外,同時(shí)可以自定義 Service 的訪問(wèn)策略。Ingress 能夠把 Service 配置成外網(wǎng)能夠訪問(wèn)的 URL,也支持提供按域名訪問(wèn)的虛擬主機(jī)功能。例如,通過(guò)負(fù)載均衡器實(shí)現(xiàn)不同的二級(jí)域名到不同 Service 的訪問(wèn)。
另外要實(shí)現(xiàn)Ingress,需提前安裝好對(duì)應(yīng)的Ingress Controller。Ingress用作將原來(lái)需要手動(dòng)配置的規(guī)則抽象成一個(gè) Ingress 對(duì)象,使用 YAML 格式的文件來(lái)創(chuàng)建和管理。Ingress Controller用作通過(guò)與 Kubernetes API 交互,動(dòng)態(tài)的去感知集群中 Ingress 規(guī)則變化,下面舉一個(gè)典型的Ingress YAML定義樣例:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: s1
servicePort: 80
path: /bar
- host: bar.foo.com
http:
paths:
- backend:
serviceName: s2
servicePort: 80
path: /foo
通過(guò)kubectl create -f命令創(chuàng)建完Ingress對(duì)象后,只要服務(wù)(s1,s2)存在,Ingress controller就會(huì)將提供一個(gè)滿(mǎn)足該Ingress的特定loadbalancer實(shí)現(xiàn)。