Deployment管理Pods和ReplicaSets,提供声明式更新。和老的ReplicationController(命令式管理)对应,发展趋势是取代老的,因此后面也不会起文章单独讨论ReplicationController了。java
备注:但由Deployment-controller管理的Pods和ReplicaSets最好自始至终都由Deployment-controller管理,最好不要手动去管理,以避免发生冲突。node
建立Deploymentnginx
以下一个Deployment的配置(nginx-deployment.yaml),建立一个ReplicaSet包含3个nginx Podsweb
apiVersion: apps/v1spring
kind: Deploymentdocker
metadata: 数据库
name: nginx-deployment api
labels: 浏览器
app: nginxtomcat
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
apiVersion这里为apps/v1,若是是1.9以前的版本为extensions/v1beta1
replicas:3 起3个replicated Pods
selector指明哪一个pod被管理,这里咱们指定了label(app:nginx)
template: spec 指明了运行一个容器nginx(以nginx:1.7.9为镜像)
开放80端口给container,以使container之间能发送和接收流量
备注:注意这里定义name 或 label 时不要和其余的重复,k8s不会检查这个,须要人工本身确认
要建立此部署,执行下面的命令(在这以前咱们提早下好nginx相关的镜像,docker pull nginx:1.7.9)
[root@master yaml]# kubectl create -f nginx-deployment.yaml --record
deployment "nginx-deployment" created
--record会记录操做历史,以便于后面回滚操做
查看deployments
[root@master yaml]# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 0 0 0 1s
NAME:在集群中的部署名称
DESIRED:显示配置里定义的副本数量,这是应该达到的副本数量
CURRENT:当前正在运行的副本数量
UP-TO-DATE:更新到当前所需状态的副本数量
AVAILABLE:可供使用的副本数量
AEG:显示app存活的时间
经过下面语句可查追踪部署状况
[root@master ~]# kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out
# 这是部署完成的状态
# 未完成的会显示当前部署哪一步了
[root@master ~]# kubectl rollout status deployment/nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out
过一会咱们再查看,就全
[root@master ~]# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 51s
这里注意若是定义了.spec.minReadySeconds,那么必须通过定义的时间才会达到AVAILABLE 状态
经过下面的命令查看Deployment建立的ReplicaSet(rs)
[root@master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-6c54bd5869 3 3 3 56m
注意ReplicaSet的名称格式为[DEPLOYMENT-NAME]-[POD-TEMPLATE-HASH-VALUE],后面的hash值是由Deployment自动建立的
查看Pods
[root@master ~]
NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-6c54bd5869-9brqp 1/1 Running 0 58m app=nginx,pod-template-hash=2710681425
nginx-deployment-6c54bd5869-dkmgh 1/1 Running 0 58m app=nginx,pod-template-hash=2710681425
nginx-deployment-6c54bd5869-vzsht 1/1 Running 0 58m app=nginx,pod-template-hash=2710681425
建立的ReplicaSet 会确保时刻有3个nginx Pods的副本在运行
假设咱们想把nginx从1.7.9更新到1.9.1,有如下3种方式
1. 直接set命令设置变动的部分
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment "nginx-deployment" image updated
以上命令会自动回滚更改Pods,即中止必定量的老的,新建新的,直到来的终止完,新的启动完
经过describe便可查看全部的细节
[root@master yaml]# kubectl describe deployment/nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Thu, 15 Mar 2018 02:51:06 -0400
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision=2
kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.9.1
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions: Type Status Reason
---- ------ ------
Available True MinimumReplicas
Available Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-5964dfd755 (3/3 replicas created)
Events: Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 2m deployment-controller Scaled up replica set nginx-deployment-5964dfd755 to 1
Normal ScalingReplicaSet 2m deployment-controller Scaled down replica set nginx-deployment-6c54bd5869 to 2
Normal ScalingReplicaSet 2m deployment-controller Scaled up replica set nginx-deployment-5964dfd755 to 2
Normal ScalingReplicaSet 2m deployment-controller Scaled down replica set nginx-deployment-6c54bd5869 to 1
Normal ScalingReplicaSet 2m deployment-controller Scaled up replica set nginx-deployment-5964dfd755 to 3
Normal ScalingReplicaSet 2m deployment-controller Scaled down replica set nginx-deployment-6c54bd5869 to 0
可见image已经变了
另外Events可查看滚动更新的过程
另外上面的说的中止和新建的比例在这里体现RollingUpdateStrategy: 25% max unavailable, 25% max surge,25% max unavailable确保在更新时只有部分会关闭(这里是pod数的25%会关闭)。25% max surge确保建立新的pod也在必定比例上(这里默认也是25%)
2. 经过直接修改线上的配置也可直接修改
kubectl edit deployment/nginx-deployment
会打开一个编辑器,修改指定的部分便可,这里是.spec.template.spec.containers[0].image
3. 修改yaml文件,经过apply从新部署
[root@master yaml]# kubectl apply -f nginx-deployment.yaml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
deployment "nginx-deployment" configured
但这里有个警告: 也就是apply方式更新的资源应该是由kubectl create 加--save-config参数建立的 或 由apply建立的 (apply当资源不存在时会建立)
这时咱们查看rs,会显示新起了一个rs并将副本扩到3个,旧的rs都缩减为0
[root@master yaml]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5964dfd755 3 3 3 21m
nginx-deployment-6c54bd5869 0 0 0 1h
有时须要回滚的操做,好比更新错误,手误等一系列问题
好比上面的操做更新到1.9.1时,写错了,写成1.91了
[root@master yaml]# kubectl set image deployment/nginx-deployment nginx=nginx:1.91
deployment "nginx-deployment" image updated
追踪状态
[root@master yaml]# kubectl rollout status deployments nginx-deployment
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
可见卡住不动了, Ctrl+C终止,查看rs以下
[root@master yaml]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5964dfd755 3 3 3 40m
nginx-deployment-5d5cfdbd5f 1 1 0 1m
nginx-deployment-6c54bd5869 0 0 0 2h
新的rs只启动了Pod但没有处于READY状态
查看Pods
[root@master yaml]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5964dfd755-8z8b7 1/1 Running 0 27m
nginx-deployment-5964dfd755-bnznj 1/1 Running 0 27m
nginx-deployment-5964dfd755-pt54q 1/1 Running 0 27m
nginx-deployment-5d5cfdbd5f-srdcc 0/1 ImagePullBackOff 0 2m
可发现ImagePullBackOff,实际就是镜像不存在
要修复这个,咱们就须要rollback到前一个ok的版本
查看操做历史
[root@master yaml]# kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
1 kubectl create -f docs/user-guide/nginx-deployment.yaml --record
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
3 kubectl set image deployment/nginx-deployment nginx=nginx:1.91
要查看每一个版本的详细状况,指定--revision
[root@master yaml]# kubectl rollout history deployment/nginx-deployment --revision=2
deployments "nginx-deployment" with revision #2
Pod Template:
Labels: app=nginx pod-template-hash=2710681425
Annotations: kubernetes.io/change-cause=kubectl edit deployment/nginx-deployment
Containers:
nginx:
Image: nginx:1.9.1
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
接下来进行回滚的操做
不指定版本,默认回滚到上一个版本
[root@master yaml]# kubectl rollout undo deployment/nginx-deployment
deployment "nginx-deployment" rolled back
指定版本,经过--to-revision指定
[root@master yaml]# kubectl rollout undo deployment/nginx-deployment --to-revision=2
deployment "nginx-deployment" rolled back
查看
kubectl describe deployment/nginx-deployment
...............
可看到有DeploymentRollback Reason的事件
可经过以下的命令进行扩展
[root@master yaml]# kubectl scale deployment nginx-deployment --replicas=5
deployment "nginx-deployment" scaled
查看Pods
[root@master yaml]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5964dfd755-8z8b7 1/1 Running 0 41m
nginx-deployment-5964dfd755-bhm2s 1/1 Running 0 1m
nginx-deployment-5964dfd755-bnznj 1/1 Running 0 41m
nginx-deployment-5964dfd755-cftfj 1/1 Running 0 6s
nginx-deployment-5964dfd755-pt54q 1/1 Running 0 41m
可见已扩展到5个
使用autoscale还可设置自动水平扩展(hpa),可根据机器负载之类的信息自动扩展或缩减,这个后面细讲
$ kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
deployment "nginx-deployment" autoscaled
暂停和恢复Deployment
有时须要修改多个部分,而不是上面的只修改image,这样的话每次改完都自动部署,显然很差,经过pause便可暂停Deployment,更改完了,经过resume便可恢复部署
暂停
[root@master yaml]# kubectl rollout pause deployment/nginx-deployment
deployment "nginx-deployment" paused
修改
[root@master yaml]# kubectl set image deploy/nginx-deployment nginx=nginx:1.7.9
deployment "nginx-deployment" image updated
查看Pods
[root@master yaml]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5964dfd755-8z8b7 1/1 Running 0 57m
nginx-deployment-5964dfd755-bhm2s 1/1 Running 0 17m
nginx-deployment-5964dfd755-bnznj 1/1 Running 0 57m
nginx-deployment-5964dfd755-cftfj 1/1 Running 0 16m
nginx-deployment-5964dfd755-pt54q 1/1 Running 0 57m
注意后面的AGE仍是以前的Pod,这里就不会自动更新了
恢复
[root@master yaml]# kubectl rollout resume deploy/nginx-deployment
deployment "nginx-deployment" resumed
这时再查看Pods
[root@master yaml]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-6c54bd5869-htjxz 1/1 Running 0 25s
nginx-deployment-6c54bd5869-lj288 1/1 Running 0 30s
nginx-deployment-6c54bd5869-nt8lt 1/1 Running 0 30s
nginx-deployment-6c54bd5869-svqz6 1/1 Running 0 29s
nginx-deployment-6c54bd5869-zq8tl 1/1 Running 0 25s
可见已经更新部署了
内部Deployment部分大概就讲完了,下面把nginx服务暴露到外面
[root@master yaml]# kubectl delete -f nginx-deployment.yaml
deployment "nginx-deployment" deleted
部署service
服务的暴露须要Service,它是Pod的抽象代理(具体机制见这里)。见nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
sessionAffinity: ClientIP
selector:
app: nginx
ports:
- port: 80
nodePort: 30080
kind:Service表明是一个服务
type:NodePort k8s将会在每一个Node上打开一个端口而且每一个Node的端口都是同样的,经过<NodeIP>:NodePort的方式Kubernetes集群外部的程序能够访问Service。
selector:哪一个服务须要暴露
port:service暴露的端口
TargetPort:pod的端口
nodePort:对外暴露的端口,不设置会默认分配,范围:30000-32767
转发逻辑是:
<NodeIP>:<nodeport> => <ServiceVIP>:<port>=> <PodIP>:<targetport>
部署service服务:
[root@master yaml]# kubectl create -f nginx-service.yaml s
ervice "nginx-service" created
可看到启动了一个svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d
svc/nginx-service NodePort 10.101.86.235 <none> 80:30080/TCP 4m
浏览器测试
本文出自https://my.oschina.net/u/2306127/blog/1647246
maxSurge: 1 表示滚动升级时会先启动1个pod
maxUnavailable: 1 表示滚动升级时容许的最大Unavailable的pod个数
因为replicas为3,则整个升级,pod个数在2-4个之间
k8s将会给应用发送SIGTERM信号,能够用来正确、优雅地关闭应用,默认为30秒。
若是须要更优雅地关闭,则可使用k8s提供的pre-stop lifecycle hook 的配置声明,将会在发送SIGTERM以前执行。
livenessProbe是kubernetes认为该pod是存活的,不存在则须要kill掉,而后再新启动一个,以达到replicas指定的个数。
readinessProbe是kubernetes认为该pod是启动成功的,这里根据每一个应用的特性,本身去判断,能够执行command,也能够进行httpGet。好比对于使用java web服务的应用来讲,并非简单地说tomcat启动成功就能够对外提供服务的,还须要等待spring容器初始化,数据库链接链接上等等。对于spring boot应用,默认的actuator带有/health接口,能够用来进行启动成功的判断。
其中readinessProbe.initialDelaySeconds能够设置为系统彻底启动起来所需的最少时间,livenessProbe.initialDelaySeconds能够设置为系统彻底启动起来所需的最大时间+若干秒。
参考使用kubernetes的deployment进行RollingUpdate
https://www.jianshu.com/p/6bc8e0ae65d1