惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Jina AI
Jina AI
The Hacker News
The Hacker News
F
Fortinet All Blogs
The GitHub Blog
The GitHub Blog
IT之家
IT之家
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
月光博客
月光博客
AI
AI
罗磊的独立博客
B
Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 聂微东
Google DeepMind News
Google DeepMind News
爱范儿
爱范儿
Blog — PlanetScale
Blog — PlanetScale
Security Latest
Security Latest
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Check Point Blog
D
DataBreaches.Net
T
Threat Research - Cisco Blogs
I
InfoQ
阮一峰的网络日志
阮一峰的网络日志
人人都是产品经理
人人都是产品经理
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - Franky
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
MongoDB | Blog
MongoDB | Blog
P
Privacy & Cybersecurity Law Blog
Cisco Talos Blog
Cisco Talos Blog
P
Privacy International News Feed
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
博客园_首页
I
Intezer
云风的 BLOG
云风的 BLOG
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
美团技术团队
Simon Willison's Weblog
Simon Willison's Weblog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Forbes - Security
Forbes - Security
T
Tailwind CSS Blog
腾讯CDC
T
Troy Hunt's Blog
Know Your Adversary
Know Your Adversary
U
Unit 42

lvbibir's Blog

shell | 磁盘空间分析脚本 Linux cat 和 tee 命令写入文件 python | 使用 uv 管理你的 python 环境 Claude Code 完整配置指南 windows | mihomo 内核独立部署指南 linux | 磁盘扩容 wsl | 释放长久运行占用的磁盘空间 mysql | 线程上限问题处理 麒麟 7.6 安装谷歌 OTP 认证模块 suse 12sp5 升级 openssh 及 openssl suse 12sp5 部署 mysql 5.7 《谁的青春不迷茫》 docker | centos7 部署 docker vim | 基础配置和使用 windows | rime 输入法 & 雾凇方案 shell | sshpass 批量传输文件及执行命令 wsl | 原生 linux 方式安装 docker nodejs | fnm + pnpm 开发环境配置 wsl | 安装配置 miniconda 虚拟环境 wsl | 自动更新系统代理 wsl | bashrc 环境变量不正确加载的处理方法 wsl | win10 安装 wsl2 troubleshooting | ssh 成功但是 scp 失败 linux | 常用命令总结 docker 部署 piclist shell | 检测网站存活并自动钉钉告警 Zabbix | 监控端口连通性并自动追踪 TCP 路由 windows | 自定义开机快速启动项 windows | miniconda 配置 python 虚拟环境 Zabbix | 监控主机到指定 ip 的流量大小 shell | centos 初始化 loki (二) 部署 loki (一) 简介 prometheus (六) Alertmanager prometheus (五) 记录规则与告警规则 prometheus (四) 黑盒监控 prometheus (三) 服务发现 prometheus (二) 静态配置 prometheus (一) 简介及部署 traefik (四) TraefikService 服务 traefik (三) Middleware 中间件 traefik (二) ingressRoute 路由 traefik (一) 简介、部署和配置 kubernetes | Gateway API 简介及部署 linux | dns 配置文件中 search 和 options ndots 详解 kubernetes | command args 和 dockerfile 中的 ENTRYPOINT CMD kubernetes | statefulset 控制器详解 docker | dockerfile 最佳实践 docker | dockerfile 指令详解 linux | kill 命令详解以及 linux 中的信号 troubleshooting | elasticsearch 安装插件报错 shell | if 条件判断 docker | 下载外网镜像的几种方式 python | 鬼谷子数学问题 steam挂刀教程 linux | history 命令的格式化输出 shell | 将本地镜像批量推送到 harbor windows | hosts 文件修复 kubernetes | configmap & secret kubernetes | RBAC 鉴权和 NetworkPolicy kubernetes | service & ingress kubernetes | 存储 kubernetes | 控制器 kubernetes | 日志 kubernetes | 调度 kubernetes | pod kubernetes | 杂记 linux | set 命令详解 ceph | openeuler 部署 ceph-v16 ceph | ceph-v16 离线安装解决方案 pxe 如何应对复杂的服务器硬件环境 python | 批量修改目录下文件名 《微习惯》 ceph | openeuler (aarch64) 部署 ceph-v16 troubleshooting | glibc 误升级后修复 pxe 安装配置大全 《人间失格》 跑步日常 [置顶] Hello, hugo! shell | 检索某 url 中所有文件的内容 shell | 不同执行方式的区别 shell | 开启 debug 模式 vscode | 常见问题 windows & linux 多网卡时设置默认路由以及添加静态路由 mysql (二) 主从复制原理 GTID 并行复制 mysql (一) 部署 mysql | 杂记 cicd | jenkins 部署 mall-swarm 项目 httpd 源码打包编译成 rpm 包 openssl 源码打包编译成 rpm 包 centos7 | 修改网卡名称 ceph | pool pg_num 配置 docker | 脚本方式批量导出/导入镜像 centos 密码尝试次数过多问题处理 centos7 | 升级内核至 5.10 CVE-1999-0526 ceph | centos7 部署 ceph-v12 python | 修改 pip 源 troubleshooting | 安装 cloud-init 后导致 ssh 连接失败 windows | autohotkey 常用脚本
kubernetes | 滚动升级和自动伸缩
lvbibir · 2022-10-05 · via lvbibir's Blog

