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