1
00:00:02,160 --> 00:00:03,969
Now to get our hands dirty,

2
00:00:03,969 --> 00:00:07,590
attached to find a very simple web application,

3
00:00:07,590 --> 00:00:10,790
a very simple Node.js application

4
00:00:10,790 --> 00:00:13,200
which just has two end points,

5
00:00:13,200 --> 00:00:17,660
a get request to /nothing and one to /error

6
00:00:17,660 --> 00:00:20,250
which will then crash this node application

7
00:00:20,250 --> 00:00:21,660
with this code line.

8
00:00:21,660 --> 00:00:23,130
I'll come back to that later.

9
00:00:23,130 --> 00:00:27,093
And let's deploy this to our kubernetes cluster.

10
00:00:28,350 --> 00:00:30,360
Now there's one super important thing

11
00:00:30,360 --> 00:00:33,060
which is easy to forget now

12
00:00:33,060 --> 00:00:35,870
with all that new kubernetes knowledge.

13
00:00:35,870 --> 00:00:38,389
We still need to use Docker

14
00:00:38,389 --> 00:00:41,820
to create an image based on this application

15
00:00:41,820 --> 00:00:45,190
because kubernetes is all about containers.

16
00:00:45,190 --> 00:00:48,820
And in order to run containers, it needs an image, right?

17
00:00:48,820 --> 00:00:50,620
That does not change.

18
00:00:50,620 --> 00:00:52,010
So while you'll learn about images

19
00:00:52,010 --> 00:00:54,250
and containers still applies.

20
00:00:54,250 --> 00:00:56,820
The only difference with kubernetes will be

21
00:00:56,820 --> 00:00:59,670
that you don't run your containers on your own anymore

22
00:00:59,670 --> 00:01:02,300
but we still need to create the images

23
00:01:02,300 --> 00:01:04,882
which we want to run as containers.

24
00:01:05,820 --> 00:01:09,760
So that's why I also added a Dockerfile to this project.

25
00:01:09,760 --> 00:01:13,330
A very simple Node.js app Dockerfile

26
00:01:13,330 --> 00:01:15,980
as we saw it many times throughout this course.

27
00:01:15,980 --> 00:01:18,490
Setting a base image and the working directory,

28
00:01:18,490 --> 00:01:21,960
installing dependencies, copying over the source code,

29
00:01:21,960 --> 00:01:23,630
exposing port 8080

30
00:01:23,630 --> 00:01:26,440
because that is the port we're listening on here.

31
00:01:26,440 --> 00:01:30,630
And then running this app.js file with the node executable

32
00:01:30,630 --> 00:01:32,313
when the container starts.

33
00:01:33,210 --> 00:01:36,380
Now, we could absolutely run this application locally

34
00:01:36,380 --> 00:01:41,380
but of course, I now want to run this on my cluster.

35
00:01:41,390 --> 00:01:45,070
And for this I'll open up the terminal here in my IDE.

36
00:01:45,070 --> 00:01:48,920
And first of all, build this image with docker build

37
00:01:48,920 --> 00:01:53,090
and give it a name of maybe kub-first-app.

38
00:01:56,300 --> 00:01:57,350
That's my name.

39
00:01:57,350 --> 00:02:00,060
And of course you can pick any name you want.

40
00:02:00,060 --> 00:02:02,390
This will now build this as an image

41
00:02:02,390 --> 00:02:03,930
and for me it's super fast

42
00:02:03,930 --> 00:02:06,970
because I already built it off screen before.

43
00:02:06,970 --> 00:02:08,520
But there's nothing fancy about it,

44
00:02:08,520 --> 00:02:11,430
we just built this image as we did it multiple times

45
00:02:11,430 --> 00:02:12,530
throughout the course.

46
00:02:14,300 --> 00:02:16,460
Now, once the image is built,

47
00:02:16,460 --> 00:02:20,090
we kind of wanna send it to the Kubernetes cluster

48
00:02:20,090 --> 00:02:24,300
but of course not like this, but instead as part of a pod

49
00:02:24,300 --> 00:02:28,680
or actually as we learned as part of a deployment,

50
00:02:28,680 --> 00:02:30,257
which will then create the pod

51
00:02:30,257 --> 00:02:34,333
and they offered a container running into pod for us,

52
00:02:34,333 --> 00:02:37,023
and it will also manage it for us.

53
00:02:37,920 --> 00:02:39,380
And to do that,

54
00:02:39,380 --> 00:02:43,130
to send this instruction to the Kubernetes cluster,

55
00:02:43,130 --> 00:02:45,380
we first of all need to ensure

56
00:02:45,380 --> 00:02:48,040
that this cluster is up and running.

57
00:02:48,040 --> 00:02:50,320
Now, if you followed along in the last lectures,

58
00:02:50,320 --> 00:02:51,700
that should be the case,

59
00:02:51,700 --> 00:02:54,320
but you can run minikube status

60
00:02:54,320 --> 00:02:56,460
to check whether it is up and running.

61
00:02:56,460 --> 00:02:58,440
And you should see a bunch of running here,

62
00:02:58,440 --> 00:03:01,470
which means this cluster is up and running.

63
00:03:01,470 --> 00:03:02,540
If it's not,

64
00:03:02,540 --> 00:03:07,100
you can restart it with minikube start --driver=docker

65
00:03:07,100 --> 00:03:11,140
and then set the driver to virtual box if you installed that

66
00:03:11,140 --> 00:03:13,470
or give docker a try,

67
00:03:13,470 --> 00:03:16,640
which is actually pretty inception like,

68
00:03:16,640 --> 00:03:19,000
because we would then use docker

69
00:03:19,000 --> 00:03:22,210
to create a virtual environment,

70
00:03:22,210 --> 00:03:26,420
a containerized environment in this case for the cluster,

71
00:03:26,420 --> 00:03:28,961
which we simulate on our local machine

72
00:03:28,961 --> 00:03:33,961
to then test Kubernetes which again is all about containers.

73
00:03:34,200 --> 00:03:38,580
Boom, head explosion, but it should also work as a driver

74
00:03:38,580 --> 00:03:41,080
so that is a virtual cluster,

75
00:03:41,080 --> 00:03:42,770
this cluster in a virtual machine

76
00:03:42,770 --> 00:03:46,320
is created with help of docker instead of virtual box.

77
00:03:46,320 --> 00:03:47,980
And on windows 10 pro,

78
00:03:47,980 --> 00:03:50,563
you should also be able to use hyper-V.

79
00:03:51,970 --> 00:03:54,370
Now I already got the cluster up and running.

80
00:03:54,370 --> 00:03:57,630
So with that, we can now send our image

81
00:03:57,630 --> 00:04:00,970
or send the instruction to create a deployment

82
00:04:00,970 --> 00:04:02,555
to that cluster.

83
00:04:02,555 --> 00:04:05,547
And we do this with this kubectl, this kubectl command.

84
00:04:08,010 --> 00:04:10,690
Remember that we also installed this tool

85
00:04:10,690 --> 00:04:12,600
over the last lectures.

86
00:04:12,600 --> 00:04:13,760
This is the command

87
00:04:13,760 --> 00:04:17,149
which you always execute on your local machine.

88
00:04:17,149 --> 00:04:20,260
So this will not change once we move to the cloud.

89
00:04:20,260 --> 00:04:23,080
This always executes on the local machine

90
00:04:23,080 --> 00:04:27,270
because this is the command we use to send instructions

91
00:04:27,270 --> 00:04:29,390
to our kubernetes cluster.

92
00:04:29,390 --> 00:04:32,580
So to master node and to control plane

93
00:04:32,580 --> 00:04:34,453
in that cluster so to say.

94
00:04:35,390 --> 00:04:36,970
So this is the command we need.

95
00:04:36,970 --> 00:04:39,930
And now this actually supports a broad variety

96
00:04:39,930 --> 00:04:42,190
of things we can do.

97
00:04:42,190 --> 00:04:45,698
If you just type kubectl help,

98
00:04:45,698 --> 00:04:50,350
you get a long list of commands you can execute.

99
00:04:50,350 --> 00:04:53,870
So there's a lot you can do, and this can be overwhelming

100
00:04:53,870 --> 00:04:58,870
but we actually only need a fraction of these things here.

101
00:04:59,130 --> 00:05:00,720
Now, of course, you can always dive

102
00:05:00,720 --> 00:05:03,910
in the official kubernetes docs if you wanna learn more

103
00:05:03,910 --> 00:05:06,870
but I will also show you the most important things

104
00:05:06,870 --> 00:05:09,473
throughout this and the next modules.

105
00:05:11,860 --> 00:05:16,190
So here we wanna use the kubectl command

106
00:05:16,190 --> 00:05:19,570
to create a new deployment object.

107
00:05:19,570 --> 00:05:22,640
Because as I mentioned, you work with these objects,

108
00:05:22,640 --> 00:05:25,710
which are then picked up by the Kubernetes cluster

109
00:05:25,710 --> 00:05:27,380
to then do something.

110
00:05:27,380 --> 00:05:31,660
And you create objects with the kubectl create command.

111
00:05:31,660 --> 00:05:33,700
Now, if you just hit enter like this,

112
00:05:33,700 --> 00:05:36,280
you actually get help for this command.

113
00:05:36,280 --> 00:05:39,240
And you can see what you can create there,

114
00:05:39,240 --> 00:05:41,290
basically these things.

115
00:05:41,290 --> 00:05:44,940
And for the moment we need to create a deployment object.

116
00:05:44,940 --> 00:05:48,690
And this is one of the most common objects you will create.

117
00:05:48,690 --> 00:05:52,640
As a side note at the moment, by using this create command,

118
00:05:52,640 --> 00:05:57,640
we are using this imperative approach of creating objects.

119
00:05:58,270 --> 00:06:02,550
Later, I will also show you the declarative approach.

120
00:06:02,550 --> 00:06:04,370
But for the moment we run create

121
00:06:04,370 --> 00:06:06,380
and we run create deployment,

122
00:06:06,380 --> 00:06:08,860
to create a new deployment object.

123
00:06:08,860 --> 00:06:11,730
And this object is then also automatically sent

124
00:06:11,730 --> 00:06:13,280
to the Kubernetes cluster.

125
00:06:13,280 --> 00:06:17,100
So we don't need to run a separate command for this.

126
00:06:17,100 --> 00:06:18,940
Now this deployment should get a name

127
00:06:18,940 --> 00:06:20,650
and we could name it first-app,

128
00:06:20,650 --> 00:06:23,550
but of course, this name is totally up to you.

129
00:06:23,550 --> 00:06:27,390
And then we need to specify one important thing here.

130
00:06:27,390 --> 00:06:30,780
We need to pass one important option.

131
00:06:30,780 --> 00:06:35,660
And that's the --image option, where we wanna specify

132
00:06:35,660 --> 00:06:39,073
which image should be used for the container

133
00:06:39,073 --> 00:06:42,750
of the pod created by this deployment.

134
00:06:42,750 --> 00:06:45,670
And this is --image=.

135
00:06:45,670 --> 00:06:49,340
Now here, you could of course think that you simply use

136
00:06:49,340 --> 00:06:53,280
that local image we just created, kub-first-app.

137
00:06:53,280 --> 00:06:56,100
That's the image I just built locally.

138
00:06:56,100 --> 00:06:58,330
But this actually won't work

139
00:06:58,330 --> 00:07:00,350
as you will see if you hit enter.

140
00:07:00,350 --> 00:07:03,040
You actually get a success message here.

141
00:07:03,040 --> 00:07:08,040
But if we now run another command, kubectl get deployments,

142
00:07:08,270 --> 00:07:12,050
we can see how many deployments we have in our cluster

143
00:07:12,050 --> 00:07:13,620
to which we connected here.

144
00:07:13,620 --> 00:07:17,280
By the way, kubectl was configured by minikube

145
00:07:17,280 --> 00:07:19,740
to automatically connect to minikube

146
00:07:19,740 --> 00:07:21,303
so we don't need to tell the command

147
00:07:21,303 --> 00:07:24,550
that we wanna interact with minikube here.

148
00:07:24,550 --> 00:07:26,180
So if I now run gets deployments,

149
00:07:26,180 --> 00:07:29,542
I see all the deployments in my minikube demo cluster

150
00:07:29,542 --> 00:07:33,090
and we see the deployment we just made.

151
00:07:33,090 --> 00:07:35,130
But we also see this.

152
00:07:35,130 --> 00:07:39,670
We have one deployment and zero of them are ready.

