Yaml 文件详解、rc、rs 及 deployment 控制器详解 | 学习笔记

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
EMR Serverless StarRocks,5000CU*H 48000GB*H
简介: 快速学习 Yaml 文件详解、rc、rs 及 deployment 控制器详解

开发者学堂课程【Kubernetes 入门实战演练2020版Yaml 文件详解、rc、rs 及 deployment 控制器详解学习笔记,与课程紧密连接,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/656/detail/10865


Yaml 文件详解、rc、rs 及 deployment 控制器详解


Nginx 业务 yaml 文件详解

# pwd

/opt/k8s-data/yaml/linux36

# mkdir nginx tomcat-app1 tomcat-app2

# cd nginx/

# pwd

/opt/k8s-data/yaml/linux36/nginx

# cat nginx.yaml

1.Deployment

kind: Deployment   #类型,是deployment控制器,kubectl explain Deployment

apiVersion: extensions/v1betal   #API版本,# kubectl explain Deployment . apiVersion

metadata: #pod的元数据信息,kubect1 explain Deployment.metadata

labels:

#自定义 pod 的标签,

# kubectl explain Deployment .metadata.labels

app: linux36-nginx-deployment-label #标签名称为 app 值为linux36-nginx-deployment-label,后面会用到此标签

name: linux36-nginx-deployment  #pod的名称

namespace: linux36  #pod的namespace,默认是defaule

spec:  #定义deployment中容器的详细信息,kubectl explain Deployment.spec

replicas : 1  #创建出的pod的副本数,即多少个pod,默认值为1

selector:   #定义标签选择器

matchLabels :  #定义匹配的标签,必须要设置

app: linux 36-nginx-selector  #匹配的目标标签,

template:  #定义模板,必须定义,模板是起到描述要创建的pod的作用

metadata:  #定义模板元数据

labels:

#定义模板label,

Deployment.spec.template.metadata.labels

app: linux36-nginx-selector  

#定义标签,等于 Deployment.spec.selector.matchLabels

spec:  #定义 pod 信息

containers :  #定义 pod 中容器列表,可以多个至少一个,pod不能动态增减容器

- name: linux36-nginx-container  #容器名称

image: harbor .magedu.net/linux36/nginx-web1:v1  #镜像地址

#command: [" /apps/tomcat/bin/run_tomcat.sh"]  #容器启动执行的命令或脚本

imagePullPolicy: IfNotPresent

imagePullPolicy:  Always  #拉取镜像策略

ports:  #定义容器端口列表

- containerPort: 80  #定义一个端口

protocol : TCP  #端口协议

name: http  #端口名称

- containerPort : 443  #定义一个端口

protocol : TCP  #端口协议

name: https   #端口名称

env :  #配置环境变量

- name : "password"  #变量名称。必须要用引号引起来

value: "123456"  #当前变量的值

- name: "age"  #另一个变量名称

value: "18"  #另一个变量的值

resources:  #对资源的请求设置和限制设置

limits:  #资源限制设置,上限

cpu: 2  #cpu的限制,单位为core数,可以写0.5或者500m等CPU压缩值

memory: 2Gi  #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数

requests:  #资源请求的设置

cpu: 1  #cpu请求数。容器启动的初始可用数量,可以写0.5或者500m等CPU压缩值

memory: 512Mi  #内存请求大小。容器启动的初始可用数量,用于调度pod时候使用

第一行 kind 类型,表明我们要创建的类型是什么样的对象资源,可以是deployment、service等等,具体创建什么类型,在该文件中去写。在端口中输入kube^C

再输入history

可以看到有很多命令类型

通过命令kubectl api-resources可以拿到当前的kubectl中部分kind类型

创建的kind类型一定在显示出的范围内,不会超出区域,比如上述的deployment

第二行apiVersion是要创建对象资源的api版本,例如创建deployment资源,需要访问哪个版本,版本一定要与当前版本一致。具体使用哪个版本,可以在端口中输入命令:kubectl explain deployment去看,如下该版本是apps/v1

