Cloud Native Essentials Lab
Cloud Native Essentials Lab
Install Docker
1. Run the Docker installer.
Expected output:
shell
# Executing docker install script, commit: e5543d473431b782227f8908005543bb4389b8de
+ sudo -E sh -c apt-get update -qq >/dev/null
+ sudo -E sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -qq apt-transport-https c
...
1 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
newgrp docker
docker version
sha256sum go1.21.3.linux-amd64.tar.gz
echo "1241381b2843fae5a9707eec1f8fb2ef94d827990582c7c7c32f5bdfbfd420c8
go1.21.3.linux-amd64.tar.gz" | sha256sum --check
Expected output:
go1.21.3.linux-amd64.tar.gz: OK shell
2 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
mkdir -p ~/simple-app
import (
"fmt"
"net/http"
"os"
"log"
)
func main() {
logger := log.New(os.Stdout, "http: ", log.LstdFlags)
logger.Printf("Server is starting...")
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
EOF
go run ~/simple-app/main.go
3 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
7.
Open a browser to test the application http://harbor.${vminfo:harbor:public_ip}.sslip.io:8080.
8.
Stop the program from running with ctrl+c
Expected output:
shell
[+] Building 35.1s (10/10) FINISHED
=> [internal] load build definition from Dockerfile
=> => transferring dockerfile: 218B
=> [internal] load .dockerignore
=> => transferring context: 2B
4 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
docker image ls
Expected output:
shell
REPOSITORY TAG IMAGE ID CREATED SIZE
simple-app 0.1 c451b4bdc00a About a minute ago 291MB
5 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Harbor Installation
Expected output:
6 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
sudo vi /etc/docker/daemon.json
{ shell
"insecure-registries" : [ "harbor.${vminfo:harbor:public_ip}.sslip.io" ]
}
To save: esc:wq
3. Restart Docker
7 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Harbor Installation
4. Download the Harbor online installer
wget https://github.com/goharbor/harbor/releases/download/v2.7.3/harbor-online-
installer-v2.7.3.tgz
Expected output
shell
--2023-10-12 18:57:59-- https://github.com/goharbor/harbor/releases/download/v2.7.3/harbor
Resolving github.com (github.com)... 192.30.255.113
Connecting to github.com (github.com)|192.30.255.113|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/5061
--2023-10-12 18:58:00-- https://objects.githubusercontent.com/github-production-release-as
Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.111.133,
Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.111.133
HTTP request sent, awaiting response... 200 OK
Length: 11087 (11K) [application/octet-stream]
Saving to: ‘harbor-online-installer-v2.7.3.tgz’
harbor-online-installer-v2.7.3.tgz 100%[================================================
wget https://github.com/goharbor/harbor/releases/download/v2.7.3/harbor-online-
installer-v2.7.3.tgz.asc
Expected output:
shell
--2023-10-12 18:58:31-- https://github.com/goharbor/harbor/releases/download/v2.7.3/harbor
Resolving github.com (github.com)... 192.30.255.113
Connecting to github.com (github.com)|192.30.255.113|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/5061
--2023-10-12 18:58:31-- https://objects.githubusercontent.com/github-production-release-as
Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.109.133,
Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.109.133
8 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
harbor-online-installer-v2.7.3.tgz.as 100%[================================================
Expected output
Expected output
Expected output
harbor/prepare shell
harbor/LICENSE
9 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
harbor/install.sh
harbor/common.sh
harbor/harbor.yml.tmpl
cp ~/harbor/harbor.yml.tmpl ~/harbor/harbor.yml
10. Update the Harbor yaml file with your Harbor's url
vi ~/harbor/harbor.yml
# https: shell
# https port for harbor, default is 443
# port: 443
# The path of cert and key files for nginx
# certificate: /your/certificate/path
# private_key: /your/private/key/path
To save: esc:wq
Deploy Harbor
12. Run install.sh
sudo ~/harbor/./install.sh
Expected output:
10 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
docker ps
Expected output:
shell
CONTAINER ID IMAGE COMMAND CREATED
bde32f01e01a goharbor/harbor-jobservice:v2.7.3 "/harbor/entrypoint.…" 57 seconds ago
9c08d0ebaff5 goharbor/nginx-photon:v2.7.3 "nginx -g 'daemon of…" 57 seconds ago
14d6a81db604 goharbor/harbor-core:v2.7.3 "/harbor/entrypoint.…" 57 seconds ago
feddcf259078 goharbor/harbor-db:v2.7.3 "/docker-entrypoint.…" 57 seconds ago
5c125bfedb63 goharbor/registry-photon:v2.7.3 "/home/harbor/entryp…" 57 seconds ago
8ec76866659b goharbor/redis-photon:v2.7.3 "redis-server /etc/r…" 57 seconds ago
9f60993c55c9 goharbor/harbor-portal:v2.7.3 "nginx -g 'daemon of…" 57 seconds ago
eaa338023837 goharbor/harbor-registryctl:v2.7.3 "/home/harbor/start.…" 57 seconds ago
98e7c9694a13 goharbor/harbor-log:v2.7.3 "/bin/sh -c /usr/loc…" About a minute
13. Log into Harbor from the Docker client
Use the default admin credentials to login: username: admin password: Harbor12345
Expected output:
shell
11 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Login Succeeded
14.
Access Harbor at http://harbor.${vminfo:harbor:public_ip}.sslip.io Some browsers might show a warning stating
that the Certificate Authority (CA) is unknown. This happens when using a self-signed CA that is not from a
trusted third-party CA. You can import the CA to the browser to remove the warning. You can skip this warning.
Some Chromium based browsers may not show a skip button. If this is the case, just click anywhere on the error
page and type "thisisunsafe" (without quotes). This will force the browser to bypass the warning and accept the
certificate.
15.
Use the default admin credentials: username: admin password: Harbor12345
16.
Create a new project, give it the name cloudnativeessentials , set it for public and use the defaults for
the rest.
Expected output:
shell
The push refers to repository [harbor.34.223.238.124.sslip.io/cloudnativeessentials/simple-
508125c76cbd: Pushed
b678f20984d2: Pushed
518b489031a7: Pushed
19b1389586ed: Pushed
ede2f060dece: Pushed
12 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
fe7d12ddfc65: Pushed
fbc321379a11: Pushed
e51777ae0bce: Pushed
2ef3351afa6d: Pushed
5cc3a4df1251: Pushed
2fa37f2ee66e: Pushed
0.1: digest: sha256:593fca85b1a7782af61eaf78cdea99fabeebcb23d8f64fce5d91f77b120d25c8 size:
3. Go to the Harbor instance and select the cloudnativeessentials project to verify the container image is present
5. Use docker run to pull the simple-app:0.1 container image from your Harbor instance and run a
container
6.
Open a browser to test the application http://harbor.${vminfo:harbor:public_ip}.sslip.io:8080
7.
Stop the simple-app container
cgroups v2
Starting in Kubernetes 1.28, Kubernetes can leverage cgroups v2 for enhanced resource management
13 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
capabilities including swap. If cgroups v1 is used then you would have to disable swap with sudo swapoff
-a and disable swap in /etc/fstab or systemd.swap .
1. Check if cgroups v2 is used.
Expected output:
cgroup2fs shell
3. The modprobe command can add or remove kernel modules. Use modprobe to add the overlay
and br_netfilter kernel modules. The br_netfilter module enables transparent masquerading and
facilitate Virtual Extensible LAN (VxLAN) traffic for communication between Kubernetes pods.
14 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Expected output:
15 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
net.ipv4.ip_forward = 1
* Applying /etc/sysctl.conf ...
6. Verify that the br_netfilter, overlay modules are loaded
Expected output:
Expected output:
Expected output:
net.bridge.bridge-nf-call-iptables = 1 shell
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
8. socat helps redirect traffic within the Kubernetes cluster. Install socat
Expected output:
16 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
8. conntrack helps connection information between Pods and Services. Install conntrack
Expected output:
17 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Install containerd
1. Download the containerd archive from https://github.com/containerd/containerd/releases, verify its
sha256sum, and extract it under /usr/local .
wget https://github.com/containerd/containerd/releases/download/v1.7.7/containerd-
1.7.7-linux-amd64.tar.gz
Expected output:
shell
--2023-10-17 20:08:23-- https://github.com/containerd/containerd/releases/download/v1.7.7/
Resolving github.com (github.com)... 192.30.255.112
Connecting to github.com (github.com)|192.30.255.112|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/4608
--2023-10-17 20:08:24-- https://objects.githubusercontent.com/github-production-release-as
Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.109.133,
Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.109.133
HTTP request sent, awaiting response... 200 OK
Length: 46887113 (45M) [application/octet-stream]
Saving to: ‘containerd-1.7.7-linux-amd64.tar.gz’
18 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
containerd-1.7.7-linux-amd64.tar.gz 100%[================================================
wget https://github.com/containerd/containerd/releases/download/v1.7.7/containerd-
1.7.7-linux-amd64.tar.gz.sha256sum
Expected output:
shell
--2023-10-17 20:08:51-- https://github.com/containerd/containerd/releases/download/v1.7.7/
Resolving github.com (github.com)... 192.30.255.113
Connecting to github.com (github.com)|192.30.255.113|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/4608
--2023-10-17 20:08:51-- https://objects.githubusercontent.com/github-production-release-as
Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133,
Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133
HTTP request sent, awaiting response... 200 OK
Length: 102 [application/octet-stream]
Saving to: ‘containerd-1.7.7-linux-amd64.tar.gz.sha256sum’
containerd-1.7.7-linux-amd64.tar.gz.s 100%[================================================
sha256sum -c containerd-1.7.7-linux-amd64.tar.gz.sha256sum
Expected output:
containerd-1.7.7-linux-amd64.tar.gz: OK shell
Expected output:
bin/ shell
bin/containerd-shim-runc-v1
bin/containerd-stress
bin/containerd-shim-runc-v2
bin/containerd
19 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
bin/containerd-shim
bin/ctr
4. Since we will use systemd to containerd, download the containerd.service unit file.
wget https://github.com/opencontainers/runc/releases/download/v1.1.9/runc.amd64
Expected output:
shell
--2023-10-17 20:15:07-- https://github.com/opencontainers/runc/releases/download/v1.1.9/ru
Resolving github.com (github.com)... 192.30.255.113
Connecting to github.com (github.com)|192.30.255.113|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/3696
--2023-10-17 20:15:08-- https://objects.githubusercontent.com/github-production-release-as
Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.109.133,
Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.109.133
HTTP request sent, awaiting response... 200 OK
Length: 10684992 (10M) [application/octet-stream]
Saving to: ‘runc.amd64’
runc.amd64 100%[================================================
wget https://github.com/opencontainers/runc/releases/download/v1.1.9
/runc.amd64.asc
Expected output:
20 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
shell
--2023-10-17 20:15:45-- https://github.com/opencontainers/runc/releases/download/v1.1.9/ru
Resolving github.com (github.com)... 192.30.255.112
Connecting to github.com (github.com)|192.30.255.112|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/3696
--2023-10-17 20:15:46-- https://objects.githubusercontent.com/github-production-release-as
Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.110.133,
Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.110.133
HTTP request sent, awaiting response... 200 OK
Length: 854 [application/octet-stream]
Saving to: ‘runc.amd64.asc’
runc.amd64.asc 100%[================================================
9. containerd uses a configuration file called config.toml to specify dameon-level options. The
config.toml is located /etc/containerd/config.toml
Generate the default config.toml
Expected output:
disabled_plugins = [] shell
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
state = "/run/containerd"
temp = ""
version = 2
[cgroup]
path = ""
21 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
[debug]
address = ""
format = ""
gid = 0
level = ""
uid = 0
[grpc]
address = "/run/containerd/containerd.sock"
gid = 0
max_recv_message_size = 16777216
max_send_message_size = 16777216
tcp_address = ""
tcp_tls_ca = ""
tcp_tls_cert = ""
tcp_tls_key = ""
uid = 0
[metrics]
address = ""
grpc_histogram = false
[plugins]
[plugins."io.containerd.gc.v1.scheduler"]
deletion_threshold = 0
mutation_threshold = 100
pause_threshold = 0.02
schedule_delay = "0s"
startup_delay = "100ms"
[plugins."io.containerd.grpc.v1.cri"]
cdi_spec_dirs = ["/etc/cdi", "/var/run/cdi"]
device_ownership_from_security_context = false
disable_apparmor = false
disable_cgroup = false
disable_hugetlb_controller = true
disable_proc_mount = false
disable_tcp_service = true
drain_exec_sync_io_timeout = "0s"
enable_cdi = false
enable_selinux = false
enable_tls_streaming = false
enable_unprivileged_icmp = false
enable_unprivileged_ports = false
22 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
ignore_image_defined_volumes = false
image_pull_progress_timeout = "1m0s"
max_concurrent_downloads = 3
max_container_log_line_size = 16384
netns_mounts_under_state_dir = false
restrict_oom_score_adj = false
sandbox_image = "registry.k8s.io/pause:3.8"
selinux_category_range = 1024
stats_collect_period = 10
stream_idle_timeout = "4h0m0s"
stream_server_address = "127.0.0.1"
stream_server_port = "0"
systemd_cgroup = false
tolerate_missing_hugetlb_controller = true
unset_seccomp_profile = ""
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
conf_template = ""
ip_pref = ""
max_conf_num = 1
setup_serially = false
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
disable_snapshot_annotations = true
discard_unpacked_layers = false
ignore_blockio_not_enabled_errors = false
ignore_rdt_not_enabled_errors = false
no_pivot = false
snapshotter = "overlayfs"
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
privileged_without_host_devices_all_devices_allowed = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = ""
23 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
sandbox_mode = ""
snapshotter = ""
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
privileged_without_host_devices_all_devices_allowed = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = "io.containerd.runc.v2"
sandbox_mode = "podsandbox"
snapshotter = ""
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
BinaryName = ""
CriuImagePath = ""
CriuPath = ""
CriuWorkPath = ""
IoGid = 0
IoUid = 0
NoNewKeyring = false
NoPivotRoot = false
Root = ""
ShimCgroup = ""
SystemdCgroup = false
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
privileged_without_host_devices_all_devices_allowed = false
runtime_engine = ""
runtime_path = ""
24 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
runtime_root = ""
runtime_type = ""
sandbox_mode = ""
snapshotter = ""
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options]
[plugins."io.containerd.grpc.v1.cri".image_decryption]
key_model = "node"
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = ""
[plugins."io.containerd.grpc.v1.cri".registry.auths]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.headers]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
tls_cert_file = ""
tls_key_file = ""
[plugins."io.containerd.internal.v1.opt"]
path = "/opt/containerd"
[plugins."io.containerd.internal.v1.restart"]
interval = "10s"
[plugins."io.containerd.internal.v1.tracing"]
sampling_ratio = 1.0
service_name = "containerd"
[plugins."io.containerd.metadata.v1.bolt"]
content_sharing_policy = "shared"
[plugins."io.containerd.monitor.v1.cgroups"]
no_prometheus = false
[plugins."io.containerd.nri.v1.nri"]
disable = true
disable_connections = false
plugin_config_path = "/etc/nri/conf.d"
25 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
plugin_path = "/opt/nri/plugins"
plugin_registration_timeout = "5s"
plugin_request_timeout = "2s"
socket_path = "/var/run/nri/nri.sock"
[plugins."io.containerd.runtime.v1.linux"]
no_shim = false
runtime = "runc"
runtime_root = ""
shim = "containerd-shim"
shim_debug = false
[plugins."io.containerd.runtime.v2.task"]
platforms = ["linux/amd64"]
sched_core = false
[plugins."io.containerd.service.v1.diff-service"]
default = ["walking"]
[plugins."io.containerd.service.v1.tasks-service"]
blockio_config_file = ""
rdt_config_file = ""
[plugins."io.containerd.snapshotter.v1.aufs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.blockfile"]
fs_type = ""
mount_options = []
root_path = ""
scratch_file = ""
[plugins."io.containerd.snapshotter.v1.btrfs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.devmapper"]
async_remove = false
base_image_size = ""
discard_blocks = false
fs_options = ""
fs_type = ""
pool_name = ""
root_path = ""
[plugins."io.containerd.snapshotter.v1.native"]
26 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
root_path = ""
[plugins."io.containerd.snapshotter.v1.overlayfs"]
mount_options = []
root_path = ""
sync_remove = false
upperdir_label = false
[plugins."io.containerd.snapshotter.v1.zfs"]
root_path = ""
[plugins."io.containerd.tracing.processor.v1.otlp"]
endpoint = ""
insecure = false
protocol = ""
[plugins."io.containerd.transfer.v1.local"]
config_path = ""
max_concurrent_downloads = 3
max_concurrent_uploaded_layers = 3
[[plugins."io.containerd.transfer.v1.local".unpack_config]]
differ = ""
platform = "linux/amd64"
snapshotter = "overlayfs"
[proxy_plugins]
[stream_processors]
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar"
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar+gzip"
[timeouts]
27 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
"io.containerd.timeout.bolt.open" = "0s"
"io.containerd.timeout.metrics.shimstats" = "2s"
"io.containerd.timeout.shim.cleanup" = "5s"
"io.containerd.timeout.shim.load" = "5s"
"io.containerd.timeout.shim.shutdown" = "3s"
"io.containerd.timeout.task.state" = "2s"
[ttrpc]
address = ""
gid = 0
uid = 0
10. Set the systemd cgroup driver with runc Set the SystemdCgroup setting to true
CNI installation
CNI plugins are required to implement the Kubernetes network model.
1. Install CNI plugins.
CNI_PLUGINS_VERSION="v1.3.0"
ARCH="amd64"
DEST="/opt/cni/bin"
curl -L "https://github.com/containernetworking/plugins/releases/download
/${CNI_PLUGINS_VERSION}/cni-plugins-linux-${ARCH}-${CNI_PLUGINS_VERSION}.tgz" |
sudo tar -C "$DEST" -xz
Expected output:
28 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
DOWNLOAD_DIR="/usr/local/bin"
CRICTL_VERSION="v1.28.0"
ARCH="amd64"
curl -L "https://github.com/kubernetes-sigs/cri-tools/releases/download
/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-${ARCH}.tar.gz" | sudo tar -C
$DOWNLOAD_DIR -xz
Expected output:
shell
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 22.7M 100 22.7M 0 0 12.9M 0 0:00:01 0:00:01 --:--:-- 40.4M
2. Test crictl
crictl --version
Expected output:
29 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
cd $DOWNLOAD_DIR
sudo curl -L --remote-name-all https://dl.k8s.io/release/${RELEASE}/bin/linux
/${ARCH}/{kubeadm,kubelet}
The 10-kubeadm.conf file is the configuration for how systemd should run the kubelet. Download the 10-
kubeadm.conf file.
Expected output:
30 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
shell
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 138 100 138 0 0 743 0 --:--:-- --:--:-- --:--:-- 745
100 48.4M 100 48.4M 0 0 23.7M 0 0:00:02 0:00:02 --:--:-- 31.7M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 138 100 138 0 0 2432 0 --:--:-- --:--:-- --:--:-- 2464
100 105M 100 105M 0 0 156M 0 --:--:-- --:--:-- --:--:-- 156M
[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=https://kubernetes.io/docs/
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/local/bin/kubelet
Restart=always
StartLimitInterval=0
RestartSec=10
[Install]
WantedBy=multi-user.target
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubel
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating th
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort.
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET
EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/local/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUB
3. Enable and start kubelet
Expected output:
shell
Created symlink /etc/systemd/system/multi-user.target.wants/kubelet.service ! /etc/systemd/
Note: The kubelet is crashlooping while waiting for kubeadm
31 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Install kubectl
kubectl is the Kubernetes cli tool and allows you to run commands against Kubernetes clusters.
1. Download the kubectl binary for the latest release
Expected output:
shell
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 138 100 138 0 0 774 0 --:--:-- --:--:-- --:--:-- 775
100 47.5M 100 47.5M 0 0 48.0M 0 --:--:-- --:--:-- --:--:-- 114M
2. Download the kubectl checksum file
Expected output:
shell
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 138 100 138 0 0 831 0 --:--:-- --:--:-- --:--:-- 836
100 64 100 64 0 0 219 0 --:--:-- --:--:-- --:--:-- 219
3. Validate the kubectl binary with the checksum file
Expected output:
kubectl: OK shell
4. Install kubectl
5. Test kubectl
32 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Expected output:
kubectl cluster-info
Expected output:
shell
E1017 21:31:38.476094 1921 memcache.go:265] couldn't get current server API group list:
E1017 21:31:38.476522 1921 memcache.go:265] couldn't get current server API group list:
E1017 21:31:38.477836 1921 memcache.go:265] couldn't get current server API group list:
E1017 21:31:38.479106 1921 memcache.go:265] couldn't get current server API group list:
E1017 21:31:38.480359 1921 memcache.go:265] couldn't get current server API group list:
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
The connection to the server localhost:8080 was refused - did you specify the right host or
Expected output:
33 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
34 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
Then you can join any number of worker nodes by running the following on each as root:
2. Follow the instructions from the end of kubeadm init , this copies the kubeconfig file to where kubectl
expectes the kubeconfig file to be. The kubeconfig file contains how you will authenticate to the kubernetes
cluster.
mkdir -p $HOME/.kube
kubectl cluster-info
Expected output:
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
4. By default, control plane nodes are tainted Remove the taint on the node
35 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Expected output:
node/${vminfo:kubernetes:hostname} untainted
Expected output:
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-
cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases
/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
Expected output
shell
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 34.5M 100 34.5M 0 0 28.6M 0 0:00:01 0:00:01 --:--:-- 97.0M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 92 100 92 0 0 305 0 --:--:-- --:--:-- --:--:-- 305
cilium-linux-amd64.tar.gz: OK
cilium
36 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
2. Install Cilium into the Kubernetes cluster pointed to by your current kubectl context:
Expected output:
Expected output:
/¯¯\ shell
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Envoy DaemonSet: disabled (using embedded mode)
\__/¯¯\__/ Hubble Relay: disabled
\__/ ClusterMesh: disabled
Expected output:
37 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Kubernetes Basics
With our Kubernetes cluster ready, let's deploy basic Kubernetes resources
Namespace
1. A namespace isolates a group of resources within a Kubernetes cluster. Create a new namespace my-
namespace .
Expected output:
namespace/my-namespace created
Pod
A Pod is the smallest deployable unit in Kubernetes. A Pod can be one or more containers that work together.
2. Use an imperative command to deploy an nginx webserver:
Expected output:
3. Find the Pod's virtual IP and test access to the nginx container.
38 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Expected output:
shell
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE R
nginx 1/1 Running 0 83s <VIP> <hostname> <none> <none>
4. Curl the nginx container on the Virtual IP, the command below is not click-to-run since you have to enter the
Pod's VIP.
Expected output:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
5. Delete the Pod as we will deploy multiple replicas of the same Pod in the next step.
Expected output:
In the next several steps we'll look at how to create resources to scale an application and expose it outside the
Kubernetes cluster.
Deployment
A Deployment is a Kubernetes resource that provides declartive updates at a controlled rate for Pods. This time
you will use a Kubernetes manifest to deploy a Deployment.
6. Create a Kubernetes manifest for a Deployment in the my-namespace namespace for two replicas of Pod
that runs the nginx webserver.
This time give the app=nginx labels to the Deployment and Pods of the Deployment so we can group and
identify the Pods in a later step.
mkdir -p ~/manifests
cat <<EOF > ~/manifests/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
39 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
name: nginx
namespace: my-namespace
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25.3
ports:
- containerPort: 80
EOF
7. Use kubectl apply to apply the configuration from the deployment.yaml manifest.
Expected output:
Expected output:
With 2 replicas of the nginx webserver running, let's expose the Pods of the Deployment to outside of the cluster
40 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Services
A Service abstracts a group of Pods over a network using a label selector identify the Pods to expose.
There are multiple types of Kubernetes Services, we will use the NodePort service to expose the Service on each
Node's IP of a cluster.
By default, a NodePort exposes the Service in the port range of 30000 to 32767.
Expose the Pods of the nginx Deployment to be reachable with your browser.
10. Create a manifest for a Service that uses the Pod's label in the my-namespace namespace.
Expected output:
41 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Helm
Helm is Kubernetes package manager and a CNCF graduated project. Helm helps you manage applications.
Helm charts are the packaging format. A chart are files in a particulary directory structure that describe related
Kubernetes resources.
A chart can be used to deploy something simple like a single Pod with a single container or complex like an
application composed of an HTTP server, database, caches, etc.
Helm charts are stored in Helm repositories.
You will use Helm to install several CNCF graduated projects later in this scenario.
1. Install Helm.
Expected output:
shell
% Total % Received % Xferd
Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 11661 100 11661 0 0 87773 0 --:--:-- --:--:-- --:--:-- 88340
Downloading https://get.helm.sh/helm-v3.13.1-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
2. Verify Helm install.
Expected output:
shell
version.BuildInfo{Version:"v3.13.1", GitCommit:"3547a4b5bf5edb5478ce352e18858d8a552a4110",
Observability: Metrics
There are 3 pillars of observability: metrics, traces, and logs. Some add a fourth pillar, events.
In this tutorial, you will install monitoring and logging solutions. Let's start with monitoring.
42 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Prometheus stores and collects metrics as time series data. Prometheus is a monitoring and alerting toolkit and is
a CNCF graduated project.
There are multiple ways to install Prometheus. For this tutorial, we will install Prometheus via Helm.
The kube-prometheus-stack is a community-maintained helm chart that is a "batteries-included" chart that
includes the following:
• Prometheus Operator
• Prometheus with Prometheus rules
• Alertmanager
• Prometheus node-exporter
• Prometheus Adapter for Kubernetes Metrics APIs
• kube-state-metrics
• Grafana with dashboards
1. Add the Prometheus community helm repository.
Expected output:
Expected output:
Hang tight while we grab the latest from your chart repositories... shell
...Successfully got an update from the "prometheus-community" chart repository
Update Complete. ⎈Happy Helming!⎈
3. Use helm to install the kube-prometheus-stack
43 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
--set prometheus-node-exporter.namespaceOverride=kube-prometheus-stack
Expected output:
Expected output:
shell
NAME READY STATUS RESTARTS AG
kube-prometheus-stack-kube-state-metrics-6bdd78dc74-4frg8 1/1 Running 0 44
kube-prometheus-stack-operator-67bc68d75-h8z5d 1/1 Running 0 44
kube-prometheus-stack-prometheus-node-exporter-nhpzn 1/1 Running 0 44
5. Kubernetes Services expose applications. A Service type of NodePort exposes Services at each Kubernetes
nodes' IP at a static port from 30000 to 32767. Check the services
Expected output:
shell
NAME TYPE CLUSTER-IP EXTERNAL-IP
alertmanager-operated ClusterIP None <none>
kube-prometheus-stack-alertmanager NodePort 10.102.162.47 <none>
kube-prometheus-stack-grafana NodePort 10.110.209.69 <none>
kube-prometheus-stack-kube-state-metrics ClusterIP 10.107.28.248 <none>
kube-prometheus-stack-operator NodePort 10.111.61.81 <none>
kube-prometheus-stack-prometheus NodePort 10.96.184.91 <none>
kube-prometheus-stack-prometheus-node-exporter ClusterIP 10.97.91.228 <none>
prometheus-operated ClusterIP None <none>
6.
44 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Logging
You can gather logs from containers with the kubectl -n <namespace> logs <pod name> -c
<container name if multiple containers in pod> command.
An application may use multiple containers and it'll be difficult to obtain logs through single containers. A tool to
collect logs of an application will simplify log collection.
Fluentd is an open source log aggregator, collector, processor written in Ruby and is a CNCF graduated project.
Fluent Bit is an open source log aggregator, collector, processor, forwarder written in C. Fluent Bit is a CNCF
graduated sub-project under the umbrella of Fluentd.
Both Fluentd and Fluent Bit use plugins to integrate with data sources and data outputs.
Fluent Bit excels in highly distributed environment and has a smaller footprint than FluentD ~450kb vs ~40MB of
memory. Both were developed by Treasure Data.
Fluent Bit is not as flexible as Fluentd. Fluent Bit has about 45 plugins versus Fluentd has about 700 plugins.
Fluent Bit has native support for environmental metric collection.
The use of both Fluent Bit and Fluentd optimizes resource consumption on the nodes with Fluent Bit's smaller
footprint and optimizes the flexibilty of Fluentd with more than 700 plugins available.
For this tutorial, we'll use Fluentd to collect logs
45 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Expected output:
Expected output:
Elasticsearch will take a few minutes to be at a ready state/ You can check the status of the Elasticsearch pod
with kubectl get pods
46 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Expected output:
Expected output:
Expected output:
Expected output:
47 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Expected output:
fluentd
5. Create the required ServiceAccount, ClusterRole, ClusterRoleBinding for fluentd.
48 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: fluentd
roleRef:
kind: ClusterRole
name: fluentd
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: fluentd
namespace: kube-system
EOF
Expected output:
49 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
labels:
k8s-app: fluentd-logging
version: v1
spec:
serviceAccount: fluentd
serviceAccountName: fluentd
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:elasticsearch
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch-master.elk.svc.cluster.local"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
- name: FLUENT_ELASTICSEARCH_SCHEME
value: "http"
- name: FLUENT_UID
value: "0"
# X-Pack Authentication
# =====================
- name: FLUENT_ELASTICSEARCH_USER
value: "elastic"
- name: FLUENT_ELASTICSEARCH_PASSWORD
value: "changeme"
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
50 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
EOF
Expected output:
9. Navigate to the kibana UI > Management > Index Management to see a new Logstash index generated by the
fluentd DaemonSet.
Expected output:
51 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
Expected output:
Constraint Framework
A Constraint is the declaration of a policy. For example, if you require each resource in a specific namespace
requires a key label.
Before you can use Constraints, you must have a Constraint Template. The Constraint Template defines the input
parameters and the rego that defines and enforces a policy.
3. Create a Constraint Template that requires an app label.
52 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
Expected output:
4. Create a Constraint that enforces the ConstraintTemplate to require a label. Specify this policy for Namespaces
with the label owner . Note this is a dry-run.
53 of 54 11/5/23, 11:10 PM
HobbyFarm Learn https://lab.cloudnativeessentials.com/scenario/git-maintained-cloud-nati...
kind: Namespace
metadata:
name: new-namespace
labels:
owner: you
EOF
Expected output:
Expected output:
shell
Error from server (Forbidden): error when creating "STDIN": admission webhook "validation.g
54 of 54 11/5/23, 11:10 PM