- Requirements
- Install containerd with CRI plugin enabled
- Install Kata Containers
- Install Kubernetes
- Configure containerd to use Kata Containers
- Configure Kubelet to use containerd
- Configure proxy - OPTIONAL
- Start Kubernetes
- Install a Pod Network
- Allow pods to run in the master node
- Create an unstrusted pod using Kata Containers
- Delete created pod
This document describes how to set up a single-machine Kubernetes (k8s) cluster.
The Kubernetes cluster will use the CRI containerd plugin and Kata Containers to launch untrusted workloads.
- Kubernetes, kubelet, kubeadm
- cri-containerd
- Kata Containers
Note: For information about the supported versions of these components, see the Kata Containers versions.yaml file.
-
Follow the instructions from the CRI installation guide.
-
Check if
containerd
is now available$ command -v containerd
Follow the instructions to install Kata Containers.
-
Follow the instructions for kubeadm installation.
-
Check
kubeadm
is now available$ command -v kubeadm
The CRI containerd
plugin supports configuration for two runtime types.
-
Default runtime:
A runtime that is used by default to run workloads.
-
Untrusted workload runtime:
A runtime that will be used to run untrusted workloads. This is appropriate for workloads that require a higher degree of security isolation.
Configure containerd
to use the Kata runtime to run untrusted workloads by
setting the plugins.cri.containerd.untrusted_workload_runtime
config option:
$ sudo mkdir -p /etc/containerd/
$ cat << EOT | sudo tee /etc/containerd/config.toml
[plugins]
[plugins.cri.containerd]
[plugins.cri.containerd.untrusted_workload_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/bin/kata-runtime"
EOT
Note: Unless configured otherwise, the default runtime is set to
runc
.
In order to allow kubelet to use containerd (using the CRI interface), configure the service to point to the containerd
socket.
-
Configure Kubernetes to use
containerd
$ sudo mkdir -p /etc/systemd/system/kubelet.service.d/ $ cat << EOF | sudo tee /etc/systemd/system/kubelet.service.d/0-containerd.conf [Service] Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --runtime-request-timeout=15m --container-runtime-endpoint=unix:///run/containerd/containerd.sock" EOF
-
Inform systemd about the new configuration
$ sudo systemctl daemon-reload
If you are behind a proxy, use the following script to configure your proxy for docker, kubelet, and containerd:
$ services="
kubelet
containerd
docker
"
$ for service in ${services}; do
service_dir="/etc/systemd/system/${service}.service.d/"
sudo mkdir -p ${service_dir}
cat << EOT | sudo tee "${service_dir}/proxy.conf"
[Service]
Environment="HTTP_PROXY=${http_proxy}"
Environment="HTTPS_PROXY=${https_proxy}"
Environment="NO_PROXY=${no_proxy}"
EOT
done
$ sudo systemctl daemon-reload
-
Make sure
containerd
is up and running$ sudo systemctl restart containerd $ sudo systemctl status containerd
-
Prevent conflicts between
docker
iptables (packet filtering) rules and k8s pod communicationIf Docker is installed on the node, it is necessary to modify the rule below. See kubernetes/kubernetes#40182 for further details.
$ sudo iptables -P FORWARD ACCEPT
-
Start cluster using
kubeadm
$ sudo kubeadm init --skip-preflight-checks --cri-socket /run/containerd/containerd.sock --pod-network-cidr=10.244.0.0/16 $ export KUBECONFIG=/etc/kubernetes/admin.conf $ sudo -E kubectl get nodes $ sudo -E kubectl get pods
A pod network plugin is needed to allow pods to communicate with each other.
-
Install the
flannel
plugin by following the Using kubeadm to Create a Cluster guide, starting from the Installing a pod network section. -
Create a pod network using flannel
Note: There is no known way to determine programmatically the best version (commit) to use. See flannel-io/flannel#995.
$ sudo -E kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
-
Wait for the pod network to become available
# number of seconds to wait for pod network to become available $ timeout_dns=420 $ while [ "$timeout_dns" -gt 0 ]; do if sudo -E kubectl get pods --all-namespaces | grep dns | grep Running; then break fi sleep 1s ((timeout_dns--)) done
-
Check the pod network is running
$ sudo -E kubectl get pods --all-namespaces | grep dns | grep Running && echo "OK" || ( echo "FAIL" && false )
By default, the cluster will not schedule pods in the master node. To enable master node scheduling:
$ sudo -E kubectl taint nodes --all node-role.kubernetes.io/master-
By default, all pods are created with the default runtime configured in CRI containerd plugin.
If a pod has the io.kubernetes.cri.untrusted-workload
annotation set to "true"
, the CRI plugin runs the pod with the
Kata Containers runtime.
-
Create an untrusted pod configuration
$ cat << EOT | tee nginx-untrusted.yaml apiVersion: v1 kind: Pod metadata: name: nginx-untrusted annotations: io.kubernetes.cri.untrusted-workload: "true" spec: containers: - name: nginx image: nginx EOT
-
Create an untrusted pod
$ sudo -E kubectl apply -f nginx-untrusted.yaml
-
Check pod is running
$ sudo -E kubectl get pods
-
Check hypervisor is running
$ ps aux | grep qemu
$ sudo -E kubectl delete -f nginx-untrusted.yaml