Kubernetes介绍

Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展。它与Swarm是类似的,并且是竞争产品。Swarm是Docker公司开发内置的,K8s是一个专门的社区,在2017年的时候,Docker公司宣布支持K8s,因为K8s的社区等都比较活跃及完善,所以这场竞争中,是K8s胜利了。

使用Kubernetes可以:

  1. 自动化容器的部署和复制
  2. 随时扩展或收缩容器规模
  3. 将容器组织成组,并且提供容器间的负载均衡
  4. 很容易地升级应用程序容器的新版本
  5. 提供容器弹性,如果容器失效就替换它,等等…

Kubernetes解决的问题:

  1. 调度 - 容器应该在哪个机器上运行
  2. 生命周期和健康状况 - 容器在无错的条件下运行
  3. 服务发现 - 容器在哪,怎样与它通信
  4. 监控 - 容器是否运行正常
  5. 认证 - 谁能访问容器
  6. 容器聚合 - 如何将多个容器合并成一个工程

Kubernetes架构及组件

Kubernetes属于主从分布式架构,主要由Master Node和Worker Node组成,以及包括客户端命令行工具kubectl和其它附加项(Add on)。

Master Node

作为控制节点,对集群进行调度管理(它类似于Swarm的Manager节点),它是K8s集群的大脑。Master Node由API Server、Scheduler、Cluster State Store和Controller-Manger Server所组成。

API Server

API Server是暴露给外接访问的,我们可以通过UI或者CLI通过API Server去跟集群进行交互。

API Server主要用来处理REST的操作,确保它们生效,并执行相关业务逻辑,以及更新etcd(或者其他存储)中的相关对象。API Server是所有REST命令的入口,它的相关结果状态将被保存在etcd(或其他存储)中。

另外,API Server也作为集群的网关。默认情况,客户端通过API Server对集群进行访问,客户端需要通过认证,并使用API Server作为访问Node和Pod(以及service)的堡垒和代理/通道。

Scheduler

Scheduler是一个调度模块,比如我们通过API Server创建一个应用,这个应用有两个容器,那么这两个容器到底要部署在哪个节点上,这就是通过Scheduler模块来进行一些算法来确认的。

scheduler组件为容器自动选择运行的主机。依据请求资源的可用性,服务请求的质量等约束条件,scheduler监控未绑定的pod,并将其绑定至特定的node节点。Kubernetes也支持用户自己提供的调度器,Scheduler负责根据调度策略自动将Pod部署到合适Node中,调度策略分为预选策略和优选策略,Pod的整个调度过程分为两步:

  1. 预选Node:遍历集群中所有的Node,按照具体的预选策略筛选出符合要求的Node列表。如没有Node符合预选策略规则,该Pod就会被挂起,直到集群中出现符合要求的Node。
  2. 优选Node:预选Node列表的基础上,按照优选策略为待选的Node进行打分和排序,从中获取最优Node。

Controller-Manager Server

控制管理服务器,主要是控制容器的负载均衡,或者对容器的横向扩展,比如增加节点等。

它用于执行大部分的集群层次的功能,它既执行生命周期功能(例如:命名空间创建和生命周期、事件垃圾收集、已终止垃圾收集、级联删除垃圾收集、node垃圾收集),也执行API业务逻辑(例如:pod的弹性扩容)。控制管理提供自愈能力、扩容、应用生命周期管理、服务发现、路由、服务绑定和提供。Kubernetes默认提供Replication Controller、Node Controller、Namespace Controller、Service Controller、Endpoints Controller、Persistent Controller、DaemonSet Controller等控制器。

etcd(Cluster state store)

集群状态存储,Kubernetes默认使用etcd作为集群整体存储,当然也可以使用其它的技术。etcd是一个简单的、分布式的、一致的key-value存储,主要被用来共享配置和服务发现。etcd提供了一个CRUD操作的REST API,以及提供了作为注册的接口,以监控指定的Node。集群的所有状态都存储在etcd实例中,并具有监控的能力,因此当etcd中的信息发生变化时,就能够快速的通知集群中相关的组件。

Worker Node

作为真正的工作节点,运行业务应用的容器;Worker Node包含kubelet、kube proxy和Fluented、Container Runtime。

Pod

在Kubernets中,Pod作为基本的执行单元,在Kubernetes中,最小的管理元素不是一个个独立的容器,而是Pod,Pod是最小的,管理,创建,计划的最小单元。Pod指的是具有相同的Name Space(这里的Name Space包含了所有的,最重要的是Network Name Space)的一些Container的组合,容器可能有多个,如果是多个,它们之间共享一个Network Name Space所以它可以拥有多个容器和存储数据卷,能够方便在每个容器中打包一个单一的应用,从而解耦了应用构建时和部署时的所关心的事项,已经能够方便在物理机/虚拟机之间进行迁移。

