注:yaml文件嚴格要求縮進,默認不一樣層次等級是兩個空格的縮進
一、使用httpd鏡像建立一個Deployment資源對象node
[root@docker-k8s01 ~]# mkdir yaml [root@docker-k8s01 ~]# cd yaml/ [root@docker-k8s01 yaml]# vim test01.yaml kind: Deployment # 指定要建立的資源對象類型 apiVersion: extensions/v1beta1 # 指定deployment所對應的API版本 metadata: name: test01-deploy # 定義deployment的名稱 spec: replicas: 4 # 定義須要建立pod副本的數量 template: metadata: labels: user: zyz # 指定pod的標籤 spec: containers: - name: httpd # 指定容器的名稱 image: httpd # 指定建立容器基於的鏡像 [root@docker-k8s01 yaml]# kubectl apply -f test01.yaml # 執行編寫的文件 deployment.extensions/test01-deploy created # 返回信息顯示已經建立 #注:若是不知道某個資源對象所對應的API版本,能夠經過此命令查看 [root@docker-k8s01 yaml]# kubectl explain deployment KIND: Deployment VERSION: extensions/v1beta1 # 這就是Deployment資源所對應的API版本 #肯定所執行的yaml文件生成了咱們所需數量的pod [root@docker-k8s01 ~]# kubectl get deployments test01-deploy NAME READY UP-TO-DATE AVAILABLE AGE test01-deploy 4/4 4 4 2m19s
查看其pod標籤,是不是咱們定義的label算法
#查看這個資源對象的詳細信息 [root@docker-k8s01 ~]# kubectl describe deployments test01-deploy Name: test01-deploy Namespace: default CreationTimestamp: Wed, 26 Aug 2020 11:26:28 +0800 Labels: user=zyz # 這裏就是該資源對象的標籤
二、建立一個svc資源對象與上述Deployment資源對象關聯。且可以對外網提供服務。映射節點端口爲:32123docker
[root@docker-k8s01 yaml]# vim httpd-service.yaml kind: Service apiVersion: v1 metadata: name: httpd-service spec: type: NodePort # 這裏須要指定類型爲「NodePort」,不然默認是cluster IP selector: user: zyz # 與deployment資源對象的這個標籤進行關聯 ports: - protocol: TCP # 指定協議 port: 79 # 這裏指定要映射到的Cluster IP的端口 targetPort: 80 # 這裏指定的是要映射pod中的端口 nodePort: 32123 # 這裏指定的是映射到宿主機的端口 #執行剛剛編輯的文件 [root@docker-k8s01 yaml]# kubectl apply -f httpd-service.yaml service/httpd-service created [root@docker-k8s01 yaml]# kubectl get svc httpd-service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-service NodePort 10.102.10.20 <none> 79:32123/TCP 48s #能夠看到將指定的羣集端口映射到了本地的32123
如今就可使用client訪問k8s羣集中任意一個節點的32123端口,便可看到pod所提供的服務vim
#查看該service的詳細信息 [root@docker-k8s01 yaml]# kubectl get svc httpd-service
返回的信息以下(只能顯示少許IP,剩下的只是被省略了,而不是未指定)
既然上面說到了,endpoint指定的都是後端pod的IP地址,那麼就來查看驗證一下,是否正確後端
#輸出後端pod的IP地址 #能夠確認查看的IP能對應上上面service的endpoint指定的IP [root@docker-k8s01 yaml]# kubectl get pod -o wide | awk '{print$6}' IP 10.244.1.3 10.244.2.3 10.244.2.2 10.244.1.2
查看svc映射endpoint的詳細狀況,並詳細說明負載均衡的底層原理api
三、當咱們作完上述操做後,client是能夠訪問咱們pod提供的服務的(而且是負載均衡的效果),那麼這是一個什麼樣的實現過程呢?依賴什麼實現的?
其實,背後的原理並無那麼高大上,kube-proxy經過iptables的轉發機制來實現負載均衡的效果的,先定義目標IP是service提供的羣集IP,而後使用「-j」選項轉發到其餘iptables規則app
[root@docker-k8s01 yaml]# kubectl get svc httpd-service | awk '{print$3}' CLUSTER-IP 10.102.10.20 # 查看到service的羣集IP [root@docker-k8s01 yaml]# iptables-save > a.txt # 將iptables規則輸出到文件中,方便咱們查找 [root@docker-k8s01 yaml]# vim a.txt # 打開導出的規則進行查看
搜索咱們的羣集IP,能夠看到,當目標地址是羣集IP地址時,就會轉發到另外一個規則「KUBE-SVC-X2P42VLQEZCHLPKZ」,以下
那麼,如今繼續搜索它轉發到的規則上
上面的圖中,就是與他實現負載均衡相關的策略的,咱們一共四個pod,因此上圖中的第一個規則使用了random的算法,只有0.25(1/4)的概率採用這個規則,當到達第二條規則後,則有0.33的概率,由於去除前一個pod,還剩下三個pod,10/3=0.33,這就是這個概率的由來,依次類推,當到達最後一個規則後,那麼就不用指定概率了,確定是它來處理這條請求。負載均衡
附:爲node節點打標籤,以便使pod運行在指定的節點dom
#給節點node01打標籤「disktype=ssd」(自定義的標籤) [root@docker-k8s01 yaml]# kubectl label nodes node01 disktype=ssd #相應的yaml文件以下: kind: Deployment apiVersion: extensions/v1beta1 metadata: name: httpd spec: revisionHistoryLimit: 10 replicas: 3 template: metadata: labels: app: httpd-server spec: containers: - name: httpd image: 192.168.171.151:5000/httpd:v1 ports: - containerPort: 80 nodeSelector: //指定標籤選擇器 disktype: ssd