Kubernetes-in-action (七)
本节内容:Deployment,StatefulSet
Deployment
作用
- 作为RC和RS的高一级资源 [RC -> replicationController, RS -> ReplicaSet]
- 可以让pod 模板变化后立即生效,不需要手动重启pod来让配置生效。 (会自动删除重建)
- 对于滚动升级友好,不需要额外允许多条命令来执行升级
实践
-
使用ReplicationController来进行滚动升级
-
蓝绿部署: 创建新的pod -> 将service改成选中新的pod ->
新pod功能可以,则删除旧的pod,不可以则回滚service的选择器。 [不接受服务暂时不可用情况下] - 修改rc文件中的pod模板 -> 删除旧的pod [可以接受暂时服务不可用]
-
蓝绿部署: 创建新的pod -> 将service改成选中新的pod ->
apiVersion: v1
kind: ReplicationController
metadata:
name: kubia-v1
spec:
replicas: 3
template:
metadata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia:v1
name: nodejs
---
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
type: LoadBalancer
selector:
app: kubia
ports:
- port: 8000
targetPort: 8080
-
使用Deployment来进行滚动升级
-
部署后,升级镜像并查看容器结果:
-
kubectl create -f kubia-deployment-and-service-v1.yaml --record
# 指定 –record 则在查看历史版本时可以知道改版本修改了什么,
既 CHANGE-CAUSE -
kubectl set image deployment kubia nodejs=luksa/kubia:v3
# 更新镜像,从而升级。 -
kubectl rollout status deployment kubia
# 执行上面指令后,可以执行这个指令查看升级过程 -
while true; do curl localhost:8000; sleep 1s; done;
# 一直调用service,看容器是否升级成功 -
kubectl rollout history deployment kubia
# 查看可以回滚的版本 -
kubectl rollout undo deployment kubia --to-revision=1
## 回滚指定版本,不加后面的–的参数则是回滚到上个版本 -
kubectl rollout pause deployment kubia
# 暂停升级, 暂停都不能继续升级,恢复后才能。 -
kubectl rollout resume deployment kubia
# 恢复升级
-
-
部署后,升级镜像并查看容器结果:
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubia
spec:
replicas: 3
minReadySeconds: 10 # 设置就绪多久pod才算ready,才能被访问
strategy: # 配置升级速率
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: kubia
template:
metadata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia:v1
name: nodejs
readinessProbe: # 就绪探针
periodSeconds: 1
httpGet:
path: /
port: 8080
---
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
type: LoadBalancer
selector:
app: kubia
ports:
- port: 8000
targetPort: 8080
注意
-
为什么kubectl rolling-update已经过时
- 由于rolling-update是由kubectl执行,然后同步到kube api-server,所以如果出现网络问题,会导致升级处于中间态,需要手动修复。
-
deployment的pod name组成
- metadata.name + deployment 模板的 hash + 随机数
-
deployment 升级策略
- Recreate 策略在删除旧的pod之后才开始创建新的pod
-
RollingUpdate 策略会渐进地删除旧的pod,与此同时创建新的
pod,使应⽤程序在整个升级过程中都处于可⽤状态,并确保其处理请求的能⼒没有因为升级⽽有所影响。 [默认的]-
设置的期望副本数为3,上述的两个属性都设置为25%, maxSurge 允许最多pod数量达到 4,同时 maxUnavailable
不允许出现任何不可⽤的pod [结果四舍五入] - 这两个参数用于升级时候的速率控制
-
设置的期望副本数为3,上述的两个属性都设置为25%, maxSurge 允许最多pod数量达到 4,同时 maxUnavailable
-
升级后rs为什么还在
- 因为回滚时候会用上rs模板中的pod模板来生成指定版本的pod。revisionHistoryLimit默认为 10,保留是十个版本。
-
升级失败怎么办
- progressDeadlineSeconds参数设置了多久升级未完成则为失败,如果pod没有默认的值,则只能自己手动undo这次升级,不然就会一直停着。
StatefulSet
作用
- Stateful pod的允许需要持久卷的支持,pod内产生的数据需要持久化,StatefulSet 则是管理 Stateful Pod的资源
- StatefulSet 生成的pod后缀都是从下表-0开始, pod-0,pod-1,pod-2, 只有当第一个生成完才会生成第二个。
实践
-
配置一个statefulSet,包含一个pod,三个副本,每个副本都绑定到一个pv上。
-
修改pod的副本数量
kubectl edit statefulSet kubia
- 删除pod时,pv和pvc依旧在,是因为防止误操作导致数据丢失,所以只能手动删除。
-
修改pod的副本数量
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
clusterIP: None # headless
selector:
app: kubia
ports:
- name: http
port: 8000
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kubia
spec:
serviceName: kubia
replicas: 2
selector:
matchLabels:
app: kubia # has to match .spec.template.metadata.labels
template:
metadata:
labels:
app: kubia
spec:
containers:
- name: kubia
image: luksa/kubia-pet
ports:
- name: http
containerPort: 8080
volumeMounts:
- name: data
mountPath: /var/data
volumeClaimTemplates:
- metadata:
name: data
spec:
resources:
requests:
storage: 1Mi
accessModes:
- ReadWriteOnce
-
使用kube proxy来在一个pod中访问另一个pod
-
使用命令
kubectl proxy
生成proxy -
curl localhost:8001/api/v1/namespaces/default/pods/kubia-0/proxy/
#访问pod,最后的
/
必须加,因为api server解析流程如下-
proxy将
/api/v1/namespaces/default/pods/kubia-0/proxy/
转发给 api server -
api server 将访问pod的
/
路径既
pod-host:port/
, 如果没有最后的斜杠,则被认为只是访问api server而不是转发请求。
-
proxy将
-
使用命令
-
模拟节点失效导致statefulSet的pod状态无感知
-
关闭某个node的网卡
ifconfig eth0 down
-
pod 变成
unknown
状态, 坏node上的kubectl没办法通知api server 当前pod的状态。 - 在好的node上增加一个pod
-
在好的node上执行删除故障node上的pod, 除非强制删除不然删不掉,因为pod本身就是terminating。
kubectl delete pod name --force --grace-period 0
-
关闭某个node的网卡
注意
-
有状态的pod需要保证集群内部不会出现两个一样名称的pod。 (如果出现一样的,则数据可能会重复执行)
- 当有状态的pod被分配到多个node中时,其中一个node断开连接, pod不会执行删除重建,而是等待失联的node重连后告知pod的最新状态。
版权声明:本文为samveltor原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。