153
00:07:39,670 --> 00:07:43,760
Which means one deployment of one deployment failed

154
00:07:43,760 --> 00:07:47,653
which is not the best ratio to put it like that.

155
00:07:48,780 --> 00:07:53,040
Now to get or insights, we can run kubectl get pods

156
00:07:53,040 --> 00:07:57,630
and we'll now see all it's created by our deployments.

157
00:07:57,630 --> 00:08:01,750
And we see one part created by the first-app deployment

158
00:08:01,750 --> 00:08:05,090
but we see that here, one pod should be created.

159
00:08:05,090 --> 00:08:07,560
This is the target states so to say,

160
00:08:07,560 --> 00:08:10,740
but we don't have one pod created.

161
00:08:10,740 --> 00:08:15,720
And here we see the reason it's an ImagePull error

162
00:08:15,720 --> 00:08:19,200
and it should be pretty clear what's causing this.

163
00:08:19,200 --> 00:08:20,858
When we created deployment

164
00:08:20,858 --> 00:08:23,480
with this create deployment command

165
00:08:23,480 --> 00:08:25,930
the image which we specify here

166
00:08:25,930 --> 00:08:28,620
is not taken from the local machine

167
00:08:28,620 --> 00:08:31,480
and sent to the virtual machine.

168
00:08:31,480 --> 00:08:35,261
Instead, this command is sent to the Kubernetes cluster

169
00:08:35,261 --> 00:08:39,159
and then the cluster will look for this image.

170
00:08:39,159 --> 00:08:41,734
And since the cluster runs in a virtual machine,

171
00:08:41,734 --> 00:08:44,220
which I guess technically of course,

172
00:08:44,220 --> 00:08:46,090
is running on our local machine

173
00:08:46,090 --> 00:08:49,840
but which actually acts like a totally separate machine.

174
00:08:49,840 --> 00:08:53,550
This image, which only exists on our local machine,

175
00:08:53,550 --> 00:08:57,223
but not in the Kubernetes cluster of course isn't found.

176
00:08:58,350 --> 00:09:02,220
So instead of sending or specifying a local image here,

177
00:09:02,220 --> 00:09:03,960
we should specify an image

178
00:09:03,960 --> 00:09:08,700
which is part of a image registry like Docker Hub.

179
00:09:08,700 --> 00:09:11,690
So they affirmed let's for the moment,

180
00:09:11,690 --> 00:09:15,190
delete this first-app deployment.

181
00:09:15,190 --> 00:09:18,533
So run Kubectl delete deployment first-app,

182
00:09:18,533 --> 00:09:20,673
so that we remove that again.

183
00:09:21,800 --> 00:09:25,130
Thereafter you'll have no pods anymore.

184
00:09:25,130 --> 00:09:29,130
And let's now push this image from our local machine

185
00:09:29,130 --> 00:09:30,243
to Docker Hub.

186
00:09:32,120 --> 00:09:35,000
For that on your Docker Hub account,

187
00:09:35,000 --> 00:09:39,610
create a new repository and I'll name mine kub-first-app.

188
00:09:39,610 --> 00:09:41,230
And therefore it can later be found

189
00:09:41,230 --> 00:09:45,300
under your account named slash this name,

190
00:09:45,300 --> 00:09:48,880
create it, and then you learned how that works.

191
00:09:48,880 --> 00:09:53,880
Let's re-tag our local kub-first-app image

192
00:09:54,300 --> 00:09:57,730
as your Docker Hub account named slash

193
00:09:57,730 --> 00:10:00,220
and then your repository name.

194
00:10:00,220 --> 00:10:03,180
So in my case, I tag it like this

195
00:10:03,180 --> 00:10:06,100
and thereafter we can run docker push

196
00:10:06,100 --> 00:10:09,120
and then this repository image name.

197
00:10:09,120 --> 00:10:12,840
And now it does this being pushed to Docker hub,

198
00:10:12,840 --> 00:10:15,260
and that means that now it can be accessed

199
00:10:15,260 --> 00:10:19,943
from anywhere in the world, including our cluster machine.

200
00:10:21,210 --> 00:10:23,840
So with that if we now run this again,

201
00:10:23,840 --> 00:10:26,060
the create deployment command

