Intro
Certificate Signing Requests (CSRs) are a critical part of Kubernetes security, enabling nodes, services, and users to obtain signed certificates from the cluster's certificate authority. When a CSR fails to be approved, or a certificate cannot be issued, the root cause often lies in networking: the API server may be unreachable, DNS resolution may fail, or a required port may be blocked. This guide provides a practical, step-by-step approach to troubleshoot Kubernetes CSR networking issues. You will learn how to gather information about your cluster, verify connectivity, diagnose common failure modes, and recover from them.
This article is aimed at Kubernetes administrators, DevOps engineers, and developers who manage clusters and need to resolve CSR-related problems quickly. We focus on the networking aspects: DNS, ports, connectivity, and the tools to diagnose them. By following the structured workflow presented here, you can move from an observed symptom to a verified resolution, minimizing downtime and ensuring the security of your cluster.
The goal is operational safety: observe before changing, limit the blast radius, use placeholders instead of secrets, verify results, and document recovery procedures.
Version and Environment Inventory
Before troubleshooting any CSR networking issue, you must understand your cluster's version and environment. Different Kubernetes versions may have different CSR APIs and networking behaviors. For example, the certificates.k8s.io/v1 API is stable since v1.19, while older versions may use v1beta1. Knowing your version helps you choose the right commands and interpret outputs.
Start by identifying the version of your Kubernetes cluster and the components involved.
Gather Cluster Information
Run the following commands to get an overview of your cluster:
kubectl version --short
kubectl cluster-info
Example output:
Client Version: v1.27.3
Kustomize Version: v5.0.1
Server Version: v1.27.3
Note the server version; if it is older than v1.19, you may need to use certificates.k8s.io/v1beta1 for CSR objects.
Check the nodes and their status:
kubectl get nodes -o wide
This shows node names, status, roles, versions, and internal/external IPs. If any node is NotReady, CSR approval might be delayed because the kubelet cannot reach the API server.
Check CSR API Availability
Ensure that the CSR API is enabled and accessible. You can list existing CSRs:
kubectl get csr
If you get an error like the server doesn't have a resource type "csr", the API may be disabled or you lack permissions.
Verify Prerequisites
Make sure you have the necessary permissions to manage CSRs. For example, to approve a CSR, you need the certificates.k8s.io permissions. Check your access:
kubectl auth can-i create certificatesigningrequests/approval
kubectl auth can-i get certificatesigningrequests
If you get no, ask your cluster administrator to grant you the appropriate roles.
Understand the Topology
Determine where the CSR signer components run. In a typical cluster, the controller manager (kube-controller-manager) includes the CSR approver and signer. Check if it is running:
kubectl get pods -n kube-system | grep controller-manager
If the controller manager pod is missing or crashing, CSRs will not be processed. Use kubectl describe pod and kubectl logs to diagnose.
Example: A Node Bootstrap CSR Issue
Imagine a new node fails to join the cluster and its kubelet log shows:
Failed to create CSR: Post "https://api.example.com:6443/apis/certificates.k8s.io/v1/certificatesigningrequests": dial tcp 10.0.0.10:6443: connect: no route to host
This indicates a networking problem: the node cannot reach the API server. We will address such issues in later sections.
Safe Configuration Path
When modifying configuration to fix CSR networking, follow a safe path: make small, reversible changes, and always verify before and after. This section outlines the key configuration areas that affect CSR networking.
API Server Endpoint Configuration
Nodes and clients must know the correct API server address. This is often specified in kubeconfig files or kubelet configuration.
Check the kubelet's configuration on a node:
cat /var/lib/kubelet/config.yaml
Look for the server field under cluster in the kubeconfig or the --kubeconfig flag. Ensure the address is correct and reachable from the node.
If the API server is behind a load balancer, verify that the load balancer forwards traffic to the API server port (default 6443) and that health checks pass.
DNS Configuration
Nodes must resolve the API server hostname. Check the DNS settings in /etc/resolv.conf on each node. For clusters using CoreDNS, ensure that the DNS service is running and properly configured.
Test DNS resolution from a node:
nslookup api.example.com
Example expected output:
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: api.example.com
Address: 10.0.0.10
If resolution fails, check CoreDNS pods:
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns
Network Policies and Firewalls
Network policies can inadvertently block traffic to the API server or between components. Review any NetworkPolicies that may affect the kubelet or controller manager.
List network policies:
kubectl get networkpolicies --all-namespaces
If you suspect a policy is blocking traffic, you can temporarily delete it (after backing up) to test. But first, examine its rules:
kubectl describe networkpolicy <name> -n <namespace>
Also, check cloud provider security groups or firewall rules. Ensure that port 6443 is open for nodes and clients, and that internal traffic between control plane components is allowed.
Certificate Signing Request Signer Configuration
The controller manager must be configured with the correct signer flags. Check the controller manager pod spec or configuration file.
For example, in a kubeadm cluster, the controller manager may have these flags:
--cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
--cluster-signing-key-file=/etc/kubernetes/pki/ca.key
If these files are missing or corrupted, CSRs cannot be signed. Verify that the files exist and are readable.
Applying Changes Safely
When changing configuration, follow these steps:
- Backup the current configuration file or resource.
- Apply the change to a single component or node.
- Verify the effect using the appropriate check.
- If successful, roll out to other components if necessary.
- If unsuccessful, revert to the backup immediately.
For example, to update the kubelet's kubeconfig, you might edit the file and restart the kubelet:
sudo systemctl restart kubelet
Then check its status:
sudo systemctl status kubelet
Verification and Diagnostics
After configuring or observing a problem, you need to systematically verify connectivity and diagnose issues. This section provides a set of commands and procedures.
Basic Connectivity Checks from Nodes
From a node, test connectivity to the API server using curl or nc.
curl -k https://api.example.com:6443/healthz
Expected output: ok if healthy.
If curl is not available, use nc:
nc -zv api.example.com 6443
A successful connection shows:
Connection to api.example.com 6443 port [tcp/*] succeeded!
If the connection fails, check routing:
ip route
Ensure there is a route to the API server network. Also check if the port is open locally with ss:
ss -tuln | grep 6443
Checking Kubernetes DNS
If pods are having trouble resolving service names, check CoreDNS logs for errors.
Get CoreDNS pod names:
kubectl get pods -n kube-system -l k8s-app=kube-dns -o name
View logs:
kubectl logs -n kube-system <coredns-pod>
Look for errors like SERVFAIL or i/o timeout. Also, test DNS resolution from within a pod:
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default
Expected output includes the service IP.
Inspecting CSRs
List CSRs and examine their status:
kubectl get csr
kubectl describe csr <csr-name>
In the describe output, check the Conditions field. If the CSR is pending, it may be waiting for approval. If it is approved but not issued, the signer may be failing.
Check CSR details including the requested usages and signer name:
kubectl get csr <csr-name> -o yaml
Verifying Controller Manager Logs
The controller manager logs often contain errors related to CSR signing. Fetch logs:
kubectl logs -n kube-system <controller-manager-pod> | grep -i csr
Look for messages like failed to sign CSR or certificate signing error.
Using Network Tracing Tools
For deeper diagnosis, you can use tcpdump on nodes to capture traffic to the API server.
sudo tcpdump -i any port 6443 -w /tmp/api-traffic.pcap
Then analyze with Wireshark if needed.
Example: Diagnosing a CSR Approval Delay
Suppose a CSR remains in Pending state even after approval. Check the controller manager logs and see:
E0120 10:00:00.123456 1 certificate_manager.go:562] kubernetes.io/kube-apiserver-client-kubelet: Failed while requesting a signed certificate from the cluster: cannot create certificate signing request: Post "https://api.example.com:6443/apis/certificates.k8s.io/v1/certificatesigningrequests": dial tcp: i/o timeout
This indicates the controller manager cannot reach the API server. Proceed to check connectivity from the controller manager pod's node to the API server, as described earlier.
Failure Modes and Recovery
CSR networking can fail in several ways. This section describes common failure modes and how to recover from them.
Failure Mode 1: API Server Unreachable
Symptoms: Nodes cannot create CSRs, clients get connection refused or timeout errors, and kubectl commands hang.
Possible Causes:
- API server pod not running.
- Network misconfiguration, firewall rules, or network policies blocking port 6443.
- Load balancer misconfiguration.
Recovery Steps:
- Check if the API server pod is running:
kubectl get pods -n kube-system | grep kube-apiserver
- If not running, inspect why (describe, logs).
- Check firewall rules: ensure port 6443 is open.
- Test connectivity from a node using
curl -k https://<api-server>:6443/healthz. - If using a load balancer, verify its configuration and backend health.
Failure Mode 2: DNS Resolution Failure
Symptoms: Nodes cannot resolve api.example.com, CSR creation fails with no such host.
Possible Causes:
- CoreDNS not running or misconfigured.
- Node's
/etc/resolv.confpoints to incorrect DNS server. - Network policy blocking DNS traffic (UDP/TCP port 53).
Recovery Steps:
- Check CoreDNS pods:
kubectl get pods -n kube-system -l k8s-app=kube-dns
- Test DNS from a node:
nslookup api.example.com. - Check
/etc/resolv.conf; ensure it includes the cluster DNS IP (usually 10.96.0.10). - Review network policies for DNS.
Failure Mode 3: CSR Stuck in Pending
Symptoms: CSR exists but never gets approved or signed.
Possible Causes:
- No approver configured (e.g., no controller manager CSR approver).
- Signer not configured or missing CA files.
- Permissions insufficient.
Recovery Steps:
- Check controller manager flags for
--cluster-signing-cert-fileand--cluster-signing-key-file. - Ensure the CSR approver is running and not crashing.
- Manually approve if appropriate:
kubectl certificate approve <csr-name>
- If the CSR is signed but certificate not issued, check controller manager logs for errors.
Failure Mode 4: Certificate Not Trusted
Symptoms: After CSR is approved and signed, clients reject the certificate.
Possible Causes:
- Wrong CA used to sign.
- Certificate lacks required usages or SANs.
Recovery Steps:
- Verify the certificate details:
kubectl get csr <csr-name> -o jsonpath='{.status.certificate}' | base64 -d | openssl x509 -text -noout
- Check that the signer is the correct cluster CA.
- If necessary, recreate the CSR with correct usages and SANs.
Recovery Documentation
Always document the failure mode, steps taken, and verification. This helps in future incidents and for audit compliance.
Operations Checklist
This checklist summarizes the steps for troubleshooting CSR networking issues. Use it as a quick reference during incidents.
| Step | Action | Command/Signal | Expected Result |
|---|---|---|---|
| 1 | Verify cluster version | kubectl version --short | Server version >=1.19 for v1 CSR API |
| 2 | Check CSR API availability | kubectl get csr | No error, list appears |
| 3 | Check nodes status | kubectl get nodes | All nodes Ready |
| 4 | Test API server connectivity | curl -k https://<api-server>:6443/healthz | ok |
| 5 | Test DNS resolution | nslookup api.example.com | Correct IP returned |
| 6 | Check CoreDNS logs | kubectl logs -n kube-system -l k8s-app=kube-dns | No SERVFAIL errors |
| 7 | Inspect pending CSRs | kubectl describe csr <csr-name> | Conditions show Pending |
| 8 | Check controller manager logs | kubectl logs -n kube-system <controller-manager-pod> | grep -i csr | No signing errors |
| 9 | Verify signer configuration | Check controller manager flags for CA files | Flags present and files exist |
| 10 | Manual approval test | kubectl certificate approve <csr-name> | CSR becomes Approved,Issued |
Conclusion
Troubleshooting Kubernetes CSR networking requires a systematic approach: understand your environment, verify connectivity, diagnose failures, and apply safe fixes. By following the steps in this guide—using concrete commands and examples—you can resolve issues efficiently. Remember to always observe before changing, limit the blast radius, protect sensitive data, and document your recovery procedures. With these practices, you can maintain a secure and reliable Kubernetes cluster. Continue to build your troubleshooting skills by practicing in a test environment and keeping your knowledge up to date with Kubernetes releases.