Exercise
In this exercise, you’ll install crictl, a command-line interface for CRI-compatible container runtimes. crictl is an handy tool for low-level troubleshooting when kubectl is not sufficient.
- Install crictl on your worker Nodes
Run the following command on each worker. Make sure to select the right architecture.
VERSION="v1.33.0"
ARCH=amd64 # Use arm64 if you run your Multipass cluster on MacOS with ARM processor
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-$ARCH.tar.gz
sudo tar zxvf crictl-$VERSION-linux-$ARCH.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-$ARCH.tar.gz
# Verify the installation
crictl --versionConfigure crictl to connect to the container runtime
List and inspect containers using crictl
Debug a failing pod using crictl commands
Compare crictl output with kubectl output
Clean up test resources
Documentation
https://kubernetes.io/docs/tasks/debug/debug-cluster/crictl/
https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md
Solution
- Install crictl on a worker node
Instructions provided
- Configure crictl to connect to the container runtime
First, check the container runtime socket (containerd in your environment):
sudo crictl config --listThen, verify the configuration:
sudo crictl info- List and inspect containers using crictl
- Listing all Pods, this is similar to
kubectl get podsbut at container runtime level
sudo crictl pods- Listing all containers
sudo crictl ps- Listing all containers including stopped ones
sudo crictl ps -a- Getting detailed information about containers
sudo crictl ps -v- listing images present on the current Node
sudo crictl images- Checking container resources usage
sudo crictl stats --all- Debug a failing Pod using crictl commands
First, create the following Pod from your control plane Node:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: debug-test
namespace: default
spec:
containers:
- name: failing-container
image: busybox:1.37
command: ["/bin/sh"]
args: ["-c", "echo 'Starting...' && sleep 10 && exit 1"]
- name: working-container
image: busybox:1.37
command: ["/bin/sh"]
args: ["-c", "while true; do echo 'Working...'; sleep 30; done"]
restartPolicy: Always
EOFNext, check where the Pod is running:
kubectl get pod debug-test -o wideNext, SSH onto the corresponding worker Node.
Then, use crictl to get the Pod’s details and to troubleshoot the error you’ll find.
- verify the Pod is on the Node
sudo crictl pods | grep debug-test- Get the Pod’s identifier
POD_ID=$(sudo crictl pods --name debug-test -q)- Get detailed pod information
sudo crictl inspectp $POD_ID- List containers in the pod
sudo crictl ps --pod $POD_ID- Get logs from the failing container
FAILING_CONTAINER_ID=$(sudo crictl ps --pod $POD_ID --name failing-container -aq)
sudo crictl logs $FAILING_CONTAINER_IDYou should only see:
Starting...- Get logs with timestamps
sudo crictl logs -t $FAILING_CONTAINER_ID- Follow logs in real-time
sudo crictl logs -f $FAILING_CONTAINER_ID- Inspect the failing container
sudo crictl inspect $FAILING_CONTAINER_ID- Execute commands in the working container
WORKING_CONTAINER_ID=$(sudo crictl ps --pod $POD_ID --name working-container -q)
sudo crictl exec -it $WORKING_CONTAINER_ID /bin/sh- Check container statistics
sudo crictl stats $WORKING_CONTAINER_ID- Compare crictl output with kubectl output
- From control plane (kubectl):
kubectl get pods debug-test -o wide
kubectl describe pod debug-test
kubectl logs debug-test -c failing-container
kubectl exec -it debug-test -c working-container -- /bin/sh- From worker node (crictl):
sudo crictl pods --name debug-test
sudo crictl inspectp $POD_ID
sudo crictl logs $FAILING_CONTAINER_ID
sudo crictl exec -it $WORKING_CONTAINER_ID /bin/shThe key differences between these tools:
- crictl works directly with the container runtime
- crictl shows container runtime IDs vs Kubernetes Pod names
- crictl can access containers even if the kubelet is not responsive
- crictl provides runtime-specific information (cgroup, namespaces, etc.)
- Clean up test resources
Run the Pod deletion command from the control plane Node:
kubectl delete pod debug-testFrom the worker Node, verify the containers and the Pod are gone:
sudo crictl ps --name debug-test
sudo crictl pods --name debug-testYou’ll find below examples of crictl commands for various scenario:
When kubectl is not working, but containers are running:
sudo crictl ps
sudo crictl logs <container-id>When you need to inspect container mounts and volumes:
sudo crictl inspect <container-id> | jq '.status.mounts'When debugging network issues at container level:
sudo crictl inspectp <pod-id> | jq '.status.network'When checking container restart history:
sudo crictl ps -a | grep <container-name>When you need to stop/start containers manually:
sudo crictl stop <container-id>
sudo crictl start <container-id>When debugging image pull issues:
sudo crictl images
sudo crictl pull <image-name>
sudo crictl rmi <image-id>