Understanding TLS Certificates, Authentication & Authorization - CKA


Certificates at Different Level
In the previous blog, we discussed how SSL/TLS certificates work. In brief, the server requests a certificate from a Certificate Authority (CA), the CA issues the certificate, and then the server presents this certificate to the client. The client validates the certificate, and a secure connection is established. This same concept is used in Kubernetes to secure connections between the user and the cluster using TLS certificates. Let’s dive deeper into this with a hands-on example.
TLS Certificates in cluster
In the diagram above, we see one master node and three worker nodes. There is also an external user who wants to interact with the kube-apiserver
on the master node. In this scenario, the user acts as the client, and the master node acts as the server. When the master node interacts with the worker nodes, the roles reverse, with the master node becoming the client and the worker nodes becoming the servers. These connections must be secured, and we achieve this by using TLS certificates, which work the same way as described in the earlier section.
In the diagram, you can see that each component in the cluster and the user has both a public certificate and a private key.
Understanding the Difference: Certificate vs. Private Key
Before proceeding with the hands-on example, it's crucial to understand how to distinguish between a certificate and a private key:
Certificate: If the file has a
.crt
or.pem
extension, it is likely a public certificate.Private Key: If the file name includes the keyword
key
or has a.key
extension, it is a private key.
Issuing a Certificate for a New User
Let’s say a new user, "harshit", has joined the team and needs access to the Kubernetes cluster. To do this, we need to issue a certificate for the user.
Create a Private Key:
The first step is to generate a private key for the user:
openssl genrsa -out harshit.key 2048
Now, the user (harshit) has their private key.
Generate a Certificate Signing Request (CSR):
Using this private key, the user generates a CSR (Certificate Signing Request) to CA:
openssl req -new -key harshit.key -out harshit.csr -subj "/CN=harshit"
Create a CertificateSigningRequest Object:
As an admin, you will create an object to add the user’s signing request for approval:
apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: harshit spec: request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo= signerName: kubernetes.io/kube-apiserver-client expirationSeconds: 604800 # Valid for 1 week usages: - client auth
Before pasting the user request into this YAML file, first, decode the request and make it a single line. This is necessary because, in YAML files, the request is encoded:
cat harshit.csr | base64 | tr -d "\n"
After pasting the request, apply this file using:
kubectl apply -f csr.yaml
On describing the CertificateSigningRequest:
You can see that the requested user is
k8s-admin
, and the signer iskube-apiserver-client
that is validate from control-plane node.Approve the CertificateSigningRequest:
Until now, the user has created a certificate-signing request and shared it with the admin. As an admin, we create an object, but it is in a pending state because the request needs to be approved by an authorized CA. Since we are not using an external CA, the admin can approve this request manually because all the certificates are already there in node, so CA will auto-authenticate with it:
kubectl certificate approve harshit
To deny a csr
kubectl certificate deny <certificate-signing-request-name>
Retrieve the Issued Certificate:
Once approved, get the issued certificate to share it with the user:
kubectl get csr harshit -o yaml > issuedcsr.yaml
The
issuedcsr.yaml
file will contain the issued certificate, which can then be shared with the user.apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"certificates.k8s.io/v1","kind":"CertificateSigningRequest","metadata":{"annotations":{},"name":"harshit"},"spec":{"expirationSeconds":604800,"request":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1Z6Q0NBVDhDQVFBd0VqRVFNQTRHQTFVRUF3d0hhR0Z5YzJocGREQ0NBU0l3RFFZSktvWklodmNOQVFFQgpCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFOK2ZvRkJVRmY5THBHVEs1ellwYjQ5ekxEZUJCWjVtdHJWVXFzaERFa2lhCkNJVTVDdkRjRkZGRTBFWjkvZXVKMGxKUVlCRm5IM29BM0MvVy9mSFQzNWQ3Vzh6eE1DdGRiSGN2Q3hzVmh0blcKRkhoTHVnWkVHa2JCazdDeDdnU2RRRzBldW5jeTB4c3UyVFVWczRmcWJteTJpVjRtWnA3bmQ2SHZpRHgzSkk1ZAoyUnNFeGUzd1IxbmF3V21GcEJLTDViV2kzcFcxcmdyR0FFMTN5NnVZUzJ2VHdad0hIVnNHdFJwVVY3MEZUOExWCkVkRm1ZeXVnMjY0ZjZUdmYraldPMXJPTTlKMkJxZnN4dHNiOXFhU3pBTkhCUHRmOXR5WXlZMDkwZ2tkbldoQmwKR3RZWkY2WEs0cU8yUXgzRlJ4bWRncHRLL2ZPMEwrdzNiQ1BXT05aOW51c0NBd0VBQWFBQU1BMEdDU3FHU0liMwpEUUVCQ3dVQUE0SUJBUUFXd05hZ0RkelJ6N1M5YUROcFpPWWRqdFlyTlRjYnlvSDlzNWZ0aHVQR0sveERURUpJCktCQzVLR1hPTGhxbmtBNzZ4aHFSdmVJRm9mOG9IMWJhaGRNL3ZDc1pGZGMzMnpOaUZaM281MXhXSjlSblhDZHUKb2dMNWVWZWFlbkVOVWhPN2pGcGw0d1F1KzZzbU5BcUo4U0JJcG9INStzZ0V3Q09JV0srMWNjNXFVQXNLSDRzQgpzY2NTaldPVy9MbSs0TkoyaEVNM1J0bHlpWlJKWTJubnNUdjZENDlnUDRmajQvNGx5TXIrRCtSSjBaTFlPKzg5CmpFSWV2ZndFZ25YNDZPMG9VOGFlOHFFQ2locTY1ak9FRDBnaDBxRGJxdHBxQkhZaTF5OHZOKzdsQXZhNmorbUcKN25PbVVpckllV1N1d01hQ0JxMXBZdE5yeW5nM2JNVTRobWpPCi0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=","signerName":"kubernetes.io/kube-apiserver-client","usages":["client auth"]}} creationTimestamp: "2024-12-25T11:50:57Z" name: harshit resourceVersion: "147045" uid: c4783597-d085-4342-bf41-4659ae9a831e spec: expirationSeconds: 604800 groups: - system:masters - system:authenticated request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1Z6Q0NBVDhDQVFBd0VqRVFNQTRHQTFVRUF3d0hhR0Z5YzJocGREQ0NBU0l3RFFZSktvWklodmNOQVFFQgpCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFOK2ZvRkJVRmY5THBHVEs1ellwYjQ5ekxEZUJCWjVtdHJWVXFzaERFa2lhCkNJVTVDdkRjRkZGRTBFWjkvZXVKMGxKUVlCRm5IM29BM0MvVy9mSFQzNWQ3Vzh6eE1DdGRiSGN2Q3hzVmh0blcKRkhoTHVnWkVHa2JCazdDeDdnU2RRRzBldW5jeTB4c3UyVFVWczRmcWJteTJpVjRtWnA3bmQ2SHZpRHgzSkk1ZAoyUnNFeGUzd1IxbmF3V21GcEJLTDViV2kzcFcxcmdyR0FFMTN5NnVZUzJ2VHdad0hIVnNHdFJwVVY3MEZUOExWCkVkRm1ZeXVnMjY0ZjZUdmYraldPMXJPTTlKMkJxZnN4dHNiOXFhU3pBTkhCUHRmOXR5WXlZMDkwZ2tkbldoQmwKR3RZWkY2WEs0cU8yUXgzRlJ4bWRncHRLL2ZPMEwrdzNiQ1BXT05aOW51c0NBd0VBQWFBQU1BMEdDU3FHU0liMwpEUUVCQ3dVQUE0SUJBUUFXd05hZ0RkelJ6N1M5YUROcFpPWWRqdFlyTlRjYnlvSDlzNWZ0aHVQR0sveERURUpJCktCQzVLR1hPTGhxbmtBNzZ4aHFSdmVJRm9mOG9IMWJhaGRNL3ZDc1pGZGMzMnpOaUZaM281MXhXSjlSblhDZHUKb2dMNWVWZWFlbkVOVWhPN2pGcGw0d1F1KzZzbU5BcUo4U0JJcG9INStzZ0V3Q09JV0srMWNjNXFVQXNLSDRzQgpzY2NTaldPVy9MbSs0TkoyaEVNM1J0bHlpWlJKWTJubnNUdjZENDlnUDRmajQvNGx5TXIrRCtSSjBaTFlPKzg5CmpFSWV2ZndFZ25YNDZPMG9VOGFlOHFFQ2locTY1ak9FRDBnaDBxRGJxdHBxQkhZaTF5OHZOKzdsQXZhNmorbUcKN25PbVVpckllV1N1d01hQ0JxMXBZdE5yeW5nM2JNVTRobWpPCi0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo= signerName: kubernetes.io/kube-apiserver-client usages: - client auth username: kubernetes-admin status: certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMrRENDQWVDZ0F3SUJBZ0lSQU5mVjJ1VUJUWkxmOWx4VFB0SEQ1N0F3RFFZSktvWklodmNOQVFFTEJRQXcKRlRFVE1CRUdBMVVFQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TkRFeU1qVXhNVFV5TVRSYUZ3MHlOVEF4TURFeApNVFV5TVRSYU1CSXhFREFPQmdOVkJBTVRCMmhoY25Ob2FYUXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRRGZuNkJRVkJYL1M2Umt5dWMyS1crUGN5dzNnUVdlWnJhMVZLcklReEpJbWdpRk9RcncKM0JSUlJOQkdmZjNyaWRKU1VHQVJaeDk2QU53djF2M3gwOStYZTF2TThUQXJYV3gzTHdzYkZZYloxaFI0UzdvRwpSQnBHd1pPd3NlNEVuVUJ0SHJwM010TWJMdGsxRmJPSDZtNXN0b2xlSm1hZTUzZWg3NGc4ZHlTT1hka2JCTVh0CjhFZFoyc0ZwaGFRU2krVzFvdDZWdGE0S3hnQk5kOHVybUV0cjA4R2NCeDFiQnJVYVZGZTlCVS9DMVJIUlptTXIKb051dUgrazczL28xanRhempQU2RnYW43TWJiRy9hbWtzd0RSd1Q3WC9iY21NbU5QZElKSFoxb1FaUnJXR1JlbAp5dUtqdGtNZHhVY1puWUtiU3YzenRDL3NOMndqMWpqV2ZaN3JBZ01CQUFHalJqQkVNQk1HQTFVZEpRUU1NQW9HCkNDc0dBUVVGQndNQ01Bd0dBMVVkRXdFQi93UUNNQUF3SHdZRFZSMGpCQmd3Rm9BVW1jb1JyK2c3Nk5BQnMyYkIKWUtESnAwSXJ1c3d3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUZoR0FWSGR6SVllYXJXeDBUQkg5UWw2d0psKwpISzdZSEU1clNOODIvTVZFRjd6cTRSZzRzU29OblRBMUdURXZtaW1DNEV1NG9zdGRNbHlLeEcwUXZpL1RGMHZNCkZvbzZYUUNBTXFaK0tCeUZBRjdqZXBESlliWDZoVFJjV0MvbDNlZU50eHB3bjZuaG12ZitwSDl4MGl6S2F5REQKRXVwbHBpUm02QVkyeFlxSytyWUZKT1grc2swOHdkL0lkSGlidWhLR2JpUTJMcDJ0MlN1Nk50d1pwbXB2Rm9OSApmYUlFMFdlV3lQOWFjd2QxclVleFBzcEUzNlA5L1VNd0JiV3M2YkJHcEdiQzRtVkNYaUJOaFdVbkNnK2Q3VVNJCmZhVlVUSXM5Y0VXWndkM2tXTWxhem4xKy9kcVYxd2ErVjZaWGt3b01MSGxiUWRGN1ZON2xsdlFsQ2h3PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== conditions: - lastTransitionTime: "2024-12-25T11:57:14Z" lastUpdateTime: "2024-12-25T11:57:14Z" message: This CSR was approved by kubectl certificate approve. reason: KubectlApprove status: "True" type: Approved
In the status section, you can see the certificate, but before giving it to the user, decode it using
echo "csr" | base64 -d
.Now you can share this certificate with any user or add it to a kubeconfig file to perform tasks in the cluster. We will cover this in more detail in our next blog.
Get the certificate
Retrieve the certificate from the CSR:
kubectl get csr/harshit -o yaml
The certificate value is in Base64-encoded format under
status.certificate
.Export the issued certificate from the CertificateSigningRequest.
kubectl get csr harshit -o jsonpath='{.status.certificate}'| base64 -d > harshit.crt
Authentication and Authorization
Authentication
Authentication in Kubernetes is the process of verifying the identity of a user or a service.
Kubernetes supports multiple authentication mechanisms:
Client Certificates: Users or services authenticate using certificates signed by a trusted Certificate Authority (CA).
Bearer Tokens: Tokens issued by a trusted entity, often used for service accounts.
Basic Authentication: Simple username and password authentication (not recommended for production).
OIDC (OpenID Connect): Integration with identity providers like Google, Azure AD, etc.
Webhook Token Authentication: Custom authentication using webhooks.
We already did a hands-on client certificate.
Authorization
Authorization in Kubernetes determines what actions an authenticated user or service can perform on resources in the cluster. Kubernetes supports several authorization mechanisms:
RBAC (Role-Based Access Control): The most common mechanism, which grants permissions to users based on roles.
ABAC (Attribute-Based Access Control): Permissions based on attributes like user, group, or labels.
Webhook Authorization: Custom authorization via a webhook.
Node Authorization: Limits access based on the node's identity, typically for Kubelets.
Kubeconfig
Whenever you run kubectl get pod
or any other command it first get authenticated from the node as per the user who is requesting. So in backend this command checks the server configuration, client certificates, and CSR etc. All these information are stored in kubeconfig
file.
This file is present at you home directory with
$HOME/.kube/config
Let’s Explore a sample kubeconfig file
apiVersion: v1
kind: Config
preferences: {}
clusters:
- cluster:
name: development
- cluster:
name: test
users:
- name: developer
- name: experimenter
contexts:
- context:
name: dev-frontend
- context:
name: dev-storage
- context: # context is a combination for user and cluster, it is used for defining a cluster to a user
user: experimenter
cluster: test
name: exp-test
A configuration file describes clusters, users, and contexts. Your config-demo
file has the framework to describe two clusters, two users, and three contexts.
Let’s see the default config file in our system
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJME1USXlOREE0TlRrek5Gb1hEVE0wTVRJeU1qQTROVGt6TkZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTkpMCkFKU3NRa2hIb1FJUWE0ZHdvVWc0cHFuREQxa1NIYlh0ekkxZ2hUU2Y5SXo3MG9aMjN5cU1JVGxoS05TT2ZRcjUKeEJwaStPREl1S0ZtdC9TckVTK0Z1Nk9TdDdLc3g0WEw1bDBVRk9Yc3BwZEh4Tm0rbGE1ZlUxeU9FVjJhbWM4eAo3Z2EwRjIycUJTQkV2Znc2dFhQWmRYUllqTno4VWhDampTVThZbmNJTTRtVlJsUUw2RndSVnM2czV4QnErczR6CjMxeXprUk43bnd0eXdCRngzNkNGbGhBL3A3dDZ6Zmd5bDI3KzFHZmNpZ29FU1U3bnhkREhSNDNqMkxickNOQ1EKSzF1RDEvZEY4ME5janRoYmxiYk4xeUh2VDhTdStPR0xLTXVldGkxK3ZDOUNJRE1BbEdlUSt3WWI2MGVtaTRlaQo5UndJWFBiN3cxWjJHbXdwK28wQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZKbktFYS9vTytqUUFiTm13V0NneWFkQ0s3ck1NQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRUxNZ1krUTJsdyt3YmZmd0dPOQpuclB2d3lsUCtlNHdaVElYUE43MzRaRHVJemdiTktGRTJPLzloZWpPSlQxTU1RcG8vei83OS9jd1JERW14bTRoCkJmZHkycHdHVnUxakxkK2J0Y0dYbjVyZkQrUUNtRldnN0F1NitKRDVuelhSVFhNelV2Rllkay9kL0VJc0VGQ2kKZHdTSXo2YUlZU2JCT3hjOFFUOGZkVU43eW9WR2JtNGtxak5sQm81VEVlYlBYUmhQUFUwcFpoaENMKzhqWStuKwpqWUlNSFROZExwcjBQV0p1Y0tSbmxqNDFVS0h6QmU5RXVmOTlYV1MwT3JHTGVrNDRiakZjWlptQ1Y5amw4aXljCkY1S3MxU3NoYWU4UGNEem9hd2pEeEFobklSZUxGbHVoOTJPUHhxSmhLOEc3bENMdFNhZXE1TjZxTGV2UkY0dGQKSGRjPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://127.0.0.1:35873
name: kind-cka-cluster
contexts:
- context:
cluster: kind-cka-cluster
user: kind-cka-cluster
name: kind-cka-cluster
current-context: kind-cka-cluster
kind: Config
preferences: {}
users:
- name: kind-cka-cluster
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURJVENDQWdtZ0F3SUJBZ0lJSm9CNnRrQ2hjcWN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TkRFeU1qUXdPRFU1TXpSYUZ3MHlOVEV5TWpRd09EVTVNemhhTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXFSQ2FwdU94cGdHNTVuVUEKYzJKUzFWeWxXTDlTaWFCNGdBTzR6RjZ1VUdHQXZIbHhCYU4wcFlrWENLK0dXUWUvZ3FKNVBrbmdNKzEraExGVQp6cFBxOWZpbFlKWHVsTFhKVnQ1OEJ4U3FtTHFOZWdOMXFlL0N5UFoydXpMWXd4NnpuSG1wWDFnUDNLK0EvUWZSCm9NbHVTV0tWRUZDTGMxTWJUQTJ2cGpvZDhzWmk1RjVjMTI1QVArUEY3NnN3ZmZIQUNKcUo1bDNhOXI1YmUvaXgKT1htbG5yc0wwblVPYUg1OGQ0NlBaK3NxckxPbjhUVVNHdk03T1hESGVhWW14K2w0eVRkZnJzdmNoQVRSU2lHNwpXejdkYjFKbUcxdUlUaE5acjR3TVNBMzdWZkZtTDdLS3haUmxpbE80U2hENUtKRjBHTGR3NHNGQ2RDWmlkMzhJCnl0M2hWd0lEQVFBQm8xWXdWREFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RBWURWUjBUQVFIL0JBSXdBREFmQmdOVkhTTUVHREFXZ0JTWnloR3Y2RHZvMEFHelpzRmdvTW1uUWl1Ngp6REFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBcDdWUThXSGNzZFlLMVo5QXBrZWtsMmR5T1ZzOFFyeDI2d2lNCmhxQ05COGFVU1BTUDZtaHEzVkVMUWJ1dlRZdGdOTWR0VDBnWlFubkwxZjV3MjAwK3c4eXhrbVpheVd2SHdvdzYKKzloV3JqN3NBRnN4dzVEWDI2bWlYV3hreWo3NnFsWkVrK1RXZ25qb29vNlZobWZ4YlVSS2MxUUIyaXVKNkRzMwo2KzZpclhRSnFuRUwvY0ZPZ2hid01mYXZjaTQwalFCUEdIUFlBVWpaNGJ5bTQ5T3JHYzh6bmxjV2piT1BNNTZkClFwTDdXRHpyOEcwRktmMndFVTl3Z2Ricjh5WDVkdHRiNTVXQTlPNG0wS1hoWnZjdmxYN0RCVURjUHZSd0FhcUUKb1dzLzlXU0F0azZMWDlsOFNZZGhZZ0ZlR3N6VjVsc09iaW4zdE5ZMjBxS0tJRGVVK0E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBcVJDYXB1T3hwZ0c1NW5VQWMySlMxVnlsV0w5U2lhQjRnQU80ekY2dVVHR0F2SGx4CkJhTjBwWWtYQ0srR1dRZS9ncUo1UGtuZ00rMStoTEZVenBQcTlmaWxZSlh1bExYSlZ0NThCeFNxbUxxTmVnTjEKcWUvQ3lQWjJ1ekxZd3g2em5IbXBYMWdQM0srQS9RZlJvTWx1U1dLVkVGQ0xjMU1iVEEydnBqb2Q4c1ppNUY1YwoxMjVBUCtQRjc2c3dmZkhBQ0pxSjVsM2E5cjViZS9peE9YbWxucnNMMG5VT2FINThkNDZQWitzcXJMT244VFVTCkd2TTdPWERIZWFZbXgrbDR5VGRmcnN2Y2hBVFJTaUc3V3o3ZGIxSm1HMXVJVGhOWnI0d01TQTM3VmZGbUw3S0sKeFpSbGlsTzRTaEQ1S0pGMEdMZHc0c0ZDZENaaWQzOEl5dDNoVndJREFRQUJBb0lCQUFlaUgwbHZ1R0tsYTA1VApkQXpCb0xuUGNBdTh2NjVGRjR1NEgwemk3WDNsbVJscFprZjU1RmRoQkRBNU5KaXFkK1FmRDloWEg0OVlwc0M0Ci9QcEN4WFlMbnZQb2NSZzN5UHBxR3pGNnBtVTA3eFJXT2FiTmszN2RXZWtEMTdPZm5ENXhZOHRSUDQ0WVFudXEKTWJYUHduSC95SGt2R2N6QU1OaFRPZDRJZTdldFdJNUU2NHZmTXFRK0RSdnpqZlVDM3lTRlZJVHdibGpEeEJ2dgpNQzRqSmYyWTZiN2NiOHpPTVFBcWZZaG55MW9SRzh6Mm1qSnRhR1l1WEZPYWJsQ25ESEhPZFJSMWNuMGlvQnh1CjZHN2krSHF0MFBhUXpHZ0VUZWxFeHF2NnA0RDNURUxTRW1pSWdobUM4Ymk4cDFhckZlOXNBbDIzQ2JYYVFWbWQKdkovTjVvRUNnWUVBd2NZSk53Zmw5d2FRZ0F4dHRDcUpMYk0vMjQ2dWtQRHY0aDViRzZyTmkyMVBPZ3V5bENUKwp4UXBYaCtrZHZlczhjL3l2YllFTVUvNUkxZy8rNjl2a0dMTVRZTFdDMjF5Rzh3Z2xwcHpGY3VLdjRmdFMyRHo3CkdPMk1tVklaVUJEcDNmdmI4UnhCUWpvbmRPazVNc2FoK2FhUG1OZ3k0U3VZZlZJeVZYcXNIWmNDZ1lFQTMxdEkKOXdZUE5NU2taUEpTc0o1dXMyOWF3NW9pRWgzWklGM3ZsMWlTVHovS2hrU0pxb1M3aEFGZnQ3eWlBOUw5RGVITQp2cm55Yk1LcEVTckcvUTVXRmdxa2UwM2FHSXkwaGxwTFFTVDE0WFBIZlVIaDJEbmVZVk1jbkNuV1FwNVVyelg0CjdWczFVbUJDMHRsVHFLNElWN1dPWWlUb2xFQXFURWlYSzIvUVVrRUNnWUEwODU0UENMeUI3YXhOSVpoVTlJNjYKQzFLMjk5MmlSQVQ1Z0p3YkNtalM0aE1WWko3dk50RGNIWUJmNW9jM0gvSk1LOC93bDZRN3k3QXh0dnROanJCZApRNHBYRWlMcE9QYXpzUlZBMjNSbGVhYmdsU0pGYnh5YTZrZFNtb25LUkdUMFFXQVFHazJIQUlkSnZuWGY5MEhLCkRBY1BtSDBHNVRmdGZ5bThEQ0srandLQmdEbmJHM3RoUm04VXdNQ2xSR1liby9FMjF2dno0UDl3VzkzV2QwbHMKMS9sUFBOYXF5ajR4UTZGZCtiMU9UMmxPTGQ1NnJ0NTRyQ01nQ1VzNUdYSlRWRmxCU0hub0lLWmJUQ2ZCRzkwMApCYnp3a0t3UmRMN2R2b3pYU29IcEZHY05QRUptYUtTVEM2emE0blJiZHlBcWRGN0QySzN6Z1l0bFU0K08vaGx5ClRUUUJBb0dBVlIySExsYk40NDJUeFo4N0VvTml6YXBBWHl6NTAxSjE1NzhzK0NKczNSWlRJV050Tk5MVXpPYlgKdXJtT0JwdWxkazc4WjVMb0JOaW9MN1p5RlJmanN6RFIwMTgxaVBlNHZJYitwTFROZE5EdG4ycHpTUytJV0FibgpieFFic0pXS21JWUpadVEwRDFBWk0vK1liVDBSR09pUTlwQVdtcDR6a2dHUncvWGkrdjg9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
The user authorized with the client-certificate data and client-key-data to get response on requests.
Let’s inspect more kube-api-server
:
Login to Kube-api-server:
docker exec -it cka-cluster-control-plane bash
All the files of control-plane are stored in /etc/kubernetes/manifests
See the content of kube-apiserver.yaml
cat kube-apiserver.yaml
From this file we can see many details of api-server like
- It follows Node and RBAC for authorization within an order of priority.
When we request anything, that request is validated through kubeconfig
file but whenever the api-server
and its component try to request with any other component, they authenticate with several certificates and CSRs which you can check from there components manifest file and all those certificates are stored in /etc/kuberenetes/pki
.
All the files with .crt
are public certificates and .key
are private keys. You can observe that api-server has many certificates and keys like apiserver.key
, apiserver.crt
, apiserver-kubelet-client.key
, apiserver-kubelet-client.crt
, apiserver-etcd-client.key
, apiserver-etcd-client.crt
. In above we have studied that api-server acts as server when it deals with clients like user, kube-scheduler, kube-controller, kube-proxy but act as client also for kubelet and etcd, that's why it has different certificates and private key as per the request and response.
Conclusion
In this blog, we explored how TLS certificates are used within Kubernetes to secure communication between different components and users in the cluster. We also touched upon the concepts of authentication and authorization, which ensure that only authorized users and components can interact with the Kubernetes API.
By understanding these security mechanisms, you can better manage and secure your Kubernetes cluster, ensuring that it remains robust and resilient against unauthorized access.
Subscribe to my newsletter
Read articles from Harshit Sahu directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Harshit Sahu
Harshit Sahu
Enthusiastic about DevOps tools like Docker, Kubernetes, Maven, Nagios, Chef, and Ansible and currently learning and gaining experience by doing some hands-on projects on these tools. Also, started learning about AWS and GCP (Cloud Computing Platforms).