-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdocker.html
1169 lines (842 loc) · 44.7 KB
/
docker.html
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
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!-- xhtml format, hw6 (tables) had to use transitional instead of strict dtd. -->
<!--
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
the one below for strict html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
sttrict xhtml:
-->
<!--
CSS Class - UCSCX - 2012.07 - Final Project
Also making it as part of my PSG page remake.
CSS validator: http://jigsaw.w3.org/css-validator/#validate_by_uri
HTML validator: http://validator.w3.org/
-->
<head>
<title>Sys Admin Pocket Survival Guide</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="psg.css" type="text/css" media="screen">
<!--
<link rel="stylesheet" href="psg-table.css" type="text/css">
<link rel="stylesheet" href="psg2-links-icons.css" type="text/css">
<link rel="stylesheet" href="psg-positioning.css" type="text/css">
-->
<link rel="stylesheet" href="psg-print.css" type="text/css" media="print">
</head>
<body>
<div class="navheader">
<table summary="Navigation header" width="100%">
<tbody>
<tr>
<th colspan="12" align="center">
<A HREF="http://tin6150.github.io/psg/docker.html">Sys Admin Pocket Survival Guide - Docker</A>
</th>
</tr>
<tr>
<td align="left"> <a accesskey="h" href="psg.html">Home</a> </td>
<td align="center"><a accesskey="d" href="k8s.html">Kubernetes</a> </td>
<td align="center"><a accesskey="x" href="singularity.html">Singularity</a> </td> <!--TBA-->
<td align="center"><a accesskey="r" href="coreos.html">CoreOS</a> </td>
<td align="center"><a accesskey="w" href="aws.html">AWS</a> </td>
<td align="center"><a accesskey="b" href="bigdata.html">BigData</a> </td>
<td align="center"><a accesskey="s" href="devops.html">DevOps</a> </td>
<td align="center"><a accesskey="o" href="openstack.html">OpenStack</a> </td>
<td align="center"><a accesskey="v" href="vagrant.html">Vagrant</a> </td>
<td align="center"><a accesskey="c" href="blogger_container_hpc.html">Container in HPC</a> </td>
<td align="center"><a accesskey="l" href="lsf.html">lsf/slurm/uge</a> </td>
<td align="right"> <a accesskey="a" href="https://github.com/tin6150/inet-dev-class/tree/master/ansible">ansible</a> </td>
</tr>
</tbody>
</table>
<hr></div>
<div class="chapter" lang="en">
<div class="titlepage">
</div>
</div>
<!-- changed to use old psg css, cuz lines are too long to fit in narrow column. to go back, see git log dc3b937 -->
<!-- this file is kinda frankenstein. started with psg2.css, then moved back to use psg1.css -->
<!--
<div id="wrapper">
<div id="header">
<CENTER>
<H5>Sys Admin Pocket Survival Guide</H5>
<H5>A Quick Reference Guide for Sys Admins with Alzeimer :)</H5>
</CENTER>
</div>
<div id="navigation">
<div class="azul">Cloud</div>
<li> <a href="docker.html">docker</a></li>
<li> <a href="aws.html">AWS</a></li>
<BR>
<div class="azul">Big Data</div>
<li> <a href="lsf.html">SGE/UGE, PBS/Torque, LSF.</a></li>
<li> <a href="blogger_container_hpc.html">Container in HPC.</a></li>
<li> <a href="mpi.html">MPI, PVM.</a></li>
<li> <a href="sci-file.html">Science File Format/Info.</a></li>
<li><a href="sci-app.html">Sci-App.</a></li>
<li> <a href="bigdata.html">Big Data engines.</a></li>
<BR>
<div class="azul">Unix</div>
<li> <a href="nixos.html">NixOS</a></li>
<li> <a href="linux.html">Linux</a></li>
<li> <a href="coreos.html">CoreOS</a></li>
<li> <a href="sol.html">Solaris</a></li>
<li> <a href="hpux.html">HP-UX</a> and <br>
<a href="hpux.supl.html">supplement</a></li>
<li> <a href="aix.html">AIX</a> and <br>
<a href="aix_cd_catalog.html">AIX CD catalog</a><br></li>
<li> <a href="irix.html">Irix</a></li>
<li> <a href="dos.html">Windows</a></li>
<li> <a href="apple.html">Apple Mac</a></li>
<BR>
<div class="azul">Storage</div>
<li> <a href="netapp.html">NetApp</a></li>
<li> <a href="emc.html">EMC SAN - Clariion</a></li>
<li> <a href="emcCelerra.html">EMC NAS - Celerra</a></li>
<li> <a href="isilon.html">Isilon</a></li>
<li> <a href="fs.html">Unix File System</a></li>
<BR>
<div class="azul">Unix Dev</div>
<li><a href="development.html">compilers, etc</a></li>
<li><a href="shellScript.txt">sh/bash, csh/tcsh</a></li>
<li><a href="awk.txt">AWK</a></li>
<li><a href="perl.html">Perl</a></li>
<li><a href="python.html">Python</a></li>
<li><a href="php.txt">PHP</a></li>
<li><a href="javascript_eg.html">javascript_eg</a></li>
<li>gcc</li>
<li><a href="gdb.html">gdb</a></li>
<li>java</li>
<li>rcs, cvs, p4, subversion</li>
<li><a href="vi.html">vi</a></li>
<BR>
<div class="azul">Network</div>
<li> <a href="ipmi.html">IPMI</a></li>
<li> <a href="ipv6.html">IPv6</a></li>
<li> <a href="net.html">Network</a></li>
<li> <a href="infiniband.html">InfiniBand</a><br></li>
<li> <a href="acopia.html">Acopia</a></li>
<BR>
<div class="azul">Other</div>
<li> <a href="softenv+modules.html">SoftEnv, Environment Modules</a></li>
<li> <a href="puppet.html">Puppet</a></li>
<li> <a href="cfengine.html">CfEngine</a></li>
<li> <a href="factory_pw.html">factory password</a></li>
<li> <a href="ldap.html">LDAP</a><BR></li>
<li> <a href="admin.html">General Unix Sys Admin </a></li>
<li> <a href="tool.html">Sys Admin tools and performance tuning</a></li>
<li> <a href="vnc.html">VNC, X Emulation</a></li>
<li> <a href="backup.html">Unix backup</a></li>
<li> <a href="general_unix.html">Generic Unix Commands</a></li>
<li> <a href="veritas.html">Veritas</a></li>
<li> <a href="legato.html">Legato Networker</a></li>
<li> <a href="mysql.html">MySQL</a></li>
<li> <a href="html.txt">HTML tags</a></li>
<li> <a href="wiki.html">WiKi tags</a></li>
<li> <a href="3rdParty">3rd Party and Vendor Docs Cache</a></li>
<BR>
<div class="azul">IMHO</div>
<li> <a href="monitor.html">Network monitoring tool review</a></li>
<li> <a href="netArch.html">Network Architecture Approaches</a></li>
<li> <a href="docPlatform.html">Documentation platform</a></li>
<BR>
<div class="azul">Prod Review</div>
<li><a href="termSvr.html">Terminal (Serial Console) Servers</a></li>
<li><a href="ent_prod.html">Enterprise Products</a></li>
<BR>
<div class="azul">More</div>
<li><a href="psg1.html">Full TOC</A></li>
<BR>
</div>
-->
<!-- closes #navigation -->
<!-- ########################################################## -->
<!-- ########################################################## -->
<div id="content">
<A HREF="http://www.docker.io/static/img/docker-top-logo.png"><IMG SRC="fig/Docker-logo.png" alt="docker logo (download via wikipedia)" width="96%" ></A> <!-- width="96%" stock ~600x180 -->
<BR><BR>
<!-- move this lower after presentation -->
<A HREF="http://nathanleclaire.com/blog/2014/03/22/what-is-this-docker-thing-that-everyone-is-so-hyped-about/">
Motivation for Docker</A>: <BR>
<A HREF="http://nathanleclaire.com/blog/2014/03/22/what-is-this-docker-thing-that-everyone-is-so-hyped-about/"><IMG SRC="fig/docker-matrix-from-hell.png" width="96%" alt="docker matrix from hell diagram"></A> <!-- stock 442x229, tried 530x274, but % works better on mobile-->
<BR><BR>
Docker vs Virtual Machine
(<A HREF="http://slurm.schedmd.com/SLUG15/shifter.pdf">NeRSC Shifter</A> slide 13): <BR>
<A HREF="https://www.nersc.gov/news-publications/nersc-news/nersc-center-news/2015/shifter-makes-container-based-hpc-a-breeze/"><IMG SRC="fig/container-vs-vm.nersc-shifter-p13.png" width="96%" alt="docker vs vm diagram"></A>
<!--A HREF="http://slurm.schedmd.com/SLUG15/shifter.pdf"><IMG SRC="fig/container-vs-vm.nersc-shifter-p13.png" width="943" height="694" alt="docker vs vm diagram"></A-->
<!--A HREF="http://www.shadowandy.net/wp/wp-content/uploads/docker-containers-vs-vms.png"><IMG SRC="fig/docker-containers-vs-vms.png" width="594" height="306"></A> -->
<BR>
<BR>
<A HREF="https://docs.docker.com/engine/introduction/understanding-docker/">
Docker architecture</A>:<BR>
<A HREF="https://docs.docker.com/engine/introduction/understanding-docker/"><IMG SRC="fig/docker-architecture.svg" width="96%" alt="docker architecture diagram"></A> <!-- 551x288-->
<BR>
<BR>
<BR>
<A HREF="https://blog.docker.com/2014/03/docker-0-9-introducing-execution-drivers-and-libcontainer/">
Under the hood</A>: <BR>
<A HREF="https://blog.docker.com/2014/03/docker-0-9-introducing-execution-drivers-and-libcontainer/">
<IMG SRC="fig/docker-execdriver-diagram.png" width="96%" alt="docker under the hood diagram"></A> <!--593x445-->
<BR>
<OL>
<LI>Container isolation is provided by Linux kernel Namespace.
<LI>Resource restriction (cpu, memory) is governed by CGroups.
<LI>UnionFS provides a unified file system inside the container, even when there are multiple pieces mounted in overlapping fashion. Several implementation exist, eg AUFS, btrfs, DeviceMapper, etc
<LI>A container format is a wrapper around the components above. Modern docker use libcontainer. Older system used LXC, libvirt, etc.
<LI>
</OL>
<BR>
<BR>
<A NAME="101"></A>
<H2><div class="azul">Docker traits</div></H2>
<UL>
<LI> Container provides instant application portability.
<LI>
<LI> Container is kernel virtualization (VM is hardware virtualization).
<LI>Docker creates a thin compartamentalization between apps, calling them containers.
<LI>Think of Docker as Solaris Container/Zone, AIX WPAR, FreeBSD jail or even a glorified chroot.
<LI>A container uses the host OS kernel, and bin/lib if possible.
<LI> Container is similar to KVM, where virtual guest machine uses the host kernel and bin. But container is more lightweight than KVM.
<LI> cgroup is used to enforce resource quota for each container
<LI>a container CAN have diff bin and lib than the host, such container would be much fatter. But it is possible to have a host OS running CoreOS and a container using Ubuntu.
<LI> namespace
<LI>
<LI>
<LI> Lots of little apps... So, multiple dockers, each hosting an app, are run to satisfy a specific "suite".
<LI> Wordpress container rely on a separate MySQL container to host its files.
<LI> Both need to rely on OS... ? An OS docker is needed to ... ?? Does not run docker inside another docker.
<LI>
</UL>
<BR>
<H3>Ecosystem, Competitor</H3>
<UL>
<LI> <A HREF="#k8s">Kubernetes</A>
<LI> <A HREF="bigdata.html#mesos">Mesos</A>
<LI>Vagrant
<LI>ClusterHQ
<li> <a href="coreos.html">CoreOS</a>
<LI> OpenVC
<LI> LXC = namespace + cgroup
<LI> Rocket (rkt), a newer, open source container/pod contender.
<LI> systemd-nspawn, AppArmor rkt, runC,
<LI> AUFS, Copy on Write
<LI>
<LI>
</UL>
<PRE>
</PRE>
<BR><BR>
<H3>Docker Hub</H3>
Docker images can be placed in a central repository. The "app store" equivalent for docker is at
<A HREF="https://hub.docker.com">hub.docker.com</A>. <BR>
This Pocket Survival Guide web site is served by an apache container with all the necessary web content in
<A HREF="https://hub.docker.com/r/tin6150/apache_psg3/">https://hub.docker.com/r/tin6150/apache_psg3/</A> <BR>
<BR>
No account is needed to pull docker images from the hub. <BR>
Account IS needed to post image to the hub. <BR>
<H3>Docker and RHEL7</H3>
<UL>
<LI>Docker leverages new kernel features, devicemapper (thin provisioning, direct lvm), sVirt, systemd
<LI>RH don't recommend use of docker with RHEL6 and don't ship rpm for it.
<LI>RHEL6.5 with kernel 2.6.32+ supported early docker implementation, but not recommended nowadays.
<LI>EPEL provides docker-io.rpm in RHEL 6, but it wants kernel 3.8.0 and above, so point to use RHEL7 again. (note the docker.rpm is is unrelated, it is for a GUI applet thingy).
</UL>
<H3>Docker and CoreOS</H3>
<UL>
<li> <a href="coreos.html">CoreOS</a>
is much thinner than traditional Linux distro.
<LI>Built intend to host many docker containers.
<LI>
<LI>
</UL>
<H3>Config</H3>
<PRE>
HTTPS_PROXY # said to look at this env var for proxy
/etc/sysconfig/docker # docker daemon config for RHEL/Fedora
# may need to config proxy here.
/etc/default/docker # docker daemon config for ubuntu
/var/log/docker
/var/lib/docker # cache of container images, many run time stuff.
</PRE>
<H3>Installation</H3>
<PRE>
### installation in ubuntu
sudo apt-get install docker.io # "docker" without .io is for some gui docklet applet.
sudo service docker start # start docker daemon
docker search httpd # to allow non root to run docker command, add the user to the docker group.
/etc/default/docker # docker daemon config for ubuntu
### installation on amazon linux
### http://docs.aws.amazon.com/AmazonECS/latest/developerguide/docker-basics.html
sudo yum install -y docker
sudo service docker start # start docker daemon
sudo usermod -a -G docker ec2-user # to allow non root to run docker command, add the user to the docker group.
# docker commands are often run under the os-level user rather than root.
### installation on rhel7
sudo yum install docker # (deps: docker-selinux device-mapper, lvm2). There are other optional tools
sudo service docker start
sudo usermod -a -G Dockerroot bofh
# other setup maybe needed... docker command still don't run as bofh ... maybe selinux stuff?
sudo docker run httpd # will download httpd container if not already present
/etc/sysconfig/docker # docker daemon config for RHEL/Fedora
# may need to config proxy here.
</PRE>
<H3>Basic Commands</H3>
<CENTER>
<A HREF="http://www.slideshare.net/insideHPC/docker-for-hpc-in-a-nutshell"><IMG SRC="fig/docker-workflow-cmd.png" width="96%" alt="diagram of basic docker actions and commands"></A>
</CENTER>
<PRE>
docker search http # look for container in hub.docker.com
docker pull httpd:latest # download the httpd image from hub.docker.com. get the "latest" version.
# stored in??
docker images
docker run -p 80:80 httpd # run the httpd docker image, mapping port 80 on the container to port 80 on the host
# if image not already pull-ed, docker run will pull it automatically
docker run -p 8000:80 httpd & # run the httpd docker image, mapping port 80 on the container to port 8000 on the host,
# putting docker in background so get back the prompt.
# two instanced can run as above, resulting in service running in parallel
# netstat -an | grep LISTEN will show that both port 80 and 8000 are in LISTEN state
# note that the httpd process is visible on the host.
# it is NOT like in a VM that run all its process in a black box.
docker run -P -d training/webapp python app.py # this run a demo web app called app.py
# -P will map all ports in container to host.
# but it maps sequentially starting from 32768
# -d is daemon mode, ie, put process in background.
docker ps # list running docker process, container id, name, port mappings, etc
docker ps -l # list last continer that was started
docker ps -a # list all containers, including stopped one
docker logs c7f46acc532b # get console output of the specified container id
docker stop c7f46acc532b # stop the specified container id (container nickname can be used instead)
docker start c7f46acc532b # restart the specified container id (assuming image hasn't deleted)
docker exec -it c7f46acc532b bash # drop into a bash shell inside a running container
docker exec uranus_hertz df -h # run the "df -h" command inside the named container
docker port c7f46acc532b # show port mapping of a container to its host (similar to former docker network ls)
docker top uranus_hertz # see the process running inside the specified container
docker pull rhel7:latest # get a basic, off-the-shelf container for redhat 7 (eg from rh cert guide)
docker info # display info on existing container, images, space util, etc.
docker inspect httpd # get lots of details about the container. output in JSON
# eg data volumes, (namespace?) mappings,
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' uranus_hertz # only retrieve specific "inspection" item
docker images -a # list images (from docker pull). Note that a container is an execution instance, reading info from an image.
docker ps -a # list containers (process, -a include stopped containers) (note diff vs image, which is more like a source file)
docker rm ContainerName # remove container (process listed by docker ps -a)
docker rmi ImageName # remove image (files listed by docker image -a)
# images files from docker pull. container are instance of image.
docker commit clever_shockley rhel7box2 # save changes of a running container to a new named image called "rhel7box2"
docker commit -m "msg desc" # -m add a message about the commit (description for the new image)
docker commit -a "author name" # -a add the authoer's name
docker tag ... # tag/name (?container as image) for docker push to hub.docker.com
docker login # login to hub.docker.com ...
docker info # version, disk usage, metadata size, etc
man docker # docker damon and general instructions
man docker run # specific man page for the run command of docker
# (not sure how space is handled by man, but it does!)
docker --help
docker run --help # help specific to the sub command.
</PRE>
<A NAME="under_the_hood"></A>
<H2>Under the hood</H2>
<H3>Process Isolation</H3>
<OL>
<LI> Each container has its own process tree, with its "seed" process (eg httpd) as PID 1.
<LI> Achieved using Namespace.
<LI> Parent is aware of all child process, but child don't know anything about parent -- security.
<LI> Parent see child process, and each child process really has 2 PIDs.
<LI>
</OL>
<H3>Network Isolation</H3>
<OL>
<LI> Each container has its own network stack, NIC, ARP space, IP space, routing tables,
<LI> Achieved using <TT>ip netns</TT>
<LI> iptables, brctl, virtual switches
<LI> Docker provides network isolation, but no throtling
<LI> 3 network methods:
<UL>
<LI>bridged (default)
<UL>
<LI> Virtual ethernet interface is used (veth), called docker0
<LI> All containers on docker0 can communicate with one another by default (icc=true), ie no isolation between these containers.
</UL>
<LI>host
<UL>
<LI> container use host network stack, thus no isolation
<LI> allow access to D-Bus, unexpected behavior.
<LI> use not really recommended
</UL>
<LI>shared
<UL>
<LI> An existing container network stack is shaerd with other containers. ie Network Namespace is shared.
<LI> like bridged, FS and Process isolation remains
</UL>
</UL>
<LI> Docker will manipulate iptables, bypass UFW. if want to protect container from general access, see <A HREF="#behind_ufw">below</A>.
<LI>
<LI>
</OL>
<A ID="ufw"></A>
<A NAME="behind_ufw"></A>
<H5>Docker containers behind UFW</H5>
Ref:
<LI> <A HREF="https://www.mkubaczyk.com/2017/09/05/force-docker-not-bypass-ufw-rules-ubuntu-16-04/">mkubaczyk blog</A>
<LI> via https://stackoverflow.com/questions/30383845/what-is-the-best-practice-of-docker-ufw-under-ubuntu
<PRE>
Disable docker from mocking with iptables:
echo "{
\"iptables\": false
}" > /etc/docker/daemon.json
(did not get correct config in /etc/default/docker)
allow forwarding to the container:
cp -p /etc/default/ufw /etc/default/ufw.bak
sed -i -e 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/g' /etc/default/ufw
systemctl restart docker
systemctl restart ufw
allow container to go out to internet.
exact ip from ifconfig docker0
(haven't done this yet, but from inside the container was able to go out. docker-compose port maps to specific ip , but that should not matter for outbound traffic
the other thing is that the host, bofh, had a rule that allow full access (meant for cueball-bofh traffic))
iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE
</PRE>
x-ref: https://github.com/tin6150/inet-dev-class/blob/master/tig/README.mode2.rst
<H3>File System Isolation</H3>
<OL>
<LI> File system inside container is isolated from the host
<LI> No Disk I/O throtle, no disk quota.
<LI> Union FS: DeviceMapper in Fedora. AUFS in Ubuntu.
<LI>
<LI>
</OL>
<H3>Docker vs LXC</H3>
<OL>
<LI> LXC is lightweight, but heavily embeded into Gentoo Linux, not portable.
<LI> Docker started in Ubuntu. application portability was key goal. Gentoo was providing a container for security/isolation.
<LI> Both rely on Cgroup, union file system.
<LI>
</OL>
<H3>docker run</H3>
<H5>
Stock httpd conainer
</H5>
<PRE>
# run a stock container (apache httpd) on amazon linux
# no changes to the content of the container
docker run -p 80:80 -i -t --rm --name ApacheA -v ~/htdocs4docker:/usr/local/apache2/htdocs/ httpd
docker run -p 8000:80 --name ApacheB -v "$PWD":/usr/local/apache2/htdocs/ httpd &
# run a process (httpd) in a new container
# each process has its own FS, network, isolated process tree.
# most of the default param are defined in the IMAGE, but cli arg will overwrite the IMAGE conf.
#
# -p = map host port 8000 to port 80 on the container
# if not specified, default maps NOTHING,
# so outside, even on the host, can't get into the inside of the docker app!
# -i = interactive, def=false. ^P ^Q ^Z bg can suspend and background this. cannot use with &
# -t = allocate pseudo-tty, def=false
# --name foo = assign a name to the container. if not specified, a random 2_words name will be assigned
# --rm = remove container when exiting, def=false.
# if don't delete container, it linger around.
# will see them with docker ps -a. remove with docker rm ContainerName
# Note that each time a container is started, the name must not match existing or stopped container.
# --rm is good especially for testing, to avoid having to do lot of clean up work.
# -v "$PWD":/usr/local/apache2/htdocs/ bind mounts the host's current dir into the container's apache htdocs dir.
# -v or --volume=... format is host : container
docker run -it httpd /bin/bash
# this run (a new) apache httpd container, and start the bash shell running *inside* the container env.
# /usr/local/apache2/htdocs inside this container is where the web pages are served up from (if not mapped with -v)
# changes to this will persist inside this instance, till container is removed with docker rm ContainerName
docker exec -it ApacheB /bin/bash
# this run the bash command in an already running container called ApacheB
# -it will make it interactive with tty, thus leaving one with a shell inside the container
# ^D or exit will terminate this exec. the container will continue to run. it is like logout.
docker exec ApacheB ps -ef
# will run "ps -ef" inside the container, print output, and terminate the exec
# think of "ssh remotehost ps -ef" to run command w/o interactive shell in a remote environment
</PRE>
<H5>
Container of OSes in Amazon Linux
</H5>
<PRE>
docker pull ubuntu
docker run -it ubuntu /bin/bash
# start a bash shell that run inside the docker process tree env
# the run command by default attach stdin, stdout and stderr to the console,
# so all keystrokes will pass thru (which is why hitting ^Z) does not put docker to background.
# this was done on backbox
# apt-get works, no aptitude (even though host does have this command)
# ps -ef shows only the bash process!
docker pull rhel7
docker run -it rhel7 /bin/bash
# this was done on backbox
# uname shows ubuntu
# /etc/redhat-release exist in the FS inside the container
# yum works
# df -hl is very different than the ubuntu container
# mount shows the same list of mounts as in the ubuntu container
</PRE>
<H5>
CoreOS
</H5>
<a href="coreos.html">CoreOS</a>
relies on docker to provide packages. no rpm, dpkg, yum, apt-get <BR>
All CoreOS install has two boot partition, active/standby, where OS upgrade is done on standby. <BR>
<PRE>
docker pull httpd
docker run -p 80:80 httpd
docker pull pdevine/elinks2
docker run -it --rm pdevine/elinks2 elinks http://www.yahoo.com # will start interactive browser
docker run -it --rm pdevine/elinks2 elinks http://172.31.28.159 # use the host's eth0 IP to access the web server running on it
</PRE>
<A NAME="dockerfile"></A>
<H2>Building an image using dockerfile</H2>
One way to build an image is to save/commit an existing/modified image. <BR>
The other method is to build one from scratch using dockerfile <BR>
ref:
<A HREF="https://docs.docker.com/engine/userguide/dockerimages/">
https://docs.docker.com/engine/userguide/dockerimages/</A><BR>
<PRE>
mkdir myapp
cd myapp
vi dockerfile
docker build -t tin6150/myapp:v3 . # . will search for ./dockerfile -t is for tag
# optional upload to docker hub, assuming user tin6150 has been registered
# the "push path" depends on the tag used to do the build, not the relative file path of where dockerfile is located.
docker push tin6150/myapp
docker rmi myapp... # remove an image from the lost host.
</PRE>
dockerfile ::
<PRE class="code">
FROM ubuntu:14.04 # use ubuntu as a base image to build this docker container/app
MAINTAINER user <[email protected]>
RUN apt-get update && apt-get install -y ruby ruby-dev #
RUN gem install sinatra
# always run the apt-get update and install command in the same line using &&,
# or it would result in a db problem on the resulting container.
# on flip side, it is kinda "bad form" needing to run update, should just base it on a newer image.
</PRE>
<BR>
<UL>
<LI> Each RUN line adds a layer, better to chain unix commands using &&
<LI> ADD command will copy files from the build host to the container. build is then no longer "build anywhere"
<LI>
</UL>
<H5>Example Docker HTTPD image + psg static web content</H5>
<PRE>
docker run -p 80:80 -i -t --name ApachePsg -v ~/htdocs4docker:/mnt/htdocs httpd /bin/bash
# /mnt/htdocs will be created inside the container by the startup process
# note inside this container, it has very few commands. no scp, no wget.
# run this inside the container's bash :
# cp -pR /mnt/htdocs/psg/* /usr/local/apache2/htdocs
# httpd # this starts process and return to bash
# run the following on the host (ie, from a different window)
docker commit ApachePsg # create a new image from changes done to exisiting container
docker kill ApachePsg
docker run -p 80:80 -i -t --name ApachePsg2 -v ~/htdocs4docker:/mnt/htdocs ApachePsg /bin/bash
## above didn't work.
docker start ApachePsg # re-start a container using its name
docker attach ApachePsg # attach to the container (last start with bash, so get back to a prompt)
docker export # Export the contents of a container's filesystem as a tar archive
docker save # Save an image(s) to a tar archive (streamed to STDOUT by default)
docker commit # Create a new image from a container's changes
docker commit -m "commitMsg" RunningContainerName
# but how is it don't see the new item in docker images?
# nor was i able to do docker run with the new image...
# certainly, after commit, psg content remained inside the container.
# No way to give a name to the image! and no way to rename it!
# -m commitMsg is very important for identifying the image using history
# Even after commit is done, docker ps -a don't show the new container id
# because that was saved to disk and isn't the running instance!
# so can only see the info by carefully checking with docker images -a
# Managment in Docker is said to be none existing! Kubernetes??
docker images -a # see that 8e300072616a is newest image created
docker history 8e300072616a # 8e300072616a is the IMAGENAME from above docker commit.
# this cmd will show the commitMsg
# and some info on how image was created, and the
docker run -p 80:80 -i -t --name ApachePsgII 8e300072616a /usr/local/apache2/bin/httpd
# confirm that the new image can start
docker rename # rename a container
? rename image... no way to do this?? but when upload to dockerhub, give it a new name, and pull it again...
docker login # login to docker hub. credentials will be saved w/ encryption
docker commit -m "apache psgIII" edb6d60c97da tin6150/apache_psg3
# edb6d60c97da is a container id (from docker ps -a)
# tin6150/apache_psg3 is username/imagename
docker push tin6150/apache_psg3 # push the image to hub.docker.com
# at this point, image is uploaded to the web and ready for use by others :)
docker tag e4718e38a3b1 tin6150/apache_psg_3a:dev2 # was able to tag and push, no commit...
## but this push all images on the chain to create the current image??
## certainly pushing lot of stuff... but prev pull end up with lot of stuff too...
docker push tin6150/apache_psg_3a:dev2 # in hub.docker.com, see 81MB image.
# docker tag ref https://docs.docker.com/mac/step_six/
## on a different machine, eg centos7, can pull the image to test it out
docker run -p 80:80 -i -t --name ApachePsg_C tin6150/apache_psg3 /bin/bash
# docker run will pull the image, and create a container to run this service.
# dropped into bash prompt, can check the htdocs dir.
# httpd will start the web server
docker run -p 80:80 -i -t --name ApachePsg_C tin6150/apache_psg_3a:dev2 httpd # when no latest tag exist, must specify which one to get
</PRE>
<H2>Other more advance topics</H2>
<H3>Docker Data Volume</H3>
There are ways for container to mount the host's directory to its internal directory.
<BR>
Multiple container can mount the same host directory as well, but application need to be careful with data access and lock or it can create corruption.
<BR>
https://docs.docker.com/engine/userguide/dockervolumes/
<BR>
<PRE>
</PRE>
<H3>Performance</H3>
Better than VM, as no hypervisor overhead.
However, best hypervisor overhead is said to be just 2% over baremetal, so beyond the VM boot up time, some claim there is little room for container to improve on.
For microservice, app startup time is important thus container still offer advantage over VM.
<PRE>
docker run --cpu-shares=n
# assign a weight of how much cpu this run command get
# by default all container share cpu equally.
# weight are 0 to 1024. All containers weight are added and then ratio calculated based on requested weight.
docker run --cpu-quota=n
# wonder if they are enforced using cgroup
</PRE>
<H3>Dependencies</H3>
<PRE>
docker run will pull dependencies needed (think of yum auto download dependencies).
multi-container apps... one way is to view them as different pieces running on multiple host and rely on network communication.
</PRE>
<A NAME="linking"></A>
<H3>Linking Containers</H3>
Linking allow container to communicate with one another.
vs dependencies ??
https://goldmann.pl/blog/2014/01/21/connecting-docker-containers-on-multiple-hosts/
(maybe add diagram)
<H3>Multi-container app</H3>
Example of running wordpress in one container, and a MySQL DB on a different one. Ref:
<A HREF="http://www.sitepoint.com/how-to-use-the-official-docker-wordpress-image/">Article by Aleksander Koko</A>
<BR>
<PRE>
docker run --name wordpressdb -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress -d mysql:5.7
# starts MySQL container
docker run -e WORDPRESS_DB_PASSWORD=password --name wordpress --link wordpressdb:mysql -p 0.0.0.0:80:80 -d wordpress
# starts wordpress container
# --link name:alias is to create a private network connection to the named container
# (--link also copy ENV variables, if conflict, duplicated to HOST_ENV_abc and HOST_PORT_nnn)
# if don't specify to bind to 0.0.0.0:80, wordpress default to some docker bridge IP.
# use "-i -t" instead of "-d" to see web page access log in the console.
# Can then detach from session using ^P ^Q (it will NOT put container in paused state)
# alt, ^C on process. docker start wordpress will largely resume where it was left off
# (wordpress saved most state info to disk).
# (tested to work on amazon linux. centos7 didn't work, maybe SELinux... maybe cuz ran docker as root.)
</PRE>
The above just serve as proof of concept. It is not secure. To really run a wordpress site this way, refer to info in
<A HREF="https://hub.docker.com/_/wordpress/">docker hub</A>
<BR><BR>
Also, there is a more complex setup with NGINX load balancer, Redis cache:
<A HREF="http://www.dockerwordpress.com/">docker wordpress</A>
(mostly done via Docker Compose)
<H3>Docker Compose</H3>
Docker Compose is a declarative way of managing containers. Think Puppet, Chef and other configuration management tool,
applied to docker.
<BR>
eg Both examples of wordpress setup has reference to Docker Compose.
<BR>
<H3>Reference</H3>
<UL>
<li><A HREF="http://docs.aws.amazon.com/AmazonECS/latest/developerguide/docker-basics.html">Docker basic from AWS</A></li>
<li><A HREF="https://docs.docker.com/engine/userguide/dockerizing/">Docker Getting Started</A></li>
<li><A HREF="http://files.meetup.com/1590495/Docker.pdf">Docker (Taos)</A>slide 50 demo cgroup on memory </li>
<li><A HREF=""></A></li>
<li><A HREF="http://redis.io/">redis key-value db</A></li>
<li><A HREF="http://nginx.org/en/">nginx (engine x) load balancer</A></li>
<li><A HREF="">Open Container Initiative (OCI)</A> - Plumbing: RunC, Notary (content signing) </li>
<li><A HREF=""></A></li>
<li><A HREF=""></A></li>
<li>man docker # docker daemon man page</li>
<li>man docker run # man page for the run command of docker</li>
<li></li>
<li></li>
<li><A HREF="http://www.slideshare.net/jpetazzo/anatomy-of-a-container-namespaces-cgroups-some-filesystem-magic-linuxcon">Container SlideShare</A></li>
<li><A HREF="http://tba/">tba</A></li>
<li><A HREF="">tba</A></li>
</UL>
<BR><BR>
<!-- remove H1 after presentation -->
<div class="tomb">
<!-- tiny.cc/dock was registered but prob not under the tin6150 acc -->
<A HREF="http://tiny.cc/DOCKER">
http://tiny.cc/DOCKER</A>
</div>
<A HREF="https://www.pinterest.com/pin/361906520034094732/"><IMG SRC="fig/uranus-hertz.jpg" alt="dilbert comic uranus-hertz (download via pinterest)" width="100%" ></A>
(I am still waiting for docker to actually name my container Uranus_Hertz, but maybe it is just a matter of time?) <BR>
<BR><BR>
<H1>Container Runtime</H1>
<UL>
<LI>Docker runtime engine (LXC?)
<LI>containerd
<LI>rkt
<LI><A HREF="singularity.html">singularity</A>
</UL>
<H1>Container Orchaestration</H1>
<UL>
<LI><A HREF="k8s.html">Kubernetes</A>
<LI>Docker Swarm
<LI>Rancher
<LI>Mesos Marathon
<LI>
</UL>
<A NAME="landscape"></A>
<H1>Container Landscape</H1>
<CENTER>
<A HREF="http://www.slideshare.net/lilumb/docker-101-61428727/9"><IMG SRC="fig/univa-container-landscape.png" alt="container landscape stack diagram"></A> <BR>
Players in the container world, circa 2016. (Univa slide)
<BR>
</CENTER>
<A ID="hpc"></A>
<H3>Container in HPC</H3>
Container in HPC is a quite a large topic. For a feature comparison table of Shifter vs Singularity, and a list of relevant articles, see my blogger article
<A HREF="http://geekyap.blogspot.com/2016/11/docker-vs-singularity-vs-shifter-in-hpc.html">Docker vs Singularity vs Shifter</A>
<BR>
<H2>LBNL/NERSC Shifter</H2>
<UL>
<LI> NeRSC R&D + collaboration w/ Cray, in production use at NeRSC (Edison, Cori), open source release soon. Cray may develop commercial support for this.
<LI> <A HREF="http://slurm.schedmd.com/SLUG15/shifter.pdf">Paper in SC 2015.11</A>
<LI> <A HREF="https://www.nersc.gov/news-publications/nersc-news/nersc-center-news/2015/shifter-makes-container-based-hpc-a-breeze/">https://www.nersc.gov/news-publications/nersc-news/nersc-center-news/2015/shifter-makes-container-based-hpc-a-breeze/</A>
<LI> Flexibility: user-defined images (UDI) sw stack, placed as container image.
<LI> Reproducible research: UDI can be validated and workflow will run exactly every time it is started, even if environment may have aged.
<LI> SW stack isolation. Different users in diff realm maintain their own UDI, HPC just run them as jobs, they are completely independent of one another. Accomplished by using linux VFS namespaces to run multiple Shifter containers.
<LI> Utilize public image repos like DockerHub, user can start application stack without sys admin priviledges.
<LI> Not using Docker daemon, as that assume local disk (aufs, btrfs)
<LI> native app perf, fast job startup.
<LI> FS are re-mounted, no setuid.
<LI> Containers are read-only to user (write to network location?) (Dockers allow changes to container after admin issue save command.)
<LI> Shifter essentially adopt docker images, but have to redo the backend to provide docker daemon-like features executed by the HPC batch manager system.
<LI>
</UL>
<BR>
<H2>LBNL/HPCS Singularity v 1.0 </H2>
<UL>
<LI> For feature of the newer Singularity 2.2, see
<A HREF="http://geekyap.blogspot.com/2016/11/docker-vs-singularity-vs-shifter-in-hpc.html">Docker vs Singularity vs Shifter</A>
<LI> VM does not address portability. Singularity address portability.
<LI> It is like getting the portability of Docker and make it run in an HPC batch system. However, Singularity does not use any piece of Docker.
<LI> SAPP (Singularity App) = Combination of RPM and Container.
<LI> ldd shows what library a program need. Singularity automatically build dependency tree and add all the required dependency into container it builds.
<LI> all dependencies, down to C libraries, are included. Thus, SAPP is very portable and reproducible.