# Security

## Authentication

#### We have 2 types of users:

* **Users:** Admins & Developers
* **Bots:** Service Accounts which are other processes, services, apps that require access to cluster

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F7V9MPR6OtRqYTD7MXzpy%2Fimage.png?alt=media&#x26;token=26e0c99f-f793-43a5-91a3-f195cf2c23fe" alt=""><figcaption></figcaption></figure>

### Users

#### Kubernetes doesn't manage user accounts natively, it relies on external sources such as:

* File with user details
* Certificates
* 3rd-party identity service like LDAP

So you cannot create users or list users in a Kubernetes cluster

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FkKMVeF0p0wwMPFYWJVyI%2Fimage.png?alt=media&#x26;token=ed5105a8-cbb6-41b1-bcaa-0df57c38d0ea" alt=""><figcaption></figcaption></figure>

### Service Accounts

Kubernetes can manage service accounts using the kubeapi-server

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FWBt0uLggsRBv7Hz9oHRe%2Fimage.png?alt=media&#x26;token=b623f126-fca6-4a0a-a0fa-7dcc4d585c1e" alt=""><figcaption></figcaption></figure>

### Authentication Mechanisms

#### How does kube-apiserver authenticate?

* **Static Password File:** List of username & password in a file
* **Static Token File:** Usernames & Token in a file
* **Certificates:** Authenticate using certificates
* **Identity Services:** Connect to 3rd party authentication protocols such as LDAP, Kerberos etc...

#### Basic Authentication

* Static Password File
* Static Token File

We can create list of users with their passwords as a csv file:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FBRfnOoEsL0j4ayR1YqEA%2Fimage.png?alt=media&#x26;token=76f07887-4803-4aa1-a441-a633f3744e38" alt=""><figcaption></figcaption></figure>

Then pass the csv file name as an option to the kube-apiserver then restart manually

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FpduBykUvnrm2fKsW1ohH%2Fimage.png?alt=media&#x26;token=642e9a03-40ce-4171-a9ac-e27c31e88edb" alt=""><figcaption></figcaption></figure>

Or using the kubeadm tool in the `/etc/kubernetes/manifests/kube-apiserver.yaml` file which will be restarted automatically by the kubeadm tool

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F1l9g5yMss7yeGJoZzALs%2Fimage.png?alt=media&#x26;token=b72b16e8-d274-43eb-a6e1-c3ac43ca258e" alt=""><figcaption></figcaption></figure>

To authenticate user using the basic credentials while accessing the kube-apiserver, specify the user and password

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FStDYcU8x0jxDObGpHFXB%2Fimage.png?alt=media&#x26;token=652b906a-ed4c-4e58-9345-96f77202bd4e" alt=""><figcaption></figcaption></figure>

We can have a 4th column to specify a group

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2Fzpg8IIjuu6mK69ARr1Tw%2Fimage.png?alt=media&#x26;token=0c57f959-3fff-49bb-87de-bdd9aa1cac9f" alt=""><figcaption></figcaption></figure>

Also, if we are using tokens instead of password, we must add it to the csv file and use the token as bearer in the request header

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2Fl4iZ5BwRf19YQlxLp0kl%2Fimage.png?alt=media&#x26;token=3a731cd2-9caa-473b-b5bf-701cb5c5287b" alt=""><figcaption></figcaption></figure>

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FiqGFLEe87rTNZcxpMrqu%2Fimage.png?alt=media&#x26;token=4ca3cbfa-127a-457f-ac6d-c008b07de681" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
This is not the recommended approach for authentication as it stores plain text information

Consider volume mount while providing the auth file in a kubdeadm setup
{% endhint %}

## TLS Basics

#### A certificate is used to guarantee trust between two parties during a transaction, for example:

&#x20;If user tries to access a web server, TLS certificates ensure the traffic between user and web server is encrypted and the web server is who it says it is.

{% hint style="info" %}
Hackers can sniff symmetric keys sent by user to the server and decrypt the messages
{% endhint %}

To solve this issue, we use asymmetric encryption to generate public and private keys using OpenSSL

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FiAC1a0idzBihfi560iwq%2Fimage.png?alt=media&#x26;token=172fffd2-e8f1-4374-b3bf-ae4eb51bb85b" alt=""><figcaption></figcaption></figure>

#### Let's view what happens:

* User requests the web server on HTTPS
* The web server sends a public key to the user
* The user browser encrypts the symmetric key using the public key sent by the webserver
* The user then sends his message (encrypted with symmetric key) which is also encrypted with public key of the server
* The server receives the message and decrypts it using its private key

The hacker only has a public key and encrypted data which he can't do anything with them.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FQeVoUx3MvTKQTFdsoV6l%2Fimage.png?alt=media&#x26;token=46b60869-f2c7-440f-8c4b-20702e257a58" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Hackers now know our trick and creates their own server and generating their own private and public keys for a secure connection and somehow routes our request to their server
{% endhint %}

To solve this issue, here is where the certificates play a crucial role, so when we request to the server on HTTPS and receive its public key.

#### We can inspect the public key and see its certificate which includes information like:

* Public key of server
* Location of server
* Who is the certificate for
* DNS Information etc...

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F7UyK9B21DrmmETIHjw2C%2Fimage.png?alt=media&#x26;token=42a5cb72-cdf9-44cf-b260-647fb2ca86c2" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Most important part to verify a certificate is to check who signed and issued the certificate
{% endhint %}