Kubelet

Kubelet是Kubernetes中最主要的控制器,它是Pod和Node API的主要实现者,Kubelet负责驱动容器执行层。在Kubernetes中,应用容器彼此是隔离的,并且与运行其的主机也是隔离的,这是对应用进行独立解耦管理的关键点。

API准入控制可以拒绝或者Pod,或者为Pod添加额外的调度约束,但是Kubelet才是Pod是否能够运行在特定Node上的最终裁决者,而不是scheduler或者DaemonSet。kubelet默认情况使用cAdvisor进行资源监控。负责管理Pod、容器、镜像、数据卷等,实现集群(Manager)对节点的管理,并将容器的运行状态汇报给Kubernetes API Server。

kube proxy

它是跟网络有关的,(总结就是例如一个service有多个容器,我们对这个service的所有容器提供一个公共的IP,并且实现负载均衡),基于一种公共访问策略(例如:负载均衡),服务提供了一种访问一群pod的途径。此方式通过创建一个虚拟的IP来实现,客户端能够访问此IP,并能够将服务透明的代理至Pod。每一个Node都会运行一个kube-proxy,kube proxy通过iptables规则引导访问至服务IP,并将重定向至正确的后端应用,通过这种方式kube-proxy提供了一个高可用的负载均衡解决方案。服务发现主要通过DNS实现。

在Kubernetes中,kube proxy负责为Pod创建代理服务;引到访问至服务;并实现服务到Pod的路由和转发,以及通过应用的负载均衡。

Container Runtime

每一个Node都会运行一个Container Runtime,其负责下载镜像和运行容器。这里容器我们一般选择Docker,当然也可以选择其他产品。

Fluented

主要是用于日志的采集、存储、查询等。

Add-on

Add-on是对Kubernetes核心功能的扩展,例如增加网络和网络策略等能力,在Kunbernetes中可以以附加项的方式扩展Kubernetes的功能,目前主要有网络、服务发现和可视化这三大类的附加项。

kubectl

kubectl是Kubernetes集群的命令行工具,通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。它用于通过命令行与API Server进行交互,而对Kubernetes进行操作,实现在集群中进行各种资源的增删改查等操作。命令的语法如下所示:kubectl [command] [TYPE] [NAME] [flags]

Kubernates安装

  1. Kubernates-the-hard-way:最基础的方式,一步一步的安装各种组件,然后安装完成K8s集群,困难度很高

  2. minikube:是一个工具,它能快速在我们本地创建一个只有一个节点的K8s集群

  3. kuberadm:是一个工具,它能快速在我们本地搭建一个有多个节点的K8s集群

  4. kops:快速的在云上创建K8s集群,比如AWS等,操作比较简单

  5. Tectonic:企业版的一个工具,节点数量比较少,免费,大于十个节点是收费的

  6. Play Way Kubernates:在云上快速搭建一个K8s集群,但是它有时间限制,四个小时后会自动销毁

具体的搭建方法可以Google或者Baidu

我们这里使用minikube的方式来创建。

安装完成我们就可以通过一些基础命令开查看K8s集群的状态了,例如:

  1. kubectl config view:查看当前config的基本情况,包括Api的IP地址和端口,以及认证信息,context的名字等

  2. kubectl config get-contexts:查看当前的context

  3. kubectl cluster-info:查看当前K8s集群的基本情况,节点信息,类似于swarm中的 docker node 命令

  4. 使用minikube创建的k8s集群我们可以通过 minikube ssh 命令进入到虚拟机中,在这里面我们可以做具体的操作,比如直接操作docker等

Pod详解及基本操作命令

K8s我们不直接对container进行操作,pod是我们的基本操作单元。之前我们说过,一个Pod中的容器是共享一个Namespace的,他们之间是可以直接通信的。

基础操作

创建Pod,K8s中我们创建Pod需要通过一个yml文件来创建,这个yml文件有点类似于我们之前学习docker-compose和swarm的stack的文件,以下是一个示例文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# api的版本
apiVersion: v1

# yml锁定义的内容的类型,这里是一个Pod
kind: Pod

# 一些基本的元数据
metadata:
name: nginx-pod
labels:
app: nginx

# 最重要的部分,它是直接定义容器的
spec:

# containers表示我们可以定义多个容器,这里只写了一些
containers:
- name: nginx-container
image: nginx
ports:
- name: nginx-port
containerPort: 80
  • kubectl create -f [yml文件的路径名称]: 创建Pod

  • kubectl delete -f [yml文件的路径名称]: 删除已经创建的Pod

  • kubectl get pods:查看当前集群中所有的Pod及状态信息等

  • kubectl get pods -o wide:查看当前集群中所有的Pod及状态信息,包含的信息更全面一些,包含了容器的IP信息和运行的节点等

  • kubectl delete pods [Pod名称]:删除指定的Pod

  • kubectl describe [Pod名称]:查看Pod的详细信息,包含名称,节点信息,Namespace,所有的Container的详细信息,我们的Pod中的具体容器信息也能显示出来,这里我们就能够查到容器的Iamge、IP、端口、容器ID、状态等信息

  • kubectl exec -it [Pod名称] -c [Pod中Container名称] /bin/bash:进入Pod中的具体某一个容器,如果我们这里不使用 -c 参数,默认是进入第一个容器中

  • kubectl port-forward [Pod名称] [本地端口:Pod端口]:端口映射,类似于将容器的端口映射到宿主机上,此命令如果停止我们就无法访问

  • kubectl get nodes: 查询K8s集群中所有的节点信息

ReplicationController

Replication Controller简称RC,RC是Kubernetes系统中的核心概念之一,简单来说,RC可以保证在任意时间运行Pod的副本数量,能够保证Pod总是可用的。如果实际Pod数量比指定的多那就结束掉多余的,如果实际数量比指定的少就新启动一些Pod,当Pod失败、被删除或者挂掉后,RC都会去自动创建新的Pod来保证副本数量,所以即使只有一个Pod,我们也应该使用RC来管理我们的Pod。可以说,通过ReplicationController,Kubernetes实现了集群的高可用性。

  • 核心命令:
  1. kubectl create -f [rc的yml路径名称]:根据yml文件创建ReplicationController应用

  2. kubectl get rc:查看我们K8s集群所有的rc的简单信息

  3. kubectl get rc -o wide:查看我们K8s集群所有的rc的详细一些信息

  4. kubectl scala rc [rc名称] –replicas=[要扩展后或回收后的Pod总数量]:扩展或者回收rc应用的pod

  5. kubectl delete -f [rc的yml路径名称]:根据yml文件删除ReplicationController应用

ReplicationController和Pod一样,都是Kubernetes中的对象,因此创建方式类似。通过yaml或json描述文件来定义一个ReplicationController对象。一个最简单的ReplicationController的定义如下 rc-nginx.yml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:

# 指定副本数,这里指定为3,那么K8s就会创建三个Pod
replicas: 3
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80

基于此文件,我们就可以通过命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 1.通过rc-nginx.yml来创建我们的应用
jjw@jjw-PC:~$ kubectl create -f rc-nginx.yml
replicationcontroller/nginx created

# 2.查看我们K8s集群创建的此rc的简单信息
jjw@jjw-PC:~$ kubectl get rc
NAME DESIRED CURRENT READY AGE
nginx 3 3 0 32s

# 3.查看集群中所有Pod的具体信息,这里有三个Pod,因为我们在rc-nginx.yml文件中指定了replicas为3个
jjw@jjw-PC:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-5p7s2 1/1 Running 0 61s
nginx-ckph9 1/1 Running 0 61s
nginx-rs8qk 1/1 Running 0 61s

# 4.我们尝试通过命令删除上述查询出的其中一个Pod
jjw@jjw-PC:~$ kubectl delete pods nginx-5p7s2
pod "nginx-5p7s2" deleted

# 5.删除之后我们再次查看所有Pod,发现有四个,其中一个的状态为Terminating,然后新增了一个,一共三个是Runnig的状态,说明我们通过rc创建的Pod,它能帮我们维持Pod的数目,这里与Swarm中的stack是一样的
jjw@jjw-PC:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-ckph9 1/1 Running 0 51s
nginx-rs8qk 1/1 Running 0 51s
nginx-6w6zs 1/1 Running 0 4m1s

# 6.我们通过scala将此rc的Pod数量降为2个
jjw@jjw-PC:~$ kubectl scale rc nginx --replicas=2
replicationcontroller/nginx scaled

# 7.然后查看rc的具体信息,发现该nginx rc只有两个了
jjw@jjw-PC:~$ kubectl get rc
NAME DESIRED CURRENT READY AGE
nginx 2 2 2 7m22s

# 8.我们查看每一个Pod的具体信息,它们的IP地址是不同的
jjw@jjw-PC:~$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ckph9 1/1 Running 0 7m45s 172.18.0.6 minikube <none> <none>
nginx-rs8qk 1/1 Running 0 7m45s 172.18.0.5 minikube <none> <none>

