课程课件:https://edu.aliyun.com/lesson_1651_17053?spm=5176.10731542.0.0.513620beJRqEuB#_17053
容器和镜像
- 进入操作系统,使用ps查看进程
进程的特点
- 进程之间是可以相互通信的:高级权限进程可以攻击其他进程
- 共享同一份文件系统(对同样一份文件进行读写操作):对数据的增删差改,某些进程可以把其他进程需要的文件删除掉,进程各自所需要的依赖会相互冲突
- 同样的一份系统资源:资源抢占问题,单一应用消耗很大的cpu和内存,使得某些进程资源不够,无法提供服务
容器基于进程,如何解决进程的这三个问题
- namespace技术:资源视图的隔离
- chroot:linux和unix可以通过chroot将子目录变成根目录
- cgroup:限制资源使用率(docker要将systemd改成cgroup)
容器和镜像的概念
- 容器是一个独立的文件系统,不需要具备内核相关的代码和工作,只需要提供容器所需要的二进制文件、配置文件和依赖即可。
- 镜像:容器运行时所需要的所有文件的集合,一次构建可到处运行
Dockerfile的概念
- Dockerfile: 构建镜像,提供了很好的语法糖,帮助我们很好描述构建的每一个步骤。每一个构建步骤会对已有的文件系统进行增删查改,会导致文件系统变化,这些变化称之为changeset。将Dockerfile的每一条步骤依次作用到一个空的文件夹下,会得到一个完整的镜像。
- changeset的特点:分层+复用
- 分层导致可以复用:第一部分,alpine镜像;第二部分,golang镜像基于alpine镜像的自身变化
- 复用产生的效果:
- 提高分发效率:大的镜像,将其拆分成各个小块就能够提高镜像的分发效率,因为镜像拆分之后就可以并行下载这些数据;
- 数据相互共享,如果已经包含数据,不需要再去下载
- 镜像共享,节省磁盘空间
Dockerfile文件简要介绍
- FROM 行表示以下的构建步骤基于什么镜像进行构建,正如前面所提到的,镜像是可以复用的;
- WORKDIR 行表示会把接下来的构建步骤都在哪一个相应的具体目录下进行,其起到的作用类似于 Shell 里面的 cd;
- COPY 行表示的是可以将宿主机上的文件拷贝到容器镜像内;
- RUN 行表示在具体的文件系统内执行相应的动作。当我们运行完毕之后就可以得到一个应用了;
- CMD 行表示使用镜像时的默认程序名字。
构建镜像
- docker build 构建镜像
- docker push 将镜像推送到镜像仓库(镜像的中转站:中心存储)
运行容器
- docker pull 下载镜像 (docker pull busybox:1.25)
- docker images 查看镜像
- docker run 运行镜像(配置:容器名称、镜像地址、指定运行程序比如top)
- top表示容器所对应的进程是一个top命令 (指定运行程序)
容器的生命周期
容器运行时的生命周期
- docker run:选择一个镜像来提供一个独立的文件系统,并指定相应的运行程序initial进程
- initial进程启动退出,容器也启动退出
- 容器内除了initial进程还有其他进程。
- initial进程管理范围:initial进程产生其他子进程+docker exec产生的运维操作
- initial进程退出,管理范围内的资源都会释放,以防止资源泄露。这波操作引发的问题:容器产生的数据会丢失(容器可能是有状态的,比如redis和mysql)。解决方案:重要数据持久化到指定目录(该目录称之为数据卷)
数据卷的管理方式
- 通过bind,将宿主机的目录挂载在容器内。 docker run -v 宿主机目录:容器目录 …。缺点:需要对所有宿主机的目录进行统一管理
- 将目录管理交给moby运行引擎
- docker create volume xx,使用docker创建一个数据卷,docker管理它。docker run -v volume名称xx:容器目录
容器项目的架构
moby容器管理引擎
- 当前最流行的容器管理引擎,moby daemon 会对上提供有关于容器、镜像、网络以及 Volume的管理。
- moby依赖的最重要的组件是containerd(容器运行时管理引擎,独立于moby daemon)
- containerd下面一层是shim,守护进程,管理容器的生命周期,容器是由不同的容器运行时创建的。容器从containerd中脱离,通过插件shim进行管理
- 目前有多种容器虚拟化的解决方案:runC、kata、gVisor。shim可以针对不同的容器运行时虚拟化解决方案进行开发
- moby跪了。因为shim,容器还在
- moby和containered,可以自由升级。因为shim还在,不影响业务。
容器和vm
虚拟机
- 安装虚拟机:使用hypervisor虚拟化技术来模拟CPU、内存等硬件资源,在宿主机上构建了一个Guest OS(独立的内核ubuntu、centos等)
- 更好的隔离效果,但
- 需要一部分的资源去运行Hypervisor
- Guest OS占用大量的磁盘空间(windows10-30G,ubuntu5-6G)
- 启动比较慢
容器
- 独立的文件系统,需要提供镜像(所需的所有文件集合)
- 进程级别的隔离,未来向着强隔离的方向发展(比如kata、gVisor等)
- 启动时间快于vm,磁盘占用小于vm
课后习题
- https://www.cnblogs.com/songqingbo/p/11389725.html
- https://docs.docker.com/engine/reference/commandline/ps/
问题1
- 已运行 docker run -d -t —name demo ubuntu top 命令,以下哪个 docker 命令创建出的容器能看见 demo 容器进程 B
- A.docker run --name demo-x --net container:demo ubuntu ps
- B.docker run --name demo-x --pid container:demo ubuntu ps
- C.docker run --name demo-x --ipc container:demo ubuntu ps
- https://blog.csdn.net/nickDaDa/article/details/88716395
- pid
--pid="" : Set the PID (Process) Namespace mode for the container,
'container:<name|id>': joins another container's PID namespace
'host': use the host's PID namespace inside the container
- IPC(POSIX/SysV IPC)命名空间提供了相互隔离的命名共享内存、信号灯变量和消息队列。
- http://dockone.io/article/152
--ipc="MODE" : 给容器设置IPC模式
+ ”” Use daemon’s default.
“none” Own private IPC namespace, with /dev/shm not mounted.
“private” Own private IPC namespace.
“shareable” Own private IPC namespace, with a possibility to share it with other containers.
“container: <_name-or-ID_>" Join another (“shareable”) container’s IPC namespace.
“host” Use the host system’s IPC namespace.
- net
--dns=[] : Set custom dns servers for the container
--network="bridge" : Connect a container to a network
'bridge': create a network stack on the default Docker bridge
'none': no networking
'container:<name|id>': reuse another container's network stack
'host': use the Docker host network stack
'<network-name>|<network-id>': connect to a user-defined network
--network-alias=[] : Add network-scoped alias for the container
--add-host="" : Add a line to /etc/hosts (host:IP)
--mac-address="" : Sets the container's Ethernet device's MAC address
--ip="" : Sets the container's Ethernet device's IPv4 address
--ip6="" : Sets the container's Ethernet device's IPv6 address
--link-local-ip=[] : Sets one or more container's Ethernet device's link local IPv4/IPv6 addresses
问题2
- –uts="" : Set the UTS namespace mode for the container,
‘host’: use the host’s UTS namespace inside the container - UTS命名空间用于设置主机名和对该命名空间中正在运行的进程可见的域。默认下,所有的容器,包括那么以–network=host运行的容器,有它们自己的UTS命名空间。设置UTS为host将使容器使用与主机相同的UTS命名空间。注意–hostname在host UTS模式是无效的。
- 当你想在主机更改hostname之后,同时也更改同样的hostname到容器,这就需要与主机共享UTS命名空间。一个更高级的用例是从容器更改主机的hostname。
- 以下哪个 docker 命令可以用来创建一个使用宿主机主机名的容器? A
- A. docker run --uts=host ubuntu hostname
- B. docker run ubuntu hostname
- C. docker run --ipc host ubuntu ps
问题3
- 已运行 docker run -d -t —name demo ubuntu top 命令, 在 demo 这个容器内看到 top 命令的 PID 是什么? B
- A.随机数字
- B. 1
- -t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上
问题4
- 如何快速判断 docker daemon 是否支持动态接管运行容器? AB
- A. docker info | grep ‘Live Restore Enabled’
- B. docker info -f ‘{{.LiveRestoreEnabled}}’
- C. docker info -f “{{.Live_Restore_Enabled}}”
- docker info 显示一些相关的系统信息
- -f :根据条件过滤显示的内容。
- grep 命令用于查找文件里符合条件的字符串。
问题5:容器重启
- 创建容器时添加参数 --restart=always 后,当 docker 重启时,容器自动启动。
- docker -d :后台运行容器,并返回容器ID;
问题6: docker inspect
- 显示一个容器的具体配置信息
- docker inspect demo -f ‘{{.State.Pid}}’ demo启动进程的pid
- 参考:https://www.cnblogs.com/ilinuxer/p/6188303.html
问题7:top
- docker run -d -t --name demo ubuntu top,docker exec -it demo kill -9 1强行给容器内一号进程发kill信号,容器是否会退出? 答案:否
问题8
- 已运行 docker run -d -t —name demo ubuntu top 和 docker run --name demo-x --pid container:demo ubuntu ps 命令,是否可以在 demo-x 容器内部停止容器? 答案:是
附录:名词详解
语法糖
- (Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。
Alpine
- https://yeasy.gitbooks.io/docker_practice/content/cases/os/alpine.html
- Alpine操作系统是一个面向安全的轻型 Linux 发行版。它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐。在保持瘦身的同时,Alpine 还提供了自己的包管理工具 apk,可以通过 https://pkgs.alpinelinux.org/packages 网站上查询包信息,也可以直接通过 apk 命令直接查询和安装各种软件。
- Alpine 由非商业组织维护的,支持广泛场景的 Linux发行版,它特别为资深/重度Linux用户而优化,关注安全,性能和资源效能。Alpine 镜像可以适用于更多常用场景,并且是一个优秀的可以适用于生产的基础系统/环境。
- Alpine Docker 镜像也继承了 Alpine Linux 发行版的这些优势。相比于其他 Docker 镜像,它的容量非常小,仅仅只有 5 MB 左右(对比 Ubuntu 系列镜像接近 200 MB),且拥有非常友好的包管理机制。官方镜像来自 docker-alpine 项目。
- 目前 Docker 官方已开始推荐使用 Alpine 替代之前的 Ubuntu 做为基础镜像环境。这样会带来多个好处。包括镜像下载速度加快,镜像安全性提高,主机之间的切换更方便,占用更少磁盘空间等。
top命令
- top命令经常用来监控Linux的系统状况,比如cpu、内存的使用等
moby
- https://blog.csdn.net/yk20091201/java/article/details/80016135
- 2017年年初,docker公司将原先的docker项目改名为moby,并创建了docker-ce和docker-ee
- moby是继承了原先的docker的项目,是社区维护的的开源项目,谁都可以在moby的基础打造自己的容器产品
- docker-ce是docker公司维护的开源项目,是一个基于moby项目的免费的容器产品。
- docker-ee是docker公司维护的闭源产品,是docker公司的商业产品。
- moby project由社区维护,docker-ce project是docker公司维护,docker-ee是闭源的。