Kubernetes——滚动更新和数据管理
滚动更新就是一次只更新一小部分副本,更新成功之后再更新更多的副本,最终完成所有副本的更新。
滚动更新最大的好处是零停机,整个更新的过程中始终有副本运行,从而保证了业务的连续性。
kubectl create deploy httpd3 --image=httpd --dry-run -o yaml > httpd3.yaml
或者手动编写yaml文件:
kind: Deployment
metadata:
labels:
app: httpd3
name: httpd3
spec:
replicas: 3
selector:
matchLabels:
app: httpd3
template:
metadata:
labels:
app: httpd3
spec:
containers:
- image: httpd:2.2.31
name: httpd
kubectl apply -f httpd3.yaml
kubectl get deploy -o wide #可以查看image的版本信息
kubectl get rs -o wide #可以查看iamge的版本信息
kubectl get po -o wide #使用这种方式来查看image的版本信息是不可以的,查看不到
kind: Deployment
metadata:
labels:
app: httpd3
name: httpd3
spec:
replicas: 3
selector:
matchLabels:
app: httpd3
template:
metadata:
labels:
app: httpd3
spec:
containers:
- image: httpd:2.2.32
name: httpd
kubectl get deploy -o wide #发现版本变更了,但是deploy实际上没有发生变化
kubectl get rs #发现rs变了,生成了新的rs
kubectl get rs -o wide #查看新的httpd版本
kubectl delete -f httpd3.yaml
然后准备三个(或多个)yaml文件,分别对应三个(或多个)版本镜像的httpd
只需要修改镜像的版本即可,其他无需更改。
执行:
kubectl apply -f httpd31.yaml --record
kubectl get po #查看相应的信息
依次执行:
kubectl apply -f httpd32.yaml --record
kubectl apply -f httpd33.yaml --record
实现滚动更新:
kubectl rollout history deploy httpd3 #查看记录的历史,可以看到REVISON的编号
kubectl get rs -o wide #可以看到历史的各rs和对应的iamges
回滚:
kubectl rollout undo deploy httpd --to-revision=1
kubectl get rs -o wide #发现对应的rs已经起来了
再次查看历史:
kubectl rollout history deploy httpd3 #发现revision的编号已经从1、2、3滚到了2、3、4,会依次往下叠加
kubectl get po
kubectl apply -f httpd31.yaml
kubectl apply -f httpd32.yaml
然后立马查看pod的情况
kubectl get po -w
kubectl describe deploy httpd3 #查看Events返回信息可以看出是一次只更新一个副本,成功之后再更新下一个。
始终维持3个预期值,过程是一个一个更新替换。
数据卷:emptyDir hostPath nfs pv/pvc
实际上pod的生命周期可能很短,会被频繁地销毁和创建,容器销毁时,保存在容器内部文件系统中的数据都会被删除。
为了数据的持久化,可以使用kubernetes volume
volume的生命周期独立于容器,pod中的容器可能被销毁,但是volume会被保存下来。
本质而言k8s volume是一个目录,这一点也docker volume类似。当volume mount 到pod,pod中的所有容器都可以访问这个volume
kubernetes volume支持多种backend类型,包括哟emptydir 、hostpath 、GCE persistent Disk、nfs 、ceph等
volume提供了对各种backend的抽象,容器在使用volume读写数据时,无需关心数据是存到本地文件系统中还是云硬盘上,对它来说,所有类型的
volume就是一个目录。
emptydir volume对于容器来说是持久的,但是对于pod则不是,当pod从节点中删除时,volume的内容也会被删除,但如果只是容器被销毁,pod还在
那么volume不受影响。也就是说emptydir volume与pod的生命周期一致。
pod中的所有容器都可以共享volume,它们可以指定各自的mount路径。
kubectl get po -n kube-system
vim nginx.yaml
apiVersion:apps/v1
kind: Deployment
metadata:
name: nginx2
spec:
replicas: 2
template:
metadata:
lables:
run: nginx
spec:
containers:
- name: nginx
image: nginx
iamgePullPolicy: IfNotPresent
volumeMounts:
- name: nginx
mountPath: /usr/share/nginx/html #容器的目录
volumes:
- name: nginx
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: nginx-sve
spec:
selector:
run: nginx
type:NodePort
ports:
- port:80
targetPort:80
nodePort:30008
kubectl apply -f nginx.yaml
kubectl get po -o wide
kubectl get svc
kubectl get po -o wide 找到pod所在的node上线测试网站
#去对应pod执行:
docker ps
docker inspect container-id #找到binds,查询绑定的随机目录,然后进入该目录写入echo “hello world” > index.html
然后外网访问,就能够访问到相应的内容了。然后可以上线测试网站,按正常上线网站的操作流程操作即可。
使用hostpath可以指定宿主机的目录
hostpath volume的作用是将docker host文件系统中已经存在的目录mount给pod中的容器。大部分应用不会使用hostpath,因为这实际上增加了pod
与node的耦合,限制了pod的使用灵活性。不过哪些需要访问k8s和docker内部数据的应用需要使用hostpath。
从节点需要准备相应的目录。
只需要在empthdir的基础上略作修改即可:
vim nginx-hp.yaml
apiVersion:apps/v1
kind: Deployment
metadata:
name: nginx2
spec:
replicas: 2
template:
metadata:
lables:
run: nginx
spec:
containers:
- name: nginx
image: nginx
iamgePullPolicy: IfNotPresent
volumeMounts:
- name: nginx
mountPath: /usr/share/nginx/html #容器的目录
volumes:
- name: nginx
hostPath:
path: /ken
---
apiVersion: v1
kind: Service
metadata:
name: nginx-sve
spec:
selector:
run: nginx
type:NodePort
ports:
- port:80
targetPort:80
nodePort:30008
#这需要你的每一个节点都要有/ken 目录,这个/ken目录实际在pod运行的node上。
然后再/ken这个目录下上线你的网站即可。
只需要略作修改:
apiVersion:apps/v1
kind: Deployment
metadata:
name: nginx2
spec:
replicas: 2
template:
metadata:
lables:
run: nginx
spec:
containers:
- name: nginx
image: nginx
iamgePullPolicy: IfNotPresent
volumeMounts:
- name: nginx
mountPath: /usr/share/nginx/html #容器的目录
volumes:
- name: nginx
nfs:
path: /ken #只需要nfs节点有这个ken目录就可以
server: 192.168.27.20 #写上你自己的nfs共享目录
---
apiVersion: v1
kind: Service
metadata:
name: nginx-sve
spec:
selector:
run: nginx
type:NodePort
ports:
- port:80
targetPort:80
nodePort:30008
#值得注意得是nfs的配置文件/etc/exports 中的几个内容:
#all_squash 把每个节点访问nfs的用户全部映射为nfsnobody
#root_squash 把访问nfs的root用户映射为nfsnobody
#no_root_squash 把访问nfs的非root用户映射为nfsnobody
persistentvolume是外部存储系统中的一块存储空间,由管理员创建和维护,pv具有持久性,生命周期独立于pod。
persistentvolumeclaim实际上就是对pv的申请(claim)pvc通常由普通用户来创建和维护。当需要为pod分配存储资源的时候,用户可以创建一个pvc
指明存储资源的容量大小和访问模式(如只读)等信息,k8s会查找并提供满足条件的pv。
有了pvc,用户只需要告诉k8s需要什么样的存储资源,而不必关心正真的空间从哪儿分配,如何访问等底层细节,这些storage provider的底层信息
交给管理员来处理,只有管理员才应该关心创建pv的细节信息。
本文使用nfs来创建pv
首先搭建nfs共享文件系统。
然后创建pv
ReadWriteOnce——相应的volume可以以可读可写的形式被挂载到一个node
ReadOnlyMany——相应的volume可以以只读的形式被挂载到多个node
ReadWriteMany——相应的volume可以以读写被挂载到多个node
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
path: /ken3
server: 192.168.27.30
kubectl apply -f pv.yaml
kubectl get pv #只有状态为available时才能申请pvc
vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
spec:
volumeName: pv1
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
kubectl apply -f pvc.yaml
kubectl get pvc #状态为bond
vim nginx.yaml
kind: Deployment
metadata:
name: nginx2
spec:
replicas: 2
template:
metadata:
lables:
run: nginx
spec:
containers:
- name: nginx
image: nginx
iamgePullPolicy: IfNotPresent
volumeMounts:
- name: nginx
mountPath: /usr/share/nginx/html #容器的目录
volumes:
- name: nginx
persistentVolumeClaim:
claimName: pvc1
---
apiVersion: v1
kind: Service
metadata:
name: nginx-sve
spec:
selector:
run: nginx
type:NodePort
ports:
- port:80
targetPort:80
nodePort:30008
kubectl apply -f nginx.yaml
kubectl exec -it nginx2-sdhoga21gw-ehr12 bash
然后写入一些内容,如果权限被拒绝了,那么就修改nfs的共享目录/ken3的属主属组为nfsnobody即可。
pv的状态为available的时候才可用。
kubectl delete -f nginx.yaml
kubectl delete -f pvc.yaml
kubectl get pv #此时的状态为released,这个状态实际上不能申请pvc
kubectl delete -f pv.yaml
kubectl apply -f pv.yaml
kubectl get pv #此时的状态为available,可以申请pvc
然后再进入nfs共享目录/ken3,发现以前写入pod的数据被保存了下来,实现了数据的持久化。
Kubernetes——滚动更新和数据管理的更多相关文章
- kubernetes滚动更新
系列目录 简介 当kubernetes集群中的某个服务需要升级时,传统的做法是,先将要更新的服务下线,业务停止后再更新版本和配置,然后重新启动并提供服务.如果业务集群规模较大时,这个工作就变成了一个挑 ...
- 详谈kubernetes滚动更新-1
系列目录 这个系列分为两个小节,第一个小节介绍deployment滚动更新时,deployment.replicaset.pod的细节以及创建过程以及deployment版本管理的方式 第二个小节将介 ...
- Kubernetes滚动更新介绍及使用-minReadySeconds
滚动升级Deployment 现在我们将刚刚保存的yaml文件中的nginx镜像修改为 nginx:1.13.3,然后在spec下面添加滚动升级策略: 1 2 3 4 5 6 7 minReady ...
- kubernetes 滚动更新发布及回滚
基本命令 记录历史 --record kubectl apply -f **** --record 查看当前状态 kubectl rollout status deployment/demo -w ...
- Kubernetes集群中Service的滚动更新
Kubernetes集群中Service的滚动更新 二月 9, 2017 0 条评论 在移动互联网时代,消费者的消费行为已经“全天候化”,为此,商家的业务系统也要保持7×24小时不间断地提供服务以满足 ...
- Kubernetes Deloyment实现滚动更新
目录 滚动更新简介 使用kubectl rolling-update更新RC Deployment的rolling-update 滚动更新简介 当kubernetes集群中的某个服务需要升级时,传统的 ...
- Kubernetes Pod应用的滚动更新(八)
一.环境准备 我们紧接上一节的环境,进行下面的操作,如果不清楚的,可以先查看上一篇博文. 滚动更新是一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新.滚动更新的最大的好处是零停 ...
- kubernetes之DaemonSet以及滚动更新
1.什么是DaemonSet? 1.1DaemonSet是Pod控制器的又一种实现方式,用于在集群中的全部节点上同时运行一份指定的Pod资源副本,后续加入集群的节点也会自动创建一个相关的Pod对象,当 ...
- Kubernetes 零宕机滚动更新
转载自:https://www.qikqiak.com/post/zero-downtime-rolling-update-k8s/ 软件世界的发展比以往任何时候都快,为了保持竞争力需要尽快推出新的软 ...
随机推荐
- Ubuntu系统中创建虚拟环境
1.虚拟环境产生的原因:如果在一台电脑上, 想开发多个不同的项目, 需要用到同一个包的不同版本, 如果使用上面的命令, 在同一个目录下安装或者更新, 新版本会覆盖以前的版本, 其它的项目就无法运行了. ...
- 2019牛客暑期多校训练营(第十场) Han Xin and His Troop (高精度+拓展中国剩余定理)
题意 裸题 思路 题中的模数之间并不互质,所以应该用拓展中国剩余定理. 但是交上去会炸,__int128过不了,所以用高精度的板子或者java大数都挺好过的. 这里推荐java大数,因为高精度板子用起 ...
- Linux新手常用命令
Linux下有时候需要转换到管理员权限 su root 然后输入密码 或者直接 su ---------------------------------------- 但可能存在鉴定错误的异常 ...
- Java 去除字符串前后指定的字符
一.去除字符串中的中文字符. /** * 去除字符串中的中文字符 * * 示例:brandName值为: 中国ABCD88深圳 * * 返回: ABCD88 * * @param brandName ...
- Java面向对象编程 -1.6
引用传递与垃圾产生分析 经过了一系列的分析之后已经确认,所有的引用传递的本质就是一场堆内存的调戏游戏.如果对于引用传递如果处理不当那么也会造成垃圾的产生, 那么本次将针对于垃圾产生的原因进行简单分析. ...
- java面试(二)
1.java常见的容器 几乎所有的容器都继承了Collecton接口,包括List.Set.Queue.Map List包括Vector.ArrayList.LinkedList, Set包 ...
- Esp32的一些资料链接
http://wiki.ai-thinker.com/doku.php/utils/esp32_idf_menuconfig http://wiki.ai-thinker.com/doku.php ...
- 「CF1313C Skyscrapers」
题目大意 给出一个长度为 \(N\) 的序列 \(a\) 需要构造出一个长度为 \(N\) 的序列 \(h\) 使得 \(\forall i \in \{1,2,\ldots ,N\} h_i \le ...
- idea提交项目到码云
1.安装Git 2.在码云上创建项目 3.在IDEA提交项目到码云
- sqlmap命令手册
http://127.0.0.1/sqli-labs-master/Less-1/?id=1 当给sqlmap上面这么一个url的时候,它会自动: 1.判断可注入的参数 2.判断可以用那种SQL注入技 ...