具体的api版本在deployment下有一个apiVersion,输入kubectl explain deployment.apiVersion去查看。kind也可以通过kubectl explain deployment.kind查看,如图显示出类型

类型是 kind 加字符串,字符串可以用图中找,复制打开网页查看官方文档。

第三行是metadata,定义pod的元数据信息,元数据信息主要有labels,定义pod的标签,标签可以写多个,使用键值对,左侧是key,右侧是值;name定义pod的名称,namespace可以写pod创建完后属于哪个namespace

属于哪个namespace图如下,不同的业务的pod要创建在不同的namespace之内。

所以说指定就是根据namespace来指定,具体的可以查看metadata下有哪些字段需要我们写。比如deployment,deployment下有metadata。所以输入

kubectl explain deployment.metadata

可以看到有namespace,labels

namespace也可以不写,创建完后则默认为defaule。

接下来的spec是用来定义deployment中容器的详细信息,可以使用kubectl explain Deployment.spec查看有哪些字段。

有replicas,是基于当前的创建出的pod副本数,即默认创建出多少个pod;有selector,就是定义标签选择器,该标签选择器在新版本中必须要设置,即必须设置 matchLabels,matchLabels可以基于app进行定义,该app必须与template模板下的 app 一致;template 是定义模板,下面定义 metadata、labels、app等

输入 kubectl explain deployment.spec.replicas

可以看到如果不写,会默认创建一个pod。

输入 kubectl explain deployment.spec.template进行查看

然后查看 metadata下的 labels,输入kubectl explain deployment.spec.template.metadata.labels

可以看到也是键值对,还有官方介绍

template下除了metadata还有spec,该spec定义pod信息,里面有containers,定义pod中容器列表,该列表中的选项以-开头。若多个容器可以再写-开头与name平级,就意味着又是新的容器。但是需要注意pod中不能动态的增减容器。输入

kubectl explain deployment.spec.template.spec | grep cont 进行查看

那么在 pod 在 containers怎么定义呢?

首先有 name 指定容器名称。下面的内容就是在给当前的容器定义一堆配置,包括该容器创建时所使用的image镜像,指定的地址可以是harbor的官方地址。接着是command,定义容器初始化的所执行的命令脚本,通常不用写。

imagePullpolicy有两个参数可以写,输入kubectl explain deployment.spec.template.spec.containers

通常我们会选择 always 和 ifnotpresent。Always是一直拉取镜像策略,什么时候用到呢?

之前跑的是 v1版本的代码,如果想升级成 v2,因为 node 里没有该镜像,所以需要从 harbor  中拉取。如果升级的 v2存在bug需要回到 v1,那么v1还是被创建在该节点上,本地已经有该镜像,所以就不需要再从harbor中拉取镜像。如果设置成always,会重新拉取,而ifnotpresent是如果本地存在则不拉取,不存在则拉取。

为了保证我们代码更新成功率,不会因为镜像相同而代码不同而出现业务更新失败的问题。

即我们这个镜像名称有可能不是 v1,而是release版本的一个image,版本无论更新多少次都是release,但是内部代码已经更新。每次拉镜像都会从gitlab中拉代码,拉完代码后打成镜像,是通过jenkins来完成的。设置为ifnotpresent,如果本地有镜像,就不会重新拉取镜像,代码就不会更新为最新的。所以此时若你们公司的镜像名称是固定的名称,一定要设置为always。

如果每打一个镜像都是变化的,可以设置为ifnotpresent。为了避免版本升级但是代码没有升级的问题,可以直接设置为always。但是设置为alwasys会出现:本地节点已经有这个镜像,但是pod删了又重新建一次,那么还是需要到harbor里重新拉取镜像;

一个 kubernetes 中可能有多个节点,出现有一个节点出现宕机状态,而导致pod自动迁移,从一个节点迁移到另一个节点,而另一个节点中存在镜像,因为宕机之后探测到该 pod 挂掉后,该节点不能用就会自动调用到另一个节点上重新创建一个新的 pod,这个节点中已经存在镜像但是还会重新拉取一次,然后将新的pod跑起来。

