k8s.io/client-go@v0.31.1/examples/create-update-delete-deployment/main.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  // Note: the example only works with the code within the same release/branch.
    18  package main
    19  
    20  import (
    21  	"bufio"
    22  	"context"
    23  	"flag"
    24  	"fmt"
    25  	"os"
    26  	"path/filepath"
    27  
    28  	appsv1 "k8s.io/api/apps/v1"
    29  	apiv1 "k8s.io/api/core/v1"
    30  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    31  	"k8s.io/client-go/kubernetes"
    32  	"k8s.io/client-go/tools/clientcmd"
    33  	"k8s.io/client-go/util/homedir"
    34  	"k8s.io/client-go/util/retry"
    35  	//
    36  	// Uncomment to load all auth plugins
    37  	// _ "k8s.io/client-go/plugin/pkg/client/auth"
    38  	//
    39  	// Or uncomment to load specific auth plugins
    40  	// _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
    41  	// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
    42  	// _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
    43  )
    44  
    45  func main() {
    46  	var kubeconfig *string
    47  	if home := homedir.HomeDir(); home != "" {
    48  		kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
    49  	} else {
    50  		kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
    51  	}
    52  	flag.Parse()
    53  
    54  	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    55  	if err != nil {
    56  		panic(err)
    57  	}
    58  	clientset, err := kubernetes.NewForConfig(config)
    59  	if err != nil {
    60  		panic(err)
    61  	}
    62  
    63  	deploymentsClient := clientset.AppsV1().Deployments(apiv1.NamespaceDefault)
    64  
    65  	deployment := &appsv1.Deployment{
    66  		ObjectMeta: metav1.ObjectMeta{
    67  			Name: "demo-deployment",
    68  		},
    69  		Spec: appsv1.DeploymentSpec{
    70  			Replicas: int32Ptr(2),
    71  			Selector: &metav1.LabelSelector{
    72  				MatchLabels: map[string]string{
    73  					"app": "demo",
    74  				},
    75  			},
    76  			Template: apiv1.PodTemplateSpec{
    77  				ObjectMeta: metav1.ObjectMeta{
    78  					Labels: map[string]string{
    79  						"app": "demo",
    80  					},
    81  				},
    82  				Spec: apiv1.PodSpec{
    83  					Containers: []apiv1.Container{
    84  						{
    85  							Name:  "web",
    86  							Image: "nginx:1.12",
    87  							Ports: []apiv1.ContainerPort{
    88  								{
    89  									Name:          "http",
    90  									Protocol:      apiv1.ProtocolTCP,
    91  									ContainerPort: 80,
    92  								},
    93  							},
    94  						},
    95  					},
    96  				},
    97  			},
    98  		},
    99  	}
   100  
   101  	// Create Deployment
   102  	fmt.Println("Creating deployment...")
   103  	result, err := deploymentsClient.Create(context.TODO(), deployment, metav1.CreateOptions{})
   104  	if err != nil {
   105  		panic(err)
   106  	}
   107  	fmt.Printf("Created deployment %q.\n", result.GetObjectMeta().GetName())
   108  
   109  	// Update Deployment
   110  	prompt()
   111  	fmt.Println("Updating deployment...")
   112  	//    You have two options to Update() this Deployment:
   113  	//
   114  	//    1. Modify the "deployment" variable and call: Update(deployment).
   115  	//       This works like the "kubectl replace" command and it overwrites/loses changes
   116  	//       made by other clients between you Create() and Update() the object.
   117  	//    2. Modify the "result" returned by Get() and retry Update(result) until
   118  	//       you no longer get a conflict error. This way, you can preserve changes made
   119  	//       by other clients between Create() and Update(). This is implemented below
   120  	//			 using the retry utility package included with client-go. (RECOMMENDED)
   121  	//
   122  	// More Info:
   123  	// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
   124  
   125  	retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
   126  		// Retrieve the latest version of Deployment before attempting update
   127  		// RetryOnConflict uses exponential backoff to avoid exhausting the apiserver
   128  		result, getErr := deploymentsClient.Get(context.TODO(), "demo-deployment", metav1.GetOptions{})
   129  		if getErr != nil {
   130  			panic(fmt.Errorf("Failed to get latest version of Deployment: %v", getErr))
   131  		}
   132  
   133  		result.Spec.Replicas = int32Ptr(1)                           // reduce replica count
   134  		result.Spec.Template.Spec.Containers[0].Image = "nginx:1.13" // change nginx version
   135  		_, updateErr := deploymentsClient.Update(context.TODO(), result, metav1.UpdateOptions{})
   136  		return updateErr
   137  	})
   138  	if retryErr != nil {
   139  		panic(fmt.Errorf("Update failed: %v", retryErr))
   140  	}
   141  	fmt.Println("Updated deployment...")
   142  
   143  	// List Deployments
   144  	prompt()
   145  	fmt.Printf("Listing deployments in namespace %q:\n", apiv1.NamespaceDefault)
   146  	list, err := deploymentsClient.List(context.TODO(), metav1.ListOptions{})
   147  	if err != nil {
   148  		panic(err)
   149  	}
   150  	for _, d := range list.Items {
   151  		fmt.Printf(" * %s (%d replicas)\n", d.Name, *d.Spec.Replicas)
   152  	}
   153  
   154  	// Delete Deployment
   155  	prompt()
   156  	fmt.Println("Deleting deployment...")
   157  	deletePolicy := metav1.DeletePropagationForeground
   158  	if err := deploymentsClient.Delete(context.TODO(), "demo-deployment", metav1.DeleteOptions{
   159  		PropagationPolicy: &deletePolicy,
   160  	}); err != nil {
   161  		panic(err)
   162  	}
   163  	fmt.Println("Deleted deployment.")
   164  }
   165  
   166  func prompt() {
   167  	fmt.Printf("-> Press Return key to continue.")
   168  	scanner := bufio.NewScanner(os.Stdin)
   169  	for scanner.Scan() {
   170  		break
   171  	}
   172  	if err := scanner.Err(); err != nil {
   173  		panic(err)
   174  	}
   175  	fmt.Println()
   176  }
   177  
   178  func int32Ptr(i int32) *int32 { return &i }