{"id":1078,"date":"2019-01-14T22:11:45","date_gmt":"2019-01-14T22:11:45","guid":{"rendered":"https:\/\/www.appservgrid.com\/paw93\/?p=1078"},"modified":"2019-01-24T04:00:04","modified_gmt":"2019-01-24T04:00:04","slug":"apiserver-dry-run-and-kubectl-diff","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw93\/index.php\/2019\/01\/14\/apiserver-dry-run-and-kubectl-diff\/","title":{"rendered":"APIServer dry-run and kubectl diff"},"content":{"rendered":"<h3><a href=\"https:\/\/kubernetes.io\/blog\/2019\/01\/14\/apiserver-dry-run-and-kubectl-diff\/\">APIServer dry-run and kubectl diff<\/a><\/h3>\n<p>Author: Antoine Pelisse (Google Cloud, @apelisse)<\/p>\n<p>Declarative configuration management, also known as configuration-as-code, is<br \/>\none of the key strengths of Kubernetes. It allows users to commit the desired state of<br \/>\nthe cluster, and to keep track of the different versions, improve auditing and<br \/>\nautomation through CI\/CD pipelines. The <a href=\"https:\/\/groups.google.com\/forum\/#!forum\/kubernetes-wg-apply\" target=\"_blank\" rel=\"noopener\">Apply working-group<\/a><br \/>\nis working on fixing some of the gaps, and is happy to announce that Kubernetes<br \/>\n1.13 promoted server-side dry-run and kubectl diff to beta. These<br \/>\ntwo features are big improvements for the Kubernetes declarative model.<\/p>\n<h2>Challenges<\/h2>\n<p>A few pieces are still missing in order to have a seamless declarative<br \/>\nexperience with Kubernetes, and we tried to address some of these:<\/p>\n<ul>\n<li>While compilers and linters do a good job to detect errors in pull-requests<br \/>\nfor code, a good validation is missing for Kubernetes configuration files.<br \/>\nThe existing solution is to run kubectl apply &#8211;dry-run, but this runs a<br \/>\n<em>local<\/em> dry-run that doesn\u2019t talk to the server: it doesn\u2019t have server<br \/>\nvalidation and doesn\u2019t go through validating admission controllers. As an<br \/>\nexample, Custom resource names are only validated on the server so a local<br \/>\ndry-run won\u2019t help.<\/li>\n<li>It can be difficult to know how your object is going to be applied by the<br \/>\nserver for multiple reasons:<\/p>\n<ul>\n<li>Defaulting will set some fields to potentially unexpected values,<\/li>\n<li>Mutating webhooks might set fields or clobber\/change some values.<\/li>\n<li>Patch and merges can have surprising effects and result in unexpected<br \/>\nobjects. For example, it can be hard to know how lists are going to be<br \/>\nordered once merged.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>The working group has tried to address these problems.<\/p>\n<h2>APIServer dry-run<\/h2>\n<p><a href=\"https:\/\/kubernetes.io\/docs\/reference\/using-api\/api-concepts\/#dry-run\" target=\"_blank\" rel=\"noopener\">APIServer dry-run<\/a> was implemented to address these two problems:<\/p>\n<ul>\n<li>it allows individual requests to the apiserver to be marked as \u201cdry-run\u201d,<\/li>\n<li>the apiserver guarantees that dry-run requests won\u2019t be persisted to storage,<\/li>\n<li>the request is still processed as typical request: the fields are<br \/>\ndefaulted, the object is validated, it goes through the validation admission<br \/>\nchain, and through the mutating admission chain, and then the final object is<br \/>\nreturned to the user as it normally would, without being persisted.<\/li>\n<\/ul>\n<p>While dynamic admission controllers are not supposed to have side-effects on<br \/>\neach request, dry-run requests are only processed if all admission controllers<br \/>\nexplicitly announce that they don\u2019t have any dry-run side-effects.<\/p>\n<h3>How to enable it<\/h3>\n<p>Server-side dry-run is enabled through a feature-gate. Now that the feature is<br \/>\nBeta in 1.13, it should be enabled by default, but still can be enabled\/disabled<br \/>\nusing kube-apiserver &#8211;feature-gates DryRun=true.<\/p>\n<p>If you have dynamic admission controllers, you might have to fix them to:<\/p>\n<ul>\n<li>Remove any side-effects when the dry-run parameter is specified on the webhook request,<\/li>\n<li>Specify in the <a href=\"https:\/\/kubernetes.io\/docs\/reference\/generated\/kubernetes-api\/v1.13\/#webhook-v1beta1-admissionregistration\" target=\"_blank\" rel=\"noopener\">sideEffects<\/a><br \/>\nfield of the admissionregistration.k8s.io\/v1beta1.Webhook object to indicate that the object doesn\u2019t<br \/>\nhave side-effects on dry-run (or at all).<\/li>\n<\/ul>\n<h3>How to use it<\/h3>\n<p>You can trigger the feature from kubectl by using kubectl apply<br \/>\n&#8211;server-dry-run, which will decorate the request with the dryRun flag<br \/>\nand return the object as it would have been applied, or an error if it would<br \/>\nhave failed.<\/p>\n<h2>Kubectl diff<\/h2>\n<p>APIServer dry-run is convenient because it lets you see how the object would be<br \/>\nprocessed, but it can be hard to identify exactly what changed if the object is<br \/>\nbig. kubectl diff does exactly what you want by showing the differences between<br \/>\nthe current \u201clive\u201d object and the new \u201cdry-run\u201d object. It makes it very<br \/>\nconvenient to focus on only the changes that are made to the object, how the<br \/>\nserver has merged these and how the mutating webhooks affects the output.<\/p>\n<h3>How to use it<\/h3>\n<p>kubectl diff is meant to be as similar as possible to kubectl apply:<br \/>\nkubectl diff -f some-resources.yaml will show a diff for the resources in the yaml file. One can even use the diff program of their choice by using the KUBECTL_EXTERNAL_DIFF environment variable, for example:<\/p>\n<p>KUBECTL_EXTERNAL_DIFF=meld kubectl diff -f some-resources.yaml<\/p>\n<h2>What\u2019s next<\/h2>\n<p>The working group is still busy trying to improve some of these things:<\/p>\n<ul>\n<li>Server-side apply is trying to improve the apply scenario, by adding owner<br \/>\nsemantics to fields! It\u2019s also going to improve support for CRDs and unions!<\/li>\n<li>Some kubectl apply features are missing from diff and could be useful, like the ability<br \/>\nto filter by label, or to display pruned resources.<\/li>\n<li>Eventually, kubectl diff will use server-side apply!<\/li>\n<\/ul>\n<p><a href=\"https:\/\/kubernetes.io\/blog\/2019\/01\/14\/apiserver-dry-run-and-kubectl-diff\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>APIServer dry-run and kubectl diff Author: Antoine Pelisse (Google Cloud, @apelisse) Declarative configuration management, also known as configuration-as-code, is one of the key strengths of Kubernetes. It allows users to commit the desired state of the cluster, and to keep track of the different versions, improve auditing and automation through CI\/CD pipelines. The Apply working-group &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw93\/index.php\/2019\/01\/14\/apiserver-dry-run-and-kubectl-diff\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;APIServer dry-run and kubectl diff&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-1078","post","type-post","status-publish","format-standard","hentry","category-kubernetes"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1078","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/comments?post=1078"}],"version-history":[{"count":1,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1078\/revisions"}],"predecessor-version":[{"id":1141,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1078\/revisions\/1141"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/media?parent=1078"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/categories?post=1078"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/tags?post=1078"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}