k8s中设置annotation的方法总结

news/2024/12/14 9:33:44/

k8s中设置annotation的方法总结

annotation是什么

在 Kubernetes 中,Annotations 是一种用于向 Kubernetes 对象附加非标识性元数据的机制。

annotation有什么用

annotation与 Labels 类似,但有一些关键区别和特定用途。 常用于存储与对象相关的配置信息、工具信息、元数据等,但这些信息不会影响 Kubernetes 对象的调度或生命周期管理。

注意相比labels来说, annotation具有不可见性: Annotations 不会被 Kubernetes API 用于选择或路由对象,因此不会影响调度决策或资源管理。

annotation的设置方式

我们可以为常见的资源种类,pod、pvc、pv、deployment、statefulset等设置annotation.

对于 annotation 的操作,只有3种:增加、删除、更新。(如果需要查看可以kubectl get pod -oyaml方式从详细信息中过滤)

方式一:kubectl annotate命令

# 为pod设置一个新的 annotation
root@dg02-k8s-pnode1:~# kubectl annotate pod ubuntu1604 it/city="shenzhen"
pod/ubuntu1604 annotated# 为pod修改存在的 annotation 对应的key/value
root@dg02-k8s-pnode1:~# kubectl annotate pod ubuntu1604 it/city="shanghai" --overwrite
pod/ubuntu1604 annotated# 删除 annotation 对应的key/value
root@dg02-k8s-pnode1:~# kubectl annotate pod ubuntu1604 it/city-
pod/ubuntu1604 annotated

方式二: kubectl patch命令

这里需要注意,在patch时,对于json串中的~,/需要分别转义为~0~1

# 增
kubectl patch pod --type=json -p='[{"op": "add", "path": "/metadata/annotations/it~1city", "value": "shenzhen"}]' ubuntu1604
# 改
kubectl patch pod --type=json -p='[{"op": "replace", "path": "/metadata/annotations/it~1city", "value": "shanghai"}]' ubuntu1604
# 删
kubectl patch pod --type=json -p='[{"op": "remove", "path": "/metadata/annotations/it~1city", "value": ""}]' ubuntu1604

方式三: client-go

除了前2种使用kubectl命令的方式,开发人员通常使用client-go对资源操控annotation

使用Patch方式更新K8S的 API Objects 一共有三种方式:strategic merge patch, json-patch,json merge patch。本文介绍最常用的json-patch,其他2种方式,请参考其他文献

本次示例以给一个pod新增一个annotation为例,直接上代码:

package serviceimport ("encoding/json""fmt""github.com/pkg/errors""go.uber.org/zap"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/apimachinery/pkg/types""kubecmdb/internal/buildk8s""kubecmdb/utils""strings"
)// AnnotationReplace 更新pod的annotation
func AnnotationReplace(clusterName, namespace, name, key string, value interface{}) error {// 获取 clientSetmyClientSet := buildk8s.GetK8SClientSet(clusterName)// 判断 pod 是否存在_, err := myClientSet.CoreV1().Pods(namespace).Get(name, metav1.GetOptions{})if err != nil {utils.Error("[annotation]", zap.String("err", err.Error()))return errors.Wrapf(err, "AnnotationAdd pod get err.")}// 符号 ~ 需要转换为 ~0if strings.Contains(key, "~") {key = strings.Replace(key, "~", "~0", -1)}if strings.Contains(key, "/") {// 符号 / 需要转换为 ~1key = strings.Replace(key, "/", "~1", -1)}// 需要修改的 annotation 的键值对patchObj := struct {Op    string      `json:"op"`Path  string      `json:"path"`Value interface{} `json:"value"`}{Op:    "replace", // 可以使用add 或 replacePath:  "/metadata/annotations/" + key,Value: value,}// 转换为json串var patchObjs []interface{}patchObjs = append(patchObjs, patchObj)patchData, err := json.Marshal(patchObjs)if err != nil {utils.Error("[annotation]", zap.String("err", err.Error()))return errors.Wrapf(err, "AnnotationAdd Marshal err.")}// 使用 Patch 方法修改//patchData:=fmt.Sprintf("'[{\"op\": \"replace\", \"path\": \"/metadata/annotations/it~1domain\", \"value\": \"xxx\"}]'")fmt.Printf("patchData=%v\n", string(patchData))_, err = myClientSet.CoreV1().Pods(namespace).Patch(name, types.JSONPatchType, patchData)if err != nil {utils.Error("[annotation]", zap.String("err", err.Error()))return errors.Wrapf(err, "AnnotationAdd Patch err.")}return nil}// AnnotationAdd 添加pod的annotation
func AnnotationAdd(clusterName, namespace, name, key string,value interface{}) error {return AnnotationReplace(clusterName, namespace, name, key, value)
}// AnnotationRemove 删除pod的annotation
func AnnotationRemove(clusterName, namespace, name, key string) error {// 获取 clientSetmyClientSet := buildk8s.GetK8SClientSet(clusterName)pod, err := myClientSet.CoreV1().Pods(namespace).Get(name, metav1.GetOptions{})if err != nil {utils.Error("[annotation]", zap.String("err", err.Error()))return errors.Wrapf(err, "AnnotationAdd pod get err.")}// 如果不存在,返回操作成功if _,ok := pod.ObjectMeta.Annotations[key];!ok {return nil}// 符号 ~ 需要转换为 ~0if strings.Contains(key, "~") {key = strings.Replace(key, "~", "~0", -1)}// 符号 / 需要转换为 ~1if strings.Contains(key, "/") {key = strings.Replace(key, "/", "~1", -1)}// 需要修改的 annotation 的键值对patchObj := struct {Op    string      `json:"op"`Path  string      `json:"path"`Value interface{} `json:"value"`}{Op:    "remove",Path:  "/metadata/annotations/" + key,Value: "", // 不需要填 value}// 转换为json串var patchObjs []interface{}patchObjs = append(patchObjs, patchObj)patchData, err := json.Marshal(patchObjs)if err != nil {utils.Error("[annotation]", zap.String("err", err.Error()))return errors.Wrapf(err, "AnnotationAdd Marshal err.")}// 使用 Patch 方法修改//patchData:=fmt.Sprintf("'[{\"op\": \"replace\", \"path\": \"/metadata/annotations/it~1domain\", \"value\": \"xxx\"}]'")fmt.Printf("patchData=%v\n", string(patchData))_, err = myClientSet.CoreV1().Pods(namespace).Patch(name, types.JSONPatchType, patchData)if err != nil {utils.Error("[annotation]", zap.String("err", err.Error()))return errors.Wrapf(err, "AnnotationAdd Patch err.")}return nil
}

单元测试


package serviceimport ("testing"
)// 更改
// go test -run "^TestAnnotationReplace$" -v
func TestAnnotationReplace(t *testing.T) {err := AnnotationReplace("dg11test", "public", "ubuntu1604", "it/city", "shanghai")if err != nil {t.Fatal(err)}
}// 添加
// go test -run "^TestAnnotationAdd$" -v
func TestAnnotationAdd(t *testing.T) {err := AnnotationAdd("dg11test", "public", "ubuntu1604", "it/city", "shenzhen")if err != nil {t.Fatal(err)}
}//删除
// go test -run "^TestAnnotationRemove$" -v
func TestAnnotationRemove(t *testing.T) {err := AnnotationRemove("dg11test", "public", "ubuntu1604", "it/city", )if err != nil {t.Fatal(err)}
}

参考文献

K8S client-go Patch example
kuberntes中文文档


http://www.ppmy.cn/news/1554984.html

相关文章

【Hexo】给博客添加宠物挂件

适配安知鱼主题和Solitude主题,我采用的是安知鱼主题,Solitude主题可参考教程 {% link 给你的博客底部添加一排宠物,青桔气球,https://blog.qjqq.cn/posts/f69c.html %} 同时感谢梦爱吃鱼 大佬的耐心指导和帮助,原文可参考 {% link 给你的…

用于日语词汇学习的微信小程序+ssm

日语词汇学习小程序是高校人才培养计划的重要组成部分,是实现人才培养目标、培养学生科研能力与创新思维、检验学生综合素质与实践能力的重要手段与综合性实践教学环节。本学生所在学院多采用半手工管理日语词汇学习小程序的方式,所以有必要开发日语词汇…

单元测试中如何使用 Mockito 框架

使用 Mockito 进行单元测试的基本框架可以分为几个步骤。Mockito 是一个强大的 Java 框架,用于创建模拟对象(mock objects),可以在不依赖外部系统或组件的情况下测试代码。以下是使用 Mockito 架构进行单元测试的通用步骤&#xf…

前端页面导出word

html-docx-js bug: vite使用html-docx.js会报错&#xff0c;点击下载上方文件替换即可 正文 npm install html-docx-js -S npm install file-saver -S<template><div id"managerReport">word内容......</div> </template><script>&l…

边界层气象:脉动量预报方程展开 | 湍流脉动速度方差预报方程 | 平均湍流动能收支方程推导

写成分量形式 原始式子&#xff1a; ∂ u i ′ ∂ t u ‾ j ∂ u i ′ ∂ x j u j ′ ∂ u ‾ i ∂ x j u j ′ ∂ u i ′ ∂ x j − 1 ρ ‾ ⋅ ∂ p ′ ∂ x i g θ v ′ θ ‾ v δ i 3 f ϵ i j 3 u j ′ v ∂ 2 u i ′ ∂ x j 2 ∂ ( u i ′ u j ′ ‾ ) ∂ x j…

satoken 后端获取用户id的原理是啥 用了前端传的那个参数

在 Sa-Token 框架中&#xff0c;后端获取用户 ID 的过程与前端传递的参数密切相关。Sa-Token 是一个基于 JWT 的轻量级权限管理框架&#xff0c;主要用于解决权限控制、登录管理等问题。具体来说&#xff0c;后端如何获取用户 ID&#xff0c;取决于你前后端如何设计以及 Sa-Tok…

vue项目通过appendChild()函数向页面上追加组件

前言&#xff1a; 此篇文章自己结合项目和文档自己理解的&#xff0c;作用于往后遇见此类开发需求时参考。 正文&#xff1a; 1、createApp() 创建一个应用程序实例 function createApp(rootComponent: Component, rootProps?: object): App 第一个参数是根组件。第二个可选…

Scratch节日作品 | 圣诞节礼物——体验节日的温馨与编程的乐趣! ❄️

今天为大家推荐一款充满节日氛围的Scratch作品——《圣诞礼物》&#xff01;这款程序不仅带来了雪花飘落、圣诞老人和麋鹿的经典场景&#xff0c;还通过编程的形式让小朋友们体验到收到礼物的喜悦。通过这款游戏&#xff0c;小朋友们能学习编程知识、了解圣诞文化&#xff0c;同…