Manually Accessing the Kubernetes API with a ServiceAccount Using Curl
Accessing the Kubernetes API manually can be a powerful way to interact with your cluster and understand its internals. In this guide, we’ll walk through the process of creating a Pod that uses a specific ServiceAccount and then using curl
to access the Kubernetes API, listing all available secrets.
Step 1: Creating the Pod with a ServiceAccount
First, we need to create a Pod that will use the secret-reader
ServiceAccount in the project-hamster
namespace. We’ll use the curlimages/curl:7.65.3
image for this Pod.
Start by generating the Pod YAML file:
1 2 3 4 5 6 7 |
kubectl run tmp-api-contact \ --image=curlimages/curl:7.65.3 --dry-run=client \ --command -o yaml -- sh -c 'sleep 1d' > e2.yaml |
Edit the e2.yaml
file to include the ServiceAccount and Namespace:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
apiVersion: v1 kind: Pod metadata: name: tmp-api-contact namespace: project-hamster spec: serviceAccountName: secret-reader containers: - name: tmp-api-contact image: curlimages/curl:7.65.3 command: ["sh", "-c", "sleep 1d"] restartPolicy: Always |
Apply the configuration to create the Pod:
1 2 3 |
kubectl apply -f e2.yaml |
Step 2: Executing into the Pod
Now that the Pod is running, we’ll exec into it to manually contact the Kubernetes API:
1 2 3 |
kubectl -n project-hamster exec -it tmp-api-contact -- sh |
Step 3: Manually Contacting the Kubernetes API
Inside the Pod, we can use curl
to interact with the Kubernetes API. The API server is usually accessible via the kubernetes.default
Service in the default
namespace.
Start by trying to access the API:
1 2 3 4 5 6 7 |
curl https://kubernetes.default curl -k https://kubernetes.default # Ignore insecure HTTPS warnings curl -k https://kubernetes.default/api/v1/secrets # Should show Forbidden 403 |
The last command returns a 403 Forbidden error because we haven’t provided any authentication. By default, Kubernetes treats the request as coming from system:anonymous
. We need to use the ServiceAccount token to authenticate.
Step 4: Using the ServiceAccount Token to Authenticate
To authenticate, we’ll use the token associated with the secret-reader
ServiceAccount, which is mounted in the Pod at /var/run/secrets/kubernetes.io/serviceaccount/token
.
1 2 3 4 5 6 |
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) curl -k https://kubernetes.default/api/v1/secrets -H "Authorization: Bearer ${TOKEN}" |
This command should return a list of all secrets in the cluster, confirming that we are now authenticated as the secret-reader
ServiceAccount.
If you want to use the CA certificate for a secure connection, you can use the following command:
1 2 3 4 5 6 |
CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt curl --cacert ${CACERT} https://kubernetes.default/api/v1/secrets -H "Authorization: Bearer ${TOKEN}" |
Step 5: Verifying Permissions
You can also verify whether the secret-reader
ServiceAccount has the necessary permissions using the following command:
1 2 3 |
kubectl auth can-i get secret --as system:serviceaccount:project-hamster:secret-reader |
If the output is yes
, the ServiceAccount has the required permissions to list secrets.
Step 6: Writing the Commands to a Script
Finally, save the commands into a script file for easy reference:
1 2 3 4 5 6 7 |
# /opt/course/e4/list-secrets.sh TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) curl -k https://kubernetes.default/api/v1/secrets -H "Authorization: Bearer ${TOKEN}" |
Conclusion
Manually contacting the Kubernetes API using curl
provides valuable insights into how Kubernetes API authentication works. By following these steps, you can explore and interact with your cluster in a more granular and controlled manner, leveraging ServiceAccounts for secure access.