kubectl Patch Deployment的volume和volumeMounts

K8s运维中,为Deployment添加/追加volumes及volumeMounts(如挂载配置、license文件)时,手动操作效率低、风险高。本文精简介绍patch-exist.sh脚本,聚焦其用法、适用场景及核心原理,帮助运维人员高效安全完成配置更新。

一、脚本核心定位

patch-exist.sh专为K8s Deployment设计,核心是「先备份、再操作」,兼容"无原有卷/挂载""有原有卷/挂载"两种场景,不覆盖原有配置,降低运维门槛,避免误操作故障。

二、脚本详细用法

(一)前置准备

  1. 依赖:安装kubectl(K8s客户端)和jq(JSON解析工具),命令:yum install jq -y,kubectl需配置集群连接。

  2. 配置:修改脚本中NAMESPACE参数(默认your_namespace),匹配实际集群命名空间。

  3. 权限:执行用户需拥有目标命名空间Deployment的get、patch权限。

(二)脚本执行

仅需传入Deployment名称,命令格式:bash patch-exist.sh <deployment-name>

示例:bash patch-exist.sh bus-server,执行后自动完成备份、配置处理、结果验证,失败则终止。

(三)结果验证与备份恢复

  1. 验证:手动执行命令确认配置生效(筛选tongweb-lic相关配置):

kubectl get deployment <deployment-name> -n <namespace> -o jsonpath='{.spec.template.spec.volumes}' | jq '.[] | select(.name=="tongweb-lic")' kubectl get deployment <deployment-name> -n <namespace> -o jsonpath='{.spec.template.spec.containers[0].volumeMounts}' | jq '.[] | select(.name=="tongweb-lic")'

  1. 恢复:脚本自动在./backup目录生成备份文件,恢复命令:kubectl apply -f ./backup/<backup-file-name> -n <namespace>

三、脚本适用场景

  1. 批量挂载:多Deployment统一挂载配置(如tongweb-lic),示例:for deploy in admin-server portal-server; do bash patch-exist.sh $deploy; done

  2. 新增配置:新建Deployment无卷/挂载时,自动创建字段并添加配置。

  3. 追加配置:已存在卷/挂载的Deployment,在原有数组末尾追加,不覆盖原有配置。

  4. 高安全场景:备份失败终止操作,可通过备份快速恢复,适配生产环境。

四、脚本核心原理

脚本依托K8s JSON Patch机制和Shell逻辑,核心分4个模块:

  1. 前置校验:检查Deployment名称参数、kubectl和jq是否安装,缺失则退出。

  2. 备份逻辑:自动创建备份目录,导出Deployment配置至YAML文件,备份失败终止操作。

  3. 配置Patch:用jq判断volumes/volumeMounts是否存在------不存在则创建字段并添加配置;存在则在数组末尾追加(路径末尾加-)。

  4. 结果验证:提取目标配置并筛选,确认Patch生效。

五、脚本完整源码(含精简注释)

bash 复制代码
#!/bin/bash
# patch-exist.sh - 先备份再兼容添加/追加volumes和volumeMounts,不覆盖原有配置
# 用法:bash patch-exist.sh <deployment-name>

# 检查参数
if [ -z "$1" ]; then
  echo "错误:请传入Deployment名称,例如:bash patch-exist.sh bus-server"
  exit 1
fi

DEPLOY_NAME=$1
NAMESPACE="your_namespace"
# 定义备份目录和备份文件名(含时间戳,避免覆盖)
BACKUP_DIR="./backup"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${DEPLOY_NAME}_backup_${TIMESTAMP}.yaml"

# 依赖检查
if ! command -v jq &> /dev/null; then
  echo "错误:未安装jq,请执行 yum install jq -y 安装"
  exit 1
fi

if ! command -v kubectl &> /dev/null; then
  echo "错误:未安装kubectl,请先配置K8s客户端"
  exit 1
fi

# -------------------------- 核心备份逻辑 --------------------------
echo "==== 开始备份Deployment配置 ===="
# 创建备份目录(不存在则创建)
mkdir -p "${BACKUP_DIR}"
# 备份Deployment完整配置到YAML文件
if kubectl get deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" -o yaml > "${BACKUP_FILE}"; then
  echo "备份成功!配置文件已保存至:${BACKUP_FILE}"
else
  echo "备份失败!请检查Deployment名称或K8s连接状态"
  exit 1  # 备份失败则终止脚本,避免误操作
