本文只是自己的精簡後的總結,若需要詳細的資料,請繞步。
注:yaml文件嚴格要求縮進,默認不同層次等級是兩個空格的縮進。
1、使用httpd鏡像創建一個Deployment資源對象
[root@master ~]# vim lvjianzhao.yaml #編寫yaml文件
kind: Deployment #指定要創建的資源對象類型
apiVersion: extensions/v1beta1 #指定deployment所對應的API版本
metadata:
name: lvjianzhao-deploy #定義deployment的名稱
spec:
replicas: 4 #定義需要創建pod副本的數量
template:
metadata:
labels: #指定pod的標籤
user: lvjianzhao
spec:
containers:
- name: httpd #指定容器的名稱
image: httpd #指定基於哪個鏡像運行容器
[root@master ~]# kubectl apply -f lvjianzhao.yaml #執行編寫的文件
[root@master ~]# kubectl explain deployment
#注:如果不知道某個資源對象所對應的API版本,可以通過此命令查看
KIND: Deployment
VERSION: extensions/v1beta1 #這就是Deployment資源所對應的API版本
........................#省略部分內容
[root@master ~]# kubectl get deployment lvjianzhao-deploy
#確定所執行的yaml文件生成了我們所需數量的pod
查看其pod標籤,是否是我們定義的label:
[root@master ~]# kubectl describe deployment lvjianzhao-deploy #查看這個資源對象的詳細信息
Name: lvjianzhao-deploy
Namespace: default
CreationTimestamp: Thu, 07 Nov 2019 17:50:44 +0800
Labels: "user=lvjianzhao" #這裏就是該資源對象的標籤
2、創建一個svc資源對象與上述Deployment資源對象關聯。且能夠對外網提供服務。映射節點端口爲:32123.
[root@master ~]# vim httpd-service.yaml #編寫service的yaml文件
kind: Service
apiVersion: v1
metadata:
name: httpd-service
spec:
type: NodePort #這裏需要指定類型爲“NodePort”,否則默認是cluster IP
selector:
user: lvjianzhao #與deployment資源對象的這個標籤進行關聯
ports:
- protocol: TCP
port: 79 #這裏指定要映射到的Cluster IP的端口
targetPort: 80 #這裏指定的是要映射pod中的端口
nodePort: 32123 #這裏指定的是映射到宿主機的端口
[root@master ~]# kubectl apply -f httpd-service.yaml #執行該yaml文件
[root@master ~]# kubectl get svc httpd-service #查看創建的svc(service)
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd-service NodePort 10.97.13.198 <none> 79:32123/TCP 2m1s
#可以看到將指定的羣集端口映射到了本地的32123
現在就可以使用client訪問k8s羣集中任意一個節點的32123端口,即可看到pod所提供的服務,如下:
[root@master ~]# kubectl describe svc httpd-service #查看該service的詳細信息
返回的信息如下(只能顯示少量IP,剩下的只是被省略了,而不是未指定):
既然上面說到了,endpoint指定的都是後端pod的IP地址,那麼就來查看驗證一下,是否正確,如下:
[root@master ~]# kubectl get pod -o wide | awk '{print]' #輸出後端pod的IP地址
IP
10.244.1.18
10.244.2.21
10.244.1.17
10.244.2.20
#可以確認查看的IP能對應上上面service的endpoint指定的IP
查看svc映射endpoint的詳細情況,並詳細說明負載均衡的底層原理。
3、當我們做完上述操作後,client是可以訪問我們pod提供的服務的(並且是負載均衡的效果),那麼這是一個什麼樣的實現過程呢?依賴什麼實現的?
其實,背後的原理並沒有那麼高大上,kube-proxy通過iptables的轉發機制來實現負載均衡的效果的,先定義目標IP是service提供的羣集IP,然後使用“-j”選項轉發到其他iptables規則,如下:
[root@master ~]# kubectl get svc httpd-service | awk '{print $3}'
#我們需要先查看到service的羣集IP
CLUSTER-IP
10.97.13.198
[root@master ~]# iptables-save > a.txt #將iptables規則輸出到文件中,方便我們查找
[root@master ~]# vim a.txt #打開iptables規則
搜索我們的羣集IP,可以看到,當目標地址是羣集IP地址時,就會轉發到另一個規則“KUBE-SVC-X2P42VLQEZCHLPKZ”,如下:
那麼,現在繼續搜索它轉發到的規則上,如下:
上面的圖中,就是與他實現負載均衡相關的策略的,我們一共四個pod,所以上圖中的第一個規則使用了random的算法,只有0.25(1/4)的機率採用這個規則,當到達第二條規則後,則有0.33的機率,因爲去除前一個pod,還剩下三個pod,10/3=0.33,這就是這個機率的由來,依次類推,當到達最後一個規則後,那麼就不用指定機率了,肯定是它來處理這條請求。