[k8s源码]2.CURD deployment

加载kubernetes配置

使用 clientcmd方法,是通过"k8s.io/client-go/tools/clientcmd"包加载的。这个函数返回的是config和error两个值。可以看到返回的config是一个指针变量。

func clientcmd.BuildConfigFromFlags(masterUrl string, kubeconfigPath string) (*rest.Config, error)

config,err := clientcmd.BuildConfigFromFlags("", "C:/Users/gx/.kube/config")
if err != nil {
  panic(err.Error())}
创建kubernetes客户端

func kubernetes.NewForConfig(c *rest.Config) (*kubernetes.Clientset, error)

这里的err被重新赋值,而传入的config是一个指针变量。

deployment 是一个appsv1变量,因此使用appsv1 方法来获取用于与 Kubernetes AppsV1 API 交互的客户端。这样可以轻松地对 Kubernetes 中的 Apps 资源(如 Deployment、StatefulSet 等)进行操作。

clientset, err := clientset.NewForConfig(config) 
if err != nil {
 panic(err.Error())
}
deploymentClientset := clientset.AppsV1().Deployments(apiv1.NamespaceDefault)
编写要创建的deployment 

指针允许不同的结构体实例共享相同的数据。在Kubernetes中,多个Pod可能需要共享相同的标签选择器配置。通过指针可以实现这一点。所以这里的deployment和LabelSelector是指针。这里的container和port是切片类型的数据。

deployment := &appsv1.Deployment{
  ObjectMeta: metav1.ObjectMeta{
    Name: "demo-deployment",},
  Spec: appsv1:DeploymentSpec{
    Replicas: 3,
    Selector: &metav1.LabelSelector{
      MatchLabels: map[string]string{
         "app": "demo",}
        },
     },
     Template: apiv1.PodTemplateSpec{
       ObjectMeta: metav1.ObjectMeta{
          Labels: map[string]string{
            "app":"demo",}
            },
     },
        spec: apiv1.PodSpec{
          Containers:[]apiv1.Container{
            {
               Name: "web",
               Image: "nginx:1.12",
               Ports: []apiv1.ContainerPort{
                    {
                       Name: "http",
                       Protocol: apiv1.ProtocolTCP,
                       ContainerPort: 80,}
                  },
                },
              },
          },
      },
   },
}

另一种编写方式,更加简洁,但是可能存在安全性和规范性的问题

deployment := &unstructured.Unstructured{
    Object: map[string]interface{}{
        "apiVersion": "apps/v1",
        "kind":       "Deployment",
        "metadata": map[string]interface{}{
            "name": "demo-deployment",
        },
        "spec": map[string]interface{}{
            "replicas": 2,
            "selector": map[string]interface{}{
                "matchLabels": map[string]interface{}{
                    "app": "demo",
                },
            },
            "template": map[string]interface{}{
                "metadata": map[string]interface{}{
                    "labels": map[string]interface{}{
                        "app": "demo",
                    },
                },
                "spec": map[string]interface{}{
                    "containers": []map[string]interface{}{
                        {
                            "name":  "web",
                            "image": "nginx:1.12",
                            "ports": []map[string]interface{}{
                                {
                                    "name":          "http",
                                    "protocol":      "TCP",
                                    "containerPort": 80,
                                },
                            },
                        },
                    },
                },
            },
        },
    },
}
 创建deployment

func (v1.DeploymentInterface) Create(ctx context.Context, deployment *appsv1.Deployment, opts metav1.CreateOptions) (*appsv1.Deployment, error)

在 Go 语言中,context.TODO() 是 context 包中的一个函数调用,它返回一个空的 Context 对象。Context 在 Go 中用于控制并发时的取消操作、超时控制、截止时间等,可以有效地管理并传递请求范围的值。context.TODO() 表示一个“空”的 Context,通常用作临时占位符或者当你尚未确定使用哪种具体的 Context 类型时的默认选择。

metav1.CreateOptions{} 是用于在创建资源时传递额外选项的结构体。可以通过metav1.CreateOptions{} 提供一些创建过程中需要的配置信息,例如:

  1. DryRun: 设置为 true 可以模拟创建操作,而不会实际创建资源。
  2. FieldManager: 设置创建资源的管理者的名称,用于标识谁在进行这次创建操作。
  3. Labels: 设置资源的标签,用于对资源进行分类和组织。
  4. PropagationPolicy: 设置删除资源时的传播策略,影响关联资源的删除行为。
