k8d创建资源(3)(负载均衡原理,回滚指定版本,label控制pod的位置)
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文件,要求使用自己的私有镜像,要求副本数量为三个。
[ ~]# 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)执行一下
[ ~]# kubectl apply -f xgp.yaml --record
(2)查看一下
[ ~]# kubectl get pod
(3)访问一下
[ ~]# curl 10.244.2.16
(4)更新一下yaml文件,副本加一
[ ~]# 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>执行一下
[ ~]# kubectl apply -f xgp.yaml --recore
<2>查看一下
[ ~]# kubectl get pod
副本数量加一,如果yaml文件的副本为0,则副本数量还是之前的状态,并不会更新。
2.练习写一个service文件
[ ~]# 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)执行一下
[ ~]# kubectl apply -f xgp-svc.yaml
(2)查看一下
[ ~]# kubectl get svc
(3)访问一下
[ ~]# curl 10.107.119.49
3.修改yaml文件
[ ~]# 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字段,但此字段仅供用户查看,并不实际生效
执行一下
[ ~]# kubectl apply -f xgp.yaml
4.service文件映射端口
[ ~]# 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
执行一下
[ ~]# kubectl apply -f xgp-svc.yaml
查看一下
[ ~]# kubectl get svc
访问一下
[ ~]# curl 127.0.0.1:30123
5.修改三个pod页面内容
(1)查看一下pod信息
[ ~]# kubectl get pod -o wide
(2)修改POD页面内容(三台不一样)
[ ~]# kubectl exec -it xgp-web-8d5f9656f-8z7d9 /bin/bash //根据pod名称进入pod之中
进入容器后修改页面内容
:/usr/local/apache2# echo xgp-v1 > htdocs/index.html :/usr/local/apache2# exit
访问一下
[ ~]# curl 127.0.0.1:30123
二.分析一下k8s负载均衡原理
(1)查看service的暴露IP
[ ~]# kubectl get svc
(2)查看一下iptabes规则
[ ~]# iptables-save //查看已配置的规则
SNAT:Source NAT(源地址转换)
DNAT:Destination NAT(目标地址转换)
MASQ:动态的源地址转换
(3)根据service的暴露IP,查看对应的iptabes规则
[ ~]# iptables-save | grep 10.107.119.49
[ ~]# iptables-save | grep KUBE-SVC-ESI7C72YHAUGMG5S
(4)对应一下IP是否一致
[ ~]# iptables-save | grep KUBE-SEP-ZHDQ73ZKUBMELLJB
[ ~]# kubectl get pod -o wide
Service实现的负载均衡:默认使用的是iptables规则。IPVS
三.回滚到指定版本
(1)删除之前创建的delpoy和service
[ ~]# kubectl delete -f xgp.yaml [ ~]# kubectl delete -f xgp-svc.yaml
(2)准备三个版本所使用的私有镜像,来模拟每次升级不同的镜像
[ ~]# 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)运行三个服务,并记录三个版本信息
[ ~]# kubectl apply -f xgp-1.yaml --record [ ~]# kubectl apply -f xgp-2.yaml --record [ ~]# kubectl apply -f xgp-3.yaml --record
(4)查看有哪些版本信息
[ ~]# kubectl rollout history deployment xgp-web
(5)运行之前的service文件
[ ~]# kubectl apply -f xgp-svc.yaml
(6)查看service暴露端口
[ ~]# kubectl get svc
(7)测试访问
[ ~]# curl 127.0.0.1:30123
(8)回滚到指定版本
[ ~]# kubectl rollout undo deployment xgp-web --to-revision=1 //这里指定的是版本信息的编号
<1>访问一下
[ ~]# curl 127.0.0.1:30123
<2>查看有哪些版本信息
[ ~]# 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的标签
[ ~]# kubectl label nodes node02 disk=ssd
(1)查看标签
[ ~]# kubectl get nodes --show-labels | grep node02
(2)删除副本一
[ ~]# kubectl delete -f xgp-1.yaml deployment.extensions "xgp-web" deleted [ ~]# kubectl delete svc xgp-svc
(3)修改副本一的yaml文件
[ ~]# 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)执行一下
[ ~]# kubectl apply -f xgp-1.yaml
查看一下
[ ~]# kubectl get pod -o wide
现在pod都在node02上运行
(5)删除标签
[ ~]# kubectl label nodes node02 disk-
查看一下
[ ~]# kubectl get nodes --show-labels | grep node02
没有disk标签了
五,小实验
1)使用私有镜像v1版本部署一个Deployment资源对象,要求副本Pod数量为3个,并创建一个Service资源对象相互关联,指定要求3个副本Pod全部运行在node01节点上,记录一个版本。
(1)用label控制pod的位置
[ ~]# kubectl label nodes node01 disk=ssd
(2)编写源yaml文件
[ ~]# 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文件
[ ~]# 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文件创建映射端口
[ ~]# kubectl apply -f xgp.yaml --recore [ ~]# kubectl apply -f xgp-svc.yaml
(5)查看一下pod节点
[ ~]# kubectl get pod -o wide
(6)记录一个版本
[ ~]# kubectl rollout history deployment xgp-web > pod.txt
(7)访问一下
2)根据上述Deployment,升级为v2版本,记录一个版本。
(1)修改yaml文件镜像版本
[ ~]# 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文件
[ ~]# kubectl apply -f xgp.yaml --record
(3)访问一下
(4)记录一个版本
[ ~]# kubectl rollout history deployment xgp-web > pod.txt
3)最后升级到v3版本,这时,查看Service关联,并且分析访问流量的负载均衡详细情况。
1)修改yaml文件镜像版本
[ ~]# 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文件
[ ~]# kubectl apply -f xgp.yaml --record
(3)访问一下
(5)分析访问流量的负载均衡详细情况
<1>查看一下service映射端口
<2>以ip为起点,分析访问流量的负载均衡详细情况
Service实现的负载均衡:默认使用的是iptables规则。IPVS
[ ~]# iptables-save | grep 10.107.27.229 //根据service的暴露IP,查看对应的iptabes规则
[ ~]# iptables-save | grep KUBE-SVC-ESI7C72YHAUGMG5S
这里显示了各节点的负载比例
<3>对应一下IP是否一致
[ ~]# iptables-save | grep KUBE-SEP-VDKW5WQIWOLZMJ6G
[ ~]# kubectl get pod -o wide
4)回滚到指定版本v1,并作验证。
<1>回滚到指定版本
[ ~]# kubectl rollout undo deployment xgp-web --to-revision=1 //这里指定的是版本信息的编号
<2>访问一下
[ ~]# curl 127.0.0.1:30123
排错思路
[ ~]# less /var/log/messages | grep kubelet [ ~]# kubectl logs -n kube-system kube-scheduler-master [ ~]# kubectl describe pod xgp-web-7d478f5bb7-bd4bj