接下来的 ports 是定义容器端口列表,通过 containerport 定义一个80端口,再通过containerport定义一个443端口,然后协议是TCP端口协议,还可以给ports起一个端口,这个端口就是一个键值对,给80端口加了一个属性标记,标记该端口走的是http,但实际上它是TCP,是用TCP的方式转化的。当然443端口也是走的TCP,那么这个name可以把它标记为https,说这个是https端口。

Env是一个通过文件传递一个环境变量,这个变量通常是name加上这个容器的名称,这个值的为password为123456,主要是容器传递一些变量,env下面是一个列表,还可以传递多个变量名,在下面有第一个变量名是什么,第二个变量名是什么。

resources是pot对资源的请求设置和限制设置,每个容器都会限制,一个是硬限制limit,一个是软限制requests。这个软限制通常会设置cpu和内存,这个在之前讲过,容器在创造时,默认服务器是不限制资源限制的,才可以无限制的将资源占完。但可能会导致某一部分的资源消耗比较大,导致整个服务器的资源被消耗完,之后就会影响到当前服务器的使用。

这个requests其实并不是起到一个限制的作用。当我们创建容器的时候,客户端节点会进行筛选,筛选的时候会筛选哪些主机,可用资源是否还有这么多,是不是有那么多内存,如果有的话这个主机就在我的可用范围之内,如果没有就在筛选过程中把它去掉了。这是容器创建时的筛选作用,而不是创建之后给它配置一些软限制。

在筛选的时候,如果发现没有剩余的内存,机器就会说明没有足够的内存而导致资源的调度失败 。

这个limits才是真正的硬限制,限制我们的容器能使用多大的cpu和多大的内存,主要依赖两个值,一个是cpu,一个是memory。cpu的限制,单位为core数,可以写0.5或者500m等CPU压缩值,一个cpu是一千毫核,所以当看到官网文件或是其他类型文件的时候,这个基本都是整数,有的是1.5,或是1500m,这俩个本质是一样的。

memory是内存限制,单位可以为Mib/Gib,limits里的memory是限制内存,一般使用的是Mib,例如2000mib等类型的值。将用于docker run --memory参数。

2.service

如果上面一部分容器想要通过端口对其进行访问是一定离不开service,这个是之前说过内部存在的逻辑的负载均衡,通过web的请求转化为service,service再通过筛选器选出所要的web请求之间转化过去,这个是需要service请求打开NodePort,如果不打开,这个请求就是仅限内部的调用,内部的调用就是其他地方的NodePort,比如这个app3可以调用service来去掉app4,不直接去掉app4是因为它是个容器,它的地址在每次创建完后都会被回收,但由于service是固定的,所以只要找到app3就可以找到app4,这些都是内部端口,如果是外部端口的话就需要port

kind: service #类型为service

apiversion: vl #service API版本,

service.apiversionmetadata:#定义service元数据,

service.metadata

labels :  #自定义标签,

service.metadata.1abelsapp: linux36-nginx#定义service标签的内容,这个会用户HPA,k8s动态实现pod扩容缩容。

如何进行扩容和缩容呢?这个 HPA 控制器会识别service port的数量,这个数量超过指定范围,比如cpu一直要求在60%以内,但已经超出60%,那么就会通过HPA对他进行扩容缩容。

development label:会用于service对development的labels进行筛选和调用,就是筛选development label定义号的标签进行调用,把port加入到service的后端来进行访问其他port的调用。这个的定义是,它一定要和total的service一致,比如这个service linux39,就要把service创建在其里面,不能把service创建在linux40中,会找不到,所以一定要创建在同一个内部service里面。

name: linux36-nginx-spec #定义service的名称。此名称会被DNS解析

namespace: linux36 #该service肃属于的namespaces名称,即把service创建到哪个namespace里面spec:#定义service的详细信息,service.spec

