在实际应用场景中避免不了因为业务的压力而增加容器数量以及业务应用版本迭代更新,那么本篇文章我们来学习下简单的业务弹性伸缩、滚动更新操作,滚动操作的好处在于零停机更新,也就是说每次更新一小部分副本,在整个更新的过程中始终保持有副本在线,最大程度的保障了业务的连续性。
1. 创建Replication Controller服务
Replication Controller简称RC,它能够保证Pod持续运行,并且在任何时候都有指定数量的Pod副本,在此基础上提供一些高级特性,比如滚动升级和弹性伸缩
编写配置文件:rc-ng.yaml
[root@master k8s]# vim rc-ng.yaml
apiVersion: v1
kind: ReplicationController
metadata: #设置rc的元数据
name: nginx
namespace: dev
spec: #设置rc的说明
replicas: 3 #设置rc副本数量,即创建的Pod的数量
selector: #通过selector来匹配相应的Pod的label
app: myweb
template: #设置Pod的模板
metadata: #描述Pod元数据
labels: #Pod标签
app: myweb
spec: #Pod说明书
containers: #Pod容器列表
- name: myweb
image: 192.168.56.104:5000/nginx #使用的镜像
ports:
- containerPort: 80 #Pod内部容器端口
hostPort: 80 #映射的宿主机端口
name: web
protocol: TCP
构建Pod服务
[root@master k8s]# kubectl create -f rc-ng.yaml
replicationcontroller "nginx" created
[root@master k8s]#
查看副本是否全部启动完成:
我通过获取rc、pod发现,我的副本集只启动了2个Pod,但我设置的是3个,这是为什么呢?我分析了一下,因为要创建副本集(即部署多个Pod),每个Pod里都有容器对主机相同端口的映射。所以一个副本集的多个Pod必须分布在不同的 node 节点上。我现在只有2个节点主机slave1、slave2,所以只能启动2个Pod。我们分别看一下这两台机器上容器的运行情况,果然发现一个节点只会运行副本集的一个Pod。看如下两张图:
既然如此。修改 rc-ng.yaml,使 replicas: 2,更新 rc:
更新完成后我还发现:副本收缩后,刚才构建的两个Pod名称,以及slave1、slave2启动的Pod容器id、nginx容器id全都没有变化,说明这些Pod服务并没有受到动态收缩的影响。
2. 弹性伸缩
其实上面,我们通过手动修改 rc-ng.yaml 文件定义副本的数据,然后replace更新。就完成了副本的收缩。下面我们使用命令,无需再手动修改配置文件。现在我们的副本集数量是2。
2.1 副本缩容
kubectl scale replicationcontroller nginx --replicas=1 #动态收缩副本数量,保持一个副本
查看效果,副本集数两已经收缩了。
我们仔细对比发现,相比刚才两个副本少了一个名为 `nginx-wbpz9` 的Pod副本。这个Pod刚才是被分配到了slave2节点,现在我切换到 slave2 节点,查看一下当前运行的容器。看缺少的这个Pod的情况:
查看 rc-ng.yaml 文件是否被修改了呢?显然系统并没有修改我的本地文件。
2.2 副本扩容
kubectl scale replicationcontroller nginx --replicas=2 #副本数量扩展上限,不能大于当前kubelet节点的数量
查看nginx pod已经扩容至2个
3. 滚动发布
3.1 准备两个版本镜像:
将我本地的Nginx镜像重新打个 1.5 、1.6版本的标签:
docker tag nginx:latest 192.168.56.104:5000/nginx:1.5
docker tag nginx:latest 192.168.56.104:5000/nginx:1.6
再将这两个镜像上传到 Rgistry仓库:
docker push 192.168.56.104:5000/nginx:1.5
docker push 192.168.56.104:5000/nginx:1.6
查看docker私服仓库,看镜像是否都已上传:
3.2 构建Deployment类型,并留存发布记录
创建 Deployment 类型的构建文件,deploy-ng.yaml:
apiVersion: extensions/v1beta1 #这个类型要特别注意,我用的1.5.2的k8s,只能用这个类型extensions/v1beta1.Deployment
kind: Deployment
metadata: #设置rc的元数据
name: ng-deploy
namespace: esign-dev #命名空间
spec: #设置rc的具体规格
replicas: 2 #设置Pod的副本数量
template: #设置Pod的模板
metadata:
labels:
app: ng-deploy
spec:
containers:
- name: ng-deploy
image: 192.168.56.104:5000/nginx:1.5
imagePullPolicy: Always #一直从远程仓库拉取
ports:
- containerPort: 80
hostPort: 80
name: web
protocol: TCP
创建带记录点方式的deployment,如下命令将开始记录所有对Depolyment的操作:
[root@master k8s]# kubectl create -f deploy-ng.yaml --record
deployment "ng-deploy" created
查询 deployment 类型,同样需要指定namespace:
[root@master k8s]# kubectl get deploy -n esign-dev
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
ng-deploy 2 2 2 2 21s
查看版本发布的历史记录,同样需要指定namespace:
[root@master k8s]# kubectl rollout history deployment ng-deploy -n esign-dev
deployments "ng-deploy"
REVISION CHANGE-CAUSE
1 kubectl create -f deploy-ng.yaml --record
3.3 服务升级
现在我们修改deploy-ng.yaml,将nginx镜像的1.5版本,修改成1.6的:
升级 Deployment,执行如下:
可以对比一下,升级前后。Deployment类型下Pod名称已经发生了改变。
3.4 版本回退
查看变更历史
回退到:revision=1
kubectl rollout undo deployment ng-deploy -n esign-dev --to-revision=1
执行结果:
再次查看变更历史