1 00:00:00,601 --> 00:00:03,901 Now that we know what a Pod is and how it works, 2 00:00:04,067 --> 00:00:07,701 let's create one by ourselves. We have seen 3 00:00:07,701 --> 00:00:10,867 previously, that there are two ways to create any 4 00:00:10,867 --> 00:00:14,867 object in Kubernetes, imperative and declarative. 5 00:00:15,001 --> 00:00:18,334 To make sure that we cover both of these ways, we 6 00:00:18,334 --> 00:00:21,867 have two terminals open side by side. In one 7 00:00:21,867 --> 00:00:25,001 terminal, we'll create a Pod imperatively, 8 00:00:25,067 --> 00:00:27,834 whereas on the other terminal, we will create the 9 00:00:27,834 --> 00:00:30,801 pod declaratively. We have these terminals side 10 00:00:30,801 --> 00:00:33,767 by side so that we can compare them once both of 11 00:00:33,767 --> 00:00:37,667 them are created. Let's start with the imperative one. 12 00:00:37,667 --> 00:00:40,834 For creating a Pod imperatively, we need to 13 00:00:40,834 --> 00:00:43,867 provide all of the specifications through either a 14 00:00:43,867 --> 00:00:48,167 command or a YAML file, we will choose yaml this time. 15 00:00:48,167 --> 00:00:53,267 Let's write a file called imperative-pod.yaml. 16 00:00:53,267 --> 00:00:56,734 We are using nano as our text editor, but you 17 00:00:56,734 --> 00:01:00,034 can use any text editor which you want. The basics 18 00:01:00,034 --> 00:01:03,334 of the YAML file remains the same as Docker Compose. 19 00:01:03,334 --> 00:01:05,467 Only difference would be the fields, 20 00:01:05,467 --> 00:01:08,834 which would be indicated as key value pairs. 21 00:01:08,834 --> 00:01:13,201 With that said, let's get started. Our first field or 22 00:01:13,201 --> 00:01:18,034 first key value pair is API version. This field is 23 00:01:18,034 --> 00:01:21,567 used to let Kubernetes know which version of API 24 00:01:21,567 --> 00:01:24,301 is being used to create this object. For more 25 00:01:24,301 --> 00:01:27,267 information about the API versions, and which 26 00:01:27,267 --> 00:01:29,967 version to use for which object, you can follow 27 00:01:29,967 --> 00:01:32,967 the official Kubernetes documentation by going to 28 00:01:32,967 --> 00:01:37,467 the following link. Next up, we have kind, 29 00:01:37,467 --> 00:01:42,534 kind specifies which kind or which type of object is to 30 00:01:42,534 --> 00:01:45,634 be created using this file, we want to create a 31 00:01:45,634 --> 00:01:50,334 Pod. So our kind field or kind key, will have 32 00:01:50,334 --> 00:01:55,467 the value Pod. Next up we have metadata. It does 33 00:01:55,467 --> 00:01:58,801 what its name suggests, it is data about the 34 00:01:58,801 --> 00:02:01,867 object which is going to be created. Typically, 35 00:02:01,867 --> 00:02:05,401 metadata would contain fields like names, labels, 36 00:02:05,401 --> 00:02:08,533 and so on. The primary use of metadata in 37 00:02:08,533 --> 00:02:12,667 Kubernetes is for us and the Kubernetes itself to 38 00:02:12,667 --> 00:02:17,667 identify, group and sort the Pods. We want to name 39 00:02:17,667 --> 00:02:22,767 the Pod as imp, or imp-pod, and we want to 40 00:02:22,767 --> 00:02:27,001 give a label, which says app equals myapp. 41 00:02:27,101 --> 00:02:31,034 You may have noticed that labels are a key value pair. 42 00:02:31,034 --> 00:02:35,067 For now, let's not dwell too deep into labels and 43 00:02:35,067 --> 00:02:38,434 let's go further. Next up we have spec field, 44 00:02:38,601 --> 00:02:42,567 which stands for specifications. You can consider 45 00:02:42,567 --> 00:02:45,934 spec as the most important field of this file. 46 00:02:45,934 --> 00:02:50,234 And why is that? Well, the reason is quite obvious. 47 00:02:50,601 --> 00:02:53,501 Specs are used to provide object configuration 48 00:02:53,501 --> 00:02:58,267 information, which means that here, spec field 49 00:02:58,267 --> 00:03:02,001 will provide information and configurations about 50 00:03:02,001 --> 00:03:07,301 the Pod itself. Our first spec is containers. 51 00:03:07,667 --> 00:03:12,034 Unlike Docker, containers are just a specification 52 00:03:12,034 --> 00:03:15,667 or a field of the parent object, which is Pod. 53 00:03:16,001 --> 00:03:19,734 Specifications may vary with objects, which means 54 00:03:19,734 --> 00:03:21,501 that different objects may have different 55 00:03:21,501 --> 00:03:24,867 specifications and different fields to provide 56 00:03:24,867 --> 00:03:29,134 them. Our next entry under the containers spec is 57 00:03:29,134 --> 00:03:32,167 the name of the container. It is different from 58 00:03:32,167 --> 00:03:36,167 the name of the Pod. In theory, you can keep both 59 00:03:36,167 --> 00:03:38,867 of them same, but keeping them different makes 60 00:03:38,867 --> 00:03:43,034 things simpler. Next up, we have image field image 61 00:03:43,034 --> 00:03:45,534 field describes the image which is going to be 62 00:03:45,534 --> 00:03:49,534 used to run this container. By default, Kubernetes 63 00:03:49,534 --> 00:03:52,867 uses images from Docker Hub, but if we want to use 64 00:03:52,867 --> 00:03:56,067 other registries, we need to provide specific URL, 65 00:03:56,067 --> 00:03:58,734 but we will get into that later. Next up we have 66 00:03:58,734 --> 00:04:02,234 command this one is quite simple to comprehend. 67 00:04:02,234 --> 00:04:05,967 We are asking our container to run shell command and 68 00:04:05,967 --> 00:04:08,967 echo a string called 'Welcome to Container 69 00:04:09,001 --> 00:04:11,701 MasterClass by CeruleanCanvas' 70 00:04:11,701 --> 00:04:15,401 and sleep for 60 seconds. We have mentioned all of 71 00:04:15,401 --> 00:04:18,401 the required specifications to create this Pod. 72 00:04:18,401 --> 00:04:21,867 Let's save our file and exit the text editor 73 00:04:21,867 --> 00:04:25,901 Parallely, we are also writing another file called 74 00:04:25,901 --> 00:04:29,767 declarative-pod.yaml. And as you can see, 75 00:04:29,767 --> 00:04:32,601 they're also providing similar fields as previous 76 00:04:32,601 --> 00:04:37,401 file in this one such as API version, kind, and 77 00:04:37,401 --> 00:04:40,601 metadata. To distinguish this Pod from previous 78 00:04:40,601 --> 00:04:44,067 Pod, we are giving it a different name, but both of 79 00:04:44,067 --> 00:04:47,701 the pods will contain same label. Next up, we have 80 00:04:47,701 --> 00:04:51,334 specifications. Again, the name of the container 81 00:04:51,334 --> 00:04:55,167 is changing but the image is remaining the same. 82 00:04:55,667 --> 00:04:59,001 And this time, we are asking it to print the same 83 00:04:59,001 --> 00:05:02,534 string but sleep for 60 more seconds. Let's save 84 00:05:02,534 --> 00:05:06,067 this and exit as well. Let's go back to our left 85 00:05:06,067 --> 00:05:10,867 hand terminal and write the command kubectl create -f 86 00:05:10,867 --> 00:05:13,734 imperative-pod.yaml. We are 87 00:05:13,734 --> 00:05:18,267 asking kubectl to create an object from this 88 00:05:18,267 --> 00:05:21,267 particular file. As a nod to success of this 89 00:05:21,267 --> 00:05:26,001 command, we receive the notification of imp-pod 90 00:05:26,001 --> 00:05:28,701 having been created. Let's go back to right 91 00:05:28,701 --> 00:05:32,167 hand side terminal. Unlike imperative way, we will 92 00:05:32,167 --> 00:05:35,834 write the command kubectl apply and mentioned the 93 00:05:35,834 --> 00:05:40,401 file using -f flag, and the Pod is created 94 00:05:40,401 --> 00:05:43,701 as well. In this case, even if we had wanted to 95 00:05:43,701 --> 00:05:46,567 delete or scale the Pod, the command would have 96 00:05:46,567 --> 00:05:50,234 been the same Kubernetes or kubectl would have 97 00:05:50,234 --> 00:05:52,967 figured it out by itself. What do we want to 98 00:05:52,967 --> 00:05:55,567 convey through the file, whereas in case of 99 00:05:55,567 --> 00:05:58,734 imperative command, we specifically had to tell 100 00:05:58,734 --> 00:06:02,301 Kubernetes to create an object. In any case, both 101 00:06:02,301 --> 00:06:04,901 our imperative and declarative Pods are created. 102 00:06:04,901 --> 00:06:07,134 So let's see if they are running or not. 103 00:06:07,267 --> 00:06:11,234 Like kubectl get pods, we will be using this command a 104 00:06:11,234 --> 00:06:15,201 lot in future demos. It gives a well arranged list 105 00:06:15,201 --> 00:06:18,867 of Pods along with a few more attributes, like how 106 00:06:18,867 --> 00:06:21,567 many of the listed Pods are ready, what is the 107 00:06:21,567 --> 00:06:24,934 status of each and every Pod, whether there was any 108 00:06:24,934 --> 00:06:28,367 restarts during the runtime of the Pod, and since 109 00:06:28,367 --> 00:06:31,301 how long is the Pod running, we can see both 110 00:06:31,301 --> 00:06:33,701 imperative and declarative pod having been 111 00:06:33,701 --> 00:06:36,634 created. Now let's dig deeper into both of the 112 00:06:36,634 --> 00:06:41,667 Pods by writing the command kubectl describe pods, 113 00:06:41,667 --> 00:06:44,767 followed by the name of the Pod, which in 114 00:06:44,767 --> 00:06:49,501 this case, is imp-pod. We will also run the same 115 00:06:49,501 --> 00:06:53,901 command on the right hand side or declare to terminal as well. 116 00:06:54,501 --> 00:06:56,867 Now we have descriptions of both 117 00:06:56,867 --> 00:06:59,867 of the Pods, so we can make a fair comparison. 118 00:06:59,867 --> 00:07:02,834 Let's start from the top. First of all, we have 119 00:07:02,834 --> 00:07:05,967 Name of both of the parts, which are unique. 120 00:07:05,967 --> 00:07:10,101 Then, we can see that both of the Pods are allotted to 121 00:07:10,101 --> 00:07:13,767 the same Namespace, which is default Namespace. 122 00:07:13,901 --> 00:07:17,634 Our imperative Pod is scheduled on node-2, 123 00:07:17,634 --> 00:07:20,934 whereas declarative Pod is scheduled on node-1. 124 00:07:20,934 --> 00:07:24,434 We also have that starting timestamps and their 125 00:07:24,434 --> 00:07:28,034 labels, which is common. As for the differences, 126 00:07:28,034 --> 00:07:31,667 our imperative Pod doesn't have any annotations, 127 00:07:31,667 --> 00:07:34,701 whereas the declarative pod has quite a few of 128 00:07:34,701 --> 00:07:38,101 them. The reason behind that is, kubectl has used 129 00:07:38,101 --> 00:07:41,067 the configuration which were provided by us to 130 00:07:41,067 --> 00:07:45,001 create the Pod in case of imperative Pod. Whereas 131 00:07:45,001 --> 00:07:48,567 in case of declarative Pod, it has used a specified 132 00:07:48,567 --> 00:07:53,167 Pod template, and has just filled in or replaced 133 00:07:53,167 --> 00:07:55,634 the information which we have provided. 134 00:07:55,634 --> 00:07:59,634 Moving further, we have IP for both of the Pods, but 135 00:07:59,634 --> 00:08:02,867 we'll get into that later. Next up, we have 136 00:08:02,867 --> 00:08:06,334 Container information. As you can see, both of the 137 00:08:06,334 --> 00:08:09,101 container have different Names and different 138 00:08:09,101 --> 00:08:12,634 Container IDs. But the container Image and the 139 00:08:12,634 --> 00:08:16,834 Image IDs are same. We also have the command which 140 00:08:16,834 --> 00:08:19,467 is going to be executed by both of the containers, 141 00:08:19,467 --> 00:08:22,801 and it has a slight difference as we had mentioned. 142 00:08:22,801 --> 00:08:25,901 Moving further, we have the state of 143 00:08:25,901 --> 00:08:29,034 the container which is running in both of the cases. 144 00:08:29,034 --> 00:08:31,834 And we also have the starting timestamp of 145 00:08:31,834 --> 00:08:35,034 the container, which means that this is the point 146 00:08:35,034 --> 00:08:38,301 where the container went from Created state to 147 00:08:38,301 --> 00:08:41,134 Started state. Our first container, which is 148 00:08:41,134 --> 00:08:45,501 imperative or imp container has already exited or 149 00:08:45,501 --> 00:08:49,034 terminated because it was completed. Whereas same 150 00:08:49,034 --> 00:08:51,567 is not the case with the other one because the 151 00:08:51,567 --> 00:08:54,034 sleeping period was a bit longer. 152 00:08:54,567 --> 00:08:57,801 Next up, we have Mount and Volume information, 153 00:08:57,801 --> 00:09:00,734 but we don't need to dwell too deep into that right now. 154 00:09:00,734 --> 00:09:05,467 We will look into them when we study volumes for Kubernetes. 155 00:09:05,467 --> 00:09:07,901 My personal favorite part about the 156 00:09:07,901 --> 00:09:11,334 description of the containers is the events. This 157 00:09:11,334 --> 00:09:14,234 is different from how we used to inspect our 158 00:09:14,234 --> 00:09:17,901 containers using Docker. Kubernetes gives us a 159 00:09:17,901 --> 00:09:20,701 short and sweet summary of events, which were 160 00:09:20,701 --> 00:09:24,234 really important. We can see that both of the 161 00:09:24,234 --> 00:09:27,367 containers went through a bunch of events, 162 00:09:27,367 --> 00:09:31,134 including their scheduling, pulling an image, 163 00:09:31,301 --> 00:09:35,501 containers having been created, and finally started. 164 00:09:35,667 --> 00:09:38,601 So this is how we can create and 165 00:09:38,601 --> 00:09:41,367 distinguish imperative and declarative Pods.