fi

# -------------------------- 处理volumes --------------------------
echo -e "\n==== 处理volumes配置 ===="
# 判断volumes字段是否存在
VOLUMES_EXIST=$(kubectl get deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" -o json | jq -r '.spec.template.spec | has("volumes")')

if [ "${VOLUMES_EXIST}" = "false" ]; then
  # 字段不存在:直接创建volumes字段并添加目标卷(一步到位,无空数组)
  kubectl patch deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" \
    --type json \
    --patch '[
      {"op":"add","path":"/spec/template/spec/volumes","value":[
        {"name":"tongweb-lic","configMap":{"name":"tongweb-lic","items":[{"key":"license.dat","path":"license.dat"}],"defaultMode":420}}
      ]}
    ]'
  echo "volumes字段不存在,已直接创建并添加tongweb-lic卷"
else
  # 字段存在:追加卷到现有数组(保留原有配置)
  kubectl patch deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" \
    --type json \
    --patch '[
      {"op":"add","path":"/spec/template/spec/volumes/-","value":
        {"name":"tongweb-lic","configMap":{"name":"tongweb-lic","items":[{"key":"license.dat","path":"license.dat"}],"defaultMode":420}}
      }
    ]'
  echo "volumes字段已存在,已追加tongweb-lic卷(原有配置保留)"
fi

# -------------------------- 处理volumeMounts --------------------------
echo -e "\n==== 处理volumeMounts配置 ===="
# 判断volumeMounts字段是否存在
VOLUME_MOUNTS_EXIST=$(kubectl get deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" -o json | jq -r '.spec.template.spec.containers[0] | has("volumeMounts")')

if [ "${VOLUME_MOUNTS_EXIST}" = "false" ]; then
  # 字段不存在:直接创建volumeMounts字段并添加目标挂载(一步到位,无空数组)
  kubectl patch deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" \
    --type json \
    --patch '[
      {"op":"add","path":"/spec/template/spec/containers/0/volumeMounts","value":[
        {"name":"tongweb-lic","readOnly":true,"mountPath":"/app/config/lic/license.dat"}
      ]}
    ]'
  echo "volumeMounts字段不存在,已直接创建并添加tongweb-lic挂载"
else
  # 字段存在:追加挂载到现有数组(保留原有配置)
  kubectl patch deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" \
    --type json \
    --patch '[
      {"op":"add","path":"/spec/template/spec/containers/0/volumeMounts/-","value":
        {"name":"tongweb-lic","readOnly":true,"mountPath":"/app/config/lic/license.dat"}
      }
    ]'
  echo "volumeMounts字段已存在,已追加tongweb-lic挂载(原有配置保留)"
fi

# -------------------------- 验证结果 --------------------------
echo -e "\n==== 验证配置 ===="
echo "volumes配置:"
kubectl get deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" -o jsonpath='{.spec.template.spec.volumes}' | jq '.[] | select(.name=="tongweb-lic")'

echo -e "\nvolumeMounts配置:"
kubectl get deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" -o jsonpath='{.spec.template.spec.containers[0].volumeMounts}' | jq '.[] | select(.name=="tongweb-lic")'

echo -e "\n所有操作完成!备份文件路径:${BACKUP_FILE}"

源码说明:可修改NAMESPACE、卷名称、挂载路径适配需求,注释聚焦核心逻辑,便于快速使用。

相关推荐
Master_Azur2 小时前
java循环语句
后端
凌览2 小时前
充值成功,腾讯成为OpenClaw官方赞肋商
前端·javascript·后端
J2虾虾3 小时前
SpringBoot 中给 @Autowired 搭配 @Lazy
java·spring boot·后端
Bright Data3 小时前
Pinterest 数据集示例
后端·python·flask
小江的记录本3 小时前
【HTTP】HTTP请求方法与状态码(全体系知识总结+附表格)
前端·网络·后端·网络协议·http·状态模式·web
掘金者阿豪4 小时前
小爱音箱秒变智能搭子!MiGPT GUI+cpolar,远程操控超省心
后端
Java编程爱好者4 小时前
Java面试高频场景题:在工作中或者一些组件源码里面或多或少会用到锁,你能整理概括下锁的分类么?
后端
sheji34164 小时前
【开题答辩全过程】以 基于springboot的健身预约系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
文心快码BaiduComate4 小时前
Comate 3月全新升级:全新Plan模式、Explore Subagent深度检索能力增强
前端·后端·程序员