createOptions := metav1.CreateOptions{
    DryRun:       []string{"All"}, // 模拟创建,不实际创建资源
    FieldManager: "my-controller", // 设置创建资源的管理者
    Labels: map[string]string{
        "app": "demo",
    },
    // 可以根据需要添加其他选项
}

deploymentsClient.Create(context.TODO(), deployment, createOptions)

具体在我们的代码里面,用以下命令创建deployment

result, err := deploymentsClient.Create(context.TODO(), deployment, metav1.CreateOptions{})
	if err != nil {
		panic(err)
	}
	fmt.Printf("Created deployment %q.\n", result.GetObjectMeta().GetName())
更新deployment

retry.RetryOnConflict 函数是一个用于处理在更新资源时可能遇到的冲突的函数。在更新资源时,可能会因为多个并发请求同时修改资源而产生冲突。RetryOnConflict 函数会帮助你处理这种情况,使用指数退避策略(exponential backoff)来避免频繁地向 API 服务器发送请求,从而减少对 API 服务器的负载和提高更新成功的几率。

func retry.RetryOnConflict(backoff wait.Backoff, fn func() error) error

func (v1.DeploymentInterface) Update(ctx context.Context, deployment *appsv1.Deployment, opts metav1.UpdateOptions) (*appsv1.Deployment, error)

retry这个函数来源于包:"k8s.io/client-go/util/retry"

retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
		// Retrieve the latest version of Deployment before attempting update
		// RetryOnConflict uses exponential backoff to avoid exhausting the apiserver
		result, getErr := deploymentsClient.Get(context.TODO(), "demo-deployment", metav1.GetOptions{})
		if getErr != nil {
			panic(fmt.Errorf("Failed to get latest version of Deployment: %v", getErr))
		}

		result.Spec.Replicas = int32Ptr(1)                           // reduce replica count
		result.Spec.Template.Spec.Containers[0].Image = "nginx:1.13" // change nginx version
		_, updateErr := deploymentsClient.Update(context.TODO(), result, metav1.UpdateOptions{})
		return updateErr
	})
	if retryErr != nil {
		panic(fmt.Errorf("Update failed: %v", retryErr))
	}
	fmt.Println("Updated deployment...")
 列举deployments
fmt.Printf("Listing deployments in namespace %q:\n", apiv1.NamespaceDefault)
	list, err := deploymentsClient.List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		panic(err)
	}
	for _, d := range list.Items {
		fmt.Printf(" * %s (%d replicas)\n", d.Name, *d.Spec.Replicas)
	}
删除deployment
deletePolicy := metav1.DeletePropagationForeground
	if err := deploymentsClient.Delete(context.TODO(), "demo-deployment", metav1.DeleteOptions{
		PropagationPolicy: &deletePolicy,
	}); err != nil {
		panic(err)
	}
	fmt.Println("Deleted deployment.")
}

相关推荐

  1. [k8s]2.CURD deployment

    2024-07-15 12:56:04       23 阅读
  2. [k8s]6.reflector

    2024-07-15 12:56:04       14 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-15 12:56:04       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-15 12:56:04       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-15 12:56:04       57 阅读
  4. Python语言-面向对象

    2024-07-15 12:56:04       68 阅读

热门阅读

  1. 善的忽视、恶的纵容

    2024-07-15 12:56:04       23 阅读
  2. qt 拖拽矩形开发

    2024-07-15 12:56:04       17 阅读
  3. Unity与Unreal Engine:AR建筑应用开发之选

    2024-07-15 12:56:04       21 阅读
  4. React组件的解耦小技巧

    2024-07-15 12:56:04       16 阅读
  5. 2024,小鹏汽车穿越火线

    2024-07-15 12:56:04       25 阅读
  6. 【qt】有点意思的信号与槽

    2024-07-15 12:56:04       23 阅读
  7. ArcGIS Pro SDK (八)地理数据库 8 拓扑

    2024-07-15 12:56:04       20 阅读
  8. ArcGIS Pro SDK (九)几何 3 点

    2024-07-15 12:56:04       19 阅读
  9. 服务器主板开发阶段以及测试重点

    2024-07-15 12:56:04       24 阅读
  10. Linux:解决vim打开文件默认为replace模式

    2024-07-15 12:56:04       20 阅读
  11. mysql中的if语句:case when

    2024-07-15 12:56:04       24 阅读
  12. Linux使用systemctl添加自启动程序实现步骤

    2024-07-15 12:56:04       22 阅读