Kubernetes中Service機(jī)制

Service

Pod的IP是在docker0網(wǎng)段動(dòng)態(tài)分配的,當(dāng)發(fā)生重啟,擴(kuò)容等操作時(shí),IP地址會(huì)隨之變化。當(dāng)某個(gè)Pod(frontend)需要去訪問(wèn)其依賴的另外一組Pod(backend)時(shí),如果backend的IP發(fā)生變化時(shí),如何保證fronted到backend的正常通信變的非常重要。由此,引出了Service的概念。

這里docker0是一個(gè)網(wǎng)橋,docker daemon啟動(dòng)container時(shí)會(huì)根據(jù)docker0的網(wǎng)段來(lái)劃粉container的IP地址Docker網(wǎng)絡(luò)

在實(shí)際生產(chǎn)環(huán)境中,對(duì)Service的訪問(wèn)可能會(huì)有兩種來(lái)源:Kubernetes集群內(nèi)部的程序(Pod)和Kubernetes集群外部,為了滿足上述的場(chǎng)景,Kubernetes service有以下三種類型:

  • ClusterIP:提供一個(gè)集群內(nèi)部的虛擬IP以供Pod訪問(wèn)。
  • NodePort:在每個(gè)Node上打開(kāi)一個(gè)端口以供外部訪問(wèn)。
  • LoadBalancer:通過(guò)外部的負(fù)載均衡器來(lái)訪問(wèn)。

ClusterIP && NodePort && LoadBalancer

1. ClusterIP

此模式會(huì)提供一個(gè)集群內(nèi)部的虛擬IP(與Pod不在同一網(wǎng)段),以供集群內(nèi)部的pod之間通信使用。
ClusterIP也是Kubernetes service的默認(rèn)類型。

service-network.png

為了實(shí)現(xiàn)圖上的功能主要需要以下幾個(gè)組件的協(xié)同工作

  • apiserver 用戶通過(guò)kubectl命令向apiserver發(fā)送創(chuàng)建service的命令,apiserver接收到請(qǐng)求以后將數(shù)據(jù)存儲(chǔ)到etcd中。
  • kube-proxy kubernetes的每個(gè)節(jié)點(diǎn)中都有一個(gè)叫做kube-proxy的進(jìn)程,這個(gè)進(jìn)程負(fù)責(zé)感知service,pod的變化,并將變化的信息寫(xiě)入本地的iptables中。
  • iptables 使用NAT等技術(shù)將virtualIP的流量轉(zhuǎn)至endpoint中。

下面我們實(shí)際發(fā)布一個(gè)Service,能夠更清晰的了解到Service是如何工作的。

1.1 發(fā)布一個(gè)rc,并指定replices count為3.

yancey@ yancey-macbook kubernetes-1$kubectl create -f rc_nginx.yaml
yancey@ yancey-macbook kubernetes-1$kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE
k8s-master-core-v2-01    4/4       Running   0          8m
k8s-proxy-core-v2-01     1/1       Running   0          8m
nginx-controller-6bovu   1/1       Running   0          4m
nginx-controller-iowux   1/1       Running   0          4m
nginx-controller-o7m6u   1/1       Running   0          4m
yancey@ yancey-macbook kubernetes-1$kubectl describe pod nginx-controller-6bovu
Name:       nginx-controller-6bovu
Namespace:  default
Node:       core-v2-01/172.17.8.101
Start Time: Fri, 17 Jun 2016 15:22:20 +0800
Labels:     app=nginx
Status:     Running
IP:     10.1.13.3
Controllers:    ReplicationController/nginx-controller

1.2. 發(fā)布一個(gè)service,并指定步驟1中的label。

yancey@ yancey-macbook kubernetes-1$kubectl create -f service_nginx.yaml
yancey@ yancey-macbook kubernetes-1$kubectl get svc
NAME            CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
kubernetes      10.0.0.1     <none>        443/TCP    9m
nginx-service   10.0.0.252   <none>        8000/TCP   4m

kubernetes為nginx-server這個(gè)service創(chuàng)建了一個(gè)10.0.0.252這個(gè)ClusterIP,也可以稱為VirtualIP.

yancey@ yancey-macbook kubernetes-1$kubectl get ep
NAME            ENDPOINTS                                AGE
kubernetes      172.17.8.101:6443                        9m
nginx-service   10.1.13.2:80,10.1.13.3:80,10.1.13.4:80   4m

查看endpoint信息,發(fā)現(xiàn)nginx-service一共有三個(gè)endpoint地址,分別對(duì)應(yīng)nginx的三個(gè)pod。

1.3. 查看iptables,觀察其NAT表中的信息(只截取了部分和這個(gè)service有關(guān)的信息)

查看iptables中NAT表的命令:iptables -L -v -n -t nat

Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
   37  2766 KUBE-SERVICES  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */
   33  2112 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

在PREROUTING鏈中會(huì)先匹配到KUBE-SERVICES這個(gè)Chain。