type: NodePort #service的类型,定义服务的访问方式,默认为ClusterIP,service.spec.typeports :#定义访问端口,service.spec.ports。

- name: http #定义一个端口名称

port: 80 #service 80端口,这个是指定的service端口,可以看到service端口是80就是说开发服务器内部是通过service访问app4,就是这个app3在访问service时就会访问端口然后转换到后端服务器的端口80,所以说是内部服务器的原型,并且在传输层。

protocol : TCP #协议类型

targetPort: 80#目标pod的端口 nodePort: 30001 #node节点暴露的端口,通过这个来指定

name: https #SSL端口

port: 443 #service 443端口protocol: TCP #端口协议

targetPort: 443 #目标pod端口

nodePort : 30043 #node节点暴露的SSL端口

selector : #service的标签选择器,定义要访问的目标pod

app: 1inux36-nginx#将流量路到选择的pod上,须等于Deployment.spec.selector.matchLabels

这些是对容器一些定义。然后再往下是service。如果我们的容器想要通过web的端口对它进行访问的话,那么一定离不开service。它其实是kubernetes内部存在的一个逻辑转化的负载均衡。

它可以把通过web的请求转化到service,service再通过它的的筛选器筛选出来。但是需要在副主机打开一个NodePort,如果不打开只能仅限于内部的调用。内部的调用就是别的Port可以调用这个service。比如说这个app3,可以用这个service来调用app4。因为这个app4是个Port是个容器,它的地址在每次被创建完都会被回收,但是这个service是固定的。

那这个service是怎么定义的呢?首先也要定义它的类型为service,也要定义service创建时的API版本和元数据。也可以给service起个labels。后面我们会讲到动态扩容,service Iabel主要会用于HPA,k8s动态实现pod扩容缩容。deployment label主要用于 service对deployment的label进行筛选和调用。

这个service也有name service。假如说有个linux39,这个有一堆pod,要把service创建到这个里面,而不能创建到Linux40里面,那个时候它会找不到,所以要创建到同一个name service。

在service的spec里面要定义详细信息。

这个类型叫NodePort,就是给副主机打开一个接应端口。其实除了NodePort还有别的类型。

我们可以看到api版本、它的类型、metadata和spac等。在spac里面就要定义type。

这里默认是ClusterIP。使用kubectl get service的时候,这个地方看到的就是ClusterIP。默认创建的内部的IP地址。在默认的情况下,这个地址是不能从外网访问,就不能从HAProxy进行负载均衡,也就是不会建立一个四维端口。ClusterIP可以从内网进行调用,默认情况下是不对外的。有效的是EternalName、ClusterIP、NodePort和LoadBalancer。

LoadBalancer是一个复杂均衡器。创建 服务 时,你可以选择自动创建云网络负载均衡器。 负载均衡器提供外部可访问的 IP 地址,可将流量发送到集群节点上的正确端口上 ( 假设集群在支持的环境中运行,并配置了正确的云负载均衡器驱动包)。你还可以使用 Ingress 代替 Service。请务必注意,此功能的数据路径由 Kubernetes 集群外部的负载均衡器提供。

可以通过在服务的清单文件中将 externalTrafficPolicy 设置为 Local 来激活此功能。

比如:

apiVersion: v1

kind: Servicemetadata:

name: example-servicespec:

selector:  

app: example

ports:  

-port: 8765    

targetPort: 9376

externalTrafficPolicy: Local

type: LoadBalancer

对网络其他的主机来访问的话,那么也要把他指向NodePort。通过NodePort在service副主机上建立一个端口,所以后面是通过ports来定义访问端口。这个都那口里面有这么几个实例。端口名称其实无所谓,这个ports定义的是service的端口。

为什么会有service端口呢?其实指的就是在我的集成内部,别的服务想要通过service访问port。这个port的端口可能是8080,但是service可以让它监听到80。所以app3在访问service的时候就访问的是80端口,然后就会转化到后端服务器的80端口,所以他是一个内部负载均衡器。

这个协议类型要走TCP。如果port是8080端口的话那么targetPort就要是8080。如果NOdePort再开一个端口,这个通常会比较大,比如说30001。访问的过程是这样的:用户访问防火墙,这个防火墙220.1.1.1:80把公网地址传递给HAProxy的一个VIP,我们为了保障负载均衡能够可用,我们会做两个VIP,即两个HAProxy。第一个HAProxy会监听一个内网地址,比如是172.20.100.100:80。HAProxy再把它转换到30001,这个30001再转换到service 80,再转换给port的8080,这样port容器就收到用户的请求了。https也与http一样。

这个select至关重要。前面写了许多多东西,这些东西到底转换到那个port上。是service的标签选择器,就是定义好service要把用户访问的请求转化为的目标pod。这个app叫1inux36-nginx将流量路到选择的pod上,必须等于

Deployment.spec.selector.matchLabels,就是spec下的selector和app必须和template下的labels和app相等。如果不相等就会告诉这个文件不可使用,所以这三个地方的内容必须一样。这样service会把所有请求转化为app标签的pod上,这就是通过service创建的容器。

这时候在服务器上使用kubectl get ep,看看它的后端服务器是哪些。我们在之前的配置文件里指定了它们的label标签。

进入编写文件可以看到service 的app等于nginx,等于template的nginx,等于selector下面的nginx。

如果我们把nginx写错了,先把它的服务删了,看是否能够执行比如说改成nagix-linux39,这样一改文件就不符合标准了,因为matchLabels和metadata的值不一致导致无法使用。当报错的时候需要仔细查看哪里出错,报错内容现实spec下的template的matadata下的labels无效,显示和template里的值不一样,无法匹配。

改正方法,可以选择将上面的linux删除掉,或是在下面的内容中加上,总之俩个必需保证一样才可以。

这样就可以创建了,但是访问不了。Nagix-service端口是30004,这样是不通的,在筛选的时候,这个标签没有labels,里面就几个容器,没有符合条件的pod,就筛选不成功。

这就导致这个Nginx service没有后端服务器,所以使用Get ep的时候,nginx的endpoint是没有的。就要把select标签改成某些port中的label相同的值就能找到。

加上后apply一下就可以,如果不apply的话,它是不会生效的,所以之间访问3.109.1004它是不通过的,无论是怎样,浏览器访问等都不会生效。

通过语句kubectl apply -f nginx.yml应用一下,会进行修改前后的对比,可以看到原来development的位置没有发生改变,但是service发生了改变后,就可以找见文件,就可以在浏览器里进行访问。所以在配置过程是比较简单,但是稍微不注意就会导致服务无法访问。

如果已经报错,更换是没有用的,只能根据当前报错的信息去排除错误。

有时候会说某一个端点无法使用,说已经被占用了,会从k8s删除一个服务,删除后立即创建是创建不好的,短时间内是不能够把数据传完的,就是端口还未被回收,需要等待一段时间才能够创建好。假设现在删完后直接操作,会看到端口还未被回收,要确保service回收之后,才能创建。

这个问题在正式环境或是pod比较多的情况下是延迟时间是比较多的。这个是删除看上去比较简单的,在整个k8s中是要几个服务的交接。交接是给某个pod下指令给服务器,k8s把指令从etcd上,这个指令是kubernetes master标记的etcd的值,到操作把node上的值监听,把3004取消监听。

这个取消监听不是kubernetes master完成的事情,而是HAProxy,这个时候要kubernetes master发送指令,接到之后才能把本机的端口监听去掉。

就是把之前的antitable删掉,删掉后就无法访问。

kubernetes master和n ode 节点的交互是要几个步骤的,会在后期进行讲解。上面就是删除和创建的操作。

yml文件每个对象都有三大属性:元数据metadate、规范spec和状态status。

spec和status的区别:

在yml文件中spec是一个期望值,但是当最后pod创建后的是所得status为当前的运行值。

