Closed ianlewis closed 5 years ago
I tried to repro this outside of minikube but execing into a gvisor sandbox container using crictl but it seems like crictl doesn't support sandbox annotations anymore? I can't get crictl to pass the untrusted-workload annotation to containerd.
cat <<EOF > sandbox.json
{
"metadata": {
"name": "nginx-sandbox",
"namespace": "default",
"attempt": 1,
"uid": "hdishd83djaidwnduwk28bcsb",
"annotations": {
"io.kubernetes.cri.untrusted-workload": "true"
}
},
"linux": {
},
"log_directory": "/tmp"
}
EOF
cat <<EOF > container.json
{
"metadata": {
"name": "nginx"
},
"image":{
"image": "nginx"
},
"log_path":"nginx.0.log",
"linux": {
}
}
EOF
sudo crictl pull nginx
SANDBOX_ID=$(sudo crictl runp sandbox.json)
CONTAINER_ID=$(sudo crictl create ${SANDBOX_ID} container.json sandbox.json)
sudo crictl start ${CONTAINER_ID}
sudo crictl exec ${CONTAINER_ID} ls
sudo crictl exec -ti ${CONTAINER_ID} /bin/sh
Cleanup:
sudo crictl stop ${CONTAINER_ID}
sudo crictl rm ${CONTAINER_ID}
sudo crictl stopp ${SANDBOX_ID}
sudo crictl rmp ${SANDBOX_ID}
hrm. crictl doesn't seem to send the annotations in the pod create request.
ianlewis@containerd-test:~$ sudo crictl -D runp sandbox.json
DEBU[0000] RunPodSandboxRequest: &RunPodSandboxRequest{Config:&PodSandboxConfig{Metadata:&PodSandboxMetadata{Name:nginx-sandbox,Uid:hdishd83djaidwnduwk28bcsb,Namespace:default,Attempt:1,},Hostname:,LogDirectory:/tmp,DnsConfig:nil,PortMappings:[],Labels:map[string]string{},Annotations:map[string]string{},Linux:&LinuxPodSandboxConfig{CgroupParent:,SecurityContext:nil,Sysctls:map[string]string{},},},RuntimeHandler:,}
DEBU[0002] RunPodSandboxResponse: &RunPodSandboxResponse{PodSandboxId:791d4c30507c5219a50bbe0e75966aec9ec3f766639dcc1612a7e7f765d6d5d8,}
791d4c30507c5219a50bbe0e75966aec9ec3f766639dcc1612a7e7f765d6d5d8
ianlewis@containerd-test:~$ sudo crictl -D create 791d4c30507c5219a50bbe0e75966aec9ec3f766639dcc1612a7e7f765d6d5d8 container.json sandbox.json
DEBU[0000] CreateContainerRequest: &CreateContainerRequest{PodSandboxId:791d4c30507c5219a50bbe0e75966aec9ec3f766639dcc1612a7e7f765d6d5d8,Config:&ContainerConfig{Metadata:&ContainerMetadata{Name:nginx,Attempt:0,},Image:&ImageSpec{Image:nginx,},Command:[],Args:[],WorkingDir:,Envs:[],Mounts:[],Devices:[],Labels:map[string]string{},Annotations:map[string]string{},LogPath:nginx.0.log,Stdin:false,StdinOnce:false,Tty:false,Linux:&LinuxContainerConfig{Resources:nil,SecurityContext:nil,},Windows:nil,},SandboxConfig:&PodSandboxConfig{Metadata:&PodSandboxMetadata{Name:nginx-sandbox,Uid:hdishd83djaidwnduwk28bcsb,Namespace:default,Attempt:1,},Hostname:,LogDirectory:/tmp,DnsConfig:nil,PortMappings:[],Labels:map[string]string{},Annotations:map[string]string{},Linux:&LinuxPodSandboxConfig{CgroupParent:,SecurityContext:nil,Sysctls:map[string]string{},},},}
DEBU[0000] CreateContainerResponse: &CreateContainerResponse{ContainerId:125dd5b7c95e0e6991a9c24aa848c536b0511c73d0b523e6b750ed615c244487,}
125dd5b7c95e0e6991a9c24aa848c536b0511c73d0b523e6b750ed615c244487
ianlewis@containerd-test:~$ sudo crictl --version
crictl version v1.13.0
I realized that annotations isn't part of metadata
cat <<EOF > sandbox.json
{
"metadata": {
"name": "nginx-sandbox",
"namespace": "default",
"attempt": 1,
"uid": "hdishd83djaidwnduwk28bcsb"
},
"annotations": {
"io.kubernetes.cri.untrusted-workload": "true"
},
"linux": {
},
"log_directory": "/tmp"
}
EOF
This should have been fixed by https://github.com/google/gvisor/commit/4cd4b60352bc8a572a0a9482c58564397c49446c.
Does the runsc version in minikube include that fix?
@Random-Liu minikube is using the 2018-12-07 version of runsc so I think that change should be included.
https://github.com/kubernetes/minikube/blob/master/pkg/minikube/constants/constants.go#L285
@Random-Liu Also, the fix you are pointing to is for the pid file, but the minikube issue is for the internal pid file.
I can get the containers to launch in crictl
but I can't repro the issue with exec. It seems to work properly when I use crictl
@Random-Liu Also, the fix you are pointing to is for the pid file, but the minikube issue is for the internal pid file.
It is for the internal pid file. It moves the pid file generation to the end, which makes sure internal pid file is generated before the pid file, and because runsc exec
has a loop to wait for pid file generation, so the internal pid file is guaranteedto be generated before runsc exec
returns.
@Random-Liu Hmm, was the fix not in the 2018-12-07 version of runsc then?
I'll try the latest version of runsc in minikube to see if it fixes the issue but this CL should be included AFAICT
@Random-Liu Ok. I don't totally understand your fix, but I tried using the latest version and I can't repo any more so it looks like you're right. I was deceived by the minikube code https://github.com/kubernetes/minikube/blob/master/pkg/minikube/constants/constants.go#L285. The minikube gvisor addon doesn't seem to be using the 2018-12-07 version of runsc. The docker image that they use references an older version.
$ for m in $(seq -f "%02g" 1 12); do
> for d in $(seq -f "%02g" 1 31); do
> if grep "https://storage.googleapis.com/gvisor/releases/nightly/2018-${m}-${d}/runsc" gvisor-addon; then
> echo "2018-${m}-${d}";
> fi;
> done;
> done;
Binary file gvisor-addon matches
2018-11-08
Found originally in minikube. Original bug: https://github.com/kubernetes/minikube/issues/3446
It looks like gvisor-containerd-shim contains a race condition where it runs runsc to exec a process in the sandbox and immediately tries to read the internal pid for the new container process, but many times runsc hasn't created the pid in time and gvisor-containerd-shim fails to read it.
Relevant error is in exec.go https://github.com/google/gvisor-containerd-shim/blob/ae2250b1dd07fcdb6a2212022b75d63d26966499/pkg/proc/exec.go#L215
Script to set up containerd environment: