k8s中设置annotation的方法总结

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 service

import (
	"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 {

	// 获取 clientSet
	myClientSet := 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.")
	}

	// 符号 ~ 需要转换为 ~0
	if strings.Contains(key, "~") {
		key = strings.Replace(key, "~", "~0", -1)
	}
	if strings.Contains(key, "/") {
		// 符号 / 需要转换为 ~1
		key = strings.Replace(key, "/", "~1", -1)
	}
	// 需要修改的 annotation 的键值对
	patchObj := struct {
		Op    string      `json:"op"`
		Path  string      `json:"path"`
		Value interface{} `json:"value"`
	}{
		Op:    "replace", // 可以使用add 或 replace
		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

}

// 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 {

	// 获取 clientSet
	myClientSet := 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
	}

	// 符号 ~ 需要转换为 ~0
	if strings.Contains(key, "~") {
		key = strings.Replace(key, "~", "~0", -1)
	}
	// 符号 / 需要转换为 ~1
	if 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 service

import (
	"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中文文档

Kubernetesk8s)中,Annotation(注解)是一种用于存储与对象相关的非标识性信息的机制。它们以键值对的形式定义,并且可以用于描述和记录对象的元数据信息,如版本、作者、创建时间等。与Label不同,Annotation没有严格的命名规范,并且不用于Label Selector。Annotation的主要作用是提供额外的信息,以便于用户或工具对对象进行更详细的描述和管理。例如,可以使用Annotation来记录对象的配置信息、监控指标、审计日志等。通过使用Annotation,用户可以自定义和扩展Kubernetes对象的元数据,以满足特定的需求。 #### 引用[.reference_title] - *1* *3* [带你玩转kubernetes-k8s(第八篇:k8s-Persisten Volume、Namespace、Annotation、ConfigMap概念及其实例)](https://blog.csdn.net/qq_31136839/article/details/94762459)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [确定 k8sAnnotation 与 Labels 你用对了?](https://blog.csdn.net/wan212000/article/details/127550634)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SRExianxian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值