Kubectl Book updates for 1.14
This commit is contained in:
		
							parent
							
								
									2a31209eeb
								
							
						
					
					
						commit
						b9f105d4aa
					
				|  | @ -3,8 +3,8 @@ | |||
| ## Running Locally | ||||
| 
 | ||||
| - Install [GitBook Toolchain](https://toolchain.gitbook.com/setup.html) | ||||
| - From `docs/book` run `gitbook install`  to install node_modules locally | ||||
|   - Retry if this fails, it is flaky | ||||
| - From `docs/book` run `npm ci`  to install node_modules locally (don't run install, it updates the shrinkwrap.json) | ||||
| - From `docs/book` run `npm audit` to make sure there are no vulnerabilities | ||||
| - From `docs/book` run `gitbook serve` | ||||
| - Go to `http://localhost:4000` in a browser | ||||
| 
 | ||||
|  | @ -50,4 +50,13 @@ Notes may have the following styles: | |||
| ## Adding GitBook plugins | ||||
| 
 | ||||
| - Update `book.json` with the plugin | ||||
| - Run `gitbook install` | ||||
| - Run `npm i <npm-plugin-name>` | ||||
| - Run `npm strinkwrap` | ||||
| - Run `npm audit` - fix issues by hand updating `npm-shrinkwrap.json` libraries with the fixed versions | ||||
| - Run `npm ci` - install the new version | ||||
| - Run `npm audit` - verify the fixes | ||||
| - Commit `npm-shrinkwrap.json` and `package.json` | ||||
| 
 | ||||
| ### Cool plugins | ||||
| 
 | ||||
| See https://github.com/swapagarwal/awesome-gitbook-plugins for more plugins. | ||||
|  | @ -1,47 +1,50 @@ | |||
| # Introduction | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Kubernetes runs Containerized Workloads in a cluster | ||||
| - The Kubectl Book explains Kubernetes tools and workflows | ||||
| {% endpanel %} | ||||
| 
 | ||||
| The goal of this book is to document how users should configure, deploy and manage their  | ||||
| containerized Workloads in Kubernetes. | ||||
| # Introduction | ||||
| 
 | ||||
| It is broken into the following sections: | ||||
| The goal of this book is to document how to configure, deploy and manage their containerized | ||||
| Workloads in Kubernetes using Kubectl. | ||||
| 
 | ||||
| - Introduction to Kubernetes & Kubectl | ||||
| - How to configure Applications through Resource Config | ||||
| - How to debug Applications using Kubectl | ||||
| - How to configure Projects composed of multiple Applications | ||||
| - How to rollout changes with CICD | ||||
| - How to perform cluster maintenance operations using Kubectl | ||||
| It covers the following topics: | ||||
| 
 | ||||
| ## Background | ||||
| - Introduction to Kubernetes Workload APIs & Kubectl | ||||
| - Declarative Configuration | ||||
| - Deployment Techniques | ||||
| - Printing information about Workloads | ||||
| - Debugging Workloads | ||||
| - Imperative Porcelain Commands | ||||
| 
 | ||||
| ## Overview | ||||
| 
 | ||||
| Kubernetes is a set of APIs to run containerized Workloads in a cluster. | ||||
| 
 | ||||
| Users define API objects (i.e. Resources) in files checked into source control, and use kubectl | ||||
| to Apply (i.e. create, update, delete) configuration files to cluster Resources. | ||||
| Users define API objects (i.e. Resources) in files which are typically checked into source control. | ||||
| They then use kubectl to Apply (i.e. create, update, delete) to update cluster state. | ||||
| 
 | ||||
| ### Pods | ||||
|   | ||||
| Containers are run in [*Pods*](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/) which are scheduled to *Nodes* (i.e. worker machines) in a cluster. | ||||
| Containers are run in [*Pods*](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/) which are | ||||
| scheduled to run on *Nodes* (i.e. worker machines) in a cluster. | ||||
| 
 | ||||
| Pods provide the following a Pod running a *single instance* of an Application: | ||||
| Pods run a *single replica* of an Application and provide: | ||||
| 
 | ||||
| - Compute Resources (cpu, memory, disk) | ||||
| - Environment Variables | ||||
| - Readiness and Health Checking | ||||
| - Network (IP address shared by containers in the Pod) | ||||
| - Mounting Shared Configuration and Secrets | ||||
| - Mounting Storage Volumes | ||||
| - Initialization | ||||
| 
 | ||||
| {% panel style="info", title="Multi Container Pods" %} | ||||
| Multiple identical instances of an Application should be run by creating multiple copies of | ||||
| the same Pod using a Workload API. | ||||
| {% panel style="warning", title="Multi Container Pods" %} | ||||
| Multiple replicas of an Application should be created using a Workload API to manage | ||||
| creation and deletion of Pod replicas using a PodTemplate. | ||||
| 
 | ||||
| A Pod may contain multiple Containers which are a single instance of an Application.  These | ||||
| containers may coordinate with one another through shared network (IP) and files. | ||||
| In some cases a Pod may contain multiple Containers forming a single instance of an Application.  These | ||||
| containers may coordinate with one another through shared network (IP) and storage. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ### Workloads | ||||
|  | @ -62,15 +65,15 @@ The most common out-of-the-box Workload APIs (manage Pods) are: | |||
| - [DaemonSets](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) (Per-Machine) | ||||
|   - per-Node scheduling | ||||
| 
 | ||||
| {% panel style="info", title="Abstraction Layers" %} | ||||
| {% panel style="success", title="API Abstraction Layers" %} | ||||
| High-level Workload APIs may manage lower-level Workload APIs instead of directly managing Pods | ||||
| (e.g. Deployments manage ReplicaSets). | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ### Service Discovery and Load Balancing | ||||
| 
 | ||||
| Service discovery and Load Balancing is managed by a *Service* object.  Services provide a single | ||||
| IP address and dns name to talk to a collection of Pods. | ||||
| Service discovery and Load Balancing may be managed by a *Service* object.  Services provide a single | ||||
| virtual IP address and dns name load balanced to a collection of Pods matching Labels. | ||||
| 
 | ||||
| {% panel style="info", title="Internal vs External Services" %} | ||||
| - [Services Resources](https://kubernetes.io/docs/concepts/services-networking/service/) | ||||
|  | @ -81,9 +84,9 @@ IP address and dns name to talk to a collection of Pods. | |||
| 
 | ||||
| ### Configuration and Secrets | ||||
| 
 | ||||
| Shared Configuration and Secret data may be provided by Secrets and ConfigMaps.  This allows | ||||
| Environment Variables, Commandline Arguments and Files to be setup and decoupled from | ||||
| the Pods and Containers. | ||||
| Shared Configuration and Secret data may be provided by ConfigMaps and Secrets.  This allows | ||||
| Environment Variables, Commandline Arguments and Files to be loosely injected into | ||||
| the Pods and Containers that consume them. | ||||
| 
 | ||||
| {% panel style="info", title="ConfigMaps vs Secrets" %} | ||||
| - [ConfigMaps](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) | ||||
|  |  | |||
|  | @ -1,67 +1,58 @@ | |||
| ## The Kubectl Book | ||||
| ## Kubectl Book | ||||
| 
 | ||||
| * [Resources and Controllers](pages/book_resources.md) | ||||
| * [Kubectl](pages/book_kubectl.md) | ||||
| * [Resources and Controllers](pages/kubectl_book/resources_and_controllers.md) | ||||
| * [Kubectl](pages/kubectl_book/kubectl.md) | ||||
| 
 | ||||
| ## Declarative Application Management | ||||
| ## App Management | ||||
| 
 | ||||
| * [Introduction](pages/dam_introduction.md) | ||||
| * [Apply](pages/dam_apply.md) | ||||
| * [Secret and ConfigMap Generation](pages/dam_generators.md) | ||||
| * [Container Image Tags](pages/dam_images.md)       | ||||
| * [Namespaces and Names](pages/dam_namespaces.md) | ||||
| * [Labels and Annotations](pages/dam_labels.md) | ||||
| * [Config Reflection](pages/dam_variables.md) | ||||
| * [Introduction](pages/app_management/introduction.md) | ||||
| * [Apply](pages/app_management/apply.md) | ||||
| * [Secrets and ConfigMaps](pages/app_management/secrets_and_configmaps.md) | ||||
| * [Container Images](pages/app_management/container_images.md)       | ||||
| * [Namespaces and Names](pages/app_management/namespaces_and_names.md) | ||||
| * [Labels and Annotations](pages/app_management/labels_and_annotations.md) | ||||
| * [Field Merge Semantics](pages/app_management/field_merge_semantics.md) | ||||
| 
 | ||||
| ## Debugging Workloads | ||||
| ## App Customization | ||||
| 
 | ||||
| * Viewing Resource State | ||||
| * Container Logs | ||||
| * Container Files | ||||
| * Container Shell | ||||
| * Accessing Services | ||||
| * RBAC Permissions | ||||
| * [Introduction](pages/app_customization/introduction.md) | ||||
| * [Bases and Variations](pages/app_customization/bases_and_variants.md) | ||||
| * [Customizing Pod Templates](pages/app_customization/customizing_pod_templates.md) | ||||
| * [Customizing Metadata](pages/app_customization/customizing_metadata.md) | ||||
| * [Customizing Arbitrary Fields](pages/app_customization/customizing_arbitrary_fields.md) | ||||
| * [Config Reflection](pages/app_customization/config_reflection.md) | ||||
| 
 | ||||
| ## Project Composition and Variation | ||||
| ## App Composition and Deployment | ||||
| 
 | ||||
| * [Bases and Variations](pages/project_variants.md) | ||||
| * [Customizing Whitebox Bases](pages/project_whitebox.md) | ||||
| * [Composing Multiple Bases](pages/project_composition.md) | ||||
| * [Overlay Merge Semantics](pages/project_merge.md) | ||||
| * [Diffing Local and Remote State](pages/app_composition_and_deployment/diffing_local_and_remote_resources.md) | ||||
| * [Accessing Multiple Clusters](pages/app_composition_and_deployment/accessing_multiple_clusters.md) | ||||
| * [Structure: Multi-Tier Apps](pages/app_composition_and_deployment/structure_multi_tier_apps.md) | ||||
| * [Structure: Directories](pages/app_composition_and_deployment/structure_directories.md) | ||||
| * [Structure: Branches](pages/app_composition_and_deployment/structure_branches.md) | ||||
| * [Structure: Repositories](pages/app_composition_and_deployment/structure_repositories.md) | ||||
| * [Publishing Bases](pages/app_composition_and_deployment/publishing_bases.md) | ||||
| 
 | ||||
| ## CICD | ||||
| ## Resource Printing | ||||
| 
 | ||||
| * [Project Structure](pages/cicd_structure.md) | ||||
| * [Linting Resource Config](pages/cicd_linting.md) | ||||
| * [Builds](pages/cicd_builds.md) | ||||
| * [Rollouts](pages/cicd_rollouts.md) | ||||
| * [Auditing and Reviewing Changes](pages/cicd_audit.md) | ||||
| * [Rolling out Across Environments](pages/cicd_environments.md) | ||||
| * [Rolling out Across Clusters](pages/cdicd_clusters.md) | ||||
| * [Rollout Errors and Rolling Back](pages/cicd_rollback.md) | ||||
| * [Summaries](pages/resource_printing/summaries.md) | ||||
| * [Raw](pages/resource_printing/raw.md) | ||||
| * [Fields](pages/resource_printing/fields.md) | ||||
| * [Describe](pages/resource_printing/describe.md) | ||||
| * [Queries and Options](pages/resource_printing/queries_and_options.md) | ||||
| * [Watch](pages/resource_printing/watch.md) | ||||
| * [Cluster Information](pages/resource_printing/cluster_information.md) | ||||
| 
 | ||||
| ## Cluster Management | ||||
| ## Container Debugging | ||||
| 
 | ||||
| * Viewing Cluster Metadata | ||||
| * Setting Node Availability | ||||
| * Viewing Node Resource Usage | ||||
| * Managing the Client Config | ||||
| * Checking Authorization | ||||
| * [Container Logs](pages/container_debugging/container_logs.md) | ||||
| * [Copying Container Files](pages/container_debugging/copying_container_files.md) | ||||
| * [Executing a Command in a Container](pages/container_debugging/executing_a_command_in_a_container.md) | ||||
| * [Port Forward to Pods](pages/container_debugging/port_forward_to_pods.md) | ||||
| * [Proxying Traffic to Services](pages/container_debugging/proxying_traffic_to_services.md) | ||||
| 
 | ||||
| ## Porcelain | ||||
| ## Imperative Porcelain | ||||
| 
 | ||||
| * Creating Resources | ||||
| * Setting Fields | ||||
| * Setting Labels and Annotations | ||||
| * Modifying Live Resources Directly | ||||
| 
 | ||||
| ## Plugins | ||||
| 
 | ||||
| * Discovering Plugins | ||||
| * Managing Plugins | ||||
| * Developing Plugins | ||||
| * Publishing Plugins | ||||
| 
 | ||||
| ## Reference | ||||
| 
 | ||||
| * apply.yaml | ||||
| * [Introduction](pages/imperative_porcelain/introduction.md) | ||||
| * [Creating Resources](pages/imperative_porcelain/creating_resources.md) | ||||
| * [Setting Fields](pages/imperative_porcelain/setting_fields.md) | ||||
| * [Editing Workloads](pages/imperative_porcelain/editing_workloads.md) | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1,138 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Target a cluster for a rollout with the `--context` flag | ||||
| - Target a cluster for a rollout with the `--kubeconfig` flag | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Multi-Cluster Targeting | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| It is common for users to need to deploy **different Variants of an Application to different clusters**. | ||||
| This can be done by configuring the different Variants using different `kustomization.yaml`'s, | ||||
| and targeting each variant using the `--context` or `--kubeconfig` flag. | ||||
| 
 | ||||
| **Note:** The examples shown in this chapter store the Resource Config in a directory | ||||
| matching the name of the cluster (i.e. as it is referred to be context) | ||||
| 
 | ||||
| 
 | ||||
| ## Targeting a Cluster via Context | ||||
| 
 | ||||
| The kubeconfig file allows multiple contexts to be specified, each with a different cluster + auth. | ||||
| 
 | ||||
| ### List Contexts | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| List the contexts in the kubeconfig file | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| ```sh | ||||
| $ kubectl config get-contexts | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| CURRENT   NAME   CLUSTER   AUTHINFO   NAMESPACE | ||||
|           us-central1-c  us-central1-c  us-central1-c   | ||||
| *         us-east1-c  us-east1-c  us-east1-c   | ||||
|           us-west2-c   us-west2-c   us-west2-c    | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ### Print a Context | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| Print information about the current context | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| ```sh | ||||
| $ kubectl config --kubeconfig=config-demo view --minify | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| apiVersion: v1 | ||||
| clusters: | ||||
| - cluster: | ||||
|     certificate-authority: fake-ca-file | ||||
|     server: https://1.2.3.4 | ||||
|   name: development | ||||
| contexts: | ||||
| - context: | ||||
|     cluster: development | ||||
|     namespace: frontend | ||||
|     user: developer | ||||
|   name: dev-frontend | ||||
| current-context: dev-frontend | ||||
| kind: Config | ||||
| preferences: {} | ||||
| users: | ||||
| - name: developer | ||||
|   user: | ||||
|     client-certificate: fake-cert-file | ||||
|     client-key: fake-key-file   | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ### Specify a Context Flag | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| Specify the kubeconfig context as part of the command. | ||||
| 
 | ||||
| **Note:** In this example the `kustomization.yaml` exists in a directory whose name matches | ||||
| the name of the context. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```sh | ||||
| $ export CLUSTER=us-west2-c; kubectl apply -k ${CLUSTER} --context=${CLUSTER} | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ### Switch to use a Context | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| Switch the current context before running the command. | ||||
| 
 | ||||
| **Note:** In this example the `kustomization.yaml` exists in a directory whose name matches | ||||
| the name of the context. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```sh | ||||
| # change the context to us-west2-c | ||||
| $ kubectl config use-context us-west2-c | ||||
| # deploy Resources from the ./us-west2-c/kustomization.yaml | ||||
| $ kubectl apply -k ./us-west2-c | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ## Targeting a Cluster via Kubeconfig | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| Alternatively, different kubeconfig files may be used for different clusters.  The | ||||
| kubeconfig may be specified with the `--kubeconfig` flag. | ||||
| 
 | ||||
| **Note:** In this example the `kustomization.yaml` exists in a directory whose name matches | ||||
| the name of the directory containing the kubeconfig. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```sh | ||||
| $ kubectl apply -k ./us-west2-c --kubeconfig /path/to/us-west2-c/config | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="More Info" %} | ||||
| For more information on configuring kubeconfig and contexts, see the | ||||
| [Configure Access to Multiple Clusters](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) | ||||
| k8s.io document. | ||||
| {% endpanel %} | ||||
| 
 | ||||
|  | @ -0,0 +1,40 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - View diff of changes before they are Applied to the cluster | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Diffing Local and Cluster State | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| The ability to view what changes will be made before applying them to a cluster can be useful. | ||||
| 
 | ||||
| {% method %} | ||||
| ## Generating a Diff | ||||
| 
 | ||||
| Use the `diff` program in a user's path to display a diff of the changes that will be | ||||
| made by Apply. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```sh | ||||
| $ kubectl diff -k ./dir/ | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Setting the Diff Program | ||||
| 
 | ||||
| The `KUBECTL_EXTERNAL_DIFF` environment variable can be used to select your own diff command. | ||||
| By default, the "diff" command available in your path will be run with "-u" (unicode) and "-N" | ||||
| (treat new files as empty) options. | ||||
| 
 | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```sh | ||||
| $ export KUBECTL_EXTERNAL_DIFF=meld; kubectl diff -k ./dir/ | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
|  | @ -1,10 +1,14 @@ | |||
| # Customizing White Box Bases | ||||
| {% panel style="warning", title="Alpha Recommendations" %} | ||||
| This chapter contains recommendations that are still being actively evaluated, and may | ||||
| be changed in the future. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Run a White Box Application as a Base | ||||
| - Customize a White Box Application | ||||
| - Publish a White Box Application as a Base for other users to Kustomize | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Publishing Bases | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Users may want to run a common White Box Application without writing the Resource Config | ||||
|  | @ -15,18 +19,19 @@ their specific needs. | |||
| - Run a White Box Application (e.g. Cassandra, MongoDB) instance from ready-made Resource Config | ||||
| - Publish Resource Config to run an Application | ||||
| 
 | ||||
| ## Consuming a White Box Base | ||||
| ## Publishing a White Box Base | ||||
| 
 | ||||
| {% method %} | ||||
| White Box Applications may be published to a URL and consumed as Bases in an `apply.yaml` | ||||
| White Box Applications may be published to a URL and consumed as Bases in an `kustomization.yaml`.  It | ||||
| can then be consumed in the following manner. | ||||
| 
 | ||||
| **Use Case:** Run a White Box Application published to GitHub. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| **Input:** The kustomization.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| # kustomization.yaml | ||||
| bases: | ||||
| # GitHub URL | ||||
| - github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6 | ||||
|  | @ -52,7 +57,7 @@ spec: | |||
| ## Customizing White Box Bases | ||||
| 
 | ||||
| The White Box Application may be customized using the same techniques described in | ||||
| [Bases and Variations](project_variants.md) | ||||
| [Bases and Variations](../app_customization/bases_and_variants.md) | ||||
| 
 | ||||
| ## Versioning White Box Bases | ||||
| 
 | ||||
|  | @ -0,0 +1,241 @@ | |||
| {% panel style="warning", title="Warning: Alpha Recommendations" %} | ||||
| This chapter contains recommendations that are still being actively evaluated, and may | ||||
| be changed in the future. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Use separate branches for separate Environments to  | ||||
|   - **Decouple release specific and operational specific changes** to Resource Config | ||||
|   - Clean audit log of changes to the Environment | ||||
|   - Facilitate Rollbacks to an Environment | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Branch Structure Based Composition | ||||
| 
 | ||||
| The are several techniques for users to structure their Resource Config files. | ||||
| 
 | ||||
| | Type                                   | Summary               | Benefits                                           | | ||||
| |----------------------------------------|-----------------------|----------------------------------------------------| | ||||
| | [Directories](structure_directories.md)   | *Simplest approach*   | Easy to get started and understand               | | ||||
| | **[Branches](structure_branches.md)**   | **More flexible**       | **Loose coupling between release specific and operation changes** | | ||||
| | [Repositories](structure_repositories.md) | *Fine grain control*  | Isolated permissions model                         | | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| This chapter describes conventions for using **Branches** with Directories. | ||||
| 
 | ||||
| **Advantages:** | ||||
| 
 | ||||
| - Flexibility | ||||
|   - Decouple release specific changes (e.g. images) from operational specific changes (e.g. cpu reservations) | ||||
|   - Trigger Webhooks scoped to specific Environments | ||||
|   - Simple to view changes for a specific Environment in *git* | ||||
|   - Simple to rollback changes for a specific Environment using *git* | ||||
| 
 | ||||
| **Drawbacks:** | ||||
| 
 | ||||
| - More complicated to setup and configure | ||||
| - Additional steps for merging release specific changes into and Environment branches | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| ## Branch Structure | ||||
| 
 | ||||
| ### Resource Config | ||||
| 
 | ||||
| The convention shown here should be changed and adapted as needed. | ||||
| 
 | ||||
| Structure: | ||||
| 
 | ||||
| - Use a Base (e.g. master, release-version, etc) branch for configuration tightly coupled to releasing new code | ||||
|   - Looks like [Directories](structure_directories.md) approach | ||||
| - Create separate branches for deploying to different Environments | ||||
|   - Create a **new Directory for the operational overlays** - e.g. `release-<env>` | ||||
|   - Uses Bases that point to Directories merged from the Base branch | ||||
| 
 | ||||
| Techniques: | ||||
| 
 | ||||
| - Add new required flags and environment variables to the Resource Config in the base branch at the | ||||
|   time they are added to the code. | ||||
|   - Will be rolled out when the code is rolled out. | ||||
| - Adjust flags and configuration to the Resource Config in the Operational branch in the release directory | ||||
|   - Will be rolled out immediately independent of releases | ||||
| - Merge code from the Base branch to the Operational branches to perform a Rollout | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| **Base Branch:** | ||||
| 
 | ||||
| ```bash | ||||
| $ tree | ||||
| . | ||||
| ├── bases | ||||
| │   ├── ... | ||||
| ├── prod | ||||
| │   ├── bases  | ||||
| │   │   ├── ... | ||||
| │   ├── us-central | ||||
| │   │   ├── kustomization.yaml | ||||
| │   │   └── backend | ||||
| │   │       └── deployment-patch.yaml | ||||
| │   ├── us-east  | ||||
| │   │   └── kustomization.yaml | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml | ||||
| ├── staging | ||||
| │   ├── bases  | ||||
| │   │   ├── ... | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml | ||||
| └── test | ||||
|     ├── bases  | ||||
|     │   ├── ... | ||||
|     └── us-west  | ||||
|         └── kustomization.yaml | ||||
| ``` | ||||
| 
 | ||||
| **Operational Branches:** | ||||
| 
 | ||||
| ```bash | ||||
| $ tree | ||||
| . | ||||
| ├── bases # From Base Branch | ||||
| │   ├── ... | ||||
| ├── prod # From Base Branch | ||||
| │   ├── ...  | ||||
| └── release-prod # Prod release folder | ||||
|     ├── us-central | ||||
|     │   ├── kustomization.yaml # Uses bases: ["../../prod/us-central"] | ||||
|     ├── us-east  | ||||
|     │   └── kustomization.yaml # Uses bases: ["../../prod/us-east"] | ||||
|     └── us-west  | ||||
|         └── kustomization.yaml # Uses bases: ["../../prod/us-west"] | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| $ tree | ||||
| . | ||||
| ├── bases # From Base Branch | ||||
| │   ├── ... | ||||
| ├── release-staging # Staging release folder | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml # Uses bases: ["../../staging/us-west"] | ||||
| └── staging # From Base Branch | ||||
|     └── ... | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| $ tree | ||||
| . | ||||
| ├── bases # From Base Branch | ||||
| │   ├── ... | ||||
| ├──release-test # Test release folder | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml # Uses bases: ["../../test/us-west"] | ||||
| └── test # From Base Branch | ||||
|     └── ... | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="success", title="Better Merging" %} | ||||
| 
 | ||||
| - If a user's application source code and Resource Config are both in the Base branch, user's may want | ||||
|   to only merge the Resource Config.  This could be done using `git checkout` - e.g. | ||||
|   `git checkout <base-branch> bases/ prod/` | ||||
|    | ||||
| - Instead of merging from the Base branch directly, users can create release branches of the Base. | ||||
|   Alternatively, users can tag the Base branch commits as releases and check these out. | ||||
| 
 | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| ## Alternative Branch Structure | ||||
| 
 | ||||
| An alternative to the above structure is to use branches similar to how *GitHub Pages* branches | ||||
| functions - where code is not merged between branches and is similar to having a new repository. | ||||
| 
 | ||||
| This approach looks very similar to the [Repository Based Structure](structure_repositories.md), but | ||||
| using branches instead of Repositories. | ||||
| 
 | ||||
| - Use a Base (e.g. master, release-version, etc) branch for configuration tightly coupled to releasing new code | ||||
|   - Looks like [Directories](structure_directories.md) approach | ||||
| - Create separate branches for deploying to different Environments | ||||
|   - Create a **new Directory for the operational overlays** - e.g. `release-<env>` | ||||
|   - Base Branch is never merge.  Operational overlays refer to Bases as remote urls. | ||||
| 
 | ||||
| Techniques: | ||||
| 
 | ||||
| - Add new required flags and environment variables to the Resource Config in the base branch at the | ||||
|   time they are added to the code. | ||||
|   - Will be rolled out when the code is rolled out. | ||||
| - Adjust flags and configuration to the Resource Config in the Operational branch in the release directory | ||||
|   - Will be rolled out immediately independent of releases | ||||
| - Tag the base branch with releases | ||||
|   - Operational branches use tagged references as their bases | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| **Base Branch:** | ||||
| 
 | ||||
| ```bash | ||||
| $ tree | ||||
| . | ||||
| ├── bases | ||||
| │   ├── ... | ||||
| ├── prod | ||||
| │   ├── bases  | ||||
| │   │   ├── ... | ||||
| │   ├── us-central | ||||
| │   │   ├── kustomization.yaml | ||||
| │   │   └── backend | ||||
| │   │       └── deployment-patch.yaml | ||||
| │   ├── us-east  | ||||
| │   │   └── kustomization.yaml | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml | ||||
| ├── staging | ||||
| │   ├── bases  | ||||
| │   │   ├── ... | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml | ||||
| └── test | ||||
|     ├── bases  | ||||
|     │   ├── ... | ||||
|     └── us-west  | ||||
|         └── kustomization.yaml | ||||
| ``` | ||||
| 
 | ||||
| **Operational Branches:** | ||||
| 
 | ||||
| ```bash | ||||
| $ tree | ||||
| . | ||||
| └── release-prod | ||||
|     ├── us-central | ||||
|     │   ├── kustomization.yaml | ||||
|     ├── us-east  | ||||
|     │   └── kustomization.yaml | ||||
|     └── us-west  | ||||
|         └── kustomization.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| $ tree | ||||
| . | ||||
| └── release-staging | ||||
|     └── us-west  | ||||
|         └── kustomization.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| $ tree | ||||
| . | ||||
| └── release-test | ||||
|     └── us-west  | ||||
|         └── kustomization.yaml | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,123 @@ | |||
| {% panel style="warning", title="Warning: Alpha Recommendations" %} | ||||
| This chapter contains recommendations that are still being actively evaluated, and may | ||||
| be changed in the future. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Use **directory hierarchy to structure Resource Config** | ||||
|   - Separate directories for separate Environment and Cluster [Config Variants](../app_customization/bases_and_variants.md) | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Directory Structure Based Composition | ||||
| 
 | ||||
| The are several techniques for users to structure their Resource Config files. | ||||
| 
 | ||||
| | Type                                   | Summary               | Benefits                                           | | ||||
| |----------------------------------------|-----------------------|----------------------------------------------------| | ||||
| | **[Directories](structure_directories.md)**   | **Simplest approach**   | **Easy to get started and understand**               | | ||||
| | [Branches](structure_branches.md)   | *More flexible*       | Loose coupling between release specific and operation changes | | ||||
| | [Repositories](structure_repositories.md) | *Fine grain control*  | Isolated permissions model                         | | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| This chapter describes conventions for using **Directories** alone. | ||||
| 
 | ||||
| **Advantages:** | ||||
| 
 | ||||
| - Simplicity | ||||
|   - Simple to learn | ||||
|   - Simple to navigate using conventional tools | ||||
|   - Simple to audit | ||||
| 
 | ||||
| **Drawbacks:** | ||||
| 
 | ||||
| - Limited permissions and ownership models | ||||
|   - Read/Write access typically given at a per-repo model | ||||
| - Less granular event triggers | ||||
|   - Webhooks triggered for repo+branch can't be focused on a specific environment + cluster | ||||
| - Harder to decouple release related changes from operational related changes | ||||
|   - Changes to scale or cpu should be rolled out immediately | ||||
|   - Changes to image or flags should be rolled out with the release | ||||
| 
 | ||||
| {% panel style="info", title="Config Repo or Mono Repo?" %} | ||||
| The techniques and conventions in this Chapter work regardless of whether or not the Resource Config | ||||
| exists in the same Repository as the source code that is being deployed. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## Directory Structure | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| ### Resource Config | ||||
| 
 | ||||
| The convention shown here should be changed and adapted as needed. | ||||
| 
 | ||||
| Structure: | ||||
| 
 | ||||
| - Put reusable bases under `*/bases/` | ||||
|   - `<project-name>/bases/` | ||||
|   - `<project-name>/<environment>/bases/` | ||||
| - Put deployable targets under `<project-name>/<environment>/<cluster>/` | ||||
| 
 | ||||
| Techniques: | ||||
|   | ||||
| - Each Layer adds a [namePrefix](../app_management/namespaces_and_names.md#setting-a-name-prefix-or-suffix-for-all-resources) and [commonLabels](../app_management/labels_and_annotations.md#setting-labels-for-all-resources). | ||||
| - Each deployable target sets a [namespace](../app_management/namespaces_and_names.md#setting-the-namespace-for-all-resources). | ||||
| - Override [Pod Environment Variables and Arguments](../app_customization/customizing_pod_templates.md) using `configMapGenerator`s with `behavior: merge`. | ||||
| - Perform Last-mile customizations with [patches / overlays](../app_customization/customizing_arbitrary_fields.md) | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ tree | ||||
| . | ||||
| ├── bases # Used as a Base only | ||||
| │   ├── kustomization.yaml | ||||
| │   ├── backend | ||||
| │   │   ├── deployment.yaml | ||||
| │   │   └── service.yaml | ||||
| │   ├── frontend | ||||
| │   │   ├── deployment.yaml | ||||
| │   │   ├── ingress.yaml | ||||
| │   │   └── service.yaml | ||||
| │   └── storage | ||||
| │       ├── service.yaml | ||||
| │       └── statefulset.yaml | ||||
| ├── prod # Production | ||||
| │   ├── bases  | ||||
| │   │   ├── kustomization.yaml # Uses bases: ["../../bases"] | ||||
| │   │   ├── backend | ||||
| │   │   │   └── deployment-patch.yaml # Production Env specific backend overrides | ||||
| │   │   ├── frontend | ||||
| │   │   │   └── deployment-patch.yaml # Production Env specific frontend overrides | ||||
| │   │   └── storage | ||||
| │   │       └── statefulset-patch.yaml # Production Env specific storage overrides | ||||
| │   ├── us-central | ||||
| │   │   ├── kustomization.yaml # Uses bases: ["../bases"] | ||||
| │   │   └── backend | ||||
| │   │       └── deployment-patch.yaml # us-central cluster specific backend overrides | ||||
| │   ├── us-east  | ||||
| │   │   └── kustomization.yaml # Uses bases: ["../bases"] | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml # Uses bases: ["../bases"] | ||||
| ├── staging # Staging | ||||
| │   ├── bases  | ||||
| │   │   ├── kustomization.yaml # Uses bases: ["../../bases"] | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml # Uses bases: ["../bases"] | ||||
| └── test # Test | ||||
|     ├── bases  | ||||
|     │   ├── kustomization.yaml # Uses bases: ["../../bases"] | ||||
|     └── us-west  | ||||
|         └── kustomization.yaml # Uses bases: ["../bases"] | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="warning", title="Applying Environment + Cluster" %} | ||||
| Though the directory structure contains the cluster in the path, this won't be used by | ||||
| Apply to determine the cluster context.  To Apply a specific cluster, add that cluster to the  | ||||
| kubectl config`, and specify the corresponding context when running Apply. | ||||
| 
 | ||||
| For more information see [Multi-Cluster](accessing_multiple_clusters.md). | ||||
| {% endpanel %} | ||||
|  | @ -1,12 +1,17 @@ | |||
| # Composing Bases | ||||
| {% panel style="warning", title="Warning: Alpha Recommendations" %} | ||||
| This chapter contains recommendations that are still being actively evaluated, and may | ||||
| be changed in the future. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - The same Base may be used multiple times for different Applications within the same project. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Advanced Composition | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Users may want to reuse the same base multiple times within the same Apply Project.  Examples: | ||||
| Users may want to reuse the **same base multiple times within the same Apply Project**.  Examples: | ||||
| 
 | ||||
| - Define a very generic base (e.g. "Java Application") used by multiple Applications within a Project. | ||||
| - Define multiple Environments (e.g. Staging, Canary, Prod) within a Project. | ||||
|  | @ -17,19 +22,18 @@ Users may want to reuse the same base multiple times within the same Apply Proje | |||
| It is possible to reuse the same base multiple times within the same project by using a 3-tier | ||||
| structure to compose multiple Variants of the base. | ||||
| 
 | ||||
| 1. Generic Base. | ||||
| 1. Variants on the Generic Base. | ||||
| 1. Composition of Variants. | ||||
| 1. Generic Base in a `kustomization.yaml`. | ||||
| 1. Variants of the Generic Base in multiple `kustomization.yaml`s. | ||||
| 1. Compose Variants as Bases to a single `kustomization.yaml`. | ||||
| 
 | ||||
| Each layer may add customizations and resources to the preceding layers. | ||||
| 
 | ||||
| **apply.yaml** | ||||
| Generic Base Layer: **../base/java** | ||||
| 
 | ||||
| - compose the 2 apps as bases | ||||
| - set the namespace for Resources in the project | ||||
| - set a namePrefix for Resources in the project | ||||
| - define the java app base Deployment | ||||
| - define the java app base Service | ||||
| 
 | ||||
| **../app1/ & ../app2/** | ||||
| Variant Layers: **../app1/ + ../app2/** | ||||
| 
 | ||||
| - inherit the generic base | ||||
| - set a namePrefix | ||||
|  | @ -37,74 +41,23 @@ Each layer may add customizations and resources to the preceding layers. | |||
| - overlay an image on the base | ||||
| - set the image tag | ||||
| 
 | ||||
| **../base/java** | ||||
| Composition Layer: **kustomization.yaml** | ||||
| 
 | ||||
| - compose the 2 apps as bases | ||||
| - set the namespace for Resources in the project | ||||
| - set a namePrefix for Resources in the project | ||||
| 
 | ||||
| - define the java app base Deployment | ||||
| - define the java app base Service | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** | ||||
| **Generic Base Layer:** | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| namePrefix: app- | ||||
| namespace: app | ||||
| bases: | ||||
| - app1 | ||||
| - app2 | ||||
| 
 | ||||
| # app1/apply.yaml | ||||
| namePrefix: 1- | ||||
| commonLabels: | ||||
|   app: app1 | ||||
| bases: | ||||
| - ../base/java | ||||
| patchesStrategicMerge: | ||||
| - overlay.yaml | ||||
| imageTags: | ||||
|   - name: myapp2 | ||||
|     newTag: v2 | ||||
| 
 | ||||
| # app1/overlay.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: java | ||||
| spec: | ||||
|   template: | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: myapp2 | ||||
|         name: java | ||||
| 
 | ||||
| # ../app2/apply.yaml | ||||
| namePrefix: 2- | ||||
| commonLabels: | ||||
|   app: app2 | ||||
| bases: | ||||
| - ../base/java | ||||
| patchesStrategicMerge: | ||||
| - overlay.yaml | ||||
| imageTags: | ||||
|   - name: myapp1 | ||||
|     newTag: v1 | ||||
| 
 | ||||
| # app2/overlay.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: java | ||||
| spec: | ||||
|   template: | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: myapp1 | ||||
|         name: java | ||||
| 
 | ||||
| # base/java/apply.yaml | ||||
| # base/java/kustomization.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| - service.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # base/java/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
|  | @ -138,7 +91,9 @@ spec: | |||
|             port: 8010 | ||||
|           initialDelaySeconds: 30 | ||||
|           timeoutSeconds: 1         | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # base/java/service.yaml | ||||
| kind: Service | ||||
| apiVersion: v1 | ||||
|  | @ -152,13 +107,83 @@ spec: | |||
|     port: 8080 | ||||
|     targetPort: 8080 | ||||
| ``` | ||||
| 
 | ||||
| **Variant Layers 1 and 2:** | ||||
| 
 | ||||
| ```yaml | ||||
| # app1/kustomization.yaml | ||||
| namePrefix: 1- | ||||
| commonLabels: | ||||
|   app: app1 | ||||
| bases: | ||||
| - ../base/java | ||||
| patchesStrategicMerge: | ||||
| - overlay.yaml | ||||
| images: | ||||
|   - name: myapp1 | ||||
|     newTag: v2 | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # app1/overlay.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: java | ||||
| spec: | ||||
|   template: | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: myapp1 | ||||
|         name: java | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../app2/kustomization.yaml | ||||
| namePrefix: 2- | ||||
| commonLabels: | ||||
|   app: app2 | ||||
| bases: | ||||
| - ../base/java | ||||
| patchesStrategicMerge: | ||||
| - overlay.yaml | ||||
| images: | ||||
|   - name: myapp2 | ||||
|     newTag: v1 | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # app2/overlay.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: java | ||||
| spec: | ||||
|   template: | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: myapp2 | ||||
|         name: java | ||||
| ``` | ||||
| 
 | ||||
| **Composition Layer:** | ||||
| 
 | ||||
| ```yaml | ||||
| # kustomization.yaml | ||||
| namePrefix: app- | ||||
| namespace: app | ||||
| bases: | ||||
| - app1 | ||||
| - app2 | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| **Result**: | ||||
| 
 | ||||
| - 2 Deployments are created | ||||
| - Each Deployment has a different image and imageTag | ||||
| - Each Deployment has a different images | ||||
| - Each Deployment has different labels / selectors | ||||
| - Each Deployment has a different name | ||||
| - 2 Services are created | ||||
|  | @ -185,11 +210,11 @@ spec: | |||
| apiVersion: v1 | ||||
| kind: Service | ||||
| metadata: | ||||
|   # name has both app1 and project apply.yaml namePrefixes | ||||
|   # name has both app1 and project kustomization.yaml namePrefixes | ||||
|   name: app-1-java | ||||
|   # namespace updated by namespace in project apply.yaml | ||||
|   # namespace updated by namespace in project kustomization.yaml | ||||
|   namespace: app | ||||
|   # labels updated by commonLabels in app1 apply.yaml | ||||
|   # labels updated by commonLabels in app1 kustomization.yaml | ||||
|   labels: | ||||
|     app: app1 | ||||
| spec: | ||||
|  | @ -197,18 +222,18 @@ spec: | |||
|   - port: 8080 | ||||
|     protocol: TCP | ||||
|     targetPort: 8080 | ||||
|   # selector updated by commonLabels in app1 apply.yaml | ||||
|   # selector updated by commonLabels in app1 kustomization.yaml | ||||
|   selector: | ||||
|     app: app1 | ||||
| --- | ||||
| apiVersion: v1 | ||||
| kind: Service | ||||
| metadata: | ||||
|   # name has both app2 and project apply.yaml namePrefixes | ||||
|   # name has both app2 and project kustomization.yaml namePrefixes | ||||
|   name: app-2-java | ||||
|   # namespace updated by namespace in project apply.yaml | ||||
|   # namespace updated by namespace in project kustomization.yaml | ||||
|   namespace: app | ||||
|   # labels updated by commonLabels in app2 apply.yaml | ||||
|   # labels updated by commonLabels in app2 kustomization.yaml | ||||
|   labels: | ||||
|     app: app2 | ||||
| spec: | ||||
|  | @ -216,35 +241,35 @@ spec: | |||
|   - port: 8080 | ||||
|     protocol: TCP | ||||
|     targetPort: 8080 | ||||
|   # selector updated by commonLabels in app2 apply.yaml | ||||
|   # selector updated by commonLabels in app2 kustomization.yaml | ||||
|   selector: | ||||
|     app: app2 | ||||
| --- | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # namespace updated by namespace in project apply.yaml | ||||
|   # namespace updated by namespace in project kustomization.yaml | ||||
|   namespace: app | ||||
|   # name has both app1 and project apply.yaml namePrefixes | ||||
|   # name has both app1 and project kustomization.yaml namePrefixes | ||||
|   name: app-1-java | ||||
|   # labels updated by commonLabels in app1 apply.yaml | ||||
|   # labels updated by commonLabels in app1 kustomization.yaml | ||||
|   labels: | ||||
|     app: app1 | ||||
| spec: | ||||
|   # selector updated by commonLabels in app1 apply.yaml | ||||
|   # selector updated by commonLabels in app1 kustomization.yaml | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: app1 | ||||
|   template: | ||||
|     metadata: | ||||
|       # labels updated by commonLabels in app1 apply.yaml | ||||
|       # labels updated by commonLabels in app1 kustomization.yaml | ||||
|       labels: | ||||
|         app: app1 | ||||
|     spec: | ||||
|       containers: | ||||
|       # Image is updated by Overlay | ||||
|       # ImageTag is updated by imageTag in app1 apply.yaml | ||||
|       - image: myapp2:v2 | ||||
|       # ImageTag is updated by images in app1 kustomization.yaml | ||||
|       - image: myapp1:v2 | ||||
|         name: java | ||||
|         # ports and probes inherited from the base | ||||
|         ports: | ||||
|  | @ -265,28 +290,28 @@ spec: | |||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # namespace updated by namespace in project apply.yaml | ||||
|   # namespace updated by namespace in project kustomization.yaml | ||||
|   namespace: app | ||||
|   # name has both app2 and project apply.yaml namePrefixes | ||||
|   # name has both app2 and project kustomization.yaml namePrefixes | ||||
|   name: app-2-java | ||||
|   # labels updated by commonLabels in app2 apply.yaml | ||||
|   # labels updated by commonLabels in app2 kustomization.yaml | ||||
|   labels: | ||||
|     app: app2 | ||||
| spec: | ||||
|   # selector updated by commonLabels in app2 apply.yaml | ||||
|   # selector updated by commonLabels in app2 kustomization.yaml | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: app2 | ||||
|   template: | ||||
|     metadata: | ||||
|       # labels updated by commonLabels in app2 apply.yaml | ||||
|       # labels updated by commonLabels in app2 kustomization.yaml | ||||
|       labels: | ||||
|         app: app2 | ||||
|     spec: | ||||
|       containers: | ||||
|       # Image is updated by Overlay | ||||
|       # ImageTag is updated by imageTag in app2 apply.yaml | ||||
|       - image: myapp1:v1 | ||||
|       # ImageTag is updated by images in app2 kustomization.yaml | ||||
|       - image: myapp2:v1 | ||||
|         name: java | ||||
|         # ports and probes inherited from the base | ||||
|         ports: | ||||
|  | @ -0,0 +1,144 @@ | |||
| {% panel style="warning", title="Warning: Alpha Recommendations" %} | ||||
| This chapter contains recommendations that are still being actively evaluated, and may | ||||
| be changed in the future. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Finer grain management using separate repos for separate Team  | ||||
|   - Separate permissions for committing changes to separate environments | ||||
|   - Separate Issue, Project and PR tracking | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Repository Structure Based Composition | ||||
| 
 | ||||
| The are several techniques for users to structure their Resource Config files. | ||||
| 
 | ||||
| | Type                                        | Summary               | Benefits                                           | | ||||
| |---------------------------------------------|-----------------------|----------------------------------------------------| | ||||
| | [Directories](structure_directories.md)        | *Simplest approach*   | Easy to get started and understand               | | ||||
| | [Branches](structure_branches.md)        | *More flexible*       | Loose coupling between release specific and operation changes | | ||||
| | **[Repositories](structure_repositories.md)** | **Fine grain control**  | **Isolated permissions model**                         | | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| This chapter describes conventions for using **Repositories** with Directories. | ||||
| 
 | ||||
| **Advantages:** | ||||
| 
 | ||||
| - **Isolation between teams** managing separate Environments | ||||
|   - Permissions | ||||
| - **Fine grain control** over | ||||
|   - PRs | ||||
|   - Issues | ||||
|   - Projects | ||||
|   - Automation | ||||
|     | ||||
| **Drawbacks:** | ||||
| 
 | ||||
| - Tools designed to work with files and directories don't work across Repositories | ||||
| - Complicated to setup and manage | ||||
| - **Harder to reason about the system as a whole** | ||||
|   - State spread across multiple Repositories | ||||
| 
 | ||||
| ## Directory Structure | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| ### Resource Config | ||||
| 
 | ||||
| The convention shown here should be changed and adapted as needed. | ||||
| 
 | ||||
| Structure: | ||||
| 
 | ||||
| - Create a base Repository for shared configuration | ||||
|   - Looks like [Directories](structure_directories.md) approach | ||||
| - For each **separate Team, create a separate Repository** | ||||
|   - References the base Repository in Bases | ||||
| 
 | ||||
| Techniques: | ||||
| 
 | ||||
| - Use techniques described in [Directories](structure_directories.md) and [Branches](structure_branches.md) | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| 
 | ||||
| **Base Repository:** | ||||
| 
 | ||||
| ```bash | ||||
| $ tree | ||||
| . | ||||
| ├── bases # Used as a Base only | ||||
| │   ├── kustomization.yaml | ||||
| │   ├── backend | ||||
| │   │   ├── deployment.yaml | ||||
| │   │   └── service.yaml | ||||
| │   ├── frontend | ||||
| │   │   ├── deployment.yaml | ||||
| │   │   ├── ingress.yaml | ||||
| │   │   └── service.yaml | ||||
| │   └── storage | ||||
| │       ├── service.yaml | ||||
| │       └── statefulset.yaml | ||||
| ├── prod # Production | ||||
| │   ├── bases  | ||||
| │   │   ├── kustomization.yaml # Uses bases: ["../../bases"] | ||||
| │   │   ├── backend | ||||
| │   │   │   └── deployment-patch.yaml # Production Env specific backend overrides | ||||
| │   │   ├── frontend | ||||
| │   │   │   └── deployment-patch.yaml # Production Env specific frontend overrides | ||||
| │   │   └── storage | ||||
| │   │       └── statefulset-patch.yaml # Production Env specific storage overrides | ||||
| │   ├── us-central | ||||
| │   │   ├── kustomization.yaml # Uses bases: ["../bases"] | ||||
| │   │   └── backend | ||||
| │   │       └── deployment-patch.yaml # us-central cluster specific backend overrides | ||||
| │   ├── us-east  | ||||
| │   │   └── kustomization.yaml # Uses bases: ["../bases"] | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml # Uses bases: ["../bases"] | ||||
| ├── staging # Staging | ||||
| │   ├── bases  | ||||
| │   │   ├── kustomization.yaml # Uses bases: ["../../bases"] | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml # Uses bases: ["../bases"] | ||||
| └── test # Test | ||||
|     ├── bases  | ||||
|     │   ├── kustomization.yaml # Uses bases: ["../../bases"] | ||||
|     └── us-west  | ||||
|         └── kustomization.yaml # Uses bases: ["../bases"] | ||||
| ``` | ||||
| 
 | ||||
| **Team Repositories:** | ||||
| 
 | ||||
| ```bash | ||||
| # sre team | ||||
| $ tree | ||||
| . | ||||
| ├── prod | ||||
| │   ├── us-central | ||||
| │   │   ├── kustomization.yaml # Uses bases: ["https://<your-repo>/prod/us-central?ref=<prod-release>"] | ||||
| │   ├── us-east  | ||||
| │   │   └── kustomization.yaml # Uses bases: ["https://<your-repo>/prod/us-east?ref=<prod-release>"] | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml # Uses bases: ["https://<your-repo>/prod/us-west?ref=<prod-release>"] | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| # qa team | ||||
| $ tree | ||||
| . | ||||
| ├── staging # Staging | ||||
| │   └── us-west  | ||||
| │       └── kustomization.yaml # Uses bases: ["https://<your-repo>/staging/us-west?ref=<staging-release>"] | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| # dev team | ||||
| $ tree | ||||
| . | ||||
| └── test # Test | ||||
|     └── us-west  | ||||
|         └── kustomization.yaml # Uses bases: ["https://<your-repo>/test/us-west?ref=<test-release>"] | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,131 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Reuse Resource Config as Bases to `kustomization.yaml`'s. | ||||
| - Customize Base for different Environments. | ||||
| - Reuse a Base across multiple Projects. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Bases and Variations | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| It is common for users to deploy several **Variants of the same Resource Config**, or for different projects | ||||
| to **reuse the same Resource Config**.  The Resource Config produced by a `kustomization.yaml` can be | ||||
| reused across multiple project using the `kustomization.yaml` as a *Base*. | ||||
| 
 | ||||
| Examples: | ||||
| 
 | ||||
| - a project may be deployed to **dev, test, staging, canary and production environments**, | ||||
|   but with variants between the environments. | ||||
| - a project may be deployed to **different clusters** that are tuned differently or running | ||||
|   different versions of the project. | ||||
|    | ||||
| ## Referring to a Base | ||||
| 
 | ||||
| A project can add a Base by adding a path (relative to the `kustomization.yaml`) to **`base` that | ||||
| points to a directory** containing another `kustomization.yaml` file.  This will automatically | ||||
| add and kustomize all of the Resources from the base project to the current project. | ||||
| 
 | ||||
| Bases can be: | ||||
| 
 | ||||
| - Relative paths from the `kustomization.yaml` - e.g. `../base` | ||||
| - Urls - e.g. `github.com/kubernetes-sigs/kustomize/examples/multibases?ref=v1.0.6` | ||||
| 
 | ||||
| {% method %} | ||||
| **Example:** Add a `kustomization.yaml` as a Base. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The kustomization.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # kustomization.yaml | ||||
| bases: | ||||
| - ../base | ||||
| ``` | ||||
| 
 | ||||
| **Base: kustomization.yaml and Resource Config** | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/kustomization.yaml | ||||
| configMapGenerator: | ||||
| - name: myJavaServerEnvVars | ||||
|   literals:	 | ||||
|   - JAVA_HOME=/opt/java/jdk | ||||
|   - JAVA_TOOL_OPTIONS=-agentlib:hprof | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
|         volumeMounts: | ||||
|         - mountPath: /etc/config | ||||
|           name: config-volume | ||||
|       volumes: | ||||
|       - configMap: | ||||
|           name: myJavaServerEnvVars | ||||
|         name: config-volume | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Unmodified Generated Base Resource | ||||
| apiVersion: v1 | ||||
| kind: ConfigMap | ||||
| metadata: | ||||
|   name: myJavaServerEnvVars-k44mhd6h5f | ||||
| data: | ||||
|   JAVA_HOME: /opt/java/jdk | ||||
|   JAVA_TOOL_OPTIONS: -agentlib:hprof | ||||
| --- | ||||
| # Unmodified  Config Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
|         volumeMounts: | ||||
|         - mountPath: /etc/config | ||||
|           name: config-volume | ||||
|       volumes: | ||||
|       - configMap: | ||||
|           name: myJavaServerEnvVars-k44mhd6h5f | ||||
|         name: config-volume | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Bases in Bases" %} | ||||
| Bases themselves may also be Variants and have their own Bases. See [Advanced Composition](../app_composition_and_deployment/structure_multi_tier_apps.md) | ||||
| for more information. | ||||
| {% endpanel %} | ||||
|  | @ -1,17 +1,17 @@ | |||
| # Config Reflection | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Inject the values of other Resource Config fields into Pod Env Vars and Command Args. | ||||
| - Inject the values of other Resource Config fields into Pod Env Vars and Command Args with `vars`. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Config Reflection | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Pods may need to refer to the values of Resource Config fields.  For example | ||||
| a Pod may take the name of Service defined in the Project as a command argument. | ||||
| Instead of hard coding the value directly into the PodSpec, it is preferable | ||||
| to use a `vars` entry to reference the value by path.  This will ensure | ||||
| if the value is updated or transformed by the `apply.yaml` file, the | ||||
| value will be propagated to where it is referenced in the PodSpec.  | ||||
| Applications running in Pods may need to know about Application context or configuration. | ||||
| For example, a **Pod may take the name of Service defined in the Project as a command argument**. | ||||
| Instead of hard coding the value of the Service directly into the PodSpec, users can **reference | ||||
| the Service value using a `vars` entry**.  If the value is updated or transformed by the | ||||
| `kustomization.yaml` file (e.g. by setting a `namePrefix`), the value will be propagated | ||||
| to where it is referenced in the PodSpec.  | ||||
| 
 | ||||
| ## Vars | ||||
| 
 | ||||
|  | @ -31,22 +31,45 @@ Apply will set the resolve $(BACKEND_SERVICE_NAME) to a value using the path | |||
| specified in `vars`. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml, deployment.yaml and service.yaml files | ||||
| **Input:** The kustomization.yaml, deployment.yaml and service.yaml files | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| # kustomization.yaml | ||||
| namePrefix: "test-" | ||||
| vars: | ||||
|   # Name of the variable so it can be referenced | ||||
| - name: BACKEND_SERVICE_NAME | ||||
|   # GVK of the object with the field | ||||
|   objref: | ||||
|     kind: Service | ||||
|     name: backend-service | ||||
|     apiVersion: v1 | ||||
|   # Path to the field | ||||
|   fieldref: | ||||
|     fieldpath: metadata.name | ||||
| resources: | ||||
| - deployment.yaml | ||||
| - service.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # service.yaml | ||||
| kind: Service | ||||
| apiVersion: v1 | ||||
| metadata: | ||||
|   # Value of the variable.  This will be customized with | ||||
|   # a namePrefix, and change the Variable value. | ||||
|   name: backend-service | ||||
| spec: | ||||
|   selector: | ||||
|     app: backend | ||||
|   ports: | ||||
|   - protocol: TCP | ||||
|     port: 80 | ||||
|     targetPort: 9376 | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
|  | @ -66,20 +89,8 @@ spec: | |||
|       containers: | ||||
|       - name: curl | ||||
|         image: ubuntu | ||||
|         command: ["curl", "$(BACKEND_SERVICE)"] | ||||
|          | ||||
| # service.yaml | ||||
| kind: Service | ||||
| apiVersion: v1 | ||||
| metadata: | ||||
|   name: backend-service | ||||
| spec: | ||||
|   selector: | ||||
|     app: backend | ||||
|   ports: | ||||
|   - protocol: TCP | ||||
|     port: 80 | ||||
|     targetPort: 9376 | ||||
|         # Reference the Service name field value as a variable | ||||
|         command: ["curl", "$(BACKEND_SERVICE_NAME)"] | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resources that are Applied to the cluster | ||||
|  | @ -88,7 +99,7 @@ spec: | |||
| apiVersion: v1 | ||||
| kind: Service | ||||
| metadata: | ||||
|   name: backend-service | ||||
|   name: test-backend-service | ||||
| spec: | ||||
|   ports: | ||||
|   - port: 80 | ||||
|  | @ -100,9 +111,9 @@ spec: | |||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: test-curl-deployment | ||||
|   labels: | ||||
|     app: curl | ||||
|   name: curl-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|  | @ -116,15 +127,15 @@ spec: | |||
|       - command: | ||||
|         - curl | ||||
|         # $(BACKEND_SERVICE_NAME) has been resolved to | ||||
|         # backend-service | ||||
|         - backend-service | ||||
|         # test-backend-service | ||||
|         - test-backend-service | ||||
|         image: ubuntu | ||||
|         name: curl | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Referencing Variables" %} | ||||
| Variables are intended to allow Pods to access Resource Config values from.  They are | ||||
| {% panel style="warning", title="Referencing Variables" %} | ||||
| Variables are intended only to inject Resource Config into Pods.  They are | ||||
| **not** intended as a general templating mechanism.  Overriding values should be done with | ||||
| patches instead of variables.  See [Bases and Variations](project_variants.md). | ||||
| patches instead of variables.  See [Bases and Variations](bases_and_variants.md). | ||||
| {% endpanel %} | ||||
|  | @ -0,0 +1,226 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Customize arbitrary fields from arbitrary Resources in a Base. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Customizing Resource Fields | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| It is often necessary for users to want to **modify arbitrary fields** from a Base, such | ||||
| as resource reservations for Pods, replicas on Deployments, etc.  Overlays and patches can | ||||
| be used by Variants to specify fields values which will override the Base field values. | ||||
|   | ||||
| ## Customizing Arbitrary Fields with Overlays | ||||
| 
 | ||||
| {% method %} | ||||
| Arbitrary **fields may be added, changed, or deleted** by supplying *Overlays* against the | ||||
| Resources provided by the Base.  **Overlays are sparse Resource definitions** that | ||||
| allow arbitrary customizations to be performed without requiring a base to expose | ||||
| the customization as a template. | ||||
| 
 | ||||
| Overlays require the *Group, Version, Kind* and *Name* of the Resource to be specified, as | ||||
| well as any fields that should be set on the base Resource.  Overlays are applied using | ||||
| *StrategicMergePatch*. | ||||
| 
 | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) require fields such as | ||||
| replicas or resources to be overridden. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The kustomization.yaml file and overlay | ||||
| 
 | ||||
| ```yaml | ||||
| # kustomization.yaml | ||||
| bases: | ||||
| - ../base | ||||
| patchesStrategicMerge: | ||||
| - overlay.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # overlay.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # override replicas | ||||
|   replicas: 3 | ||||
|   template: | ||||
|     spec: | ||||
|       containers: | ||||
|       - name: nginx | ||||
|         # override resources | ||||
|         resources: | ||||
|           limits: | ||||
|             cpu: "1" | ||||
|           requests: | ||||
|             cpu: "0.5" | ||||
| ``` | ||||
| 
 | ||||
| **Base:** | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/kustomization.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
|         resources: | ||||
|           limits: | ||||
|             cpu: "0.2" | ||||
|           requests: | ||||
|             cpu: "0.1"         | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Overlayed Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # replicas field has been added | ||||
|   replicas: 3 | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
|         # resources have been overridden | ||||
|         resources: | ||||
|           limits: | ||||
|             cpu: "1" | ||||
|           requests: | ||||
|             cpu: "0.5" | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Merge Semantics for Overlays" %} | ||||
| Overlays use the same [merge semantics](../app_management/field_merge_semantics.md) as Applying Resource Config to cluster.  One difference | ||||
| is that there is no *Last Applied Resource Config* when merging overlays, so fields may only be deleted | ||||
| if they are explicitly set to nil. | ||||
| {% endpanel %} | ||||
|      | ||||
| ## Customizing Arbitrary Fields with JsonPatch | ||||
| 
 | ||||
| {% method %} | ||||
| Arbitrary fields may be added, changed, or deleted by supplying *Json 6902 Patches* against the | ||||
| Resources provided by the base. | ||||
| 
 | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) require fields such as | ||||
| replicas or resources to be overridden. | ||||
| 
 | ||||
| Json 6902 Patches are [rfc6902](https://tools.ietf.org/html/rfc6902) patches that are applied | ||||
| to resources.  Patches require the *Group, Version, Kind* and *Name* of the Resource to be | ||||
| specified in addition to the Patch.  Patches offer a number of powerful imperative operations | ||||
| for modifying the base Resources. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The kustomization.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # kustomization.yaml | ||||
| bases: | ||||
| - ../base | ||||
| patchesJson6902: | ||||
| - target: | ||||
|     group: apps | ||||
|     version: v1 | ||||
|     kind: Deployment | ||||
|     name: nginx-deployment | ||||
|   path: patch.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # patch.yaml | ||||
| - op: add | ||||
|   path: /spec/replicas | ||||
|   value: 3 | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/kustomization.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Patched Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # replicas field has been added | ||||
|   replicas: 3 | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,271 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Customize Base Resource Namespaces | ||||
| - Customize Base Resource Names with Prefixes or Suffixes | ||||
| - Customize Base Resource Labels or Annotations | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Customizing Resource Metadata | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| It is common for users to customize the metadata of their Applications - including | ||||
| the **names, namespaces, labels and annotations**. | ||||
| 
 | ||||
| Examples: | ||||
| 
 | ||||
| - Overriding the Namespace | ||||
| - Overriding the Names of Resources by supplying a Prefix or Suffix | ||||
| - Overriding Labels and Annotations | ||||
| - Running **multiple instances of the same White-Box Base** using the above techniques | ||||
|   | ||||
| ## Customizing Resource Namespaces | ||||
| 
 | ||||
| {% method %} | ||||
| **Use Case:** | ||||
| - Change the Namespace for Resources from Base. | ||||
| 
 | ||||
| Customize the Namespace of all Resources in the Base by adding `namespace`. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The kustomization.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # kustomization.yaml | ||||
| bases: | ||||
| - ../base | ||||
| namespace: test | ||||
| ``` | ||||
| 
 | ||||
| **Base:** | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/kustomization.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
|   namespace: default | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Modified Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
|   # Namepace has been changed to test | ||||
|   namespace: test | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|   | ||||
| ## Customizing Resource Name Prefixes and Suffixes | ||||
| 
 | ||||
| {% method %} | ||||
| **Use Case:** | ||||
| - Run multiple instances of the same Base. | ||||
| - Create naming conventions for different Environments (test, dev, staging, canary, prod). | ||||
| 
 | ||||
| Customize the Name of all Resources in the Base by adding `namePrefix` or `nameSuffix` in Variants. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The kustomization.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # kustomization.yaml | ||||
| bases: | ||||
| - ../base | ||||
| namePrefix: test- | ||||
| ``` | ||||
| 
 | ||||
| **Base:** | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/kustomization.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Modified Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   # Name has been prefixed with the environment | ||||
|   name: test-nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| See [Namespaces and Names](../app_management/namespaces_and_names.md). | ||||
| 
 | ||||
| {% panel style="success", title="Chaining Name Prefixes" %} | ||||
| Name Prefix's and Suffix's in Bases will be concatenated with Name Prefix's | ||||
| and Suffix's specified in Variants - e.g. if a Base has a Name Prefix of `app-name-` | ||||
| and the Variant has a Name Prefix of `test-` the Applied Resources will have | ||||
| a Name Prefix of `test-app-name-`. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## Customizing Resource Labels and Annotations | ||||
| 
 | ||||
| {% method %} | ||||
| **Use Case:** | ||||
| - Create Label or Annotation conventions for different Environments (test, dev, staging, canary, prod). | ||||
| 
 | ||||
| Customize the Labels and Annotations of all Resources in the Base by adding a | ||||
| `commonLabels` or `commonAnnotations` in the variants. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The kustomization.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # kustomization.yaml | ||||
| bases: | ||||
| - ../base | ||||
| commonLabels: | ||||
|   app: test-nginx | ||||
|   environment: test | ||||
| commonAnnotations: | ||||
|   oncallPager: 800-555-1212 | ||||
| ``` | ||||
| 
 | ||||
| **Base:** | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/kustomization.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|     base: label | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Modified Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # labels have been overridden | ||||
|   labels: | ||||
|     app: test-nginx | ||||
|     environment: test | ||||
|     base: label | ||||
|   # annotations have been overridden | ||||
|   annotations: | ||||
|     oncallPager: 800-555-1212 | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: test-nginx | ||||
|       environment: test | ||||
|       base: label | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|        app: test-nginx | ||||
|        environment: test | ||||
|        base: label | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,338 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Override Base Pod and PodTemplate Image Tags | ||||
| - Override Base Pod and PodTemplate Environment Variables and Arguments | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Customizing Pods | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| It is common for users to customize their Applications for specific environments. | ||||
| Simple customizations to Pod Templates may be through **Images, Environment Variables and | ||||
| Command Line Arguments**. | ||||
| 
 | ||||
| Common examples include: | ||||
| 
 | ||||
| - Running **different versions of an Image** for dev, test, canary, production | ||||
| - Configuring **different Pod Environment Variables and Arguments** for dev, test, canary, production | ||||
|   | ||||
| ## Customizing Images | ||||
| 
 | ||||
| {% method %} | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) use images with different tags. | ||||
| 
 | ||||
| Override the tag for an `image` field from a Pod Template in a base by specifying the `images` field in the | ||||
| `kustomization.yaml`.  The `newTag` may be specified to override the image tag for images whose image | ||||
| name matches `name`. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The `kustomization.yaml` file | ||||
| 
 | ||||
| ```yaml | ||||
| # kustomization.yaml | ||||
| bases: | ||||
| - ../base | ||||
| images: | ||||
|   - name: nginx-pod | ||||
|     newTag: 1.15 | ||||
| ``` | ||||
| 
 | ||||
| **Base:** Resources to be modified by the `kustomization.yaml` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/kustomization.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: nginx-deployment | ||||
|   labels: | ||||
|     app: nginx | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - name: nginx | ||||
|         image: nginx-pod | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Modified Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       # The image image tag has been changed for the container | ||||
|       - name: nginx | ||||
|         image: nginx-pod:1.15 | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| 
 | ||||
| {% panel style="info", title="More Info" %} | ||||
| For more information on customizing images, see [Container Images](../app_management/container_images.md). | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## Customizing Pod Environment Variables | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) are configured with | ||||
| different Environment Variables. | ||||
| 
 | ||||
| Override Pod Environment Variables. | ||||
| 
 | ||||
| - Base uses ConfigMap data in Pods as Environment Variables | ||||
| - Each Variant overrides or extends ConfigMap data | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The kustomization.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # kustomization.yaml | ||||
| bases: | ||||
| - ../base | ||||
| configMapGenerator: | ||||
| - name: special-config | ||||
|   behavior: merge | ||||
|   literals: | ||||
|   - special.how=very # override the base value | ||||
|   - special.type=charm # add a value to the base | ||||
| ``` | ||||
| 
 | ||||
| **Base: kustomization.yaml and Resources** | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/kustomization.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| configMapGenerator: | ||||
| - name: special-config | ||||
|   behavior: merge | ||||
|   literals: | ||||
|   - special.how=some # this value is overridden | ||||
|   - special.other=that # this value is kept | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: nginx-deployment | ||||
|   labels: | ||||
|     app: nginx | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - name: nginx | ||||
|         image: nginx | ||||
|         envFrom: | ||||
|         - configMapRef: | ||||
|             name: special-config | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resources that are Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Generated Variant Resource | ||||
| apiVersion: v1 | ||||
| kind: ConfigMap | ||||
| metadata: | ||||
|   name: special-config-82tc88cmcg | ||||
| data: | ||||
|   special.how: very | ||||
|   special.type: charm | ||||
|   special.other: that | ||||
| --- | ||||
| # Unmodified Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - name: nginx | ||||
|         image: nginx | ||||
|         envFrom: | ||||
|         # Container env will have the overridden ConfigMap values | ||||
|         - configMapRef: | ||||
|             name: special-config-82tc88cmcg | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| See [ConfigMaps and Secrets](../app_management/secrets_and_configmaps.md). | ||||
| 
 | ||||
| 
 | ||||
| ## Customizing Pod Command Arguments | ||||
| 
 | ||||
| {% method %} | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) provide different Commandline | ||||
| Arguments to a Pod. | ||||
| 
 | ||||
| Override Pod Command Arguments. | ||||
| 
 | ||||
| - Base uses ConfigMap data in Pods as Command Arguments | ||||
| - Each Variant defines different ConfigMap data | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The kustomization.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # kustomization.yaml | ||||
| bases: | ||||
| - ../base | ||||
| configMapGenerator: | ||||
| - name: special-config | ||||
|   behavior: merge | ||||
|   literals: | ||||
|   - SPECIAL_LEVEL=very | ||||
|   - SPECIAL_TYPE=charm | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/kustomization.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| 
 | ||||
| configMapGenerator: | ||||
| - name: special-config | ||||
|   literals: | ||||
|   - SPECIAL_LEVEL=override.me | ||||
|   - SPECIAL_TYPE=override.me | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: nginx-deployment | ||||
|   labels: | ||||
|     app: nginx | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - name: test-container | ||||
|         image: k8s.gcr.io/busybox | ||||
|         command: [ "/bin/sh" ] | ||||
|         # Use the ConfigMap Environment Variables in the Command | ||||
|         args: ["-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] | ||||
|         env: | ||||
|           - name: SPECIAL_LEVEL_KEY | ||||
|             valueFrom: | ||||
|               configMapKeyRef: | ||||
|                 name: special-config | ||||
|                 key: SPECIAL_LEVEL | ||||
|           - name: SPECIAL_TYPE_KEY | ||||
|             valueFrom: | ||||
|               configMapKeyRef: | ||||
|                 name: special-config | ||||
|                 key: SPECIAL_TYPE | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resources that are Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Generated Variant Resource | ||||
| apiVersion: v1 | ||||
| kind: ConfigMap | ||||
| metadata: | ||||
|   name: special-config-82tc88cmcg | ||||
| data: | ||||
|   SPECIAL_LEVEL: very | ||||
|   SPECIAL_TYPE: charm | ||||
| --- | ||||
| # Unmodified Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: k8s.gcr.io/busybox | ||||
|         name: test-container | ||||
|         command: | ||||
|         - /bin/sh | ||||
|         args: | ||||
|         - -c | ||||
|         # Container args will have the overridden ConfigMap values | ||||
|         - echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY) | ||||
|         env: | ||||
|         - name: SPECIAL_LEVEL_KEY | ||||
|           valueFrom: | ||||
|             configMapKeyRef: | ||||
|               key: SPECIAL_LEVEL | ||||
|               name: special-config-82tc88cmcg | ||||
|         - name: SPECIAL_TYPE_KEY | ||||
|           valueFrom: | ||||
|             configMapKeyRef: | ||||
|               key: SPECIAL_TYPE | ||||
|               name: special-config-82tc88cmcg | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="More Info" %} | ||||
| See [Secrets and ConfigMaps](../app_management/secrets_and_configmaps.md) for more information on ConfigMap and Secret generation. | ||||
| {% endpanel %} | ||||
| 
 | ||||
|  | @ -0,0 +1,12 @@ | |||
| # Introduction | ||||
| 
 | ||||
| This section of the book covers how to build Projects and Applications with multiple subcomponents | ||||
| partially defined by multiple teams or organizations.  Apply kustomizations allow the authoring | ||||
| of Resource Config to be a collaboration across teams. | ||||
| 
 | ||||
| Kustomizations facilitate: | ||||
| 
 | ||||
| - Developing Variations of Resource Config for multiple Environments with different configurations | ||||
| - Developing Variations of Resource Config for multiple Clusters with different configurations | ||||
| - Developing and Publishing Ready-Made Resource Config for users to extend and customize | ||||
| - Composing Resource Config from multiple sources | ||||
|  | @ -0,0 +1,133 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Apply Creates and Updates Resources in a cluster through running `kubectl apply` on Resource Config. | ||||
| - Apply manages complexity such as ordering of operations and merging user defined and cluster defined state. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Apply | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Apply will update a Kubernetes cluster to match state defined locally in files. | ||||
| 
 | ||||
| - Fully declarative - don't need to specify create or update - just manage files | ||||
| - Merges user owned state (e.g. Service `selector`) with state owned by the cluster (e.g. Service `clusterIp`) | ||||
| 
 | ||||
| ## Definitions | ||||
| 
 | ||||
| - **Resources**: *Objects* in a cluster - e.g. Deployments, Services, etc. | ||||
| - **Resource Config**: *Files* declaring the desired state for Resources - e.g. deployment.yaml. | ||||
|   Resources are created and updated using Apply with these files. | ||||
| 
 | ||||
| *kubectl apply* Creates and Updates Resources through local or remote files.  This may be through | ||||
| either raw Resource Config or *kustomization.yaml*. | ||||
| 
 | ||||
| ## Usage | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| It is recommended to use a `kustomization.yaml` with Apply.  `kustomization.yaml` provides low-level | ||||
| tooling to simplify managing collections of Resources Configs. | ||||
| 
 | ||||
| This `kustomization.yaml` file contains a Deployment Resource Config which will be Applied. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```yaml | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| 
 | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: nginx | ||||
|   labels: | ||||
|     app: nginx | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - name: nginx | ||||
|         image: nginx:1.15.4 | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| Users run Apply on directories containing `kustomization.yaml` files using `-k` or on raw | ||||
| ResourceConfig files using `-f`. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| ```bash | ||||
| # Apply the Resource Config | ||||
| $ kubectl apply -k . | ||||
| 
 | ||||
| # View the Resources | ||||
| $ kubectl get -k . | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Multi-Resource Configs" %} | ||||
| A single Resource Config file may declare multiple Resources separated by `\n---\n`. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## CRUD Operations | ||||
| 
 | ||||
| ### Creating Resources | ||||
| 
 | ||||
| Any Resources that do not exist and are declared in Resource Config when Apply is run will be Created. | ||||
| 
 | ||||
| ### Updating Resources | ||||
| 
 | ||||
| Any Resources that already exist and are declared in Resource Config when Apply is run may be Updated. | ||||
| 
 | ||||
| **Added Fields** | ||||
| 
 | ||||
| Any fields that have been added to the Resource Config will be set on the Resource. | ||||
| 
 | ||||
| **Updated Fields**  | ||||
|   | ||||
| Any fields that contain different values for the fields specified locally in the Resource Config from what is | ||||
| in the Resource will be updated by merging the Resource Config into the live Resource.  See [merging](field_merge_semantics.md) | ||||
| for more details. | ||||
| 
 | ||||
| **Deleted Fields** | ||||
| 
 | ||||
| Fields that were in the Resource Config the last time Apply was run, will be deleted from the Resource, and | ||||
| return to their default values. | ||||
| 
 | ||||
| **Unmanaged Fields** | ||||
| 
 | ||||
| Fields that were not specified in the Resource Config but are set on the Resource will be left unmodified. | ||||
| 
 | ||||
| ### Deleting Resources | ||||
| 
 | ||||
| Declarative deletion of Resources does not yet exist in a usable form, but is under development. | ||||
| 
 | ||||
| {% panel style="info", title="Continuously Applying The Hard Way" %} | ||||
| In some cases, it may be useful to automatically Apply changes when ever the Resource Config is changed. | ||||
| 
 | ||||
| This example uses the unix `watch` command to periodically invoke Apply against a target. | ||||
| `watch -n 60 kubectl apply -k https://github.com/myorg/myrepo` | ||||
| 
 | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## Resource Creation Ordering | ||||
| 
 | ||||
| Certain Resource Types may be dependent on other Resource Types being created first.  e.g. Namespaced | ||||
| Resources on the Namespaces, RoleBindings on Roles, CustomResources on the CRDs, etc. | ||||
| 
 | ||||
| When used with a `kustomization.yaml`, Apply sorts the Resources by Resource type to ensure Resources | ||||
| with these dependencies are created in the correct order. | ||||
|  | @ -1,47 +1,53 @@ | |||
| # Container Image Tags | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Set the Tag for all Container Images matching a Name | ||||
| - Set the Tag for Container Images from another source (e.g. Git Hash) | ||||
| - Override or set the Tag for Container Images | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Container Images | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| It may be useful to specify the tags that are used for specific container images across many Workloads. | ||||
| It may be useful to define the tags of container images which are | ||||
| used across many Workloads. | ||||
| 
 | ||||
| - The same image tag is used for multiple different container images  | ||||
| - The same container image is used in multiple containers or Workloads | ||||
| - Increase visibility of the versions of container images being used within the project | ||||
| - Setting the image tag from external sources - such as environment variables | ||||
| - Update the container image tag for multiple Workloads at once | ||||
| - Increase visibility of the versions of container images being used within | ||||
|   the project | ||||
| - Set the image tag from external sources - such as environment variables | ||||
| - Copy or Fork an existing Project and change the Image Tag for a container | ||||
| - Change the registry used for an image | ||||
| 
 | ||||
| See [Bases and Variations](project_variants.md) for more details on Copying Projects. | ||||
| See [Bases and Variations](../app_customization/bases_and_variants.md) for more details on Copying Projects. | ||||
| 
 | ||||
| ## imageTags | ||||
| ## images | ||||
| 
 | ||||
| It is possible to set image tags for container images by name through `apply.yaml` using the `imageTags` | ||||
| field.  When `imageTags` are specified, Apply will set the image tag for all images | ||||
| that match the name and **do not** have a tag already specified. | ||||
| It is possible to set image image tags for container images through  | ||||
| the `kustomization.yaml` using the `images` field.  When `images` are  | ||||
| specified, Apply will override the images whose image name matches `name` with a new | ||||
| tag. | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| **Example:** Set the `imageTags` specified in the `apply.yaml` on the container images specified | ||||
| in `deployment.yaml` | ||||
| **Example:** Use `images` in the `kustomization.yaml` to update the container | ||||
| images in `deployment.yaml` | ||||
| 
 | ||||
| Apply will set the `nginx` image to have the tag `1.8.0` - e.g. `nginx:1.8.0`. | ||||
| This will set the tag for *all* untagged images matching the *name*. | ||||
| This will set the tag for *all* images matching the *name*. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml and deployment.yaml files | ||||
| **Input:** The kustomization.yaml and deployment.yaml files | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| imageTags: | ||||
|   - name: nginx | ||||
|     newTag: 1.8.0 | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| images: | ||||
|   - name: nginx # match images with this name | ||||
|     newTag: 1.8.0 # override the tag | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
|  | @ -95,8 +101,10 @@ spec: | |||
| The tag for an image may be set by specifying `newTag` and the name of the container image. | ||||
| {% sample lang="yaml" %} | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| imageTags: | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| images: | ||||
|   - name: mycontainerregistry/myimage | ||||
|     newTag: v1 | ||||
| ``` | ||||
|  | @ -108,13 +116,16 @@ imageTags: | |||
| The digest for an image may be set by specifying `digest` and the name of the container image. | ||||
| {% sample lang="yaml" %} | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| imageTags: | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| images: | ||||
|   - name: alpine | ||||
|     digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| 
 | ||||
| ## Setting a Tag from the latest commit SHA | ||||
| 
 | ||||
| {% method %} | ||||
|  | @ -122,7 +133,8 @@ A common CICD pattern is to tag container images with the git commit SHA of sour | |||
| the image name is `foo` and an image was built for the source code at commit `1bb359ccce344ca5d263cd257958ea035c978fd3` | ||||
| then the conatiner image would be `foo:1bb359ccce344ca5d263cd257958ea035c978fd3`. | ||||
| 
 | ||||
| A simple way to push an image that was just build without manually updating the image tags is to use the | ||||
| A simple way to push an image that was just built without manually updating the image tags is to | ||||
| download the [kustomize standalone](https://github.com/kubernetes-sigs/kustomize/) tool and run | ||||
| `kustomize edit set imagetag` command to update the tags for you. | ||||
| 
 | ||||
| **Example:** Set the latest git commit SHA as the image tag for `foo` images. | ||||
|  | @ -143,13 +155,14 @@ It is also possible to set a Tag from an environment variable using the same tec | |||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| ```bash | ||||
| $ kustomize edit set imagetag foo:$FOO_IMAGE_TAG | ||||
| $ kustomize edit set image foo:$FOO_IMAGE_TAG | ||||
| $ kubectl apply -f . | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Committing Image Tag Updates" %} | ||||
| The `apply.yaml` changes *may* be committed back to git so that they can be audited.  When committing the image tag | ||||
| updates that have already been pushed by a CICD system, be careful not to trigger new builds + deployments for | ||||
| these changes. | ||||
| The `kustomization.yaml` changes *may* be committed back to git so that they | ||||
| can be audited.  When committing the image tag updates that have already  | ||||
| been pushed by a CICD system, be careful not to trigger new builds +  | ||||
| deployments for these changes. | ||||
| {% endpanel %} | ||||
|  | @ -0,0 +1,473 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Fields set and deleted from Resource Config are merged into Resources by Apply | ||||
|     - If a Resource already exists, Apply updates the Resources by merging the local Resource Config into the remote Resources | ||||
|     - Fields removed from the Resource Config will be deleted from the remote Resource | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Merging Fields | ||||
| 
 | ||||
| ## When are fields merged? | ||||
| 
 | ||||
| This page describes how Resource Config is merged with Resources or other Resource Config.  This | ||||
| may occur when: | ||||
| 
 | ||||
| - Applying Resource Config updates to the live Resources in the cluster  | ||||
| - Defining Patches in the `kustomization.yaml` which are overlayed on `resources` and [bases](../app_customization/bases_and_variants.md) | ||||
| 
 | ||||
| ### Applying Resource Config Updates | ||||
| 
 | ||||
| Rather than replacing the Resource with the new Resource Config, **Apply will merge the new Resource Config | ||||
| into the live Resource**.  This retains values which may be set by the control plane - such as `replicas` values | ||||
| set by auto scalers | ||||
| 
 | ||||
| ### Defining Patches | ||||
| 
 | ||||
| `patches` are sparse Resource Config which **contain a subset of fields that override values | ||||
| defined in other Resource Config** with the same Group/Version/Kind/Namespace/Name. | ||||
| This is used to alter values defined on Resource Config without having to fork it. | ||||
| 
 | ||||
| ## Motivation (Apply) | ||||
| 
 | ||||
| This page describes the semantics for merging Resource Config. | ||||
| 
 | ||||
| Ownership of Resource fields are shared between declarative Resource Config authored by human | ||||
| users, and values set by Controllers running in the cluster.  Some fields, such as the `status` | ||||
| and `clusterIp` fields, are owned exclusively by Controllers.  Fields, such as the `name` | ||||
| and `namespace` fields, are owned exclusively by the human user managing the Resource. | ||||
| 
 | ||||
| Other fields, such as `replicas`, may be owned by either human users, the apiserver or | ||||
| Controllers.  For example, `replicas` may be explicitly set by a user, implicitly set | ||||
| to a default value by the apiserver, or continuously adjusted by a Controller such as | ||||
| and HorizontalPodAutoscaler. | ||||
| 
 | ||||
| {% method %} | ||||
| ### Last Applied Resource Condfig | ||||
| 
 | ||||
| When Apply creates or updates a Resource, it writes the Resource Config it Applied to an annotation on the | ||||
| Resource.  This allows it to compare the last Resource Config it Applied to the current Resource | ||||
| Config and identify fields that have been deleted. | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml (Resource Config) | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - name: nginx | ||||
|         image: nginx:1.7.9 | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Original Resource | ||||
| Doesn't Exist | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Applied Resource | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   annotations: | ||||
|     # ... | ||||
|     # This is the deployment.yaml Resource Config written as an annotation on the object | ||||
|     # It was written by kubectl apply when the object was created | ||||
|     kubectl.kubernetes.io/last-applied-configuration: | | ||||
|       {"apiVersion":"apps/v1","kind":"Deployment", | ||||
|       "metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"}, | ||||
|       "spec":{"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}}, | ||||
|       "spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx"}]}}}} | ||||
|   # ... | ||||
| spec: | ||||
|   # ... | ||||
| status: | ||||
|   # ... | ||||
| 
 | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ## Merging Resources | ||||
| 
 | ||||
| Following are the merge semantics for Resources: | ||||
| 
 | ||||
| {% method %} | ||||
| **Adding Fields:** | ||||
| 
 | ||||
| - Fields present in the Resource Config that are missing from the Resource will be added to the | ||||
|   Resource. | ||||
| - Fields will be added to the Last Applied Resource Config | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml (Resource Config) | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # ... | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # ... | ||||
|   minReadySeconds: 3 | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Original Resource | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # ... | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # ... | ||||
| status: | ||||
|   # ... | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Applied Resource | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # ... | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # ... | ||||
|   minReadySeconds: 3 | ||||
| status: | ||||
|   # ... | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| **Updating Fields** | ||||
| 
 | ||||
| - Fields present in the Resource Config that are also present in the Resource will be merged recursively | ||||
|   until a primitive field is updated, or a field is added / deleted. | ||||
| - Fields will be updated in the Last Applied Resource Config | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml (Resource Config) | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # ... | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # ... | ||||
|   replicas: 2 | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Original Resource | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # ... | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # ... | ||||
|   # could be defaulted or set by Resource Config | ||||
|   replicas: 1 | ||||
| status: | ||||
|   # ... | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Applied Resource | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # ... | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # ... | ||||
|   # updated | ||||
|   replicas: 2 | ||||
| status: | ||||
|   # ... | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| **Deleting Fields** | ||||
| 
 | ||||
| - Fields present in the **Last Applied Resource Config** that have been removed from the Resource Config | ||||
|   will be deleted from the Resource. | ||||
| - Fields set to *null* in the Resource Config that are present in the Resource Config will be deleted from the | ||||
|   Resource. | ||||
| - Fields will be removed from the Last Applied Resource Config | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml (Resource Config) | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # ... | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # ... | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Original Resource | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # ... | ||||
|   name: nginx-deployment | ||||
|   # Containers replicas and minReadySeconds | ||||
|   kubectl.kubernetes.io/last-applied-configuration: | | ||||
|       {"apiVersion":"apps/v1","kind":"Deployment", "spec":{"replicas": "2", "minReadySeconds": "3", ...}, "metadata": {...}} | ||||
| spec: | ||||
|   # ... | ||||
|   minReadySeconds: 3 | ||||
|   replicas: 2 | ||||
| status: | ||||
|   # ... | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Applied Resource | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   # ... | ||||
|   name: nginx-deployment | ||||
|   kubectl.kubernetes.io/last-applied-configuration: | | ||||
|       {"apiVersion":"apps/v1","kind":"Deployment", "spec":{...}, "metadata": {...}} | ||||
| spec: | ||||
|   # ... | ||||
|   # deleted and then defaulted, but not in Last Applied | ||||
|   replicas: 1 | ||||
|   # minReadySeconds deleted | ||||
| status: | ||||
|   # ... | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="danger", title="Removing Fields from Resource Config" %} | ||||
| Simply removing a field from the Resource Config will *not* transfer the ownership to the cluster. | ||||
| Instead it will delete the field from the Resource.  If a field is set in the Resource Config and | ||||
| the user wants to give up ownership (e.g. removing `replicas` from the Resource Config and using | ||||
| and autoscaler), the user must first remove it from the last Applied Resource Config stored by the | ||||
| cluster. | ||||
| 
 | ||||
| This can be performed using `kubectl apply edit-last-applied` to delete the `replicas` field from | ||||
| the **Last Applied Resource Config**, and then deleting it from the **Resource Config.** | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## Field Merge Semantics | ||||
| 
 | ||||
| ### Merging Primitives | ||||
| 
 | ||||
| Primitive fields are merged by replacing the current value with the new value. | ||||
| 
 | ||||
| **Field Creation:** Add the primitive field | ||||
| 
 | ||||
| **Field Update:** Change the primitive field value | ||||
| 
 | ||||
| **Field Deletion:** Delete the primitive field | ||||
| 
 | ||||
| | Field in Resource Config  | Field in Resource | Field in Last Applied | Action                                  | | ||||
| |---------------------------|-------------------|-----------------------|-----------------------------------------| | ||||
| | Yes                       | Yes               | -                     | Set live to the Resource Config value.  | | ||||
| | Yes                       | No                | -                     | Set live to the Resource Config value.  | | ||||
| | No                        | -                 | Yes                   | Remove from Resource.                   | | ||||
| | No                        | -                 | No                    | Do nothing.                             | | ||||
| 
 | ||||
| 
 | ||||
| ### Merging Objects | ||||
| 
 | ||||
| Objects fields are updated by merging the sub-fields recursively (by field name) until a primitive field is found or | ||||
| the field is added / deleted. | ||||
| 
 | ||||
| **Field Creation:** Add the object field | ||||
| 
 | ||||
| **Field Update:** Recursively compare object sub-field values and merge them | ||||
| 
 | ||||
| **Field Deletion:** Delete the object field | ||||
| 
 | ||||
| **Merge Table:** For each field merge Resource Config and Resource values with the same name | ||||
| 
 | ||||
| | Field in Resource Config  | Field in Resource | Field in Last Applied | Action                                    | | ||||
| |---------------------------|-------------------|-----------------------|-------------------------------------------| | ||||
| | Yes                       | Yes               | -                     | Recursively merge the Resource Config and Resource values.         | | ||||
| | Yes                       | No                | -                     | Set live to the Resource Config value.    | | ||||
| | No                        | -                 | Yes                   | Remove field from Resource.                     | | ||||
| | No                        | -                 | No                    | Do nothing.                               | | ||||
| 
 | ||||
| ### Merging Maps | ||||
| 
 | ||||
| Map fields are updated by merging the elements (by key) until a primitive field is found or the value is | ||||
| added / deleted. | ||||
| 
 | ||||
| **Field Creation:** Add the map field | ||||
| 
 | ||||
| **Field Update:** Recursively compare map values by key and merge them | ||||
| 
 | ||||
| **Field Deletion:** Delete the map field | ||||
| 
 | ||||
| **Merge Table:** For each map element merge Resource Config and Resource values with the same key | ||||
| 
 | ||||
| | Key in Resource Config    | Key   in Resource | Key in Last Applied   | Action                                    | | ||||
| |---------------------------|-------------------|-----------------------|-------------------------------------------| | ||||
| | Yes                       | Yes               | -                     | Recursively merge the Resource Config and Resource values.        | | ||||
| | Yes                       | No                | -                     | Set live to the Resource Config value.    | | ||||
| | No                        | -                 | Yes                   | Remove map element from Resource.                     | | ||||
| | No                        | -                 | No                    | Do nothing.                               | | ||||
| 
 | ||||
| ### Merging Lists of Primitives | ||||
| 
 | ||||
| Lists of primitives will be merged if they have a `patch strategy: merge` on the field otherwise they will | ||||
| be replaced.  [Finalizer list example](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.12/#objectmeta-v1-meta) | ||||
| 
 | ||||
| **Merge Strategy:** | ||||
| 
 | ||||
| - Merged primitive lists behave like ordered sets | ||||
| - Replace primitive lists are replaced when merged | ||||
| 
 | ||||
| **Ordering:** Uses the ordering specified in the Resource Config.  Elements not specified in the Resource Config | ||||
| do not have ordering guarantees with respect to the elements in the Resource Config. | ||||
| 
 | ||||
| **Merge Table:** For each list element merge Resource Config and Resource element with the same value | ||||
| 
 | ||||
| | Element in Resource Config  | Element in Resource | Element in Last Applied | Action                                  | | ||||
| |---------------------------|-------------------|-----------------------|-----------------------------------------| | ||||
| | Yes                       | Yes               | -                     | Do nothing  | | ||||
| | Yes                       | No                | -                     | Add to list.  | | ||||
| | No                        | -                 | Yes                   | Remove from list.                   | | ||||
| | No                        | -                 | No                    | Do nothing.                             | | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| This merge strategy uses the patch merge key to identify container elements in a list and merge them. | ||||
| The `patch merge key` is defined in the [Kubernetes API](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.12/#podspec-v1-core) | ||||
| on the field. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```yaml | ||||
| # Last Applied | ||||
| args: ["a", "b"] | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Resource Config (Local) | ||||
| args: ["a", "c"] | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Resource (Live) | ||||
| args: ["a", "b", "d"] | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Applied Resource | ||||
| args: ["a", "c", "d"] | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ### Merging Lists of Objects | ||||
| 
 | ||||
| **Merge Strategy:** Lists of primitives may be merged or replaced.  Lists are merged if the list has a `patch strategy` of *merge* | ||||
| and a `patch merge key` on the list field.  [Container list example](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.12/#podspec-v1-core). | ||||
| 
 | ||||
| **Merge Key:** The `patch merge key` is used to identify same elements in a list.  Unlike map elements (keyed by key) and object fields | ||||
| (keyed by field name), lists don't have a built-in merge identity for elements (index does not define identity). | ||||
| Instead an object field is used as a synthetic *key/value* for merging elements.  This fields is the | ||||
| `patch merge key`.  List elements with the same patch merge key will be merged when lists are merged. | ||||
| 
 | ||||
| **Ordering:** Uses the ordering specified in the Resource Config.  Elements not specified in the Resource Config | ||||
| do not have ordering guarantees. | ||||
| 
 | ||||
| **Merge Table:** For each list element merge Resource Config and Resource element where the elements have the same | ||||
| value for the `patch merge key` | ||||
| 
 | ||||
| | Element in Resource Config  | Element in Resource | Element in Last Applied | Action                                  | | ||||
| |---------------------------|-------------------|-----------------------|-----------------------------------------| | ||||
| | Yes                       | -               | -                       | Recursively merge the Resource Config and Resource values.  | | ||||
| | Yes                       | No                | -                     | Add to list.  | | ||||
| | No                        | -                 | Yes                   | Remove from list.                   | | ||||
| | No                        | -                 | No                    | Do nothing.                             | | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| This merge strategy uses the patch merge key to identify container elements in a list and merge them. | ||||
| The `patch merge key` is defined in the [Kubernetes API](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.12/#podspec-v1-core) | ||||
| on the field. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```yaml | ||||
| # Last Applied Resource Config | ||||
| containers: | ||||
| - name: nginx          # key: nginx | ||||
|   image: nginx:1.10 | ||||
| - name: nginx-helper-a # key: nginx-helper-a; will be deleted in result | ||||
|   image: helper:1.3 | ||||
| - name: nginx-helper-b # key: nginx-helper-b; will be retained | ||||
|   image: helper:1.3 | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Resource Config (Local) | ||||
| containers: | ||||
| - name: nginx | ||||
|   image: nginx:1.10 | ||||
| - name: nginx-helper-b | ||||
|   image: helper:1.3 | ||||
| - name: nginx-helper-c # key: nginx-helper-c; will be added in result | ||||
|   image: helper:1.3 | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Resource (Live) | ||||
| containers: | ||||
| - name: nginx | ||||
|   image: nginx:1.10 | ||||
| - name: nginx-helper-a | ||||
|   image: helper:1.3 | ||||
| - name: nginx-helper-b | ||||
|   image: helper:1.3 | ||||
|   args: ["run"] # Field will be retained | ||||
| - name: nginx-helper-d # key: nginx-helper-d; will be retained | ||||
|   image: helper:1.3 | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Applied Resource | ||||
| containers: | ||||
| - name: nginx | ||||
|   image: nginx:1.10 | ||||
|   # Element nginx-helper-a was Deleted | ||||
| - name: nginx-helper-b | ||||
|   image: helper:1.3 | ||||
|   # Field was Ignored | ||||
|   args: ["run"] | ||||
|   # Element was Added | ||||
| - name: nginx-helper-c | ||||
|   image: helper:1.3 | ||||
|   # Element was Ignored | ||||
| - name: nginx-helper-d | ||||
|   image: helper:1.3 | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Edit and Set" %} | ||||
| While `kubectl edit` and `kubectl set` ignore the Last Applied Resource Config, Apply will | ||||
| change any values in the Resource Config set by either `kubectl edit` or `kubectl set`. | ||||
| To ignore values set by `kubectl edit` or `kubectl set`: | ||||
| 
 | ||||
| - Use `kubectl apply edit-last-applied` to remove the value from the Last Applied (if it is present) | ||||
| - Remove the field from the Resource Config | ||||
| 
 | ||||
| This is the same technique for retaining values set by cluster components such as autoscalers. | ||||
| {% endpanel %} | ||||
|  | @ -0,0 +1,44 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Apply manages Applications through files defining Kubernetes Resources (i.e. Resource Config) | ||||
| - Kustomize is used to author Resource Config | ||||
| {% endpanel %} | ||||
| 
 | ||||
| 
 | ||||
| # Declarative Application Management | ||||
| 
 | ||||
| This section covers how to declaratively manage Workloads and Applications. | ||||
| 
 | ||||
| Workloads in a cluster may be configured through files called *Resource Config*.  These files are | ||||
| typically checked into source control, and allow cluster state changes to be reviewed before they | ||||
| are Applied, and audited. | ||||
| 
 | ||||
| There are 2 components to Application Management. | ||||
| 
 | ||||
| ## Server Component | ||||
| 
 | ||||
| The server component consists of a human applying the authored Resource Config to the cluster | ||||
| to create or update Resources.  Once Applied, the Kubernetes cluster will set additional desired | ||||
| state on the Resource - e.g. *defaulting unspecified fields, filling in IP addresses, autoscaling | ||||
| replica count, etc.* | ||||
| 
 | ||||
| Note that the process of Application Management is a collaborative one between users and the | ||||
| Kubernetes system itself - where each may contribute to defining the desired state. | ||||
| 
 | ||||
| **Example**: An Autoscaler Controller in the cluster may set the scale field on a Deployment managed by a user. | ||||
| 
 | ||||
| ## Client Component | ||||
| 
 | ||||
| The client component consists of one or more humans collectively authoring the desired | ||||
| state of an Application as Resource Config.  This may be done as a collection of | ||||
| raw Resource Config files, or by composing and overlaying Resource Config authored | ||||
| by separate parties (using the `-k` flag with a `kustomization.yaml`). | ||||
| 
 | ||||
| Kustomize offers low-level tooling for simplifying the authoring of Resource Config.  It provides: | ||||
| 
 | ||||
| - **Generating Resource Config** from other canonical sources - e.g. ConfigMaps, Secrets | ||||
| - **Reusing and Composing one or more collections of Resource Config** | ||||
| - **Customizing Resource Config** | ||||
| - **Setting cross-cutting fields** - e.g. namespace, labels, annotations, name-prefixes, etc | ||||
| 
 | ||||
| **Example:** One user may define a Base for an application,  while another user may customize | ||||
| a specific instance of the Base. | ||||
|  | @ -1,10 +1,10 @@ | |||
| # Setting Labels and Annotations | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Set Labels for all Resources declared within a Project | ||||
| - Set Annotations for all Resources declared within a Project | ||||
| - Set Labels for all Resources declared within a Project with `commonLables` | ||||
| - Set Annotations for all Resources declared within a Project with `commonAnnotations` | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Setting Labels and Annotations | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Users may want to define a common set of labels or annotations for all the Resource in a project. | ||||
|  | @ -13,24 +13,28 @@ Users may want to define a common set of labels or annotations for all the Resou | |||
| - Set metadata for all Resources within a project (e.g. environment=test) | ||||
| - Copy or Fork an existing Project and add or change labels and annotations | ||||
| 
 | ||||
| See [Bases and Variations](project_variants.md) for more details on Copying Projects. | ||||
| See [Bases and Variations](../app_customization/bases_and_variants.md) for more details on Copying Projects. | ||||
| 
 | ||||
| ## Setting a Labels for all Resources | ||||
| ## Setting Labels for all Resources | ||||
| 
 | ||||
| {% method %} | ||||
| **Example:** Add the labels declared in `commonLabels` to all Resources in the project. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml and deployment.yaml files | ||||
| **Input:** The kustomization.yaml and deployment.yaml files | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| commonLabels: | ||||
|   app: foo | ||||
|   environment: test | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
|  | @ -91,22 +95,38 @@ labels.  e.g. the selectors for Services in the project will be updated to inclu | |||
| *in addition* to the other labels. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% panel style="success", title="Effective Labeling Strategies" %} | ||||
| A common practice is to label Resources with metadata about the environment, application, | ||||
| tier and version.  Labeling Workload Resources makes it simpler to query Pods - e.g. for the | ||||
| purpose of getting their logs. | ||||
| 
 | ||||
| ## Setting an annotation for all Resources | ||||
| - `app=nginx` | ||||
| - `tier=frontend` | ||||
| - `env=prod` | ||||
| - `version=1.16` | ||||
| 
 | ||||
| {% endpanel %} | ||||
| 
 | ||||
| 
 | ||||
| ## Setting Annotations for all Resources | ||||
| 
 | ||||
| {% method %} | ||||
| **Example:** Add the annotations declared in `commonAnnotations` to all Resources in the project. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml and deployment.yaml files | ||||
| **Input:** The kustomization.yaml and deployment.yaml files | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| commonAnnotations: | ||||
|   oncallPager: 800-555-1212 | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
|  | @ -1,10 +1,11 @@ | |||
| # Setting Namespaces and Names | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Set the Namespace for all Resources within a Project | ||||
| - Prefix the Names of all Resources within a Project | ||||
| - Set the Namespace for all Resources within a Project with `namespace` | ||||
| - Prefix the Names of all Resources within a Project with `namePrefix` | ||||
| - Suffix the Names of all Resources within a Project with `nameSuffix` | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Setting Namespaces and Names | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| It may be useful to enforce consistency across the namespace and names of all Resources within | ||||
|  | @ -14,7 +15,7 @@ a Project. | |||
| - Ensure all Resources share a common naming convention | ||||
| - Copy or Fork an existing Project and change the Namespace / Names | ||||
| 
 | ||||
| See [Bases and Variations](project_variants.md) for more details on Copying Projects. | ||||
| See [Bases and Variations](../app_customization/bases_and_variants.md) for more details on Copying Projects. | ||||
| 
 | ||||
| ## Setting the Namespace for all Resources | ||||
| 
 | ||||
|  | @ -23,17 +24,21 @@ This sets the namespace for both generated Resources (e.g. ConfigMaps and Secret | |||
| Resources. | ||||
| 
 | ||||
| {% method %} | ||||
| **Example:** Set the `namespace` specified in the `apply.yaml` on the namespaced Resources. | ||||
| **Example:** Set the `namespace` specified in the `kustomization.yaml` on the namespaced Resources. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml and deployment.yaml files | ||||
| **Input:** The kustomization.yaml and deployment.yaml files | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| namespace: my-namespace | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
|  | @ -82,20 +87,27 @@ spec: | |||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ## Setting a Name prefix for all Resources | ||||
| ## Setting a Name prefix or suffix for all Resources | ||||
| 
 | ||||
| A name prefix or suffix can be set for all resources using `namePrefix` or | ||||
| `nameSuffix`. | ||||
| 
 | ||||
| {% method %} | ||||
| **Example:** Prefix the names of all Resources. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml and deployment.yaml files | ||||
| **Input:** The kustomization.yaml and deployment.yaml files | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| namePrefix: foo- | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
|  | @ -146,10 +158,11 @@ spec: | |||
| Resources such as Deployments and StatefulSets may reference other Resources such as | ||||
| ConfigMaps and Secrets in the Pod Spec. | ||||
| 
 | ||||
| This sets a name prefix for both generated Resources (e.g. ConfigMaps and Secrets) and non-generated | ||||
| Resources. | ||||
| This sets a name prefix or suffix for both generated Resources (e.g. ConfigMaps  | ||||
| and Secrets) and non-generated Resources. | ||||
| 
 | ||||
| The namePrefix that is applied is propagated to references within the Project. | ||||
| The namePrefix or nameSuffix that is applied is propagated to references within  | ||||
| the Project. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% method %} | ||||
|  | @ -158,10 +171,12 @@ The namePrefix that is applied is propagated to references within the Project. | |||
| This will update the ConfigMap reference in the Deployment to have the `foo` prefix. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml and deployment.yaml files | ||||
| **Input:** The kustomization.yaml and deployment.yaml files | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| namePrefix: foo- | ||||
| configMapGenerator: | ||||
| - name: props | ||||
|  | @ -169,7 +184,9 @@ configMapGenerator: | |||
|   - BAR=baz | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
|  | @ -1,26 +1,29 @@ | |||
| # ConfigMaps and Secrets | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Generate Secrets and Configmaps from files and literals | ||||
| - Generate Secrets from files and literals with `secretGenerator` | ||||
| - Generate ConfigMaps from files and literals with `configMapGenerator` | ||||
| - Rolling out changes to Secrets and ConfigMaps | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Secrets and ConfigMaps | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| The source of truth for ConfigMap and Secret Resources typically resides somewhere else, such as a `.properties` | ||||
| or `.pem` file.  Apply offers native support for generating both ConfigMaps and Secrets from other sources | ||||
| such as files, literals and command outputs. | ||||
| The source of truth for Secret and ConfigMap Resources typically resides  | ||||
| somewhere else, such as a `.properties` file.  Apply offers native support  | ||||
| for generating both Secrets and ConfigMaps from other sources such as files and  | ||||
| literals. | ||||
| 
 | ||||
| Additionally, ConfigMaps and Secrets require roll outs to be performed differently than for most | ||||
| other Resources in order for the changes to be rolled out to Pods consuming them. | ||||
| Additionally, Secrets and ConfigMaps require roll outs to be performed  | ||||
| differently than for most other Resources in order for the changes to be  | ||||
| rolled out to Pods consuming them. | ||||
| 
 | ||||
| ## Generators | ||||
| 
 | ||||
| ConfigMap and Secret Resources can be generated by adding `configMapGenerator` and `secretGenerator` | ||||
| entries to the `apply.yaml` file.  `configMapGenerator` and `secretGenerator` each take a list of items. | ||||
| Each item generates a different Resources. | ||||
| Secret and ConfigMap Resources can be generated by adding `secretGenerator`  | ||||
| or `configMapGenerator` entries to the `kustomization.yaml` file. | ||||
| 
 | ||||
| **The generated Resources name's will have suffixes as hashes of their data.  See [Rollouts](#rollouts) for more on this.** | ||||
| **The generated Resources name's will have suffixes that change when their data | ||||
| changes.  See [Rollouts](#rollouts) for more on this.** | ||||
| 
 | ||||
| ### ConfigMaps From Files | ||||
| 
 | ||||
|  | @ -34,15 +37,19 @@ The ConfigMaps will have data values populated from the file contents.  The cont | |||
| appear as a single data item in the ConfigMap keyed by the filename. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| **Input:** The kustomization.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| configMapGenerator: | ||||
| - name: myApplicationProperties | ||||
|   files: | ||||
|   - application.properties | ||||
|    | ||||
|   - application.properties   | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # application.properties | ||||
| FOO=Bar | ||||
| ``` | ||||
|  | @ -77,10 +84,12 @@ list of `literals`. | |||
| **Example:** Create a ConfigMap with 2 data items generated from literals. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| **Input:** The kustomization.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| configMapGenerator: | ||||
| - name: myJavaServerEnvVars | ||||
|   literals:	 | ||||
|  | @ -103,30 +112,37 @@ data: | |||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ### Secrets from Commands | ||||
| {% panel style="success", title="Overriding Base ConfigMap Values" %} | ||||
| ConfigMaps Values from Bases may be overridden by adding another generator for the ConfigMap | ||||
| in the Variant and specifying the `behavior` field.  `behavior` may be | ||||
| one of `create` (default value), `replace` (replace the base ConfigMap), | ||||
| or `merge` (add or update the values the ConfigMap).  See [Bases and Variantions](../app_customization/bases_and_variants.md) | ||||
| for more on using Bases.  e.g. `behavior: "merge"` | ||||
| {% endpanel %} | ||||
| 
 | ||||
| Secret Resources may be generated from commands that output the data items.  Commands may simply output | ||||
| the contents of a file as data, but may do more complicate actions such as fetching data from a remote | ||||
| location, or decrypting files. | ||||
| ### Secrets from Files | ||||
| 
 | ||||
| Secret Resources may be generated from files much like ConfigMaps can. | ||||
| 
 | ||||
| {% panel style="info", title="Secret Syntax" %} | ||||
| - Secret type is set using the `type` field. | ||||
| - Timeout for the command output maybe set using the `timeoutSeconds` field. | ||||
| Secret type is set using the `type` field. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% method %} | ||||
| **Example:** Generate a `kubernetes.io/tls` Secret from local files | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| **Input:** The kustomization.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| secretGenerator: | ||||
| - name: app-tls | ||||
|   commands: | ||||
|     tls.crt: "cat secret/tls.cert" | ||||
|     tls.key: "cat secret/tls.key" | ||||
|   files: | ||||
|     - "secret/tls.cert" | ||||
|     - "secret/tls.key" | ||||
|   type: "kubernetes.io/tls" | ||||
| ``` | ||||
| 
 | ||||
|  | @ -146,99 +162,54 @@ data: | |||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| **Example:** Generate an `Opaque` Secret from downloading remote files | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| secretGenerator: | ||||
| - name: downloaded_secret | ||||
|   timeoutSeconds: 30 | ||||
|   commands: | ||||
|     username: "curl -s https://path/to/username" | ||||
|     password: "curl -s https://path/to/password" | ||||
|   type: "kubernetes.io/tls" | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster. | ||||
| 
 | ||||
| ```yaml | ||||
| apiVersion: v1 | ||||
| kind: Secret | ||||
| metadata: | ||||
|   # The name has had a suffix applied | ||||
|   name: downloaded_secret-gm74hh58b5 | ||||
| type: Opaque | ||||
| # The data has been populated from each command's output | ||||
| data: | ||||
|   password: YmFyCg== | ||||
|   username: Zm9vCg== | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ### Secrets from Env Commands | ||||
| 
 | ||||
| Secret Resources may also be generated from commands that output multiple data items as key value pairs. | ||||
| This is useful for encoding the elements of Docker .env files or .ini files as separate data items within | ||||
| Secrets. | ||||
| 
 | ||||
| {% panel style="info", title="Commands vs EnvCommands" %} | ||||
| The difference between `commands` and `envCommand` is that **with a command, each item creates a different data | ||||
| item** whereas **with an envCommand each output line creates a different data item.** | ||||
| {% endpanel %} | ||||
| ### Generator Options | ||||
| 
 | ||||
| {% method %} | ||||
| **Example:** Generate an `Opaque` Secret from the environment | ||||
| It is also possible to specify cross-cutting options for generated objects  | ||||
| using  `generatorOptions`. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| secretGenerator: | ||||
| - name: env_file_secret | ||||
|   envCommand: printf "DB_USERNAME=admin\nDB_PASSWORD=somepw" | ||||
|   type: Opaque | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| generatorOptions: | ||||
|   # labels to add to all generated resources | ||||
|   labels: | ||||
|     kustomize.generated.resources: somevalue | ||||
|   # annotations to add to all generated resources | ||||
|   annotations: | ||||
|     kustomize.generated.resource: somevalue | ||||
|   # disableNameSuffixHash is true disables the default behavior of adding a | ||||
|   # suffix to the names of generated resources that is a hash of | ||||
|   # the resource contents. | ||||
|   disableNameSuffixHash: true | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster. | ||||
| 
 | ||||
| ```yaml | ||||
| apiVersion: v1 | ||||
| kind: Secret | ||||
| metadata: | ||||
|   # The name has had a suffix applied | ||||
|   name: env_file_secret-hc4d62fgb8 | ||||
| type: Opaque | ||||
| # The data has been populated from the command output lines | ||||
| data: | ||||
|   DB_PASSWORD: c29tZXB3 | ||||
|   DB_USERNAME: YWRtaW4= | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ### Propagating the Name Suffix | ||||
| 
 | ||||
| {% method %} | ||||
| Workloads that reference the ConfigMap or Secret will need to know the name of the generated Resource | ||||
| including the suffix, however Apply solves this automatically for users.  Apply will identify | ||||
| references to generated ConfigMaps and Secrets, and update their them. | ||||
| including the suffix, however Apply takes care of this automatically for users.  Apply will identify | ||||
| references to generated ConfigMaps and Secrets, and update them. | ||||
| 
 | ||||
| The generated ConfigMap name will be `myJavaServerEnvVars` with a suffix unique to its contents. | ||||
| Changes to the contents will change the name suffix, resulting in the creation of a new ConfigMap. | ||||
| Changes to the contents will change the name suffix, resulting in the creation of a new ConfigMap, | ||||
| and transform Workloads to point to this one. | ||||
| 
 | ||||
| The PodTemplate volume references the ConfigMap by the name specified in the generator (excluding the suffix). | ||||
| Apply will update the name to include the suffix applied to the ConfigMap name. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml and deployment.yaml files | ||||
| **Input:** The kustomization.yaml and deployment.yaml files | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| # kustomization.yaml | ||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||||
| kind: Kustomization | ||||
| configMapGenerator: | ||||
| - name: myJavaServerEnvVars | ||||
|   literals:	 | ||||
|  | @ -246,7 +217,9 @@ configMapGenerator: | |||
|   - JAVA_TOOL_OPTIONS=-agentlib:hprof | ||||
| resources: | ||||
| - deployment.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
|  | @ -324,35 +297,23 @@ spec: | |||
| 
 | ||||
| ## Rollouts | ||||
| 
 | ||||
| ConfigMap and Secret values are consumed by Pods as: environment variables, commandline arguments and files. | ||||
| ConfigMap values are consumed by Pods as: environment variables, commandline arguments and files. | ||||
| 
 | ||||
| This is important because Updating a ConfigMap or Secret will: | ||||
| This is important because Updating a ConfigMap will: | ||||
| 
 | ||||
| - immediately update the files mounted by *all* Pods consuming them | ||||
| - not update the environment variables or commandline arguments until the Pod is restarted | ||||
|   | ||||
| Typically users want to perform a rolling update of the ConfigMap or Secret changes to Pods as soon as | ||||
| the ConfigMap or Secret changes are pushed. | ||||
| Typically users want to perform a rolling update of the ConfigMap changes to Pods as soon as | ||||
| the ConfigMap changes are pushed. | ||||
| 
 | ||||
| Apply facilitates rolling updates for ConfigMaps and Secrets by creating a new ConfigMap or Secret | ||||
| Apply facilitates rolling updates for ConfigMaps by creating a new ConfigMap | ||||
| for each change to the data.  Workloads (e.g. Deployments, StatefulSets, etc) are updated to point to a new | ||||
| ConfigMap or Secret instead of the old one.  This allows the change to be gradually rolled the same way | ||||
| ConfigMap instead of the old one.  This allows the change to be gradually rolled the same way | ||||
| other Pod Template changes are rolled out. | ||||
| 
 | ||||
| Each generated Resources name has a suffix appended by hashing the contents.  This approach ensures a new | ||||
| ConfigMap or Secret is generated each time the contents is modified. | ||||
| ConfigMap is generated each time the contents is modified. | ||||
| 
 | ||||
| **Note:** Because the Resource names will contain a suffix, when looking for them with `kubectl get`, | ||||
| their names will not match exactly what is specified in the apply.yaml file. | ||||
| 
 | ||||
| ### Deletion and Cleanup | ||||
| 
 | ||||
| Apply will not automatically delete generated ConfigMaps or Secrets as long as they are in use by Resources within | ||||
| the project. This may mean that they are not deleted until Apply is run again after the rollouts are complete. | ||||
| e.g. both the old ConfigMap and new ConfigMap will continue to exist until only the new ConfigMap is used and Apply is | ||||
| run again. | ||||
| 
 | ||||
| {% panel style="info", title="Blocking Apply" %} | ||||
| If Apply is run with `--wait` it will block until the Rollouts have completed.  In this situtation, the old generated | ||||
| ConfigMaps and Secrets should not longer be in use, and will be deleted by Apply before exiting. | ||||
| {% endpanel %} | ||||
| their names will not match exactly what is specified in the kustomization.yaml file. | ||||
|  | @ -1,58 +0,0 @@ | |||
| # Kubectl | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Kubectl is the Kubernetes CLI. | ||||
| - Kubectl has different command groups for different types of user workflows. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| Kubectl is the Kubernetes CLI and used to manage Resources. | ||||
| 
 | ||||
| ## Command Families | ||||
| 
 | ||||
| While Kubectl has many different commands, they fall into only a few categories. | ||||
| 
 | ||||
| - Declaratively Creating, Updating, Deleting Resources (Apply) | ||||
| - Debugging Workloads and Reading Cluster State | ||||
| - Managing the cluster itself | ||||
| - Porcelain commands for working with Resources | ||||
| 
 | ||||
| ## Declaratively Creating, Updating, Deleting Resources (Apply) | ||||
| 
 | ||||
| Creating, Updating and Deleting Resources is done through declarative files called Resource Config | ||||
| and the Kubectl *Apply* command.  This command reads a local (or remote) file structure and modifies | ||||
| cluster state to reflect the declared intent. | ||||
| 
 | ||||
| {% panel style="info", title="Apply" %} | ||||
| Apply is the preferred mechanism for managing Resources in a Kubernetes cluster. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## Debugging Workloads and Reading Cluster State | ||||
| 
 | ||||
| Users will need to debug and view Workloads running in a cluster.  Kubectl supports debugging | ||||
| by providing commands for: | ||||
| 
 | ||||
| - printing state and information about Resources | ||||
| - printing Container logs | ||||
| - printing cluster events | ||||
| - exec or attaching to a Container | ||||
| - copying files from Containers in the cluster to a user's filesystem | ||||
| 
 | ||||
| ## Cluster Management | ||||
| 
 | ||||
| On occasion, users may need to perform operations to the Nodes of cluster.  Kubectl supports | ||||
| commands to drain Workloads from a Node so that it can be decommission or debugged. | ||||
| 
 | ||||
| ## Porcelain | ||||
| 
 | ||||
| Users may find using Resource Config overly verbose for *Development* and prefer to work with | ||||
| the cluster *imperatively* with a shell-like workflow.  Kubectl offers porcelain commands for | ||||
| generating and modifying Resources. | ||||
| 
 | ||||
| - generating + creating Resources such as Deployments, StatefulSets, Services, ConfigMaps, etc | ||||
| - setting fields on Resources | ||||
| - editing (live) Resources in a text editor | ||||
| 
 | ||||
| {% panel style="info", title="Porcelain For Dev Only" %} | ||||
| Porcelain commands are time saving for experimenting with workloads in a dev cluster, but | ||||
| shouldn't be used for production. | ||||
| {% endpanel %} | ||||
|  | @ -1,7 +0,0 @@ | |||
| # Rolling out Across Clusters | ||||
| 
 | ||||
| ## Targeting a Cluster | ||||
| 
 | ||||
| ## Sequentially Rolling Out | ||||
| 
 | ||||
| ## Concurrently Rolling Out | ||||
|  | @ -1,22 +0,0 @@ | |||
| # Auditing and Reviewing Changes | ||||
| 
 | ||||
| ## Automatic Deployment vs Manual Deployment | ||||
| 
 | ||||
| ## Git PR | ||||
| 
 | ||||
| - Description Template | ||||
| - Labeling conventions | ||||
| 
 | ||||
| ## Reviewing Changes Before they are pushed | ||||
| 
 | ||||
| ### Resource Config Diffs | ||||
| 
 | ||||
| Reviewing the changes to Resource Config | ||||
| 
 | ||||
| ### Resource Diffs | ||||
| 
 | ||||
| Reviewing the changes to the live Resources | ||||
| 
 | ||||
| ## Auditing Past Changes | ||||
| 
 | ||||
| Auditing changes that have been merged | ||||
|  | @ -1,7 +0,0 @@ | |||
| # Builds | ||||
| 
 | ||||
| ## Building Containers from Source | ||||
| 
 | ||||
| - Multi-Stage Builds | ||||
| 
 | ||||
| ## Triggering Builds | ||||
|  | @ -1,15 +0,0 @@ | |||
| # Rolling out Across Environments | ||||
| 
 | ||||
| ## Automatic Sequential Rollouts | ||||
| 
 | ||||
| **Immediate:** Rollout one environment immediately after the previous | ||||
| 
 | ||||
| **Delayed:** Pause between rollouts | ||||
| 
 | ||||
| ## Manual Sequential Rollouts | ||||
| 
 | ||||
| Require humans to push | ||||
| 
 | ||||
| ## Incorporating Application Metrics | ||||
| 
 | ||||
| Use Application metrics to identify issues and pause or rollback. | ||||
|  | @ -1,7 +0,0 @@ | |||
| # Linting Resource Config | ||||
| 
 | ||||
| ## Configuring the Linter | ||||
| 
 | ||||
| ## Error Types | ||||
| 
 | ||||
| ## Ignoring Linter Errors | ||||
|  | @ -1,8 +0,0 @@ | |||
| # Rolling Back Changes | ||||
| 
 | ||||
| ## Types of Errors | ||||
| 
 | ||||
| ## Notification of an Error | ||||
| 
 | ||||
| ## How to Rollback | ||||
| 
 | ||||
|  | @ -1,5 +0,0 @@ | |||
| # Rollouts | ||||
| 
 | ||||
| ## Triggering a Rollout | ||||
| 
 | ||||
| ## Sequentially Rolling out Components | ||||
|  | @ -1,66 +0,0 @@ | |||
| # Project Structure | ||||
| 
 | ||||
| ## Definitions | ||||
| 
 | ||||
| - **Project:** TODO: Define this | ||||
| - **Application:** TODO: Define this | ||||
| - **Bespoke:** TODO: Define this | ||||
| - **Ready-Made:** TODO: Define this | ||||
| 
 | ||||
| ## Application with Bespoke Components | ||||
| 
 | ||||
| **Example:** An application whose images and Resource Config are owned by user. | ||||
| 
 | ||||
| ### Organizing Components | ||||
| 
 | ||||
| ### Use of Namespaces | ||||
| 
 | ||||
| ## Application with Ready-Made Components | ||||
| 
 | ||||
| **Example:** An application built from components whose images and Resource Config are owned by a different group. | ||||
| 
 | ||||
| ### Referencing Ready-Made Bases | ||||
| 
 | ||||
| ### Organizing Components | ||||
| 
 | ||||
| ## Multi Application | ||||
| 
 | ||||
| **Example:** Multiple applications owned and operated by the same group. | ||||
| 
 | ||||
| ### Organizing Applications | ||||
| 
 | ||||
| ### Use of Namespaces | ||||
| 
 | ||||
| ## Multi Environment | ||||
| 
 | ||||
| **Example:** Multiple applications owned and operated by the same group rolledout across multiple environments - | ||||
| e.g. dev, test, staging, canary, production. | ||||
| 
 | ||||
| ### Organizing Environments | ||||
| 
 | ||||
| ### Use of Namespaces | ||||
| 
 | ||||
| ### Organizing Bespoke Bases + Variants | ||||
| 
 | ||||
| ## Multi Cluster | ||||
| 
 | ||||
| **Example:** An application that is rolledout to multiple Kubernetes clusters sequentially or in parallel. | ||||
| 
 | ||||
| ### Organizing Bespoke Bases + Variants | ||||
| 
 | ||||
| ### Use of KubeConfigs | ||||
| 
 | ||||
| ## Multi Project | ||||
| 
 | ||||
| **Example:** Multiple projects developed by separate teams whose Resource Config lives in the same repository or | ||||
| in multiple repositories. | ||||
| 
 | ||||
| ### Organizing Groups | ||||
| 
 | ||||
| ### Publishing Shared Bases | ||||
| 
 | ||||
| ## Resource Config and Source Code Repositories | ||||
| 
 | ||||
| ### Separate Repositories | ||||
| 
 | ||||
| ### Shared  Repository | ||||
|  | @ -0,0 +1,161 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Print the Logs of a Container in a cluster | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Summarizing Resources | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Debugging Workloads by printing out the Logs of containers in a cluster. | ||||
| 
 | ||||
| {% method %} | ||||
| ## Print Logs for a Container in a Pod | ||||
| 
 | ||||
| Print the logs for a Pod running a single Container | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl logs echo-c6bc8ccff-nnj52 | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| hello | ||||
| hello | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| 
 | ||||
| {% panel style="success", title="Crash Looping Containers" %} | ||||
| If a container is crash looping and you want to print its logs after it | ||||
| exits, use the `-p` flag to look at the **logs from containers that have | ||||
| exited**.  e.g. `kubectl logs -p -c ruby web-1` | ||||
| {% endpanel %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Print Logs for all Pods for a Workload | ||||
| 
 | ||||
| Print the logs for all Pods for a Workload | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| # Print logs from all containers matching label | ||||
| $ kubectl logs -l app=nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="success", title="Workloads Logs" %} | ||||
| Print all logs from **all containers for a Workload** by passing the | ||||
| Workload label selector to the `-l` flag.  e.g. if your Workload | ||||
| label selector is `app=nginx` usie `-l "app=nginx"` to print logs | ||||
| for all the Pods from that Workload. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Follow Logs for a Container | ||||
| 
 | ||||
| Stream logs from a container. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| # Follow logs from container | ||||
| $ kubectl logs nginx-78f5d695bd-czm8z -f | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Printing Logs for a Container that has exited | ||||
| 
 | ||||
| Print the logs for the previously running container.  This is useful for printing containers that have | ||||
| crashed or are crash looping. | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| # Print logs from exited container | ||||
| $ kubectl logs nginx-78f5d695bd-czm8z -p | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Selecting a Container in a Pod  | ||||
| 
 | ||||
| Print the logs from a specific container within a Pod.  This is necessary for Pods running multiple | ||||
| containers. | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| # Print logs from the nginx container in the nginx-78f5d695bd-czm8z Pod | ||||
| $ kubectl logs nginx-78f5d695bd-czm8z -c nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Printing Logs After a Time | ||||
| 
 | ||||
| Print the logs that occurred after an absolute time. | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| # Print logs since a date | ||||
| $ kubectl logs nginx-78f5d695bd-czm8z --since-time=2018-11-01T15:00:00Z | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Printing Logs Since a Time | ||||
| 
 | ||||
| Print the logs that are newer than a duration. | ||||
| 
 | ||||
| Examples: | ||||
| 
 | ||||
| - 0s: 0 seconds | ||||
| - 1m: 1 minute | ||||
| - 2h: 2 hours | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| # Print logs for the past hour | ||||
| $ kubectl logs nginx-78f5d695bd-czm8z --since=1h | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Include Timestamps | ||||
| 
 | ||||
| Include timestamps in the log lines | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| # Print logs with timestamps | ||||
| $ kubectl logs -l app=echo --timestamps | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| 2018-11-16T05:26:31.38898405Z hello | ||||
| 2018-11-16T05:27:13.363932497Z hello | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,77 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Copy files to and from Containers in a cluster | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Copying Container Files | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| - Copying files from Containers in a cluster to a local filesystem | ||||
| - Copying files from a local filesystem to Containers in a cluster | ||||
| 
 | ||||
| {% panel style="warning", title="Install Tar" %} | ||||
| Copy requires that *tar* be installed on the local filesystem and is on the user's | ||||
| PATH. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Local to Remote | ||||
| 
 | ||||
| Copy a local file to a remote Pod in a cluster. | ||||
| 
 | ||||
| - Local file format is `<path>` | ||||
| - Remote file format is `<pod-name>:<path>` | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl cp /tmp/foo_dir <some-pod>:/tmp/bar_dir | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Remote to Local | ||||
| 
 | ||||
| Copy a remote file from a Pod to a local file. | ||||
| 
 | ||||
| - Local file format is `<path>` | ||||
| - Remote file format is `<pod-name>:<path>` | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl cp /tmp/foo <some-pod>:/tmp/bar | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Specify the Conainer | ||||
| 
 | ||||
| Specify the Container within a Pod running multiple containers. | ||||
| 
 | ||||
| - `-c <container-name>` | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl cp /tmp/foo <some-pod>:/tmp/bar -c <specific-container> | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|    | ||||
| {% method %} | ||||
| ## Namespaces | ||||
| 
 | ||||
| Set the Pod namespace by prefixing the Pod name with `<namespace>/` . | ||||
| 
 | ||||
| - `<pod-namespace>/<pod-name>:<path>` | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl cp /tmp/foo <some-namespace>/<some-pod>:/tmp/bar | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,68 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Execute a Command in a Container | ||||
| - Get a Shell in a Container | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Executing Commands | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Debugging Workloads by running commands within the Container.  Commands may be a Shell with | ||||
| a tty. | ||||
| 
 | ||||
| {% method %} | ||||
| ## Exec Command | ||||
| 
 | ||||
| Run a command in a Container in the cluster by specifying the **Pod name**. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl exec nginx-78f5d695bd-czm8z ls | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| bin | ||||
| boot | ||||
| dev | ||||
| etc | ||||
| home | ||||
| lib | ||||
| lib64 | ||||
| media | ||||
| mnt | ||||
| opt | ||||
| proc | ||||
| root | ||||
| run | ||||
| sbin | ||||
| srv | ||||
| sys | ||||
| tmp | ||||
| usr | ||||
| var | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Exec Shell | ||||
| 
 | ||||
| To get a Shell in a Container, use the `-t -i` options to get a tty and attach STDIN. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl exec -t -i nginx-78f5d695bd-czm8z bash | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| root@nginx-78f5d695bd-czm8z:/# ls | ||||
| bin  boot  dev	etc  home  lib	lib64  media  mnt  opt	proc  root  run  sbin  srv  sys  tmp  usr  var | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Specifying the Container" %} | ||||
| For Pods running multiple Containers, the Container should be specified with `-c <container-name>` | ||||
| {% endpanel %} | ||||
|  | @ -0,0 +1,96 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Port Forward local connections to Pods running in a cluster  | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Port Forward | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Connect to ports of Pods running a cluster by port forwarding local ports. | ||||
| 
 | ||||
| {% method %} | ||||
| ## Forward Multiple Ports | ||||
| 
 | ||||
| Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl port-forward pod/mypod 5000 6000 | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Pod in a Workload | ||||
| 
 | ||||
| Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in a pod selected by the | ||||
| deployment | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl port-forward deployment/mydeployment 5000 6000 | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Different Local and Remote Ports | ||||
| 
 | ||||
| Listen on port 8888 locally, forwarding to 5000 in the pod | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl port-forward pod/mypod 8888:5000 | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Random Local Port | ||||
| 
 | ||||
| Listen on a random port locally, forwarding to 5000 in the pod | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl port-forward pod/mypod :5000 | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Specify the Conainer | ||||
| 
 | ||||
| Specify the Container within a Pod running multiple containers. | ||||
| 
 | ||||
| - `-c <container-name>` | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl cp /tmp/foo <some-pod>:/tmp/bar -c <specific-container> | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|    | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ## Namespaces | ||||
| 
 | ||||
| Set the Pod namespace by prefixing the Pod name with `<namespace>/` . | ||||
| 
 | ||||
| - `<pod-namespace>/<pod-name>:<path>` | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl cp /tmp/foo <some-namespace>/<some-pod>:/tmp/bar | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,74 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Proxy local connections to Services running in the cluster | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Connecting to Services | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Not all Services running a Kubernetes cluster are exposed externally.  However Services | ||||
| only exposed internally to a cluster with a *clusterIp* are accessible through an | ||||
| apiserver proxy. | ||||
| 
 | ||||
| Users may use Proxy to **connect to Kubernetes Services in a cluster that are not | ||||
| externally exposed**. | ||||
| 
 | ||||
| 
 | ||||
| **Note:** Services running a type LoadBalancer or type NodePort may be exposed externally and | ||||
| accessed without the need for a Proxy. | ||||
| 
 | ||||
| {% method %} | ||||
| ## Connecting to an internal Service | ||||
| 
 | ||||
| Connect to a internal Service using the Proxy command, and the Service Proxy url. | ||||
| 
 | ||||
| To visit the nginx service go to the Proxy URL at  | ||||
| `http://127.0.0.1:8001/api/v1/namespaces/default/services/nginx/proxy/` | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl proxy | ||||
| 
 | ||||
| Starting to serve on 127.0.0.1:8001 | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| $ curl http://127.0.0.1:8001/api/v1/namespaces/default/services/nginx/proxy/ | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Literal Syntax" %} | ||||
| To connect to a Service through a proxy the user must build the Proxy URL.  The Proxy URL format is: | ||||
| 
 | ||||
| `http://<apiserver-address>/api/v1/namespaces/<service-namespace>/services/[https:]<service-name>[:<port-name>]/proxy` | ||||
| 
 | ||||
| - The apiserver-address should be the URL printed by the Proxy command | ||||
| - The Port is optional if you haven’t specified a name for your port | ||||
| - The Protocol is optional if you are using `http` | ||||
| 
 | ||||
| {% endpanel %} | ||||
|    | ||||
| ## Builtin Cluster Services | ||||
| 
 | ||||
| A common usecase is to connect to Services running as part of the cluster itself.  A user can print out these | ||||
| Services and their Proxy Urls with `kubectl cluster-info`. | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl cluster-info | ||||
| 
 | ||||
| Kubernetes master is running at https://104.197.5.247 | ||||
| GLBCDefaultBackend is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/default-http-backend:http/proxy | ||||
| Heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/heapster/proxy | ||||
| KubeDNS is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy | ||||
| Metrics-server is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy | ||||
| ``` | ||||
| 
 | ||||
| {% panel style="info", title="More Info" %} | ||||
| For more information on connecting to a cluster, see the | ||||
| [Accessing Clusters](https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/) | ||||
| k8s.io doc. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1,144 +0,0 @@ | |||
| # Apply | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Apply Creates, Updates and Deletes Resources in a cluster through declarative files. | ||||
| - Apply merges user owned state with state owned by the cluster when Updating Resources. | ||||
| - Apply ensures the correct ordering when creating Resources. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Apply will update a Kubernetes cluster to match state defined locally in files. | ||||
| 
 | ||||
| - Fully declarative - don't need to specify create, update or delete - just manage files | ||||
| - Merges user owned state (e.g. Service `selector`) with state owned by the cluster (e.g. Service `clusterIp`) | ||||
| 
 | ||||
| ## Definitions | ||||
| 
 | ||||
| - **Resources**: *Objects* in a cluster - e.g. Deployments, Services, etc. | ||||
| - **Resource Config**: *Files* declaring the desired state for Resources - e.g. deployment.yaml. | ||||
|   Resources are created and updated using Apply with these files. | ||||
| 
 | ||||
| *kubectl apply* Creates, Updates and Deletes Resources using Resource Config with a *apply.yaml*. | ||||
| 
 | ||||
| ## Applying a Project | ||||
| 
 | ||||
| {% method %} | ||||
| apply.yaml defines and transforms a collection of Resources Configs.  `kubectl apply` | ||||
| takes a list of directories containing `apply.yaml` files. | ||||
| 
 | ||||
| This `apply.yaml` file contains a list of Resource Configs that will be applied. | ||||
| The file paths are relative to the `apply.yaml` file. | ||||
| {% sample lang="yaml" %} | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| resources: | ||||
| - some-service.yaml | ||||
| - ../some-dir/some-deployment.yaml | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| Users run Apply on directories containing `apply.yaml` files. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| ```bash | ||||
| $ kubectl apply -f /path/to/project1/ -f /path/to/project2/ | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Multi-Resource Configs" %} | ||||
| A single Resource Config file may declare multiple Resources separated by `\n---\n`. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## CRUD Operations | ||||
| 
 | ||||
| ### Creating Resources | ||||
| 
 | ||||
| Any Resources that do not exist and are declared in Resource Config when Apply is run will be Created. | ||||
| 
 | ||||
| ### Updating Resources | ||||
| 
 | ||||
| Any Resources that already exist and are declaraed in Resource Config when Apply is run may be updated. | ||||
| 
 | ||||
| **Added Fields** | ||||
| 
 | ||||
| Any fields that have been added to the Resource Config will be set on the Resource. | ||||
| 
 | ||||
| **Updated Fields**  | ||||
|   | ||||
| Any fields that contain different values for the fields specified locally in the Resource Config from what is | ||||
| in the Resource will be updated by Apply. | ||||
| 
 | ||||
| 
 | ||||
| Apply will overwrite any fields that are defined in the Resource Config, and whose values do not match.  For | ||||
| example, if a Resource was modified by another source (e.g. an Autoscaler), it will be changed back to have the | ||||
| values that are specified in the Resource Config. | ||||
| 
 | ||||
| **Deleted Fields** | ||||
| 
 | ||||
| If a field is deleted from the Resource Config: | ||||
| 
 | ||||
| - Fields that were *most recently* set by Apply, will be deleted from the Resource, and return to their default values. | ||||
| - Fields that were set by Apply, but have been set by another source more recently (e.g. an Autoscaler), will | ||||
|   be left unmodified. | ||||
| 
 | ||||
| **Unmanaged Fields** | ||||
| 
 | ||||
| Fields that have not been specified in the Resource Config but are set on the Resource will be left unmodified. | ||||
| 
 | ||||
| 
 | ||||
| ### Deleting Resources | ||||
| 
 | ||||
| {% method %} | ||||
| Any Resources that exist and are not declared in the Resource Config when Apply is run will be deleted | ||||
| if and only if all of the following are true: | ||||
| 
 | ||||
| - A `pruneSelector` field is set in the `apply.yaml` | ||||
| - The Resource matches the `pruneSelector` label selector | ||||
| - If the Resource is Namespaced and the `namespace` field is set in the `apply.yaml` and the namespace matches | ||||
| - The Resource is not a ConfigMap or Secret that is currently in use | ||||
| 
 | ||||
| ConfigMaps and Secrets are not deleted immediately because they may be in use by Workloads even if they are not | ||||
| directly referenced in the newest Resource Config. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| namespace: foo | ||||
| pruneSelector: | ||||
|   app: my-app | ||||
| labels: | ||||
|   app: my-app | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ## Resource Creation Ordering | ||||
| 
 | ||||
| Certain Resource Types may be dependent on other Resource Types being created first.  e.g. Namespaced | ||||
| Resources on the Namespaces, RoleBindings on Roles, CustomResources on the CRDs, etc. | ||||
| 
 | ||||
| Apply sorts the Resources by Resource type to ensure Resources with these dependencies | ||||
| are created in the correct order. | ||||
| 
 | ||||
| ## Blocking on Completion | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| By default, Apply exists immediately after all changes have been sent to the apiserver, but before | ||||
| the changes have been fully rolled out by the Controllers. | ||||
| 
 | ||||
| Using `--wait` will cause Apply to wait until the Controllers have rolled out all changes before | ||||
| exiting.  When used with `--wait`, Apply will output the status of roll outs. | ||||
|   | ||||
|   | ||||
| It is possible to Apply updates to Resources *sequentially* by using `--wait` and structuring the | ||||
| Resource Config so Apply is called separately for each sequential collection of Resources. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| ```bash | ||||
| kubectl apply -f /path/to/project1/ --wait | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1,26 +0,0 @@ | |||
| # Rollout Status | ||||
| 
 | ||||
| ## Apply | ||||
| 
 | ||||
| {% method %} | ||||
| {% sample lang="yaml" %} | ||||
| ```bash | ||||
| $ kubectl apply -f dir/ --wait | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| 
 | ||||
| ## Checking on the Status of an existing Rollout | ||||
| 
 | ||||
| {% method %} | ||||
| {% sample lang="yaml" %} | ||||
| ```bash | ||||
| $ kubectl rollout status -f dir/ | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ## Conditions and Fields | ||||
| 
 | ||||
| ### Rollout Completion | ||||
| 
 | ||||
| ### Rollout Health | ||||
|  | @ -1,5 +0,0 @@ | |||
| # Declarative Application Management | ||||
| 
 | ||||
| This section of the book describes who to run Workloads in a Kubernetes cluster by declaring | ||||
| the desired state of the cluster in files called *Resource Config*.  This is the preferred | ||||
| approach for managing Production workloads. | ||||
|  | @ -0,0 +1,177 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Imperatively Create a Resources | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Creating Resources | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Create Resources directly from the commandline for the purposes of development or debugging. | ||||
| Not for production Application Management. | ||||
| 
 | ||||
| {% method %} | ||||
| ## Deployment | ||||
| 
 | ||||
| A Deployment can be created by either the `create deployment` command or the `run` command. | ||||
| While `run` may also create other types of resources, `create deployment` will only create | ||||
| Deployments. | ||||
| 
 | ||||
| While `run` has a variety of flags and options, `create deployment` is intended to stay | ||||
| very simple. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl create deployment my-dep --image=busybox | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| kubectl run my-dep --image=busybox | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="success", title="Running and Attaching" %} | ||||
| It is possible to run a container and immediately attach to it using the `-i -t` flags.  e.g. | ||||
| `kubectl run -t -i my-dep --image ubuntu -- bash` | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## ConfigMap | ||||
| 
 | ||||
| Create a configmap based on a file, directory, or specified literal value.  | ||||
| 
 | ||||
| A single configmap may package one or more key/value pairs.  | ||||
| 
 | ||||
| When creating a configmap based on a file, the key will default to the basename of the file, and the value will default | ||||
| to the file content.  If the basename is an invalid key, you may specify an alternate key.  | ||||
| 
 | ||||
| When creating a configmap based on a directory, each file whose basename is a valid key in the directory will be | ||||
| packaged into the configmap.  Any directory entries except regular files are ignored (e.g. subdirectories, symlinks, | ||||
| devices, pipes, etc). | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| # Create a new configmap named my-config based on folder bar | ||||
| kubectl create configmap my-config --from-file=path/to/bar | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| # Create a new configmap named my-config with specified keys instead of file basenames on disk | ||||
| kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt | ||||
|   ``` | ||||
| 
 | ||||
| ```bash | ||||
| # Create a new configmap named my-config with key1=config1 and key2=config2 | ||||
| kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2 | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| # Create a new configmap named my-config from an env file | ||||
| kubectl create configmap my-config --from-env-file=path/to/bar.env | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Secret | ||||
| 
 | ||||
| Create a new secret named my-secret with keys for each file in folder bar | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl create secret generic my-secret --from-file=path/to/bar | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="success", title="Bootstrapping Config" %} | ||||
| Imperative commands can be used to bootstrap config by using `--dry-run -o yaml`. | ||||
| `kubectl create secret generic my-secret --from-file=path/to/bar --dry-run -o yaml` | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Namespace | ||||
| 
 | ||||
| Create a new namespace named my-namespace | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl create namespace my-namespace | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ## Auth Resources | ||||
| 
 | ||||
| {% method %} | ||||
| ### ClusterRole | ||||
| 
 | ||||
| Create a ClusterRole named "foo" with API Group specified. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl create clusterrole foo --verb=get,list,watch --resource=rs.extensions | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ### ClusterRoleBinding | ||||
| 
 | ||||
| Create a role binding to give a user cluster admin permissions. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl create clusterrolebinding <choose-a-name> --clusterrole=cluster-admin --user=<your-cloud-email-account> | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Required Admin Permissions" %} | ||||
| The cluster-admin role maybe required for creating new RBAC bindings. | ||||
| {% endpanel %} | ||||
|    | ||||
| {% method %} | ||||
| ### Role | ||||
| 
 | ||||
| Create a Role named "foo" with API Group specified. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl create role foo --verb=get,list,watch --resource=rs.extensions | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ### RoleBinding | ||||
| 
 | ||||
| Create a RoleBinding for user1, user2, and group1 using the admin ClusterRole. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl create rolebinding admin --clusterrole=admin --user=user1 --user=user2 --group=group1 | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ### ServiceAccount | ||||
| 
 | ||||
| Create a new service account named my-service-account | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl create serviceaccount my-service-account | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,40 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Edit a live Resource in an editor | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Editing Resources | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Directly modify a Resource in the cluster by opening its Config in an editor. | ||||
| 
 | ||||
| {% method %} | ||||
| ## Edit | ||||
| 
 | ||||
| Edit allows a user to directly edit a Resource in a cluster rather than | ||||
| editing it through a local file. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```yaml | ||||
| # Edit the service named 'docker-registry': | ||||
| kubectl edit svc/docker-registry | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Use an alternative editor | ||||
| KUBE_EDITOR="nano" kubectl edit svc/docker-registry | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Edit the job 'myjob' in JSON using the v1 API format: | ||||
| kubectl edit job.v1.batch/myjob -o json | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| # Edit the deployment 'mydeployment' in YAML and save the modified config in its annotation: | ||||
| kubectl edit deployment/mydeployment -o yaml --save-config | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
|  | @ -0,0 +1,11 @@ | |||
| # Introduction | ||||
| 
 | ||||
| While Declarative Management of Applications is the recommended pattern for production | ||||
| use cases, imperative porcelain commands may be helpful for development or debugging | ||||
| issues.  These commands are particularly helpful for learning about Kubernetes when coming | ||||
| from an imperative system. | ||||
| 
 | ||||
| **Note:** Some imperative commands can by run with `--dry-run -o yaml` to display the declarative | ||||
| form. | ||||
| 
 | ||||
| This section describes imperative commands that will generate or patch Resource Config. | ||||
|  | @ -0,0 +1,168 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Imperatively Set fields on Resources | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Creating Resources | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Set fields on Resources directly from the commandline for the purposes of development or debugging. | ||||
| Not for production Application Management. | ||||
| 
 | ||||
| {% method %} | ||||
| ## Scale | ||||
| 
 | ||||
| The Replicas field on a Resource can be set using the `kubectl scale` command | ||||
| 
 | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| # Scale a replicaset named 'foo' to 3. | ||||
| kubectl scale --replicas=3 rs/foo | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Scale a resource identified by type and name specified in "foo.yaml" to 3. | ||||
| kubectl scale --replicas=3 -f foo.yaml | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # If the deployment named mysql's current size is 2, scale mysql to 3. | ||||
| kubectl scale --current-replicas=2 --replicas=3 deployment/mysql | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Scale multiple replication controllers. | ||||
| kubectl scale --replicas=5 rc/foo rc/bar rc/baz | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Scale statefulset named 'web' to 3. | ||||
| kubectl scale --replicas=3 statefulset/web | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Conditional Scale Update" %} | ||||
| It is possible to conditionally update the replicas if and only if the | ||||
| replicas haven't changed from their last known value using the `--current-replicas` flag. | ||||
| e.g. `kubectl scale --current-replicas=2 --replicas=3 deployment/mysql` | ||||
| {% endpanel %} | ||||
| 
 | ||||
| 
 | ||||
| {% method %} | ||||
| ## Labels | ||||
| 
 | ||||
| Labels can be set using the `kubectl label` command.  Multiple Resources can | ||||
| be updated in a single command using the `-l` flag. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```sh | ||||
| # Update pod 'foo' with the label 'unhealthy' and the value 'true'. | ||||
| kubectl label pods foo unhealthy=true | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update pod 'foo' with the label 'status' and the value 'unhealthy', overwriting any existing value. | ||||
| kubectl label --overwrite pods foo status=unhealthy | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update all pods in the namespace | ||||
| kubectl label pods --all status=unhealthy | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update a pod identified by the type and name in "pod.json" | ||||
| kubectl label -f pod.json status=unhealthy | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update pod 'foo' only if the resource is unchanged from version 1. | ||||
| kubectl label pods foo status=unhealthy --resource-version=1 | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update pod 'foo' by removing a label named 'bar' if it exists. | ||||
| # Does not require the --overwrite flag. | ||||
| kubectl label pods foo bar- | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Annotations | ||||
| 
 | ||||
| Annotations can be set using the `kubectl annotate` command. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```sh | ||||
| # Update pod 'foo' with the annotation 'description' and the value 'my frontend'. | ||||
| # If the same annotation is set multiple times, only the last value will be applied | ||||
| kubectl annotate pods foo description='my frontend' | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update a pod identified by type and name in "pod.json" | ||||
| kubectl annotate -f pod.json description='my frontend' | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update pod 'foo' with the annotation 'description' and the value 'my frontend running nginx', overwriting any | ||||
| existing value. | ||||
| kubectl annotate --overwrite pods foo description='my frontend running nginx' | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update all pods in the namespace | ||||
| kubectl annotate pods --all description='my frontend running nginx' | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update pod 'foo' only if the resource is unchanged from version 1. | ||||
| kubectl annotate pods foo description='my frontend running nginx' --resource-version=1 | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update pod 'foo' by removing an annotation named 'description' if it exists. | ||||
| # Does not require the --overwrite flag. | ||||
| kubectl annotate pods foo description- | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Patches | ||||
| 
 | ||||
| Arbitrary fields can be set using the `kubectl patch` command. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```sh | ||||
| # Partially update a node using a strategic merge patch. Specify the patch as JSON. | ||||
| kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}' | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Partially update a node using a strategic merge patch. Specify the patch as YAML. | ||||
| kubectl patch node k8s-node-1 -p $'spec:\n unschedulable: true' | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Partially update a node identified by the type and name specified in "node.json" using strategic merge patch. | ||||
| kubectl patch -f node.json -p '{"spec":{"unschedulable":true}}' | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update a container's image; spec.containers[*].name is required because it's a merge key. | ||||
| kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}' | ||||
| ``` | ||||
| 
 | ||||
| ```sh | ||||
| # Update a container's image using a json patch with positional arrays. | ||||
| kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"newimage"}]' | ||||
| ``` | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,71 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Kubectl is the Kubernetes CLI and Tooling | ||||
| - Kubectl provides a swiss army knife of functionality for working with Kubernetes | ||||
| - Kubectl may be used to deploy and manage applications on Kubernetes | ||||
| - Kubectl may be used for scripting and building higher-level frameworks | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Kubectl | ||||
| 
 | ||||
| Kubectl is the Kubernetes cli version of a swiss army knife. | ||||
| 
 | ||||
| ## Command Families | ||||
| 
 | ||||
| While Kubectl has many different commands, they typically fall into one of a few categories: | ||||
| 
 | ||||
| | Type                                   | Used For               | Description                                           | | ||||
| |----------------------------------------|-----------------------|----------------------------------------------------| | ||||
| | Declarative Resource Management        | Production Operations and GitOps   | Declaratively manage Kubernetes Workloads using Resource Config               | | ||||
| | Imperative Resource Management   | Development       | Run commands to manage Kubernetes Workloads using Command Line arguments and flags | | ||||
| | Printing Workload State | Debugging  | Print information about Workloads | | ||||
| | Interacting with Containers | Debugging  | Exec, Attach, Cp, Logs | | ||||
| | Cluster Management | Cluster Ops | Drain and Cordon Nodes | | ||||
| 
 | ||||
| ## Declarative Application Management | ||||
| 
 | ||||
| The preferred approach for managing Resources is through | ||||
| declarative files called Resource Config used with the Kubectl *Apply* command. | ||||
| This command reads a local (or remote) file structure and modifies cluster state to | ||||
| reflect the declared intent. | ||||
| 
 | ||||
| {% panel style="info", title="Apply" %} | ||||
| Apply is the preferred mechanism for managing Resources in a Kubernetes cluster. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## Printing state about Workloads | ||||
| 
 | ||||
| Users will need to view Workload state. | ||||
| 
 | ||||
| - Printing summarize state and information about Resources | ||||
| - Printing complete state and information about Resources | ||||
| - Printing specific fields from Resources | ||||
| - Query Resources matching labels | ||||
| 
 | ||||
| ## Debugging Workloads | ||||
| 
 | ||||
| Kubectl supports debugging by providing commands for: | ||||
| 
 | ||||
| - Printing Container logs | ||||
| - Printing cluster events | ||||
| - Exec or attaching to a Container | ||||
| - Copying files from Containers in the cluster to a user's filesystem | ||||
| 
 | ||||
| ## Cluster Management | ||||
| 
 | ||||
| On occasion, users may need to perform operations to the Nodes of cluster.  Kubectl supports | ||||
| commands to drain Workloads from a Node so that it can be decommission or debugged. | ||||
| 
 | ||||
| ## Porcelain | ||||
| 
 | ||||
| Users may find using Resource Config overly verbose for *Development* and prefer to work with | ||||
| the cluster *imperatively* with a shell-like workflow.  Kubectl offers porcelain commands for | ||||
| generating and modifying Resources. | ||||
| 
 | ||||
| - Generating + creating Resources such as Deployments, StatefulSets, Services, ConfigMaps, etc | ||||
| - Setting fields on Resources | ||||
| - Editing (live) Resources in a text editor | ||||
| 
 | ||||
| {% panel style="danger", title="Porcelain For Dev Only" %} | ||||
| Porcelain commands are time saving for experimenting with workloads in a dev cluster, but shouldn't | ||||
| be used for production. | ||||
| {% endpanel %} | ||||
|  | @ -1,11 +1,11 @@ | |||
| # The Kubernetes Resource Model | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - A Kubernetes API has 2 parts - a Resource Type and a Controller | ||||
| - Resources are object declared as json or yaml and written to a cluster | ||||
| - Resources are objects declared as json or yaml and written to a cluster | ||||
| - Controllers asynchronously actuate Resources after they are stored | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # The Kubernetes Resource Model | ||||
| 
 | ||||
| ## Resources | ||||
| 
 | ||||
| Instances of Kubernetes objects such as | ||||
|  | @ -13,27 +13,26 @@ Instances of Kubernetes objects such as | |||
| [StatefulSets](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/), | ||||
| [Jobs](https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/), | ||||
| [CronJobs](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) and | ||||
| [DaemonSets](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) are called Resources. | ||||
| [DaemonSets](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) are called **Resources**. | ||||
| 
 | ||||
| It is important to understand the structure of Resources, as Resources are how users interact | ||||
| with Kubernetes. | ||||
| 
 | ||||
| Users work with Resource APIs by declaring the desired state of Kubernetes Resources in | ||||
| files called Resource Config.  *After* Resource Config is Applied to a cluster and the | ||||
| request completes, a Controller actuates the API. | ||||
| **Users work with Resource APIs by declaring them in files called Resource Config.**  Resource Config is | ||||
| *Applied* (declarative Create/Update/Delete) to a Kubernetes cluster, and actuated by a *Controller*. | ||||
| 
 | ||||
| Resources are keyed by: | ||||
| 
 | ||||
| - **apiVersion** | ||||
| - **kind** | ||||
| - (metadata) **namespace** | ||||
| - (metadata) **name** | ||||
| - **apiVersion** (API Type Group and Version) | ||||
| - **kind** (API Type Name) | ||||
| - **metadata.namespace** (Instance namespace) | ||||
| - **metadata.name** (Instance name) | ||||
| 
 | ||||
| {% panel style="info", title="Default Namespace" %} | ||||
| If namespace is omitted from the Resource Config, the *default* namespace is used. | ||||
| {% panel style="warning", title="Default Namespace" %} | ||||
| If namespace is omitted from the Resource Config, the *default* namespace is used.  Users | ||||
| should almost always explicitly specify the namespace for their Application using a | ||||
| `kustomization.yaml`. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| ### Resources Structure | ||||
| 
 | ||||
| Resources have the following components. | ||||
|  | @ -42,11 +41,11 @@ Resources have the following components. | |||
| 
 | ||||
| **ObjectMeta:** Resource **name** and **namespace** + other metadata (labels, annotations, etc). | ||||
| 
 | ||||
| **Spec:** the desired state of the Resource - declared by the user. | ||||
| **Spec:** the desired state of the Resource - intended state the user provides to the cluster. | ||||
| 
 | ||||
| **Status:** the observed state of the object - recorded by the Controller. | ||||
| **Status:** the observed state of the object - recorded state the cluster provides to the user. | ||||
| 
 | ||||
| Resource Config omits the Status. | ||||
| Resource Config written by the user omits the Status field. | ||||
| 
 | ||||
| **Example Deployment Resource Config** | ||||
| {% sample lang="yaml" %} | ||||
|  | @ -75,7 +74,7 @@ spec: | |||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Spec and Status" %} | ||||
| Resources such as ConfigMaps and Secrets do not have a Status written by a Controller, | ||||
| Resources such as ConfigMaps and Secrets do not have a Status, | ||||
| and as a result their Spec is implicit (i.e. they don't have a spec field). | ||||
| {% endpanel %} | ||||
| 
 | ||||
|  | @ -88,25 +87,33 @@ changes either to desired state of Resources (create, update, delete) or the sys | |||
| Controllers then make changes to the cluster to fulfill the intent specified by the user | ||||
| (e.g. in Resource Config) or automation (e.g. changes from Autoscalers). | ||||
| 
 | ||||
| {% panel style="info", title="Asynchronous Actuation" %} | ||||
| **Example:** After a user creates a Deployment, the Deployment Controller will see | ||||
| that the Deployment exists and verify that the corresponding ReplicaSet it expects | ||||
| to find exists.  The Controller will see that the ReplicaSet does not exist and will | ||||
| create one. | ||||
| 
 | ||||
| {% panel style="warning", title="Asynchronous Actuation" %} | ||||
| Because Controllers run asynchronously, issues such as a bad | ||||
| Container Image or unschedulable Pods will not be present in the CRUD response. | ||||
| Tools must facilitate watching the state of the system until changes are | ||||
| completely actuated by Controllers. | ||||
| Tooling must facilitate processes for watching the state of the system until changes are | ||||
| completely actuated by Controllers.  Once the changes have been fully actuated such | ||||
| that the desired state matches the observed state, the Resource is considered *Settled*. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ### Controller Structure | ||||
| 
 | ||||
| **Reconcile** | ||||
| 
 | ||||
| Controllers actuate Resources by reading the Resource they are Reconciling + related Resources. | ||||
| Controllers **do not** Reconcile events, instead they compare the expected | ||||
| cluster state to the observed cluster state, and make changes. | ||||
| Controllers actuate Resources by reading the Resource they are Reconciling + related Resources, | ||||
| such as those that they create and delete. | ||||
| 
 | ||||
| - Deployment Controller creates/deletes ReplicaSets | ||||
| - ReplicaSet Controller creates/delete Pods | ||||
| - Scheduler (Controller) writes Nodes to Pods | ||||
| - Node (Controller) runs Containers specifid in Pods on the Node | ||||
| **Controllers *do not* Reconcile events, rather they Reconcile the expected | ||||
| cluster state to the observed cluster state at the time Reconcile is run.** | ||||
| 
 | ||||
| 1. Deployment Controller creates/deletes ReplicaSets | ||||
| 1. ReplicaSet Controller creates/delete Pods | ||||
| 1. Scheduler (Controller) writes Nodes to Pods | ||||
| 1. Node (Controller) runs Containers specifid in Pods on the Node | ||||
| 
 | ||||
| **Watch** | ||||
| 
 | ||||
|  | @ -123,7 +130,7 @@ the Event for this information). | |||
| 
 | ||||
| {% panel style="info", title="Level vs Edge Based Reconciliation" %} | ||||
| Because Controllers don't respond to individual Events, but instead Reconcile the state | ||||
| of the system at the time the Controller is run, several different changes may be observed | ||||
| and Reconciled together.  This is referred to as a **Level Based** system, whereas a system that | ||||
| responds to each requested state would be an **Edge Based** system. | ||||
| of the system at the time that Reconcile is run, **changes from several different events may be observed | ||||
| and Reconciled together.**  This is referred to as a *Level Based* system, whereas a system that | ||||
| responds to each event individually would be referred to as an *Edge Based* system. | ||||
| {% endpanel %} | ||||
|  | @ -1,45 +0,0 @@ | |||
| # Merging Fields | ||||
| 
 | ||||
| ## Shared Ownership of Fields | ||||
| 
 | ||||
| ### User Owned Fields | ||||
| 
 | ||||
| ### Cluster Owned Fields  | ||||
| 
 | ||||
| ### Transferring Field Ownership | ||||
| 
 | ||||
| ## Merging Resources | ||||
| 
 | ||||
| ### Adding Fields | ||||
| 
 | ||||
| ### Updating Fields | ||||
| 
 | ||||
| ### Deleting Fields | ||||
| 
 | ||||
| ## Field Merge Semantics | ||||
| 
 | ||||
| ### Merging Primitives | ||||
| 
 | ||||
| **Field Creation:** | ||||
| 
 | ||||
| **Field Update:** | ||||
| 
 | ||||
| **Field Deletion:** | ||||
| 
 | ||||
| ### Merging Structures | ||||
| 
 | ||||
| ### Merging Maps | ||||
| 
 | ||||
| ### Merging Lists of Primitives | ||||
| 
 | ||||
| **Merge Strategy:** | ||||
| 
 | ||||
| **Ordering:** | ||||
| 
 | ||||
| ### Merging Lists of Structures | ||||
| 
 | ||||
| **Merge Strategy:** | ||||
| 
 | ||||
| **Merge Key:** | ||||
| 
 | ||||
| **Ordering:** | ||||
|  | @ -1,768 +0,0 @@ | |||
| # Creating Bases and Variations | ||||
| 
 | ||||
| {% panel style="info", title="TL;DR" %} | ||||
| - Create Variants of a Project for different Environments. | ||||
| - Customize Resource Config shared across multiple Projects. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| It is common for users to deploy several variants of the same project. | ||||
| 
 | ||||
| Examples: | ||||
| 
 | ||||
| - a project may be deployed to dev, test, staging, canary and production environments, | ||||
|   but with variants between the environments. | ||||
| - a project may be deployed to different clusters that are tuned differently or running | ||||
|   different versions of the project. | ||||
|    | ||||
| Apply allows users to refer to another project as *Base*, and then apply additional customizations | ||||
| to it. | ||||
| 
 | ||||
| Examples of changes between variants: | ||||
| 
 | ||||
| - Change replica count and resource | ||||
| - Change image tag | ||||
| - Change Environment Variables and Command Args  | ||||
| 
 | ||||
| ## Referring to a Base | ||||
| 
 | ||||
| A project can refer by adding a path (relative to the `apply.yaml`) to `base` that | ||||
| points to a directory containing another `apply.yaml` file.  This will automatically | ||||
| add all of the Resources from the base project to the current project. | ||||
| 
 | ||||
| Bases can be: | ||||
| 
 | ||||
| - Relative paths from the `apply.yaml` - e.g. `../base` | ||||
| - Urls - e.g. `github.com/kubernetes-sigs/kustomize/examples/multibases?ref=v1.0.6` | ||||
| 
 | ||||
| {% panel style="info", title="URL Syntax" %} | ||||
| The Base URLs should follow | ||||
| [hashicorp/go-getter URL format](https://github.com/hashicorp/go-getter#url-format). | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% method %} | ||||
| **Example:** Add the Resource Config from a base. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| bases: | ||||
| - ../base | ||||
| 
 | ||||
| # ../base/apply.yaml | ||||
| configMapGenerator: | ||||
| - name: myJavaServerEnvVars | ||||
|   literals:	 | ||||
|   - JAVA_HOME=/opt/java/jdk | ||||
|   - JAVA_TOOL_OPTIONS=-agentlib:hprof | ||||
| resources: | ||||
| - deployment.yaml | ||||
| 
 | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
|         volumeMounts: | ||||
|         - mountPath: /etc/config | ||||
|           name: config-volume | ||||
|       volumes: | ||||
|       - configMap: | ||||
|           name: myJavaServerEnvVars | ||||
|         name: config-volume | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Unmodified Generated Base Resource | ||||
| apiVersion: v1 | ||||
| kind: ConfigMap | ||||
| metadata: | ||||
|   name: myJavaServerEnvVars-k44mhd6h5f | ||||
| data: | ||||
|   JAVA_HOME: /opt/java/jdk | ||||
|   JAVA_TOOL_OPTIONS: -agentlib:hprof | ||||
| --- | ||||
| # Unmodified  Config Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
|         volumeMounts: | ||||
|         - mountPath: /etc/config | ||||
|           name: config-volume | ||||
|       volumes: | ||||
|       - configMap: | ||||
|           name: myJavaServerEnvVars-k44mhd6h5f | ||||
|         name: config-volume | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ## Customizing Each Variant | ||||
| 
 | ||||
| When users have multiple similar projects with a shared base, they will want | ||||
| to create variants that customize the original base. | ||||
| 
 | ||||
| ### Customizing Pod Environment Variables | ||||
| 
 | ||||
| {% method %} | ||||
| Customizing Pod Command arguments may be performed by generating different ConfigMaps | ||||
| in each Variant and using the ConfigMap values in the Pod Environment Variables. | ||||
| 
 | ||||
| - Base uses ConfigMap data in Pods as Environment Variables | ||||
| - Each Variant defines different ConfigMap data | ||||
| 
 | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) provide different Environment | ||||
| Variables to a Pod. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| bases: | ||||
| - ../base | ||||
| configMapGenerator: | ||||
| - name: special-config | ||||
|   literals: | ||||
|   - special.how=very | ||||
|   - special.type=charm | ||||
| 
 | ||||
| # ../base/apply.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| 
 | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: nginx-deployment | ||||
|   labels: | ||||
|     app: nginx | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - name: nginx | ||||
|         image: nginx | ||||
|         env: | ||||
|         - name: SPECIAL_LEVEL_KEY | ||||
|           valueFrom: | ||||
|             configMapKeyRef: | ||||
|               name: special-config | ||||
|               key: special.how | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resources that are Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Generated Variant Resource | ||||
| apiVersion: v1 | ||||
| kind: ConfigMap | ||||
| metadata: | ||||
|   name: special-config-82tc88cmcg | ||||
| data: | ||||
|   special.how: very | ||||
|   special.type: charm | ||||
| --- | ||||
| # Unmodified Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - env: | ||||
|         - name: SPECIAL_LEVEL_KEY | ||||
|           valueFrom: | ||||
|             configMapKeyRef: | ||||
|               key: special.how | ||||
|               name: special-config-82tc88cmcg | ||||
|         image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| See [ConfigMaps and Secrets](dam_generators.md). | ||||
| 
 | ||||
| 
 | ||||
| ### Customizing Pod Command Arguments | ||||
| 
 | ||||
| {% method %} | ||||
| Customizing Pod Command arguments may be performed by generating different ConfigMaps | ||||
| in each Variant and using the ConfigMap values in the Pod Command Arguments. | ||||
| 
 | ||||
| - Base uses ConfigMap data in Pods as Command Arguments | ||||
| - Each Variant defines different ConfigMap data | ||||
| 
 | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) provide different Commandline | ||||
| Arguments to a Pod. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| bases: | ||||
| - ../base | ||||
| configMapGenerator: | ||||
| - name: special-config | ||||
|   literals: | ||||
|   - special.how=very | ||||
|   - special.type=charm | ||||
| 
 | ||||
| # ../base/apply.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| 
 | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: nginx-deployment | ||||
|   labels: | ||||
|     app: nginx | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - name: test-container | ||||
|         image: k8s.gcr.io/busybox | ||||
|         # Use the ConfigMap Environment Variables in the Command | ||||
|         command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] | ||||
|         env: | ||||
|         - name: SPECIAL_LEVEL_KEY | ||||
|           valueFrom: | ||||
|             configMapKeyRef: | ||||
|               name: special-config | ||||
|               key: SPECIAL_LEVEL | ||||
|         - name: SPECIAL_TYPE_KEY | ||||
|           valueFrom: | ||||
|             configMapKeyRef: | ||||
|               name: special-config | ||||
|               key: SPECIAL_TYPE | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resources that are Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Generated Variant Resource | ||||
| apiVersion: v1 | ||||
| kind: ConfigMap | ||||
| metadata: | ||||
|   name: special-config-82tc88cmcg | ||||
| data: | ||||
|   special.how: very | ||||
|   special.type: charm | ||||
| --- | ||||
| # Unmodified Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - command: | ||||
|         - /bin/sh | ||||
|         - -c | ||||
|         # Use the ConfigMap Environment Variables in the Command | ||||
|         - echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY) | ||||
|         env: | ||||
|         - name: SPECIAL_LEVEL_KEY | ||||
|           valueFrom: | ||||
|             configMapKeyRef: | ||||
|               key: SPECIAL_LEVEL | ||||
|               name: special-config-82tc88cmcg | ||||
|         - name: SPECIAL_TYPE_KEY | ||||
|           valueFrom: | ||||
|             configMapKeyRef: | ||||
|               key: SPECIAL_TYPE | ||||
|               name: special-config-82tc88cmcg | ||||
|         image: k8s.gcr.io/busybox | ||||
|         name: test-container | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| See [ConfigMaps and Secrets](dam_generators.md). | ||||
| 
 | ||||
| ### Customizing Image Tags | ||||
| 
 | ||||
| {% method %} | ||||
| Customizing the Image Tag run in each Variant can be performed by specifying `imageTags` | ||||
| in each Variant `apply.yaml`. | ||||
| 
 | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) can use images with different tags. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| bases: | ||||
| - ../base | ||||
| imageTags: | ||||
|   - name: nginx | ||||
|     newTag: 1.8.0 | ||||
| 
 | ||||
| # ../base/apply.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| 
 | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: nginx-deployment | ||||
|   labels: | ||||
|     app: nginx | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - name: nginx | ||||
|         image: nginx | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Modified Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       # The image has been changed to include the tag | ||||
|       - image: nginx:1.8.0 | ||||
|         name: nginx | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| See [Image Tags](dam_images.md). | ||||
| 
 | ||||
| ### Customizing Namespace | ||||
| 
 | ||||
| {% method %} | ||||
| Customizing the Namespace in each Variant can be performed by specifying `namespace` in each | ||||
| Variant `apply.yaml`. | ||||
| 
 | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) run in different Namespaces. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| bases: | ||||
| - ../base | ||||
| namespace: test | ||||
| 
 | ||||
| # ../base/apply.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| 
 | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Modified Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
|   # Namespace has been set | ||||
|   namespace: test | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| 
 | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| See [Namespaces and Names](dam_namespaces.md). | ||||
| 
 | ||||
| ### Customizing Resource Name Prefixes | ||||
| 
 | ||||
| {% method %} | ||||
| Customizing the Name by adding a prefix in each Variant can be performed by specifying `namePrefix` in each | ||||
| Variant `apply.yaml`. | ||||
| 
 | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) have different Naming conventions. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| bases: | ||||
| - ../base | ||||
| namePrefix: test- | ||||
| 
 | ||||
| # ../base/apply.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| 
 | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Modified Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   # Name has been prefixed with the environment | ||||
|   name: test-nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| See [Namespaces and Names](dam_namespaces.md). | ||||
| 
 | ||||
| ### Customizing Arbitrary Fields with Overlays | ||||
| 
 | ||||
| {% method %} | ||||
| Arbitrary fields may be added, changed, or deleted by supplying *Overlays* against the | ||||
| Resources provided by the base.  Overlays are sparse Resource definitions that | ||||
| allow arbitrary customizations to be performed without requiring a base to expose | ||||
| the customization as a template. | ||||
| 
 | ||||
| Overlays require the *Group, Version, Kind* and *Name* of the Resource to be specified, as | ||||
| well as any fields that should be set on the base Resource.  Overlays are applied using | ||||
| *StrategicMergePatch*. | ||||
| 
 | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) require fields such as | ||||
| replicas or resources to be overridden. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| bases: | ||||
| - ../base | ||||
| patchesStrategicMerge: | ||||
| - overlay.yaml | ||||
| 
 | ||||
| # overlay.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # override replicas | ||||
|   replicas: 3 | ||||
|   template: | ||||
|     spec: | ||||
|       containers: | ||||
|       - name: nginx | ||||
|         # override resources | ||||
|         resources: | ||||
|           limits: | ||||
|             cpu: "1" | ||||
|           requests: | ||||
|             cpu: "0.5" | ||||
| 
 | ||||
| # ../base/apply.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| 
 | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
|         resources: | ||||
|           limits: | ||||
|             cpu: "0.2" | ||||
|           requests: | ||||
|             cpu: "0.1"         | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Overlayed Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # replicas field has been added | ||||
|   replicas: 3 | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
|         # resources have been overridden | ||||
|         resources: | ||||
|           limits: | ||||
|             cpu: "1" | ||||
|           requests: | ||||
|             cpu: "0.5" | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Overlay URLs" %} | ||||
| Like Bases, Overlays may also be URLs and should follow the | ||||
| [hashicorp/go-getter URL format](https://github.com/hashicorp/go-getter#url-format). | ||||
| {% endpanel %} | ||||
| 
 | ||||
| 
 | ||||
| ### Customizing Arbitrary Fields with JsonPatch | ||||
| 
 | ||||
| {% method %} | ||||
| Arbitrary fields may be added, changed, or deleted by supplying *Json 6902 Patches* against the | ||||
| Resources provided by the base. | ||||
| 
 | ||||
| **Use Case:** Different Environments (test, dev, staging, canary, prod) require fields such as | ||||
| replicas or resources to be overridden. | ||||
| 
 | ||||
| Json 6902 Patches are [rfc6902](https://tools.ietf.org/html/rfc6902) patches that are applied | ||||
| to resources.  Patches require the *Group, Version, Kind* and *Name* of the Resource to be | ||||
| specified in addition to the Patch.  Patches offer a number of powerful imperative operations | ||||
| for modifying the base Resources. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| **Input:** The apply.yaml file | ||||
| 
 | ||||
| ```yaml | ||||
| # apply.yaml | ||||
| bases: | ||||
| - ../base | ||||
| patchesJson6902: | ||||
| - target: | ||||
|     group: apps | ||||
|     version: v1 | ||||
|     kind: Deployment | ||||
|     name: nginx-deployment | ||||
|   path: patch.yaml | ||||
| 
 | ||||
| # patch.yaml | ||||
| - op: add | ||||
|   path: /spec/replicas | ||||
|   value: 3 | ||||
| 
 | ||||
| # ../base/apply.yaml | ||||
| resources: | ||||
| - deployment.yaml | ||||
| 
 | ||||
| # ../base/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| 
 | ||||
| **Applied:** The Resource that is Applied to the cluster | ||||
| 
 | ||||
| ```yaml | ||||
| # Patched Base Resource | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   labels: | ||||
|     app: nginx | ||||
|   name: nginx-deployment | ||||
| spec: | ||||
|   # replicas field has been added | ||||
|   replicas: 3 | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: nginx | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: nginx | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: nginx | ||||
|         name: nginx | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ### Adding Resources to a Base | ||||
| 
 | ||||
| Additional Resources not specified in the Base may be added to Variants by | ||||
| Variants specifying them as `resources` in their `apply.yaml`. | ||||
|  | @ -0,0 +1,197 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Print information about the Cluster and Client versions | ||||
| - Print information about the Control Plane | ||||
| - Print information about Nodes | ||||
| - Print information about APIs | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Cluster Info | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| It may be necessary to learn about the Kubernetes cluster itself, rather | ||||
| than just the workloads running in it.  This can be useful for debugging | ||||
| unexpected behavior. | ||||
| 
 | ||||
| ## Versions | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| The `kubectl version` prints the client and server versions.  Note that | ||||
| the client version may not be present for clients built locally from | ||||
| source. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl version | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.5", GitCommit:"f01a2bf98249a4db383560443a59bed0c13575df", GitTreeState:"clean", BuildDate:"2018-03-19T19:38:17Z", GoVersion:"go1.9.4", Compiler:"gc", Platform:"darwin/amd64"} | ||||
| Server Version: version.Info{Major:"1", Minor:"11+", GitVersion:"v1.11.6-gke.2", GitCommit:"04ad69a117f331df6272a343b5d8f9e2aee5ab0c", GitTreeState:"clean", BuildDate:"2019-01-04T16:19:46Z", GoVersion:"go1.10.3b4", Compiler:"gc", Platform:"linux/amd64"} | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="warning", title="Version Skew" %} | ||||
| Kubectl supports +/-1 version skew with the Kubernetes cluster.  Kubectl | ||||
| versions that are more than 1 version ahead of or behind the cluster are | ||||
| not guaranteed to be compatible. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## Control Plane and Addons | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| The `kubectl cluster-info` prints information about the control plane and | ||||
| add-ons. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl cluster-info | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
|   Kubernetes master is running at https://1.1.1.1 | ||||
|   GLBCDefaultBackend is running at https://1.1.1.1/api/v1/namespaces/kube-system/services/default-http-backend:http/proxy | ||||
|   Heapster is running at https://1.1.1.1/api/v1/namespaces/kube-system/services/heapster/proxy | ||||
|   KubeDNS is running at https://1.1.1.1/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy | ||||
|   Metrics-server is running at https://1.1.1.1/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Kube Proxy" %} | ||||
| The URLs printed by `cluster-info` can be access at `127.0.0.1:8001` by | ||||
| running `kubectl proxy`.  | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ## Nodes | ||||
| 
 | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| The `kubectl top node` and `kubectl top pod` print information about the | ||||
| top nodes and pods. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl top node | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
|   NAME                                 CPU(cores)   CPU%      MEMORY(bytes)   MEMORY%    | ||||
|   gke-dev-default-pool-e1e7bf6a-cc8b   37m          1%        571Mi           10%        | ||||
|   gke-dev-default-pool-e1e7bf6a-f0xh   103m         5%        1106Mi          19%        | ||||
|   gke-dev-default-pool-e1e7bf6a-jfq5   139m         7%        1252Mi          22%        | ||||
|   gke-dev-default-pool-e1e7bf6a-x37l   112m         5%        982Mi           17%   | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| ## APIs | ||||
| 
 | ||||
| The `kubectl api-versions` and `kubectl resource-types` print information | ||||
| about the available Kubernetes APIs.  This information is read from the | ||||
| Discovery Service. | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| Print the Resource Types available in the cluster. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl api-resources | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| NAME                              SHORTNAMES   APIGROUP                       NAMESPACED   KIND | ||||
| bindings                                                                      true         Binding | ||||
| componentstatuses                 cs                                          false        ComponentStatus | ||||
| configmaps                        cm                                          true         ConfigMap | ||||
| endpoints                         ep                                          true         Endpoints | ||||
| events                            ev                                          true         Event | ||||
| limitranges                       limits                                      true         LimitRange | ||||
| namespaces                        ns                                          false        Namespace | ||||
| ... | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| Print the API versions available in the cluster. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl api-versions | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
|   admissionregistration.k8s.io/v1beta1 | ||||
|   apiextensions.k8s.io/v1beta1 | ||||
|   apiregistration.k8s.io/v1 | ||||
|   apiregistration.k8s.io/v1beta1 | ||||
|   apps/v1 | ||||
|   apps/v1beta1 | ||||
|   apps/v1beta2 | ||||
|   ... | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Discovery" %} | ||||
| The discovery information can be viewed at `127.0.0.1:8001/` by running | ||||
| `kubectl proxy`.  The Discovery for specific API can be found under either | ||||
| `/api/v1` or `apis/<group>/<version>`, depending on the API group - | ||||
| e.g. `127.0.0.1:8001/apis/apps/v1` | ||||
| {% endpanel %} | ||||
| 
 | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| The `kubectl explain` command can be used to print metadata about specific | ||||
| Resource types.  This is useful for learning about the type. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl explain deployment --api-version apps/v1 | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| KIND:     Deployment | ||||
| VERSION:  apps/v1 | ||||
| 
 | ||||
| DESCRIPTION: | ||||
|      Deployment enables declarative updates for Pods and ReplicaSets. | ||||
| 
 | ||||
| FIELDS: | ||||
|    apiVersion	<string> | ||||
|      APIVersion defines the versioned schema of this representation of an | ||||
|      object. Servers should convert recognized schemas to the latest internal | ||||
|      value, and may reject unrecognized values. More info: | ||||
|      https://git.k8s.io/community/contributors/devel/api-conventions.md#resources | ||||
| 
 | ||||
|    kind	<string> | ||||
|      Kind is a string value representing the REST resource this object | ||||
|      represents. Servers may infer this from the endpoint the client submits | ||||
|      requests to. Cannot be updated. In CamelCase. More info: | ||||
|      https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds | ||||
| 
 | ||||
|    metadata	<Object> | ||||
|      Standard object metadata. | ||||
| 
 | ||||
|    spec	<Object> | ||||
|      Specification of the desired behavior of the Deployment. | ||||
| 
 | ||||
|    status	<Object> | ||||
|      Most recently observed status of the Deployment. | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
|   | ||||
|  | @ -0,0 +1,64 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Print verbose debug information about a Resource | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Describe Resources | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| {% method %} | ||||
| Describe is a **higher level printing operation that may aggregate data from other sources** in addition | ||||
| to the Resource being queried (e.g. Events). | ||||
| 
 | ||||
| Describe pulls out the most important information about a Resource from the Resource itself and related | ||||
| Resources, and formats and prints this information on multiple lines. | ||||
| 
 | ||||
| - Aggregates data from related Resources | ||||
| - Formats Verbose Output for debugging | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl describe deployments | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| Name:                   nginx | ||||
| Namespace:              default | ||||
| CreationTimestamp:      Thu, 15 Nov 2018 10:58:03 -0800 | ||||
| Labels:                 app=nginx | ||||
| Annotations:            deployment.kubernetes.io/revision=1 | ||||
| Selector:               app=nginx | ||||
| Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable | ||||
| StrategyType:           RollingUpdate | ||||
| MinReadySeconds:        0 | ||||
| RollingUpdateStrategy:  25% max unavailable, 25% max surge | ||||
| Pod Template: | ||||
|   Labels:  app=nginx | ||||
|   Containers: | ||||
|    nginx: | ||||
|     Image:        nginx | ||||
|     Port:         <none> | ||||
|     Host Port:    <none> | ||||
|     Environment:  <none> | ||||
|     Mounts:       <none> | ||||
|   Volumes:        <none> | ||||
| Conditions: | ||||
|   Type           Status  Reason | ||||
|   ----           ------  ------ | ||||
|   Progressing    True    NewReplicaSetAvailable | ||||
|   Available      True    MinimumReplicasAvailable | ||||
| OldReplicaSets:  <none> | ||||
| NewReplicaSet:   nginx-78f5d695bd (1/1 replicas created) | ||||
| Events:          <none> | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="info", title="Get vs Describe" %} | ||||
| When Describing a Resource, it may aggregate information from several other Resources.  For instance Describing | ||||
| a Node will aggregate Pod Resources to print the Node utilization. | ||||
| 
 | ||||
| When Getting a Resource, it will only print information available from reading that Resource.  While Get may aggregate | ||||
| data from the the *fields* of that Resource, it won't look at fields from other Resources. | ||||
| {% endpanel %} | ||||
|  | @ -0,0 +1,183 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Format and print specific fields from Resources | ||||
| - Use when scripting with Get | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Print Resource Fields | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Kubectl Get is able to pull out fields from Resources it queries and format them as output. | ||||
| 
 | ||||
| This may be **useful for scripting or gathering data** about Resources from a Kubernetes cluster. | ||||
| 
 | ||||
| ## Get | ||||
| 
 | ||||
| The `kubectl get` reads Resources from the cluster and formats them as output.  The examples in | ||||
| this chapter will query for Resources by providing Get the *Resource Type* with the | ||||
| Version and Group as an argument. | ||||
| For more query options see [Queries and Options](queries_and_options.md). | ||||
| 
 | ||||
| Kubectl can format and print specific fields from Resources using Json Path. | ||||
| 
 | ||||
| {% panel style="warning", title="Scripting Pitfalls" %} | ||||
| By default, if no API group or version is specified, kubectl will use the group and version preferred by | ||||
| the apiserver. | ||||
| 
 | ||||
| Because the **Resource structure may change between API groups and Versions**, users *should* specify the | ||||
| API Group and Version when emitting fields from `kubectl get` to make sure the command does not break | ||||
| in future releases. | ||||
| 
 | ||||
| Failure to do this may result in the different API group / version being used after a cluster upgrade, and | ||||
| this group / version may have changed the representation of fields. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| ### Json Path | ||||
| 
 | ||||
| Print the fields from the Json Path | ||||
| 
 | ||||
| **Note:**  Json Path can also be read from a file using `-o custom-columns-file`. | ||||
| 
 | ||||
| - Json Path template is composed of JSONPath expressions enclosed by {}. In addition to the original JSONPath syntax, several capabilities are added: | ||||
|   - The `$` operator is optional (the expression starts from the root object by default). | ||||
|   - Use "" to quote text inside JSONPath expressions. | ||||
|   - Use range operator to iterate lists. | ||||
|   - Use negative slice indices to step backwards through a list. Negative indices do not “wrap around” a list. They are valid as long as -index + listLength >= 0. | ||||
| 
 | ||||
| ### Json Path Symbols Table | ||||
| 
 | ||||
| | Function	| Description	| Example	| Result | | ||||
| |---|---|---|---| | ||||
| | text	| the plain text	| kind is {.kind}	| kind is List | | ||||
| | @	| the current object	| {@}	| the same as input | | ||||
| | . or [] |	child operator	| {.kind} or {[‘kind’]}	| List | | ||||
| | ..	| recursive descent	| {..name}	| 127.0.0.1 127.0.0.2 myself e2e | | ||||
| | *	| wildcard. Get all objects	| {.items[*].metadata.name}	| [127.0.0.1 127.0.0.2] | | ||||
| | [start:end :step]	| subscript operator	| {.users[0].name}	| myself | | ||||
| | [,]	| union operator	| {.items[*][‘metadata.name’, ‘status.capacity’]}	|127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8] | | ||||
| | ?()	| filter	| {.users[?(@.name==“e2e”)].user.password}	| secret | | ||||
| | range, end	| iterate list	| {range .items[*]}[{.metadata.name}, {.status.capacity}] {end}	| [127.0.0.1, map[cpu:4]] [127.0.0.2, map[cpu:8]] | | ||||
| | “	| quote interpreted string	|{range .items[*]}{.metadata.name}{’\t’} | {end}	127.0.0.1 127.0.0.2| | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| Print the Json representation of the first Deployment in the list on a single line. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployment.v1.apps -o=jsonpath='{.items[0]}{"\n"}' | ||||
| 
 | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| map[apiVersion:apps/v1 kind:Deployment...replicas:1 updatedReplicas:1]] | ||||
| ``` | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| Print the `metadata.name` field for the first Deployment in the list. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployment.v1.apps -o=jsonpath='{.items[0].metadata.name}{"\n"}' | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| For each Deployment, print its `metadata.name` field and a newline afterward. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployment.v1.apps -o=jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| nginx | ||||
| nginx2 | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| For each Deployment, print its `metadata.name` and `.status.availableReplicas`. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployment.v1.apps -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.availableReplicas}{"\n"}{end}' | ||||
| ``` | ||||
| ```bash | ||||
| nginx	1 | ||||
| nginx2	1 | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| Print the list of Deployments as single line. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployment.v1.apps -o=jsonpath='{@}{"\n"}' | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| map[kind:List apiVersion:v1 metadata:map[selfLink: resourceVersion:] items:[map[apiVersion:apps/v1 kind:Deployment...replicas:1 updatedReplicas:1]]]] | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| Print each Deployment on a new line. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployment.v1.apps -o=jsonpath='{range .items[*]}{@}{"\n"}{end}' | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| map[kind:Deployment...readyReplicas:1]] | ||||
| map[kind:Deployment...readyReplicas:1]] | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% panel style="info", title="Literal Syntax" %} | ||||
| On Windows, you must double quote any JSONPath template that contains spaces (not single quote as shown above for bash). | ||||
| This in turn means that you must use a single quote or escaped double quote around any literals in the template. | ||||
| 
 | ||||
| For example: | ||||
| 
 | ||||
| ```bash | ||||
| C:\> kubectl get pods -o=jsonpath="{range .items[*]}{.metadata.name}{'\t'}{.status.startTime}{'\n'}{end}" | ||||
| ``` | ||||
| {% endpanel %} | ||||
|  | @ -0,0 +1,176 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Queries for Getting or Describing Resources | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Matching Objects from Get and Describing | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Match Resources with Queries when Getting or Describing them. | ||||
| 
 | ||||
| {% method %} | ||||
| ## Resource Config By `kustomization.yaml` | ||||
| 
 | ||||
| Get all Resources provided by the `kustomization.yaml` in project/. | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get -k project/ | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Resource Config By Dir | ||||
| 
 | ||||
| Get all Resources present in the Resource Config for a directory. | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get -f configs/ | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Resource Types | ||||
| 
 | ||||
| Get **all** Resources in a namespace for a given type. | ||||
| 
 | ||||
| The Group and Version for the Resource are determined by the apiserver discovery service. | ||||
| 
 | ||||
| The Singular, Plural, Short Name also apply to *Types with Name* and *Types with Selectors*. | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| # Plural | ||||
| $ kubectl get deployments | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| # Singular | ||||
| $ kubectl get deployment | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| # Short name | ||||
| $ kubectl get deploy | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Resource Types with Group / Version | ||||
| 
 | ||||
| Get **all** Resources in a namespace for a given type. | ||||
| 
 | ||||
| The Group and Version for the Resource are explicit. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployments.apps | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployments.v1.apps | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Resource Types with Name | ||||
| 
 | ||||
| Get named Resources in a namespace for a given type. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployment nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Label Selector | ||||
| 
 | ||||
| Get **all** Resources in a namespace **matching a label select** for a given type. | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployments -l app=nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Namespaces | ||||
| 
 | ||||
| By default Get and Describe will fetch resource in the default namespace or the namespace specified | ||||
| with `--namespace`. | ||||
| 
 | ||||
| The `---all-namespaces` flag will **fetch Resources from all namespaces**. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployments --all-namespaces | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| 
 | ||||
| {% method %} | ||||
| ## List multiple Resource types | ||||
| 
 | ||||
| Get and Describe can accept **multiple Resource types**, and it will print them both in separate sections. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployments,services | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
|    | ||||
| {% method %} | ||||
| ## List multiple Resource types by name | ||||
| 
 | ||||
| Get and Describe can accept **multiple Resource types and names**. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get kubectl get rc/web service/frontend pods/web-pod-13je7 | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|    | ||||
| {% method %} | ||||
| ## Uninitialized | ||||
| 
 | ||||
| Kubernetes **Resources may be hidden until they have gone through an initialization process**. | ||||
| These Resources can be view with the `--include-uninitialized` flag. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployments --include-uninitialized | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% method %} | ||||
| ## Not Found | ||||
| 
 | ||||
| By default, Get or Describe **will return an error if an object is requested and doesn't exist**. | ||||
| The `--ignore-not-found` flag will cause kubectl to exit 0 if the Resource is not found | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployment nginx --ignore-not-found | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,225 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Get or List Raw Resources in a cluster as Yaml or Json | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Print Raw Resource | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Inspecting or Debugging Resources. | ||||
| 
 | ||||
| The Kubernetes Resources stored in etcd by the apiserver have **many more fields than | ||||
| are shown in the summarized views**.  Users can learn much more about a Resource by | ||||
| viewing the Raw Resource as Yaml or Json.  The Raw Resource will contain: | ||||
|   | ||||
| - fields specified by the **user** in the Resource Config (e.g. `metdata.name`) | ||||
| - metadata fields owned by the **apiserver** (e.g. `metadata.creationTimestamp`) | ||||
| - fields defaulted by the **apiserver** (e.g. `spec..imagePullPolicy`) | ||||
| - fields set by **Controllers** (e.g. `spec.clusterIp`, `status`) | ||||
| 
 | ||||
| ## Get | ||||
| 
 | ||||
| The `kubectl get` reads Resources from the cluster and formats them as output.  The examples in | ||||
| this chapter will query for Resources by providing Get the *Resource Type* as an argument. | ||||
| For more query options see [Queries and Options](queries_and_options.md). | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| ### Yaml | ||||
| 
 | ||||
| Print the Raw Resource formatting it as Yaml. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployments -o yaml | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| apiVersion: v1 | ||||
| items: | ||||
| - apiVersion: extensions/v1beta1 | ||||
|   kind: Deployment | ||||
|   metadata: | ||||
|     annotations: | ||||
|       deployment.kubernetes.io/revision: "1" | ||||
|     creationTimestamp: 2018-11-15T18:58:03Z | ||||
|     generation: 1 | ||||
|     labels: | ||||
|       app: nginx | ||||
|     name: nginx | ||||
|     namespace: default | ||||
|     resourceVersion: "1672574" | ||||
|     selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx | ||||
|     uid: 6131547f-e908-11e8-9ff6-42010a8a00d1 | ||||
|   spec: | ||||
|     progressDeadlineSeconds: 600 | ||||
|     replicas: 1 | ||||
|     revisionHistoryLimit: 10 | ||||
|     selector: | ||||
|       matchLabels: | ||||
|         app: nginx | ||||
|     strategy: | ||||
|       rollingUpdate: | ||||
|         maxSurge: 25% | ||||
|         maxUnavailable: 25% | ||||
|       type: RollingUpdate | ||||
|     template: | ||||
|       metadata: | ||||
|         creationTimestamp: null | ||||
|         labels: | ||||
|           app: nginx | ||||
|       spec: | ||||
|         containers: | ||||
|         - image: nginx | ||||
|           imagePullPolicy: Always | ||||
|           name: nginx | ||||
|           resources: {} | ||||
|           terminationMessagePath: /dev/termination-log | ||||
|           terminationMessagePolicy: File | ||||
|         dnsPolicy: ClusterFirst | ||||
|         restartPolicy: Always | ||||
|         schedulerName: default-scheduler | ||||
|         securityContext: {} | ||||
|         terminationGracePeriodSeconds: 30 | ||||
|   status: | ||||
|     availableReplicas: 1 | ||||
|     conditions: | ||||
|     - lastTransitionTime: 2018-11-15T18:58:10Z | ||||
|       lastUpdateTime: 2018-11-15T18:58:10Z | ||||
|       message: Deployment has minimum availability. | ||||
|       reason: MinimumReplicasAvailable | ||||
|       status: "True" | ||||
|       type: Available | ||||
|     - lastTransitionTime: 2018-11-15T18:58:03Z | ||||
|       lastUpdateTime: 2018-11-15T18:58:10Z | ||||
|       message: ReplicaSet "nginx-78f5d695bd" has successfully progressed. | ||||
|       reason: NewReplicaSetAvailable | ||||
|       status: "True" | ||||
|       type: Progressing | ||||
|     observedGeneration: 1 | ||||
|     readyReplicas: 1 | ||||
|     replicas: 1 | ||||
|     updatedReplicas: 1 | ||||
| kind: List | ||||
| metadata: | ||||
|   resourceVersion: "" | ||||
|   selfLink: "" | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| ### Json | ||||
| 
 | ||||
| Print the Raw Resource formatting it as Json. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployments -o json | ||||
| ``` | ||||
| 
 | ||||
| ```json | ||||
| { | ||||
|     "apiVersion": "v1", | ||||
|     "items": [ | ||||
|         { | ||||
|             "apiVersion": "extensions/v1beta1", | ||||
|             "kind": "Deployment", | ||||
|             "metadata": { | ||||
|                 "annotations": { | ||||
|                     "deployment.kubernetes.io/revision": "1" | ||||
|                 }, | ||||
|                 "creationTimestamp": "2018-11-15T18:58:03Z", | ||||
|                 "generation": 1, | ||||
|                 "labels": { | ||||
|                     "app": "nginx" | ||||
|                 }, | ||||
|                 "name": "nginx", | ||||
|                 "namespace": "default", | ||||
|                 "resourceVersion": "1672574", | ||||
|                 "selfLink": "/apis/extensions/v1beta1/namespaces/default/deployments/nginx", | ||||
|                 "uid": "6131547f-e908-11e8-9ff6-42010a8a00d1" | ||||
|             }, | ||||
|             "spec": { | ||||
|                 "progressDeadlineSeconds": 600, | ||||
|                 "replicas": 1, | ||||
|                 "revisionHistoryLimit": 10, | ||||
|                 "selector": { | ||||
|                     "matchLabels": { | ||||
|                         "app": "nginx" | ||||
|                     } | ||||
|                 }, | ||||
|                 "strategy": { | ||||
|                     "rollingUpdate": { | ||||
|                         "maxSurge": "25%", | ||||
|                         "maxUnavailable": "25%" | ||||
|                     }, | ||||
|                     "type": "RollingUpdate" | ||||
|                 }, | ||||
|                 "template": { | ||||
|                     "metadata": { | ||||
|                         "creationTimestamp": null, | ||||
|                         "labels": { | ||||
|                             "app": "nginx" | ||||
|                         } | ||||
|                     }, | ||||
|                     "spec": { | ||||
|                         "containers": [ | ||||
|                             { | ||||
|                                 "image": "nginx", | ||||
|                                 "imagePullPolicy": "Always", | ||||
|                                 "name": "nginx", | ||||
|                                 "resources": {}, | ||||
|                                 "terminationMessagePath": "/dev/termination-log", | ||||
|                                 "terminationMessagePolicy": "File" | ||||
|                             } | ||||
|                         ], | ||||
|                         "dnsPolicy": "ClusterFirst", | ||||
|                         "restartPolicy": "Always", | ||||
|                         "schedulerName": "default-scheduler", | ||||
|                         "securityContext": {}, | ||||
|                         "terminationGracePeriodSeconds": 30 | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             "status": { | ||||
|                 "availableReplicas": 1, | ||||
|                 "conditions": [ | ||||
|                     { | ||||
|                         "lastTransitionTime": "2018-11-15T18:58:10Z", | ||||
|                         "lastUpdateTime": "2018-11-15T18:58:10Z", | ||||
|                         "message": "Deployment has minimum availability.", | ||||
|                         "reason": "MinimumReplicasAvailable", | ||||
|                         "status": "True", | ||||
|                         "type": "Available" | ||||
|                     }, | ||||
|                     { | ||||
|                         "lastTransitionTime": "2018-11-15T18:58:03Z", | ||||
|                         "lastUpdateTime": "2018-11-15T18:58:10Z", | ||||
|                         "message": "ReplicaSet \"nginx-78f5d695bd\" has successfully progressed.", | ||||
|                         "reason": "NewReplicaSetAvailable", | ||||
|                         "status": "True", | ||||
|                         "type": "Progressing" | ||||
|                     } | ||||
|                 ], | ||||
|                 "observedGeneration": 1, | ||||
|                 "readyReplicas": 1, | ||||
|                 "replicas": 1, | ||||
|                 "updatedReplicas": 1 | ||||
|             } | ||||
|         } | ||||
|     ], | ||||
|     "kind": "List", | ||||
|     "metadata": { | ||||
|         "resourceVersion": "", | ||||
|         "selfLink": "" | ||||
|     } | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,146 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Get a Summary of Resources Running in the Cluster | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Summarizing Resources | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Quickly summarizing a collection of Resources and their state. | ||||
| 
 | ||||
| Summarizing Resource State using a columnar format is the most common way to view cluster | ||||
| state when developing applications or triaging issues.  The **columnar view gives a compact | ||||
| summary of the most relevant information** for a collection of Resources. | ||||
| 
 | ||||
| ## Get | ||||
| 
 | ||||
| The `kubectl get` reads Resources from the cluster and formats them as output.  The examples in | ||||
| this chapter will query for Resources by providing Get the *Resource Type* as an argument. | ||||
| For more query options see [Queries and Options](queries_and_options.md). | ||||
| 
 | ||||
| {% method %} | ||||
| ### Default | ||||
| 
 | ||||
| If no output format is specified, Get will print a default set of columns. | ||||
| 
 | ||||
| **Note:** Some columns *may* not directly map to fields on the Resource, but instead may | ||||
| be a summary of fields. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployments nginx | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE | ||||
| nginx     1         1         1            0           5s | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ### Wide | ||||
| 
 | ||||
| Print the default columns plus some additional columns. | ||||
| 
 | ||||
| **Note:** Some columns *may* not directly map to fields on the Resource, but instead may | ||||
| be a summary of fields. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get -o=wide deployments nginx | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINERS   IMAGES    SELECTOR | ||||
| nginx     1         1         1            1           26s       nginx        nginx     app=nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ### Custom Columns | ||||
| 
 | ||||
| Print out specific fields as Columns. | ||||
| 
 | ||||
| **Note:** Custom Columns can also be read from a file using `-o custom-columns-file`. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployments -o custom-columns="Name:metadata.name,Replicas:spec.replicas,Strategy:spec.strategy.type" | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| Name      Replicas   Strategy | ||||
| nginx     1          RollingUpdate | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| #### Labels | ||||
| 
 | ||||
| Print out specific labels each as their own columns | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl get deployments -L=app | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       APP | ||||
| nginx     1         1         1            1           8m        nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ### Show Labels | ||||
| 
 | ||||
| Print out all labels on each Resource in a single column (last). | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployment --show-labels | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       LABELS | ||||
| nginx     1         1         1            1           7m        app=nginx | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| {% method %} | ||||
| ### Show Kind | ||||
| 
 | ||||
| Print out the Group.Kind as part of the Name column. | ||||
| 
 | ||||
| **Note:** This can be useful if the user did not specify the group in the command and | ||||
| they want to know which API is being used. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| $ kubectl get deployments --show-kind | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| NAME                          DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE | ||||
| deployment.extensions/nginx   1         1         1            1           8m | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
|  | @ -0,0 +1,47 @@ | |||
| {% panel style="info", title="TL;DR" %} | ||||
| - Continuously Watch and print Resources as they change | ||||
| {% endpanel %} | ||||
| 
 | ||||
| # Watching Resources for changes | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Print Resources as they are updated. | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| It is possible to have `kubectl get` **continuously watch for changes to objects**, and print the objects | ||||
| when they are changed or when the watch is reestablished. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl get deployments --watch | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE | ||||
| nginx     1         1         1            1           6h | ||||
| nginx2    1         1         1            1           21m | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
| {% panel style="danger", title="Watch Timeouts" %} | ||||
| Watch **timesout after 5 minutes**, after which kubectl will re-establish the watch and print the | ||||
| resources. | ||||
| {% endpanel %} | ||||
| 
 | ||||
| {% method %} | ||||
| 
 | ||||
| It is possible to have `kubectl get` continuously watch for changes to objects **without fetching them first** | ||||
| using the `--watch-only` flag. | ||||
| 
 | ||||
| {% sample lang="yaml" %} | ||||
| 
 | ||||
| ```bash | ||||
| kubectl get deployments --watch-only | ||||
| ``` | ||||
| 
 | ||||
| {% endmethod %} | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue