Monday, March 22, 2021

Kubernetes - Imperative and Declarative commands

3/22/2021 - Note

 Imperative and Declarative commands


object created directly using command line and also yaml

imperative,
- how to go to destination what to do and how to do

declarative
- no step by step direction, declaring destination , declaring final destination

what to do, not how to do is decleartive.

Imperative approach
1. Provision a vm by the name web-serv
2. Install nginx software
3. Edit config file to use port 8080
4. Edit config file for web path as /var/www/nginx
5. Upload web pages to /var/www/nginx form git repo - X
6. Start nginx server

what is required and how things are done

in this example, we can use
> kc run --image=nginx nginx
> kc create deployment --image=nginx nginx
> kc expose deployment nginx --port
> kc edit deployment nginx
> kc scale deployment nginx --replicas=5
> kc set image deployment nginx nginx=nigx:1.18
> kc create -f nginx.yaml
> kc replace -f nginx.yaml
> kc deleate -f nginx.yaml

These are imperative approaches managinv object in k8s. we seen  how to bring creating, updateing, deleting objects.

Create objects
> kc run --image=nginx nginx
> kc create deployment --image=nginx nginx
> kc expose deployment nginx --port

Update objects
> kc edit deployment nginx
> kc scale deployment nginx --replicas=5
> kc set image deployment nginx nginx=nigx:1.18

These commands help you to work on objects quickly.
These comes with limited functionality.


cat nginx.yaml (static)
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
    type: front-end
spec:
  containers:
  - name: nginx-container
    image: nginx

Create objects
> kc create -f nginx.yaml

> kc deleate -f nginx.yaml


Update object (live)
> kc edit deployment nginx
opens yaml file and you can make changes.

or edit the main yaml config file and use replace command
> kc replace -f nginx.yaml

remove and replace
> kc replace --force -f nginx.yaml

This is still an imperative approach.
What happend you run create command, it will fail
> kc create -f nginx.yaml
error: already exists.

when running update, it should check before running update command.
> kc replace -f nginx.yaml

if object does not exisit, it will fail with error message.

In this approach, you are engage so much.


Declarative

VM Name: web-server
Database: nginx
port: nginx
path: /var/www/nginx
Code: GIT repo - X

Here, we declear our requirement with above information.
Everything need to be done to make ready is done by system using tools like ansible, puppet or other tools.

However, there are other checks to see if nginx already installed or web-server is already installed.

system should be intellegent enoguth to know what is already done.


Delcarative approach is

> kc apply -f nginx
apply command look for existing configuration and figure out what changes need to be made on the system.


In the declarative approach, you use the same config file, but instead of create or replace command option, we use apply option.
> kc apply -f nginx.yaml
it is intellegent enough to check if object is already exists.

cat nginx.yaml (static)
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
    type: front-end
spec:
  containers:
  - name: nginx-container
    image: nginx

> kc apply -f nginx.yaml
> kc apply -f /path//to/config-files

update objects
> kc apply -f nginx.yaml

google for imperative and declarative commands


Before we begin, familiarize with the two options that can come in handy while working with the below commands:

--dry-run: By default as soon as the command is run, the resource will be created. If you simply want to test your command, use the --dry-run=client option. This will not create the resource, instead, tell you whether the resource can be created and if your command is right.

-o yaml: This will output the resource definition in YAML format on the screen.

Use the above two in combination to generate a resource definition file quickly, that you can then modify and create resources as required, instead of creating the files from scratch.

POD
Create an NGINX Pod
$ kubectl run nginx --image=nginx

Generate POD Manifest YAML file (-o yaml). Don't create it(--dry-run)
$ kubectl run nginx --image=nginx  --dry-run=client -o yaml

Deployment
Create a deployment
$ kubectl create deployment --image=nginx nginx

Generate Deployment YAML file (-o yaml). Don't create it(--dry-run)
$ kubectl create deployment --image=nginx nginx --dry-run -o yaml

Generate Deployment with 4 Replicas
$ kubectl create deployment nginx --image=nginx --replicas=4

You can also scale a deployment using the kubectl scale command.
$ kubectl scale deployment nginx --replicas=4

Another way to do this is to save the YAML definition to a file.
$ kubectl create deployment nginx --image=nginx--dry-run=client -o yaml > nginx-deployment.yaml

You can then update the YAML file with the replicas or any other field before creating the deployment.

Service
Create a Service named redis-service of type ClusterIP to expose pod redis on port 6379
$ kubectl expose pod redis --port=6379 --name redis-service --dry-run=client -o yaml

(This will automatically use the pod's labels as selectors)
Or
$ kubectl create service clusterip redis --tcp=6379:6379 --dry-run=client -o yaml  

(This will not use the pods labels as selectors, instead it will assume selectors as app=redis. You cannot pass in selectors as an option. So it does not work very well if your pod has a different label set. So generate the file and modify the selectors before creating the service)

Create a Service named nginx of type NodePort to expose pod nginx's port 80 on port 30080 on the nodes:
$ kubectl expose pod nginx --port=80 --name nginx-service --type=NodePort --dry-run=client -o yaml

(This will automatically use the pod's labels as selectors, but you cannot specify the node port. You have to generate a definition file and then add the node port in manually before creating the service with the pod.)
Or
$ kubectl create service nodeport nginx --tcp=80:80 --node-port=30080 --dry-run=client -o yaml

(This will not use the pods labels as selectors)

Both the above commands have their own challenges. While one of it cannot accept a selector the other cannot accept a node port. I would recommend going with the `kubectl expose` command. If you need to specify a node port, generate a definition file using the same command and manually input the nodeport before creating the service.

Reference:
https://kubernetes.io/docs/reference/kubectl/conventions/

=============================================
Lab:

1. In this lab, you will get hands-on practice with creating Kubernetes objects imperatively.

All the questions in this lab can be done imperatively. However, for some questions, you may need to first create the YAML file using imperative methods. You can then modify the YAML according to the need and create the object using kubectl apply -f command.

2. Deploy a pod named nginx-pod using the nginx:alpine image.
Use imperative commands only.
    Name: nginx-pod
    Image: nginx:alpine

Hints: Use the command kubectl run to create a pod nginx-pod using image nginx:alpine.

root@controlplane:~# kc run pod nginx-pod --image=nginx:alpine
pod/pod created
root@controlplane:~# kc get pods
NAME   READY   STATUS              RESTARTS   AGE
pod    0/1     ContainerCreating   0          8s
root@controlplane:~#

root@controlplane:~# kc run nginx-pod --image=nginx:alone
pod/nginx-pod created
root@controlplane:~# kc get po
NAME        READY   STATUS              RESTARTS   AGE
nginx-pod   0/1     ContainerCreating   0          4s
pod         0/1     CrashLoopBackOff    2          61s
root@controlplane:~# kc delete pod pod
pod "pod" deleted
kc get pod
root@controlplane:~# kc get pod
NAME        READY   STATUS         RESTARTS   AGE
nginx-pod   0/1     ErrImagePull   0          18s
root@controlplane:~#

Solution: Run the command: kubectl run nginx-pod --image=nginx:alpine

root@controlplane:~# kc run nginx-pod --image=nginx:alpine
pod/nginx-pod created
root@controlplane:~# kc get po
NAME        READY   STATUS              RESTARTS   AGE
nginx-pod   0/1     ContainerCreating   0          3s
root@controlplane:~#


3. Deploy a redis pod using the redis:alpine image with the labels set to tier=db.

Either use imperative commands to create the pod with the labels. Or else use imperative commands to generate the pod definition file, then add the labels before creating the pod using the file.

    Pod Name: redis
    Image: redis:alpine
    Labels: tier=db

Hints: Use the command kubectl run to create a pod redis using redis:alpine image with label tier=db.

root@controlplane:~# kc run redis --image=redis:alpine label tier=db --dry-run=client -oyaml > myredis.yaml
root@controlplane:~#

# vi myredis.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    tier: db
  name: redis
spec:
  containers:
  - image: redis:alpine
    name: redis
  dnsPolicy: ClusterFirst
  restartPolicy: Always

root@controlplane:~# kc create -f myredis.yaml
pod/redis created
root@controlplane:~# kc get po
NAME        READY   STATUS              RESTARTS   AGE
nginx-pod   1/1     Running             0          9m3s
redis       0/1     ContainerCreating   0          5s
root@controlplane:~#

Solution:
Run the command to generate the definition file:
$ kubectl run redis --image=redis:alpine --dry-run=client -oyaml > redis-pod.yaml
Add given labels tier=db under the metadata section.

4. Create a service redis-service to expose the redis application within the cluster on port 6379.
Use imperative commands.
    Service: redis-service
    Port: 6379
    Type: ClusterIP

Hints: Use the kubectl expose command.
Solution: Run the command: kubectl expose pod redis --port=6379 --name redis-service

root@controlplane:~# kc expose pod redis --port=6379 --name redis-service
service/redis-service exposed
root@controlplane:~# kc get pod
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          17m
redis       1/1     Running   0          8m4s
root@controlplane:~# kc get svc
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes      ClusterIP   10.96.0.1        <none>        443/TCP    37m
redis-service   ClusterIP   10.103.225.213   <none>        6379/TCP   37s
root@controlplane:~#

5. Create a deployment named webapp using the image kodekloud/webapp-color with 3 replicas.

Try to use imperative commands only. Do not create definition files.

    Name: webapp
    Image: kodekloud/webapp-color
    Replicas: 3

Hint: Use the command kubectl create to create a webapp deployment and scale the webapp to 3 using imperative command.

> kc create deployment webapp --image=kodekloud/webap-color --replicas=3
deployment.apps/webapp created
root@controlplane:~# kc get deployment
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
webapp   0/3     3            0           14s
root@controlplane:~# kc delete deployment webapp

root@controlplane:~# kc create deployment webapp --image=kodekloud/webapp-color --replicas=3
deployment.apps/webapp created
root@controlplane:~# kc get po
NAME                      READY   STATUS              RESTARTS   AGE
nginx-pod                 1/1     Running             0          21m
redis                     1/1     Running             0          12m
webapp-56847f875b-895sj   0/1     ContainerCreating   0          4s
webapp-56847f875b-9gz5q   0/1     ContainerCreating   0          4s
webapp-56847f875b-nct6p   0/1     ContainerCreating   0          4s

6. Create a new pod called custom-nginx using the nginx image and expose it on container port 8080.

    Pod created correctly?

> kc expose pod custom-nginx --image=nginx --port=8080

solution:
Run the command: kubectl run custom-nginx --image=nginx --port=8080
root@controlplane:~# kc run custom-nginx --image=nginx --port=8080
pod/custom-nginx created
root@controlplane:~# kc get po
NAME                      READY   STATUS              RESTARTS   AGE
custom-nginx              0/1     ContainerCreating   0          16s
nginx-pod                 1/1     Running             0          24m
redis                     1/1     Running             0          15m
webapp-56847f875b-895sj   1/1     Running             0          3m3s
webapp-56847f875b-9gz5q   1/1     Running             0          3m3s
webapp-56847f875b-nct6p   1/1     Running             0          3m3s
root@controlplane:~#

7. Create a new namespace called dev-ns.
Use imperative commands.

    Namespace created?
$ kc create ns dev-ns

9. Create a new deployment called redis-deploy in the dev-ns namespace with the redis image. It should have 2 replicas.
Use imperative commands.
    'redis-deploy' created in the 'dev-ns' namespace?
    replicas: 2

> kc create deployment redis-deploy --image=redis --replicas=3 --ns=dev-ns

Hints:
Step 1: Create the deployment YAML file
  $ kubectl create deployment redis-deploy --image redis --namespace=dev-ns --dry-run=client -o yaml > deploy.yaml
Step 2: Edit the YAML file and add update the replicas to 2
Step 3: Run kubectl apply -f deploy.yaml to create the deployment in the dev-ns namespace.
You can also use kubectl scale deployment or kubectl edit deployment to change the number of replicas once the object has been created.

solution:
Run the command: kubectl create deployment redis-deploy --image=redis --replicas=2 -n dev-ns

root@controlplane:~# kc create deployment redis-deploy --image=redis --replicas=2 -n dev-ns
deployment.apps/redis-deploy created

9. Create a pod called httpd using the image httpd:alpine in the default namespace. Next, create a service of type ClusterIP by the same name (httpd). The target port for the service should be 80.

Try to do this with as few steps as possible.

    'httpd' pod created with the correct image?
    'httpd' service is of type 'ClusterIP'?
    'httpd' service uses correct target port 80?
    'httpd' service exposes the 'httpd' pod?

Solution: Run the command: kubectl run httpd --image=httpd:alpine --port=80 --expose

root@controlplane:~# kc run httpd --image=httpd:alpine --port=80 expose
pod/httpd created
root@controlplane:~# kc get po -o wide
root@controlplane:~# kc delete pod httpd


root@controlplane:~# kc run httpd --image=httpd:alpine --port=80 --expose
service/httpd created
pod/httpd created




No comments:

Post a Comment

Git branch show detached HEAD

  Git branch show detached HEAD 1. List your branch $ git branch * (HEAD detached at f219e03)   00 2. Run re-set hard $ git reset --hard 3. ...