Chain KUBE-SERVICES (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-SVC-GKN7Y2BSGW4NJTYL  tcp  --  *      *       0.0.0.0/0            10.0.0.252           /* default/nginx-service: cluster IP */ tcp dpt:8000
   18  1080 KUBE-NODEPORTS  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ ADDRTYPE match dst-type LOCAL

所有destinationIP為10.0.0.252的包都轉(zhuǎn)到KUBE-SVC-GKN7Y2BSGW4NJTYL這個(gè)Chain

Chain KUBE-SVC-GKN7Y2BSGW4NJTYL (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-SEP-7ROBBXFV7SD4AIRW  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */ statistic mode random probability 0.33332999982
    0     0 KUBE-SEP-XY3F6VJIZ7ELIF4Z  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */ statistic mode random probability 0.50000000000
    0     0 KUBE-SEP-JIDZHFC4A3T535AK  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */

這里能看到請(qǐng)求會(huì)平均執(zhí)行KUBE-SEP-7ROBBXFV7SD4AIRW,KUBE-SEP-XY3F6VJIZ7ELIF4Z,KUBE-SEP-XY3F6VJIZ7ELIF4Z這三個(gè)Chain.最后我們看下KUBE-SEP-7ROBBXFV7SD4AIRW這個(gè)Chain做了什么

Chain KUBE-SEP-7ROBBXFV7SD4AIRW (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.1.13.2            0.0.0.0/0            /* default/nginx-service: */
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */ tcp to:10.1.13.2:80

這個(gè)Chain使用了DNAT規(guī)則將流量轉(zhuǎn)發(fā)到10.1.13.2:80這個(gè)地址。至此從Pod發(fā)出來(lái)的流量通過(guò)本地的iptables將流量轉(zhuǎn)至了service背后的pod上。

2. NodePort

Kubernetes將會(huì)在每個(gè)Node上打開(kāi)一個(gè)端口并且每個(gè)Node的端口都是一樣的,通過(guò)<NodeIP>:NodePort的方式Kubernetes集群外部的程序可以訪問(wèn)Service。

修改kubernetes/service_nginx.yaml,將Service的type改為NodePort類型。

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  ports:
  - port: 8000
    targetPort: 80
    protocol: TCP
  # just like the selector in the replication controller,
  # but this time it identifies the set of pods to load balance
  # traffic to.
  selector:
    app: nginx

發(fā)布這個(gè)service,可以看到已經(jīng)隨機(jī)分配了一個(gè)NodePort端口。

yancey@ yancey-macbook kubernetes-1$kubectl get svc nginx-service -o yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: 2016-06-18T03:29:42Z
  name: nginx-service
  namespace: default
  resourceVersion: "1405"
  selfLink: /api/v1/namespaces/default/services/nginx-service
  uid: e50ba23a-3504-11e6-a94f-080027a75e9e
spec:
  clusterIP: 10.0.0.229
  ports:
  - nodePort: 30802
    port: 8000
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

觀察Iptables中的變化,KUBE-NODEPORTS這個(gè)Chain中增加了如下內(nèi)容

Chain KUBE-NODEPORTS (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-MARK-MASQ  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */ tcp dpt:30802
    0     0 KUBE-SVC-GKN7Y2BSGW4NJTYL  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */ tcp dpt:30802

可以看到流量會(huì)轉(zhuǎn)至KUBE-SVC-GKN7Y2BSGW4NJTYL這個(gè)Chain中處理一次,也就是ClusterIP中提到的通過(guò)負(fù)載均衡將流量平均分配到3個(gè)endpoint上。

3. LoadBalancer

待補(bǔ)充。

服務(wù)發(fā)現(xiàn)

當(dāng)發(fā)布一個(gè)服務(wù)之后,我們要使用這個(gè)服務(wù),第一個(gè)問(wèn)題就是要拿到這些服務(wù)的IP和PORT,kubernetes提供兩種方式以便在程序中去動(dòng)態(tài)的獲取這些信息。

  1. ENV環(huán)境變量
    在Pod其中之后,kubernetes會(huì)將現(xiàn)有服務(wù)的IP,PORT以環(huán)境變量的方式寫(xiě)入pod中,程序只要讀取這些環(huán)境變量即可。
  2. DNS,程序中可以使用server的名稱對(duì)服務(wù)進(jìn)行訪問(wèn),在程序啟時(shí)候,不必預(yù)先讀取環(huán)境變量中的內(nèi)容。

這是兩種方式的詳細(xì)說(shuō)明:http://kubernetes.io/docs/user-guide/services/#discovering-services

附錄

  1. iptables文檔
  2. Debuging Service
最后編輯于
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ?Kubernetes介紹1.背景介紹云計(jì)算飛速發(fā)展- IaaS- PaaS- SaaSDocker技術(shù)突飛猛進(jìn)-...
    Zero___閱讀 14,860評(píng)論 0 21
  • kubernetes 簡(jiǎn)介 一個(gè)迅速過(guò)一遍kubernetes 非常不錯(cuò)的資源:基于Kubernetes構(gòu)建Doc...
    bradyjoestar閱讀 15,354評(píng)論 2 7
  • 1.1 Kubernetes是什么 首先,它是一個(gè)全新的基于容器技術(shù)的分布式架構(gòu)領(lǐng)先方案; 其次,Kubernet...
    c84f3109853b閱讀 80,777評(píng)論 1 117
  • 如何不去思念一個(gè)人 大概沒(méi)人知道 談戀愛(ài)的人哪怕對(duì)方在眼前也依然想念
    熬出歡喜閱讀 201評(píng)論 0 1
  • 我聽(tīng)了那么多網(wǎng)上課程,結(jié)果一個(gè)多月的寒假最大的成就是沒(méi)有跟我媽吵架(大概是我媽也懶得嫌棄我了),而最糟心是總有人問(wèn)...
    安月白閱讀 398評(píng)論 4 7

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