diff --git a/k8s/insecure-dashboard.yaml b/k8s/insecure-dashboard.yaml index ebf49362..373ec001 100644 --- a/k8s/insecure-dashboard.yaml +++ b/k8s/insecure-dashboard.yaml @@ -1,3 +1,10 @@ +# This file is based on the following manifest: +# https://github.com/kubernetes/dashboard/blob/master/aio/deploy/recommended.yaml +# It adds the "skip login" flag, as well as an insecure hack to defeat SSL. +# As its name implies, it is INSECURE and you should not use it in production, +# or on clusters that contain any kind of important or sensitive data, or on +# clusters that have a life span of more than a few hours. + # Copyright 2017 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -187,7 +194,7 @@ spec: spec: containers: - name: kubernetes-dashboard - image: kubernetesui/dashboard:v2.0.0-rc2 + image: kubernetesui/dashboard:v2.0.0 imagePullPolicy: Always ports: - containerPort: 8443 @@ -226,7 +233,7 @@ spec: emptyDir: {} serviceAccountName: kubernetes-dashboard nodeSelector: - "beta.kubernetes.io/os": linux + "kubernetes.io/os": linux # Comment the following tolerations if Dashboard must not be deployed on master tolerations: - key: node-role.kubernetes.io/master @@ -272,7 +279,7 @@ spec: spec: containers: - name: dashboard-metrics-scraper - image: kubernetesui/metrics-scraper:v1.0.2 + image: kubernetesui/metrics-scraper:v1.0.4 ports: - containerPort: 8000 protocol: TCP @@ -293,7 +300,7 @@ spec: runAsGroup: 2001 serviceAccountName: kubernetes-dashboard nodeSelector: - "beta.kubernetes.io/os": linux + "kubernetes.io/os": linux # Comment the following tolerations if Dashboard must not be deployed on master tolerations: - key: node-role.kubernetes.io/master diff --git a/k8s/kubernetes-dashboard.yaml b/k8s/kubernetes-dashboard.yaml index ee6977bf..b2e5802b 100644 --- a/k8s/kubernetes-dashboard.yaml +++ b/k8s/kubernetes-dashboard.yaml @@ -1,3 +1,6 @@ +# This is a copy of the following file: +# https://github.com/kubernetes/dashboard/blob/master/aio/deploy/recommended.yaml + # Copyright 2017 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,19 +15,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -# ------------------- Dashboard Secret ------------------- # - apiVersion: v1 -kind: Secret +kind: Namespace metadata: - labels: - k8s-app: kubernetes-dashboard - name: kubernetes-dashboard-certs - namespace: kube-system -type: Opaque + name: kubernetes-dashboard --- -# ------------------- Dashboard Service Account ------------------- # apiVersion: v1 kind: ServiceAccount @@ -32,62 +28,147 @@ metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard - namespace: kube-system + namespace: kubernetes-dashboard + +--- + +kind: Service +apiVersion: v1 +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard + namespace: kubernetes-dashboard +spec: + ports: + - port: 443 + targetPort: 8443 + selector: + k8s-app: kubernetes-dashboard + +--- + +apiVersion: v1 +kind: Secret +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard-certs + namespace: kubernetes-dashboard +type: Opaque + +--- + +apiVersion: v1 +kind: Secret +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard-csrf + namespace: kubernetes-dashboard +type: Opaque +data: + csrf: "" + +--- + +apiVersion: v1 +kind: Secret +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard-key-holder + namespace: kubernetes-dashboard +type: Opaque + +--- + +kind: ConfigMap +apiVersion: v1 +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard-settings + namespace: kubernetes-dashboard --- -# ------------------- Dashboard Role & Role Binding ------------------- # kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: kubernetes-dashboard-minimal - namespace: kube-system + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard + namespace: kubernetes-dashboard rules: - # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret. -- apiGroups: [""] - resources: ["secrets"] - verbs: ["create"] - # Allow Dashboard to create 'kubernetes-dashboard-settings' config map. -- apiGroups: [""] - resources: ["configmaps"] - verbs: ["create"] # Allow Dashboard to get, update and delete Dashboard exclusive secrets. -- apiGroups: [""] - resources: ["secrets"] - resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"] - verbs: ["get", "update", "delete"] - # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map. -- apiGroups: [""] - resources: ["configmaps"] - resourceNames: ["kubernetes-dashboard-settings"] - verbs: ["get", "update"] - # Allow Dashboard to get metrics from heapster. -- apiGroups: [""] - resources: ["services"] - resourceNames: ["heapster"] - verbs: ["proxy"] -- apiGroups: [""] - resources: ["services/proxy"] - resourceNames: ["heapster", "http:heapster:", "https:heapster:"] - verbs: ["get"] + - apiGroups: [""] + resources: ["secrets"] + resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"] + verbs: ["get", "update", "delete"] + # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map. + - apiGroups: [""] + resources: ["configmaps"] + resourceNames: ["kubernetes-dashboard-settings"] + verbs: ["get", "update"] + # Allow Dashboard to get metrics. + - apiGroups: [""] + resources: ["services"] + resourceNames: ["heapster", "dashboard-metrics-scraper"] + verbs: ["proxy"] + - apiGroups: [""] + resources: ["services/proxy"] + resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"] + verbs: ["get"] --- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard +rules: + # Allow Metrics Scraper to get metrics from the Metrics server + - apiGroups: ["metrics.k8s.io"] + resources: ["pods", "nodes"] + verbs: ["get", "list", "watch"] + +--- + apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: kubernetes-dashboard-minimal - namespace: kube-system + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard + namespace: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: kubernetes-dashboard-minimal -subjects: -- kind: ServiceAccount name: kubernetes-dashboard - namespace: kube-system +subjects: + - kind: ServiceAccount + name: kubernetes-dashboard + namespace: kubernetes-dashboard + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kubernetes-dashboard +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kubernetes-dashboard +subjects: + - kind: ServiceAccount + name: kubernetes-dashboard + namespace: kubernetes-dashboard --- -# ------------------- Dashboard Deployment ------------------- # kind: Deployment apiVersion: apps/v1 @@ -95,7 +176,7 @@ metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard - namespace: kube-system + namespace: kubernetes-dashboard spec: replicas: 1 revisionHistoryLimit: 10 @@ -108,55 +189,117 @@ spec: k8s-app: kubernetes-dashboard spec: containers: - - name: kubernetes-dashboard - image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1 - ports: - - containerPort: 8443 - protocol: TCP - args: - - --auto-generate-certificates - # Uncomment the following line to manually specify Kubernetes API server Host - # If not specified, Dashboard will attempt to auto discover the API server and connect - # to it. Uncomment only if the default does not work. - # - --apiserver-host=http://my-address:port - volumeMounts: - - name: kubernetes-dashboard-certs - mountPath: /certs - # Create on-disk volume to store exec logs - - mountPath: /tmp - name: tmp-volume - livenessProbe: - httpGet: - scheme: HTTPS - path: / - port: 8443 - initialDelaySeconds: 30 - timeoutSeconds: 30 + - name: kubernetes-dashboard + image: kubernetesui/dashboard:v2.0.0 + imagePullPolicy: Always + ports: + - containerPort: 8443 + protocol: TCP + args: + - --auto-generate-certificates + - --namespace=kubernetes-dashboard + # Uncomment the following line to manually specify Kubernetes API server Host + # If not specified, Dashboard will attempt to auto discover the API server and connect + # to it. Uncomment only if the default does not work. + # - --apiserver-host=http://my-address:port + volumeMounts: + - name: kubernetes-dashboard-certs + mountPath: /certs + # Create on-disk volume to store exec logs + - mountPath: /tmp + name: tmp-volume + livenessProbe: + httpGet: + scheme: HTTPS + path: / + port: 8443 + initialDelaySeconds: 30 + timeoutSeconds: 30 + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsUser: 1001 + runAsGroup: 2001 volumes: - - name: kubernetes-dashboard-certs - secret: - secretName: kubernetes-dashboard-certs - - name: tmp-volume - emptyDir: {} + - name: kubernetes-dashboard-certs + secret: + secretName: kubernetes-dashboard-certs + - name: tmp-volume + emptyDir: {} serviceAccountName: kubernetes-dashboard + nodeSelector: + "kubernetes.io/os": linux # Comment the following tolerations if Dashboard must not be deployed on master tolerations: - - key: node-role.kubernetes.io/master - effect: NoSchedule + - key: node-role.kubernetes.io/master + effect: NoSchedule --- -# ------------------- Dashboard Service ------------------- # kind: Service apiVersion: v1 metadata: labels: - k8s-app: kubernetes-dashboard - name: kubernetes-dashboard - namespace: kube-system + k8s-app: dashboard-metrics-scraper + name: dashboard-metrics-scraper + namespace: kubernetes-dashboard spec: ports: - - port: 443 - targetPort: 8443 + - port: 8000 + targetPort: 8000 selector: - k8s-app: kubernetes-dashboard + k8s-app: dashboard-metrics-scraper + +--- + +kind: Deployment +apiVersion: apps/v1 +metadata: + labels: + k8s-app: dashboard-metrics-scraper + name: dashboard-metrics-scraper + namespace: kubernetes-dashboard +spec: + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + k8s-app: dashboard-metrics-scraper + template: + metadata: + labels: + k8s-app: dashboard-metrics-scraper + annotations: + seccomp.security.alpha.kubernetes.io/pod: 'runtime/default' + spec: + containers: + - name: dashboard-metrics-scraper + image: kubernetesui/metrics-scraper:v1.0.4 + ports: + - containerPort: 8000 + protocol: TCP + livenessProbe: + httpGet: + scheme: HTTP + path: / + port: 8000 + initialDelaySeconds: 30 + timeoutSeconds: 30 + volumeMounts: + - mountPath: /tmp + name: tmp-volume + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsUser: 1001 + runAsGroup: 2001 + serviceAccountName: kubernetes-dashboard + nodeSelector: + "kubernetes.io/os": linux + # Comment the following tolerations if Dashboard must not be deployed on master + tolerations: + - key: node-role.kubernetes.io/master + effect: NoSchedule + volumes: + - name: tmp-volume + emptyDir: {} diff --git a/k8s/nginx-4-with-init.yaml b/k8s/nginx-4-with-init.yaml index d41ecd7a..c3023070 100644 --- a/k8s/nginx-4-with-init.yaml +++ b/k8s/nginx-4-with-init.yaml @@ -14,7 +14,7 @@ spec: initContainers: - name: git image: alpine - command: [ "sh", "-c", "apk add --no-cache git && git clone https://github.com/octocat/Spoon-Knife /www" ] + command: [ "sh", "-c", "apk add git && sleep 5 && git clone https://github.com/octocat/Spoon-Knife /www" ] volumeMounts: - name: www mountPath: /www/ diff --git a/k8s/psp-restricted.yaml b/k8s/psp-restricted.yaml index a73e7049..962685d0 100644 --- a/k8s/psp-restricted.yaml +++ b/k8s/psp-restricted.yaml @@ -1,5 +1,5 @@ --- -apiVersion: extensions/v1beta1 +apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: annotations: diff --git a/k8s/users:jean.doe.yaml b/k8s/user=jean.doe.yaml similarity index 85% rename from k8s/users:jean.doe.yaml rename to k8s/user=jean.doe.yaml index ef96d39e..4789038d 100644 --- a/k8s/users:jean.doe.yaml +++ b/k8s/user=jean.doe.yaml @@ -8,24 +8,24 @@ metadata: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: users:jean.doe + name: user=jean.doe rules: - apiGroups: [ certificates.k8s.io ] resources: [ certificatesigningrequests ] verbs: [ create ] - apiGroups: [ certificates.k8s.io ] - resourceNames: [ users:jean.doe ] + resourceNames: [ user=jean.doe ] resources: [ certificatesigningrequests ] verbs: [ get, create, delete, watch ] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: users:jean.doe + name: user=jean.doe roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: users:jean.doe + name: user=jean.doe subjects: - kind: ServiceAccount name: jean.doe diff --git a/prepare-vms/lib/commands.sh b/prepare-vms/lib/commands.sh index 5493f62f..e6934124 100644 --- a/prepare-vms/lib/commands.sh +++ b/prepare-vms/lib/commands.sh @@ -246,6 +246,14 @@ EOF" helm completion bash | sudo tee /etc/bash_completion.d/helm fi" + # Install kustomize + pssh " + if [ ! -x /usr/local/bin/kustomize ]; then + curl -L https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.5.4/kustomize_v3.5.1_linux_amd64.tar.gz | + sudo tar -C /usr/local/bin -zx kustomize + echo complete -C /usr/local/bin/kustomize kustomize | sudo tee /etc/bash_completion.d/kustomize + fi" + # Install ship pssh " if [ ! -x /usr/local/bin/ship ]; then diff --git a/slides/k8s/csr-api.md b/slides/k8s/csr-api.md index 47c83cac..fabf5c5f 100644 --- a/slides/k8s/csr-api.md +++ b/slides/k8s/csr-api.md @@ -132,11 +132,33 @@ For a user named `jean.doe`, we will have: - ServiceAccount `jean.doe` in Namespace `users` -- CertificateSigningRequest `users:jean.doe` +- CertificateSigningRequest `user=jean.doe` -- ClusterRole `users:jean.doe` giving read/write access to that CSR +- ClusterRole `user=jean.doe` giving read/write access to that CSR -- ClusterRoleBinding `users:jean.doe` binding ClusterRole and ServiceAccount +- ClusterRoleBinding `user=jean.doe` binding ClusterRole and ServiceAccount + +--- + +class: extra-details + +## About resource name constraints + +- Most Kubernetes identifiers and names are fairly restricted + +- They generally are DNS-1123 *labels* or *subdomains* (from [RFC 1123](https://tools.ietf.org/html/rfc1123)) + +- A label is lowercase letters, numbers, dashes; can't start or finish with a dash + +- A subdomain is one or multiple labels separated by dots + +- Some resources have more relaxed constraints, and can be "path segment names" + + (uppercase are allowed, as well as some characters like `#:?!,_`) + +- This includes RBAC objects (like Roles, RoleBindings...) and CSRs + +- See the [Identifiers and Names](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/identifiers.md) design document and the [Object Names and IDs](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#path-segment-names) documentation page for more details --- @@ -153,7 +175,7 @@ For a user named `jean.doe`, we will have: - Create the ServiceAccount, ClusterRole, ClusterRoleBinding for `jean.doe`: ```bash - kubectl apply -f ~/container.training/k8s/users:jean.doe.yaml + kubectl apply -f ~/container.training/k8s/user=jean.doe.yaml ``` ] @@ -195,7 +217,13 @@ For a user named `jean.doe`, we will have: - Add a new context using that identity: ```bash - kubectl config set-context jean.doe --user=token:jean.doe --cluster=kubernetes + kubectl config set-context jean.doe --user=token:jean.doe --cluster=`kubernetes` + ``` + (Make sure to adapt the cluster name if yours is different!) + +- Use that context: + ```bash + kubectl config use-context jean.doe ``` ] @@ -216,7 +244,7 @@ For a user named `jean.doe`, we will have: - Try to access "our" CertificateSigningRequest: ```bash - kubectl get csr users:jean.doe + kubectl get csr user=jean.doe ``` (This should tell us "NotFound") @@ -273,7 +301,7 @@ The command above generates: apiVersion: certificates.k8s.io/v1beta1 kind: CertificateSigningRequest metadata: - name: users:jean.doe + name: user=jean.doe spec: request: $(base64 -w0 < csr.pem) usages: @@ -324,12 +352,12 @@ The command above generates: - Inspect the CSR: ```bash - kubectl describe csr users:jean.doe + kubectl describe csr user=jean.doe ``` - Approve it: ```bash - kubectl certificate approve users:jean.doe + kubectl certificate approve user=jean.doe ``` ] @@ -347,7 +375,7 @@ The command above generates: - Retrieve the updated CSR object and extract the certificate: ```bash - kubectl get csr users:jean.doe \ + kubectl get csr user=jean.doe \ -o jsonpath={.status.certificate} \ | base64 -d > cert.pem ``` diff --git a/slides/k8s/helm-create-better-chart.md b/slides/k8s/helm-create-better-chart.md index a96d46dc..992f7fd2 100644 --- a/slides/k8s/helm-create-better-chart.md +++ b/slides/k8s/helm-create-better-chart.md @@ -121,7 +121,7 @@ This creates a basic chart in the directory `helmcoins`. helm install COMPONENT-NAME CHART-DIRECTORY ``` -- We can also use the following command, which is idempotent: +- We can also use the following command, which is *idempotent*: ```bash helm upgrade COMPONENT-NAME CHART-DIRECTORY --install ``` @@ -139,6 +139,28 @@ This creates a basic chart in the directory `helmcoins`. --- +class: extra-details + +## "Idempotent" + +- Idempotent = that can be applied multiple times without changing the result + + (the word is commonly used in maths and computer science) + +- In this context, this means: + + - if the action (installing the chart) wasn't done, do it + + - if the action was already done, don't do anything + +- Ideally, when such an action fails, it can be retried safely + + (as opposed to, e.g., installing a new release each time we run it) + +- Other example: `kubectl -f some-file.yaml` + +--- + ## Checking what we've done - Let's see if DockerCoins is working! diff --git a/slides/k8s/helm-intro.md b/slides/k8s/helm-intro.md index e98cd8a9..2db93989 100644 --- a/slides/k8s/helm-intro.md +++ b/slides/k8s/helm-intro.md @@ -18,6 +18,25 @@ --- +## CNCF graduation status + +- On April 30th 2020, Helm was the 10th project to *graduate* within the CNCF + + .emoji[🎉] + + (alongside Containerd, Prometheus, and Kubernetes itself) + +- This is an acknowledgement by the CNCF for projects that + + *demonstrate thriving adoption, an open governance process, +
+ and a strong commitment to community, sustainability, and inclusivity.* + +- See [CNCF announcement](https://www.cncf.io/announcement/2020/04/30/cloud-native-computing-foundation-announces-helm-graduation/) + and [Helm announcement](https://helm.sh/blog/celebrating-helms-cncf-graduation/) + +--- + ## Helm concepts - `helm` is a CLI tool diff --git a/slides/k8s/kustomize.md b/slides/k8s/kustomize.md index 84fa9d19..db3dd89d 100644 --- a/slides/k8s/kustomize.md +++ b/slides/k8s/kustomize.md @@ -8,45 +8,164 @@ - They are left untouched by Kustomize -- Kustomize lets us define *overlays* that extend or change the resource files +- Kustomize lets us define *kustomizations* + +- A *kustomization* is conceptually similar to a *layer* + +- Technically, a *kustomization* is a file named `kustomization.yaml` + + (or a directory containing that files + additional files) --- -## Differences with Helm +## What's in a kustomization -- Helm charts use placeholders `{{ like.this }}` +- A kustomization can do any combination of the following: -- Kustomize "bases" are standard Kubernetes YAML + - include other kustomizations -- It is possible to use an existing set of YAML as a Kustomize base + - include Kubernetes resources defined in YAML files -- As a result, writing a Helm chart is more work ... + - patch Kubernetes resources (change values) -- ... But Helm charts are also more powerful; e.g. they can: + - add labels or annotations to all resources - - use flags to conditionally include resources or blocks + - specify ConfigMaps and Secrets from literal values or local files - - check if a given Kubernetes API group is supported - - - [and much more](https://helm.sh/docs/chart_template_guide/) +(... And a few more advanced features that we won't cover today!) --- -## Kustomize concepts +## A simple kustomization -- Kustomize needs a `kustomization.yaml` file +This features a Deployment, Service, and Ingress (in separate files), +and a couple of patches (to change the number of replicas and the hostname +used in the Ingress). -- That file can be a *base* or a *variant* +```yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +patchesStrategicMerge: +- scale-deployment.yaml +- ingress-hostname.yaml +resources: +- deployment.yaml +- service.yaml +- ingress.yaml +``` -- If it's a *base*: +On the next slide, let's see a more complex example ... - - it lists YAML resource files to use +--- -- If it's a *variant* (or *overlay*): +```yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +commonLabels: + add-this-to-all-my-resources: please +patchesStrategicMerge: +- prod-scaling.yaml +- prod-healthchecks.yaml +bases: +- api/ +- frontend/ +- db/ +- github.com/example/app?ref=tag-or-branch +resources: +- ingress.yaml +- permissions.yaml +configMapGenerator: +- name: appconfig + files: + - global.conf + - local.conf=prod.conf +``` - - it refers to (at least) one *base* +--- - - and some *patches* +## Glossary + +- A *base* is a kustomization that is referred to by other kustomizations + +- An *overlay* is a kustomization that refers to other kustomizations + +- A kustomization can be both a base and an overlay at the same time + + (a kustomization can refer to another, which can refer to a third) + +- A *patch* describes how to alter an existing resource + + (e.g. to change the image in a Deployment; or scaling parameters; etc.) + +- A *variant* is the final outcome of applying bases + overlays + +(See the [kustomize glossary](https://github.com/kubernetes-sigs/kustomize/blob/master/docs/glossary.md) for more definitions!) + +--- + +## What Kustomize *cannot* do + +- By design, there are a number of things that Kustomize won't do + +- For instance: + + - using command-line arguments or environment variables to generate a variant + + - overlays can only *add* resources, not *remove* them + +- See the full list of [eschewed features](https://github.com/kubernetes-sigs/kustomize/blob/master/docs/eschewedFeatures.md) for more details + +--- + +## Kustomize workflows + +- The Kustomize documentation proposes two different workflows + +- *Bespoke configuration* + + - base and overlays managed by the same team + +- *Off-the-shelf configuration* (OTS) + + - base and overlays managed by different teams + + - base is regularly updated by "upstream" (e.g. a vendor) + + - our overlays and patches should (hopefully!) apply cleanly + + - we may regularly update the base, or use a remote base + +--- + +## Remote bases + +- Kustomize can fetch remote bases using Hashicorp go-getter library + +- Examples: + + github.com/jpetazzo/kubercoins (remote git repository) + + github.com/jpetazzo/kubercoins?ref=kustomize (specific tag or branch) + + https://releases.hello.io/k/1.0.zip (remote archive) + + https://releases.hello.io/k/1.0.zip//some-subdir (subdirectory in archive) + +- See [hashicorp/go-getter URL format docs](https://github.com/hashicorp/go-getter#url-format) for more examples + +--- + +## Managing `kustomization.yaml` + +- There are many ways to manage `kustomization.yaml` files, including: + + - web wizards like [Replicated Ship](https://www.replicated.com/ship/) + + - the `kustomize` CLI + + - opening the file with our favorite text editor + +- Let's see these in action! --- @@ -200,7 +319,62 @@ Note: it might take a minute or two for the worker to start. +--- + +## Working with the `kustomize` CLI + +- This is another way to get started + +- General workflow: + + `kustomize create` to generate an empty `kustomization.yaml` file + + `kustomize edit add resource` to add Kubernetes YAML files to it + + `kustomize edit add patch` to add patches to said resources + + `kustomize build | kubectl apply -f-` or `kubectl apply -k .` + +--- + +## `kubectl apply -k` + +- Kustomize has been integrated in `kubectl` + +- The `kustomize` tool is still needed if we want to use `create`, `edit`, ... + +- Also, warning: `kubectl apply -k` is a slightly older version than `kustomize`! + +- In recent versions of `kustomize`, bases can be listed in `resources` + + (and `kustomize edit add base` will add its arguments to `resources`) + +- `kubectl apply -k` requires bases to be listed in `bases` + + (so after using `kustomize edit add base`, we need to fix `kustomization.yaml`) + +--- + +## Differences with Helm + +- Helm charts use placeholders `{{ like.this }}` + +- Kustomize "bases" are standard Kubernetes YAML + +- It is possible to use an existing set of YAML as a Kustomize base + +- As a result, writing a Helm chart is more work ... + +- ... But Helm charts are also more powerful; e.g. they can: + + - use flags to conditionally include resources or blocks + + - check if a given Kubernetes API group is supported + + - [and much more](https://helm.sh/docs/chart_template_guide/) + ??? :EN:- Packaging and running apps with Kustomize :FR:- *Packaging* d'applications avec Kustomize + diff --git a/slides/k8s/labels-annotations.md b/slides/k8s/labels-annotations.md index 790841ba..a295c289 100644 --- a/slides/k8s/labels-annotations.md +++ b/slides/k8s/labels-annotations.md @@ -26,12 +26,12 @@ - Create a Deployment: ```bash - kubectl create deployment web --image=nginx + kubectl create deployment clock --image=jpetazzo/clock ``` - Look at its annotations and labels: ```bash - kubectl describe deployment web + kubectl describe deployment clock ``` ] diff --git a/slides/k8s/logs-cli.md b/slides/k8s/logs-cli.md index 288d929a..93485ab2 100644 --- a/slides/k8s/logs-cli.md +++ b/slides/k8s/logs-cli.md @@ -45,7 +45,7 @@ Exactly what we need! --- -## Installing Stern +## Checking if Stern is installed - Run `stern` (without arguments) to check if it's installed: @@ -57,7 +57,17 @@ Exactly what we need! stern pod-query [flags] ``` -- If it is not installed, the easiest method is to download a [binary release](https://github.com/wercker/stern/releases) +- If it's missing, let's see how to install it + +--- + +## Installing Stern + +- Stern is written in Go, and Go programs are usually shipped as a single binary + +- We just need to download that binary and put it in our `PATH`! + +- Binary releases are available [here](https://github.com/wercker/stern/releases) on GitHub - The following commands will install Stern on a Linux Intel 64 bit machine: ```bash @@ -66,7 +76,7 @@ Exactly what we need! sudo chmod +x /usr/local/bin/stern ``` -- On OS X, just `brew install stern` +- On macOS, we can also `brew install stern` or `port install stern` diff --git a/slides/k8s/podsecuritypolicy.md b/slides/k8s/podsecuritypolicy.md index 8e0e9a0c..6542362a 100644 --- a/slides/k8s/podsecuritypolicy.md +++ b/slides/k8s/podsecuritypolicy.md @@ -287,7 +287,7 @@ - Try to create a Deployment: ```bash - kubectl run testpsp2 --image=nginx + kubectl create deployment testpsp2 --image=nginx ``` - Look at existing resources: @@ -350,7 +350,7 @@ We can get hints at what's happening by looking at the ReplicaSet and Events. - Create a Deployment as well: ```bash - kubectl run testpsp4 --image=nginx + kubectl create deployment testpsp4 --image=nginx ``` - Confirm that the Deployment is *not* creating any Pods: diff --git a/slides/k8s/volumes.md b/slides/k8s/volumes.md index 2870877b..8e408c2f 100644 --- a/slides/k8s/volumes.md +++ b/slides/k8s/volumes.md @@ -404,7 +404,7 @@ spec: initContainers: - name: git image: alpine - command: [ "sh", "-c", "apk add --no-cache git && git clone https://github.com/octocat/Spoon-Knife /www" ] + command: [ "sh", "-c", "apk add git && git clone https://github.com/octocat/Spoon-Knife /www" ] volumeMounts: - name: www mountPath: /www/ @@ -417,9 +417,12 @@ spec: .exercise[ -- Repeat the same operation as earlier +- Create the pod: + ```bash + kubectl create -f ~/container.training/k8s/nginx-4-with-init.yaml + ``` - (try to send HTTP requests as soon as the pod comes up) +- Try to send HTTP requests as soon as the pod comes up