202
00:10:26,060 --> 00:10:28,930
but now we point at this remote image.

203
00:10:28,930 --> 00:10:30,920
So this image on Docker Hub,

204
00:10:30,920 --> 00:10:34,040
and hence we adjust the image name here.

205
00:10:34,040 --> 00:10:36,120
If we tried this now,

206
00:10:36,120 --> 00:10:39,630
you will see that if you now get your deployments,

207
00:10:39,630 --> 00:10:43,793
you will eventually have one over one ready deployments.

208
00:10:44,790 --> 00:10:47,260
Initially, whilst it's starting up,

209
00:10:47,260 --> 00:10:49,670
you could still see zero over one here,

210
00:10:49,670 --> 00:10:53,080
but eventually you will have one over one here.

211
00:10:53,080 --> 00:10:56,200
And therefore, if you run get pods,

212
00:10:56,200 --> 00:10:59,400
you will also have one over one ready pod here

213
00:10:59,400 --> 00:11:01,470
with a status of running.

214
00:11:01,470 --> 00:11:03,443
So this is looking good now,

215
00:11:03,443 --> 00:11:06,820
our application is up and running.

216
00:11:06,820 --> 00:11:10,380
Of course at the moment, we can't really reach it though.

217
00:11:10,380 --> 00:11:12,680
So that's something we're going to work on,

218
00:11:12,680 --> 00:11:17,230
but to see at least something, we can run minikube dashboard

219
00:11:17,230 --> 00:11:20,030
which you might remember is this web dashboard

220
00:11:20,030 --> 00:11:21,530
which we can open up.

221
00:11:21,530 --> 00:11:25,020
This now is a process which needs to stay up and running

222
00:11:25,020 --> 00:11:28,000
at least as long as you wanna visit that dashboard.

223
00:11:28,000 --> 00:11:29,860
And it should open up the dashboard

224
00:11:29,860 --> 00:11:32,370
and the new browser window automatically

225
00:11:32,370 --> 00:11:35,280
if not, simply use that link, which you get here.

226
00:11:35,280 --> 00:11:38,650
And this is now our cluster.

227
00:11:38,650 --> 00:11:40,850
And here you should see your deployment

228
00:11:40,850 --> 00:11:42,350
the first-app deployment

229
00:11:42,350 --> 00:11:45,500
and also all the pods which are up and running.

230
00:11:45,500 --> 00:11:48,270
You'll also see that this pod has a label

231
00:11:48,270 --> 00:11:51,450
which is basically some metadata attached to it,

232
00:11:51,450 --> 00:11:54,230
which identifies the application

233
00:11:54,230 --> 00:11:56,770
and the deployment that belongs to.

234
00:11:56,770 --> 00:11:59,270
And you can also look into these things

235
00:11:59,270 --> 00:12:02,980
and you'll see more information about the deployment

236
00:12:02,980 --> 00:12:05,250
it's status and so on.

237
00:12:05,250 --> 00:12:07,078
And if you look into your pod,

238
00:12:07,078 --> 00:12:09,330
you also can learn more about that.

239
00:12:09,330 --> 00:12:12,720
For example, you can also find an IP address here

240
00:12:12,720 --> 00:12:16,090
but this will only be the internal IP address

241
00:12:16,090 --> 00:12:17,680
inside of the cluster.

242
00:12:17,680 --> 00:12:22,600
So if you try using that in your browser to reach that pod,

243
00:12:22,600 --> 00:12:23,840
this won't work,

244
00:12:23,840 --> 00:12:28,230
even if you use the port exposed by the container.

245
00:12:28,230 --> 00:12:29,820
So for the moment this won't work

246
00:12:29,820 --> 00:12:31,880
but we'll see how we can reach this pod

247
00:12:31,880 --> 00:12:33,683
and this container later.

248
00:12:34,840 --> 00:12:39,330
So that is all working, now I wanna take a brief look

249
00:12:39,330 --> 00:12:41,610
behind the scenes of what happened here

250
00:12:41,610 --> 00:12:43,110
before we then ensure

251
00:12:43,110 --> 00:12:46,160
that we can actually see and visit this webpage,

252
00:12:46,160 --> 00:12:48,015
which was created by the container,

253
00:12:48,015 --> 00:12:51,083
which has part off that pod we deployed.

