K8s API


The K8s APIs are grouped as follows:
  1. api
  2. apis
  3. healthz
  4. logs
  5. metrics
  6. version


Out of them, first two are related to cluster functionalities. "api" is also called "core api" and "apis" are called "named api". They are defined as "" in RBAC. The named api (apis) are further classified as following resource groups: 
  1. admission
  2. admissionregistration.k8s.io
  3. apiextensions.k8s.io
  4. apiregistration.k8s.io
  5. apps
  6. auditregistration
  7. authentication.k8s.io
  8. authorization.k8s.io
  9. autoscaling
  10. batch
  11. certificates.k8s.io
  12. coordination.k8s.io
  13. core
  14. discovery
  15. events.k8s.io
  16. extensions
  17. flowcontrol
  18. imagepolicy
  19. monitoring.coreos.com
  20. networking.k8s.io
  21. node.k8s.io
  22. policy
  23. rbac.authorization.k8s.io
  24. scheduling.k8s.io
  25. settings
  26. storage.k8s.io
  27. testdata
One can perform following actions (verbs) on these resource groups, if RBAC policy allows. 
  1. list
  2. get
  3. create
  4. delete
  5. update
  6. watch
As per K8s 1.17, the K8s resources are grouped as follows: 


The below table indicates, composition relationships among all K8s objects, as per K8s 1.17



Reference: 
https://kubernetes.io/docs/reference/
https://kubernetes.io/docs/reference/kubectl/overview/
https://kubernetes.io/docs/concepts/overview/working-with-objects/object-management/
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md
https://www.cncf.io/blog/2020/03/17/how-to-setup-role-based-access-to-kubernetes-cluster/
https://github.com/kubernetes/kubernetes/issues/7856

https://kubernetes.io/docs/concepts/overview/kubernetes-api/
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md

CKA 7: Security


For all hosts (master nodes and worker nodes)
- Root access should be disabled.
- Password based authentication should be disabled.
- Only SSH key based authentication should be enabled.

Control access to the kube-apiserver
1. who can access? Authentication 

-- Username and password :

* Static password file user-details.csv
* It has 4 columns (1) password (2) user name (3) user id (4) group id is optional
* command like option --basic-auth-file to kube-api-server. If kubeadm is used then modify pod YAML for kube-apiserver
* curl command pass:  -u "username:password"
* not recommended

-- Username and token : Static token file
* It has 4 columns (1) user-token (2) user name (3) user id (4) group id is optional
* command like option --token-auth-file to kube-api-server. If kubeadm is used then modify pod YAML for kube-apiserver
* curl command pass:  --header "Authentication: Bearer TOKEN"
* not recommended

-- Certificates
* curl command pass:  --key USER.key --cert USER.crt --cacert ca.crt

-- External authentication provider. E.g. LDAP : Identity service
-- Service accounts

2. what they can do? Authorization
-- RBAC
-- ABAC
-- Node Authorization
-- Webhook mode

TLS

If data is encrypted with public key, then decrypt with private key
If data is encrypted with private key, then decrypt with public key

ssh-keygen command generates id_rsa and id_rsa.pub key pairs
openssl genrsa -out filename.key 1024
openssl rsa -in filename.key -pubout > certificate.pem

if any certificate have .crt OR .pem extension then it has public key
Example: server.crt, server.pem, client.crt, client.pem
If a file has private key then it has extension as .key OR file name has -key
Example: server.key, server-pem.key, client.key, client-key.pem

TLS in K8s

Server: Client


1. kube-apiserver:  /CN=kube-apiserver
(1) Other K8s components 
(i) kube-scheduler  /CN=system:kube-scheduler
(ii) Kube-controller-manager /CN=system:kube-controller-manager
(iii) kube-proxy /CN=system:kube-proxy
(2) external users kubectl /CN=admin/O=system:masters

All of the above use kubeconfig file

2. etcd server : kube-apiserver only  /CN=etcd-server
3. kubelet services: Kube-apiserver user name  = system:node:NODENAME group name = systems:nodes

K8s cluster may have dedicated CA for 'etcd' as server and 'kube-api server' as client. 

Tools to generate certificates

easyrsa
openssl
cfssl

1. Create private key
openssl genrsa -out FILE.key 1024
2. CSR using openssl
openssl req -new -key FILE.key -subj "/CN=NAME" -out FILE.csr
openssl req -new -key FILE.key -subj "/CN=NAME/O=GROUP" -out FILE.csr
openssl req -new -key FILE.key -subj "/CN=NAME/O=GROUP" -out FILE.csr -config openssl.conf
Here openssl.conf will have multiple names that includes DNS and IP

Once the CSR file is generated, it can be view with command

openssl req -in FILE.csr  -text --noout

3. Sign the request
openssl x509 -req -in FILE.csr -signkey FILE.key -out FILE.crt

Here, when FILE=CA then it is self-signed using root certificate. 

openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt

Next for signed by CA, we need to pass both private key of CA ca.key and CA's self-signed certificate, that contains its public key. 
openssl x509 -req -in FILE.csr -CA ca.crt -CAkey ca.key -out FILE.crt

View Certificates

openssl x509 -in CERT_FILE_WITH_PATH -text -noout

1. journalctl -u SERVICE_NAME -l
2. k logs POD_NAME
3. If kubctl is not working
docker ps -a
to find out container ID
then
docker logs CONTAINER_ID

Certificates API

1. Create private key
openssl genrsa -out FILE.key 1024
 2. CSR using openssl
openssl req -new -key FILE.key -subj "/CN=NAME" -out FILE.csr
3. Create k8s object with YAML file. Kind = CertificateSigningRequest
4. cat FILE.CSR | base64
Use this output in "request:" field at YAML file. 
5. k get csr
6. k certificate approve FILE
OR
k certificate deny FILE
7. k get csr FILE -o yaml
8. Extract content of "status->certificate"
9. echo CONTENT | base64 -decode

At master node, Controller-Manager performs all certificate related tasks. It has two controllers (1) CSR-Approving (2) CSR-Signing . The kube-controller-manager is passed with command line arguments "--cluster-signing-cert-file" it points to ca.crt and "--cluster-signing-key-file" it points to ca.key

Kubeconfig

k COMMAND --server K8S_MASTER_NODE:PORT --client-key admin.key --client-certificate admin.crt --certificate-authority ca.crt

k COMMAND --kubeconfig config
config file shall contain
--server K8S_MASTER_NODE:PORT 
--client-key admin.key 
--client-certificate admin.crt 
--certificate-authority ca.crt
Default path for config file is ~/.kube
If config file is located at this path, then no need to specify --kubeconfig config

If we use curl command and invoke REST API
curl https://URL:6443/api/v1/pods --key admin.key --cert admin.cert --cacert ca.cert

If we use command
k proxy

then we can use curl command as per config file, at port 8001

config file has 3 sections

1. clusters
k config set-cluster CLUSTER_NAME
certificate-authority OR certificate-authority-data. content for certificate-authority-data is set using cat ca.crt | base64
2. users
k config set-credentials USER
3. contexts = user@cluster + ns
k config set-context CONTEXT_NAME
4. current-context 
k config use-context USER1@CLUSTER2 //it will change  current-context in file. 

Linke with this command
k COMMAND --server K8S_MASTER_NODE:PORT --client-key admin.key --client-certificate admin.crt --certificate-authority ca.crt

Here
--server K8S_MASTER_NODE:PORT //clusters section 
--client-key admin.key //users section
--client-certificate admin.crt //users section

--certificate-authority ca.crt //clusters section

Kubectl commands
k config view // to view config file at default path ~/.kube
k config view --kubeconfig=CUSTOM_CONFIG_FILE_WITH_PATH


RBAC

k auth can-i VERB_ACTION RESOURCE_OBJECT
k auth can-i VERB_ACTION RESOURCE_OBJECT --as USER
k auth can-i VERB_ACTION RESOURCE_OBJECT --as USER --namespace NS

Image Security

If image name is xyz then it is xyz/xyz = user account/image name
Here default registry = docker.io
so xyz is docker.io/xyz/xyz

Google registry = gcr.io

K8s has default secret type with name docker-registry. it has keys
- doceker-server
- docker-username
- docker-password
- docker-email

in YAML we shall specify
imagePullSecrets: 
- name: docker-registry

Also refer: http://layers7.blogspot.com/2020/04/ckad-6security.html

K8s Secret 

at EncryptionConfiguration Kind we have providers
- identity : default. encryption = none
other options
- aescbc // secret is prefixed with k8s:enc:aescbc:v1:
- secretbox
- aesgcm
- kms //Key Management Service

32 byte key is generated with
head -c 32 /dev/urandom | base64
Set the --encryption-provider-config flag on the kube-apiserver to point to the location of the config file: YAML with kind = EncryptionConfiguration 

to update all existing secrets

kubectl get secrets --all-namespaces -o json | kubectl replace -f -

GitOps


What is GitOps?

* GitOps is code-based infrastructure and operational procedures that rely on Git as a source control system

* For Kubernetes GitOps means using git push instead of kubectl create/apply or helm install/upgrade.

*  It’s an evolution of Infrastructure as Code (IaC) and a DevOps best practice that leverages Git as the single source of truth, and control mechanism for creating, updating, and deleting system architecture. 

* Git is a single source of truth for
- CD
- automated deployment
- monitoring
- management 
- entire state of the system

* GitOps extends pipelines with a feedback loop for observing and controlling the system .

* A set of practices to use "Git pull requests" (1) to manage infrastructure and (2) to manage application configurations (3) automatically deploy system infrastructure modifications. All git procedures are applies like: review, pull request, push requests, tagging, versioning etc. 

* GitOps practice
- Declarative description of system : stored in Git
- Pull requests modify the state of the Git repository. 
- Once approved and merged, the pull requests will automatically reconfigure and sync/reconcile the live infrastructure to the state of the repository. This is done by controller software. It self-heal the system or notify the drift. 
- This live syncing pull request workflow is the core essence of GitOps.

* Declarative Description (YAML) of desired production infrastructure in git + automate to match production environment state with desired state at git

* Continuous Deployment for cloud native applications

* GitOps is an incredibly powerful workflow pattern for managing modern cloud infrastructure

* GitOps is an extension of IaC and declarative configuration

* git push + CI/CD toolchain + UI/UX

* Tools : Git , CD tools (tools for declarative infrastructure as code)

* Developer tools (read git) to drive operations. 

* GitOps provide more stability and reliability over typical CI/CD pipeline


The GitOps idea was first hatched and shared by WeaveWorks, an enterprise Kubernetes management firm

GitOps operator is a mechanism that sits between the pipeline and the orchestration system (read K8s) . A pull request starts the pipeline that then triggers the operator. The operator examines the state of the repository and the start of the orchestration and syncs them. 


Principles

1. The entire system is described declaratively. 
2. The canonical desired system state versioned in Git
3. Approved changes that can be automatically applied to the system. 
4. Software agents to ensure correctness and alert on divergence 

Tools:



  • ArgoCD: A GitOps operator for Kubernetes with a web interface. It supports multiple clusters and multiple Git repositories. 
  • Flux: The GitOps Kubernetes operator by the creators of GitOps — Weaveworks No central Management, No central UI. 
  • Gitkube: A tool for building and deploying docker images on Kubernetes using git push
  • kaniko is a tool to build container images from a Dockerfile, inside a container or Kubernetes cluster.
  • BuildKit is a toolkit for converting source code to build artifacts in an efficient, expressive and repeatable manner.
  • JenkinsX: Continuous Delivery on Kubernetes with built-in GitOps
  • Tkton Pipelines project provides k8s-style resources for declaring CI/CD-style pipelines.
  • Terragrunt: A wrapper for Terraform for keeping configurations DRY, and managing remote state
  • WKSctl: A tool for Kubernetes cluster configuration management based on GitOps principles
  • Helm Operator: An operator for using GitOps on K8s with Helm
  • Non K8s tools such as Terraform
  • harness.io 
  • Skaffold.dev handles the workflow for building, pushing and deploying application
  • kubediff
  • sealed-secrets by Bitnami OR Vault by Hashicorp

Gitops promoted by
* Weaveworks
* Cloudbees
* Bitnami (encrypt K8s secret) https://github.com/bitnami/sealed-secrets
* OpenFaaS
* Hasura
* Ocado
* Financial Times

Benefits

1. Cluster update are sequence of atomic transaction, that can fail or success. GitOps makes it easy so productivity increase. 
2. Git provides transaction logs for audit, rollback and teamwork
3. config repo and image repo acts as firewall. so even if CI pipeline is hacked, production environment is not hacked. 

Blog Posts and Social Media