Intro
Kubernetes Seccomp (secure computing mode) is a Linux kernel feature that restricts the system calls a container can make. While Seccomp is often associated with security hardening, it can also impact networking capabilities. If a profile blocks or mishandles syscalls related to network operations, your pods may fail to resolve DNS, connect to other services, or accept incoming traffic. This guide provides a practical, step-by-step approach to troubleshooting Seccomp networking issues, including safe configuration methods, verification commands, and recovery procedures.
Version and Environment Inventory
Before making any changes, document your environment. This ensures you can reproduce issues and roll back if needed. Key items to record:
- Kubernetes version:
kubectl version --short(server and client)
Example output:
Client Version: v1.28.2
Server Version: v1.28.2
- Container runtime and version:
crictl versionordocker version(if using Docker)
Example:
crictl version
Version: 0.1.0
RuntimeName: containerd
RuntimeVersion: v1.7.2
- Node OS and kernel:
uname -ron a node (e.g.,5.15.0-91-generic)
- Seccomp support: verify the kubelet has
seccomp-profile-rootconfigured (default is/var/lib/kubelet/seccomp). Check the kubelet config on a node:
cat /var/lib/kubelet/config.yaml | grep -i seccomp
Expected output: seccomp-profile-root: /var/lib/kubelet/seccomp or similar.
- Cluster topology: number of nodes, network plugin (e.g., Calico, Flannel, Cilium), and whether you are using a service mesh (e.g., Istio, Linkerd).
Prerequisites for the commands in this guide:
kubectlconfigured to access your cluster- SSH access to node(s) for runtime-level checks
jqfor parsing JSON output (optional but helpful)
Example environment inventory command:
kubectl get nodes -o wide
Expected output (truncated):
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE
node01 Ready <none> 10d v1.28.2 10.0.0.1 <none> Ubuntu 22.04
Also check the kubelet configuration for Seccomp on a node:
cat /var/lib/kubelet/config.yaml | grep -i seccomp
If the output shows seccomp-profile-root, you are good to go.
Safe Configuration Path
When you suspect Seccomp is causing networking issues, do not immediately apply a broad or restrictive profile. Follow a scoped approach:
1. Start with the Default Profile
Kubernetes has a default Seccomp profile that is usually safe for most workloads. You can enable it per-pod or per-container. For example, to run a pod with the default profile:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: test
image: busybox
command: ["sh", "-c", "sleep 3600"]
Apply with kubectl apply -f pod.yaml.
2. If Default Works, Issue is with Custom Profile
If the default profile works, the issue is likely with a custom profile. If you have a custom profile, compare it with the default. You can extract the default profile from the container runtime. For containerd, it is typically at /var/lib/containerd/io.containerd.runtime.v2.task/default/seccomp.json (path varies). Use crictl info to find the Seccomp profile path:
crictl info | jq '.config.seccomp'
3. Create a Custom Profile that Allows Necessary Network Syscalls
For example, if you need to allow DNS resolution, ensure these syscalls are permitted: socket, connect, sendto, recvfrom, bind, listen, accept, getsockname, getpeername, setsockopt, getsockopt. Note: getaddrinfo is a glibc function, not a syscall; it uses socket, connect, sendto, recvfrom. Start with a permissive profile that logs denials:
{
"defaultAction": "SCMP_ACT_LOG",
"architectures": ["SCMP_ARCH_X86_64"],
"syscalls": [
{
"names": [
"socket", "bind", "connect", "listen", "accept", "accept4",
"sendto", "recvfrom", "sendmsg", "recvmsg", "getsockname",
"getpeername", "setsockopt", "getsockopt", "shutdown"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
Save this as allow-net.json and use it in a pod spec:
apiVersion: v1
kind: Pod
metadata:
name: test-net
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: "profiles/allow-net.json"
containers:
- name: test
image: busybox
command: ["sh", "-c", "sleep 3600"]
Important: You must place the profile file in the Seccomp profile root on the node, typically /var/lib/kubelet/seccomp/profiles/allow-net.json. Ensure the file exists on all nodes where the pod may run.
4. Test with a Simple Connectivity Check
Run a pod with this profile and verify that basic networking works before proceeding.
Verification and Diagnostics
Once your pod is running with a Seccomp profile, perform these checks to confirm networking is working:
1. Check Pod Status and Events
kubectl describe pod test-net | tail -20
Expected: Status: Running and no Seccomp-related events. Look for warnings like Seccomp profile assigned or errors.
2. Execute a DNS Resolution Test
kubectl exec -it test-net -- nslookup kubernetes.default
Expected output includes Address: 10.96.0.1 (or your cluster DNS IP). If it fails with connection timed out or no servers could be reached, check DNS syscalls.
3. Test Outbound Connectivity to an External IP
kubectl exec -it test-net -- wget -O- --timeout=5 http://example.com
Expected: HTTP response. If it hangs, check connect and sendto syscalls.
4. Test Listening on a Port (If Your App Requires It)
kubectl exec -it test-net -- nc -l -p 8080 &
sleep 2
kubectl exec -it test-net -- nc -z localhost 8080
Expected: exit code 0. If it fails, check bind and listen.
5. View Seccomp Logs
If you used SCMP_ACT_LOG as default, the kernel will log denials to dmesg. On the node where your pod runs, execute:
sudo dmesg | grep -i seccomp | tail -20
Look for entries like SECCOMP: pid 1234 ... syscall=42 (connect) indicating blocked syscalls. The syscall number can be mapped using a table (e.g., on x86_64, 42 is connect).
To make this easier, use a tool like strace inside the container (if available) to see which syscalls fail:
kubectl exec -it test-net -- strace -f -e trace=network nslookup kubernetes.default
This will show connect calls and their return values.
Table: Common Network Syscalls and Their Actions
| Syscall | Description | Common Error If Blocked |
|---|---|---|
socket | Create an endpoint for communication | EPERM |
connect | Initiate a connection | EPERM |
bind | Bind a name to a socket | EPERM |
listen | Listen for connections | EPERM |
accept | Accept a connection | EPERM |
sendto | Send a message on a socket | EPERM |
recvfrom | Receive a message from a socket | EPERM |
getsockname | Get socket name | EPERM |
getsockopt | Get socket options | EPERM |
These errors typically appear in application logs or via strace.
Failure Modes and Recovery
Understanding failure modes helps you respond quickly. Here are common issues and how to recover:
1. Profile Too Restrictive
If your custom profile blocks a required syscall, the container may fail to start or crash. Check the pod status:
kubectl get pods
kubectl describe pod <name> | grep -A5 "Events:"
Look for failed to create containerd task: failed to create shim task: ... operation not permitted or similar.
Recovery: Update the profile to allow the missing syscall or switch to RuntimeDefault. Apply the change with kubectl apply or kubectl replace (if the pod is managed by a Deployment, use kubectl rollout restart).
2. Silent Network Failure
The pod runs but cannot connect. Use dmesg to check for Seccomp denials. If you have SCMP_ACT_LOG, the kernel logs will show the offending syscall. If you used SCMP_ACT_ERRNO, you will just get an error code in the app.
Recovery: Temporarily change the profile's default action to SCMP_ACT_LOG to diagnose, then add the needed syscall to the allow list.
3. Profile Path Mismatch
If the profile is not found, the pod will fail with seccomp profile not found. Verify the file is present on the node and the path in the pod spec is correct.
Recovery: Recreate the profile on the node and try again.
4. Rollback Steps
If you applied a Seccomp profile cluster-wide (via PodSecurityPolicy or SecurityContextConstraints), you can revert by removing the policy or resetting the default. For immediate rollback of a specific pod, apply the previous working configuration:
kubectl rollout undo deployment/<name>
Or patch the pod directly (if it's a bare pod):
kubectl patch pod <name> --type='json' -p='[{"op": "replace", "path": "/spec/securityContext/seccompProfile/type", "value": "RuntimeDefault"}]'
Note: Patching a pod directly may not work if the pod is managed by a controller; use kubectl edit on the deployment instead.
After recovery, verify connectivity again with the tests from the previous section.
Operations Checklist
Incorporate these checks into your operational routine to prevent and quickly resolve Seccomp networking issues:
- Document your Seccomp profile for each workload. Store profiles in version control.
- Test profiles in a staging environment before production.
- Monitor Seccomp denials. Use
dmesgor syslog collection to alert on repeated denials. - Regularly review Seccomp logs for unexpected denials that could indicate new network requirements.
- Keep profiles minimal. Only allow the syscalls required by your application.
- When upgrading Kubernetes or container runtime, validate Seccomp behavior as syscall numbers may change.
- Use the
RuntimeDefaultprofile as a baseline unless you have a specific reason to customize. - Include a network connectivity check in your pod readiness probes to catch issues early.
Table: Quick Troubleshooting Checklist
| Symptom | First Command | Possible Cause |
|---|---|---|
| DNS failure | nslookup | connect or sendto blocked |
| Outbound connection timeout | wget | connect blocked |
| Cannot bind a port | nc -l | bind or listen blocked |
| Pod fails to start | kubectl describe pod | Profile not found or syscall denied at startup |
Table: Mapping Syscall Numbers to Names (x86_64)
| Syscall Number | Name |
|---|---|
| 41 | socket |
| 42 | connect |
| 49 | bind |
| 50 | listen |
| 43 | accept |
| 44 | sendto |
| 45 | recvfrom |
| 51 | getsockname |
| 54 | setsockopt |
| 55 | getsockopt |
Conclusion
Troubleshooting Seccomp networking issues in Kubernetes requires a systematic approach: inventory your environment, apply safe configurations, verify with concrete commands, and be prepared to roll back. By using permissive logging profiles and incremental tightening, you can maintain security without compromising network functionality. Always document your profiles and test changes in isolated environments. The commands and tables provided here give you a practical toolkit to diagnose and resolve common networking failures caused by Seccomp, ensuring your applications remain secure and connected.