-
Notifications
You must be signed in to change notification settings - Fork 1
/
08-containers.slide
692 lines (479 loc) · 17.2 KB
/
08-containers.slide
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
# Containers
Course Go
Tags: golang, go
## Outline
- Containers
- Docker
- Desktop
- Hub
- Build
- Compose
- Podman
- Testcontainers
- Kubernetes
## Containers
## Containers
- A form of virtualization
- Lightweight version of virtual machines (VMs)
- Does not use a hypervisor
- Reuses host OS
- Requires:
- Compatible kernel
- Container runtime
- Shipped in a form of images
- The image generally includes all of its dependencies
[Google Cloud: Containers](https://cloud.google.com/learn/what-are-containers)
##
.image assets/lecture-08/containers/containers-and-vms.svg 450 _
## Containers vs VMs
- VMs are generally used for infrastructure provisioning
- Provide better resource isolation
- Virtualizes at the hardware level
- Containers serve as a tool for developers for shipping software
- More lightweight
- Virtualizes at the OS level
- Share the OS kernel
- Fraction of the memory is used
[Google Cloud: Containers vs VMs](https://cloud.google.com/discover/containers-vs-vms)
## Motivation
- Local development
- Running dependecies
- Minimal overhead
- Production environment
- Shipping deyployable units of software
- Simplifies collaboration with DevOps/Ops engineers
## Open Container Initiative (OCI)
- Specifies industry standards around container technology
- Formed under the Linux Foundation
- Launched by Docker and other leaders in the container industry [2015]
- Three specifications:
- [Runtime Specification](https://github.com/opencontainers/runtime-spec?tab=readme-ov-file)
- [Image Specification](https://github.com/opencontainers/image-spec)
- [Distrubution Specification](https://github.com/opencontainers/distribution-spec)
[GitHub: Open Container Initiative](https://github.com/opencontainers)
## Docker
## Docker
- Containers & their related technologies existed well before Docker
- Google's Borg [2003]
- cgroups [2008]
- [LXC](https://linuxcontainers.org) [2008]
- Docker just created a platform around them [2013]
- User friendly API
- Platform as a Service
_"Commercial use of Docker Desktop in larger enterprises (more than 250 employees OR more than $10 million USD in annual revenue) requires a paid subscription."_
[Docker](https://docker.com)
[Tech Target: Evolution of containers](https://www.techtarget.com/searchitoperations/feature/Dive-into-the-decades-long-history-of-container-technology)
##
.image assets/lecture-08/docker/ship-your-machine.jpg 500 _
[Reddit: ProgrammerHumor](https://www.reddit.com/r/ProgrammerHumor/comments/cw58z7/it_works_on_my_machine/)
## Docker Desktop
- Primarily a desktop GUI application
- Includes all necessary tools:
- Docker Engine
- Docker CLI
- Docker Build
- Docker Compose
- And a few more tools...
- "All-in-one package"
- You can also install the separately
[Docker: Docker Desktop](https://docs.docker.com/desktop/)
## Docker Images & Containers
## Docker Images & Containers
- Container images
- A form of snaphost or template for container construction
- They declare what the snapshot contains
- What is run when the image gets deployed in the form of a container
- Containers are actual running instances constructed from container images
- Run using a container runtime
## Docker Hub
- Image registry
- Largest
- De facto the standard
- Docker uses it by default
- You can easily [create your own container repository](https://docs.docker.com/docker-hub/repos/)
[Docker Hub](https://hub.docker.com)
[Docker: Docker Hub](https://docs.docker.com/docker-hub/)
## Docker workflow
.image assets/lecture-08/docker/docker-flow.svg 400 _
## Pulling images
- Images can be easily downloaded
- Implicitly uses Docker Hub
- Downloads a `postgres` image with the tag `latest`
```
$ docker pull postgres
```
- You can also specify a version using a tag
```
$ docker pull postgres:16
```
- You can also use a different registry
- GitHub Container Registry
```
$ docker pull ghcr.io/course-go/lectures:latest
```
## Running containers (1/2)
```
$ docker run postgres
```
- Fails as `postgres` requires a password for the instance
- We can easily provide it with the `-e`/`--env` option
```
$ docker run -e "POSTGRES_PASSWORD=gophers" postgres
```
- This successfully runs the instance
- Postgres runs on port `5432` by default
- However, you will not be able to connect to it from localhost
- Docker does not automatically export it
- We have to bind the port to our `localhost` machine
```
$ docker run -e "POSTGRES_PASSWORD=gophers" -p 5432:5432 postgres
```
## Exposing container ports
.image assets/lecture-08/docker/container-ports.svg 500 _
## Running containers (2/2)
- You can also run containers in detached mode
- Frees up your terminal
```
$ docker run -e "POSTGRES_PASSWORD=gophers" -p 5432:5432 -d postgres
```
- Running containers can be easily listed
```
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9a6a02b6f0d4 postgres "docker-entrypoint.s…" 2 seconds ago Up 1 second 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp serene_jemison
```
- You can also inspect images by running a interactive shell session inside of them
- Great for debugging
```
$ docker exec -it 9a6a02b6f0d4 /bin/sh
```
- You can also kill a running container
```
$ docker kill 9a6a02b6f0d4
```
## Container volumes
- Containers do not persist memory
- Any changes done inside of the container are then discarded when the container is dropped
- You can mount a disk volume to persist data in the given directory
```
$ docker run \
-e POSTGRES_PASSWORD=mysecretpassword \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-v /var/lib/pgsql/container-data:/var/lib/postgresql/data \
postgres
```
- You can also create a named volume
```
$ docker volume create postgres-container
$ docker run -d \
-v postgres-container:/var/lib/postgresql/data \
postgres
```
[Docker Hub: postgres](https://hub.docker.com/_/postgres)
## Docker architecture
.image assets/lecture-08/docker/docker-architecture.svg 520 _
## Custom images
- We can now pull and run existing images
- But what if we want to create our own?
## Docker Build
## Docker Build
- Tool for building Docker images
- Uses a custom file
- `Dockerfile`
- Custom format
[Docker Build](https://docs.docker.com/build/)
## Dockerfile keywords
```
ADD Add local or remote files and directories.
ARG Use build-time variables.
CMD Specify default commands.
COPY Copy files and directories.
ENTRYPOINT Specify default executable.
ENV Set environment variables.
EXPOSE Describe which ports your application is listening on.
FROM Create a new build stage from a base image.
HEALTHCHECK Check a container's health on startup.
LABEL Add metadata to an image.
MAINTAINER Specify the author of an image.
ONBUILD Specify instructions for when the image is used in a build.
RUN Execute build commands.
SHELL Set the default shell of an image.
STOPSIGNAL Specify the system call signal for exiting a container.
USER Set user and group ID.
VOLUME Create volume mounts.
WORKDIR Change working directory.
```
[Docker: Dockerfile](https://docs.docker.com/reference/dockerfile/)
## Dockerfile
.code assets/lecture-08/docker/Dockerfile
[Docker Build: Dockerfile](https://docs.docker.com/reference/dockerfile/)
## Building and pushing images
- You can easily build the image
- `-t` arguments specifies the tag at build time
```
$ docker build -t <NAME>:<TAG> .
```
- It can be alternatively specified after building the image
- Image can also have multiple tags
```
$ docker tag <EXISTING-NAME>:<EXISTING-TAG> <NEW-NAME>:<NEW:TAG>
```
- You have to login before pushing images to a remote registry
```
$ docker login
```
```
$ docker push <NAME>:<TAG>
```
## Build context
```
$ docker build .
```
- The build command requires a path to `Dockerfile` and a build context
- Searches for `Dockerfile` in the current directory
- Can be specified with `-f`/`--file`
```
$ docker build -f build/Dockerfile .
```
- The context specifies where the build is executed
```
$ docker build my-cool-app/src
```
[Docker Build: Context](https://docs.docker.com/build/building/context/)
## Build architecture
- `build` uses the `buildx` client in the background
- Buildkit is the building backend
- `buildkitd`
.image assets/lecture-08/docker/build-architecture.svg 300 _
[Docker Build: Architecture](https://docs.docker.com/build/architecture/)
## Multi-stage builds
- The runtime usually does not require the SDK, it's dependencies or the compiler
- In Go, we only need the final binary
- Multi-stage builds allow us to separate the image creation into multiple stages
- Benefits
- Smaller image size
- Flexibility
- Different images can be used for each step
[Docker Build: Multi-stage builds](https://docs.docker.com/build/building/multi-stage/)
## Multi-stage builds
.code assets/lecture-08/docker/Dockerfile.multistage
## Multi-platform builds
- By default, Docker creates images compatible with the builder's platform
- You can specify the platform when building an image
- Only up to a single platform
```
$ docker build --platform linux/amd64 .
```
- Multi-platform builds allow us to create multiple images supporting multiple platforms at one
- Three stategies
- [QEMU](https://docs.docker.com/build/building/multi-platform/#qemu)
- [Multiple nodes of different architecture](https://docs.docker.com/build/building/multi-platform/#multiple-native-nodes)
- [Cross-compilation](https://docs.docker.com/build/building/multi-platform/#cross-compilation)
[Docker Build: Multi-platform builds](https://docs.docker.com/build/building/multi-platform/)
## Multi-platform build using cross-compilation
- `BuildKit` supports [multiple build arguments](https://docs.docker.com/reference/dockerfile/#automatic-platform-args-in-the-global-scope) out of the box
.code assets/lecture-08/docker/Dockerfile.cross-compilation
[Docker: Cross-Compilation Guide](https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/)
## Motivation
- We can now
- Create, pull and push custom images
- Run them using the CLI
- What if we want to orchestrate multiple services
- Do we have to run all of them manually?
## Docker Compose
## YAML
- _Yet Another Markup Language_
- _YAML Ain't Markup Language_
- Superset of JSON
- More readable compared to JSON
- Basically a JSON without the brackets and the obligatory quotation marks
- Depends on indentation
- Criticism
[YAML](https://yaml.org)
## YAML
.code assets/lecture-08/docker/yaml.yaml
[YAML specification](https://yaml.org/spec/1.2.2/)
## Docker Compose
- Tools for orchestrating multiple containers at once
- Specified using a `docker-compose.yaml` file
- Also supports `compose.yaml` (preferred nowadays)
[Docker Compose](https://docs.docker.com/compose/)
## Docker Compose
.code assets/lecture-08/docker/compose.yaml
[GitHub: Compose specification](https://github.com/compose-spec/compose-spec/blob/master/spec.md)
## Running Docker Compose
- Running the compose
- `up` = `create` + `start`
```
$ docker compose up
$ docker compose up -d
```
- Shuting down the compose services
- `down` = `stop` + `rm`
```
$ docker compose down
```
- You can restart individual services
```
$ docker compose restart <SERVICE>
```
- And also display aggregated logs for all services
```
$ docker compose logs -f
```
## Networking
- Docker Compose automatically creates a network for your services
- The network gets shared by all of your services
- `bridge` type
- `default_network`
- You can explicitly specify the networks for each service
- Docker defines a [default set of drivers](https://docs.docker.com/network/drivers/)
[Docker: Networking](https://docs.docker.com/network/)
## Networking
.code assets/lecture-08/docker/compose-networking.yaml
## Networking
.image assets/lecture-08/docker/compose-networking.svg 500 _
## Profiles
- You may not want to run all services each time
- Running tests for the service may only require dependencies
- Custom profiles can be specified
- You can then run the subset of services sharing the profile
```
$ docker compose --profile <PROFILE-NAME> up
$ COMPOSE_PROFILES=<PROFILE-NAME> docker compose up
$ docker compose --profile products --profile orders up
```
[Docker Compose: Profiles](https://docs.docker.com/compose/profiles/)
## Profiles
.code assets/lecture-08/docker/compose-profiles.yaml
## Dependencies
- You can declare how services depend on each other
- Define start-up and shutdown order
- You avoid unnecessary crashing
- `depends_on`
- `service_started`
- `service_healthy`
- `service_completed_successfully`
- `healthcheck`
[Docker Compose: Control order](https://docs.docker.com/compose/startup-order/)
## Dependencies
.code assets/lecture-08/docker/compose-dependencies.yaml
## Podman
## Podman
- An alternative to Docker
- Part of a `containers` collection of open-source tools
- It mostly has the same API
- Same CLI commands
```
$ podman run postgres:16
$ podman compose up
```
[Podman Desktop](https://podman-desktop.io)
[GitHub: Containers](https://github.com/containers/)
## Testcontainers
## Testing with dependencies
- Not all tests require real dependencies
- Fakes can be used
- However, integration with real services has to be tested at some point
- Isolation of tests
- Multiple tests share a single database instance
- Create a new database per each test
- The single instance has to actually exist
- Docker Compose
- Or spawn per test instance
- Testcontainers
## Testcontainers
- Allows running containers directly in code
- Simplifies testing against real services
- SDK for many languages:
- Go, Rust, Java, .NET, Python, Node.js, Haskell...
- Keep in mind that spawning containers is not cheap
- [postgres:16](https://hub.docker.com/_/postgres) image has around 450 MB
[Testcontainers](https://testcontainers.com)
## Testcontainers
.code assets/lecture-08/testcontainers/quickstart.go /START OMIT/,/END OMIT/
[Testcontainers for Go: Quickstart](https://golang.testcontainers.org/quickstart/)
## Modules
- Preconfigured implementations of various dependencies
- All major databases
- Message brokers
- Cloud SDKs
[Testcontainers: Modules](https://testcontainers.com/modules/)
## Modules
.code assets/lecture-08/testcontainers/module.go /START OMIT/,/END OMIT/
[Testcontainers for Go: Postgres module](https://golang.testcontainers.org/modules/postgres/)
## Kubernetes
## Motivation
- What if we want to scale our applications?
- Horizontal scaling
- High availability
- Configuration management
- What if our node (server) dies?
- Self-healing
## Kubernetes
- K8s
- Platform for managing container workloads and services
- Distributed
- Developed by Google
- Open-sourced in 2014
- Handed over to [CNCF](https://www.cncf.io)
[Kubernetes](https://kubernetes.io)
[Kubernetes: Cluster architecture](https://kubernetes.io/docs/concepts/architecture/)
## Kubernetes glossary
- **Pod**: a set of running containers
- **Node**: machine that processes workload
- **kubelet**: manages and monitors containers in pods
- **kube-proxy**: manages network traffic to pods
- **Control Plane**: cluster orchestration layer
- **kube-api-server**: exposes orchestration API
- **kube-scheduler**: makes pods deployment decisions
- **kube-controller-manager**: monitors cluster state using the API
- **etcd**: key-value storage
[Kubernetes Componenets](https://kubernetes.io/docs/concepts/overview/components/#node-components)
## Kubernetes architecture
.image assets/lecture-08/kubernetes/kubernetes-components.svg 550 _
## Kubernetes architecture
.image assets/lecture-08/kubernetes/kubernetes-architecture.svg 500 _
## Minikube
- You can easily set-up local cluster using Minikube
- Great for learning or local development
```
$ minikube start
$ minikube status
$ minikube stop
```
- Minikube supports the Kubernetes Dashboard UI
- You can easily preview allocated resources
```
$ minikube dashboard
```
[Minikube](https://minikube.sigs.k8s.io/docs/)
## Kubectl
- You can interact with the cluster using the [kubectl](https://kubernetes.io/docs/reference/kubectl/) command line tool
```
$ kubectl get nodes
$ kubectl get pods
```
- Apps are deployed using `deployments`
```
$ kubectl create deployment k8s-bc --image=gcr.io/google-samples/kubernetes-bootcamp:v1
$ kubectl get deployments
```
- The deployments can easily be replicated
```
$ kubectl scale deployments/k8s-bc --replicas=3
```
- Or updated
```
$ kubectl set image deployments/k8s-bc k8s-bc=docker.io/jocatalin/kubernetes-bootcamp:v2
$ kubectl describe deployments/k8s-bc
```
[Kubernetes: Learn Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/)
## Deployment using a specification
.code assets/lecture-08/kubernetes/nginx-deployment.yaml
## Deployment using a specification
- The then apply the specification to the cluster
```
$ kubectl apply -f nginx-deployment.yaml
```
[Kubernets: Deployments](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)