0 前言

基于 centos7.9docker-ce-20.10.18kubelet-1.22.3-0

1 滚动升级

1.1 实现机制

滚动升级的实现机制

两个 replicaset 控制器分别控制旧版本的 pod 和新版本 pod,replicaset2 启动一个新版版本 pod,相应的 replicaset1 停止一个旧版本 pod,从而实现滚动升级。在这过程中,无法保证业务流量完全不丢失。

image-20221003113645777

1.2 简单示例

升级

kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N [options]
# 示例
kubectl set image deployment/demo-rollout nginx=nginx:1.15 --record=true
# --record=true 表示将升级的命令记录到升级记录中

回滚

# 上次升级状态
kubectl rollout status deployment demo-rollout
# 升级记录
kubectl rollout history deployment demo-rollout
# 回滚至上个版本
kubectl rollout undo deployment demo-rollout
# 回滚至指定版本
kubectl rollout undo deployment demo-rollout --to-revision=2

1.3 升级

在所有 work 节点先创建几个 busybox 镜像的 tag 用于升级演示

[root@k8s-node3 ~]# for i in {1..3}; do docker tag busybox:latest busybox:v${i}; done
[root@k8s-node3 ~]# docker images | grep busybox
busybox                                              latest    7cfbbec8963d   3 weeks ago     4.86MB
busybox                                              v1        7cfbbec8963d   3 weeks ago     4.86MB
busybox                                              v2        7cfbbec8963d   3 weeks ago     4.86MB
busybox                                              v3        7cfbbec8963d   3 weeks ago     4.86MB

创建 v1 版本的 deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-rollout
  labels:
    app: demo-rollout
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo-rollout
  template:
    metadata:
      labels:
        app: demo-rollout
    spec:
      containers:
      - name: busybox
        image: busybox:v1
        command: ['/bin/sh', '-c', 'sleep 36000']

也可以使用命令创建

[root@k8s-node1 ~]# kubectl create deployment demo-rollout --image=busybox:v1 --replicas=3 -- sleep 3600
deployment.apps/demo-rollout created
[root@k8s-node1 ~]# kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
demo-rollout-5d847fd86c-678pr   1/1     Running   0          4s
demo-rollout-5d847fd86c-9mj4v   1/1     Running   0          4s
demo-rollout-5d847fd86c-xhvf7   1/1     Running   0          4s

升级至 v2 和 v3

# 升级
[root@k8s-node1 ~]# kubectl set image deployment/demo-rollout busybox=busybox:v2 --record=true
[root@k8s-node1 ~]# kubectl set image deployment/demo-rollout busybox=busybox:v3 --record=true
# 查看升级状态
[root@k8s-node1 ~]# kubectl rollout status deployment demo-rollout
deployment "demo-rollout" successfully rolled out
[root@k8s-node1 ~]# kubectl rollout history deployment demo-rollout
deployment.apps/demo-rollout
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deployment/demo-rollout busybox=busybox:v2 --record=true
3         kubectl set image deployment/demo-rollout busybox=busybox:v3 --record=true
# 查看实际镜像版本
[root@k8s-node1 ~]# kubectl get deployment demo-rollout -o jsonpath='{.spec.template.spec.containers}'
[root@k8s-node1 ~]# kubectl describe deployment demo-rollout | grep -i image:
    Image:      busybox:v3

1.4 回滚

回滚至 v1 版本

[root@k8s-node1 ~]# kubectl rollout undo deployment/demo-rollout --to-revision=1
deployment.apps/demo-rollout rolled back
[root@k8s-node1 ~]# kubectl describe deployment demo-rollout | grep -i image:
    Image:      busybox:v1
[root@k8s-node1 ~]# kubectl rollout history deployment demo-rollout
deployment.apps/demo-rollout
REVISION  CHANGE-CAUSE
2         kubectl set image deployment/demo-rollout busybox=busybox:v2 --record=true
3         kubectl set image deployment/demo-rollout busybox=busybox:v3 --record=true
4         <none>

可以看到 rollout history 删除了第一次的记录, 重新记录到第四条

恢复到 v2 版本

[root@k8s-node1 ~]# kubectl rollout undo deployment/demo-rollout --to-revision=2
deployment.apps/demo-rollout rolled back
[root@k8s-node1 ~]# kubectl describe deployment demo-rollout | grep -i image:
    Image:      busybox:v2
[root@k8s-node1 ~]# kubectl rollout history deployment demo-rollout
deployment.apps/demo-rollout
REVISION  CHANGE-CAUSE
3         kubectl set image deployment/demo-rollout busybox=busybox:v3 --record=true
4         <none>
5         kubectl set image deployment/demo-rollout busybox=busybox:v2 --record=true

2 自动伸缩

手动扩容

 kubectl scale [--resource-version=version] [--current-replicas=count] --replicas=COUNT (-f FILENAME | TYPE NAME) [options]
 # 示例
 kubectl scale deployment demo-rollout --replicas=10

自动扩容

实现自动扩容需满足两个条件:

Horizontal Pod Autoscaling: pod 水平扩容,k8s 中的一个 api 资源,使用 autoscale 时会创建一个 hpa 资源

HPA 基本原理:

  • 查询指定的资源中所有 Pod 的资源平均使用率,并且与创建时设定的值和指标做对比,从而实现自动伸缩的功能.
  • HPA 自动伸缩副本时会使 POD 的资源使用率趋近于预设的 target 值
    • 比如只有一个 POD 时, 资源使用率达到了 180%/70%, HPA 会将 POD 数量扩容到 3 个, 此时资源使用率将会是 60%/70%.
  • 当 pod 资源使用率回到正常水平, controller-manager 会默认等待 5 分钟的时间再缩容 pod,以免再次出现突发流量.
kubectl autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS] --max=MAXPODS [--cpu-percent=CPU] [options]
# 基于cpu指标进行扩容
kubectl autoscale deployment demo-rollout --min=3 --max=10 --cpu-percent=10

# 查看hpa
kubectl get hpa

# replicaset控制器记录了pod的详细伸缩记录
kubectl get rs
kubectl describe rs demo-rollout-54fdcc5676

2.1 基于 CPU

创建 deployment 资源

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hpa-demo
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: 50Mi
            cpu: 50m
---
apiVersion: v1
kind: Service
metadata:
  name: hpa-demo
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30002

创建 hpa 资源

cpu 使用率 = 已使用 / request

--cpu-percent=60 代表所有 pod 的平均 cpu 使用率达到百分之 60 时触发扩容

[root@k8s-node1 ~]# kubectl autoscale deployment hpa-demo --cpu-percent=60 --min=1 --max=10
horizontalpodautoscaler.autoscaling/hpa-demo autoscaled
[root@k8s-node1 ~]# kubectl get hpa
NAME       REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
hpa-demo   Deployment/hpa-demo   0%/60%    1         10        1          18s

压测

