文章目录
一、docker简介
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 通过 Linux 内核的 Namespace 技术实现了文件系统、进程、设备以及网络的隔离,然后再通过 Cgroups 对 CPU、 内存等资源进行限制,最终实现了容器之间相互不受影响,由于容器的隔离性仅仅依靠内核来提供,因此容器的隔离性也远弱于虚拟机
1、Docker namespace
命名空间是linux内核强大的特性,每个容器都有自己的命名空间,运行在其中的应用都是在独立操作系统中运行一样。命名空间保证了容器之间彼此互不影响
2、Docker CGroups
容器使用namespace来隔离运行环境,使得容器中的进程就像在一个独立的环境中运行,但是为了防止它占用太多的资源,于是Docker就通过使用Linux cgroups来限制容器中的进程允许使用的系统资源。
Linux Cgroup可以让系统中所运行任务(进程)的用户定义组分配资源—比如CPU时间、系统内存、网络带宽
3、Docker UnionFS
UnionFS全称union file system,即联合文件系统,要理解unionFS,我们首先需要先了解bootfs和rootfs。
按照docker官网上的说法,docker的文件系统分为两层:bootfs和rootfs:
- bootfs包含了bootloader和linux内核。用户是不能对这层作任何修改的。在内核启动之后,bootfs实际上会unmount掉。
bootfs(boot file system)包含操作系统boot loader和linux内核kernel,用户不能修改这个文件系统,一旦linux启动成功后,整个linux内核加载进内存之后bootfs会被卸载掉,从而释放内存。同样的内核版本不同的linux发行版对应的bootfs都是一样的。
- rootfs则包含了一般系统上的常见目录结构,类似于/dev, /proc, /bin等等以及一些基本的文件和命令。
rootfs(root file system),linux系统在启动时,rootfs首先会被挂载为只读模式,然后再启动完成后被修改为读写模式。
4、AUFS
AUFS 即 Advanced UnionFS 其实就是 UnionFS 的升级版,它能够提供更优秀的性能和效率。
AUFS 作为先进联合文件系统,它能够将不同文件夹中的层联合(Union)到了同一个文件夹中,这些文件夹在 AUFS 中称作分支,整个『联合』的过程被称为联合挂载(Union Mount)
Docker最开始采用AUFS作为文件系统,也得益于AUFS分层的概念,实现了多个Container可以共享一个image。但是由于AUFS未并入Linux内核,且只支持Ubuntu,考虑到兼容性问题,在Docker 0.7 版本中引入了存储驱动,目前,Docker支持AUFS、Btrfs、Devicemapper、OverlayFS、ZFS五种存储驱动。
支持将不同目录挂载到同一个虚拟文件下的文件系统。这种文件系统可以一层一层地叠加修改文件。无论底下有多少层都是只读的,只有最上层的文件系统是可写的。当需要修改一个文件时,AUFS创建该文件的一个副本,使用CoW将文件从只读层复制到可写层进行修改,结果也保存在科协层。在Docker中,只读层就是image,可写层就是Container
5、Docker 镜像分层机制
Docker Image 是有一个层级结构的,最底层的 Layer 为 BaseImage(一般为一个操作系统的 ISO 镜像),然后顺序执行每一条指令,生成的 Layer 按照入栈的顺序逐渐累加,最终形成一个 Image
在系统启动时,Docker会首先一层一层的加载image,直到最下面的base image。而这些image都是只读的。
最后,在最上层添加可读写的一个容器, 这里存放着诸如unique id,网络配置之类的信息。
总之:dockers=LXC+AUFS
- LXC负责资源管理(包括cgroup,namespace,chroot等组件,并通过cgroup资源管理);
- AUFS负责镜像管理;
一、Docker常见命令
1、帮助命令
docker version # 显示docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker --help # 帮助命令
2、镜像命令
docker images # 查看所有本地的主机上的镜像
docker search # 搜索镜像
docker pull 镜像名称 [:tag] # 可指定版本,不指定版本默认最新版本
# 使用 tag 命令为镜像添加标签(类似一个快捷方式)
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
# 镜像保存
docker save -o python_3.tar python:3
# 镜像加载
docker load -i python_3.tar
docker rmi # 删除镜像
3、容器命令
# 映射外路径启动
docker run -v D:\A_Project\docker\centos:/home --name centos -d centos
# 进入当前正在运行的容器
docker exec -it 容器ID /bin/bash
# 列出所有运行的容器
docker ps -a # 查看当前所有容器
docker ps -aq # 查看当前所有容器的id
docker ps # 查看正在运行的容器
docker ps -a -n=1 # 列出最新创建的容器 n为个数
# 退出容器(容器内执行)
exit # 直接退出容器
# 删除容器
docker rm 容器id # 删除指定id的容器
# 启动和停止容器的操作
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
# 查看容器日志
docker logs -f -t --tail 100 5bf2312ac02f # 显示最后100条日志
# 查看容器进程信息ps
docker top 容器ID
# 查看镜像的元数据
docker inspect 容器ID
# 从容器内拷贝文件到主机上
docker cp 容器ID:容器内路径 目的的主机路径
# 查看容器的挂载情况
docker volume ls
二、数据卷
数据卷(Data Volumes)是宿主机中的一个目录或文件,数据卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。当容器目录和数据卷目录绑定后,对方的修改会立即同步,一个数据卷可以被多个容器同时挂载,一个容器也可以被挂载多个数据卷
1、匿名挂载
生成容器时 -v只指定容器内路径,不指定宿主机路径
docker run -d -p --name nginx_test -v /etc/nginx nginx
此时查看挂载的位置可以通过docker volume ls命令查看,很长的字母组合的名字就是匿名数据卷
[root@hecs-103705 study]# docker volume ls
DRIVER VOLUME NAME
local 4b4937ceeff2d47c0f15dddadc1d44ecd49f293e2cc12e13d5ae76894c58bc2b
2、具名挂载
docker run -d -p --name tomcat_test -v logs:/home/logs tomcat
此时查看挂载的位置可以通过docker volume ls命令查看
[root@hecs-103705 study]# docker volume ls
DRIVER VOLUME NAME
local logs
3、指定路径挂载
docker run -d -p --name tomcat_test -v /home/:/home/logs tomcat
三、Dockerfile
通过编写Dockerfile文件来构建docker镜像的构建文件,镜像是分层的,脚本一个个的命令,每个命令都是一层,层级越少越好
例子:
FROM alpine_base:v1
LABEL maintainer='ydli'
ARG SERVER_ADDR='ip地址'
ENV SERVER_ADDR=${SERVERADDR}
COPY docker-entrypoint.sh
RUN apk add --update supervisor nginx tzdata && \
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone && \
apk del tzdata && \
rm -rf /var/cache/apk/* && \
mkdir /tmp/nginx && \
mkdir -p /var/www/html && \
chown -R nginx:nginx /var/www/html && \
chmod u+x /docker-entrypoint.sh
COPY dist/ /var/www/html/
VOLUME /var/log/nginx/
EXPOSE 80 8000 443
ENTRYPOINT ["/docker-entrypoint.sh"]
1、指令
FROM # 基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤,tomcat镜像,这是tomacat压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 Dockerfile,这个时候就会运行onbuild
COPY # 类似add,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量
CMD和ENTRYPOINT区别:
CMD命令只能有一个,如果Dockerfile中包含CMD命令,但在docker run后面加cmd命令后会覆盖原Dockerfile中的CMD命令,而ENTRYPOINT不会覆盖,是追加执行
2、制作镜像的过程
1)编写Dockerfile文件
2)生成镜像
# docker build -t 镜像名:版本 .
docker build -t mynginx:v1 .
(以下是可选操作:发布镜像操作)
3)docker login -u 用户名
4)docker push 镜像名
四、Docker网络
实现容器与容器之间(同一网络下的容器之间可直接通过容器名访问),容器与外部之间的通信
在默认情况下,每一个容器在创建时都会创建一对虚拟网卡,两个虚拟网卡组成了数据的通道,其中一个会放在创建的容器中,会加入到名为 docker0 网桥中
网桥 docker0 通过 iptables 中的配置与宿主机器上的网卡相连,所有符合条件的请求都会通过 iptables 转发到 docker0 并由网桥分发给对应的机器。
可以通过ip addr
命令查看网络,其中docker0是linux安装docker后自动生成的,而下面三个4493&4492、4511&4510、4513&4512为docker容器的网络,通过桥接的方式访问,使用的linux技术是 evth-pair
docker0会为每一个容器分配一个新的 IP 地址并将 docker0 的 IP 地址设置为默认的网关
1、网络模式
bridge :桥接 docker(默认,如果自己创建也用bridge)
none:不配置网络(用的少)
host:和主机共享网络
container:容器网络连接(用的少,局限大)
2、查看网络
# 查看网络命令
docker network --help
docker network ls
----------------------------
NETWORK ID NAME DRIVER SCOPE
075fff009f22 bridge bridge local
efbaf94573b8 host host local
29125732f2e0 none null local
# 查看网络具体信息
docker network inspect 075fff009f22
3、自定义网络
自定义的网络可以直接使用容器名直接ping通
# 创建网络
docker network create django_net
# 启动容器放在自定义网络
docker run -d -P --name tomcat-net-01 --net mynet tomcat