Kubectl Book updates for 1.14

This commit is contained in:
Phillip Wittrock 2019-03-12 09:13:07 -07:00
parent 2a31209eeb
commit b9f105d4aa
57 changed files with 10205 additions and 1617 deletions

View File

@ -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.

View File

@ -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/)

View File

@ -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

5407
docs/book/npm-shrinkwrap.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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:

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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

View File

@ -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.

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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.

View 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 %}

View File

@ -1,7 +0,0 @@
# Rolling out Across Clusters
## Targeting a Cluster
## Sequentially Rolling Out
## Concurrently Rolling Out

View File

@ -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

View File

@ -1,7 +0,0 @@
# Builds
## Building Containers from Source
- Multi-Stage Builds
## Triggering Builds

View File

@ -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.

View File

@ -1,7 +0,0 @@
# Linting Resource Config
## Configuring the Linter
## Error Types
## Ignoring Linter Errors

View File

@ -1,8 +0,0 @@
# Rolling Back Changes
## Types of Errors
## Notification of an Error
## How to Rollback

View File

@ -1,5 +0,0 @@
# Rollouts
## Triggering a Rollout
## Sequentially Rolling out Components

View File

@ -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

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 havent 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 %}

View File

@ -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 %}

View File

@ -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

View File

@ -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.

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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.

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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:**

View File

@ -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`.

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}