{% hint style="info" %}
When you generate a certificate yourself, it is a self-signed certificate which appears to be suspicious, browsers validates and warns you if the certificate is fake/self-signed
{% endhint %}

### How do we get our certificates to be signed by an authority?

#### That's where Certificate Authorities (CA) comes into play, some popular authorities includes:

* Symantec
* Comodo
* GlobalSign
* digicert

#### The process of signing a certificate by an authority is:

* Generate a certificate signing request (CSR) using key we generated earlier and name of our website

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FSPQFCTkDqubKZz3rtJQ4%2Fimage.png?alt=media&#x26;token=be867c4e-a994-405f-a085-35bb66042df1" alt=""><figcaption></figcaption></figure>

* Authority validates the information you sent
* Certificate is signed and sent back to you

{% hint style="info" %}
You now have a certificate signed by a CA that the browsers trust

CAs use different techniques to make sure you're the actual owner of that domain

All CAs have their own set of public and private keys which are built in to the browsers

Browser uses public key of CA to check if its signed by CA itself
{% endhint %}

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FUSha1NDvcvjoXOmuGwh3%2Fimage.png?alt=media&#x26;token=f1991841-479e-4d1d-942a-1db74bf5efe5" alt=""><figcaption></figcaption></figure>



#### Let's say we have sites hosted privately for our organization, what shall we do?

CAs offers private hosting of their servers, we can deploy the CA server internally and then have the public key of out internal CA server installed on all employees browsers and establish secure connectivity in the organization.

#### In summary:

* Admin generates a key pair for securing SSH
* Web server generates a key pair for securing the website with HTTPS
* CA generates its own key pairs to sign certificates
* End users generates a single symmetric key to encrypt his credentials and uses it after establishing trust to the webserver to send his credentials for authentication

{% hint style="info" %}
All of these key pair generations mentioned are called Public Key Infrastructure (PKI)

You can encrypt data with both public and private keys but only decrypt with private key
{% endhint %}

### Naming Conventions

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FDf3EowchvxS0bDUcVEvw%2Fimage.png?alt=media&#x26;token=7aab8331-482f-4237-9d46-452c7ca142b3" alt=""><figcaption></figcaption></figure>

#### server.crt = server public key etc...

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F4nyIiEHmkFqt0ajZKFpF%2Fimage.png?alt=media&#x26;token=c7988c20-596f-43cc-8d76-8d0e5dc9cda1" alt=""><figcaption></figcaption></figure>

#### server.key = server private key etc...

## TLS in Kubernetes

Communication between Master and worker nodes must be secure, also when an admin uses the kubectl utility to communicate with kube-apiserver it must be secure. Overall all communications between Kubernetes components must be secure.

#### So the 2 primary requirements are:

* Server certificates for servers
* Client certificates for clients

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FEbvRSrzTFkUmYViJFgs3%2Fimage.png?alt=media&#x26;token=b9c066ec-d39a-4042-8e79-93fd33bdcbcb" alt=""><figcaption></figcaption></figure>

Let's start with the server components which uses TLS certificates.

### Server Certificates for servers

{% hint style="warning" %}
Server private and public key naming convention may differ depending on who and how the cluster was setup
{% endhint %}

#### KubeAPI server

Lets start with kube-apiserver which exposes an https service that other components and external users use to manage the Kubernetes cluster.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F6rX6s9YpFMfyFN3CNotF%2Fimage.png?alt=media&#x26;token=4738b118-e095-4674-b290-b620b53beea4" alt=""><figcaption></figcaption></figure>

#### ETCD server

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FmHdgk4D4V8gfH5GybOYp%2Fimage.png?alt=media&#x26;token=83e3f187-bdba-47b9-9145-3b6f4931d469" alt=""><figcaption></figcaption></figure>

#### Kubelet server

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F7K3EmwenzzKngyC083QQ%2Fimage.png?alt=media&#x26;token=6cc26362-70dc-4079-9169-8afac20ffe2d" alt=""><figcaption></figcaption></figure>

### Client Certificates for clients

Clients are admins or components who needs access to the kube-apiserver through kubectl or rest API.

#### Admins

Lets start with the admin which must have key-pairs to talk to the kube-apiserver and authenticate

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FL6greq1uecf8HBwLe5Yz%2Fimage.png?alt=media&#x26;token=454af7b3-bcd0-4661-b2da-ffaf31be517a" alt=""><figcaption></figcaption></figure>

#### Scheduler

The scheduler needs to communicate with the kube-apiserver to get pods who needs scheduling, which it must have key-pairs to authenticate

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F7xrqGLft3EXQ9YBOQCDY%2Fimage.png?alt=media&#x26;token=4345ded1-4453-4889-a330-01755714d56a" alt=""><figcaption></figcaption></figure>

#### Kube Controller Manager

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FHAPpogu8DMjfjhMeqX47%2Fimage.png?alt=media&#x26;token=755bdea7-ee04-4261-b12d-6596aaa34aea" alt=""><figcaption></figcaption></figure>

