Compare commits

..

87 Commits

Author SHA1 Message Date
Jérôme Petazzoni
af86f361aa 💥 HighFive 2022Q1 content update 2022-03-21 08:22:11 +01:00
Jérôme Petazzoni
025b281a2d ♻️ Switch diagram around 2022-03-21 08:21:52 +01:00
Jérôme Petazzoni
a830d51e5e Add a couple more Kyverno policies with fancy preconditions 2022-03-16 19:14:45 +01:00
Cyril Mizzi
7af1a4cfbc fix(slides.k8s.hpa-v2): update prometheus-adapter mapping rule 2022-03-16 17:50:57 +01:00
Cyril Mizzi
4f6b4b0306 fix(slides.k8s.hpa-v2): update namespace for prometheus-adapter 2022-03-16 17:50:57 +01:00
Jérôme Petazzoni
888aad583e ♻️ Update YAML manifests for dashboard
Include namespace (to work around 'helm template' bug).
Enable metrics scraper (because metrics are fun).
2022-03-08 18:14:42 +01:00
Jérôme Petazzoni
f7c1e87a89 🐛 Add missing content-type header in livedns API call 2022-03-08 16:42:58 +01:00
Jérôme Petazzoni
2e4e6bc787 Merge pull request #608 from nchauvat/patch-1
fix typo in definition of access modes
2022-02-10 16:14:39 +01:00
nchauvat
1b704316c8 fix typo in definition of access modes
IIRC https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes it is the PVClaim that lists the access modes it requires and the PV that lists the access modes it supports.
2022-02-10 12:12:36 +01:00
Jérôme Petazzoni
2e6e5425d0 Add platform check Dockerfile 2022-02-04 08:30:54 +01:00
Jérôme Petazzoni
5e2aac701e ♻️ Add cgroup v2 content 2022-02-03 18:58:21 +01:00
Jérôme Petazzoni
bb19d525e9 Merge Buildkit content 2022-02-03 17:57:35 +01:00
Jérôme Petazzoni
8ca6c5ba40 🏭️ Support multiple Terraform configurations
Historically, we only support one Terraform configuration,
through the "openstack-tf" infraclass. With these changes,
we support multiple Terraform configurations, including
(at this point) "openstack" and "oci" (Oracle Cloud).

Existing infra files that use INFRACLASS=openstack-tf
should be changed as follows:

INFRACLASS=terraform
TERRAFORM=openstack
2022-02-03 07:59:56 +01:00
Jérôme Petazzoni
e1290c5b84 Add some info about profiles and .env 2022-01-31 19:48:12 +01:00
Jérôme Petazzoni
2c2574fece ♻️ Improve PriorityClass slides 2022-01-27 13:14:26 +01:00
Jérôme Petazzoni
5c96b40bbd 🐞 Fix kustomize completion 2022-01-27 13:14:16 +01:00
Jérôme Petazzoni
5aa20362eb ♻️ Update healthcheck content 2022-01-27 11:23:43 +01:00
Jérôme Petazzoni
a01fecf679 ♻️ Bump Consul version and move SA at the beginning of the YAML
It's a tiny bit easier to run through the YAML when it starts with
the ServiceAccount, I find.
2022-01-27 10:40:37 +01:00
Jérôme Petazzoni
b75d6562b5 🏭️ Rewrite kubectl-run chapter 2022-01-27 10:36:52 +01:00
Jérôme Petazzoni
7f5944b157 📍 Correctly pin+hold package versions with APT preferences 2022-01-27 08:59:12 +01:00
Jérôme Petazzoni
21287d16bf ♻️ Switch to containerd 2022-01-26 21:05:01 +01:00
Jérôme Petazzoni
9434b40b58 🐞 Fix a couple of search-and-replace mistakes 2022-01-23 10:39:54 +01:00
Jérôme Petazzoni
b59f5dd00d Merge pull request #606 from sebgl/fix-pvc-link
Update link to the PersistentVolumeClaimBinder design doc
2022-01-23 09:08:11 +01:00
sebgl
d8ad0021cc Update link to the PersistentVolumeClaimBinder design doc
It looks like that doc has been moved elsewhere. This commit updates the link to (what I think is) the intended page.
2022-01-21 10:34:35 +01:00
Jérôme Petazzoni
8dbd6d54a0 🐞 Add warning about initial_node_count 2022-01-20 11:49:28 +01:00
Jérôme Petazzoni
b454749e92 🐞 Add info about Terraform provider version pinning 2022-01-20 09:29:11 +01:00
Jérôme Petazzoni
9a71d0e260 📃 Add gcloud auth application-default login 2022-01-19 11:24:00 +01:00
Jérôme Petazzoni
25e844fdf4 Bump up version numbers in upgrade labs 2022-01-18 12:16:46 +01:00
Jérôme Petazzoni
c40f4f5f2a 📝 Update ingress chapter
Replace cheese images with jpetazz/color.
Add details on GKE Ingress and clarify cost for cloud ingress.
Mention that Traefik canary v1 is obsolete.
2022-01-18 12:09:33 +01:00
Jérôme Petazzoni
cfa89b3ab5 📃 Update AJ's affiliation 2022-01-17 19:18:09 +01:00
Jérôme Petazzoni
a10cf8d9c3 Add GKE networking; kubernetes resource creation in TF 2022-01-17 18:18:49 +01:00
Jérôme Petazzoni
749e5da20b Add command to remove a DNS record 2022-01-17 11:08:11 +01:00
Jérôme Petazzoni
69c7ac2371 Add Terraform workshop with GKE and node pools 2022-01-17 00:00:49 +01:00
Jérôme Petazzoni
de0ad83686 Add quick intro to demo apps 2022-01-16 16:01:58 +01:00
Jérôme Petazzoni
f630f08713 🔧 Uniformize labels in rainbow demo app 2022-01-16 16:01:03 +01:00
Jérôme Petazzoni
920a075afe 🔧 Pin old cluster to an even older version 2022-01-15 18:36:16 +01:00
Jérôme Petazzoni
a47c51618b 🔧 Improve GKE config to spread across multiple locations
GCP quotas are fairly limited (on my account, I can only
use 8 public IP addresses per zone, which means that I cannot
deploy many public clusters in a single zone). I tried to
use private clusters, but that causes other problems.
This refactoring makes it possible to spread clusters
across multiple zones. Since I have access to 20+ zones
in Europe and 20+ zones in the US, this lets me create a
lot of public clusters and simplifies the module quite a bit.
2022-01-14 12:30:55 +01:00
Jérôme Petazzoni
f3156513b8 🏭️ Add wrapper script for 'prepare-tf'
This should make it easy to start a bunch of clusters
(using the new Terraform provisioning method) on various
providers.
2022-01-11 10:11:42 +01:00
Jérôme Petazzoni
96de30ca78 🐞 Minor typo fix in help line 2022-01-10 21:05:34 +01:00
Jérôme Petazzoni
8de9e6e868 🏭️ Refactor prepare-tf
- fix tags so that they don't contain '='
- install metrics-server only if necessary
- set a maximum size to GKE node pool
- change tags to be shorter
2022-01-09 20:51:58 +01:00
Jérôme Petazzoni
7eb90b9d6f Merge pull request #555 from barpilot/gitops
update gitops slides
2022-01-09 17:31:22 +01:00
Jérôme Petazzoni
931455ba31 📃 Add GCP to doc and tweak them a bit 2022-01-07 15:40:56 +01:00
Jérôme Petazzoni
f02cef0351 Add content about externalTrafficPolicy
Describe impact of extra hops when using an ingress controller.
Also discuss how to preserve the HTTP client IP address.
2022-01-06 20:44:36 +01:00
Jérôme Petazzoni
9054fd58ea 🙏🏻 Add acknowledgements+thanks to @soulshake 2022-01-06 13:32:04 +01:00
Jérôme Petazzoni
24aa1ae9f7 More tweaks on the cluster autoscaler content 2022-01-06 12:52:28 +01:00
Jérôme Petazzoni
c1c4e48457 Tweaks on the cluster autoscaler content 2022-01-06 12:05:12 +01:00
Jérôme Petazzoni
0614087b2f Update CSR API to v1 in Terraform deployment configs 2022-01-06 11:54:43 +01:00
Jérôme Petazzoni
3745d0e12a Add cluster autoscaler section 2022-01-06 11:49:36 +01:00
Jérôme Petazzoni
90885e49cf Add Terraform configurations for GKE 2022-01-04 18:51:35 +01:00
Jérôme Petazzoni
07d02e345e 🛠️ Add script to find unmerged changes 2022-01-04 12:50:20 +01:00
Jérôme Petazzoni
f2311545cd 🔙 Backport EKS section from flatiron training 2022-01-04 11:30:46 +01:00
Jérôme Petazzoni
e902962f3a 🩺 Update healthcheck exercise 2022-01-03 19:36:16 +01:00
Jérôme Petazzoni
ee7547999c ♻️ Update pssh install instructions 2022-01-03 18:06:11 +01:00
Jérôme Petazzoni
34fd6c0393 🔒️ Move slides links to HTTPS 2022-01-03 13:20:55 +01:00
Jérôme Petazzoni
e67fca695e 🛠️ Add 'list' function to Netlify helper script 2022-01-03 13:18:31 +01:00
Jérôme Petazzoni
b56e54eaec ♻️ s/exercise/lab/
Now that we have a good number of longer exercises, it makes
sense to rename the shorter demos/labs into 'labs' to avoid
confusion between the two.
2021-12-29 17:18:07 +01:00
Jérôme Petazzoni
2669eae49b Merge pull request #599 from soulshake/patch-1
Fix typo "an URL"
2021-12-15 16:21:51 +01:00
AJ Bowen
c26e51d69c Fix typo "an URL" 2021-12-15 05:44:09 -06:00
Jérôme Petazzoni
c9518631e5 🧹 Delete OCI compartments 2021-12-14 17:35:36 +01:00
Jérôme Petazzoni
164651c461 Add new Kyverno exercise 2021-12-14 16:39:06 +01:00
Jérôme Petazzoni
1d8062f1dc 📃 Improve README to show how to set token variables 2021-12-14 15:46:00 +01:00
Jérôme Petazzoni
98671ea756 🔑 Minor tweaks in netpol section 2021-12-10 16:27:50 +01:00
Jérôme Petazzoni
f0c0266c06 📦️ Add info to use kubectl-build in Tiltfile 2021-12-10 15:16:20 +01:00
Jérôme Petazzoni
1c48145cc4 Add ConfigMap exercise 2021-12-07 14:02:54 +01:00
Jérôme Petazzoni
eced9b46d6 🔑 Increase MaxAuthTries in SSH for folks with many keys 2021-12-07 12:08:44 +01:00
Jérôme Petazzoni
74947e8265 Add exercises with remote clusters 2021-12-06 15:16:38 +01:00
Jérôme Petazzoni
9f9016de0c 🧹 Delete Load Balancers etc. when deleting Kapsule clusters 2021-12-06 12:10:59 +01:00
Jérôme Petazzoni
cd9751a765 📍 Pin metrics-server version (0.5 seems broken on my clusters?) 2021-12-03 12:03:54 +01:00
Jérôme Petazzoni
e48448128d ♻️ Update Stern information 2021-12-03 12:03:26 +01:00
Jérôme Petazzoni
66b161d8ec 🔧 Tweak ingress exercise 2021-12-01 16:53:47 +01:00
Jérôme Petazzoni
031a2f7019 🔧 Tweak healthcheck exercise 2021-12-01 16:49:00 +01:00
Jérôme Petazzoni
6fb446b900 🔧 Improve explanations of the Dockercoins exercise 2021-11-30 10:47:37 +01:00
Jérôme Petazzoni
ba45fe932f 🐚 Add script to configure Netlify DNS 2021-11-29 12:25:14 +01:00
Jérôme Petazzoni
4adb75f0cb 🌈 Update HAProxy example to use literal blue/green deployment 2021-11-28 20:30:38 +01:00
Jérôme Petazzoni
c9507b4c83 📍 Pin Redis version 2021-11-28 13:12:33 +01:00
Jérôme Petazzoni
c9e7dd6dfa 🌉 Add ngrok tunnel in Tiltfile 2021-11-28 13:07:17 +01:00
Jérôme Petazzoni
bc761d512a Add commands to list verbs, resources, subresources 2021-11-28 11:36:44 +01:00
Jérôme Petazzoni
a368a3c21b ♻️ Update information about bootkube 2021-11-25 15:01:44 +01:00
Jérôme Petazzoni
607158bda3 🐞 Fix two small typos 2021-11-21 21:47:35 +01:00
Jérôme Petazzoni
52015b81fe 🏭️ Refactor stateful apps content 2021-11-20 22:00:50 +01:00
Jérôme Petazzoni
93d8a23c81 Add 'oldversion' cluster in admin course deployment script 2021-11-19 15:49:55 +01:00
Guilhem Lettron
3d724d87db gitops: update create branch method 2020-04-29 22:09:52 +02:00
Guilhem Lettron
8c04154430 gitops: update Flux log for identity.pub 2020-04-29 22:07:02 +02:00
Guilhem Lettron
66b7d118ba gitops: add Flux helm install method 2020-04-29 22:04:41 +02:00
Guilhem Lettron
a772fff88e gitops: flux use kustomize 2020-04-29 21:57:54 +02:00
Guilhem Lettron
57af933c2d gitops: add missing cd 2020-04-29 21:55:56 +02:00
Guilhem Lettron
4888ec1f5b gitops: add bash highlight 2020-04-29 21:54:27 +02:00
244 changed files with 8684 additions and 4325 deletions

View File

@@ -1,14 +1,67 @@
# (1) Setting up a registry, and telling Tilt to use it.
# Tilt needs a registry to store images.
# The following manifest defines a Deployment to run a basic Docker registry,
# and a NodePort Service to access it. Using a NodePort means that we don't
# need to obtain a TLS certificate, because we will be accessing the registry
# through localhost.
k8s_yaml('../k8s/tilt-registry.yaml')
# Tell Tilt to use the registry that we just deployed instead of whatever
# is defined in our Kubernetes resources. Tilt will patch image names to
# use our registry.
default_registry('localhost:30555')
# Create a port forward so that we can access the registry from our local
# environment, too. Note that if you run Tilt directly from a Kubernetes node
# (which is not typical, but might happen in some lab/training environments)
# the following might cause an error because port 30555 is already taken.
k8s_resource(workload='tilt-registry', port_forwards='30555:5000')
# (2) Telling Tilt how to build and run our app.
# The following two lines will use the kubectl-build plugin
# to leverage buildkit and build the images in our Kubernetes
# cluster. This is not enabled by default, because it requires
# the plugin to be installed.
# See https://github.com/vmware-tanzu/buildkit-cli-for-kubectl
# for more information about this plugin.
#load('ext://kubectl_build', 'kubectl_build')
#docker_build = kubectl_build
# Our Kubernetes manifests use images 'dockercoins/...' so we tell Tilt
# how each of these images should be built. The first argument is the name
# of the image, the second argument is the directory containing the build
# context (i.e. the Dockerfile to build the image).
docker_build('dockercoins/hasher', 'hasher')
docker_build('dockercoins/rng', 'rng')
docker_build('dockercoins/webui', 'webui')
docker_build('dockercoins/worker', 'worker')
# The following manifests defines five Deployments and four Services for
# our application.
k8s_yaml('../k8s/dockercoins.yaml')
# Uncomment the following line to let tilt run with the default kubeadm cluster-admin context.
#allow_k8s_contexts('kubernetes-admin@kubernetes')
# (3) Finishing touches.
# While we're here: if you're controlling a remote cluster, uncomment that line.
# It will create a port forward so that you can access the remote registry.
#k8s_resource(workload='registry', port_forwards='30555:5000')
# The following line lets Tilt run with the default kubeadm cluster-admin context.
allow_k8s_contexts('kubernetes-admin@kubernetes')
# This will run an ngrok tunnel to expose Tilt to the outside world.
# This is intended to be used when Tilt runs on a remote machine.
local_resource(name='ngrok:tunnel', serve_cmd='ngrok http 10350')
# This will wait until the ngrok tunnel is up, and show its URL to the user.
# We send the output to /dev/tty so that it doesn't get intercepted by
# Tilt, and gets displayed to the user's terminal instead.
# Note: this assumes that the ngrok instance will be running on port 4040.
# If you have other ngrok instances running on the machine, this might not work.
local_resource(name='ngrok:showurl', cmd='''
while sleep 1; do
TUNNELS=$(curl -fsSL http://localhost:4040/api/tunnels | jq -r .tunnels[].public_url)
[ "$TUNNELS" ] && break
done
printf "\nYou should be able to connect to the Tilt UI with the following URL(s): %s\n" "$TUNNELS" >/dev/tty
'''
)

