一.复制控制器(ReplicationController,RC)
RC用来确保Pod副本数达到预期值,这样可以确保一个或多个同类Pod总是可用的。可以通过扩缩来增加或减少pod。
(1)示例:
vim replicationcontroller-nginx.yaml
apiVersion: v1
kind: ReplicationController
metadata: #元数据
name: nginx
spec:
replicas: 3 #谁贴了“app:nginx”这个标签谁的副本数为3
selector: #选择器(选择标签)
app: nginx
template: #pod模版
metadata:
name: nginx
labels: #标签
app: nginx
spec:
containers: #容器模版
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
备注:这个文件让你的pod的副本数,始终保存在你的期望值那(副本数量)
(2)创建ReplicationController
kubectl create -f 文件名.yaml
(3)查看
查看所有复制控制器
查看由复制控制器产生的pod
(4)删除一个pod并立即查看pod状态
kubectl delete pod pod名称
备注:因为你使用的是复制控制器,它会始终将pod的数量保持在你设定的 replicas 的数量上,所以使用此方法删除,你指定的pod会被删除,但是它会生成新的pod。
kubectl delete -f replicationcontroller-nginx.yaml
二.复制集控制器 (ReplicaSet,RS)
1.ReplicaSet(复制集,RS)
ReplicaSet是支持基于集合的标签选择器的下一代Replication Contronller,它主要用于Deployment协调创建,删除和更新Pod,和Replication Contronller唯一的区别是,ReplicaSet支持标签选择器。在实际应用中,虽然ReplicSet可以单独使用,但是一般建议使用Deployment来自动管理ReplicaSet,除非自定义的Pod不需要更新或有其他编排。
2.示例
vim replicaset-example.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# modify replicas according to your case
replicas: 3
selector:
matchLabels:
tier: frontend
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- name: php-redis
image: nginx:1.7.9
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM
value: dns
# If your cluster config does not include a dns service, then to
# instead access environment variables to find service host
# info, comment out the 'value: dns' line above, and uncomment the
# line below.
# value: env
ports:
- containerPort: 80
三.标签与标签选择器
(1)标签
标签是用来标识k8s对象的一组附加在其上的键值对,通过标签我们可以方便地筛选或排除一组对象。借鉴资料中的话来讲,集群中的应用部署或是批处理的程序部署通常都是多维度的,为了实现这些对象的管理,往往需要对某一特定维度的对象进行操作,而标签可以通过用户的意愿组织集群中的对象之间的结构,而不需要对集群进行修改。
(2)标签选择器
标签选择器可以用来选择一组对象(标签并不能唯一标识一个对象),APIServer支持两种标签选择器:基于等式的标签选择器与基于集合的标签选器:
基于等式的标签选择方式:在这种选择方式下可以使用=、 、!=三种操作符来进行选择,前两个的含义是一样的,都代表相等,第三种代表不等。选择条件可以通过,加,例如date=day1,namel=build代表选择date值为day1且name值不为build的对象
基于集合的标签选择方式:这种选择器可以同时选择一组对象。支持的操作符有:in、notinexists。具体的使用方法为:
选择date包含有值为day1、day2、day3的标签:date in(day1,day2,day3)
选择name值不为build、pipline的标签:name notin(build,pipline)
选择所有包含test的标签:test
选择所有不包含test的标签:!test
基于集合的标签选择器也支持使用“,”分隔以同时叠加选择,相同意义上的选择条件在这两种选择方式之间是等价的。
标签定义方式:
基于等式定义 app=nginx(等号前后不要有等号)
基于键值对定义方式 app:nginx
基于集合的标签定义方式 {key:app,operator:In,values:[nginx,apache]}
四.Deployment无状态应用管理
1.定义:无状态服务是指服务在处理请求时,不依赖于之前的请求状态。每个请求都是独立的,不需要存储或维护会话信息。无状态服务通常通过以下方式实现:
- 无状态请求:每个请求包含所有处理该请求所需的信息。
- 横向扩展:可以轻松增加或减少实例副本,不会影响服务的功能或数据一致性。
- 故障恢复:服务实例的失败不会导致数据丢失或中断,因为没有持久化的会话数据。
这种服务通常用于 Web 应用、API 服务等,其中每个请求都可以被独立处理,无需依赖先前的请求上下文。
2.特点
(1)数据方面:无状态服务不会在本地存储持久化数据,多个实例可以共享相同的持久化数据
(2)结果方面:多个服务实例对于同一个用户请求的响应结果是完全一致的
(3)关系方面:这种服务实例之间是没有依赖关系
(4)影响方面:在k8s控制器中动态启停无状态的pod并不会对其他的pod产生影响
(5)实例方面:nginx实例,tomcat实例,web应用
(6)资源方面:相关的k8s资源有:ReplicaSet、ReplicationController、Deployment
(7)创建方式:Deployment被设计用来管理无状态服务的pod
- 每个pod完全一致,原因如下:
- 无状态服务内的多个Pod创建的顺序是没有顺序的
- 无状态服务内的多个Pod的名称是随机的
- pod被重新启动调度后,它的名称与IP都会发生变化
- 无状态服务内的多个Pod背后是共享存储的
(8)扩缩容方式:随机缩容
由于是无状态服务,所以这些控制器创建的pod序号都是随机值。并且在缩容也是随机,并不会明确缩容某一个pod。因为所有实例得到的返回值都是一样,所以缩容任何一个pod都可以
Deployment用来管理RS,并为Pod和RS提供声明性更新,以及许多其他的新的功能,生产环境中使用Deployment替代RS
Deployment一般用于部署公司的无状态服务,因为企业内部现在都是以微服务为主,微服务实现无状态化也是最佳实践。可以利用Deployment的高级功能做到无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等功能
无状态服务不会在本地存储持久化数据多个服务实例对于同一个用户请求的响应结果是完全致的。这种多服务实例之间是没有依赖关系,比如web应用,在k8s控制器中动态启停无状态服务的pod并不会对其它的pod产生影响
3.示例
(1)编写Deployment文件
vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- name: nginx
containerPort: 80
备注:
- 从1.16开始,彻底废弃了其他的apiversion,只能使用app/v1
- replicas:pod的副本数
- selector:定义Deployment如何找到要管理的Pod,与template的1abel标签对应,app/v1必须指定
- template:声明pod
- app:nginx使用1abel标记pod
- spec:定义pod的详细信息
- name: nginx表示pod运行一个名字为nginx的容器
- image:运行此pod使用的镜像
- port: 容器用于发送和接收流量的端口
(2)创建Deployment
kubectl create -f nginx-deployment.yaml
(3)查看Deployment状态
kubectl get deploy
(4)使用rollout查看整个Deployment的创建过程状态
kubectl rollout status deployment/nginx-deployment
(5)查看这个Deployment对应的RS
kubectl get rs -l app=nginx(容器的标签)
(6)列出 Kubernetes 集群中的所有 Pods,并显示每个 Pod 的标签信息
kubectl get pods --show-labels
4.更新Deployment
通过Deployment部署应用后,如果需要对Deployment文件的配置文件或者镜像版本进行更新,更改后该Deployment会创建新的RepliccaSet,之后会对管理的pod进行滚动升级。
(1)更新pod的image
kubectl set image deployment nginx-deployment nginx=nginx.1.9.0 --record
ku set image deployment nginx-deployment nginx=nginx.1.12.0 --record
或直接修改Deployment文件
kubectl edit deployment.v1.apps/nginx-deployment
deployment.v1.apps/nginx-deployment: 这是要编辑的资源类型和名称。在这个例子中,deployment.v1.apps
指的是 Deployment API 版本 v1
,nginx-deployment
是 Deployment 的名称。
(2)查看更新过程
ku rollout status deployment.v1.apps/nginx-deployment
(3)此时的Rs有新的和旧的
kubectl get rs
(4)通过describ查看Deployment的详细信息
ku describe deploy deployment名称
3.回滚deployment
(1)查看更新历史
ku rollout history deployment/deployment名称
(2) 查看每次更新的详情
ku rollout history deployment/nginx-deployment --revision=2(更新编号)
(3)回滚到指定的版本
ku rollout undo deployment/nginx-deployment --to-revision=2
(4)回滚到上次版本
ku rollout history deployment/nginx-deployment
4.扩容 deployment
(1)调整pod的副本数
ku scale deployment.v1.apps/nginx-deployment --replicas=4(数量,多扩,少缩)
5.暂停和回复deployment更新
(1)暂停更新
kubectl rollout pause deployment/nginx-deployment
(2)恢复deployment更新
kubectl rollout resume deployment.v1.apps/nginx-deployment
(3)删除deployment
kubectl delete -f deployment的yaml文件
五.有状态应用管理statefulSet
1.定义:
Statefulset(有状态集,缩写为sts)常用于部署有状态的且需要有序启动的应用程序。比如在生产环境中可以部署Elasticsearch集群、MongoDB集群或者需要持久化的RabbitMQ集群、Redis集群、Kafka集群和Zookeeper集群等。
一个Statefulset管理着基于相同容器规范的Pod。与Deployment不同的是,StatefulSet为每个Pod维护了一个标识。这些Pod是根据相同规范创建的,但是不可互换,每个Pod都有一个持久的标识符,在重新调度时也会被保留。
2.有状态服务:容器数据持久化保持
有状态服务可以说是需要数据存储功能的服务、或者指多线程类型的服务,队列等。(mysq1数据库、kafka、zookeeper等)
每个实例都需要有自己独立的持久化存储,并且在k8s中是通过申明模板来进行定义。持久卷申明模板在创建pod之前创建,绑定到pod中,模板可以定义多个。
有状态服务常常用于实现事务(并不是唯一办法,下文有另外的方案)。举一个常见的例子,在商城里购买一件商品。需要经过放入购物车、确认订单、付款等多个步骤。由于HTTP协议本身是无状态的,所以为了实现有状态服务,就需要通过一些额外的方案。比如最常见的session,将用户挑选的商品(购物车),保存到: ion中 当付款的时候,再从购物车里取出商品信息
有状态的特征
有状态服务的特征
1、数据方面:有状态服务需要在本地存储持久化数据,典型的应用是分布式数据库
2、结果方面:实例之间,请求结果可能存在不一致
3、关系方面:分布式节点实例之间有依赖的拓扑关系,比如主从关系
4、影响方面:如果K8S停止分布式集群中任一实例pod,就可能会导致数据丢失或者集群的crash(前)
5、示例方面:mysql数据库、kafka、zookeeerRedis主从架构
6、资源方面:statefuSet
7、创建方式:statefuiset管理
Stateful管理有状态的应用,Pod有如下特征:
- 唯一性:每个Pod会被分配一个唯一序号.
- 顺序性:Pod启动,更新,销是按顺疗进行
- 稳定的网络标识:Pod主机名,DNS地址不会随着Pod被重新调度而发生变化
- 稳定的持久化存储:Pod被新调度后,仍然能挂载原有的PV,从而保证了数据的完整性和一致性
3.示例
vim redis-statefulset.yaml
apiVersion: v1
kind: Service
metadata:
name: redis-svc
spec:
selector:
app: redis-sts
ports:
- port: 6379
protocol: TCP
targetPort: 6379
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-sts
spec:
serviceName: redis-svc
replicas: 2
selector:
matchLabels:
app: redis-sts
template:
metadata:
labels:
app: redis-sts
spec:
containers:
- image: redis:5-alpine
name: redis
ports:
- containerPort: 6379
(1)创建时如果有多个副本它们的pod名字不是随机的而是有顺序性的
(2)删除方式有两种
1.非级联删除
ku delete statefulset 有状态管理名 --cascade=false
删除StatefulSet,保留pod
2.级联删除
ku delete statefulset redis-sts
删除statefulSet,也删除pod
六.无状态服务和有状态服务的比较
1.无状态服务
- 服务不依赖自身的状态,实例的状态数据可以维护在内存中
- 任何一个请求都可以被任意一个实例处理
- 不存储状态数据,实例可以水平拓展,通过负载均衡将请求分发到各个节点
- 在一个封闭的系统中,只存在一个数据闭环。
- 通常存在于单体架构的集群中。
2.有状态服务
- 服务本身依赖或者存在局部的状态数据,这些数据需要自身持久化或者可以通过其他节点恢复个请求只能被某个节点(或者同等状态下的节点)处理
- 存储状态数据,实例的拓展需要整个系统参与状态的迁移
- 在一个封闭的系统中,存在多个数据闭环,需要考虑这些闭环的数据一致性问题
- 通常存在于分布式架构中