系统学docker笔记
什么是docker
Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。
Docker 是当前流行的 Linux 容器解决方案,利用 Namespaces 、Cgroups 以及联合文件系统UnionFS 实现了同一主机上容器进程间的相互隔离。
- NameSpaces:隔离进程,让进程只能访问到本命名空间里的挂载目录、PID、NetWork 等资源
- Cgroups: 限制进程能使用的计算机系统各项资源的上限,包括 CPU、内存、磁盘、网络带宽等等
- 联合文件系统UnionFS : 保存一个操作系统的所有文件和目录,在它基础之上添加应用运行依赖的文件。创建容器进程的时候给进程指定Mount Namespace 把镜像文件挂载到容器里,用 chroot 把进程的 Root目录切换到挂载的目录里,从而让容器进程各自拥有独立的操作系统目录。
虚拟化和docker区别
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
docker cs架构
docker是cs结构,Docker桌面版安装包括了Docker Client和Docker Engine。
主要包含:
- 后台进程(dockerd)
- rest api server
- cli接口(docker)
Docker的Client和Engine之间的通讯有一下几种方式
- Unix Socket 这是类unix系统进程间通讯的一种方式,当Client操作本机的Engine是就是使用这种方式。缺省的socket文件是unix:///var/run/docker.sock
- Systemd socket activation : 这是systemd提供的一种为了服务并行启动设计的socket,
- TCP : 上面两种都是只能连接本地Engine,需要连接远程Engine,必须在服务端开始TCP连接。此连接为不安全连接,数据通过明文进行传输。缺省端口2375。
- TCP_TLS : 在TCP的基础之上加上了SSL的安全证书,以保证连接安全。缺省端口2376。
docker 底层技术支持
- Namespaces:隔离pid,net,ipc,mnt,uts
- Control groups:做资源限制
- Union file systems:Conatiner和image的分层
镜像
Dockerfile命令
workdir
workdir等于linux cd命令
workdir /test # 如果没有会自动创建
workdir demo
run pwd # 输出结果为/test/demo
推荐workdir,不要 run cd。尽量使用绝对路径。
ADD COPY
对于目录而言,COPY 和 ADD 命令具有相同的特点:只复制目录中的内容而不包含目录自身。
ADD 命令可以完成 COPY 命令的所有功能,是copy的增强版,并且还可以完成两类超酷的功能:
- 解压压缩文件并把它们添加到镜像中
- 从 url 拷贝文件到镜像中
当然,这些功能也让 ADD 命令用起来复杂一些,不如 COPY 命令那么直观。 docker 官方建议我们当需要从远程复制文件时,最好使用 curl 或 wget 命令来代替 ADD 命令。原因是,当使用 ADD 命令时,会创建更多的镜像层,当然镜像的 size 也会更大
EXPOSE
expose是对端口的暴露声明,记住是声明,不写也没事。
写了expose后,运行容器时如果加-P参数,就会对expose声明的端口进行和宿主主机端口随机映射。
VOLUME
定义匿名数据卷 valume /test/data 这里会自动生成一个volume,然后/test/data和自动生成的那个目录映射。 docker run的时候如果使用-v,–mount可以覆盖dockerfile里面的这个命令。
CMD
Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数。CMD 指令就是用于指定默认的容器主进程的启动命令的。
多个cmd命令会覆盖。 docker run时如果指定入口程序也会覆盖Dcokerfile中的cmd。比如
docker run -it hello /bin/bash
// /bin/bash就会覆盖cmd命令
ENTRYPOINT
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。
ENTRYPOINT 在运行时也可以替代,不过比 CMD 要略显繁琐,需要通过 docker run 的参数 –entrypoint 来指定。
当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:
<ENTRYPOINT> "<CMD>"
docker run -it hello /bin/bashz这个例子中的/bin/bash也会当做entrypoint的参数。
容器
看几个特点:
- 通过image创建(copy)
- image是只读的。再image layer之上建立一个container layer(可读写)
- image和container类比面向对象的类和示例
- image负责APP的存储和分发,container负责运行APP
image是只读的,那从Dockerfile构建image的过程中,docker build是怎么执行命令修改的呢? 答:构建过程中会生成临时的contailer,其实是在容器上执行的操作,后面再把临时容器删除,又容器commit成image。
数据管理
把写到容器里面的东西写到宿主主机上。 分两种:
- volume类型,通过docker volume ls可以看到
- bind类型,这种不会不会生成volume
volume类型匿名挂载:
docker run -v 容器内路径
DockerFile中volume命令
volume类型具名挂载:
-v 卷名:容器内路径
bind类型
docker run -v /主机路径:容器内路径 # 指定路径挂载
docker –mount type=bind,source=/src/webapp,target=/usr/share/