View File

@@ -1,6 +1,6 @@
FROM node:4-slim
RUN npm install express
RUN npm install redis
RUN npm install redis@3
COPY files/ /files/
COPY webui.js /
CMD ["node", "webui.js"]

View File

@@ -3,6 +3,12 @@
# - no actual persistence
# - scaling down to 1 will break the cluster
# - pods may be colocated
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: consul
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
@@ -28,11 +34,6 @@ subjects:
name: consul
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: consul
---
apiVersion: v1
kind: Service
metadata:
name: consul
@@ -61,7 +62,7 @@ spec:
serviceAccountName: consul
containers:
- name: consul
image: "consul:1.8"
image: "consul:1.11"
env:
- name: NAMESPACE
valueFrom:

View File

@@ -2,6 +2,12 @@
# There is still no actual persistence, but:
# - podAntiaffinity prevents pod colocation
# - clusters works when scaling down to 1 (thanks to lifecycle hook)
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: consul
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
@@ -27,11 +33,6 @@ subjects:
name: consul
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: consul
---
apiVersion: v1
kind: Service
metadata:
name: consul
@@ -68,7 +69,7 @@ spec:
terminationGracePeriodSeconds: 10
containers:
- name: consul
image: "consul:1.8"
image: "consul:1.11"
env:
- name: NAMESPACE
valueFrom:

View File

@@ -1,5 +1,11 @@
# Even better Consul cluster.
# That one uses a volumeClaimTemplate to achieve true persistence.
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: consul
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
@@ -25,11 +31,6 @@ subjects:
name: consul
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: consul
---
apiVersion: v1
kind: Service
metadata:
name: consul
@@ -75,7 +76,7 @@ spec:
terminationGracePeriodSeconds: 10
containers:
- name: consul
image: "consul:1.8"
image: "consul:1.11"
volumeMounts:
- name: data
mountPath: /consul/data

View File

@@ -9,377 +9,273 @@ metadata:
spec: {}
status: {}
---
---
# Source: kubernetes-dashboard/templates/serviceaccount.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/secret.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# kubernetes-dashboard-certs
apiVersion: v1
kind: Secret
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-certs
namespace: kubernetes-dashboard
type: Opaque
---
# Source: kubernetes-dashboard/templates/secret.yaml
# kubernetes-dashboard-csrf
apiVersion: v1
kind: Secret
metadata:
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-csrf
namespace: kubernetes-dashboard
type: Opaque
---
# Source: kubernetes-dashboard/templates/secret.yaml
# kubernetes-dashboard-key-holder
apiVersion: v1
kind: Secret
metadata:
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-key-holder
namespace: kubernetes-dashboard
type: Opaque
---
# Source: kubernetes-dashboard/templates/configmap.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
data: null
kind: ConfigMap
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-settings
data:
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/clusterrole-metrics.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: "kubernetes-dashboard-metrics"
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-metrics
rules:
# Allow Metrics Scraper to get metrics from the Metrics server
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
# Source: kubernetes-dashboard/templates/clusterrolebinding-metrics.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: "kubernetes-dashboard-metrics"
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-metrics
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-dashboard-metrics
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/role.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
rules:
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- 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"]
- apiGroups:
- ""
resourceNames:
- kubernetes-dashboard-key-holder
- kubernetes-dashboard-certs
- kubernetes-dashboard-csrf
resources:
- secrets
verbs:
- get
- update
- delete
- apiGroups:
- ""
resourceNames:
- kubernetes-dashboard-settings
resources:
- configmaps
verbs:
- get
- update
- apiGroups:
- ""
resourceNames:
- heapster
- dashboard-metrics-scraper
resources:
- services
verbs:
- proxy
- apiGroups:
- ""
resourceNames:
- heapster
- 'http:heapster:'
- 'https:heapster:'
- dashboard-metrics-scraper
- http:dashboard-metrics-scraper
resources:
- services/proxy
verbs:
- get
---
# Source: kubernetes-dashboard/templates/rolebinding.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/service.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Service
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: kubernetes-dashboard
kubernetes.io/cluster-service: "true"
spec:
type: NodePort
ports:
- port: 443
targetPort: http
name: http
selector:
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
kubernetes.io/cluster-service: "true"
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- name: http
port: 443
targetPort: http
selector:
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/name: kubernetes-dashboard
type: NodePort
---
# Source: kubernetes-dashboard/templates/deployment.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/name: kubernetes-dashboard
strategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
selector:
matchLabels:
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/component: kubernetes-dashboard
template:
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
serviceAccountName: kubernetes-dashboard
containers:
- name: kubernetes-dashboard
image: "kubernetesui/dashboard:v2.3.1"
- args:
- --namespace=kubernetes-dashboard
- --sidecar-host=http://127.0.0.1:8000
- --enable-skip-login
- --enable-insecure-login
image: kubernetesui/dashboard:v2.5.0
imagePullPolicy: IfNotPresent
args:
- --namespace=kubernetes-dashboard
- --metrics-provider=none
- --enable-skip-login
- --enable-insecure-login
ports:
- name: http
containerPort: 9090
protocol: TCP
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
scheme: HTTP
path: /
port: 9090
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 30
name: kubernetes-dashboard
ports:
- containerPort: 9090
name: http
protocol: TCP
resources:
limits:
cpu: 2
@@ -392,102 +288,42 @@ spec:
readOnlyRootFilesystem: true
runAsGroup: 2001
runAsUser: 1001
volumeMounts:
- mountPath: /certs
name: kubernetes-dashboard-certs
- mountPath: /tmp
name: tmp-volume
- image: kubernetesui/metrics-scraper:v1.0.7
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /
port: 8000
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 30
name: dashboard-metrics-scraper
ports:
- containerPort: 8000
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsGroup: 2001
runAsUser: 1001
volumeMounts:
- mountPath: /tmp
name: tmp-volume
securityContext:
seccompProfile:
type: RuntimeDefault
serviceAccountName: kubernetes-dashboard
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
---
# Source: kubernetes-dashboard/templates/clusterrole-readonly.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/clusterrolebinding-readonly.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/ingress.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/networkpolicy.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/pdb.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/psp.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- emptyDir: {}
name: tmp-volume
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding

View File

@@ -9,376 +9,272 @@ metadata:
spec: {}
status: {}
---
---
# Source: kubernetes-dashboard/templates/serviceaccount.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/secret.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# kubernetes-dashboard-certs
apiVersion: v1
kind: Secret
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-certs
namespace: kubernetes-dashboard
type: Opaque
---
# Source: kubernetes-dashboard/templates/secret.yaml
# kubernetes-dashboard-csrf
apiVersion: v1
kind: Secret
metadata:
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-csrf
namespace: kubernetes-dashboard
type: Opaque
---
# Source: kubernetes-dashboard/templates/secret.yaml
# kubernetes-dashboard-key-holder
apiVersion: v1
kind: Secret
metadata:
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-key-holder
namespace: kubernetes-dashboard
type: Opaque
---
# Source: kubernetes-dashboard/templates/configmap.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
data: null
kind: ConfigMap
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-settings
data:
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/clusterrole-metrics.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: "kubernetes-dashboard-metrics"
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-metrics
rules:
# Allow Metrics Scraper to get metrics from the Metrics server
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
# Source: kubernetes-dashboard/templates/clusterrolebinding-metrics.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: "kubernetes-dashboard-metrics"
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-metrics
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-dashboard-metrics
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/role.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
rules:
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- 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"]
- apiGroups:
- ""
resourceNames:
- kubernetes-dashboard-key-holder
- kubernetes-dashboard-certs
- kubernetes-dashboard-csrf
resources:
- secrets
verbs:
- get
- update
- delete
- apiGroups:
- ""
resourceNames:
- kubernetes-dashboard-settings
resources:
- configmaps
verbs:
- get
- update
- apiGroups:
- ""
resourceNames:
- heapster
- dashboard-metrics-scraper
resources:
- services
verbs:
- proxy
- apiGroups:
- ""
resourceNames:
- heapster
- 'http:heapster:'
- 'https:heapster:'
- dashboard-metrics-scraper
- http:dashboard-metrics-scraper
resources:
- services/proxy
verbs:
- get
---
# Source: kubernetes-dashboard/templates/rolebinding.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/service.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Service
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: kubernetes-dashboard
kubernetes.io/cluster-service: "true"
spec:
type: ClusterIP
ports:
- port: 443
targetPort: https
name: https
selector:
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
kubernetes.io/cluster-service: "true"
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- name: https
port: 443
targetPort: https
selector:
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/name: kubernetes-dashboard
type: ClusterIP
---
# Source: kubernetes-dashboard/templates/deployment.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/name: kubernetes-dashboard
strategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
selector:
matchLabels:
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/component: kubernetes-dashboard
template:
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
serviceAccountName: kubernetes-dashboard
containers:
- name: kubernetes-dashboard
image: "kubernetesui/dashboard:v2.3.1"
- args:
- --namespace=kubernetes-dashboard
- --auto-generate-certificates
- --sidecar-host=http://127.0.0.1:8000
image: kubernetesui/dashboard:v2.5.0
imagePullPolicy: IfNotPresent
args:
- --namespace=kubernetes-dashboard
- --auto-generate-certificates
- --metrics-provider=none
ports:
- name: https
containerPort: 8443
protocol: TCP
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
scheme: HTTPS
initialDelaySeconds: 30
timeoutSeconds: 30
name: kubernetes-dashboard
ports:
- containerPort: 8443
name: https
protocol: TCP
resources:
limits:
cpu: 2
@@ -391,99 +287,39 @@ spec:
readOnlyRootFilesystem: true
runAsGroup: 2001
runAsUser: 1001
volumeMounts:
- mountPath: /certs
name: kubernetes-dashboard-certs
- mountPath: /tmp
name: tmp-volume
- image: kubernetesui/metrics-scraper:v1.0.7
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /
port: 8000
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 30
name: dashboard-metrics-scraper
ports:
- containerPort: 8000
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsGroup: 2001
runAsUser: 1001
volumeMounts:
- mountPath: /tmp
name: tmp-volume
securityContext:
seccompProfile:
type: RuntimeDefault
serviceAccountName: kubernetes-dashboard
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
---
# Source: kubernetes-dashboard/templates/clusterrole-readonly.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/clusterrolebinding-readonly.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/ingress.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/networkpolicy.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/pdb.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/psp.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- emptyDir: {}
name: tmp-volume

View File

@@ -9,376 +9,272 @@ metadata:
spec: {}
status: {}
---
---
# Source: kubernetes-dashboard/templates/serviceaccount.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/secret.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# kubernetes-dashboard-certs
apiVersion: v1
kind: Secret
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-certs
namespace: kubernetes-dashboard
type: Opaque
---
# Source: kubernetes-dashboard/templates/secret.yaml
# kubernetes-dashboard-csrf
apiVersion: v1
kind: Secret
metadata:
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-csrf
namespace: kubernetes-dashboard
type: Opaque
---
# Source: kubernetes-dashboard/templates/secret.yaml
# kubernetes-dashboard-key-holder
apiVersion: v1
kind: Secret
metadata:
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-key-holder
namespace: kubernetes-dashboard
type: Opaque
---
# Source: kubernetes-dashboard/templates/configmap.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
data: null
kind: ConfigMap
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-settings
data:
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/clusterrole-metrics.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: "kubernetes-dashboard-metrics"
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-metrics
rules:
# Allow Metrics Scraper to get metrics from the Metrics server
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
# Source: kubernetes-dashboard/templates/clusterrolebinding-metrics.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: "kubernetes-dashboard-metrics"
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard-metrics
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-dashboard-metrics
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/role.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
rules:
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- 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"]
- apiGroups:
- ""
resourceNames:
- kubernetes-dashboard-key-holder
- kubernetes-dashboard-certs
- kubernetes-dashboard-csrf
resources:
- secrets
verbs:
- get
- update
- delete
- apiGroups:
- ""
resourceNames:
- kubernetes-dashboard-settings
resources:
- configmaps
verbs:
- get
- update
- apiGroups:
- ""
resourceNames:
- heapster
- dashboard-metrics-scraper
resources:
- services
verbs:
- proxy
- apiGroups:
- ""
resourceNames:
- heapster
- 'http:heapster:'
- 'https:heapster:'
- dashboard-metrics-scraper
- http:dashboard-metrics-scraper
resources:
- services/proxy
verbs:
- get
---
# Source: kubernetes-dashboard/templates/rolebinding.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
# Source: kubernetes-dashboard/templates/service.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Service
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: kubernetes-dashboard
kubernetes.io/cluster-service: "true"
spec:
type: NodePort
ports:
- port: 443
targetPort: https
name: https
selector:
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
kubernetes.io/cluster-service: "true"
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- name: https
port: 443
targetPort: https
selector:
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/name: kubernetes-dashboard
type: NodePort
---
# Source: kubernetes-dashboard/templates/deployment.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-dashboard
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/name: kubernetes-dashboard
strategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
selector:
matchLabels:
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/component: kubernetes-dashboard
template:
metadata:
annotations: null
labels:
app.kubernetes.io/name: kubernetes-dashboard
helm.sh/chart: kubernetes-dashboard-5.0.2
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/version: "2.3.1"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: kubernetes-dashboard
app.kubernetes.io/instance: kubernetes-dashboard
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
serviceAccountName: kubernetes-dashboard
containers:
- name: kubernetes-dashboard
image: "kubernetesui/dashboard:v2.3.1"
- args:
- --namespace=kubernetes-dashboard
- --auto-generate-certificates
- --sidecar-host=http://127.0.0.1:8000
image: kubernetesui/dashboard:v2.5.0
imagePullPolicy: IfNotPresent
args:
- --namespace=kubernetes-dashboard
- --auto-generate-certificates
- --metrics-provider=none
ports:
- name: https
containerPort: 8443
protocol: TCP
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
scheme: HTTPS
initialDelaySeconds: 30
timeoutSeconds: 30
name: kubernetes-dashboard
ports:
- containerPort: 8443
name: https
protocol: TCP
resources:
limits:
cpu: 2
@@ -391,102 +287,42 @@ spec:
readOnlyRootFilesystem: true
runAsGroup: 2001
runAsUser: 1001
volumeMounts:
- mountPath: /certs
name: kubernetes-dashboard-certs
- mountPath: /tmp
name: tmp-volume
- image: kubernetesui/metrics-scraper:v1.0.7
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /
port: 8000
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 30
name: dashboard-metrics-scraper
ports:
- containerPort: 8000
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsGroup: 2001
runAsUser: 1001
volumeMounts:
- mountPath: /tmp
name: tmp-volume
securityContext:
seccompProfile:
type: RuntimeDefault
serviceAccountName: kubernetes-dashboard
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
---
# Source: kubernetes-dashboard/templates/clusterrole-readonly.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/clusterrolebinding-readonly.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/ingress.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/networkpolicy.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/pdb.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Source: kubernetes-dashboard/templates/psp.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- emptyDir: {}
name: tmp-volume
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding

View File

@@ -1,18 +1,16 @@
global
daemon
maxconn 256
defaults
mode tcp
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
timeout connect 5s
timeout client 50s
timeout server 50s
frontend the-frontend
listen very-basic-load-balancer
bind *:80
default_backend the-backend
backend the-backend
server google.com-80 google.com:80 maxconn 32 check
server ibm.fr-80 ibm.fr:80 maxconn 32 check
server blue color.blue.svc:80
server green color.green.svc:80
# Note: the services above must exist,
# otherwise HAproxy won't start.

View File

@@ -0,0 +1,28 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: ingress-domain-name
spec:
rules:
- name: create-ingress
match:
resources:
kinds:
- Service
generate:
kind: Ingress
name: "{{request.object.metadata.name}}"
namespace: "{{request.object.metadata.namespace}}"
data:
spec:
rules:
- host: "{{request.object.metadata.name}}.{{request.object.metadata.namespace}}.A.B.C.D.nip.io"
http:
paths:
- backend:
service:
name: "{{request.object.metadata.name}}"
port:
number: 80
path: /
pathType: Prefix

View File

@@ -0,0 +1,32 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: ingress-domain-name
spec:
rules:
- name: create-ingress
match:
resources:
kinds:
- Service
preconditions:
- key: "{{request.object.spec.ports[0].name}}"
operator: Equals
value: http
generate:
kind: Ingress
name: "{{request.object.metadata.name}}"
namespace: "{{request.object.metadata.namespace}}"
data:
spec:
rules:
- host: "{{request.object.metadata.name}}.{{request.object.metadata.namespace}}.A.B.C.D.nip.io"
http:
paths:
- backend:
service:
name: "{{request.object.metadata.name}}"
port:
name: http
path: /
pathType: Prefix

