Deployment介紹
Deployment是kubernetes 1.2引入的概念,用來解決Pod的編排問題。Deployment可以理解爲RC的升級版(RC+Reolicat Set)。特點在於可以隨時知道Pod的部署進度,即對Pod的創建、調度、綁定節點、啓動容器完整過程的進度展示。
使用場景
創建一個Deployment對象來生成對應的Replica Set並完成Pod副本的創建過程。
檢查Deployment的狀態來確認部署動作是否完成(Pod副本的數量是否達到預期值)。
更新Deployment以創建新的Pod(例如鏡像升級的場景)。
如果當前Deployment不穩定,回退到上一個Deployment版本。
掛起或恢復一個Deployment。
Service介紹
Service定義了一個服務的訪問入口地址,前端應用通過這個入口地址訪問其背後的一組由Pod副本組成的集羣實例,Service與其後端的Pod副本集羣之間是通過Label Selector來實現“無縫對接”。RC保證Service的Pod副本實例數目保持預期水平。
外部系統訪問Service的問題
IP類型 | 說明 |
---|---|
Node IP | Node節點的IP地址 |
Pod IP | Pod的IP地址 |
Cluster IP | Service的IP地址 |
環境介紹
主機 | IP地址 | 服務 |
---|---|---|
master | 192.168.1.21 | k8s |
node01 | 192.168.1.22 | k8s |
node02 | 192.168.1.23 | k8s |
基於https://blog.51cto.com/14320361/2464655 的實驗繼續進行
一,Delpoyment和service的簡單使用
1.練習寫一個yaml文件,要求使用自己的私有鏡像,要求副本數量爲三個。
[root@master ~]# vim xgp.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: xgp-web
spec:
replicas: 3
template:
metadata:
labels:
app: xgp-server
spec:
containers:
- name: web
image: 192.168.1.21:5000/web:v1
(1)執行一下
[root@master ~]# kubectl apply -f xgp.yaml --record
(2)查看一下
[root@master ~]# kubectl get pod
(3)訪問一下
[root@master ~]# curl 10.244.2.16
(4)更新一下yaml文件,副本加一
[root@master ~]# vim xgp.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: xgp-web
spec:
replicas: 4
template:
metadata:
labels:
app: xgp-server
spec:
containers:
- name: web
image: 192.168.1.21:5000/web:v1
<1>執行一下
[root@master ~]# kubectl apply -f xgp.yaml --recore
<2>查看一下
[root@master ~]# kubectl get pod
副本數量加一,如果yaml文件的副本爲0,則副本數量還是之前的狀態,並不會更新。
2.練習寫一個service文件
[root@master ~]# vim xgp-svc.yaml
kind: Service
apiVersion: v1
metadata:
name: xgp-svc
spec:
selector:
app: xgp-server
ports:
- protocol: TCP
port: 80
targetPort: 80
(1)執行一下
[root@master ~]# kubectl apply -f xgp-svc.yaml
(2)查看一下
[root@master ~]# kubectl get svc
(3)訪問一下
[root@master ~]# curl 10.107.119.49
3.修改yaml文件
[root@master ~]# vim xgp.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: xgp-web
spec:
replicas: 3
template:
metadata:
labels:
app: xgp-server
spec:
containers:
- name: web
image: 192.168.1.21:5000/web:v1
ports:
- containerPort: 80 #提示端口
注意:在Delpoyment資源對象中,可以添加Port字段,但此字段僅供用戶查看,並不實際生效
執行一下
[root@master ~]# kubectl apply -f xgp.yaml
4.service文件映射端口
[root@master ~]# vim xgp-svc.yaml
kind: Service
apiVersion: v1
metadata:
name: xgp-svc
spec:
type: NodePort
selector:
app: xgp-server
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30123
執行一下
[root@master ~]# kubectl apply -f xgp-svc.yaml
查看一下
[root@master ~]# kubectl get svc
訪問一下
[root@master ~]# curl 127.0.0.1:30123
5.修改三個pod頁面內容
(1)查看一下pod信息
[root@master ~]# kubectl get pod -o wide
(2)修改POD頁面內容(三臺不一樣)
[root@master ~]# kubectl exec -it xgp-web-8d5f9656f-8z7d9 /bin/bash
//根據pod名稱進入pod之中
進入容器後修改頁面內容
root@xgp-web-8d5f9656f-8z7d9:/usr/local/apache2# echo xgp-v1 > htdocs/index.html
root@xgp-web-8d5f9656f-8z7d9:/usr/local/apache2# exit
訪問一下
[root@master ~]# curl 127.0.0.1:30123
二.分析一下k8s負載均衡原理
(1)查看service的暴露IP
[root@master ~]# kubectl get svc
(2)查看一下iptabes規則
[root@master ~]# iptables-save
//查看已配置的規則
SNAT:Source NAT(源地址轉換)
DNAT:Destination NAT(目標地址轉換)
MASQ:動態的源地址轉換
(3)根據service的暴露IP,查看對應的iptabes規則
[root@master ~]# iptables-save | grep 10.107.119.49
[root@master ~]# iptables-save | grep KUBE-SVC-ESI7C72YHAUGMG5S
(4)對應一下IP是否一致
[root@master ~]# iptables-save | grep KUBE-SEP-ZHDQ73ZKUBMELLJB
[root@master ~]# kubectl get pod -o wide
Service實現的負載均衡:默認使用的是iptables規則。IPVS
三.回滾到指定版本
(1)刪除之前創建的delpoy和service
[root@master ~]# kubectl delete -f xgp.yaml
[root@master ~]# kubectl delete -f xgp-svc.yaml
(2)準備三個版本所使用的私有鏡像,來模擬每次升級不同的鏡像
[root@master ~]# vim xgp1.yaml (三個文件名不相同)
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: xgp-web
spec:
revisionHistoryLimit: 10
replicas: 3
template:
metadata:
labels:
app: xgp-server
spec:
containers:
- name: web
image: 192.168.1.21:5000/web:v1 (三臺版本不同)
ports:
- containerPort: 80
此處3個yaml文件 指定不同版本的鏡像
(3)運行三個服務,並記錄三個版本信息
[root@master ~]# kubectl apply -f xgp-1.yaml --record
[root@master ~]# kubectl apply -f xgp-2.yaml --record
[root@master ~]# kubectl apply -f xgp-3.yaml --record
(4)查看有哪些版本信息
[root@master ~]# kubectl rollout history deployment xgp-web
(5)運行之前的service文件
[root@master ~]# kubectl apply -f xgp-svc.yaml
(6)查看service暴露端口
[root@master ~]# kubectl get svc
(7)測試訪問
[root@master ~]# curl 127.0.0.1:30123
(8)回滾到指定版本
[root@master ~]# kubectl rollout undo deployment xgp-web --to-revision=1
//這裏指定的是版本信息的編號
<1>訪問一下
[root@master ~]# curl 127.0.0.1:30123
<2>查看有哪些版本信息
[root@master ~]# kubectl rollout history deployment xgp-web
編號1已經被編號2替代,從而生的是一個新的編號4
四.用label控制pod的位置
默認情況下,scheduler會將pod調度到所有可用的Node,不過有些情況我們希望將 Pod 部署到指定的 Node,比如將有大量磁盤 I/O 的 Pod 部署到配置了 SSD 的 Node;或者 Pod 需要 GPU,需要運行在配置了 GPU 的節點上。
kubernetes通過label來實現這個功能
label 是 key-value 對,各種資源都可以設置 label,靈活添加各種自定義屬性。比如執行如下命令標註 k8s-node1 是配置了 SSD 的節點
首先我們給node1節點打上一個ssd的標籤
[root@master ~]# kubectl label nodes node02 disk=ssd
(1)查看標籤
[root@master ~]# kubectl get nodes --show-labels | grep node02
(2)刪除副本一
[root@master ~]# kubectl delete -f xgp-1.yaml
deployment.extensions "xgp-web" deleted
[root@master ~]# kubectl delete svc xgp-svc
(3)修改副本一的yaml文件
[root@master ~]# vim xgp-1.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: xgp-web
spec:
revisionHistoryLimit: 10
replicas: 3
template:
metadata:
labels:
app: xgp-server
spec:
containers:
- name: web
image: 192.168.1.21:5000/web:v1
ports:
- containerPort: 80
nodeSelector: #添加節點選擇器
disk: ssd #和標籤內容一致
(4)執行一下
[root@master ~]# kubectl apply -f xgp-1.yaml
查看一下
[root@master ~]# kubectl get pod -o wide
現在pod都在node02上運行
(5)刪除標籤
[root@master ~]# kubectl label nodes node02 disk-
查看一下
[root@master ~]# kubectl get nodes --show-labels | grep node02
沒有disk標籤了
五,小實驗
1)使用私有鏡像v1版本部署一個Deployment資源對象,要求副本Pod數量爲3個,並創建一個Service資源對象相互關聯,指定要求3個副本Pod全部運行在node01節點上,記錄一個版本。
(1)用label控制pod的位置
[root@master ~]# kubectl label nodes node01 disk=ssd
(2)編寫源yaml文件
[root@master ~]# vim xgp.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: xgp-web
spec:
replicas: 3
template:
metadata:
labels:
app: xgp-server
spec:
containers:
- name: web
image: 192.168.1.21:5000/web:v1
ports:
- containerPort: 80
nodeSelector:
disk: ssd
(3)編寫源service文件
[root@master ~]# vim xgp-svc.yaml
kind: Service
apiVersion: v1
metadata:
name: xgp-svc
spec:
type: NodePort
selector:
app: xgp-server
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30123
(4)執行yaml文件,創建控制器。執行service文件創建映射端口
[root@master ~]# kubectl apply -f xgp.yaml --recore
[root@master ~]# kubectl apply -f xgp-svc.yaml
(5)查看一下pod節點
[root@master ~]# kubectl get pod -o wide
(6)記錄一個版本
[root@master ~]# kubectl rollout history deployment xgp-web > pod.txt
(7)訪問一下
2)根據上述Deployment,升級爲v2版本,記錄一個版本。
(1)修改yaml文件鏡像版本
[root@master ~]# vim xgp.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: xgp-web
spec:
replicas: 3
template:
metadata:
labels:
app: xgp-server
spec:
containers:
- name: web
image: 192.168.1.21:5000/web:v2 #修改版本爲二
ports:
- containerPort: 80
nodeSelector:
disk: ssd
(2)刷新一下yaml文件
[root@master ~]# kubectl apply -f xgp.yaml --record
(3)訪問一下
(4)記錄一個版本
[root@master ~]# kubectl rollout history deployment xgp-web > pod.txt
3)最後升級到v3版本,這時,查看Service關聯,並且分析訪問流量的負載均衡詳細情況。
1)修改yaml文件鏡像版本
[root@master ~]# vim xgp.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: xgp-web
spec:
replicas: 3
template:
metadata:
labels:
app: xgp-server
spec:
containers:
- name: web
image: 192.168.1.21:5000/web:v3 #修改版本爲二
ports:
- containerPort: 80
nodeSelector:
disk: ssd
(2)刷新一下yaml文件
[root@master ~]# kubectl apply -f xgp.yaml --record
(3)訪問一下
(5)分析訪問流量的負載均衡詳細情況
<1>查看一下service映射端口
<2>以ip爲起點,分析訪問流量的負載均衡詳細情況
Service實現的負載均衡:默認使用的是iptables規則。IPVS
[root@master ~]# iptables-save | grep 10.107.27.229
//根據service的暴露IP,查看對應的iptabes規則
[root@master ~]# iptables-save | grep KUBE-SVC-ESI7C72YHAUGMG5S
這裏顯示了各節點的負載比例
<3>對應一下IP是否一致
[root@master ~]# iptables-save | grep KUBE-SEP-VDKW5WQIWOLZMJ6G
[root@master ~]# kubectl get pod -o wide
4)回滾到指定版本v1,並作驗證。
<1>回滾到指定版本
[root@master ~]# kubectl rollout undo deployment xgp-web --to-revision=1
//這裏指定的是版本信息的編號
<2>訪問一下
[root@master ~]# curl 127.0.0.1:30123
排錯思路
[root@master ~]# less /var/log/messages | grep kubelet [root@master ~]# kubectl logs -n kube-system kube-scheduler-master [root@master ~]# kubectl describe pod xgp-web-7d478f5bb7-bd4bj