[root@k8s-node1 ~]# yum install -y httpd-tools
[root@k8s-node1 ~]# ab -n 1000000 -c 200 http://1.1.1.1:30002/

hpa 自动扩容, pod 数量增加到了 10 个

[root@k8s-node1 ~]# kubectl get hpa
NAME       REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
hpa-demo   Deployment/hpa-demo   160%/10%    1         10        10         50m

[root@k8s-node1 ~]# kubectl describe hpa hpa-demo
Events:
  Type     Reason                        Age                From                       Message
  ----     ------                        ----               ----                       -------
  Warning  FailedGetScale                17m (x8 over 19m)  horizontal-pod-autoscaler  deployments/scale.apps "hpa-demo" not found
  Normal   SuccessfulRescale             11m                horizontal-pod-autoscaler  New size: 4; reason: cpu resource utilization (percentage of request) above target
  Normal   SuccessfulRescale             11m                horizontal-pod-autoscaler  New size: 8; reason: cpu resource utilization (percentage of request) above target
  Normal   SuccessfulRescale             10m                horizontal-pod-autoscaler  New size: 10; reason:

[root@k8s-node1 ~]# kubectl describe deployment hpa-demo
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  16m    deployment-controller  Scaled up replica set hpa-demo-6b4467b546 to 1
  Normal  ScalingReplicaSet  10m    deployment-controller  Scaled up replica set hpa-demo-6b4467b546 to 4
  Normal  ScalingReplicaSet  9m53s  deployment-controller  Scaled up replica set hpa-demo-6b4467b546 to 8
  Normal  ScalingReplicaSet  9m38s  deployment-controller  Scaled up replica set hpa-demo-6b4467b546 to 10

压测结束后也并不会立即减少 pod 数量,会等一段时间后减少 pod 数量,防止流量再次激增。默认时间大概是 5 分钟左右

2.2 基于内存

使用 busybox 容器测试, 另挂载一个 configMap 用于内存压力测试, 由于用到了 mount 命令, 还需要将 container 声明为特权模式.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hpa-mem
spec:
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
      - name: busybox
        image: busybox
        command: ["/bin/sh", "-c", "sleep 36000"]
        volumeMounts:
        - name: increase-mem-script
          mountPath: /opt/
        resources:
          requests:
            memory: 50Mi
            cpu: 50m
        securityContext:
          privileged: true
      volumes:
      - name: increase-mem-script
        configMap:
          name: increase-mem-config
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: increase-mem-config
data:
  increase-mem.sh: |
    #!/bin/sh
    mkdir /tmp/memory
    mount -t tmpfs -o size=40M tmpfs /tmp/memory
    dd if=/dev/zero of=/tmp/memory/block
    sleep 60
    rm /tmp/memory/block
    umount /tmp/memory
    rmdir /tmp/memory    

获取 hpa 的模板 yaml 文件

[root@k8s-node1 ~]# kubectl autoscale deployment hpa-mem --min=1 --max=10 --dry-run=client -o yaml > hpa-mem-hpa.yml
[root@k8s-node1 ~]# vim hpa-mem-hpa.yml

使用 yaml 创建 hpa, 默认使用的是 autoscaling/v1 版本的 api, 它不支持基于内存的自动扩容, 需要修改为 autoscaling/v2beta1

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-mem
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: hpa-mem
  metrics:
  - type: Resource
    resource:
      name: memory
      targetAverageUtilization: 60

执行脚本进行压测, 随着脚本执行, hpa 自动将副本数扩容到了两个

[root@k8s-node1 ~]# kubectl exec -it hpa-mem-c6c7d4957-fpsfb -- /bin/sh /opt/increase-mem.sh
[root@k8s-node1 ~]# kubectl get hpa -w
NAME      REFERENCE            TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
hpa-mem   Deployment/hpa-mem   0%/60%    1         10        1          2m55s
hpa-mem   Deployment/hpa-mem   80%/60%   1         10        1          4m1s
hpa-mem   Deployment/hpa-mem   80%/60%   1         10        2          4m16s

脚本执行 60s 后会使内存使用率自动恢复正常, 副本数过段时间也会自动恢复

2.3 基于自定义指标

待续……

以上