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 }