In this video, we're going to go over Mock Exam 2.
Let me first set up my environment so I don't have alias.
Let me do that first.
Kubectl cheat sheet.
Let me first have the auto-completion
and the kubectl alias.
That seems to be working.
All right, so let's get started.
The first question is to take a backup of the etcd cluster
and save it to this location.
To take a backup,
we use the etcdctl utility but let's see.
Let's look at the Kubernetes documentation pages.
Etcdctl backup.
Here you have a operating etcd cluster for Kubernetes
and here if you look at here on the right,
you have the backing up an etcd cluster section,
and here we have this command.
We're going to use this.
Let me just save that here.
Now we know that in order to communicate with the etdc server,
we need the endpoint and we also need the certificates.
If you do a etcdctl snapshot command,
you look at the help, we have a few options that are required,
the cacert, the cert, the key
and then we're going to specify this as the location.
First, we need to get those parameters.
We're going to look at the etcd servers manifest file
and we can just do a grab for file,
and we get to see all of the files that are passed in as parameters.
We'll start from there.
Let's do--
The other thing is the endpoint.
That's another thing that we need.
If we go into this file,
we see that the endpoint is 127001 and the port is 2379.
Let's get out of that.
We're going to start here.
Let's get all of this.
You can either set the endpoint as an environmental variable
or just pass it through.
Let's just do this.
127001, 2379, that's the port.
The file name is this.
Then we'll just pass in the remaining things here.
The first thing that we need is cacert.
We're going to pass that in.
The file name is ca file is right here.
The next thing, we need is cert
and the certificate file is right here.
The next one is the key
and the key file is right here.
It says, "Snapshot saved at opt etcd backup."
Let's just verify.
That's ended there.
Let's go to the next question.
The next question is to create a Pod called redia-storage
with the image resid:alpine with a Volume of type emptyDir
that lasts for the life of the Pod.
Specs are given below.
To create a Pod,
we're just going to use the kubectl run command
and the Pod name, it's going to be redia-storage,
and the image is going to be redis:alpine.
Now we've got to specify the volume.
For now, what we're going to do is we're just going to do a dry run
and close client,
and generate this into a yaml format.
That's that and then we're going to move that to the file
with the name of the Pod.
Now we've got to specify the volumes.
Let's look up pods and volumes
and we have this one right here,
and this talks about all of the different options for volumes,
and what we want is the empthyDir.
As you know the emptyDir is used to create a Pod
and it's a temporary volume that's created
and it exists as long as as long as the pod is running.
Here's an example.
You have the volume and you have the volume mount.
Let's create the volume first.
We'll just edit the yaml file we created
and the volume is always under the pod spec,
it's right here.
Here we are using the emptyDir as given here,
but let's see if there's a name.
The question does not really ask us to use a specific name,
so we could use any name.
In this case, we'll just leave it as it is.
We'll just call it cache volume, and then you have the volume mount.
Let's copy that.
This is inside the container section and we'll paste that here.
Now, this volume name and this mount name,
the volume name that's given here needs to match,
so this needs to be the same, but the mount path could be anything.
There is a path given here called /data, /Redis.
We're going to use that as the path.
Redis-storage, the name is Redis storage, image is Redis Alpine.
The volume type, volume type is empty Directory
and the mount path is data Redis.
Let's save that and let's create the file.
It's being created.
Let's just give it a few seconds.
It's done and we'll just do a describe pod Redis,
just to verify if everything's good.
Here you can see the mount is data Redis from cache volume,
and here you have the cache volume and the type is empty directory,
a temporary directory that shares a pod's lifetime.
That's that.
Let's go to the next one.
The next one is to create a new pod called super-user-pod
with image busybox 1.28,
to allow the pod to be able to set system time.
The container should sleep for 4,800 seconds.
Let's first create a pod.
So we're going to do kubectl, run, super-user pod,
image is busybox 1.28.
Then I'm not sure if we can pass in the capabilities.
Let's just check help, security context.
Search for security.
No. I don't think so.
We're just going to go the traditional route.
We're going to create the pod
with the image busybox 1.28,
and we'll just do a dry run
and output AML file for that
and output that to super-user-pod.aml.
Then we will edit that file.
Then now the goal is to allow the pod--
There's also a command, so I could have given the command
in the [?] command that I ran,
but since I didn't do that I'm just going to add it here.
The command is to sleep, sleep for 4,800 seconds.
The only thing that's pending now
is to allow the pod to be able to set the system time.
We know that it's under security capabilities,
so configure a security context for a pod in a container.
If you look here, you have set capabilities for a container,
and let's take a look.
Right here, you have security context and capabilities.
This is what we need,
and this needs to go inside containers,
so right here, inside the container section,
we have security context and capabilities.
We don't need the net admins, I'm going to remove that,
and it just needs system time.
Save that.
Let's create the file,
let's create the pod,
and then let's check the status and its running.
Let's do a describe pod, super-user-pod.
Here we have the super-user-pod, we have the command.
Let's go to the next question.
The next question is a pod definition file is created at root CK use PV.Yaml.
Let's take a look at that.
We have a pod definition file.
Make use of this manifest file
and mount the persistent volume called PV1,
and ensure the pod is running and the PV is bound
so that there's a mount path given.
There's also a persistent volume claim name given.
There's a pod definition file.
Let's check.
There is there a PV, so there is a PV.
Let's check if there is a PVC.
There aren't PVCs.
What we need to do is, in order to mount this PV to the pod,
we know that we're going to add a volume mount here
but the volume mount requires a volume.
That volume is going to be from a persistent volume claim
because that's how you claim a PV.
We have to create a PVC.
The first step is to create a PVC,
and then configure that as a volume mount within the pod.
As a volume in the pod
and then configure that volume as a volume mount in the pod.
PVC, volume, and then volume mount.
Let's look at PVCs.
We have personal volume here.
If you go to persistent volume claims,
you have persistent volume claim definition file here.
Let's just copy this.
What we want to do is we want to create a PVC
but for that, we need to know the capacity and the access mode.
We need to get those two, right,
only then it's going to be bound to this PV.
The capacity is 10 mebibytes, and access mode is read-write only.
Let's create a PVC.Yaml.
Let's copy this template.
The name is my PVC.
My-PVC.
The access mode is read-write once.
Volume mode is none.
Then we have storage and that is 10 mebibytes.
That should be it so let's create the PVC.
Okay, let's check the status, get PVCs.
We see that the PVC is created and it's bound.
It's bound to the PV-1.
The capacity and access modes match.
We've done the first step of creating the PVC.
The next step is to use it as a claim in the pod.
Let's edit this file.
We need two things. We need a volume and then a volume mount.
Let's go back here.
Let's look at claims as volumes, this section right here.
Then we have the personal volume claim.
We're going to copy this template.
This is under the spec section.
Volume, and does it need--
The volume name could really be anything.
We haven't been given any volume name so we can leave that as my PV
but the persistent volume claim has to be the one that we just created.
That's My-PVC.
Then inside here, we're going to have the volume mount.
The mount path is going to be data so that's data.
This name is MY-PD so this and this need to match.
They're already matching.
We've not been given a specific name to use
so we'll just leave it as it is.
We have my PVC here and it's going to be Mount2Data.
Let's create that pod
and let's check the pod status.
You see that it's in a container-creating state.
Let's give it a few seconds to be created.
That's done.
It's use PV so we're going to do a kubectl describe
use pod-usePV.
Okay, and here we see
we have the mount data from My-PD
and while your My-PD is from persistent volume claim,
and it's using the My-PVC.
All right.
Okay, so that's about it for that question.
Let's go to the next one.
The next one is to create a new deployment called NGINX Deploy
with image nginx:1.16 and one replica
and then upgrade the deployment to version 1.17.
Let's create a deployment, so kubm ectl create deployment.
We'll call it nginx-deploy.
Let's just copy and paste.
It has to use the image nginx:1.16
and replica is going to be one,
replicas is going to be one.
Okay, so let's do a kubectl get deploy.
It's just getting ready.
Yes, so it's ready.
Let's do a kubectl describe deployment, nginx-deploy
and we see that is created.
It has the image 1.16 and it's created a replica set,
and it's scaled the replica set to one.
Okay, so that's all good.
The next step is to upgrade the deployment to version 1.17.
To upgrade a deployment,
we could use the kubectl set image command.
Let's do a help on that.
Here we see kubectl set image deployment, the deployment name,
and then you have the container and the container name.
Let's use this.
Okay, so the image, the deployment name is nginx-deploy,
nginx-deploy
and there's no container called busybox,
and the image name here is 1.17.
Now, remember that this right here is the image,
this is the container name,
so we want to make sure the container name is right.
Let's do a kubectl describe, deploy nginx-deploy.
What is the container name?
The container name is nginx, so that is right.
This should be this, these need to match.
Okay, so let's run the same command.
The version that we want to update to is 1.17.
Okay.
Let's do a describe deploy again and here we see that it's now indeed 1.17.
It is now scaled up, the replica set.
It's created a new replica set and scaled that up.
If you look at this, the strategy is already set to rolling update
so there's nothing that we have to do there.
That's that question.
Let's go to the next one.
Here, we have to create a new user called John
and grant him access to the cluster.
John should have permissions to create list,
get update and delete pods in the development namespace
and the private key exists in this location.
There's the private key and the CSR are available here.
You have root CKA and the files are there.
Let's go there, root CKA.
As of Kubernetes, 1.19,
the Certificate Signing Request object expects the signer name, yes.
Please refer to the documentation.
The CSR has to be John Developer,
and the role name is developer and the resource is pods,
and the namespace should be within the development namespace.
Ultimately, we want to make sure that the user John
has appropriate permissions.
If you look at the John CSR, you have the Certificate Signing Request.
Our approach here is to first create a Certificate Signing Request
on Kubernetes
and get that approved so we have the user in the system.
Then we create a role with these privileges,
the create list, and get update and delete pods privileges
for the development namespace.
It has to be named as the role name is developer
and then just for pods,
and then we have to create a role binding to bind this role to the user John.
The username is John.
That's what we have to do.
The first thing is to-- Let's look at role binding,
or using RBAC, so just search for RBAC.
Here we have the Certificate Signing Requests.
Actually, it's available here.
That's the first step.
We could have just searched for Certificates Signing Requests.
If you come down there should be a template for creating, yes,
it's right here.
Let's copy this and let's create a file called CSR.Yaml.
Maybe John.Yaml.
Let's space that.
The Certificate Signing Request has to be named John developer.
Copy that.
The signer name is already given, so that's good.
We don't need to set an expiry because it's not mentioned here.
Then now we have to specify the CSR here.
Let's just save this
and let's get this Certificate Signing Request
in the base64 format.
If you look here, there are instructions here
to get the base64 code of format.
You could actually just use this command,
so let's just use that, and here we have it.
Let's copy it all the way till here, right before root.
Then let's edit the file
John CSR.
Let's just delete this line
and add a new line or request.
I'm going to paste that.
We have John developer is the Certificate Signing Request.
The signer name is there.
Usages are there, that's fine and then the request.
Let's do that.
Let's create Certificate Signing Request, so it's created.
Then so let's check.
You look at the Certificate Signing Requests.
If you look at the Certificate Signing Requests,
you have John developer and it's in a pending state.
Let's approve that request.
Let's do a kubectl certificate approve John developer.
It's approved.
Let's check the status now and we see that it's in a approved state.
That's good.
We are through with the first step.
The next step is to create the role with these privileges.
We're going to do kubectl create a role.
Let's just take a look at help real quick.
We have something like this,
so we could use create role and then the verbs and the resources
that we should have access to, so maybe this one.
The role name is given here, so it has to be developer
and then the verbs are create list,
get are already there.
There is no watch.
We're good to remove that,
so it's create list get update, and delete.
Create list, get update, and delete
and the resource is pods.
Remember, this is also in the development namespace
so the namespace is development.
Let's create that.
Let's get roles in the development namespace.
We had the developer role, let's just do a describe role
and we see that it indeed has pods and create, get list, update, and delete.
The next step is to create a role binding, which will bind this role to that user.
Before that, we want to just check using the kubectl auth command.
The auth command will help us check if a user can do something right.
We're going to do a auth can I command so can I--
We're going to do kubectl auth can I create pods
as a specific user in a specific namespace.
We want to see if I can get pods
in the namespace development as the user.
We could use as, as John.
It says, no.
How about create or anything else.
It's no.
After we create the RoleBinding, this should change to yes.
That's the goal here.
Let's create the role binding, let's do a kubectl, create role binding.
Look at the help,
so create a RoleBinding, the name of the RoleBinding,
and then the role and the user.
That's what we have to do.
RoleBinding, we're going to call it the same as the role.
This is for John so let's just call it John developer
and the role is developer
and the user is John.
We forgot to specify the namespace so let's just delete that
just delete that and let's recreate it in the development namespace.
Let's do a get role binding
in the development namespace.
We have a John developer there,
let's do a describe role bindings in the development namespace.
We see that the user John has this.
Let's run the auth command again, so kubectl, auth can I get pods as John?
In the development namespace, it says yes.
How about create?
Yes.
How about something that we haven't given, let's say watch?
No.
That proves that that's working.
All right, let's go to the next one.
The next question says, create nginx pod called nginx-resolver
using the image nginx.
Expose it internally with a service called nginx resolver service.
Then test that you are able to look up the service and pod names
from within the cluster
and for that we can use the image busybox:1.28
to create a pod for the DNS lookup.
Then record the results in the nginx servers
as well as nginx.pod
for the service and pod name resolution respectively.
The first step is to create nginx pod so we do a kubectl run,
nginx-resolver and the image is nginx.
Expose it internally with a service called nginx resolve
so let's create this first.
We have the pod which is the nginx resolver
and that's running.
The next step is to expose it as a service
so we do a kubectl expose pod nginx resolver.
The type it says expose it internally so it's just a cluster IP type
so we don't have to specify that.
We do have to give our service a name which is the nginx resolver service.
Let's do that,
require support so the nginx pod is 80 so let's specify that.
Then the next task is to do nslookup
using the busybox:1.28 image by creating a pod.
Before that, let's just verify the service that we have created
and that is nginx resolver service.
We see that it does have an endpoint
and it's got the service selectors as well.
The next task is to run a busybox image,
so a kubectl run busybox.
Let's just call it busybox
and the image is going to be busybox 1.28.
What we can do is we can just do a sleep
so it keeps running and then after we can--
Let's just put a sleep for 4,000 so it keeps running in the background.
Let's do a pod and we see that we do have the busybox pod running.
We can now do an exec and do exec into the busybox
and then we run the nslookup command.
We do nslookup.
The first thing that we want to do is resolve this service.
Let's just resolve the service by its name.
As you can see it's resolved the service
so all you have to do since the busybox image,
the pod, and the next resolver are in the same namespace,
all you have to do is do a lookup to the service name.
This just works.
We're going to redirect that output to this next service.
The next step is to resolve the pod name
and direct it to here.
If you're not sure about the pod name resolution
just search for DNS,
and here you have DNS for services and pods.
If you look at pods here,
the pod resolution is always the pod IP address
and then the service, pod, and cluster local.
The IP address has to be a dash delimited so let's do that.
Let's first find out the IP address of the nginx pod.
Let's do a kubectl get pods-o wide.
We have the nginx resolver and we have the IP.
Then we're going to do an nslookup
to default.cluster.local.
The IP address is going to be delimited by a dash instead of a dot.
It's going to change that.
This is the namespace,
and this is cluster.local, that's the root domain.
I'm going to remove this so I can first see.
That didn't go through.
Let's try.
You have the IP address.
It says it ended with exit code one.default.cluster.local.
It's default. pod.cluster.local. I missed that.
Pod.cluster.local.
That seems to be resolving fine so let's move that to this file.
That should be all for this.
Let's go to the next one.
The final question.
This one is about creating a static pod on Node01
called nginx critical with the image nginx
and making sure that it's recreated, restarted automatically
in case of a failure.
There's also the path to the static pod given here.
This needs to be done on Node01.
That's important to note.
We're going to SSH to Node01.
If you don't know how to find Node01, let's do a get nodes-o wide.
We can get the IP address here.
That's SSH to this node.
The static pods, as we know are in etc Kubernetes manifests.
There's a directory there,
but there are no static pods at the moment.
All we need to do is create a pod definition file
and put it there.
Let's see if we have kubectl utility here.
Yes, there is.
Let's do kubectl run,
the pod name is nginx-critical, and the image is nginx.
Make sure that it's created restarted automatically.
There is a restart.
We are just referring to the restart policy.
Let's just check about the restart policy option.
We have the research policy.
By default, it's said to always.
There's really no reason of specifying that.
We're going to create a pod definition file.
For that, let's just go to the masters.
I'm going to open a new terminal to the master.
What we want to do is we want to create a pod definition file.
We're going to do a kubectl run nginx-critical.
That's the name of the pod, with the image nginx.
If you want, we can specify the restart policy to always,
but by default it's set to always so doesn't really matter.
Then we're going to do a dry-run=client -o yaml.
This is the file.
I'm going to copy this.
What we'll do is we'll create a file at etc/kubernetes/manifests in node01.
We'll call it nginx-critical.yaml.
Same name as the pod.
We know that as soon as we create this file,
if we do a kubectl get pods,
we'll see that its already created the static pod
with the node name at the end.
If you look at describe pod nginx critical,
we see that it gives us the nginx image.
That should be it.
That's the end of this mock exam.
Let's check our work.
Waiting the end exam button.
We have 10%, 20%, 40%, 55%, 70%,
85%, and 100%.
That's the end of that mock exam.