背景:

紧接client-go连接kubernetes集群-connect and listclient-go连接kubernetes集群-create相关操作。实例都是拿namespacedeployment两个为代表进行展开延伸的(个人环境中deployment还是具有代表性的),前面创建了namespace deployment,正常的流程下一步就是修改namespace and deployment 了!

client-go连接kubernetes集群-update相关操作

1. namespace的update

参照create
image.png
先看一眼&corev1.Namespace metav1.ObjectMeta中都有哪些配置可以修改,metav1.ObjectMeta{}填充一下所有字段:
image.png
Name还是默认的zhangpeng namespace了,我添加一个labels?
image.png
image.png
image.png
main.go

  1. package main
  2. import (
  3. "context"
  4. "flag"
  5. "fmt"
  6. corev1 "k8s.io/api/core/v1"
  7. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  8. "k8s.io/client-go/kubernetes"
  9. "k8s.io/client-go/tools/clientcmd"
  10. "k8s.io/client-go/util/homedir"
  11. "path/filepath"
  12. )
  13. func main() {
  14. var kubeconfig *string
  15. if home := homedir.HomeDir(); home != "" {
  16. kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
  17. } else {
  18. kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
  19. }
  20. flag.Parse()
  21. config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
  22. if err != nil {
  23. panic(err.Error())
  24. }
  25. // create the clientset
  26. clientset, err := kubernetes.NewForConfig(config)
  27. if err != nil {
  28. panic(err.Error())
  29. }
  30. namespace := &corev1.Namespace{
  31. ObjectMeta: metav1.ObjectMeta{
  32. Name: "zhangpeng",
  33. GenerateName: "",
  34. Namespace: "",
  35. SelfLink: "",
  36. UID: "",
  37. ResourceVersion: "",
  38. Generation: 0,
  39. CreationTimestamp: metav1.Time{},
  40. DeletionTimestamp: nil,
  41. DeletionGracePeriodSeconds: nil,
  42. Labels: map[string]string{
  43. "dev": "test",
  44. },
  45. Annotations: nil,
  46. OwnerReferences: nil,
  47. Finalizers: nil,
  48. ClusterName: "",
  49. ManagedFields: nil,
  50. },
  51. }
  52. result, _ := clientset.CoreV1().Namespaces().Update(context.TODO(), namespace, metav1.UpdateOptions{})
  53. fmt.Println(result)
  54. }

运行main.go
image.png
image.png
登录某云后台确认生成label!这里正好看到了自愿配额与限制?正巧最近在看文章的时候看到一个这样的例子:基于client-go操作namespace资源配额设计

2. 扩展一下resourcequotas

main.go

package main

import (
    "context"
    "flag"
    "fmt"
    corev1 "k8s.io/api/core/v1"
    "k8s.io/apimachinery/pkg/api/resource"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/homedir"
    "path/filepath"
)

func main() {
    var kubeconfig *string
    if home := homedir.HomeDir(); home != "" {
        kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
    } else {
        kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
    }
    flag.Parse()
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    if err != nil {
        panic(err.Error())
    }

    // create the clientset
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err.Error())
    }
    namespace := &corev1.Namespace{
        ObjectMeta: metav1.ObjectMeta{
            Name:                       "zhangpeng",
            GenerateName:               "",
            Namespace:                  "",
            SelfLink:                   "",
            UID:                        "",
            ResourceVersion:            "",
            Generation:                 0,
            CreationTimestamp:          metav1.Time{},
            DeletionTimestamp:          nil,
            DeletionGracePeriodSeconds: nil,
            Labels: map[string]string{
                "dev": "test",
            },
            Annotations:     nil,
            OwnerReferences: nil,
            Finalizers:      nil,
            ClusterName:     "",
            ManagedFields:   nil,
        },
    }
    result, _ := clientset.CoreV1().Namespaces().Update(context.TODO(), namespace, metav1.UpdateOptions{})
    fmt.Println(result)
    quotaTest := clientset.CoreV1().ResourceQuotas("zhangpeng")
    quota := &corev1.ResourceQuota{
        ObjectMeta: metav1.ObjectMeta{
            Name: "quota-namespace",
        },
        Spec: corev1.ResourceQuotaSpec{
            Hard: map[corev1.ResourceName]resource.Quantity{
                corev1.ResourceLimitsCPU:      resource.MustParse("200m"),
                corev1.ResourceLimitsMemory:   resource.MustParse("200M"),
                corev1.ResourceRequestsCPU:    resource.MustParse("1000m"),
                corev1.ResourceRequestsMemory: resource.MustParse("1Gi"),
            },
        },
    }

    result1, err := quotaTest.Create(context.TODO(), quota, metav1.CreateOptions{})
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(result1)
    }
}

image.png

kubectl get resourcequotas -n zhangpeng

image.png

3. update deployment

参照:client-go连接kubernetes集群-create相关操作生成yaml读取文件流的方式
修改nginx镜像tag为1.16
src/yamls/nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
        - image: nginx:1.16
          name: nginx
          resources: {}
status: {}

image.png
现在如果直接运行肯定是already exists的!
image.png
修改main.go如下:

package main

import (
    "context"
    "encoding/json"
    "flag"
    "fmt"
    "io/ioutil"
    v1 "k8s.io/api/apps/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/util/yaml"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/homedir"
    "path/filepath"
)

func main() {
    var kubeconfig *string
    if home := homedir.HomeDir(); home != "" {
        kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
    } else {
        kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
    }
    flag.Parse()
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    if err != nil {
        panic(err.Error())
    }

    // create the clientset
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err.Error())
    }
    b, err := ioutil.ReadFile("src/yamls/nginx.yaml")
    nginxDep := &v1.Deployment{}
    nginxJson, _ := yaml.ToJSON(b)
    if err = json.Unmarshal(nginxJson, nginxDep); err != nil {
        return
    }
    if _, err = clientset.AppsV1().Deployments("zhangpeng").Update(context.Background(), nginxDep, metav1.UpdateOptions{}); err != nil {
        fmt.Println(err)
        return
    }
}

运行main.go
image.png

kubectl get deployments -n zhangpeng -o yaml

image.png

强调:

  1. context.Background() context.TODO()还是有点懵 分不清什么时候用……
  2. 执行结果的返回没有一致格式化输出,以及一下错误的处理?