k8sday06深入控制器(1/3)

目录

Deployment

1、区分概念

2、配置文件

3、滚动更新(升级)

3.1测试滚动更新

Ⅰ、 修改Deployment 自身的元数据标签

Ⅱ、修改 Pod 模板中的元数据标签

3.2滚动更新的具体步骤:

Ⅰ、创建新 Pod

Ⅱ、等待新 Pod 就绪

Ⅲ、终止旧 Pod

3.3结论

4、回滚版本

5、扩容和缩容

Ⅰ、kubectl scale操作(常用、方便)

①、扩容

②、缩容

Ⅱ、编辑yaml文件(较麻烦)

①、扩容

②缩容

6、暂停和恢复

Ⅰ、暂停滚动更新

Ⅱ、恢复滚动更新


控制器(controller),是 Kubernetes 中用于管理 Pod 副本的机制。它负责确保 Pod 的副本数量符合预期,并且在 Pod 发生故障时自动重启或重新创建 Pod。

Deployment

1、区分概念

首先我们要区分DeploymentReplicaSet两个概念,可以这么理解两个的关系:ReplicaSet是Deployment的底部实现,我们日常更常用Deployment

维度DeploymentReplicaSet
主要功能管理版本升级、回滚、滚动更新策略只是通过标签选择器持续监控并维持指定数量的 Pod 副本,Pod多了就删除,少了就增加
更新方式支持滚动/回滚(strategy不支持,只能手动改 Pod 模板
推荐用法生产环境首选调试/特殊场景直接写 RS

其次区分LabelSelector标签 是附加到 Kubernetes 资源上的键值对,用于标识和选择这些资源。标签可以附加到 Pod、Deployment、Service 等资源上。根据用途、环境、版本等对资源进行分类,用于监控工具、日志收集器等选择需要处理的资源。选择器 是用于选择具有特定标签的资源的工具。标签通过选择器(Selector)选择特定的资源。

2、配置文件

以下给出一份常用的Deployment的yaml创建文件,并给出每一步的解释:

注意只给出基本的配置,其他配置如数据卷挂载,重启策略等等,如有需要,自行配置~

apiVersion: apps/v1               # Deployment 的API的版本
  kind: Deployment                  # 声明资源类型是 Deployment
  ​
  metadata:                         # Deployment 的元信息
    name: nginx-deployment1         # Deployment 名称(自定义),注意全小写
    namespace: default              # 目标命名空间
    labels:
      app: nginx                    # 给 Deployment 打标签,便于筛选(自定义)
  ​
  spec:              
    replicas: 3                     # 期望的 Pod 副本数
  ​
    selector:                       # 选择器,告诉 Deployment 它要管理哪些 Pod
      matchLabels:                  # 按照标签匹配
        app: nginx                  # 必须与下方 Pod 模板的 template.metadata.labels 一致
  ​
    strategy:                       # 升级/回滚策略
      type: RollingUpdate           # 更新类型,这里选择采用滚动升级(可选 Recreate)
      rollingUpdate:                # 滚动更新的策略
        maxSurge: 1                 # 升级时最多可多启动1个 Pod(最多超过期望的个数)
        maxUnavailable: 0           # 升级时最多0个 Pod 可更新不成功(最大不可用)
  ​
    template:                       # Pod 模板,通过这个模板创建副本
      metadata:                     # Pod 的元信息
        labels:
          app: nginx                # Pod 标签,必须与上方的 selector.matchLabels 一致
      spec:
        containers:
        - name: nginx               # 容器名称
          image: nginx              # 镜像版本,不加版本号默认最新版
          imagePullPolicy: IfNotPresent  # 镜像拉取策略
          ports:
          - containerPort: 80       # Pod 开放的端口
            name: http
          env:                      # 可选:注入环境变量
          - name: ENV
            value: "prod"
          resources:                # 资源请求与限制
            requests:               # 最少需要的资源
              cpu: "100m"           # 最少需要100毫核
              memory: "128Mi"       # 128 MiB 内存
            limits:                 # 最多使用的资源
              cpu: "200m"           # 最多可使用200毫核
              memory: "256Mi"       # 256 MiB 内存
              
          livenessProbe:            # 存活探针
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 10
            periodSeconds: 10
          readinessProbe:           # 就绪探针
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 5

之后直接输入命令创建Deployment即可:

  # 如果使用相对路径记得先cd到配置文件所在的路径下哦
  kubectl apply -f nginx-deploy1.yaml
  ​
  # 查看已经创建的Deployment
  kubectl get pods,deploy

当输出类似信息表示你创建成功:

可见成功创建出了3个Pod副本(使用的是同一个模板)以及1个Deployment

3、滚动更新(升级)

Deployment 通过 “先启动新 Pod → 再终止旧 Pod” 的方式,在 零停机 条件下完成镜像或配置的版本升级;底层由 ReplicaSet 接力完成。

改镜像 → 自动滚动 → 观察状态 → 一键回滚

3.1测试滚动更新

接下来我将通过两种修改方式说明Deployment 的更新机制:

Ⅰ、 修改Deployment 自身的元数据标签

如:修改Deployment 自身的metadata.labels

  metadata:                         # Deployment 的元信息
    name: nginx-deployment1         # Deployment 名称(自定义),注意全小写
    namespace: default              # 目标命名空间
    labels:
      app: nginx-deploy1            # app: nginx  ——>  app: nginx-deploy1
      # 修改 Deployment 标签,看是否进行滚动更新

使用以下代码保存查看日志,看是否进行了滚动更新:

   # 如果使用相对路径记得先cd到配置文件所在的路径下哦
   kubectl apply -f nginx-deploy1.yaml
  ​
   kubectl rollout history deployment/<你的deployment的名字>

可以得到类似下列输出:

  • REVISION:表示当前的版本号。1 表示这是初始版本

  • CHANGE-CAUSE:表示触发更新的原因。<none> 表示没有明确的更新原因记录

Ⅱ、修改 Pod 模板中的元数据标签

如:修改资源请求

这里不建议通过直接修改 Pod 模板中的标签.spec.template.metadata.labels来测试是否进行了滚动更新,因为Pod 的标签必须与 Deployment 的 selector.matchLabels 一致,否则 Deployment 无法正确管理 Pod。

如果你非要直接修改 Pod 模板中的标签,必须同时修改 Deployment 的 spec.selector.matchLabels spec.template.metadata.labels,以确保滚动更新能够正常进行

修改 Pod 标签的方法有两种:

Ⅰ、使用kubectl的set命令进行修改

Ⅱ、使用kubectl的edit命令或在外部使用其他编辑器(vscode、notepad等)对yaml文件修改

# Pod 模板中的期望状态
          resources:                # 资源请求与限制
            requests:               # 最少需要的资源
              cpu: "100m"           # 最少需要100毫核
              memory: "128Mi"       # 128 MiB 内存
            limits:                 # 最多使用的资源
              cpu: "250m"           # cpu: "200m" ——> cpu: "250m"
              # 修改最多使用的cpu资源,测试是否会进行滚动更新  
              memory: "256Mi"       # 256 MiB 内存

使用以下代码保存查看历史版本,看是否进行了滚动更新:


   # 如果使用相对路径记得先cd到配置文件所在的路径下哦
   kubectl apply -f nginx-deploy1.yaml
   
   kubectl rollout history deployment/<你的deployment的名字>

可以得到类似下列输出:

  • REVISION:表示当前的版本号。2表示这是更新后的版本

  • CHANGE-CAUSE:表示触发更新的原因。<none> 表示没有明确的更新原因记录,这是由于更新的时候没有在命令行末尾加入--record来记录你的更新原因

当然可以更直接一点(直接得出版本):

  kubectl get rs

输出类似信息:

第一个是现在更新完的最新版本,正在运行。

第二个是旧版本,已经被完全替换,所有 Pod 都已经被终止。

3.2滚动更新的具体步骤:
Ⅰ、创建新 Pod

Deployment 会根据新的 Pod 模板创建新的 Pod。

Ⅱ、等待新 Pod 就绪

新 Pod 启动并进入 Running 状态。

Ⅲ、终止旧 Pod

旧 Pod 会被逐步终止,直到所有旧 Pod 都被替换为新 Pod。

当你查看pod时可看到,旧Pod仍在停止,新Pod仍在创建的情形,在 零停机 条件下完成,如下:

3.3结论

以上两种方法说明Deployment 的更新机制仅对 Pod 模板(.spec.template)的变更敏感,如:

  • 修改容器镜像版本(如 image: nginx:1.14.2nginx:1.16.1

  • 调整 Pod 模板中的环境变量、资源限制或标签(如 .spec.template.metadata.labels

  • 修改副本数(replicas)或更新策略(如 strategy.rollingUpdate

4、回滚版本

当你更新完后,发现现版本有问题,或是更新的值虽然是错的,但还是被更新成功了,我想回退到上一个没有错误的版本,这时候即可使用命令rollout undo 命令回滚版本。

   # 查看可当前已有版本
   kubectl rollout history deployment/<你的deployment的名字>
   
   # 查看具体某个修订版的信息
   kubectl rollout history deployment/<你的deployment的名字> --revision=<你当前已有版本>

可以得到类似下列输出(可以看到当前有2个版本):

当然也是可以看到不同修订版的大致信息:

# 查看具体某个修订版的信息
   kubectl rollout undo deployment/<你的deployment的名字> --revision=<你要回滚的版本>

5、扩容和缩容

扩容和缩容是较常用的操作,可有两种方法操作(根本都是对replicas进行修改):

Ⅰ、kubectl scale操作(常用、方便)
①、扩容
kubectl scale --replicas=<你要扩容的数量> deploy/<你的deployment的名字>

通过扩容发现:

  • 并没有改变历史版本数量

  • Pod数量增加到了指定数量

  • 创建Pod是使用同一个模板

②、缩容
  kubectl scale --replicas=<你要缩容的数量> deploy/<你的deployment的名字>

缩容同理

Ⅱ、编辑yaml文件(较麻烦)
①、扩容
  
  spec:                                          
    replicas: <你要扩容的数量>                     # 期望的 Pod 副本数
②缩容
  spec:                                          
    replicas: <你要缩容的数量>                     # 期望的 Pod 副本数

6、暂停和恢复

暂停滚动更新和恢复滚动更新主要应用于需要手动干预或逐步控制更新过程时。

Ⅰ、暂停滚动更新
  kubectl rollout pause deployment/<你的deployment名字>

使用这个命令之后,你再进行对 Pod 模板进行修改都不会直接进行,而是停止,当前一直处于暂停前的版本,一直到你恢复滚动更新

Ⅱ、恢复滚动更新
  kubectl rollout resume deployment/<你的deployment名字>

使用这个命令之后,你之前对 Pod 模板进行的修改都会直接进行,生成一个新的版本,版本包含了你对上一个版本的全部更新修改

<think>嗯,用户想修改STM32的RTC闹钟代码,实现每天重复触发的功能,而且不使用HAL库。首先,我需要回忆一下STM32的RTC模块的结构和寄存器配置。RTC闹钟通常可以基于日期或者时间匹配,但每天重复的话,可能需要忽略日期部分,只关注时间。 用户提到要调整现有的RTC_SetAlarm函数,并关注秒计数机制。RTC的闹钟寄存器一般有两种模式:使用掩码来忽略某些字段,或者直接比较特定的值。比如,设置闹钟时,可以配置为忽略日期、月份、年份,只比较小时、分钟和秒,这样每到设定的时间就会触发。 接下来要考虑如何配置闹钟寄存器。在标准外设库中,可能需要设置ALRMAR寄存器的各个字段,并设置相应的掩码位。例如,设置小时、分钟、秒,并将日期和星期几的掩码位设为忽略。这样,每天同一时间都会触发闹钟中断。 然后,每次闹钟触发后,需要重新设置下一次的触发时间。因为在中断服务函数里,一旦闹钟触发,原来的设置会被清除,所以需要重新配置闹钟时间。这里可能需要读取当前时间,计算出下一次的触发时间,然后重新设置闹钟寄存器。 还要注意RTC的时钟源和分频配置,确保RTC正常工作。另外,闹钟中断的使能和NVIC配置也需要检查,确保中断能够正确触发和处理。 用户可能需要示例代码来展示如何初始化RTC,设置闹钟,以及处理中断。需要强调掩码位的设置,比如使用RTC_AlarmMask_DateWeekDay等来忽略日期部分。此外,在中断服务函数中,清除标志位并重新设置闹钟是关键步骤,以确保每天重复触发。 可能的问题点包括:是否正确配置了掩码位,是否处理了中断标志,以及是否在中断中重新设置了闹钟。需要提醒用户检查这些部分,并进行测试验证。 最后,相关的问题可能涉及如何调整闹钟的间隔时间,比如每小时触发,或者处理夏令时等复杂情况。但用户当前的需求是每天重复,所以重点放在时间掩码和中断重置上。</think>根据STM32的RTC闹钟机制,实现每日重复触发需重点关注时间掩码设置和秒计数处理。以下是具体实现步骤: 1. **RTC闹钟寄存器配置原理** - STM32的RTC_ALRMAR寄存器支持掩码模式(MASK bits),通过设置MSKx位可忽略日期/时间字段 - 每日重复需设置:MSK4=1(忽略日期/星期) + MSK3=0(启用时间匹配)[^2] 2. **关键代码修改方案** ```c // 设置每日重复闹钟 void RTC_SetDailyAlarm(uint8_t hour, uint8_t min, uint8_t sec) { RTC_AlarmTypeDef alarm; alarm.RTC_AlarmTime.RTC_H12 = RTC_H12_AM; alarm.RTC_AlarmTime.RTC_Hours = hour; alarm.RTC_AlarmTime.RTC_Minutes = min; alarm.RTC_AlarmTime.RTC_Seconds = sec; alarm.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay; // 关键掩码设置 alarm.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; alarm.RTC_AlarmDateWeekDay = 0x1; // 任意日期 RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &alarm); RTC_ITConfig(RTC_IT_ALRA, ENABLE); } // 中断服务函数 void RTC_Alarm_IRQHandler(void) { if(RTC_GetITStatus(RTC_IT_ALRA)){ RTC_ClearITPendingBit(RTC_IT_ALRA); // 自动重置闹钟(关键步骤) RTC_WaitForSynchro(); RTC_SetDailyAlarm(current_hour, current_min, current_sec); EXTI_ClearITPendingBit(EXTI_Line17); } } ``` 3. **秒计数处理要点** - 使用RTC_GetCounter()获取当前秒计数值 - 下次触发时间计算:$$ t_{next} = t_{current} + 86400 - (t_{current} \% 86400) $$ - 需处理32位计数器溢出问题,建议使用库函数RTC_SetAlarm()直接设置时分秒
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值