Friday, August 13, 2021

Kubernetes for Developers #22: Access to Multiple Clusters or Namespaces using kubectl and kubeconfig

In the previous article (Kubernetes for Developers #21: Kubernetes Namespace in-detail), we added name of the namespace in all kubectl commands to create or display kubernetes resources. Because kubeconfig current context referring to default namespace.

Kubeconfig file

kubeconfig file gets created automatically when you install k8 in the machine. It is usually located in the ~/.kube/config . This file contains all the necessary information to connect k8 cluster. kubectl CLI uses this file to execute commands against k8 cluster.

kubeconfig file contains four major sections
  1. clusters: it contains list of cluster details like name of the cluster, API server URL, Certificate Authority (CA) file, etc.
  2. users: it contains list of user credentials (like name, password, user token, certificate) for connecting an API server
  3. contexts: it contains combination of cluster name, user name and namespace. It is used for kubectl CLI when executing commands against k8
  4. current-context: Always one combination of context (i.e. name of cluster, user, namespace) must be set as current context.  (i.e. cluster name + user name + namespace name )


run following command to view kubeconfig file details
$ kubectl config view

apiVersionv1
kindConfig
clusters:
  - cluster:
      certificate-authority-dataFURS0tLXX
      serverhttps://k8.docker.internal:6443
    namemy-k8-cluster
contexts:
  - context:
      clustermy-k8-cluster
      usermy-test-user
      namespacedev-ns
    namemy-test-context
users:
  - namemy-test-user
    user:
      client-certificate-dataFUEAEXX
      client-key-dataCDESXX
current-contextmy-test-context


// display all contexts
$ kubectl config get-contexts
CURRENT   NAME              CLUSTER          AUTHINFO         NAMESPACE
*         my-test-context   my-k8-cluster   my-test-user      dev-ns

// display current context
$ kubectl config current-context
my-test-context

The following kubectl command display all pods from dev-ns namespace as current-context (i.e. my-test-context) referring to dev-ns namespace
// display pods
$ kubectl get po
NAME               READY   STATUS    RESTARTS   AGE
pod-nginx-dev-ns   1/1     Running   0          4m4s

run following command to modify namespace for the context
// modify namespace for the given context
$ kubectl config set-context my-test-context --namespace=dev2-ns
Context "my-test-context" modified.

// the below command display all pods from the dev2-ns namespace
$ kubectl get po
NAME               READY   STATUS    RESTARTS   AGE
pod-nginx-dev2-ns   1/1     Running   0          1m4s

Create new Context

As said earlier, every context consists of three parts
  1. Cluster details:
  2. use following kubectl command to configure new cluster details
// syntax
// kubectl config set-cluster <cluster-map-name> --server=<cluster-url> --certificate-authority=<ca-file>
$ kubectl config set-cluster my-new-cluster \
  --server=https://mycluster.k8.com:6443 \
  --certificate-authority=/path/cafile
Cluster "my-new-cluster" set.

     2. User details:
        use following kubectl command to configure new user details 
// syntax
// kubectl config set-credentials <user-map-name> --token=<user-token-info> (or)
// kubectl config set-credentials <user-map-name> --username=<username> --password=<password>
$ kubectl config set-credentials my-new-user --token=token1234abcd
User "my-new-user" set.

     3. Namespace details:
        use following kubectl command to view namespace details
// display all namespaces
$ kubectl get ns
NAME              STATUS   AGE
default           Active   31d
dev2-ns           Active   47m
dev-ns            Active   47m

Use following kubectl command to combine all above three details for creating new context
// syntax
// kubectl config set-context <context-name> \
   --cluster=<cluster-name> \
--user=<user-name> \
--namespace=<namespace-name>

$ kubectl config set-context my-new-context \
  --cluster=my-new-cluster \
  --user=my-new-user \
  --namespace=dev-ns
Context "my-new-context" created.

//display all contexts
$ kubectl config get-contexts
CURRENT   NAME             CLUSTER          AUTHINFO         NAMESPACE
*         docker-desktop   docker-desktop   docker-desktop
          my-new-context   my-new-cluster   my-new-user      dev-ns

// display current context
$ kubectl config current-context
docker-desktop

Use following kubectl command to switch the context
// change the context
$ kubectl config use-context my-new-context
Switched to context "my-new-context".

By default, the following kubectl command display all the pods from dev-ns namespace because CLI using "my-new-context" as current-context
// display pods
$ kubectl get po
NAME               READY   STATUS    RESTARTS   AGE
pod-nginx-dev-ns   1/1     Running   0          4m4s

Use following kubectl command to delete the context
// delete context
$ kubectl config delete-context my-new-context
deleted context my-new-context from ~\.kube\config

Kubernetes for Developers Journey.

Happy Coding :)