View File

@@ -0,0 +1,32 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: ingress-domain-name
spec:
rules:
- name: create-ingress
match:
resources:
kinds:
- Service
preconditions:
- key: http
operator: In
value: "{{request.object.spec.ports[*].name}}"
generate:
kind: Ingress
name: "{{request.object.metadata.name}}"
namespace: "{{request.object.metadata.namespace}}"
data:
spec:
rules:
- host: "{{request.object.metadata.name}}.{{request.object.metadata.namespace}}.A.B.C.D.nip.io"
http:
paths:
- backend:
service:
name: "{{request.object.metadata.name}}"
port:
name: http
path: /
pathType: Prefix

View File

@@ -0,0 +1,34 @@
# Note: this policy uses the operator "AnyIn", which was introduced in Kyverno 1.6.
# (This policy won't work with Kyverno 1.5!)
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: ingress-domain-name
spec:
rules:
- name: create-ingress
match:
resources:
kinds:
- Service
preconditions:
- key: "{{request.object.spec.ports[*].port}}"
operator: AnyIn
value: [ 80 ]
generate:
kind: Ingress
name: "{{request.object.metadata.name}}"
namespace: "{{request.object.metadata.namespace}}"
data:
spec:
rules:
- host: "{{request.object.metadata.name}}.{{request.object.metadata.namespace}}.A.B.C.D.nip.io"
http:
paths:
- backend:
service:
name: "{{request.object.metadata.name}}"
port:
name: http
path: /
pathType: Prefix

View File

@@ -0,0 +1,37 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: ingress-domain-name
spec:
rules:
- name: create-ingress
context:
- name: configmap
configMap:
name: ingress-domain-name
namespace: "{{request.object.metadata.namespace}}"
match:
resources:
kinds:
- Service
preconditions:
- key: "{{request.object.spec.ports[0].name}}"
operator: Equals
value: http
generate:
kind: Ingress
name: "{{request.object.metadata.name}}"
namespace: "{{request.object.metadata.namespace}}"
data:
spec:
rules:
- host: "{{request.object.metadata.name}}.{{request.object.metadata.namespace}}.{{configmap.data.domain}}"
http:
paths:
- backend:
service:
name: "{{request.object.metadata.name}}"
port:
name: http
path: /
pathType: Prefix

20
k8s/mounter.yaml Normal file
View File

@@ -0,0 +1,20 @@
kind: Pod
apiVersion: v1
metadata:
generateName: mounter-
labels:
container.training/mounter: ""
spec:
volumes:
- name: pvc
persistentVolumeClaim:
claimName: my-pvc-XYZ45
containers:
- name: mounter
image: alpine
stdin: true
tty: true
volumeMounts:
- name: pvc
mountPath: /pvc
workingDir: /pvc

View File

@@ -3,8 +3,7 @@ apiVersion: networking.k8s.io/v1
metadata:
name: deny-from-other-namespaces
spec:
podSelector:
matchLabels:
podSelector: {}
ingress:
- from:
- podSelector: {}

20
k8s/pv.yaml Normal file
View File

@@ -0,0 +1,20 @@
kind: PersistentVolume
apiVersion: v1
metadata:
generateName: my-pv-
labels:
container.training/pv: ""
spec:
accessModes:
- ReadWriteOnce
- ReadWriteMany
capacity:
storage: 1G
hostPath:
path: /tmp/my-pv
#storageClassName: my-sc
#claimRef:
# kind: PersistentVolumeClaim
# apiVersion: v1
# namespace: default
# name: my-pvc-XYZ45

13
k8s/pvc.yaml Normal file
View File

@@ -0,0 +1,13 @@
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
generateName: my-pvc-
labels:
container.training/pvc: ""
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1G
#storageClassName: my-sc

147
k8s/rainbow.yaml Normal file
View File

@@ -0,0 +1,147 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: blue
labels:
app: rainbow
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: rainbow
color: blue
name: color
namespace: blue
spec:
selector:
matchLabels:
app: rainbow
color: blue
template:
metadata:
labels:
app: rainbow
color: blue
spec:
containers:
- image: jpetazzo/color
name: color
---
apiVersion: v1
kind: Service
metadata:
labels:
app: rainbow
color: blue
name: color
namespace: blue
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: rainbow
color: blue
type: ClusterIP
---
apiVersion: v1
kind: Namespace
metadata:
name: green
labels:
app: rainbow
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: rainbow
color: green
name: color
namespace: green
spec:
selector:
matchLabels:
app: rainbow
color: green
template:
metadata:
labels:
app: rainbow
color: green
spec:
containers:
- image: jpetazzo/color
name: color
---
apiVersion: v1
kind: Service
metadata:
labels:
app: rainbow
color: green
name: color
namespace: green
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: rainbow
color: green
type: ClusterIP
---
apiVersion: v1
kind: Namespace
metadata:
name: red
labels:
app: rainbow
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: rainbow
color: red
name: color
namespace: red
spec:
selector:
matchLabels:
app: rainbow
color: red
template:
metadata:
labels:
app: rainbow
color: red
spec:
containers:
- image: jpetazzo/color
name: color
---
apiVersion: v1
kind: Service
metadata:
labels:
app: rainbow
color: red
name: color
namespace: red
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: rainbow
color: red
type: ClusterIP

View File