#### Kube Proxy

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F1PM60AqmEzfgsjsEx2od%2Fimage.png?alt=media&#x26;token=18d869be-9c24-496d-bfab-69f75af6d84f" alt=""><figcaption></figcaption></figure>

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FVzg9FUQah0fzxVi6uTo2%2Fimage.png?alt=media&#x26;token=041cfe12-a9f6-4833-af2b-e101763a0141" alt=""><figcaption></figcaption></figure>

#### This picture below summarizes everything regarding certificates for both client and server:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FzgJ3fQxbMW1zuaxB17N8%2Fimage.png?alt=media&#x26;token=b3c4a709-c858-4b7f-95f9-d60e4f632802" alt=""><figcaption></figcaption></figure>

## Certificate Generation

#### To generate certificates we must have at least one CA in our cluster, in fact we can have more than one:

* CA for server
* CA for client

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FsNEAOjho3JU3kQmdogZb%2Fimage.png?alt=media&#x26;token=fbe4dd26-c750-4f43-b461-6d4019ccaa54" alt=""><figcaption></figcaption></figure>

For now, we'll just stick to one CA for our cluster.

We will use OpenSSL utility to generate our certificates

#### Generate key:

```bash
openssl genrsa -out ca.key 2048 # ca.key
```

#### Certificate Signing Request:

```bash
openssl -new -key ca.key -subj "/CN=KUBERNETES-CA" -out ca.csr
```

#### Sign Certificates:

```bash
openssl x509 -req -in ca.csr -signkey ca.key -out ca.csr # Self-signed
```

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F2Jf61HuRvSznhLgdDGom%2Fimage.png?alt=media&#x26;token=c4a20733-33fa-4db1-aa8f-cbd9789dadeb" alt=""><figcaption></figcaption></figure>

To generate client certificates starting with admin

#### Generate key:

```bash
openssl genrsa -out admin.key 2048
```

#### Certificate Signing Request:

{% code overflow="wrap" %}
```bash
openssl req -new -key admin.key -subj "CN=kube-admin/OU=system:masters" -out admin.csr
```
{% endcode %}

{% hint style="success" %}
To distinguish admins from normal users, we must put the admin user in a group, and mention it in the Certificate Signing Request as `/OU=<group-name>`
{% endhint %}

{% hint style="danger" %}
For client system components such as scheduler/controller manager/kube-proxy, we must include a prefix to their certificate name (CN) like `"CN=SYSTEM:kube-scheduler"`
{% endhint %}

{% hint style="warning" %}
CN=kube-admin doesn't have to be kube-admin, you can name it as you like, but remember this is the name that kubectl client authenticates with and can be found in logs and elsewhere
{% endhint %}

#### Sign Certificates:

{% code overflow="wrap" %}
```bash
openssl x509 -req -in admin.csr -CA ca.crt -CAkey ca.key -out admin.crt # admin.crt is the certificate that will be used to authenticate to kubernetes cluster
```
{% endcode %}

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2Fwr3Iv8EkVDRBy87UQacR%2Fimage.png?alt=media&#x26;token=341187a2-ff6d-4869-92c6-409fbec0aa03" alt=""><figcaption></figcaption></figure>

#### Now, instead of authenticating with username and password/token, we can use the kube-admin certificate we generated and put it in the `kubeconfig` yaml to authenticate with it:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F5a0rIV1H0LRHjIKeJ1EZ%2Fimage.png?alt=media&#x26;token=202435d2-de08-4e19-996b-7861f63fd1df" alt=""><figcaption></figcaption></figure>

#### Or using curl (not recommended):

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FAzqKCETRd64fTiGk1Bqz%2Fimage.png?alt=media&#x26;token=3d5b1c65-caf9-43db-9ead-7b50cbdfc468" alt=""><figcaption></figcaption></figure>

### Peer Certificates

Lets take ETCD server as an example, ETCD can be deployed as a cluster across multiple server in a high availability environment, so we need to generate peer certificates to secure communication between different ETCD members in the cluster.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FXMtXRBo0Ocad9cJR3m0A%2Fimage.png?alt=media&#x26;token=1eeec423-4ca4-44fd-b761-a4df413382ad" alt="" width="402"><figcaption></figcaption></figure>

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2Fvvr8o3xLRL9YiF6fTDt8%2Fimage.png?alt=media&#x26;token=70fb4b76-f007-438f-b7c0-e2d9fe384333" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
ETCD config requires the CA root certificate to verify the client connecting to ETCD are valid
{% endhint %}

### KubeAPI server&#x20;

#### Some common names given to kube-apiserver are:

* kubernetes
* kubernetes.default
* kubernetes.default.svc
* kubernetes.default.svc.cluster.local
* By its IP address

{% hint style="info" %}
Those referring to the kube-apiserver by these names can establish a valid connection
{% endhint %}

To generate a certificate to the kube-apiserver

```bash
openssl genrsa -out apiserver.key 2048
```

To consider all alternative names to offer flexibility in establishing connection to kube-apiserver, create an `openssl.cnf` file

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2Fwq2nINl7qabyxsaUe5Y6%2Fimage.png?alt=media&#x26;token=a907c165-5f45-4799-b43a-4d0b2a6159d5" alt=""><figcaption></figcaption></figure>

Then pass it as a config when generating the certificate signing request

{% code overflow="wrap" %}
```bash
openssl req -new -key apiserver.key -subj "/CN=kube-apiserver" -out apiserver.csr -config openssl.cnf
```
{% endcode %}

```bash
openssl x509 -req -in apiserver.csr -CA ca.crt -CAkey ca.key -out apiserver.crt
```

Specify these keys in the kube-apiserver service configuration

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FEk6bFGinwRFHdfblLeHC%2Fimage.png?alt=media&#x26;token=70b2fcf5-bc21-4da6-aaa6-894d4d8dac20" alt=""><figcaption></figcaption></figure>

### Kubelets

Certificates created for kubelet are named based on the node they are on.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FoqO8TTWahiRNrnP9P31q%2Fimage.png?alt=media&#x26;token=706a9586-0ef7-4220-8f66-1bfa3286dbbd" alt=""><figcaption></figcaption></figure>

We also mentioned a set of client certificates that will be used by kubelet to authenticate to kube-apiserver. The kube-apiserver needs to know which node is authenticating (use prefix of node name) to give it right set of permissions using the group.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FHL9q1UKQb7Vki4L7op7W%2Fimage.png?alt=media&#x26;token=cace0b39-1c6c-4789-998b-be127e7b4b4f" alt=""><figcaption></figcaption></figure>

Once certificates are generated they go to `kubeconfig` file.

## View Certificate Details

#### To check certificate details, lets start with kube-apiserver as an example:

View the kube-apiserver static pod definition found in `/etc/kubernetes/manifests/kube-apiserver/yaml`

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FNo3BOtCwRFwZlCvo1DOz%2Fimage.png?alt=media&#x26;token=69a7339d-c915-45b1-b347-facbdf11666a" alt=""><figcaption></figcaption></figure>

Then to inspect a certain certificate, use the `openssl x509` command

```bash
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout
```

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FS6OXOhwTePoK8fs4ntRS%2Fimage.png?alt=media&#x26;token=a7177002-0987-475d-b0dc-12338ef55e85" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Certificate requirements are found in Kubernetes docs in details
{% endhint %}

{% embed url="https://kubernetes.io/docs/setup/best-practices/certificates/" %}

#### When you run into issues, you want to start looking at the service logs:

```bash
kubectl logs etcd-master
```

#### Sometimes if the core components such as kubeapi-server/etcd-server is down, kubectl won't function, so you need to go one level down to docker:

```bash
docker ps -a
docker logs <container-id>
```

### Lab:

I was asked to give the CN Name of kubeAPI server certificate, I chose the Issuer CN instead of the Subject CN which is wrong.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FUvgjcmkXYmd6I5xpWaO4%2Fimage.png?alt=media&#x26;token=47fd9861-d5c4-4833-b44b-5829c777b8e9" alt=""><figcaption></figcaption></figure>

#### Most used command:

```bash
openssl x509 -in <cert-path> -text -noout # Get certificate information
```

Checking the certificate paths and its name if its correct or not, then check the static pod definition to fix the issue.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FsPSWptPOq2bKxkTuIKUW%2Fimage.png?alt=media&#x26;token=7dd6b32b-fee2-45ab-8a9b-05938259eb25" alt=""><figcaption></figcaption></figure>

Utilize `crictl` to troubleshoot if kubectl is not working due to kube-apiserver or etcd server are down.

```bash
crictl ps -a # | grep kubeapi if needed
crictl logs <container-id>
```

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FoaOmxLejJnqIe6sp2NzW%2Fimage.png?alt=media&#x26;token=f112750f-2c54-4608-bab4-557591d24943" alt=""><figcaption></figcaption></figure>

It appeared to be the wrong path of `--etcd-cafile`, which must be `/etc/kubernetes/pki/etcd/ca.crt`

## Certificates API

The CA is whatever server that has the key pairs which we can sign certificates with, in our case its the master node.

Whenever a certificate expires, we need to do same steps to re-generate them, this can be inefficient as we scale, so Kubernetes helps us by providing a certificate API.

#### Instead of manually entering the master node and signing the certificates ourselves, we could:

* Create CertificateSigningRequest object
* Review requests
* Approve requests
* Share certificates to users

#### Lets take an example:

* A user creates a key and then generates a certificate signing request using the key with his name on it
* Then users sends this request to the admin
* Admin takes the key and creates a CertificateSigningRequest object using yaml definition

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FX4Wk3NT8nJ9XhpDu5YOD%2Fimage.png?alt=media&#x26;token=7823ae44-8a21-4436-b0c9-70f45d6f6ddf" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
The request must be encoded with base64 before adding it to the request in definition yaml using `cat jane.csr | base64`
{% endhint %}

* Once the object is created, admin can see it using `kubectl get csr`
* Admin can then approve the csr using `kubectl certificate approve jane`
* Admin then `kubectl get csr jane -o yaml` and decode it using `echo "encoded-cert>" | base64 -d` and share it with the end user

{% hint style="info" %}
All of these tasks are done by the **csr-approving** and **csr-signing controllers** in the controller manager component&#x20;
{% endhint %}

### Lab:

The main issue here is doing the CertificateSigningRequest object, specially that in docs it was given as a cat command.

#### Also when encoding the csr, by default base64 prints it line by line, to make it work use this command:

```bash
cat akshay.csr | base64 -w 0
```

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F5UmCgMmw1w7X9sWXPyZy%2Fimage.png?alt=media&#x26;token=93a8adc1-fda5-4315-8760-59a5f4e5d8f9" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Make sure to utilize `dd` for delete entire line and `u` for undo in vim, also to copy the whole base64 output with the "`=`"
{% endhint %}

