How kubernetes is interacting with docker ?
In a few words Container Runtime Interface is the answer to this questions. But we are going a little bit deeper. First of all what is CRI ?
CRI is one of the most mature interface in kubernetes, it’s a bridge between kubelet and container runtime. . Creating such interfaces in k8s it’s a way to shrink codebase by providing only set of rules which selected implementation of interface should fullfill. One of this example is docker, which is used as default CRI in kubelet.
$ kubelet --help
...
--container-runtime string
The container runtime to use. Possible values: 'docker', 'remote', 'rkt(deprecated)'. (default "docker")
...
So more precisely how kubelet is interacting with docker ?
As we seen there is a layer between docker and kubelet called dockershim, it is defined in: dockershim Ok, but how it looks like in real k8s installation deployed by kubespray with k8s version 1.14.3:
# lsof -p $(pgrep kubelet) -i | grep -i docker
kubelet 2539 root 5u unix 0xffff92c54bd96c00 0t0 843182256 /var/run/dockershim.sock type=STREAM
kubelet 2539 root 16u unix 0xffff92c62b970400 0t0 843180363 /var/run/dockershim.sock type=STREAM
kubelet 2539 root 18u unix 0xffff92c54bd95000 0t0 843180365 /var/run/dockershim.sock type=STREAM
so it’s a unix socket, created by kubelet: docker_server.go On a diagram we see that kubelet is talking to dockershim, communication is done by making GRPC requests. GRPC protocol is using Protocol Buffers for serializing data, structure of this data is defined in proto file, proto file for communication with CRI is defined: api.proto for testing we can write simple code, just to list all the images:
package main
import (
"context"
"fmt"
pb "test/src/v1alpha2"
"google.golang.org/grpc"
)
const (
addr = "unix:///var/run/dockershim.sock"
)
func main() {
ctx := context.Background()
newclient, err := NewImageService()
if err != nil {
fmt.Printf("error with client: %v", err)
}
images, err := newclient.ListImages(ctx, &pb.ListImagesRequest{})
if err != nil {
fmt.Printf("error getting images: %v", err)
}
for _, img := range images.Images {
fmt.Println(img.RepoTags)
}
}
func NewImageService() (pb.ImageServiceClient, error) {
conn, err := grpc.Dial(addr, grpc.WithInsecure())
return pb.NewImageServiceClient(conn), err
}
to make it happen I also need to transform proto file into golang code by using tool protoc
. Now it’s proven that GRPC is used to talk with dockershim.
Dockershim is talking to docker using standard docker libraries:
docker_container.go
so using normal docker command we can list all the containers, images, etc.
Interacting kubelet with docker is a longer way, than proposed in
https://kubernetes.io/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/
In the next blog post I will try to swap docker with just simpler containerd.
powered by Hugo and Noteworthy theme