允许值就是基于yml创建的。会有一个在创建pod时的一个记录,经过了几个步骤,第一步就是调度,使用默认的调度器以及消息(每个步骤执行的过程或结果,结果会通过日志打开出来),结果是调度成功,之后会说分配到哪一个节点;pulled是当前哪一个节点有影响,有影响的话看使用的策略是什么,会拉影响。之后会创建容器,最后启动。会看见pod的生命周期。

在知道yml文件如何写后,在这里讲述pod怎么通过yml文件创建以及控制服务器的概念。

3.Pod

概述:

Pod是k8s中最小单元;一个pod这可以运行一个容器,也可以运行多个容器;运行多个容器的话,这些容器是一起被调度的;pod的生命周期是短暂的,不会自愈,是用完就毁灭的实体;一般我们是通过Controller来创建和管理pod的。

所以在创建pod会引入以下几个控制器的概念,

Controller :控制器

Replication   Controller 和 ReplicgSet,这俩个是个组合,到目前为止已经被deployment取代了

https://kubernetes.jo/zh/docs/concepts/overview/working-with-objects/labels/ #标签选择器 这个控制器怎么控制pod的运行,就会涉及到标签选择器,就是一个label标签,控制器会基于标签选择器找到pod,再对pod进行什么操作,

https://kubernetes.io/zh/docs/concepts/workloads/controllers/replicationco  ntroller/# Replication Controller 和Replica Set

Replication Controller

注意:先推荐是用配置ReplicaSet的deployment,要保证有一个pod是可用的,ReplicationController确保在任何时候都有特定数量的pod副本处于运行状态,换句话说,Replication Controller

确保一个pod或一组同类的pod总是可用的。

Replication Controller如何工作

当pod数量过多时,Replication Controller会终止多余的pod,pod数量太少时,Replication Controller将会启动新的pod。

与手动创建的pod不同,由Replication Controller创建的pod在十八、被删除或本种植时自动替换例如,在中断性增护(如内抗开放)之后,它们pod会在节点上重新创建。

因此,即使您的应用程序只要一个pod,您也应该使用 ReplcationContrOller 创建. Replication   Controller 类似于进程管理器,但是

RepleatonController

不是监控单个节点上的单个进程,而是监控跨多个节点的多个pod。在讨论中, Replication Controller 通常缩写为“rc”,并作为kubectl命令的快捷方式,

一个简单的示例是创建一个 ReplicationController 对象来可靠地无限期地运行Pod的一个实例。更复杂的用例是运行一个多副本服务(如web服务器)的若干相同副本。

所有环境描述文件、配置(包括nginx配置)等都哟啊以代码的形式放在GitHub上,尽量不要保存在本机文件上,在guihub上可用进行后期的版本控制

环境隔离,就是不同业务的pod在不同的节点上。其他的业务通过nginx进行逻辑隔离,所以跑到哪一个物理机就是看a项目和b项目的不一样。

a、b项目的环境不一样就是逻辑隔离,把他们从物理和逻辑上都隔离开,这就可以创建服务了

Deployment

- https://kubernetes.io/ あさ/docs/concepts/workloads/ controllers / deployment /· Statefulset

Daemonset

Job,一般不回应job,用的deployment居多

在知道yml文件如何写后,在这里讲述pod怎么通过yml文件创建以及控制服务器的概念。

此时还涉及到yml文件如何保存的问题,这个服务通过yml文件创建的,肯定是可以保存的。通常情况下会在opt中创建一个目录k8s-date,其中又分为两个目录dockerfile和yml。yml其中又有两个目录,一个是namespaces。

来看几个示例文件,第一个示例是怎么通过rc来创建deploment,修改配置将replicas改为1,添加namespace:linux39,加上后会出现selector。然后进行创建输入kubectl apply -f deployment.yml,这样nginxpod就跑起来了。

输入kubectl get pod可以查看,输入kubectl get pod -n linux39可以查看到namespace里的pod信息,而linux39中正好有一个pod处于创建状态。

跑起来后输入vim rs.yml进行访问,进入到replicaset控制器,可以删掉,输入kubectl delete -f deployment.yml,再输入vim rc.yml,它和deployment.yml区别在于deployment中可以通过如下多种方式去匹配

但是replicationController不支持该写法,只支持传统格式

ReplicationController的.spec.selector字段是一个标签选择器。ReplicationController管理标签与选择器匹配的所有pod。它不区分它创建或删除的Pod和其他人或进程创建或删除的Pod。

这允许在不影响正在运行的Pod的情况下替换

ReplicationController。

还有一个区别是deployment支持很多功能:比rs更高一级的控制器,除了有rs的功能之外,还有很多高级功能,,比如说最重要的:滚动升级、回滚等。

但是replication Controller的selector标签只能为=或者!=。此外还有replicaSet副本控制集,和副本控制器的区别是:对选择器的支持(selector还支持in notin)。

而官方建议使用deployment,一个Deployment控制器为Pods和ReplicaSets握供描述性的更新方式。描述Deployment中的—_desired state,并且Deployment控制器以受控速率更改实际状态,以达到期望状态。可以定义Deployments 以创建新的ReplicaSets,或删除现有Deployments,并通过新的 Deployments使用其所有资源。

再来演示:

输入kubectl get pod -n linux39显示没有资源,创建rc,输入

kubectl apply -f rc.yml

kubectl get pod -n linux39

vim deployment.yml^C

kubectl delete -f rc.yml

vim rc.yml

修改添加上namespace:linux39

添加完后再重新创建输入

kubectl apply -f rc.yml

kubectl get pod -n linux39

这样就创建完成。

ReplicaSet是下一代的Replication Controller。ReplicaSet和Replication Controller 的唯一区别是选择器的支持。Replicaset支持新的基于集合的选择器需求,这在标签用户指南中有描述。而 Replication Controller仅支持基于相等选择器的需求。

ReplicaSet确保任何时间都有指定数量的Pod副本在运行。然而,Deployment是一个更高级的概念,它管理Replicaset,并向Pod提供声明式的更新以及许多其他有用的功能。

因此,我们建议使用Deployment而不是直接使用ReplicaSet,除非您需要自定义更新业务流程或根本不需要更新。

来梳理一下图:

Deployment可以实现对pod代码升级的特定方式,比如回滚等等,至于如何实现,在以后会讲解如何使用脚本来实现代码升级和回滚。比如deployment更新:

了解一下更新:

仅当Deployment Pod模板(即.spec.template)时,才会触发Deployment展开,例如,如果模板的标签或容器镜像已更新,其他更新(如扩展Deployment)不会触发展开。

按照以下步骤更新Deployment :

让我们更新 nginx Pods,以使用nginx:1.9.1镜像,而不是nginx:1.7.9镜像。

kubectl --record deployment.apps/nginx-deployment set imagedeployment.v1.apps/nginx-deployment nginx=nginx:1.9.1

输出:

```shell

deployment.apps/nginx-deployment image updated

```

或者,可以‘edit’ Deployment 并将

‘.spec.template .spec.containers[ ].image’从‘nginx:1.7.9’更改至‘nginx:1.9.1'。

```shell

kubectl edit deployment.v1.apps/nginx-deployment

```

等等

当然k8s中有很多容器,可以理解为这些控制器他们的操作对象是运行在k8s中的n个pod,每个控制器对pod进行维护代码升级等。

无论是使用replicationController还是replicaSet还是deployment都是对代码实现回滚升级等功能。

接着讲解控制器,刚才我们创建了一个容器,该容器是基于replicationController创建的

输入vim rc.yml

kubectl get pod -n linux39

结果有两个pod

查看pod信息kubectl describe pod ng-rc-8whpn -n linux39

可以看到它的一些信息:name、namespace等等

再来讲解rs,输入

kubectl delete -f rc.yml

vim rc.yml

kubectl apply -f rs.yml

get pod -n linux39

结果显示没有找到namespace,再来删除

Kubectl delete 0-f^C

Kubectl get pod

将这两个跑在同一个namespace内,输入

kubectl delete -f rs.yml

kubectl get pod

vim rs.yml

再来修改,加在name下输入

namespace:linux39

再来创建

kubectl apply -f rs.yml

get pod -n linux39

可以看到有两个前端服务。再来查看镜像,输入

vim rs.yml

镜像直接调用的官方镜像nginx,再来查看是否能跑起来,输入

Kubectl get pod -n linux39

结果显示running,那么删除呢?输入

Kubectl delete -f rs.yml

再来尝试create命令,输入Kubectl create -f rs.yml也可以创建,而且也可以跑起来,输入

Kubectl get pod -n linux39

如果此时想要修改yml文件的配置,想要配置重新生效,输入

Vim rs.yml

将pod数量改为3个,改完后再来创建,输入

Kubectl create -f rs.yml

结果显示报错,不能创建。

所以通过create创建的pod,后期如果想要修改并且生效的话,需要在第一次创建时添加参数,所以这种情况下只能删除第一次创建的pod,输入

Kubectl delete -f rs.yml

删完后在重新创建才能将pod改为3个

Kubectl create -f rs.yml

Kubectl get pod -n linux39

如图为三个

再来添加一个选项保存配置,输入

kubectl create -f rs.yml --save-config=true

比如将pdo再修改为5个,输入

vim rs.yml

将pod修改为5个

kubectl apply -f rs.yml

apply可以实现创建pod功能

此外还有一个选项record可以实现版本功能,输入

kubectl create -f rs.yml --save-config=true --record=true

打开之后先验证 pod 是否被创建,输入

kubectl pod -n linux39

可以看到正在被创建,再进入配置将pod改为3个

Kubectl get pod -n linux39

Kubectl apply -f rs.yml

Kubectl get pod -n linux39

可以看到变为3个。

此外 pod 在三个模式下都不能删掉,可以通过删掉控制器,例如输入

kubectl get deployment -n linux39

kubectl delete deployment nginx-deplyment-n linux39

get pod -n linux39

可以看到 pod 正在删除中

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
JSON Kubernetes API
深入理解Kubernetes配置:编写高效的YAML文件
深入理解Kubernetes配置:编写高效的YAML文件
|
1月前
|
Kubernetes 应用服务中间件 nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
|
1月前
|
Kubernetes Docker Perl
k8s常见故障--yaml文件检查没有问题 pod起不来(一直处于创建中)
k8s常见故障--yaml文件检查没有问题 pod起不来(一直处于创建中)
|
1月前
ingress相关yaml文件报错且相关资源一切正常解决方法
ingress相关yaml文件报错且相关资源一切正常解决方法
ingress相关yaml文件报错且相关资源一切正常解决方法
|
4月前
|
运维 Kubernetes Serverless
Serverless 应用引擎使用问题之s.yaml文件中如何使用外部环境变量
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
4月前
|
存储 缓存 运维
函数计算产品使用问题之如何将外部环境变量放到s.yaml文件中使用
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
3月前
|
机器学习/深度学习 计算机视觉 Python
深度学习项目中在yaml文件中定义配置,以及使用的python的PyYAML库包读取解析yaml配置文件
深度学习项目中在yaml文件中定义配置,以及使用的python的PyYAML库包读取解析yaml配置文件
103 0
|
3月前
|
JSON Kubernetes 数据格式
k8s集群yaml文件方式迁移
k8s集群yaml文件方式迁移
|
3月前
|
Kubernetes API 容器
在K8S中,deployment的yaml文件如何编写呢?
在K8S中,deployment的yaml文件如何编写呢?
|
3月前
|
Dart iOS开发 C++
Dart ffi 使用问题之在pubspec.yaml文件中,对plugin_ffi_sample插件的依赖如何配置
Dart ffi 使用问题之在pubspec.yaml文件中,对plugin_ffi_sample插件的依赖如何配置