如何訪問(wèn)K8s集群

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)。

3. 文檔參考

Ingress解析

淺析從外部訪問(wèn) Kubernetes 集群中應(yīng)用的幾種方式

從外部訪問(wèn)Kubernetes中的Pod

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容