k8s.io/client-go@v0.22.2/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  	// _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
    44  )
    45  
    46  func main() {
    47  	var kubeconfig *string
    48  	if home := homedir.HomeDir(); home != "" {
    49  		kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
    50  	} else {
    51  		kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
    52  	}
    53  	flag.Parse()
    54  
    55  	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    56  	if err != nil {
    57  		panic(err)
    58  	}
    59  	clientset, err := kubernetes.NewForConfig(config)
    60  	if err != nil {
    61  		panic(err)
    62  	}
    63  
    64  	deploymentsClient := clientset.AppsV1().Deployments(apiv1.NamespaceDefault)
    65  
    66  	deployment := &appsv1.Deployment{
    67  		ObjectMeta: metav1.ObjectMeta{
    68  			Name: "demo-deployment",
    69  		},
    70  		Spec: appsv1.DeploymentSpec{
    71  			Replicas: int32Ptr(2),
    72  			Selector: &metav1.LabelSelector{
    73  				MatchLabels: map[string]string{
    74  					"app": "demo",
    75  				},
    76  			},
    77  			Template: apiv1.PodTemplateSpec{
    78  				ObjectMeta: metav1.ObjectMeta{
    79  					Labels: map[string]string{
    80  						"app": "demo",
    81  					},
    82  				},
    83  				Spec: apiv1.PodSpec{
    84  					Containers: []apiv1.Container{
    85  						{
    86  							Name:  "web",
    87  							Image: "nginx:1.12",
    88  							Ports: []apiv1.ContainerPort{
    89  								{
    90  									Name:          "http",
    91  									Protocol:      apiv1.ProtocolTCP,
    92  									ContainerPort: 80,
    93  								},
    94  							},
    95  						},
    96  					},
    97  				},
    98  			},
    99  		},
   100  	}
   101  
   102  	// Create Deployment
   103  	fmt.Println("Creating deployment...")
   104  	result, err := deploymentsClient.Create(context.TODO(), deployment, metav1.CreateOptions{})
   105  	if err != nil {
   106  		panic(err)
   107  	}
   108  	fmt.Printf("Created deployment %q.\n", result.GetObjectMeta().GetName())
   109  
   110  	// Update Deployment
   111  	prompt()
   112  	fmt.Println("Updating deployment...")
   113  	//    You have two options to Update() this Deployment:
   114  	//
   115  	//    1. Modify the "deployment" variable and call: Update(deployment).
   116  	//       This works like the "kubectl replace" command and it overwrites/loses changes
   117  	//       made by other clients between you Create() and Update() the object.
   118  	//    2. Modify the "result" returned by Get() and retry Update(result) until
   119  	//       you no longer get a conflict error. This way, you can preserve changes made
   120  	//       by other clients between Create() and Update(). This is implemented below
   121  	//			 using the retry utility package included with client-go. (RECOMMENDED)
   122  	//
   123  	// More Info:
   124  	// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
   125  
   126  	retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
   127  		// Retrieve the latest version of Deployment before attempting update
   128  		// RetryOnConflict uses exponential backoff to avoid exhausting the apiserver
   129  		result, getErr := deploymentsClient.Get(context.TODO(), "demo-deployment", metav1.GetOptions{})
   130  		if getErr != nil {
   131  			panic(fmt.Errorf("Failed to get latest version of Deployment: %v", getErr))
   132  		}
   133  
   134  		result.Spec.Replicas = int32Ptr(1)                           // reduce replica count
   135  		result.Spec.Template.Spec.Containers[0].Image = "nginx:1.13" // change nginx version
   136  		_, updateErr := deploymentsClient.Update(context.TODO(), result, metav1.UpdateOptions{})
   137  		return updateErr
   138  	})
   139  	if retryErr != nil {
   140  		panic(fmt.Errorf("Update failed: %v", retryErr))
   141  	}
   142  	fmt.Println("Updated deployment...")
   143  
   144  	// List Deployments
   145  	prompt()
   146  	fmt.Printf("Listing deployments in namespace %q:\n", apiv1.NamespaceDefault)
   147  	list, err := deploymentsClient.List(context.TODO(), metav1.ListOptions{})
   148  	if err != nil {
   149  		panic(err)
   150  	}
   151  	for _, d := range list.Items {
   152  		fmt.Printf(" * %s (%d replicas)\n", d.Name, *d.Spec.Replicas)
   153  	}
   154  
   155  	// Delete Deployment
   156  	prompt()
   157  	fmt.Println("Deleting deployment...")
   158  	deletePolicy := metav1.DeletePropagationForeground
   159  	if err := deploymentsClient.Delete(context.TODO(), "demo-deployment", metav1.DeleteOptions{
   160  		PropagationPolicy: &deletePolicy,
   161  	}); err != nil {
   162  		panic(err)
   163  	}
   164  	fmt.Println("Deleted deployment.")
   165  }
   166  
   167  func prompt() {
   168  	fmt.Printf("-> Press Return key to continue.")
   169  	scanner := bufio.NewScanner(os.Stdin)
   170  	for scanner.Scan() {
   171  		break
   172  	}
   173  	if err := scanner.Err(); err != nil {
   174  		panic(err)
   175  	}
   176  	fmt.Println()
   177  }
   178  
   179  func int32Ptr(i int32) *int32 { return &i }