Monday, August 9, 2021

Kubernetes for Developers #21: Kubernetes Namespace in-detail

Kubernetes supports multiple virtual clusters by using Namespaces. It helps when multiple teams using same cluster and want to setup separate Roles, Binding and Environments for each team.

  • Kubernetes resource name should be unique within a namespace, but not across namespaces. It means, we can use same Pod/Deployment name in different namespaces
  • Namespaces cannot be nested
  • Each Kubernetes resource can only be in one namespace. It means, we cannot attach same Pod/Deployment to multiple namespaces
  • Try to avoid creating namespace with prefix "kube-" as it is reserved for K8 internal system
  • We can restrict resource usage limit (i.e. CPU, Memory) for each namespace
  • We can restrict users to access only selected namespaces and it’s Kubernetes objects
  • By default, all the k8 objects created under "default" namespace
The following four namespaces will be created automatically when the cluster is configured.

Namespace

description

default

By default, all the resources created under “default” namespace without CPU and Memory restrictions

kube-system

This namespace for objects created by the Kubernetes system

kube-public

It is reserved for cluster usage and it is accessible for all users. Use this only when k8 objects should be visible to publicly throughout the cluster

kube-node-lease

It is for lease objects associated with each node to improve performance of the node heartbeats




Create Namespace

  1. from YAML file
apiVersionv1
kindNamespace
metadata
  namedev-ns

Save above yaml content as "dev-ns.yaml" and run following kubectl command
// create namespace resoure from yaml file
$ kubectl apply -f dev-ns.yaml
namespace/dev-ns created

// display all namespaces
$ kubectl get ns
NAME              STATUS   AGE
default           Active   30d
kube-node-lease   Active   30d
kube-public       Active   30d
kube-system       Active   30d
dev-ns            Active   17m

// view namespace details using describe command
$ kubectl describe ns dev-ns

// view namespace details as yaml file 
$ kubectl get ns dev-ns -o yaml

   2. imperative way

// syntax $kubectl create ns <namespace-name>
$ kubectl create ns dev2-ns
namespace/dev2-ns created

// display all namespaces
$ kubectl get ns
NAME              STATUS   AGE
default           Active   30d
kube-node-lease   Active   30d
kube-public       Active   30d
kube-system       Active   30d
dev-ns            Active   17m
dev2-ns           Active   1m

Create Pod in selected Namespace

  1. from YAML file
we can achieve this by specifying namespace attribute in the metadata section

apiVersionv1
kindPod
metadata:
  namepod-nginx
  namespacedev-ns
spec:
  containers:
    - namenginx
      imagenginx:1.14.2

Save above yaml content as "pod-dev-ns.yaml" and run following kubectl command
// create pod under "dev-ns" namespace using yaml file
$ kubectl apply -f pod-dev-ns.yaml
pod/pod-nginx created

// display all pods from dev-ns namespace
// syntax
$ kubectl get po -n <namespace-name>

$ kubectl get po -n dev-ns
NAME        READY   STATUS    RESTARTS   AGE
pod-nginx   1/1     Running   0          4m4s

// delete namespace
// all pods gets deleted automatically when namespace is deleted
$ kubectl delete ns dev-ns
namespace "dev-ns" deleted

// display all pods under dev-ns namespace
$ kubectl get po -n dev-ns
No resources found in dev-ns namespace.

// delete all pods without deleting namespace
//syntax:
kubectl delete po --all -n <namespace-name>

$ kubectl delete po --all -n dev2-ns
pod "pod-nginx" deleted

// display all namespaces
$ kubectl get ns
NAME              STATUS   AGE
default           Active   31d
dev2-ns           Active   47m
kube-node-lease   Active   31d
kube-public       Active   31d
kube-system       Active   31d

2. imperative way

// syntax
// kubectl run <pod-name> --image <image-name> -n <namespace-name>
$ kubectl run pod-nginx --image nginx -n dev2-ns
pod/pod-nginx created

// display all pods from dev2-ns namespace
// syntax 
kubectl get po -n <namespace-name>

$ kubectl get po -n dev2-ns
NAME        READY   STATUS    RESTARTS   AGE
pod-nginx   1/1     Running   0          4m4s

we must use Fully Qualified Domain Name(FQDN) to access Pods from one namespace to another namespace i.e.

<servicename>.<namespace>.svc.cluster.local

Kubernetes for Developers Journey.

Happy Coding :)