## Kubeconfig

Kubeconfig is set by default in the `$HOME/.kube/config` directory and kubectl uses it without you specifying the config path with the command you enter.

#### To create a kubeconfig, it can be created using a pod definition yaml as shown below:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2Fzp4Zq6vXstrOojrxUuhz%2Fimage.png?alt=media&#x26;token=7457e029-8e24-453c-9b36-12e1e64647e5" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Regarding certificates, you must specify full path, also you could use `certificate-authority-data` instead to paste the base64 encoded certificate.
{% endhint %}

#### To view current context (The user and cluster you are using):

```
kubectl config current-context
```

#### To view all the config:

```bash
kubectl config view
kubectl config view --kubeconfig=custom-config
```

#### To use another context:

```bash
kubectl config use-context prod-user@production # use new cluster and user
kubectl config use-context prod-user # use new user, samse cluster
kubectl config use-context production # use new cluster, same user

kubectl config -h # Additional commands
```

#### You also can add a namespace in the context definition yaml, so you can switch to a new context with the namespace you added:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FxPB0MW7HogftELhgyNti%2Fimage.png?alt=media&#x26;token=99be764a-fa5a-4f5f-9e4f-bebb5565e344" alt=""><figcaption></figcaption></figure>

### Lab:

#### The kubeconfig context definition in the yaml already have a name which specifies what cluster we must access and with what user, so if we want to change and use the research current context we should run:

```bash
kubectl config use-context research
```

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FdXUSxX2meLsoEzsSaKOW%2Fimage.png?alt=media&#x26;token=6b2e2280-fda6-4301-a10a-a3f6b47c9015" alt=""><figcaption></figcaption></figure>

{% embed url="https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/" %}

## API Groups

#### Core API Groups:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FgmzAL3AwZgHJbE9vGkC0%2Fimage.png?alt=media&#x26;token=d28cb1b2-1a4d-45bc-8d4c-9830a4c70585" alt=""><figcaption></figcaption></figure>

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FTOzRmXwWJb1XKW2BiBSS%2Fimage.png?alt=media&#x26;token=8292f1e0-69f5-4d13-8ae3-a6df184855d1" alt=""><figcaption></figcaption></figure>

#### Named API groups:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2Fn7BOcZY0AqvTMUyd0X55%2Fimage.png?alt=media&#x26;token=7367d210-07ac-4d43-bf6d-2dec343cf1ba" alt=""><figcaption></figcaption></figure>

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FgtByXsbwvPEKE2vqqnlt%2Fimage.png?alt=media&#x26;token=20f943cf-d802-49ca-89c5-9b1aa6ffaf4d" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
You won't be allowed to curl like that, so you need to use your credentials as parameters  to authenticate to the API

As an alternative, you could start a `kubectl proxy` that uses your credentials from kubeconfig and then `curl localhost:8001`
{% endhint %}

### Key Takeaways

All resources in Kubernetes are grouped into different API groups

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FKaQhqX19xsXTC0vj6csC%2Fimage.png?alt=media&#x26;token=34880c92-a77e-49ce-a69e-1c95d1cac873" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
We can use all of these APIs to allow and deny actions for authorization, specially in the RBAC yaml definitions in`apiGroup:[]`
{% endhint %}

## Authorization

#### There are different authorization mechanisms in Kubernetes:

* Node Authorization
* Attribute Based Authorization (ABAC)
* Role Based Authorization (RBAC)
* Webhook

### Node Authorization

Node authorization is a special-purpose authorization mode that specifically authorizes API requests made by kubelets.

In Kubernetes Node Authorization, a "user" refers to a system component, such as a kubelet, rather than a human operator.&#x20;

The kubelet acts on behalf of a node, making requests to the KubeAPI server. The Node Authorizer processes these requests, determining access based on the node's identity and the resources it needs.

* Kubelets are registered as "users" within the SYSTEM:NODE group.
* Each kubelet's username is prefixed with SYSTEM:NODE, distinguishing their identity for authorization purposes.

This framework ensures that kubelets requests are appropriately authorized by the node authorizer.

{% embed url="https://kubernetes.io/docs/reference/access-authn-authz/node/#kubelets-with-undifferentiated-usernames" %}

### ABAC

ABAC is meant for external access to the kube-apiserver which are for instance admins/developers.

#### ABAC is to associate a user or a group of users a set of permissions by creating a permission file in a json format and passing it to the kube-apiserver:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FSfquebyDFwvvqJqBKRxw%2Fimage.png?alt=media&#x26;token=510e9bb4-579f-4120-a255-7f6acf289736" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
Every time you need to add/change policies you must edit this policy file manually and restart kubeapi-server, which is not efficient and difficult to manage.
{% endhint %}

### RBAC

Instead of directly assigning a policy to a user or group of users, we define a role (for developers in our case) and then assign all developers for this role.

So we only need to modify the role instead of modifying every single policy file.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F4VZnPFZUWKCnzmF9HNfX%2Fimage.png?alt=media&#x26;token=c5647d91-1fd2-4cd4-9fa6-3549fbe29b08" alt=""><figcaption></figcaption></figure>

### Webhook

