mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-05-02 21:47:29 +00:00
And also change links from old documentation to docs sub-directory. Fixes #444 Signed-off-by: bin liu <bin@hyper.sh>
247 lines
8.2 KiB
Markdown
247 lines
8.2 KiB
Markdown
# Kata Containers and service mesh for Kubernetes
|
|
|
|
* [Assumptions](#assumptions)
|
|
* [How they work](#how-they-work)
|
|
* [Prerequisites](#prerequisites)
|
|
* [Kata and Kubernetes](#kata-and-kubernetes)
|
|
* [Restrictions](#restrictions)
|
|
* [Install and deploy your service mesh](#install-and-deploy-your-service-mesh)
|
|
* [Service Mesh Istio](#service-mesh-istio)
|
|
* [Service Mesh Linkerd](#service-mesh-linkerd)
|
|
* [Inject your services with sidecars](#inject-your-services-with-sidecars)
|
|
* [Sidecar Istio](#sidecar-istio)
|
|
* [Sidecar Linkerd](#sidecar-linkerd)
|
|
* [Run your services with Kata](#run-your-services-with-kata)
|
|
* [Lower privileges](#lower-privileges)
|
|
* [Add annotations](#add-annotations)
|
|
* [Deploy](#deploy)
|
|
|
|
A service mesh is a way to monitor and control the traffic between
|
|
micro-services running in your Kubernetes cluster. It is a powerful
|
|
tool that you might want to use in combination with the security
|
|
brought by Kata Containers.
|
|
|
|
## Assumptions
|
|
|
|
You are expected to be familiar with concepts such as __pods__,
|
|
__containers__, __control plane__, __data plane__, and __sidecar__.
|
|
|
|
## How they work
|
|
|
|
Istio and Linkerd both rely on the same model, where they run controller
|
|
applications in the control plane, and inject a proxy as a sidecar inside
|
|
the pod running the service. The proxy registers in the control plane as
|
|
a first step, and it constantly sends different sorts of information about
|
|
the service running inside the pod. That information comes from the
|
|
filtering performed when receiving all the traffic initially intended for
|
|
the service. That is how the interaction between the control plane and the
|
|
proxy allows the user to apply load balancing and authentication rules to
|
|
the incoming and outgoing traffic, inside the cluster, and between multiple
|
|
micro-services.
|
|
|
|
This cannot not happen without a good amount of `iptables` rules ensuring
|
|
the packets reach the proxy instead of the expected service. Rules are
|
|
setup through an __init__ container because they have to be there as soon
|
|
as the proxy starts.
|
|
|
|
## Prerequisites
|
|
|
|
### Kata and Kubernetes
|
|
|
|
Follow the [instructions](../install/README.md)
|
|
to get Kata Containers properly installed and configured with Kubernetes.
|
|
You can choose between CRI-O and CRI-containerd, both are supported
|
|
through this document.
|
|
|
|
For both cases, select the workloads as _trusted_ by default. This way,
|
|
your cluster and your service mesh run with `runc`, and only the containers
|
|
you choose to annotate run with Kata Containers.
|
|
|
|
### Restrictions
|
|
|
|
As documented [here](https://github.com/linkerd/linkerd2/issues/982),
|
|
a kernel version between 4.14.22 and 4.14.40 causes a deadlock when
|
|
`getsockopt()` gets called with the `SO_ORIGINAL_DST` option. Unfortunately,
|
|
both service meshes use this system call with this same option from the
|
|
proxy container running inside the VM. This means that you cannot run
|
|
this kernel version range as the guest kernel for Kata if you want your
|
|
service mesh to work.
|
|
|
|
As mentioned when explaining the basic functioning of those service meshes,
|
|
`iptables` are heavily used, and they need to be properly enabled through
|
|
the guest kernel config. If they are not properly enabled, the init container
|
|
is not able to perform a proper setup of the rules.
|
|
|
|
## Install and deploy your service mesh
|
|
|
|
### Service Mesh Istio
|
|
|
|
As a reference, you can follow Istio [instructions](https://istio.io/docs/setup/kubernetes/quick-start/#download-and-prepare-for-the-installation).
|
|
|
|
The following is a summary of what you need to install Istio on your system:
|
|
```
|
|
$ curl -L https://git.io/getLatestIstio | sh -
|
|
$ cd istio-*
|
|
$ export PATH=$PWD/bin:$PATH
|
|
```
|
|
|
|
Now deploy Istio in the control plane of your cluster with the following:
|
|
```
|
|
$ kubectl apply -f install/kubernetes/istio-demo.yaml
|
|
```
|
|
|
|
To verify that the control plane is properly deployed, you can use both of
|
|
the following commands:
|
|
```
|
|
$ kubectl get svc -n istio-system
|
|
$ kubectl get pods -n istio-system -o wide
|
|
```
|
|
|
|
### Service Mesh Linkerd
|
|
|
|
As a reference, follow the Linkerd [instructions](https://linkerd.io/2/getting-started/index.html).
|
|
|
|
The following is a summary of what you need to install Linkerd on your system:
|
|
```
|
|
$ curl https://run.linkerd.io/install | sh
|
|
$ export PATH=$PATH:$HOME/.linkerd/bin
|
|
```
|
|
|
|
Now deploy Linkerd in the control plane of your cluster with the following:
|
|
```
|
|
$ linkerd install | kubectl apply -f -
|
|
```
|
|
|
|
To verify that the control plane is properly deployed, you can use both of
|
|
the following commands:
|
|
```
|
|
$ kubectl get svc -n linkerd
|
|
$ kubectl get pods -n linkerd -o wide
|
|
```
|
|
|
|
## Inject your services with sidecars
|
|
|
|
Once the control plane is running, you need a deployment to define a few
|
|
services that rely on each other. Then, you inject the YAML file with the
|
|
sidecar proxy using the tools provided by each service mesh.
|
|
|
|
If you do not have such a deployment ready, refer to the samples provided
|
|
by each project.
|
|
|
|
### Sidecar Istio
|
|
|
|
Istio provides a [`bookinfo`](https://istio.io/docs/examples/bookinfo/)
|
|
sample, which you can rely on to inject their `envoy` proxy as a
|
|
sidecar.
|
|
|
|
You need to use their tool called `istioctl kube-inject` to inject
|
|
your YAML file. We use their `bookinfo` sample as an example:
|
|
```
|
|
$ istioctl kube-inject -f samples/bookinfo/kube/bookinfo.yaml -o bookinfo-injected.yaml
|
|
```
|
|
|
|
### Sidecar Linkerd
|
|
|
|
Linkerd provides an [`emojivoto`](https://linkerd.io/2/getting-started/index.html)
|
|
sample, which you can rely on to inject their `linkerd` proxy as a
|
|
sidecar.
|
|
|
|
You need to use their tool called `linkerd inject` to inject your YAML
|
|
file. We use their `emojivoto` sample as example:
|
|
```
|
|
$ wget https://raw.githubusercontent.com/runconduit/conduit-examples/master/emojivoto/emojivoto.yml
|
|
$ linkerd inject emojivoto.yml > emojivoto-injected.yaml
|
|
```
|
|
|
|
## Run your services with Kata
|
|
|
|
Now that your service deployment is injected with the appropriate sidecar
|
|
containers, manually edit your deployment to make it work with Kata.
|
|
|
|
### Lower privileges
|
|
|
|
In Kubernetes, the __init__ container is often `privileged` as it needs to
|
|
setup the environment, which often needs some root privileges. In the case
|
|
of those services meshes, all they need is the `NET_ADMIN` capability to
|
|
modify the underlying network rules. Linkerd, by default, does not use
|
|
`privileged` container, but Istio does.
|
|
|
|
Because of the previous reason, if you use Istio you need to switch all
|
|
containers with `privileged: true` to `privileged: false`.
|
|
|
|
### Add annotations
|
|
|
|
There is no difference between Istio and Linkerd in this section. It is
|
|
about which CRI implementation you use.
|
|
|
|
For both CRI-O and CRI-containerd, you have to add an annotation indicating
|
|
the workload for this deployment is not _trusted_, which will trigger
|
|
`kata-runtime` to be called instead of `runc`.
|
|
|
|
__CRI-O:__
|
|
|
|
Add the following annotation for CRI-O
|
|
```yaml
|
|
io.kubernetes.cri-o.TrustedSandbox: "false"
|
|
```
|
|
The following is an example of what your YAML can look like:
|
|
|
|
```yaml
|
|
...
|
|
apiVersion: extensions/v1beta1
|
|
kind: Deployment
|
|
metadata:
|
|
creationTimestamp: null
|
|
name: details-v1
|
|
spec:
|
|
replicas: 1
|
|
strategy: {}
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
io.kubernetes.cri-o.TrustedSandbox: "false"
|
|
sidecar.istio.io/status: '{"version":"55c9e544b52e1d4e45d18a58d0b34ba4b72531e45fb6d1572c77191422556ffc","initContainers":["istio-init"],"containers":["istio-proxy"],"volumes":["istio-envoy","istio-certs"],"imagePullSecrets":null}'
|
|
creationTimestamp: null
|
|
labels:
|
|
app: details
|
|
version: v1
|
|
...
|
|
```
|
|
|
|
__CRI-containerd:__
|
|
|
|
Add the following annotation for CRI-containerd
|
|
```yaml
|
|
io.kubernetes.cri.untrusted-workload: "true"
|
|
```
|
|
The following is an example of what your YAML can look like:
|
|
|
|
```yaml
|
|
...
|
|
apiVersion: extensions/v1beta1
|
|
kind: Deployment
|
|
metadata:
|
|
creationTimestamp: null
|
|
name: details-v1
|
|
spec:
|
|
replicas: 1
|
|
strategy: {}
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
io.kubernetes.cri.untrusted-workload: "true"
|
|
sidecar.istio.io/status: '{"version":"55c9e544b52e1d4e45d18a58d0b34ba4b72531e45fb6d1572c77191422556ffc","initContainers":["istio-init"],"containers":["istio-proxy"],"volumes":["istio-envoy","istio-certs"],"imagePullSecrets":null}'
|
|
creationTimestamp: null
|
|
labels:
|
|
app: details
|
|
version: v1
|
|
...
|
|
```
|
|
|
|
### Deploy
|
|
|
|
Deploy your application by using the following:
|
|
```
|
|
$ kubectl apply -f myapp-injected.yaml
|
|
```
|