# 9.我们将其中一个pod的端口映射到当前机器上
jjw@jjw-PC:~$ kubectl port-forward nginx-ckph9 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

# 10.通过在外部访问,发现我们的8080端口能正确访问映射到pod的80端口
jjw@jjw-PC:~$ curl 127.0.0.1:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>

# 11.删除此ReplicationController
jjw@jjw-PC:~$ kubectl delete -f rc-nginx.yml
replicationcontroller "nginx" deleted

ReplicaSet

在新版本的 Kubernetes 中建议使用 ReplicaSet(简称为RS )来取代 ReplicationController。ReplicaSet 跟 ReplicationController 没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的 selector(ReplicationController 仅支持等式)

  • 核心命令(与ReplicationController的核心命令大概相同):
  1. kubectl create -f [rs的yml路径名称]:根据yml文件创建ReplicaSet应用

  2. kubectl get rs:查看我们K8s集群所有的rs的简单信息

  3. kubectl get rs -o wide:查看我们K8s集群所有的rs的详细一些信息

  4. kubectl scale rs [rs名称] –replicas=[要扩展后或回收后的Pod总数量]:扩展或者回收rs应用的pod

  5. kubectl delete -f [rs的yml路径名称]:根据yml文件删除ReplicaSet应用

下面是rs文件示例,rs-nginx.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx

# 注意 labels的定义与RC有所不同
labels:
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
name: nginx
labels:
tier: frontend
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80

具体的操作我们发现与RC是没有什么区别的,我们可以通过上面的示例,替换一下命令来测试一下,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
jjw@jjw-PC:~$ kubectl create -f rs-nginx.yml 
replicaset.apps/nginx created

jjw@jjw-PC:~$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx 3 3 0 10s

jjw@jjw-PC:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-7zzbg 1/1 Running 0 28s
nginx-nzsrh 1/1 Running 0 28s
nginx-zhzbk 1/1 Running 0 28s

jjw@jjw-PC:~$ kubectl scale rs nginx --replicas=4
replicaset.apps/nginx scaled

jjw@jjw-PC:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-7zzbg 1/1 Running 0 91s
nginx-kp4fz 1/1 Running 0 15s
nginx-nzsrh 1/1 Running 0 91s
nginx-zhzbk 1/1 Running 0 91s

jjw@jjw-PC:~$ kubectl delete -f rs-nginx.yml
replicaset.apps "nginx" deleted

jjw@jjw-PC:~$ kubectl get pods
No resources found in default namespace.

Deployment

Deployment为Pod和Replica Set提供声明式更新。(个人理解最大的作用就是更新我们的应用用的,它用来替换我们上面学习的三种创建Pod的方式,它底层使用的还是ReplicaSet,类似与对ReplicaSet又做了一层高级的封装)
你只需要在 Deployment 中描述您想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和ReplicaSet 的实际状态改变到您的目标状态。您可以定义一个全新的 Deployment 来创建 ReplicaSet 或者删除已有的 Deployment 并创建一个新的来替换。
注意:不能手动管理由 Deployment 创建的 Replica Set,否则就篡越了 Deployment controller 的职责!

  • 核心命令(与ReplicaSet的核心命令大概相同):
  1. kubectl create -f [deployment的yml路径名称]:根据yml文件创建deployment应用

  2. kubectl get deployment:查看我们K8s集群所有的deployment:的简单信息

  3. kubectl get deployment -o wide:查看我们K8s集群所有的deployment的详细一些信息

  4. kubectl set image deployment [deployment名称] [要升级的image名称]=[升级的image版本]:通过命令行直接指定升级的image来升级我们的deployment pod应用

  5. kubectl rollout history deployment [deployment名称]:查看我们的deployment的历史版本,这里默认只有当前和上一个两个版本

  6. kubectl rollout undo deployment [deployment名称]:回滚deployment应用的版本至上一个版本

  7. kubectl delete -f [deployment的yml路径名称]:根据yml文件删除Deployment应用

下面我们通过一个示例来讲解:

首先定义deployment的yml文件,文件内容如下(deployment-nginx.yml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 定义的版本,因为它底层使用的是Replica Set
apiVersion: apps/v1

# 定义类型为Deployment
kind: Deployment

metadata:
name: nginx-deployment
labels:
app: nginx

spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
# 定义我们nginx的版本,这里故意使用一个低版本,便于我们演示升级Pod
image: nginx:1.12.2
ports:
- containerPort: 80

下面演示具体的操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 通过此yml文件创建deployment
jjw@jjw-PC:~$ kubectl create -f deployment_nginx.yml
deployment.apps/nginx-deployment created

# 查看我们K8s集群创建的deployment的简单信息
jjw@jjw-PC:~$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 50s

# 通过命令查看k8s集群中的所有ReplicaSet,我们发现有一个,而且它的名字是我们deployment的名字加上一段字符
jjw@jjw-PC:~$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5cc6c7559b 3 3 3 3m44s

# 查看所有的Pod信息,我们发现pod的名称又是rs的名称加上一段字符
jjw@jjw-PC:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5cc6c7559b-c8l5c 1/1 Running 0 5m8s
nginx-deployment-5cc6c7559b-cqdzg 1/1 Running 0 5m8s
nginx-deployment-5cc6c7559b-llzgk 1/1 Running 0 5m8s

# 查看我们K8s集群创建的deployment的详细信息,这里我们的image版本是1.12.2
jjw@jjw-PC:~$ kubectl get deployment -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 3/3 3 3 11m nginx nginx:1.12.2 app=nginx

# 通过命令行指定image的版本,升级我们的deployment应用
jjw@jjw-PC:~$ kubectl set image deployment nginx-deployment nginx=nginx:1.13
deployment.apps/nginx-deployment image updated

# 再次查看我们K8s集群创建的deployment的详细信息,发现这里我们的image版本已经升级为1.13
jjw@jjw-PC:~$ kubectl get deployment -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 3/3 3 3 14m nginx nginx:1.13 app=nginx

# 然后我们查看ReplicaSet信息,发现之前的rs DESIRED 已经变成了0个,我们又新创建了一个rs
jjw@jjw-PC:~$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5cc6c7559b 0 0 0 15m
nginx-deployment-76d7bfdc99 3 3 3 2m12s

# 查看pod信息,发现在运行的有三个,但是都是全新的与之前不一样
jjw@jjw-PC:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-76d7bfdc99-9rkbg 1/1 Running 0 3m18s
nginx-deployment-76d7bfdc99-fhm5f 1/1 Running 0 3m38s
nginx-deployment-76d7bfdc99-zprtj 1/1 Running 0 3m12s

# 查看历史版本信息
jjw@jjw-PC:~$ kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>

# 使用命令回滚到上一个版本
jjw@jjw-PC:~$ kubectl rollout undo deployment nginx-deployment
deployment.apps/nginx-deployment rolled back

# 查看deployment的信息,发现image的版本恢复到了1.12.2
jjw@jjw-PC:~$ kubectl get deployment -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 3/3 3 3 22m nginx nginx:1.12.2 app=nginx

# 再次查看历史版本信息,发现序号是递增的
jjw@jjw-PC:~$ kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
2 <none>
3 <none>

上述升级方式并不是滚动升级的,即不是优雅升级,期间会有一段时间服务处于宕机状态,实现滚动升级,我们只需要重新定义depolyment.yml文件,升级后的depolyment.yml文件中添加如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 定义的版本,因为它底层使用的是Replica Set
apiVersion: apps/v1

# 定义类型为Deployment
kind: Deployment

metadata:
name: nginx-deployment
labels:
app: nginx

spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
# 定义我们nginx的版本,这里故意使用一个低版本,便于我们演示升级Pod
image: nginx:1.12.2
ports:
- containerPort: 80
#滚动升级策略
minReadySeconds: 5
strategy:
# indicate which strategy we want for rolling update
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1

具体添加内容解释如下:

minReadySeconds:
Kubernetes在等待设置的时间后才进行升级
如果没有设置该值,Kubernetes会假设该容器启动起来后就提供服务了
如果没有设置该值,在某些极端情况下可能会造成服务不正常运行
maxSurge:
升级过程中最多可以比原先设置多出的POD数量
例如:maxSurage=1,replicas=5,则表示Kubernetes会先启动1一个新的Pod后才删掉一个旧的POD,整个升级过程中最多会有5+1个POD。
maxUnavaible:
升级过程中最多有多少个POD处于无法提供服务的状态
当maxSurge不为0时,该值也不能为0
例如:maxUnavaible=1,则表示Kubernetes整个升级过程中最多会有1个POD处于无法服务的状态。

然后执行命令:

kubectl apply -f [新的depolyment的yml文件]

这样就实现了滚动升级

升级可以暂停和继续,使用如下命令:

kubectl rollout pause deployment <deployment名称>:暂停升级

kubectl rollout resume deployment <deployment名称>:继续升级

最后更新: 2020年07月10日 20:50

原始链接: https://jjw-story.github.io/2020/06/14/Kubernetes/

× 请我吃糖~
打赏二维码