For outsourcing the authorization mechanism, we could use 3rd party tool like Open Policy Agent.

Kubernetes make an API call to Open Policy Agent with information about user and his access requirements and let Open Policy Agent decide if he's permitted or not.&#x20;

Based on the Open Policy Agent response, the user is granted access.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FJmvuIDjYOGbn8PAqCnW6%2Fimage.png?alt=media&#x26;token=c0f0642f-e48a-4f1d-9933-616142fa5b66" alt=""><figcaption></figcaption></figure>

### Authorization Modes

The authorization mode is a configuration parameter option specified in the kube-apiserver configuration.

We didn't mention 2 Authorization mechanisms which are `AlwaysAllow` and `AlwaysDeny`

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FAYjn0yjfV8E1URioHpfH%2Fimage.png?alt=media&#x26;token=0d03d57b-23f1-4fd8-aab1-2623b5eeeeb6" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
By default, the authorization mode is set to `AlwaysAllow`
{% endhint %}

{% hint style="success" %}
When we specify more than one mechanism, they will get executed by order.

If Node authorizer fails to grant permission, it will move to RBAC, if RBAC grants the permission it returns to user and webhook authorization is not used.
{% endhint %}

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F5jV3zCN0HiKXxgI1vHBw%2Fimage.png?alt=media&#x26;token=c3d0c616-fd72-4db4-ae22-1cabf8a8a393" alt=""><figcaption></figcaption></figure>

## Role Based Access Controls

#### We can create an RBAC using an object definition yaml:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2Fc2WBcy9wQdnJqq0xJ25B%2Fimage.png?alt=media&#x26;token=e7874796-4c55-41d9-bce1-b840ea21bd40" alt=""><figcaption></figcaption></figure>

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FLIEYN0RPdQdsyo6qFxta%2Fimage.png?alt=media&#x26;token=7f6cb8a1-5a57-46fe-b1f8-cc90cf98044e" alt=""><figcaption></figcaption></figure>

#### Next step is to link user to that role, which we must create a Role Binding object definition:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2Fv1qegX9c49HWKqPsVS4V%2Fimage.png?alt=media&#x26;token=706fb603-ece4-4462-804f-b048059422a7" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
You can add the namespace under metadata, by default its the default namespace
{% endhint %}

#### To view all roles and role bindings:

```bash
kubectl get roles
kubectl get rolebindings
```

#### To check our current access, we can run:

```
kubectl auth can-i create deployments
yes
kubectl auth can-i delete nodes
no
etc...
```

#### If you're an admin and want to check your users permissions, you can:

```bash
kubectl auth can-i create deployments --as dev-user
no
kubectl auth can-i delete nodes --as dev-user --namespace test # In namespace test
yes
```

### Lab:

When adding additional rules (specially different api groups such as apps, storage etc...)

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FeKhshB15misk1qjI69tU%2Fimage.png?alt=media&#x26;token=13c6235b-4e89-42dd-bc4c-3e87ec37bdfc" alt=""><figcaption></figcaption></figure>

#### To get all resources information which is so useful for RBAC:

```bash
kubectl api-resources # Utilize grep to look for certain resources
```

{% embed url="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#-strong-api-groups-strong-" %}

## Cluster Roles & Role Bindings

#### There are two types of resources in kubernetes:

* **Namespaced:** Within a namespace, usually kube-system for system components and default for normal resources such as pods, deployments.
* **Cluster Scoped:** Within the whole cluster and they are not in a namespace.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F0X4qaaQalsNRtTk03zHq%2Fimage.png?alt=media&#x26;token=3f86b5fc-e6cf-498c-98f6-afb26cdeda8d" alt=""><figcaption></figcaption></figure>

#### To view all resources that are namespaced:

{% code overflow="wrap" %}
```bash
kubectl api-resources --namespaced=true # --namespaced=false if you want cluster scoped resources
```
{% endcode %}

### Cluster Roles

They are regular roles but only for cluster scoped resources.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FBLuJiTrlApkyxK9eH8LK%2Fimage.png?alt=media&#x26;token=d9e6f8b5-cccc-4cff-a574-8243765e1823" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
In Kubernetes docs, you can view how to create cluster roles and regular roles using kubectl
{% endhint %}

{% embed url="https://kubernetes.io/docs/reference/access-authn-authz/rbac/#kubectl-create-clusterrole" %}

### Lab:

Everything went well, the most useful thing I wasn't utilizing is:

```
kubectl api-resources
```

Also, make sure to check if the APIVERSION, if its v1 then in the definition yaml make sure the `apiGroup: [""]` is written like this, if its a deployment (apps) then `apiGroup: ["apps]`

## Service Accounts

#### There are 2 types of accounts in kubernetes:

* User accounts: Are used by humans, Administrators for management or developers for deploy an application
* Service accounts: Are used by bots, for example Prometheus to gather metrics for alerts and visualize it on a dashboard by quertying the kube-apiserver (needs authentication)

#### To create service accounts:

```bash
kubectl create serviceaccount prometheus-sa
kubectl get serviceaccount
```

{% hint style="info" %}
When creating a service account, a token is generated by default automatically which can be used by external application while authenticating to the kube-apiserver as a bearer token
{% endhint %}

#### The token created by the service account is in fact a secret which can be viewed by running:

```bash
kubectl get secrets
kubectl describe secret prometheus-sa-token
```

A new update to serviceaccounts was introduced which changed how it works, a TokenRequest API was introducted which now offers JWT expiration and other security enhancements, the old way of serviceaccounts tokens didn't have an expiration date and they were created automatically which is not the case now.

```
kubectl create serviceaccount prometheus-sa
```

#### And to create a token as its not generated automatically:

```
kubectl create token prometheus-sa
```

#### Although post v1.24 you can still create a non-expiry token using a secret object definition, but this is not recommended at all and if you did it, make sure to create the service account first.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FkxiuVSQFRLLYz9DvlBxB%2Fimage.png?alt=media&#x26;token=a6ed1a56-82c9-4d1e-b13c-296b03bbb148" alt=""><figcaption></figcaption></figure>

### Lab:

#### I had to concentrate on how to include a serviceaccount in a deployment definition:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FkePXacZ5Y9YW3Hrdd3zu%2Fimage.png?alt=media&#x26;token=7638c447-2fe6-48d8-8e70-22c35bdd3a9a" alt=""><figcaption></figcaption></figure>

#### Also, I could have used:

```bash
kubectl set serviceaccount deployment web-dashboard dashboard-sa
```

## Image Security

#### When specifying images in pod object definition yaml such as `image: nginx` it is in fact like this behind the scenes:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FF4aBgckQScblRDHb80yY%2Fimage.png?alt=media&#x26;token=195418ba-c032-449e-8464-533a0342d9b4" alt=""><figcaption></figcaption></figure>

You may have your own set of images that are stored in your private repository, whether its docker hub, ECR or other registries.

#### When an image is private and you want to pull it, you must authenticate to the registry first, this can be done in kubernetes as follows:

* We create a secret object with our registry URL, username and password

{% code overflow="wrap" %}
```bash
kubectl create secret docker-registry regcred --docker-server private-registry.io --docker-username registry-user --docker-password registry-password --docker-email register-user@org.com
```
{% endcode %}

* Then we specify the private image URL and the secret so kubelet on worker nodes can use this secret to pull your private image

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FBw91VUmldfwcSyJYfNlb%2Fimage.png?alt=media&#x26;token=6d1b2bbb-f49b-4898-851f-7443f1844f68" alt=""><figcaption></figcaption></figure>

### Lab (Review):

The most critical mistake I did is thinking that the `imagePullSecrets` is under `containers:` and its not correct, it must be under `spec:`

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F5KMvU2TSlgZCxaFgg95F%2Fimage.png?alt=media&#x26;token=7fad53d2-76b2-43c2-9a63-7f467404e8a5" alt=""><figcaption></figcaption></figure>

## Security Context

Containers aren't fully isolated like virtual machines, they share same kernel with host.

Containers are in their own namespaces and they can't see anything outside this namespace.

#### By default, docker runs processes as root user, if you want to change the user from root to a normal user:

```
docker run --user=1000 ubuntu sleep 60
```

Or you can specify the user ID within the docker image itself

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FODgc3oOLembHEVQ4xfdw%2Fimage.png?alt=media&#x26;token=8848db7a-9009-48af-b431-d0446e804078" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Docker limits the abilities of the root user within the container which is not the same as root user on a linux host machine
{% endhint %}

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FPpCh06vac9QAFs0dj34m%2Fimage.png?alt=media&#x26;token=4b424588-7ecf-4efd-ae4e-74d65b943abf" alt=""><figcaption></figcaption></figure>

#### Docker limits some of these capabilities by default, although you can add or drop capabilities:

```
docker run --cap-add NET_BIND ubuntu # Add NET_BIND capability
docker run --cap-drop NET_BIND ubuntu # Remove NET_BIND capability
docker run --priviliged ubuntu # Include all capabilities
```

You can configure all of these at a pod-level in an object definition yaml within kubernetes using `securityContext`

#### At a pod level:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FQd1G4wKeNbFCPfSmM9jD%2Fimage.png?alt=media&#x26;token=f36ba581-0beb-4d18-bad2-0af1cbda6d06" alt=""><figcaption></figcaption></figure>

#### At a container level:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FNXFAjnZ494NQ6EpUuhWB%2Fimage.png?alt=media&#x26;token=84af009b-91e3-4715-ad61-dcc1c1e4567f" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
Capabilities are only supported at the container level and not at the pod level
{% endhint %}

### Lab:

There was a syntax issue and I faced a problem where I edited the pod and made sure I added the securityContext but whenever I created it, it was created without security context, so I had to delete it and do another pod with the requirements.

#### Useful commands that must be used:

```
kubectl delete pod ubuntu-sleeper --force
kubectl create pod ubuntu-sleeper.yaml
```

{% hint style="warning" %}
kubectl apply caused problems, specially when dealing with pods, so lets move to kubectl create if problems were faced with apply
{% endhint %}

Also, It's important to note the difference between pod level and container level, pod level is under `spec:` and above `containers:`, container level is under `containers:`

Container level `securityContext` overrides pod level `securityContext`

{% embed url="https://kubernetes.io/docs/tasks/configure-pod-container/security-context/" %}

## Network Policy

#### Let's say we have:

* Web Frontend Pod
* Backend Pod
* DB Pod