@@ -5,25 +5,34 @@ banner() {
echo "#"
}
namespace() {
create_namespace() {
# 'helm template --namespace ... --create-namespace'
# doesn't create the namespace, so we need to create it.
# https://github.com/helm/helm/issues/9813
echo ---
kubectl create namespace kubernetes-dashboard \
-o yaml --dry-run=client
echo ---
}
add_namespace() {
# 'helm template --namespace ...' doesn't add namespace information,
# so we do it with this convenient filter instead.
# https://github.com/helm/helm/issues/10737
kubectl create -f- -o yaml --dry-run=client --namespace kubernetes-dashboard
}
(
banner
namespace
create_namespace
helm template kubernetes-dashboard kubernetes-dashboard \
--repo https://kubernetes.github.io/dashboard/ \
--create-namespace --namespace kubernetes-dashboard \
--set "extraArgs={--enable-skip-login,--enable-insecure-login}" \
--set metricsScraper.enabled=true \
--set protocolHttp=true \
--set service.type=NodePort \
#
| add_namespace
echo ---
kubectl create clusterrolebinding kubernetes-dashboard:insecure \
--clusterrole=cluster-admin \
@@ -34,21 +43,23 @@ namespace() {
(
banner
namespace
create_namespace
helm template kubernetes-dashboard kubernetes-dashboard \
--repo https://kubernetes.github.io/dashboard/ \
--create-namespace --namespace kubernetes-dashboard \
#
--set metricsScraper.enabled=true \
| add_namespace
) > dashboard-recommended.yaml
(
banner
namespace
create_namespace
helm template kubernetes-dashboard kubernetes-dashboard \
--repo https://kubernetes.github.io/dashboard/ \
--create-namespace --namespace kubernetes-dashboard \
--set metricsScraper.enabled=true \
--set service.type=NodePort \
#
| add_namespace
echo ---
kubectl create clusterrolebinding kubernetes-dashboard:cluster-admin \
--clusterrole=cluster-admin \

View File

@@ -1,16 +1,106 @@
This directory contains a Terraform configuration to deploy
a bunch of Kubernetes clusters on various cloud providers, using their respective managed Kubernetes products.
⚠️ This is work in progress. The UX needs to be improved,
and the docs could be better.
To use it:
This directory contains a Terraform configuration to deploy
a bunch of Kubernetes clusters on various cloud providers,
using their respective managed Kubernetes products.
## With shell wrapper
This is the recommended use. It makes it easy to start N clusters
on any provider. It will create a directory with a name like
`tag-YYYY-MM-DD-HH-MM-SS-SEED-PROVIDER`, copy the Terraform configuration
to that directory, then create the clusters using that configuration.
1. One-time setup: configure provider authentication for the provider(s) that you wish to use.
- Digital Ocean:
```bash
doctl auth init
```
- Google Cloud Platform: you will need to create a project named `prepare-tf`
and enable the relevant APIs for this project (sorry, if you're new to GCP,
this sounds vague; but if you're familiar with it you know what to do; if you
want to change the project name you can edit the Terraform configuration)
- Linode:
```bash
linode-cli configure
```
- Oracle Cloud: FIXME
(set up `oci` through the `oci-cli` Python package)
- Scaleway: run `scw init`
2. Optional: set number of clusters, cluster size, and region.
By default, 1 cluster will be configured, with 2 nodes, and auto-scaling up to 5 nodes.
If you want, you can override these parameters, with the following variables.
```bash
export TF_VAR_how_many_clusters=5
export TF_VAR_min_nodes_per_pool=2
export TF_VAR_max_nodes_per_pool=4
export TF_VAR_location=xxx
```
The `location` variable is optional. Each provider should have a default value.
The value of the `location` variable is provider-specific. Examples:
| Provider | Example value | How to see possible values
|---------------|-------------------|---------------------------
| Digital Ocean | `ams3` | `doctl compute region list`
| Google Cloud | `europe-north1-a` | `gcloud compute zones list`
| Linode | `eu-central` | `linode-cli regions list`
| Oracle Cloud | `eu-stockholm-1` | `oci iam region list`
You can also specify multiple locations, and then they will be
used in round-robin fashion.
For example, with Google Cloud, since the default quotas are very
low (my account is limited to 8 public IP addresses per zone, and
my requests to increase that quota were denied) you can do the
following:
```bash
export TF_VAR_location=$(gcloud compute zones list --format=json | jq -r .[].name | grep ^europe)
```
Then when you apply, clusters will be created across all available
zones in Europe. (When I write this, there are 20+ zones in Europe,
so even with my quota, I can create 40 clusters.)
3. Run!
```bash
./run.sh <providername>
```
(If you don't specify a provider name, it will list available providers.)
4. Shutting down
Go to the directory that was created by the previous step (`tag-YYYY-MM...`)
and run `terraform destroy`.
You can also run `./clean.sh` which will destroy ALL clusters deployed by the previous run script.
## Without shell wrapper
Expert mode.
Useful to run steps sperarately, and/or when working on the Terraform configurations.
1. Select the provider you wish to use.
Change the `source` attribute of the `module "clusters"` section.
Check the content of the `modules` directory to see available choices.
Go to the `source` directory and edit `main.tf`.
```bash
vim main.tf
```
Change the `source` attribute of the `module "clusters"` section.
Check the content of the `modules` directory to see available choices.
2. Initialize the provider.
@@ -20,24 +110,20 @@ terraform init
3. Configure provider authentication.
- Digital Ocean: `export DIGITALOCEAN_ACCESS_TOKEN=...`
(check `~/.config/doctl/config.yaml` for the token)
- Linode: `export LINODE_TOKEN=...`
(check `~/.config/linode-cli` for the token)
- Oracle Cloud: it should use `~/.oci/config`
- Scaleway: run `scw init`
See steps above, and add the following extra steps:
- Digital Coean:
```bash
export DIGITALOCEAN_ACCESS_TOKEN=$(grep ^access-token ~/.config/doctl/config.yaml | cut -d: -f2 | tr -d " ")
```
- Linode:
```bash
export LINODE_TOKEN=$(grep ^token ~/.config/linode-cli | cut -d= -f2 | tr -d " ")
```
4. Decide how many clusters and how many nodes per clusters you want.
```bash
export TF_VAR_how_many_clusters=5
export TF_VAR_min_nodes_per_pool=2
# Optional (will enable autoscaler when available)
export TF_VAR_max_nodes_per_pool=4
# Optional (will only work on some providers)
export TF_VAR_enable_arm_pool=true
```
5. Provision clusters.
```bash
@@ -46,7 +132,7 @@ terraform apply
6. Perform second stage provisioning.
This will install a SSH server on the clusters.
This will install an SSH server on the clusters.
```bash
cd stage2
@@ -72,5 +158,5 @@ terraform destroy
9. Clean up stage2.
```bash
rm stage/terraform.tfstate*
rm stage2/terraform.tfstate*
```

9
prepare-tf/cleanup.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/sh
export LINODE_TOKEN=$(grep ^token ~/.config/linode-cli | cut -d= -f2 | tr -d " ")
export DIGITALOCEAN_ACCESS_TOKEN=$(grep ^access-token ~/.config/doctl/config.yaml | cut -d: -f2 | tr -d " ")
for T in tag-*; do
(
cd $T
terraform apply -destroy -auto-approve && mv ../$T ../deleted$T
)
done

View File

@@ -1,16 +0,0 @@
resource "random_string" "_" {
length = 5
special = false
upper = false
}
resource "time_static" "_" {}
locals {
tag = format("tf-%s-%s", formatdate("YYYY-MM-DD-hh-mm", time_static._.rfc3339), random_string._.result)
# Common tags to be assigned to all resources
common_tags = [
"created-by=terraform",
"tag=${local.tag}"
]
}

49
prepare-tf/run.sh Executable file
View File

@@ -0,0 +1,49 @@
#!/bin/sh
set -e
TIME=$(which time)
PROVIDER=$1
[ "$PROVIDER" ] || {
echo "Please specify a provider as first argument, or 'ALL' for parallel mode."
echo "Available providers:"
ls -1 source/modules
exit 1
}
[ "$TAG" ] || {
TIMESTAMP=$(date +%Y-%m-%d-%H-%M-%S)
RANDOMTAG=$(base64 /dev/urandom | tr A-Z a-z | tr -d /+ | head -c5)
export TAG=tag-$TIMESTAMP-$RANDOMTAG
}
[ "$PROVIDER" = "ALL" ] && {
for PROVIDER in $(ls -1 source/modules); do
$TERMINAL -T $TAG-$PROVIDER -e sh -c "
export TAG=$TAG-$PROVIDER
$0 $PROVIDER
cd $TAG-$PROVIDER
bash
" &
done
exit 0
}
[ -d "source/modules/$PROVIDER" ] || {
echo "Provider '$PROVIDER' not found."
echo "Available providers:"
ls -1 source/modules
exit 1
}
export LINODE_TOKEN=$(grep ^token ~/.config/linode-cli | cut -d= -f2 | tr -d " ")
export DIGITALOCEAN_ACCESS_TOKEN=$(grep ^access-token ~/.config/doctl/config.yaml | cut -d: -f2 | tr -d " ")
cp -a source $TAG
cd $TAG
cp -r modules/$PROVIDER modules/PROVIDER
$TIME -o time.1.init terraform init
$TIME -o time.2.stage1 terraform apply -auto-approve
cd stage2
$TIME -o ../time.3.init terraform init
$TIME -o ../time.4.stage2 terraform apply -auto-approve

View File

@@ -0,0 +1,19 @@
resource "random_string" "_" {
length = 4
number = false
special = false
upper = false
}
resource "time_static" "_" {}
locals {
timestamp = formatdate("YYYY-MM-DD-hh-mm", time_static._.rfc3339)
tag = random_string._.result
# Common tags to be assigned to all resources
common_tags = [
"created-by-terraform",
format("created-at-%s", local.timestamp),
format("created-for-%s", local.tag)
]
}

View File

@@ -1,5 +1,5 @@
module "clusters" {
source = "./modules/linode"
source = "./modules/PROVIDER"
for_each = local.clusters
cluster_name = each.value.cluster_name
min_nodes_per_pool = var.min_nodes_per_pool
@@ -7,22 +7,24 @@ module "clusters" {
enable_arm_pool = var.enable_arm_pool
node_size = var.node_size
common_tags = local.common_tags
location = each.value.location
}
locals {
clusters = {
for i in range(101, 101 + var.how_many_clusters) :
i => {
cluster_name = format("%s-%03d", local.tag, i)
kubeconfig_path = format("./stage2/kubeconfig.%03d", i)
#dashdash_kubeconfig = format("--kubeconfig=./stage2/kubeconfig.%03d", i)
cluster_name = format("%s-%03d", local.tag, i)
kubeconfig_path = format("./stage2/kubeconfig.%03d", i)
externalips_path = format("./stage2/externalips.%03d", i)
flags_path = format("./stage2/flags.%03d", i)
location = local.locations[i % length(local.locations)]
}
}
}
resource "local_file" "stage2" {
filename = "./stage2/main.tf"
filename = "./stage2/main.tf"
file_permission = "0644"
content = templatefile(
"./stage2.tmpl",
@@ -30,6 +32,15 @@ resource "local_file" "stage2" {
)
}
resource "local_file" "flags" {
for_each = local.clusters
filename = each.value.flags_path
file_permission = "0600"
content = <<-EOT
has_metrics_server: ${module.clusters[each.key].has_metrics_server}
EOT
}
resource "local_file" "kubeconfig" {
for_each = local.clusters
filename = each.value.kubeconfig_path
@@ -59,8 +70,8 @@ resource "null_resource" "wait_for_nodes" {
}
data "external" "externalips" {
for_each = local.clusters
depends_on = [ null_resource.wait_for_nodes ]
for_each = local.clusters
depends_on = [null_resource.wait_for_nodes]
program = [
"sh",
"-c",

View File

@@ -1,12 +1,13 @@
resource "digitalocean_kubernetes_cluster" "_" {
name = var.cluster_name
tags = local.common_tags
region = var.region
name = var.cluster_name
tags = var.common_tags
# Region is mandatory, so let's provide a default value.
region = var.location != null ? var.location : "nyc1"
version = var.k8s_version
node_pool {
name = "dok-x86"
tags = local.common_tags
name = "x86"
tags = var.common_tags
size = local.node_type
auto_scale = true
min_nodes = var.min_nodes_per_pool

View File

@@ -5,3 +5,7 @@ output "kubeconfig" {
output "cluster_id" {
value = digitalocean_kubernetes_cluster._.id
}
output "has_metrics_server" {
value = false
}

View File

@@ -8,10 +8,6 @@ variable "common_tags" {
default = []
}
locals {
common_tags = [for tag in var.common_tags : replace(tag, "=", "-")]
}
variable "node_size" {
type = string
default = "M"
@@ -48,9 +44,9 @@ locals {
# To view supported regions, run:
# doctl compute region list
variable "region" {
variable "location" {
type = string
default = "nyc1"
default = null
}
# To view supported versions, run:

View File

@@ -0,0 +1,65 @@
resource "google_container_cluster" "_" {
name = var.cluster_name
project = local.project
location = local.location
min_master_version = var.k8s_version
# To deploy private clusters, uncomment the section below,
# and uncomment the block in network.tf.
# Private clusters require extra resources (Cloud NAT,
# router, network, subnet) and the quota for some of these
# resources is fairly low on GCP; so if you want to deploy
# a lot of private clusters (more than 10), you can use these
# blocks as a base but you will probably have to refactor
# things quite a bit (you will at least need to define a single
# shared router and use it across all the clusters).
/*
network = google_compute_network._.name
subnetwork = google_compute_subnetwork._.name
private_cluster_config {
enable_private_nodes = true
# This must be set to "false".
# (Otherwise, access to the public endpoint is disabled.)
enable_private_endpoint = false
# This must be set to a /28.
# I think it shouldn't collide with the pod network subnet.
master_ipv4_cidr_block = "10.255.255.0/28"
}
# Private clusters require "VPC_NATIVE" networking mode
# (as opposed to the legacy "ROUTES").
networking_mode = "VPC_NATIVE"
# ip_allocation_policy is required for VPC_NATIVE clusters.
ip_allocation_policy {
# This is the block that will be used for pods.
cluster_ipv4_cidr_block = "10.0.0.0/12"
# The services block is optional
# (GKE will pick one automatically).
#services_ipv4_cidr_block = ""
}
*/
node_pool {
name = "x86"
node_config {
tags = var.common_tags
machine_type = local.node_type
}
initial_node_count = var.min_nodes_per_pool
autoscaling {
min_node_count = var.min_nodes_per_pool
max_node_count = max(var.min_nodes_per_pool, var.max_nodes_per_pool)
}
}
# This is not strictly necessary.
# We'll see if we end up using it.
# (If it is removed, make sure to also remove the corresponding
# key+cert variables from outputs.tf!)
master_auth {
client_certificate_config {
issue_client_certificate = true
}
}
}

View File

@@ -0,0 +1,38 @@
/*
resource "google_compute_network" "_" {
name = var.cluster_name
project = local.project
# The default is to create subnets automatically.
# However, this creates one subnet per zone in all regions,
# which causes a quick exhaustion of the subnet quota.
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "_" {
name = var.cluster_name
ip_cidr_range = "10.254.0.0/16"
region = local.region
network = google_compute_network._.id
project = local.project
}
resource "google_compute_router" "_" {
name = var.cluster_name
region = local.region
network = google_compute_network._.name
project = local.project
}
resource "google_compute_router_nat" "_" {
name = var.cluster_name
router = google_compute_router._.name
region = local.region
project = local.project
# Everyone in the network is allowed to NAT out.
# (We would change this if we only wanted to allow specific subnets to NAT out.)
source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
# Pick NAT addresses automatically.
# (We would change this if we wanted to use specific addresses to NAT out.)
nat_ip_allocate_option = "AUTO_ONLY"
}
*/

View File

@@ -0,0 +1,35 @@
data "google_client_config" "_" {}
output "kubeconfig" {
value = <<-EOT
apiVersion: v1
kind: Config
current-context: ${google_container_cluster._.name}
clusters:
- name: ${google_container_cluster._.name}
cluster:
server: https://${google_container_cluster._.endpoint}
certificate-authority-data: ${google_container_cluster._.master_auth[0].cluster_ca_certificate}
contexts:
- name: ${google_container_cluster._.name}
context:
cluster: ${google_container_cluster._.name}
user: client-token
users:
- name: client-cert
user:
client-key-data: ${google_container_cluster._.master_auth[0].client_key}
client-certificate-data: ${google_container_cluster._.master_auth[0].client_certificate}
- name: client-token
user:
token: ${data.google_client_config._.access_token}
EOT
}
output "cluster_id" {
value = google_container_cluster._.id
}
output "has_metrics_server" {
value = true
}

View File

@@ -0,0 +1,8 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "4.5.0"
}
}
}

View File

@@ -0,0 +1,68 @@
variable "cluster_name" {
type = string
default = "deployed-with-terraform"
}
variable "common_tags" {
type = list(string)
default = []
}
variable "node_size" {
type = string
default = "M"
}
variable "min_nodes_per_pool" {
type = number
default = 2
}
variable "max_nodes_per_pool" {
type = number
default = 5
}
# FIXME
variable "enable_arm_pool" {
type = bool
default = false
}
variable "node_types" {
type = map(string)
default = {
"S" = "e2-small"
"M" = "e2-medium"
"L" = "e2-standard-2"
}
}
locals {
node_type = var.node_types[var.node_size]
}
# To view supported locations, run:
# gcloud compute zones list
variable "location" {
type = string
default = null
}
# To view supported versions, run:
# gcloud container get-server-config --region=europe-north1 '--format=flattened(channels)'
# But it's also possible to just specify e.g. "1.20" and it figures it out.
variable "k8s_version" {
type = string
default = "1.21"
}
locals {
location = var.location != null ? var.location : "europe-north1-a"
region = replace(local.location, "/-[a-z]$/", "")
# Unfortunately, the following line doesn't work
# (that attribute just returns an empty string)
# so we have to hard-code the project name.
#project = data.google_client_config._.project
project = "prepare-tf"
}

View File

@@ -1,7 +1,8 @@
resource "linode_lke_cluster" "_" {
label = var.cluster_name
tags = var.common_tags
region = var.region
label = var.cluster_name
tags = var.common_tags
# "region" is mandatory, so let's provide a default value if none was given.
region = var.location != null ? var.location : "eu-central"
k8s_version = var.k8s_version
pool {

View File

@@ -5,3 +5,7 @@ output "kubeconfig" {
output "cluster_id" {
value = linode_lke_cluster._.id
}
output "has_metrics_server" {
value = false
}

View File

@@ -42,11 +42,11 @@ locals {
node_type = var.node_types[var.node_size]
}
# To view supported versions, run:
# To view supported regions, run:
# linode-cli regions list
variable "region" {
variable "location" {
type = string
default = "us-east"
default = null
}
# To view supported versions, run:

View File

@@ -1,6 +1,7 @@
resource "oci_identity_compartment" "_" {
name = var.cluster_name
description = var.cluster_name
name = var.cluster_name
description = var.cluster_name
enable_delete = true
}
locals {

View File

@@ -9,3 +9,7 @@ output "kubeconfig" {
output "cluster_id" {
value = oci_containerengine_cluster._.id
}
output "has_metrics_server" {
value = false
}

View File

@@ -70,6 +70,13 @@ locals {
node_type = var.node_types[var.node_size]
}
# To view supported regions, run:
# oci iam region list | jq .data[].name
variable "location" {
type = string
default = null
}
# To view supported versions, run:
# oci ce cluster-options get --cluster-option-id all | jq -r '.data["kubernetes-versions"][]'
variable "k8s_version" {

View File

@@ -1,13 +1,15 @@
resource "scaleway_k8s_cluster" "_" {
name = var.cluster_name
tags = var.common_tags
version = var.k8s_version
cni = var.cni
name = var.cluster_name
region = var.location
tags = var.common_tags
version = var.k8s_version
cni = var.cni
delete_additional_resources = true
}
resource "scaleway_k8s_pool" "_" {
cluster_id = scaleway_k8s_cluster._.id
name = "scw-x86"
name = "x86"
tags = var.common_tags
node_type = local.node_type
size = var.min_nodes_per_pool

View File

@@ -5,3 +5,7 @@ output "kubeconfig" {
output "cluster_id" {
value = scaleway_k8s_cluster._.id
}
output "has_metrics_server" {
value = sort([var.k8s_version, "1.22"])[0] == "1.22"
}

View File

@@ -47,7 +47,12 @@ variable "cni" {
default = "cilium"
}
# See supported versions with:
variable "location" {
type = string
default = null
}
# To view supported versions, run:
# scw k8s version list -o json | jq -r .[].name
variable "k8s_version" {
type = string

View File

@@ -2,7 +2,7 @@ terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.0.3"
version = "2.7.1"
}
}
}
@@ -119,6 +119,11 @@ resource "kubernetes_cluster_role_binding" "shpod_${index}" {
name = "shpod"
namespace = "shpod"
}
subject {
api_group = "rbac.authorization.k8s.io"
kind = "Group"
name = "shpod-cluster-admins"
}
}
resource "random_string" "shpod_${index}" {
@@ -135,9 +140,14 @@ provider "helm" {
}
resource "helm_release" "metrics_server_${index}" {
# Some providers pre-install metrics-server.
# Some don't. Let's install metrics-server,
# but only if it's not already installed.
count = yamldecode(file("./flags.${index}"))["has_metrics_server"] ? 0 : 1
provider = helm.cluster_${index}
repository = "https://charts.bitnami.com/bitnami"
chart = "metrics-server"
version = "5.8.8"
name = "metrics-server"
namespace = "metrics-server"
create_namespace = true
@@ -181,7 +191,7 @@ resource "kubernetes_config_map" "kubeconfig_${index}" {
- name: cluster-admin
user:
client-key-data: $${base64encode(tls_private_key.cluster_admin_${index}.private_key_pem)}
client-certificate-data: $${base64encode(kubernetes_certificate_signing_request.cluster_admin_${index}.certificate)}
client-certificate-data: $${base64encode(kubernetes_certificate_signing_request_v1.cluster_admin_${index}.certificate)}
EOT
}
}
@@ -195,11 +205,14 @@ resource "tls_cert_request" "cluster_admin_${index}" {
private_key_pem = tls_private_key.cluster_admin_${index}.private_key_pem
subject {
common_name = "cluster-admin"
organization = "system:masters"
# Note: CSR API v1 doesn't allow issuing certs with "system:masters" anymore.
#organization = "system:masters"
# We'll use this custom group name instead.cluster-admin user.
organization = "shpod-cluster-admins"
}
}
resource "kubernetes_certificate_signing_request" "cluster_admin_${index}" {
resource "kubernetes_certificate_signing_request_v1" "cluster_admin_${index}" {
provider = kubernetes.cluster_${index}
metadata {
name = "cluster-admin"
@@ -207,6 +220,7 @@ resource "kubernetes_certificate_signing_request" "cluster_admin_${index}" {
spec {
usages = ["client auth"]
request = tls_cert_request.cluster_admin_${index}.cert_request_pem
signer_name = "kubernetes.io/kube-apiserver-client"
}
auto_approve = true
}

View File

@@ -0,0 +1,40 @@
variable "how_many_clusters" {
type = number
default = 1
}
variable "node_size" {
type = string
default = "M"
# Can be S, M, L.
# We map these values to different specific instance types for each provider,
# but the idea is that they shoudl correspond to the following sizes:
# S = 2 GB RAM
# M = 4 GB RAM
# L = 8 GB RAM
}
variable "min_nodes_per_pool" {
type = number
default = 1
}
variable "max_nodes_per_pool" {
type = number
default = 0
}
variable "enable_arm_pool" {
type = bool
default = false
}
variable "location" {
type = string
default = null
}
# TODO: perhaps handle if it's space-separated instead of newline?
locals {
locations = var.location == null ? [null] : split("\n", var.location)
}

View File

@@ -1,28 +0,0 @@
variable "how_many_clusters" {
type = number
default = 2
}
variable "node_size" {
type = string
default = "M"
# Can be S, M, L.
# S = 2 GB RAM
# M = 4 GB RAM
# L = 8 GB RAM
}
variable "min_nodes_per_pool" {
type = number
default = 1
}
variable "max_nodes_per_pool" {
type = number
default = 0
}
variable "enable_arm_pool" {
type = bool
default = true
}

View File

@@ -14,7 +14,9 @@ These tools can help you to create VMs on:
- [Docker](https://docs.docker.com/engine/installation/)
- [Docker Compose](https://docs.docker.com/compose/install/)
- [Parallel SSH](https://code.google.com/archive/p/parallel-ssh/) (on a Mac: `brew install pssh`)
- [Parallel SSH](https://github.com/lilydjwg/pssh)
(should be installable with `pip install git+https://github.com/lilydjwg/pssh`;
on a Mac, try `brew install pssh`)
Depending on the infrastructure that you want to use, you also need to install
the CLI that is specific to that cloud. For OpenStack deployments, you will

View File

@@ -1,4 +1,5 @@
INFRACLASS=openstack-tf
INFRACLASS=terraform
TERRAFORM=openstack
# If you are using OpenStack, copy this file (e.g. to "openstack" or "enix")
# and customize the variables below.

View File

@@ -75,9 +75,11 @@ _cmd_createuser() {
echo '$USER_LOGIN ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/$USER_LOGIN
"
# The MaxAuthTries is here to help with folks who have many SSH keys.
pssh "
set -e
sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
sudo sed -i 's/#MaxAuthTries 6/MaxAuthTries 42/' /etc/ssh/sshd_config
sudo service ssh restart
"
@@ -176,6 +178,13 @@ _cmd_clusterize() {
# install --owner=ubuntu --mode=600 /root/.ssh/authorized_keys --target-directory /home/ubuntu/.ssh"
#fi
# Special case for oracle since their iptables blocks everything but SSH
pssh "
if [ -f /etc/iptables/rules.v4 ]; then
sudo sed -i 's/-A INPUT -j REJECT --reject-with icmp-host-prohibited//' /etc/iptables/rules.v4
sudo netfilter-persistent start
fi"
# Copy settings and install Python YAML parser
pssh -I tee /tmp/settings.yaml <tags/$TAG/settings.yaml
pssh "
@@ -183,10 +192,10 @@ _cmd_clusterize() {
sudo apt-get install -y python-yaml"
# If there is no "python" binary, symlink to python3
#pssh "
#if ! which python; then
# ln -s $(which python3) /usr/local/bin/python
#fi"
pssh "
if ! which python; then
sudo ln -s $(which python3) /usr/local/bin/python
fi"
# Copy postprep.py to the remote machines, and execute it, feeding it the list of IP addresses
pssh -I tee /tmp/clusterize.py <lib/clusterize.py
@@ -246,7 +255,7 @@ _cmd_docker() {
##VERSION## https://github.com/docker/compose/releases
if [ "$ARCHITECTURE" ]; then
COMPOSE_VERSION=v2.0.1
COMPOSE_VERSION=v2.2.3
COMPOSE_PLATFORM='linux-$(uname -m)'
else
COMPOSE_VERSION=1.29.2
@@ -309,13 +318,15 @@ _cmd_kube() {
need_login_password
# Optional version, e.g. 1.13.5
KUBEVERSION=$2
SETTINGS=tags/$TAG/settings.yaml
KUBEVERSION=$(awk '/^kubernetes_version:/ {print $2}' $SETTINGS)
if [ "$KUBEVERSION" ]; then
EXTRA_APTGET="=$KUBEVERSION-00"
EXTRA_KUBEADM="kubernetesVersion: v$KUBEVERSION"
else
EXTRA_APTGET=""
EXTRA_KUBEADM=""
pssh "
sudo tee /etc/apt/preferences.d/kubernetes <<EOF
Package: kubectl kubeadm kubelet
Pin: version $KUBEVERSION*
Pin-Priority: 1000
EOF"
fi
# Install packages
@@ -326,7 +337,8 @@ _cmd_kube() {
sudo tee /etc/apt/sources.list.d/kubernetes.list"
pssh --timeout 200 "
sudo apt-get update -q &&
sudo apt-get install -qy kubelet$EXTRA_APTGET kubeadm$EXTRA_APTGET kubectl$EXTRA_APTGET &&
sudo apt-get install -qy kubelet kubeadm kubectl &&
sudo apt-mark hold kubelet kubeadm kubectl
kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl &&
echo 'alias k=kubectl' | sudo tee /etc/bash_completion.d/k &&
echo 'complete -F __start_kubectl k' | sudo tee -a /etc/bash_completion.d/k"
@@ -338,6 +350,11 @@ _cmd_kube() {
sudo swapoff -a"
fi
# Re-enable CRI interface in containerd
pssh "
echo '# Use default parameters for containerd.' | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd"
# Initialize kube control plane
pssh --timeout 200 "
if i_am_first_node && [ ! -f /etc/kubernetes/admin.conf ]; then
@@ -347,19 +364,38 @@ kind: InitConfiguration
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- token: \$(cat /tmp/token)
nodeRegistration:
# Comment out the next line to switch back to Docker.
criSocket: /run/containerd/containerd.sock
ignorePreflightErrors:
- NumCPU
---
kind: JoinConfiguration
apiVersion: kubeadm.k8s.io/v1beta2
discovery:
bootstrapToken:
apiServerEndpoint: \$(cat /etc/name_of_first_node):6443
token: \$(cat /tmp/token)
unsafeSkipCAVerification: true
nodeRegistration:
# Comment out the next line to switch back to Docker.
criSocket: /run/containerd/containerd.sock
ignorePreflightErrors:
- NumCPU
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: cgroupfs
# The following line is necessary when using Docker.
# It doesn't seem necessary when using containerd.
#cgroupDriver: cgroupfs
---
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta2
apiServer:
certSANs:
- \$(cat /tmp/ipv4)
$EXTRA_KUBEADM
EOF
sudo kubeadm init --config=/tmp/kubeadm-config.yaml --ignore-preflight-errors=NumCPU
sudo kubeadm init --config=/tmp/kubeadm-config.yaml
fi"
# Put kubeconfig in ubuntu's and $USER_LOGIN's accounts
@@ -383,8 +419,8 @@ EOF
pssh --timeout 200 "
if ! i_am_first_node && [ ! -f /etc/kubernetes/kubelet.conf ]; then
FIRSTNODE=\$(cat /etc/name_of_first_node) &&
TOKEN=\$(ssh $SSHOPTS \$FIRSTNODE cat /tmp/token) &&
sudo kubeadm join --discovery-token-unsafe-skip-ca-verification --token \$TOKEN \$FIRSTNODE:6443
ssh $SSHOPTS \$FIRSTNODE cat /tmp/kubeadm-config.yaml > /tmp/kubeadm-config.yaml &&
sudo kubeadm join --config /tmp/kubeadm-config.yaml
fi"
# Install metrics server
@@ -475,7 +511,7 @@ EOF
if [ ! -x /usr/local/bin/kustomize ]; then
curl -fsSL $URL |
sudo tar -C /usr/local/bin -zx kustomize
echo complete -C /usr/local/bin/kustomize kustomize | sudo tee /etc/bash_completion.d/kustomize
kustomize completion bash | sudo tee /etc/bash_completion.d/kustomize
kustomize version
fi"
@@ -684,7 +720,7 @@ _cmd_tailhist () {
ARCH=${ARCHITECTURE-amd64}
[ "$ARCH" = "aarch64" ] && ARCH=arm64
pssh -i "
pssh "
set -e
wget https://github.com/joewalnes/websocketd/releases/download/v0.3.0/websocketd-0.3.0-linux_$ARCH.zip
unzip websocketd-0.3.0-linux_$ARCH.zip websocketd
@@ -1022,7 +1058,8 @@ _cmd_webssh() {
need_tag
pssh "
sudo apt-get update &&
sudo apt-get install python-tornado python-paramiko -y"
sudo apt-get install python-tornado python-paramiko -y ||
sudo apt-get install python3-tornado python3-paramiko -y"
pssh "
cd /opt
[ -d webssh ] || sudo git clone https://github.com/jpetazzo/webssh"

View File

@@ -1,7 +1,26 @@
error_terraform_configuration() {
error "When using the terraform infraclass, the TERRAFORM"
error "environment variable must be set to one of the available"
error "terraform configurations. These configurations are in"
error "the prepare-vm/terraform subdirectory. You should probably"
error "update your infra file and set the variable."
error "(e.g. with TERRAFORM=openstack)"
}
if [ "$TERRAFORM" = "" ]; then
error_terraform_configuration
die "Aborting because TERRAFORM variable is not set."
fi
if [ ! -d terraform/$TERRAFORM ]; then
error_terraform_configuration
die "Aborting because no terraform configuration was found in 'terraform/$TERRAFORM'."
fi
infra_start() {
COUNT=$1
cp terraform-openstack/*.tf tags/$TAG
cp terraform/$TERRAFORM/*.tf tags/$TAG
(
cd tags/$TAG
if ! terraform init; then

View File

@@ -60,7 +60,10 @@ while domains and clusters:
zone += f"node{node} 300 IN A {ip}\n"
r = requests.put(
f"{apiurl}/{domain}/records",
headers={"x-api-key": apikey},
headers={
"x-api-key": apikey,
"content-type": "text/plain",
},
data=zone)
print(r.text)

82
prepare-vms/netlify-dns.sh Executable file
View File

@@ -0,0 +1,82 @@
#!/bin/sh
# https://open-api.netlify.com/#tag/dnsZone
[ "$1" ] || {
echo ""
echo "Add a record in Netlify DNS."
echo "This script is hardcoded to add a record to container.training".
echo ""
echo "Syntax:"
echo "$0 list"
echo "$0 add <name> <ipaddr>"
echo "$0 del <recordid>"
echo ""
echo "Example to create a A record for eu.container.training:"
echo "$0 add eu 185.145.250.0"
echo ""
exit 1
}
NETLIFY_USERID=$(jq .userId < ~/.config/netlify/config.json)
NETLIFY_TOKEN=$(jq -r .users[$NETLIFY_USERID].auth.token < ~/.config/netlify/config.json)
netlify() {
URI=$1
shift
http https://api.netlify.com/api/v1/$URI "$@" "Authorization:Bearer $NETLIFY_TOKEN"
}
ZONE_ID=$(netlify dns_zones |
jq -r '.[] | select ( .name == "container.training" ) | .id')
_list() {
netlify dns_zones/$ZONE_ID/dns_records |
jq -r '.[] | select(.type=="A") | [.hostname, .type, .value, .id] | @tsv'
}
_add() {
NAME=$1.container.training
ADDR=$2
# It looks like if we create two identical records, then delete one of them,
# Netlify DNS ends up in a weird state (the name doesn't resolve anymore even
# though it's still visible through the API and the website?)
if netlify dns_zones/$ZONE_ID/dns_records |
jq '.[] | select(.hostname=="'$NAME'" and .type=="A" and .value=="'$ADDR'")' |
grep .
then
echo "It looks like that record already exists. Refusing to create it."
exit 1
fi
netlify dns_zones/$ZONE_ID/dns_records type=A hostname=$NAME value=$ADDR ttl=300
netlify dns_zones/$ZONE_ID/dns_records |
jq '.[] | select(.hostname=="'$NAME'")'
}
_del() {
RECORD_ID=$1
# OK, since that one is dangerous, I'm putting the whole request explicitly here
http DELETE \
https://api.netlify.com/api/v1/dns_zones/$ZONE_ID/dns_records/$RECORD_ID \
"Authorization:Bearer $NETLIFY_TOKEN"
}
case "$1" in
list)
_list
;;
add)
_add $2 $3
;;
del)
_del $2
;;
*)
echo "Unknown command '$1'."
exit 1
;;
esac

View File

@@ -0,0 +1,33 @@
# Number of VMs per cluster
clustersize: 3
# The hostname of each node will be clusterprefix + a number
clusterprefix: oldversion
# Jinja2 template to use to generate ready-to-cut cards
cards_template: cards.html
# Use "Letter" in the US, and "A4" everywhere else
paper_size: A4
# Login and password that students will use
user_login: k8s
user_password: training
# For a list of old versions, check:
# https://kubernetes.io/releases/patch-releases/#non-active-branch-history
kubernetes_version: 1.18.20
image:
steps:
- wait
- clusterize
- tools
- docker
- createuser
- webssh
- tailhist
- kube
- kubetools
- kubetest

View File

@@ -3,7 +3,7 @@ set -e
export AWS_INSTANCE_TYPE=t3a.small
INFRA=infra/aws-us-east-2
INFRA=infra/aws-eu-north-1
STUDENTS=2
@@ -33,9 +33,15 @@ TAG=$PREFIX-$SETTINGS
--settings settings/$SETTINGS.yaml \
--students $STUDENTS
#INFRA=infra/aws-us-west-1
INFRA=infra/enix
export AWS_INSTANCE_TYPE=t3a.medium
SETTINGS=admin-oldversion
TAG=$PREFIX-$SETTINGS
./workshopctl start \
--tag $TAG \
--infra $INFRA \
--settings settings/$SETTINGS.yaml \
--students $STUDENTS
SETTINGS=admin-test
TAG=$PREFIX-$SETTINGS

View File

@@ -0,0 +1,48 @@
resource "oci_identity_compartment" "_" {
name = var.prefix
description = var.prefix
enable_delete = true
}
locals {
compartment_id = oci_identity_compartment._.id
}
data "oci_identity_availability_domains" "_" {
compartment_id = local.compartment_id
}
data "oci_core_images" "_" {
compartment_id = local.compartment_id
shape = var.shape
operating_system = "Canonical Ubuntu"
operating_system_version = "20.04"
#operating_system = "Oracle Linux"
#operating_system_version = "7.9"
}
resource "oci_core_instance" "_" {
count = var.how_many_nodes
display_name = format("%s-%04d", var.prefix, count.index + 1)
availability_domain = data.oci_identity_availability_domains._.availability_domains[var.availability_domain].name
compartment_id = local.compartment_id
shape = var.shape
shape_config {
memory_in_gbs = var.memory_in_gbs_per_node
ocpus = var.ocpus_per_node
}
source_details {
source_id = data.oci_core_images._.images[0].id
source_type = "image"
}
create_vnic_details {
subnet_id = oci_core_subnet._.id
}
metadata = {
ssh_authorized_keys = local.authorized_keys
}
}
output "ip_addresses" {
value = join("", formatlist("%s\n", oci_core_instance._.*.public_ip))
}

View File

@@ -0,0 +1,63 @@
resource "oci_core_vcn" "_" {
compartment_id = local.compartment_id
cidr_block = "10.0.0.0/16"
display_name = "tf-vcn"
}
#
# On OCI, you can have either "public" or "private" subnets.
# In both cases, instances get addresses in the VCN CIDR block;
# but instances in "public" subnets also get a public address.
#
# Then, to enable communication to the outside world, you need:
# - for public subnets, an "internet gateway"
# (will allow inbound and outbound traffic)
# - for private subnets, a "NAT gateway"
# (will only allow outbound traffic)
# - optionally, for private subnets, a "service gateway"
# (to access other OCI services, e.g. object store)
#
# In this configuration, we use public subnets, and since we
# need outside access, we add an internet gateway.
#
# Note that the default routing table in a VCN is empty, so we
# add the internet gateway to the default routing table.
# Similarly, the default security group in a VCN blocks almost
# everything, so we add a blanket rule in that security group.
#
resource "oci_core_internet_gateway" "_" {
compartment_id = local.compartment_id
display_name = "tf-igw"
vcn_id = oci_core_vcn._.id
}
resource "oci_core_default_route_table" "_" {
manage_default_resource_id = oci_core_vcn._.default_route_table_id
route_rules {
destination = "0.0.0.0/0"
destination_type = "CIDR_BLOCK"
network_entity_id = oci_core_internet_gateway._.id
}
}
resource "oci_core_default_security_list" "_" {
manage_default_resource_id = oci_core_vcn._.default_security_list_id
ingress_security_rules {
protocol = "all"
source = "0.0.0.0/0"
}
egress_security_rules {
protocol = "all"
destination = "0.0.0.0/0"
}
}
resource "oci_core_subnet" "_" {
compartment_id = local.compartment_id
cidr_block = "10.0.0.0/20"
vcn_id = oci_core_vcn._.id
display_name = "tf-subnet"
route_table_id = oci_core_default_route_table._.id
security_list_ids = [oci_core_default_security_list._.id]
}

View File

@@ -0,0 +1,8 @@
terraform {
required_version = ">= 1"
required_providers {
openstack = {
source = "hashicorp/oci"
version = "4.48.0" }
}
}

View File

@@ -0,0 +1,42 @@
variable "prefix" {
type = string
default = "provisioned-with-terraform"
}
variable "how_many_nodes" {
type = number
default = 2
}
locals {
authorized_keys = file("~/.ssh/id_rsa.pub")
}
/*
Available flex shapes:
"VM.Optimized3.Flex" # Intel Ice Lake
"VM.Standard3.Flex" # Intel Ice Lake
"VM.Standard.A1.Flex" # Ampere Altra
"VM.Standard.E3.Flex" # AMD Rome
"VM.Standard.E4.Flex" # AMD Milan
*/
variable "shape" {
type = string
default = "VM.Standard.A1.Flex"
}
variable "availability_domain" {
type = number
default = 0
}
variable "ocpus_per_node" {
type = number
default = 1
}
variable "memory_in_gbs_per_node" {
type = number
default = 4
}

View File

@@ -5,7 +5,7 @@ chat: "[Mattermost](https://highfive.container.training/mattermost)"
gitrepo: github.com/jpetazzo/container.training
slides: https://2021-09-enix.container.training/
slides: https://2022-02-enix.container.training/
#slidenumberprefix: "#SomeHashTag &mdash; "
@@ -29,7 +29,6 @@ content:
- containers/First_Containers.md
- containers/Background_Containers.md
- containers/Initial_Images.md
-
- containers/Building_Images_Interactively.md
- containers/Building_Images_With_Dockerfiles.md
- containers/Cmd_And_Entrypoint.md
@@ -38,29 +37,29 @@ content:
- # DAY 2
- containers/Container_Networking_Basics.md
- containers/Local_Development_Workflow.md
- containers/Start_And_Attach.md
- containers/Naming_And_Inspecting.md
- containers/Labels.md
-
- containers/Container_Network_Model.md
- containers/Compose_For_Dev_Stacks.md
- containers/Exercise_Composefile.md
- # DAY 3
- containers/Start_And_Attach.md
- containers/Naming_And_Inspecting.md
- containers/Labels.md
- containers/Getting_Inside.md
- containers/Network_Drivers.md
- containers/Dockerfile_Tips.md
- containers/Advanced_Dockerfiles.md
-
- containers/Orchestration_Overview.md
- containers/Multi_Stage_Builds.md
#- containers/Publishing_To_Docker_Hub.md
- containers/Publishing_To_Docker_Hub.md
- containers/Exercise_Dockerfile_Advanced.md
- # DAY 4
- containers/Buildkit.md
- containers/Network_Drivers.md
- containers/Namespaces_Cgroups.md
#- containers/Copy_On_Write.md
- containers/Orchestration_Overview.md
#- containers/Docker_Machine.md
#- containers/Init_Systems.md
#- containers/Application_Configuration.md
#- containers/Logging.md
#- containers/Namespaces_Cgroups.md
#- containers/Copy_On_Write.md
#- containers/Containers_From_Scratch.md
#- containers/Container_Engines.md
#- containers/Pods_Anatomy.md

View File

@@ -5,7 +5,7 @@ chat: "[Mattermost](https://highfive.container.training/mattermost)"
gitrepo: github.com/jpetazzo/container.training
slides: https://2021-09-enix.container.training/
slides: https://2022-02-enix.container.training/
#slidenumberprefix: "#SomeHashTag &mdash; "

View File

@@ -6,7 +6,7 @@ chat: "[Mattermost](https://highfive.container.training/mattermost)"
gitrepo: github.com/jpetazzo/container.training
slides: https://2021-09-enix.container.training/
slides: https://2022-02-enix.container.training/
#slidenumberprefix: "#SomeHashTag &mdash; "

View File

@@ -5,7 +5,7 @@ chat: "[Mattermost](https://highfive.container.training/mattermost)"
gitrepo: github.com/jpetazzo/container.training
slides: https://2021-09-enix.container.training/
slides: https://2022-02-enix.container.training/
#slidenumberprefix: "#SomeHashTag &mdash; "
@@ -23,29 +23,42 @@ content:
- shared/webssh.md
- shared/connecting.md
- shared/toc.md
- exercises/sealed-secrets-brief.md
- exercises/kyverno-ingress-domain-name-brief.md
- #1
- k8s/demo-apps.md
- k8s/netpol.md
- k8s/authn-authz.md
- k8s/extending-api.md
- k8s/sealed-secrets.md
- k8s/cert-manager.md
- k8s/ingress-tls.md
- exercises/sealed-secrets-details.md
- #2
- k8s/extending-api.md
- k8s/crd.md
- k8s/operators.md
- k8s/admission.md
- k8s/kyverno.md
- exercises/ingress-secret-policy-details.md
- exercises/kyverno-ingress-domain-name-details.md
- #3
- k8s/resource-limits.md
- k8s/metrics-server.md
- k8s/cluster-sizing.md
- k8s/horizontal-pod-autoscaler.md
- k8s/apiserver-deepdive.md
- k8s/aggregation-layer.md
- k8s/prometheus.md
- k8s/hpa-v2.md
- #4
- k8s/statefulsets.md
- k8s/local-persistent-volumes.md
- k8s/eck.md
- k8s/consul.md
- k8s/pv-pvc-sc.md
- k8s/volume-claim-templates.md
#- k8s/eck.md
#- k8s/portworx.md
- k8s/openebs.md
- k8s/stateful-failover.md
- k8s/operators-design.md
- k8s/operators-example.md
- k8s/owners-and-dependents.md
- k8s/events.md
- k8s/finalizers.md

View File

@@ -5,7 +5,7 @@ chat: "[Mattermost](https://highfive.container.training/mattermost)"
gitrepo: github.com/jpetazzo/container.training
slides: https://2021-09-enix.container.training/
slides: https://2022-02-enix.container.training/
#slidenumberprefix: "#SomeHashTag &mdash; "
@@ -31,7 +31,6 @@ content:
- k8s/multinode.md
- k8s/cni.md
- k8s/interco.md
- exercises/dmuc-details.md
-
- k8s/cni-internals.md
- k8s/apilb.md

View File

@@ -0,0 +1,362 @@
# Buildkit
- "New" backend for Docker builds
- announced in 2017
- ships with Docker Engine 18.09
- enabled by default on Docker Desktop in 2021
- Huge improvements in build efficiency
- 100% compatible with existing Dockerfiles
- New features for multi-arch
- Not just for building container images
---
## Old vs New
- Classic `docker build`:
- copy whole build context
- linear execution
- `docker run` + `docker commit` + `docker run` + `docker commit`...
- Buildkit:
- copy files only when they are needed; cache them
- compute dependency graph (dependencies are expressed by `COPY`)
- parallel execution
- doesn't rely on Docker, but on internal runner/snapshotter
- can run in "normal" containers (including in Kubernetes pods)
---
## Parallel execution
- In multi-stage builds, all stages can be built in parallel
(example: https://github.com/jpetazzo/shpod; [before] and [after])
- Stages are built only when they are necessary
(i.e. if their output is tagged or used in another necessary stage)
- Files are copied from context only when needed
- Files are cached in the builder
[before]: https://github.com/jpetazzo/shpod/blob/c6efedad6d6c3dc3120dbc0ae0a6915f85862474/Dockerfile
[after]: https://github.com/jpetazzo/shpod/blob/d20887bbd56b5fcae2d5d9b0ce06cae8887caabf/Dockerfile
---
## Turning it on and off
- On recent version of Docker Desktop (since 2021):
*enabled by default*
- On older versions, or on Docker CE (Linux):
`export DOCKER_BUILDKIT=1`
- Turning it off:
`export DOCKER_BUILDKIT=0`
---
## Multi-arch support
- Historically, Docker only ran on x86_64 / amd64
(Intel/AMD 64 bits architecture)
- Folks have been running it on 32-bit ARM for ages
(e.g. Raspberry Pi)
- This required a Go compiler and appropriate base images
(which means changing/adapting Dockerfiles to use these base images)
- Docker [image manifest v2 schema 2][manifest] introduces multi-arch images
(`FROM alpine` automatically gets the right image for your architecture)
[manifest]: https://docs.docker.com/registry/spec/manifest-v2-2/
---
## Why?
- Raspberry Pi (32-bit and 64-bit ARM)
- Other ARM-based embedded systems (ODROID, NVIDIA Jetson...)
- Apple M1
- AWS Graviton
- Ampere Altra (e.g. on Oracle Cloud)
- ...
---
## Multi-arch builds in a nutshell
Use the `docker buildx build` command:
```bash
docker buildx build … \
--platform linux/amd64,linux/arm64,linux/arm/v7,linux/386 \
[--tag jpetazzo/hello --push]
```
- Requires all base images to be available for these platforms
- Must not use binary downloads with hard-coded architectures!
(streamlining a Dockerfile for multi-arch: [before], [after])
[before]: https://github.com/jpetazzo/shpod/blob/d20887bbd56b5fcae2d5d9b0ce06cae8887caabf/Dockerfile
[after]: https://github.com/jpetazzo/shpod/blob/c50789e662417b34fea6f5e1d893721d66d265b7/Dockerfile
---
## Native vs emulated vs cross
- Native builds:
*aarch64 machine running aarch64 programs building aarch64 images/binaries*
- Emulated builds:
*x86_64 machine running aarch64 programs building aarch64 images/binaries*
- Cross builds:
*x86_64 machine running x86_64 programs building aarch64 images/binaries*
---
## Native
- Dockerfiles are (relatively) simple to write
(nothing special to do to handle multi-arch; just avoid hard-coded archs)
- Best performance
- Requires "exotic" machines
- Requires setting up a build farm
---
## Emulated
- Dockerfiles are (relatively) simple to write
- Emulation performance can vary
(from "OK" to "ouch this is slow")
- Emulation isn't always perfect
(weird bugs/crashes are rare but can happen)
- Doesn't require special machines
- Supports arbitrary architectures thanks to QEMU
---
## Cross
- Dockerfiles are more complicated to write
- Requires cross-compilation toolchains
- Performance is good
- Doesn't require special machines
---
## Native builds
- Requires base images to be available
- To view available architectures for an image:
```bash
regctl manifest get --list <imagename>
docker manifest inspect <imagename>
```
- Nothing special to do, *except* when downloading binaries!
```
https://releases.hashicorp.com/terraform/1.1.5/terraform_1.1.5_linux_`amd64`.zip
```
---
## Finding the right architecture
`uname -m` → armv7l, aarch64, i686, x86_64
`GOARCH` (from `go env`) → arm, arm64, 386, amd64
In Dockerfile, add `ARG TARGETARCH` (or `ARG TARGETPLATFORM`)
- `TARGETARCH` matches `GOARCH`
- `TARGETPLAFORM` → linux/arm/v7, linux/arm64, linux/386, linux/amd64
---
class: extra-details
## Welp
Sometimes, binary releases be like:
```
Linux_arm64.tar.gz
Linux_ppc64le.tar.gz
Linux_s390x.tar.gz
Linux_x86_64.tar.gz
```
This needs a bit of custom mapping.
---
## Emulation
- Leverages `binfmt_misc` and QEMU on Linux
- Enabling:
```bash
docker run --rm --privileged aptman/qus -s -- -p
```
- Disabling:
```bash
docker run --rm --privileged aptman/qus -- -r
```
- Checking status:
```bash
ls -l /proc/sys/fs/binfmt_misc
```
---
class: extra-details
## How it works
- `binfmt_misc` lets us register _interpreters_ for binaries, e.g.:
- [DOSBox][dosbox] for DOS programs
- [Wine][wine] for Windows programs
- [QEMU][qemu] for Linux programs for other architectures
- When we try to execute e.g. a SPARC binary on our x86_64 machine:
- `binfmt_misc` detects the binary format and invokes `qemu-<arch> the-binary ...`
- QEMU translates SPARC instructions to x86_64 instructions
- system calls go straight to the kernel
[dosbox]: https://www.dosbox.com/
[QEMU]: https://www.qemu.org/
[wine]: https://www.winehq.org/
---
class: extra-details
## QEMU registration
- The `aptman/qus` image mentioned earlier contains static QEMU builds
- It registers all these interpreters with the kernel
- For more details, check:
- https://github.com/dbhi/qus
- https://dbhi.github.io/qus/
---
## Cross-compilation
- Cross-compilation is about 10x faster than emulation
(non-scientific benchmarks!)
- In Dockerfile, add:
`ARG BUILDARCH BUILDPLATFORM TARGETARCH TARGETPLATFORM`
- Can use `FROM --platform=$BUILDPLATFORM <image>`
- Then use `$TARGETARCH` or `$TARGETPLATFORM`
(e.g. for Go, `export GOARCH=$TARGETARCH`)
- Check [tonistiigi/xx][xx] and [Toni's blog][toni] for some amazing cross tools!
[xx]: https://github.com/tonistiigi/xx
[toni]: https://medium.com/@tonistiigi/faster-multi-platform-builds-dockerfile-cross-compilation-guide-part-1-ec087c719eaf
---
## Checking runtime capabilities
Build and run the following Dockerfile:
```dockerfile
FROM --platform=linux/amd64 busybox AS amd64
FROM --platform=linux/arm64 busybox AS arm64
FROM --platform=linux/arm/v7 busybox AS arm32
FROM --platform=linux/386 busybox AS ia32
FROM alpine
RUN apk add file
WORKDIR /root
COPY --from=amd64 /bin/busybox /root/amd64/busybox
COPY --from=arm64 /bin/busybox /root/arm64/busybox
COPY --from=arm32 /bin/busybox /root/arm32/busybox
COPY --from=ia32 /bin/busybox /root/ia32/busybox
CMD for A in *; do echo "$A => $($A/busybox uname -a)"; done
```
It will indicate which executables can be run on your engine.
---
## More than builds
- Buildkit is also used in other systems:
- [Earthly] - generic repeatable build pipelines
- [Dagger] - CICD pipelines that run anywhere
- and more!
[Earthly]: https://earthly.dev/
[Dagger]: https://dagger.io/

View File

@@ -96,7 +96,7 @@ Compose will be smart, and only recreate the containers that have changed.
When working with interpreted languages:
- dont' rebuild each time
- don't rebuild each time
- leverage a `volumes` section instead
@@ -250,6 +250,24 @@ For the full list, check: https://docs.docker.com/compose/compose-file/
---
## Configuring a Compose stack
- Follow [12-factor app configuration principles][12factorconfig]
(configure the app through environment variables)
- Provide (in the repo) a default environment file suitable for development
(no secret or sensitive value)
- Copy the default environment file to `.env` and tweak it
(or: provide a script to generate `.env` from a template)
[12factorconfig]: https://12factor.net/config
---
## Running multiple copies of a stack
- Copy the stack in two different directories, e.g. `front` and `frontcopy`
@@ -331,7 +349,7 @@ Use `docker-compose down -v` to remove everything including volumes.
- The data in the old container is lost...
- ... Except if the container is using a *volume*
- ...Except if the container is using a *volume*
- Compose will then re-attach that volume to the new container
@@ -343,6 +361,102 @@ Use `docker-compose down -v` to remove everything including volumes.
---
## Gotchas with volumes
- Unfortunately, Docker volumes don't have labels or metadata
- Compose tracks volumes thanks to their associated container
- If the container is deleted, the volume gets orphaned
- Example: `docker-compose down && docker-compose up`
- the old volume still exists, detached from its container
- a new volume gets created
- `docker-compose down -v`/`--volumes` deletes volumes
(but **not** `docker-compose down && docker-compose down -v`!)
---
## Managing volumes explicitly
Option 1: *named volumes*
```yaml
services:
app:
volumes:
- data:/some/path
volumes:
data:
```
- Volume will be named `<project>_data`
- It won't be orphaned with `docker-compose down`
- It will correctly be removed with `docker-compose down -v`
---
## Managing volumes explicitly
Option 2: *relative paths*
```yaml
services:
app:
volumes:
- ./data:/some/path
```
- Makes it easy to colocate the app and its data
(for migration, backups, disk usage accounting...)
- Won't be removed by `docker-compose down -v`
---
## Managing complex stacks
- Compose provides multiple features to manage complex stacks
(with many containers)
- `-f`/`--file`/`$COMPOSE_FILE` can be a list of Compose files
(separated by `:` and merged together)
- Services can be assigned to one or more *profiles*
- `--profile`/`$COMPOSE_PROFILE` can be a list of comma-separated profiles
(see [Using service profiles][profiles] in the Compose documentation)
- These variables can be set in `.env`
[profiles]: https://docs.docker.com/compose/profiles/
---
## Dependencies
- A service can have a `depends_on` section
(listing one or more other services)
- This is used when bringing up individual services
(e.g. `docker-compose up blah` or `docker-compose run foo`)
⚠️ It doesn't make a service "wait" for another one to be up!
---
class: extra-details
## A bit of history and trivia

View File

@@ -32,6 +32,432 @@ The last item should be done for educational purposes only!
---
# Control groups
- Control groups provide resource *metering* and *limiting*.
- This covers a number of "usual suspects" like:
- memory
- CPU
- block I/O
- network (with cooperation from iptables/tc)
- And a few exotic ones:
- huge pages (a special way to allocate memory)
- RDMA (resources specific to InfiniBand / remote memory transfer)
---
## Crowd control
- Control groups also allow to group processes for special operations:
- freezer (conceptually similar to a "mass-SIGSTOP/SIGCONT")
- perf_event (gather performance events on multiple processes)
- cpuset (limit or pin processes to specific CPUs)
- There is a "pids" cgroup to limit the number of processes in a given group.
- There is also a "devices" cgroup to control access to device nodes.
(i.e. everything in `/dev`.)
---
## Generalities
- Cgroups form a hierarchy (a tree).
- We can create nodes in that hierarchy.
- We can associate limits to a node.
- We can move a process (or multiple processes) to a node.
- The process (or processes) will then respect these limits.
- We can check the current usage of each node.
- In other words: limits are optional (if we only want accounting).
- When a process is created, it is placed in its parent's groups.
---
## Example
The numbers are PIDs.
The names are the names of our nodes (arbitrarily chosen).
.small[
```bash
cpu memory
├── batch ├── stateless
│ ├── cryptoscam │ ├── 25
│ │ └── 52 │ ├── 26
│ └── ffmpeg │ ├── 27
│ ├── 109 │ ├── 52
│ └── 88 │ ├── 109
└── realtime │ └── 88
├── nginx └── databases
│ ├── 25 ├── 1008
│ ├── 26 └── 524
│ └── 27
├── postgres
│ └── 524
└── redis
└── 1008
```
]
---
class: extra-details, deep-dive
## Cgroups v1 vs v2
- Cgroups v1 are available on all systems (and widely used).
- Cgroups v2 are a huge refactor.
(Development started in Linux 3.10, released in 4.5.)
- Cgroups v2 have a number of differences:
- single hierarchy (instead of one tree per controller),
- processes can only be on leaf nodes (not inner nodes),
- and of course many improvements / refactorings.
- Cgroups v2 enabled by default on Fedora 31 (2019), Ubuntu 21.10...
---
## Memory cgroup: accounting
- Keeps track of pages used by each group:
- file (read/write/mmap from block devices),
- anonymous (stack, heap, anonymous mmap),
- active (recently accessed),
- inactive (candidate for eviction).
- Each page is "charged" to a group.
- Pages can be shared across multiple groups.
(Example: multiple processes reading from the same files.)
- To view all the counters kept by this cgroup:
```bash
$ cat /sys/fs/cgroup/memory/memory.stat
```
---
## Memory cgroup v1: limits
- Each group can have (optional) hard and soft limits.
- Limits can be set for different kinds of memory:
- physical memory,
- kernel memory,
- total memory (including swap).
---
## Soft limits and hard limits
- Soft limits are not enforced.
(But they influence reclaim under memory pressure.)
- Hard limits *cannot* be exceeded:
- if a group of processes exceeds a hard limit,
- and if the kernel cannot reclaim any memory,
- then the OOM (out-of-memory) killer is triggered,
- and processes are killed until memory gets below the limit again.
---
class: extra-details, deep-dive
## Avoiding the OOM killer
- For some workloads (databases and stateful systems), killing
processes because we run out of memory is not acceptable.
- The "oom-notifier" mechanism helps with that.
- When "oom-notifier" is enabled and a hard limit is exceeded:
- all processes in the cgroup are frozen,
- a notification is sent to user space (instead of killing processes),
- user space can then raise limits, migrate containers, etc.,
- once the memory usage is below the hard limit, unfreeze the cgroup.
---
class: extra-details, deep-dive
## Overhead of the memory cgroup
- Each time a process grabs or releases a page, the kernel update counters.
- This adds some overhead.
- Unfortunately, this cannot be enabled/disabled per process.
- It has to be done system-wide, at boot time.
- Also, when multiple groups use the same page:
- only the first group gets "charged",
- but if it stops using it, the "charge" is moved to another group.
---
class: extra-details, deep-dive
## Setting up a limit with the memory cgroup
Create a new memory cgroup:
```bash
$ CG=/sys/fs/cgroup/memory/onehundredmegs
$ sudo mkdir $CG
```
Limit it to approximately 100MB of memory usage:
```bash
$ sudo tee $CG/memory.memsw.limit_in_bytes <<< 100000000
```
Move the current process to that cgroup:
```bash
$ sudo tee $CG/tasks <<< $$
```
The current process *and all its future children* are now limited.
(Confused about `<<<`? Look at the next slide!)
---
class: extra-details, deep-dive
## What's `<<<`?
- This is a "here string". (It is a non-POSIX shell extension.)
- The following commands are equivalent:
```bash
foo <<< hello
```
```bash
echo hello | foo
```
```bash
foo <<EOF
hello
EOF
```
- Why did we use that?
---
class: extra-details, deep-dive
## Writing to cgroups pseudo-files requires root
Instead of:
```bash
sudo tee $CG/tasks <<< $$
```
We could have done:
```bash
sudo sh -c "echo $$ > $CG/tasks"
```
The following commands, however, would be invalid:
```bash
sudo echo $$ > $CG/tasks
```
```bash
sudo -i # (or su)
echo $$ > $CG/tasks
```
---
class: extra-details, deep-dive
## Testing the memory limit
Start the Python interpreter:
```bash
$ python
Python 3.6.4 (default, Jan 5 2018, 02:35:40)
[GCC 7.2.1 20171224] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
Allocate 80 megabytes:
```python
>>> s = "!" * 1000000 * 80
```
Add 20 megabytes more:
```python
>>> t = "!" * 1000000 * 20
Killed
```
---
## Memory cgroup v2: limits
- `memory.min` = hard reservation (guaranteed memory for this cgroup)
- `memory.low` = soft reservation ("*try* not to reclaim memory if we're below this")
- `memory.high` = soft limit (aggressively reclaim memory; don't trigger OOMK)
- `memory.max` = hard limit (triggers OOMK)
- `memory.swap.high` = aggressively reclaim memory when using that much swap
- `memory.swap.max` = prevent using more swap than this
---
## CPU cgroup
- Keeps track of CPU time used by a group of processes.
(This is easier and more accurate than `getrusage` and `/proc`.)
- Keeps track of usage per CPU as well.
(i.e., "this group of process used X seconds of CPU0 and Y seconds of CPU1".)
- Allows setting relative weights used by the scheduler.
---
## Cpuset cgroup
- Pin groups to specific CPU(s).
- Use-case: reserve CPUs for specific apps.
- Warning: make sure that "default" processes aren't using all CPUs!
- CPU pinning can also avoid performance loss due to cache flushes.
- This is also relevant for NUMA systems.
- Provides extra dials and knobs.
(Per zone memory pressure, process migration costs...)
---
## Blkio cgroup
- Keeps track of I/Os for each group:
- per block device
- read vs write
- sync vs async
- Set throttle (limits) for each group:
- per block device
- read vs write
- ops vs bytes
- Set relative weights for each group.
- Note: most writes go through the page cache.
<br/>(So classic writes will appear to be unthrottled at first.)
---
## Net_cls and net_prio cgroup
- Only works for egress (outgoing) traffic.
- Automatically set traffic class or priority
for traffic generated by processes in the group.
- Net_cls will assign traffic to a class.
- Classes have to be matched with tc or iptables, otherwise traffic just flows normally.
- Net_prio will assign traffic to a priority.
- Priorities are used by queuing disciplines.
---
## Devices cgroup
- Controls what the group can do on device nodes
- Permissions include read/write/mknod
- Typical use:
- allow `/dev/{tty,zero,random,null}` ...
- deny everything else
- A few interesting nodes:
- `/dev/net/tun` (network interface manipulation)
- `/dev/fuse` (filesystems in user space)
- `/dev/kvm` (VMs in containers, yay inception!)
- `/dev/dri` (GPU)
---
# Namespaces
- Provide processes with their own view of the system.
@@ -46,6 +472,8 @@ The last item should be done for educational purposes only!
- uts
- ipc
- user
- time
- cgroup
(We are going to detail them individually.)
@@ -619,411 +1047,25 @@ class: extra-details, deep-dive
---
# Control groups
## Time namespace
- Control groups provide resource *metering* and *limiting*.
- Virtualize time
- This covers a number of "usual suspects" like:
- Expose a slower/faster clock to some processes
- memory
(for e.g. simulation purposes)
- CPU
- Expose a clock offset to some processes
- block I/O
- network (with cooperation from iptables/tc)
- And a few exotic ones:
- huge pages (a special way to allocate memory)
- RDMA (resources specific to InfiniBand / remote memory transfer)
(simulation, suspend/restore...)
---
## Crowd control
## Cgroup namespace
- Control groups also allow to group processes for special operations:
- Virtualize access to `/proc/<PID>/cgroup`
- freezer (conceptually similar to a "mass-SIGSTOP/SIGCONT")
- perf_event (gather performance events on multiple processes)
- cpuset (limit or pin processes to specific CPUs)
- There is a "pids" cgroup to limit the number of processes in a given group.
- There is also a "devices" cgroup to control access to device nodes.
(i.e. everything in `/dev`.)
---
## Generalities
- Cgroups form a hierarchy (a tree).
- We can create nodes in that hierarchy.
- We can associate limits to a node.
- We can move a process (or multiple processes) to a node.
- The process (or processes) will then respect these limits.
- We can check the current usage of each node.
- In other words: limits are optional (if we only want accounting).
- When a process is created, it is placed in its parent's groups.
---
## Example
The numbers are PIDs.
The names are the names of our nodes (arbitrarily chosen).
.small[
```bash
cpu memory
├── batch ├── stateless
│ ├── cryptoscam │ ├── 25
│ │ └── 52 │ ├── 26
│ └── ffmpeg │ ├── 27
│ ├── 109 │ ├── 52
│ └── 88 │ ├── 109
└── realtime │ └── 88
├── nginx └── databases
│ ├── 25 ├── 1008
│ ├── 26 └── 524
│ └── 27
├── postgres
│ └── 524
└── redis
└── 1008
```
]
---
class: extra-details, deep-dive
## Cgroups v1 vs v2
- Cgroups v1 are available on all systems (and widely used).
- Cgroups v2 are a huge refactor.
(Development started in Linux 3.10, released in 4.5.)
- Cgroups v2 have a number of differences:
- single hierarchy (instead of one tree per controller),
- processes can only be on leaf nodes (not inner nodes),
- and of course many improvements / refactorings.
---
## Memory cgroup: accounting
- Keeps track of pages used by each group:
- file (read/write/mmap from block devices),
- anonymous (stack, heap, anonymous mmap),
- active (recently accessed),
- inactive (candidate for eviction).
- Each page is "charged" to a group.
- Pages can be shared across multiple groups.
(Example: multiple processes reading from the same files.)
- To view all the counters kept by this cgroup:
```bash
$ cat /sys/fs/cgroup/memory/memory.stat
```
---
## Memory cgroup: limits
- Each group can have (optional) hard and soft limits.
- Limits can be set for different kinds of memory:
- physical memory,
- kernel memory,
- total memory (including swap).
---
## Soft limits and hard limits
- Soft limits are not enforced.
(But they influence reclaim under memory pressure.)
- Hard limits *cannot* be exceeded:
- if a group of processes exceeds a hard limit,
- and if the kernel cannot reclaim any memory,
- then the OOM (out-of-memory) killer is triggered,
- and processes are killed until memory gets below the limit again.
---
class: extra-details, deep-dive
## Avoiding the OOM killer
- For some workloads (databases and stateful systems), killing
processes because we run out of memory is not acceptable.
- The "oom-notifier" mechanism helps with that.
- When "oom-notifier" is enabled and a hard limit is exceeded:
- all processes in the cgroup are frozen,
- a notification is sent to user space (instead of killing processes),
- user space can then raise limits, migrate containers, etc.,
- once the memory usage is below the hard limit, unfreeze the cgroup.
---
class: extra-details, deep-dive
## Overhead of the memory cgroup
- Each time a process grabs or releases a page, the kernel update counters.
- This adds some overhead.
- Unfortunately, this cannot be enabled/disabled per process.
- It has to be done system-wide, at boot time.
- Also, when multiple groups use the same page:
- only the first group gets "charged",
- but if it stops using it, the "charge" is moved to another group.
---
class: extra-details, deep-dive
## Setting up a limit with the memory cgroup
Create a new memory cgroup:
```bash
$ CG=/sys/fs/cgroup/memory/onehundredmegs
$ sudo mkdir $CG
```
Limit it to approximately 100MB of memory usage:
```bash
$ sudo tee $CG/memory.memsw.limit_in_bytes <<< 100000000
```
Move the current process to that cgroup:
```bash
$ sudo tee $CG/tasks <<< $$
```
The current process *and all its future children* are now limited.
(Confused about `<<<`? Look at the next slide!)
---
class: extra-details, deep-dive
## What's `<<<`?
- This is a "here string". (It is a non-POSIX shell extension.)
- The following commands are equivalent:
```bash
foo <<< hello
```
```bash
echo hello | foo
```
```bash
foo <<EOF
hello
EOF
```
- Why did we use that?
---
class: extra-details, deep-dive
## Writing to cgroups pseudo-files requires root
Instead of:
```bash
sudo tee $CG/tasks <<< $$
```
We could have done:
```bash
sudo sh -c "echo $$ > $CG/tasks"
```
The following commands, however, would be invalid:
```bash
sudo echo $$ > $CG/tasks
```
```bash
sudo -i # (or su)
echo $$ > $CG/tasks
```
---
class: extra-details, deep-dive
## Testing the memory limit
Start the Python interpreter:
```bash
$ python
Python 3.6.4 (default, Jan 5 2018, 02:35:40)
[GCC 7.2.1 20171224] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
Allocate 80 megabytes:
```python
>>> s = "!" * 1000000 * 80
```
Add 20 megabytes more:
```python
>>> t = "!" * 1000000 * 20
Killed
```
---
## CPU cgroup
- Keeps track of CPU time used by a group of processes.
(This is easier and more accurate than `getrusage` and `/proc`.)
- Keeps track of usage per CPU as well.
(i.e., "this group of process used X seconds of CPU0 and Y seconds of CPU1".)
- Allows setting relative weights used by the scheduler.
---
## Cpuset cgroup
- Pin groups to specific CPU(s).
- Use-case: reserve CPUs for specific apps.
- Warning: make sure that "default" processes aren't using all CPUs!
- CPU pinning can also avoid performance loss due to cache flushes.
- This is also relevant for NUMA systems.
- Provides extra dials and knobs.
(Per zone memory pressure, process migration costs...)
---
## Blkio cgroup
- Keeps track of I/Os for each group:
- per block device
- read vs write
- sync vs async
- Set throttle (limits) for each group:
- per block device
- read vs write
- ops vs bytes
- Set relative weights for each group.
- Note: most writes go through the page cache.
<br/>(So classic writes will appear to be unthrottled at first.)
---
## Net_cls and net_prio cgroup
- Only works for egress (outgoing) traffic.
- Automatically set traffic class or priority
for traffic generated by processes in the group.
- Net_cls will assign traffic to a class.
- Classes have to be matched with tc or iptables, otherwise traffic just flows normally.
- Net_prio will assign traffic to a priority.
- Priorities are used by queuing disciplines.
---
## Devices cgroup
- Controls what the group can do on device nodes
- Permissions include read/write/mknod
- Typical use:
- allow `/dev/{tty,zero,random,null}` ...
- deny everything else
- A few interesting nodes:
- `/dev/net/tun` (network interface manipulation)
- `/dev/fuse` (filesystems in user space)
- `/dev/kvm` (VMs in containers, yay inception!)
- `/dev/dri` (GPU)
- Lets containerized processes view their relative cgroup tree
---
@@ -1126,8 +1168,8 @@ See `man capabilities` for the full list and details.
???
:EN:Containers internals
:EN:- Linux kernel namespaces
:EN:- Control groups (cgroups)
:EN:- Linux kernel namespaces
:FR:Fonctionnement interne des conteneurs
:FR:- Les namespaces du noyau Linux
:FR:- Les "control groups" (cgroups)
:FR:- Les namespaces du noyau Linux

View File

@@ -109,7 +109,7 @@ class: extra-details
- Example: [ctr.run](https://ctr.run/)
.exercise[
.lab[
- Use ctr.run to automatically build a container image and run it:
```bash

View File

@@ -28,7 +28,7 @@ class: self-paced
- Likewise, it will take more than merely *reading* these slides
to make you an expert
- These slides include *tons* of exercises and examples
- These slides include *tons* of demos, exercises, and examples
- They assume that you have access to a machine running Docker

View File

@@ -0,0 +1,5 @@
## Exercise — Application Configuration
- Configure an application with a ConfigMap
- Generate configuration file from the downward API

View File

@@ -0,0 +1,87 @@
# Exercise — Application Configuration
- We want to configure an application with a ConfigMap
- We will use the "rainbow" example shown previously
(HAProxy load balancing traffic to services in multiple namespaces)
- We won't provide the HAProxy configuration file
- Instead, we will provide a list of namespaces
(e.g. as a space-delimited list in a ConfigMap)
- Our Pod should generate the HAProxy configuration using the ConfigMap
---
## Setup
- Let's say that we have the "rainbow" app deployed:
```bash
kubectl apply -f ~/container.training/k8s/rainbow.yaml
```
- And a ConfigMap like the following one:
```bash
kubectl create configmap rainbow --from-literal=namespaces="blue green"
```
---
## Goal 1
- We want a Deployment and a Service called `rainbow`
- The `rainbow` Service should load balance across Namespaces `blue` and `green`
(i.e. to the Services called `color` in both these Namespaces)
- We want to be able to update the configuration:
- update the ConfigMap to put `blue green red`
- what should we do so that HAproxy picks up the change?
---
## Goal 2
- Check what happens if we specify a backend that doesn't exist
(e.g. add `purple` to the list of namespaces)
- If we specify invalid backends to HAProxy, it won't start!
- Implement a workaround among these two:
- remove invalid backends from the list before starting HAProxy
- wait until all backends are valid before starting HAProxy
---
## Goal 3
- We'd like HAProxy to pick up ConfigMap updates automatically
- How can we do that?
---
## Hints
- Check the following slides if you need help!
--
- We want to generate the HAProxy configuration in an `initContainer`
--
- The `namespaces` entry of the `rainbow` ConfigMap should be exposed to the `initContainer`
--
- The HAProxy configuration should be in a volume shared with HAProxy

View File

@@ -4,8 +4,6 @@
(we will use the `rng` service in the dockercoins app)
- Observe the correct behavior of the readiness probe
- See what happens when the load increses
(when deploying e.g. an invalid image)
- Observe the behavior of the liveness probe
(spoiler alert: it involves timeouts!)

View File

@@ -2,36 +2,85 @@
- We want to add healthchecks to the `rng` service in dockercoins
- First, deploy a new copy of dockercoins
- The `rng` service exhibits an interesting behavior under load:
- Then, add a readiness probe on the `rng` service
*its latency increases (which will cause probes to time out!)*
(using a simple HTTP check on the `/` route of the service)
- We want to see:
- Check what happens when deploying an invalid image for `rng` (e.g. `alpine`)
- what happens when the readiness probe fails
- Then roll back `rng` to the original image and add a liveness probe
- what happens when the liveness probe fails
(with the same parameters)
- Scale up the `worker` service (to 15+ workers) and observe
- What happens, and how can we improve the situation?
- how to set "appropriate" probes and probe parameters
---
## Goal
## Setup
- *Before* adding the readiness probe:
- First, deploy a new copy of dockercoins
updating the image of the `rng` service with `alpine` should break it
(for instance, in a brand new namespace)
- *After* adding the readiness probe:
- Pro tip #1: ping (e.g. with `httping`) the `rng` service at all times
updating the image of the `rng` service with `alpine` shouldn't break it
- it should initially show a few milliseconds latency
- When adding the liveness probe, nothing special should happen
- that will increase when we scale up
- Scaling the `worker` service will then cause disruptions
- it will also let us detect when the service goes "boom"
- The final goal is to understand why, and how to fix it
- Pro tip #2: also keep an eye on the web UI
---
## Readiness
- Add a readiness probe to `rng`
- this requires editing the pod template in the Deployment manifest
- use a simple HTTP check on the `/` route of the service
- keep all other parameters (timeouts, thresholds...) at their default values
- Check what happens when deploying an invalid image for `rng` (e.g. `alpine`)
*(If the probe was set up correctly, the app will continue to work,
because Kubernetes won't switch over the traffic to the `alpine` containers,
because they don't pass the readiness probe.)*
---
## Readiness under load
- Then roll back `rng` to the original image
- Check what happens when we scale up the `worker` Deployment to 15+ workers
(get the latency above 1 second)
*(We should now observe intermittent unavailability of the service, i.e. every
30 seconds it will be unreachable for a bit, then come back, then go away again, etc.)*
---
## Liveness
- Now replace the readiness probe with a liveness probe
- What happens now?
*(At first the behavior looks the same as with the readiness probe:
service becomes unreachable, then reachable again, etc.; but there is
a significant difference behind the scenes. What is it?)*
---
## Readiness and liveness
- Bonus questions!
- What happens if we enable both probes at the same time?
- What strategies can we use so that both probes are useful?

View File

@@ -6,7 +6,7 @@
- the web app itself (dockercoins, NGINX, whatever we want)
- an ingress controller (we suggest Traefik)
- an ingress controller
- a domain name (`use \*.nip.io` or `\*.localdev.me`)
@@ -16,7 +16,7 @@
## Goal
- We want to be able to access the web app using an URL like:
- We want to be able to access the web app using a URL like:
http://webapp.localdev.me
@@ -30,11 +30,13 @@
## Hints
- Traefik can be installed with Helm
- For the ingress controller, we can use:
(it can be found on the Artifact Hub)
- [ingress-nginx](https://github.com/kubernetes/ingress-nginx/blob/main/docs/deploy/index.md)
- If using Kubernetes 1.22+, make sure to use Traefik 2.5+
- the [Traefik Helm chart](https://doc.traefik.io/traefik/getting-started/install-traefik/#use-the-helm-chart)
- the container.training [Traefik DaemonSet](https://raw.githubusercontent.com/jpetazzo/container.training/main/k8s/traefik-v2.yaml)
- If our cluster supports LoadBalancer Services: easy

View File

@@ -1,3 +1,5 @@
⚠️ BROKEN EXERCISE - DO NOT USE
## Exercise — Ingress Secret Policy
*Implement policy to limit impact of ingress controller vulnerabilities.*

View File

@@ -1,3 +1,5 @@
⚠️ BROKEN EXERCISE - DO NOT USE
# Exercise — Ingress Secret Policy
- Most ingress controllers have access to all Secrets

View File

@@ -8,25 +8,37 @@
- We'll use one Deployment for each component
(see next slide for the images to use)
(created with `kubectl create deployment`)
- We'll connect them with Services
- We'll check that we can access the web UI in a browser
(create with `kubectl expose`)
---
## Images
- hasher → `dockercoins/hasher:v0.1`
- We'll use the following images:
- redis → `redis`
- hasher → `dockercoins/hasher:v0.1`
- rng`dockercoins/rng:v0.1`
- redis`redis`
- webui`dockercoins/webui:v0.1`
- rng`dockercoins/rng:v0.1`
- worker`dockercoins/worker:v0.1`
- webui`dockercoins/webui:v0.1`
- worker → `dockercoins/worker:v0.1`
- All services should be internal services, except the web UI
(since we want to be able to connect to the web UI from outside)
---
class: pic
![Dockercoins architecture diagram](images/dockercoins-diagram.png)
---
@@ -34,7 +46,7 @@
- We should be able to see the web UI in our browser
(with the graph showing approximatiely 3-4 hashes/second)
(with the graph showing approximately 3-4 hashes/second)
---
@@ -44,4 +56,4 @@
(check the logs of the worker; they indicate the port numbers)
- The web UI can be exposed with a NodePort Service
- The web UI can be exposed with a NodePort or LoadBalancer Service

View File

@@ -0,0 +1,9 @@
## Exercise — Generating Ingress With Kyverno
- When a Service gets created, automatically generate an Ingress
- Step 1: expose all services with a hard-coded domain name
- Step 2: only expose services that have a port named `http`
- Step 3: configure the domain name with a per-namespace ConfigMap

View File

@@ -0,0 +1,33 @@
# Exercise — Generating Ingress With Kyverno
When a Service gets created...
*(for instance, Service `blue` in Namespace `rainbow`)*
...Automatically generate an Ingress.
*(for instance, with host name `blue.rainbow.MYDOMAIN.COM`)*
---
## Goals
- Step 1: expose all services with a hard-coded domain name
- Step 2: only expose services that have a port named `http`
- Step 3: configure the domain name with a per-namespace ConfigMap
(e.g. `kubectl create configmap ingress-domain-name --from-literal=domain=1.2.3.4.nip.io`)
---
## Hints
- We want to use a Kyverno `generate` ClusterPolicy
- For step 1, check [Generate Resources](https://kyverno.io/docs/writing-policies/generate/) documentation
- For step 2, check [Preconditions](https://kyverno.io/docs/writing-policies/preconditions/) documentation
- For step 3, check [External Data Sources](https://kyverno.io/docs/writing-policies/external-data-sources/) documentation

View File

@@ -0,0 +1,9 @@
## Exercise — Remote Cluster
- Install kubectl locally
- Retrieve the kubeconfig file of our remote cluster
- Deploy dockercoins on that cluster
- Access an internal service without exposing it

View File

@@ -0,0 +1,62 @@
# Exercise — Remote Cluster
- We want to control a remote cluster
- Then we want to run a copy of dockercoins on that cluster
- We want to be able to connect to an internal service
---
## Goal
- Be able to access e.g. hasher, rng, or webui
(without exposing them with a NodePort or LoadBalancer service)
---
## Getting access to the cluster
- If you don't have `kubectl` on your machine, install it
- Download the kubeconfig file from the remote cluster
(you can use `scp` or even copy-paste it)
- If you already have a kubeconfig file on your machine:
- save the remote kubeconfig with another name (e.g. `~/.kube/config.remote`)
- set the `KUBECONFIG` environment variable to point to that file name
- ...or use the `--kubeconfig=...` option with `kubectl`
- Check that you can access the cluster (e.g. `kubectl get nodes`)
---
## If you get an error...
⚠️ The following applies to clusters deployed with `kubeadm`
- If you have a cluster where the nodes are named `node1`, `node2`, etc.
- `kubectl` commands might show connection errors with internal IP addresses
(e.g. 10.10... or 172.17...)
- In that case, you might need to edit the `kubeconfig` file:
- find the server address
- update it to put the *external* address of the first node of the cluster
---
## Deploying an app
- Deploy another copy of dockercoins from your local machine
- Access internal services (e.g. with `kubectl port-forward`)

View File

@@ -0,0 +1,9 @@
## Exercise — Terraform Node Pools
- Write a Terraform configuration to deploy a cluster
- The cluster should have two node pools with autoscaling
- Deploy two apps, each using exclusively one node pool
- Bonus: deploy an app balanced across both node pools

View File

@@ -0,0 +1,69 @@
# Exercise — Terraform Node Pools
- Write a Terraform configuration to deploy a cluster
- The cluster should have two node pools with autoscaling
- Deploy two apps, each using exclusively one node pool
- Bonus: deploy an app balanced across both node pools
---
## Cluster deployment
- Write a Terraform configuration to deploy a cluster
- We want to have two node pools with autoscaling
- Example for sizing:
- 4 GB / 1 CPU per node
- pools of 1 to 4 nodes
---
## Cluster autoscaling
- Deploy an app on the cluster
(you can use `nginx`, `jpetazzo/color`...)
- Set a resource request (e.g. 1 GB RAM)
- Scale up and verify that the autoscaler kicks in
---
## Pool isolation
- We want to deploy two apps
- The first app should be deployed exclusively on the first pool
- The second app should be deployed exclusively on the second pool
- Check the next slide for hints!
---
## Hints
- One solution involves adding a `nodeSelector` to the pod templates
- Another solution involves adding:
- `taints` to the node pools
- matching `tolerations` to the pod templates
---
## Balancing
- Step 1: make sure that the pools are not balanced
- Step 2: deploy a new app, check that it goes to the emptiest pool
- Step 3: update the app so that it balances (as much as possible) between pools

60
slides/find-unmerged-changes.sh Executable file
View File

@@ -0,0 +1,60 @@
#!/bin/sh
# The materials for a given training live in their own branch.
# Sometimes, we write custom content (or simply new content) for a training,
# and that content doesn't get merged back to main. This script tries to
# detect that with the following heuristics:
# - list all remote branches
# - for each remote branch, list the changes that weren't merged into main
# (using "diff main...$BRANCH", three dots)
# - ignore a bunch of training-specific files that change all the time anyway
# - for the remaining files, compute the diff between main and the branch
# (using "diff main..$BRANCH", two dots)
# - ignore changes of less than 10 lines
# - also ignore a few red herrings
# - display whatever is left
# For "git diff" (in the filter function) to work correctly, we must be
# at the root of the repo.
cd $(git rev-parse --show-toplevel)
BRANCHES=$(git branch -r | grep -v origin/HEAD | grep origin/2)
filter() {
threshold=10
while read filename; do
case $filename in
# Generic training-specific files
slides/*.html) continue;;
slides/*.yml) continue;;
slides/logistics*.md) continue;;
# Specific content that can be ignored
#slides/containers/Local_Environment.md) threshold=100;;
# Content that was moved/refactored enough to confuse us
slides/containers/Local_Environment.md) threshold=100;;
slides/exercises.md) continue;;
slides/k8s/batch-jobs) threshold=20;;
# Renames
*/{*}*) continue;;
esac
git diff --find-renames --numstat main..$BRANCH -- "$filename" | {
# If the files are identical, the diff will be empty, and "read" will fail.
read plus minus filename || return
# Ignore binary files (FIXME though?)
if [ $plus = - ]; then
return
fi
diff=$((plus-minus))
if [ $diff -gt $threshold ]; then
echo git diff main..$BRANCH -- $filename
fi
}
done
}
for BRANCH in $BRANCHES; do
if FILES=$(git diff --find-renames --name-only main...$BRANCH | filter | grep .); then
echo "🌳 $BRANCH:"
echo "$FILES"
fi
done

View File

@@ -11,90 +11,96 @@
<body>
<table>
<tr>
<td>Lundi 27 septembre 2021</td>
<td>Mardi 1er février 2022</td>
<td>
<a href="1.yml.html">Docker Intensif</a>
</td>
</tr>
<tr>
<td>Mardi 28 septembre 2021</td>
<td>Mercredi 2 février 2022</td>
<td>
<a href="1.yml.html">Docker Intensif</a>
</td>
</tr>
<tr>
<td>Mercredi 29 septembre 2021</td>
<td>Jeudi 3 février 2022</td>
<td>
<a href="1.yml.html">Docker Intensif</a>
</td>
</tr>
<tr>
<td>Lundi 4 octobre 2021</td>
<td>Vendredi 4 février 2022</td>
<td>
<a href="1.yml.html">Docker Intensif</a>
</td>
</tr>
<tr>
<td>Lundi 7 février 2022 <br/> Mardi 1er mars 2022</td>
<td>
<a href="2.yml.html">Fondamentaux Kubernetes</a>
</td>
</tr>
<tr>
<td>Mardi 5 octobre 2021</td>
<td>Mardi 8 février 2022 <br/> Mercredi 2 mars 2022</td>
<td>
<a href="2.yml.html">Fondamentaux Kubernetes</a>
</td>
</tr>
<tr>
<td>Mercredi 6 octobre 2021</td>
<td>Mercredi 9 février 2022 <br/> Jeudi 3 mars 2022</td>
<td>
<a href="2.yml.html">Fondamentaux Kubernetes</a>
</td>
</tr>
<tr>
<td>Jeudi 7 octobre 2021</td>
<td>Jeudi 10 février 2022 <br/> Vendredi 4 mars 2022</td>
<td>
<a href="2.yml.html">Fondamentaux Kubernetes</a>
</td>
</tr>
<tr>
<td>Lundi 11 octobre 2021</td>
<td>Lundi 7 mars 2022</td>
<td>
<a href="3.yml.html">Packaging d'applications et CI/CD pour Kubernetes</a>
</td>
</tr>
<tr>
<td>Mardi 12 octobre 2021</td>
<td>Mardi 8 mars 2022</td>
<td>
<a href="3.yml.html">Packaging d'applications et CI/CD pour Kubernetes</a>
</td>
</tr>
<td>Lundi 8 novembre 2021</td>
<td>Lundi 14 mars 2022</td>
<td>
<a href="4.yml.html">Kubernetes Avancé</a>
</td>
</tr>
</tr>
<td>Mardi 9 novembre 2021</td>
<td>Mardi 15 mars 2022</td>
<td>
<a href="4.yml.html">Kubernetes Avancé</a>
</td>
</tr>
</tr>
<td>Lundi 15 novembre 2021</td>
<td>Mercredi 16 mars 2022</td>
<td>
<a href="4.yml.html">Kubernetes Avancé</a>
</td>
</tr>
</tr>
<td>Mardi 16 novembre 2021</td>
<td>Jeudi 17 mars 2022</td>
<td>
<a href="4.yml.html">Kubernetes Avancé</a>
</td>
</tr>
<tr>
<td>Jeudi 18 novembre 2021</td>
<td>Lundi 21 mars 2022</td>
<td>
<a href="5.yml.html">Opérer Kubernetes</a>
</td>
</tr>
<tr>
<td>Vendredi 19 novembre 2021</td>
<td>Mardi 22 mars 2022</td>
<td>
<a href="5.yml.html">Opérer Kubernetes</a>
</td>

View File

@@ -7,7 +7,7 @@ chat: "[Slack](https://dockercommunity.slack.com/messages/C7GKACWDV)"
gitrepo: github.com/jpetazzo/container.training
slides: http://container.training/
slides: https://container.training/
#slidenumberprefix: "#SomeHashTag &mdash; "
@@ -56,6 +56,7 @@ content:
- containers/Exercise_Dockerfile_Advanced.md
#- containers/Docker_Machine.md
#- containers/Advanced_Dockerfiles.md
#- containers/Buildkit.md
#- containers/Init_Systems.md
#- containers/Application_Configuration.md
#- containers/Logging.md

View File

@@ -7,7 +7,7 @@ chat: "[Slack](https://dockercommunity.slack.com/messages/C7GKACWDV)"
gitrepo: github.com/jpetazzo/container.training
slides: http://container.training/
slides: https://container.training/
#slidenumberprefix: "#SomeHashTag &mdash; "
@@ -56,6 +56,7 @@ content:
- containers/Exercise_Composefile.md
- containers/Docker_Machine.md
- - containers/Advanced_Dockerfiles.md
- containers/Buildkit.md
- containers/Init_Systems.md
- containers/Application_Configuration.md
- containers/Logging.md

View File

@@ -7,7 +7,7 @@ chat: "[Slack](https://dockercommunity.slack.com/messages/C7GKACWDV)"
gitrepo: github.com/jpetazzo/container.training
slides: http://container.training/
slides: https://container.training/
#slidenumberprefix: "#SomeHashTag &mdash; "
@@ -62,6 +62,7 @@ content:
- containers/Container_Engines.md
- containers/Init_Systems.md
- containers/Advanced_Dockerfiles.md
- containers/Buildkit.md
-
- containers/Application_Configuration.md
- containers/Logging.md

View File

@@ -32,7 +32,7 @@
- You're welcome to use whatever you like (e.g. AWS profiles)
.exercise[
.lab[
- Set the AWS region, API access key, and secret key:
```bash
@@ -58,7 +58,7 @@
- register it in our kubeconfig file
.exercise[
.lab[
- Update our kubeconfig file:
```bash

Some files were not shown because too many files have changed in this diff Show More