And we are required to create a network policy for the DB Pod to allow only Ingress traffic from the Backend pod at port 3306.&#x20;

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FolUNWJmatgiChE8wMosa%2Fimage.png?alt=media&#x26;token=7d83331a-6e5b-4b68-acee-3dcab83dfa67" alt=""><figcaption></figcaption></figure>

Now, DB pod only allow ingress traffic from the backend pod on port 3306 and blocks all others.

#### To create a network policy:

* Create a label and a selector in the DB pod

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FW4pER3wpX8kTbFcTnxrG%2Fimage.png?alt=media&#x26;token=76c234db-0e57-48fc-a889-7bae9fa1d38f" alt=""><figcaption></figcaption></figure>

* Create the policy rule

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FwppcdQo6gK1H7Fya3GwJ%2Fimage.png?alt=media&#x26;token=c0da242a-ca46-4e25-b5a4-7692adb08d51" alt=""><figcaption></figcaption></figure>

* Create the policy object definition and pass both label, selector and the policy rule

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FVLK2yt4K5IvYeAuQXTsV%2Fimage.png?alt=media&#x26;token=f0daf205-cf58-4efb-b972-46669b54e40f" alt="" width="563"><figcaption></figcaption></figure>

{% hint style="danger" %}
In the policy type we defined Ingress type only, so egress is not affected and its by default allowing all egress traffic. If needed add egress rule too.
{% endhint %}

#### Also If you want to include same pods ingress rule in different namespaces, you can add a `namepsaceSelector:`

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FolxnMGKiDNGYXJs3YT0p%2Fimage.png?alt=media&#x26;token=e76e374a-d4b2-4ebd-841b-34e3db60d261" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
If we add a -namespaceSelector and make it under the `from:` it will be 2 rules not connected together (api-pod is allowed from anywhere, all pods in namespace prod are allowed), in the given example above it means that pod must be api-pod and in prod namespace
{% endhint %}

This will allow all pods named `api-pod` in the prod namespace to access the DB at port 3306, if we removed the `api-pod` then it will allow all pods within the prod namespace.

#### If you want to allow certain IP addresses traffic, you could specify an `ipBlock:`

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FXqt9GNFZ14xfb5oFfnLn%2Fimage.png?alt=media&#x26;token=b55397c8-db70-4d26-a08a-14a5ee2b87bf" alt=""><figcaption></figcaption></figure>

#### Also, we could specify an agress rules as follows:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FerDDZxAft1fiCJMN8FMi%2Fimage.png?alt=media&#x26;token=a9ba6947-8c67-4ba6-8bc3-3519d2b2e5f3" alt=""><figcaption></figcaption></figure>

This will allow all traffic at port 80 originating from the DB pod to the backup server at the CIDR block addresses given.

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FTmIa0vmqgDtROfmTtoBf%2Fimage.png?alt=media&#x26;token=eb8138a3-0929-4575-9296-cc7376f7abb3" alt=""><figcaption></figcaption></figure>

### Lab:

#### I must change the `matchLabels: role:db` to the label in the pod that I want to write the policy for:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2F9oWYHYF6Itw4Tz1Aj1Kw%2Fimage.png?alt=media&#x26;token=06da31fd-9bc4-4abe-997c-cb7744ff392e" alt=""><figcaption></figcaption></figure>

#### Here is my final policy:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FyI9m3Y7V8VjpEk6gXwom%2Fimage.png?alt=media&#x26;token=17b1fbea-445a-4b55-9f02-9c17e232bffb" alt=""><figcaption></figcaption></figure>

#### And here is how the k8s docs helped:

<figure><img src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FL4FnsGsY2qfAO5WRDjJH%2Fimage.png?alt=media&#x26;token=54e5e5a7-66cb-4fcc-864f-ac2c332a1716" alt=""><figcaption></figcaption></figure>

{% embed url="https://kubernetes.io/docs/concepts/services-networking/network-policies/#default-policies" %}

## Kubectx & Kubens

### **Kubectx**

With this tool, you don't have to make use of lengthy “kubectl config” commands to switch between contexts. This tool is particularly useful to switch context between clusters in a multi-cluster environment.

**Installation:**

```
sudo git clone https://github.com/ahmetb/kubectx /opt/kubectxsudo ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx
```

**Syntax:**

To list all contexts:

> kubectx\
>

To switch to a new context:

> kubectx \<context\_name>

To switch back to previous context:

> kubectx -

To see current context:

> kubectx -c

### **Kubens**

This tool allows users to switch between namespaces quickly with a simple command.

**Installation:**

{% code overflow="wrap" %}
```bash
sudo git clone https://github.com/ahmetb/kubectx /opt/kubectxsudo ln -s /opt/kubectx/kubens /usr/local/bin/kubens
```
{% endcode %}

**Syntax:**

To switch to a new namespace:

> kubens \<new\_namespace>

To switch back to previous namespace:

> kubens -

## Slides

{% file src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FQWzbKaE0MZ5Hr5QKzjch%2FKubernetes%2B-CKA-%2B0600%2B-%2BSecurity.pdf?alt=media&token=fd12e41b-fbb3-466b-a76f-490109956bc1" %}

{% file src="https://4247064012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFLaJdzZGSq1DpczuSySw%2Fuploads%2FsQAUVNH7Y77kwWqqzxe6%2FNetworking.pdf?alt=media&token=4a4d064b-53d0-4492-9460-28d84746d62f" %}
