一. Docker是什么?
Docker是基于Go语言实现的云开源项目,对应用程序进行隔离,并且独立于宿主机和其他进程,这种运行时封装的状态称为容器。
Docker理念就是将应用及依赖包打包到一个可移植的容器中,可发布到任意linux发行版 docker 引擎中,使沙箱机制运行程序,程序之间相互隔离。
Docker的设计,打破过去程序即应用的观念,透过镜像将作业系统核心除外,将应用程式所需要的系统环境,由上到下打包,达到应用程式跨平台间的无缝接轨运作。只需要一次部署环境,换到别的机子上就可以一键部署,大大简化了操作。
docker的三要素:镜像、容器和仓库。
(1)镜像 (image):就是一个只读的模板,镜像可以用来创建Docker容器,一个镜像可以创建很多容器。类似于java 中的类对象。
(2)容器(container):Docker利用容器独立运行的一个或一组应用,容器是用镜像创建的运行实例,他可以被启动、开始、停止、删除。每个容器是相互隔离的、保证安全的平台。容器的定义和镜像几乎一模一样,也是一堆层的同一视角,唯一区别在于容器的最上面那层是可读可写的。
(3)仓库(repository):存放镜像文件的场所,仓库和仓库注册服务器registry是有区别的,仓库注册服务器往往存放着多个仓库,每个仓库中又包含多个镜像,每个镜像有不同的标签。
Docker是一个C/S结构的系统柜,Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从客户端接收命令并管理运行在主机上的容器
docker的内部组件:
(1)namespaces:linux内核提供的一种进程资源隔离的机制,例如进程、网络、挂载点等,不同的容器在不同的命名空间中。
(2)CGroups:linux内核提供的一种限制进程资源的机制,例如cpu、内存等资源。
(3)UnionFs:联合文件系统,它支持对于文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union文件系统是Docker镜像的基础,镜像可以通过分层进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。特性:一次同时加载多个文件系统,但从外面看其里,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终文件系统会包含所有底层的文件和目录。
二. 为什么使用 docker?
docker和vm的区别:
Docker容器 虚拟机VM
操作系统 与宿主机共享OS 宿主机OS上运行虚拟机OS
存储大小 镜像小,便于存储和传输 镜像庞大
运行性能 几乎无额外性能损失 操作系统额外的CPU、内存消耗
移植性 轻便、灵活、适应于Linux 笨重,与虚拟化技术耦合度高
硬件亲和性 面向软件开发者 面向硬件运维者
为什么 docker 比 vm 快????
(1)Docker有着比虚拟机更少的抽象层,由于docker不需要hypervisor实现硬件资源虚拟化,运行在docker容器上的程序都是直接使用的实际物理机的硬件资源,docker运行性能几乎无额外损耗。
(2)docker 直接利用宿主机的内核,而不需GuestOS,因此,当新建一个容器时,docker不需和虚拟机一样重新加载这个虚拟机内核,避免引寻、加载操作系统内核比较费时费资源的过程。当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返回新建过程是分钟级别的,而docker由于直接利用宿主机的操作系统,所以省略了这个返回过程,因此新建一个docker只需要几秒钟。
三. docker的安装
对于centos7版本以上的安装过程如下(官网安装教程)
1. 移除旧版本的docker
sudo yum remove docker docker-client docker-client-latest \
docker-common docker-latest docker-latest-logrotate \
docker-logrotate docker-engine
2. 安装所需依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
3. 设置稳定的存储库
sudo yum-config-manager --add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
4. 启用一些存储库
sudo yum-config-manager --enable docker-ce-nightly docker-ce-test
5. 开始安装最新版本的docker
sudo yum install docker-ce docker-ce-cli containerd.io
在使用docker之前,先熟悉下docker常用命令
四. 镜像
1. 镜像简介
定义:Docker镜像是一个不包含linux内核而又精简的linux操作系统。
默认会从国外拉取镜像,建议配置国内镜像仓库
vi /etc/docker/daemon.json
{
"registry-mirrors":["https://registry.docker-cn.com"]
}
docker其实是一层层的文件系统组成。我们可以通过使用docker histroy imageName
命令查看镜像各层的内容,每层对应dockerFile中的一条指令。容器其实就是在镜像上又加了一层读写层。如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。
bootfs( boot file system)主要包含 bootloader和 kernel, bootloader主要是引导加载 kernel, Linux刚启动时会加载 bootfs文件系统,在Docker镜像的最底层是 bootfs.这一层与我们典型的 Linux/Und系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载 bootfs
rootfs (root file systen),在 bootfs之上,包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层可以直接使用host的kernel,自己只需要提供rootfs就可以了,由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别。
传统的Linux加载bootfs时会先将rootfs设为read-only,然后在系统自检之后将rootfs从read-only改为read-write,然后我们就可以在rootfs上进行写和读的操作了。
但Docker的镜像却不是这样,它在bootfs自检完毕之后并不会把rootfs的read-only改为read-write。而是利用union mount(UnionFS的一种挂载机制)将一个或多个read-only的rootfs加载到之前的read-only的rootfs层之上。在加载了这么多层的rootfs之后,仍然让它看起来只像是一个文件系统,在Docker的体系里把union mount的这些read-only的rootfs叫做Docker的镜像。但是,此时的每一层rootfs都是read-only的,我们此时还不能对其进行操作。当我们创建一个容器,也就是将Docker镜像进行实例化,系统会在一层或是多层read-only的rootfs之上分配一层空的read-write的rootfs。
docker镜像的分层好处:共享资源,比如,有多个镜像都从相同的base镜像构建而来,那么宿主机只需要在磁盘上保存一份base镜像,同时内存中也只需加载一份base镜像,就可以为所有容器服务了,而且镜像的每一层都可以被共享。
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据作为镜像的一部分保存起来,那么当容器删除后,数据自然也没有了。所以我们使用容器数据卷来保存这些数据。
2. 文件共享
容器数据卷就是目录或文件,存在于一个或者多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能绕过Union file system提供一些用于持续存储或共享数据的特性。
容器数据卷的设计目的就是数据的持久化,完全独立与容器的生存周期,因此docker不会在容器删除时删除其挂载的数据卷。
容器数据卷的特点如下:
(1)数据卷可在容器之间共享或者重用数据。
(2)卷中的更改可直接生效。
(3)数据卷中的更改不会包含在镜像的更新中。
(4)数据卷的生命周期一直持续到没有容器使用它为止。
使用方式如下:
1. 新建容器时,使用 v + 参数
docker run -it -v /宿主机绝对路径目录:/容器内目录[:ro] 镜像名 //容器read only
2. 通过dockerFile创建镜像时,使用 volume命令指定
VOLUME[“/dataVolumeContainer1”,“/dataVolumeContainer2”]
容器间数据共享的方式通过继承。命名的容器挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。使用方式如下:
docker run -it --name dc02 --volumes-from dc01 imageName
容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。比如 doc01继承 doc02, doc02继承doc03,如果删除doc02,doc01 和 doc03还是会数据共享。
3. DockerFile
DockerFile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
DockerFile基础知识
(1)每条保留字指令都必须为大写字母且后面要跟至少一个参数。
(2)指令按照从上到下,顺序执行。
(3)#表示注释。
(4)每条指令都会创建一个新的镜像层,并对镜像进行提交。
DockerFile的一些常用指令。
FROM baseImage //当前镜像是基于哪个基础镜像制作的
MAINTAINER name|email //制作者的名称或者邮件地址
RUN command //构建镜像时运行的命令
EXPOSE port //当前容器对外暴露的端口
WORKDIR dir //进入伪终端时所在目录
ENV key value //设置环境变量
ADD src dest //拷贝src目录中的文件到容器dest目录,该命令会自动处理url和tar
COPY src dest //同ADD, 但是不会处理压缩文件,直接拷贝
VOLUME ["/dir1","/dir2"] //容器数据卷,用来做文件的持久化
CMD command //容器启动时运行的命令
ENTRYPOINT command //同CMD
ONBUILD command //当其他dockFile中使用该镜像做基础镜像构建镜像时,该命令会被触发
最后使用 build 命令进行构建
DockerFile构建镜像过程如下:
(1)Docker从基础镜像运行一个容器。
(2)执行一个命令对该容器进行修改。
(3)执行类似 commit 对当前容器新建成一个新的镜像。
(4)对新镜像运行出一个新容器,重复2-3
构建 java网站环境镜像使用案例:
vim dockerFile
FROM centos:7
MAINTAINER someone
ADD jdk....tar.gz /usr/local
ENV JAVA_HOME /usr/local/jdk...
ADD tomcat9 /usr/local
RUN rm -rf /usr/local/*.tar.gz
WORKDIR /usr/local/tomcat9
EXPOSE 8080
五. 镜像仓库
1. 搭建私有仓库
Docker Hub作为Docker默认官方公共镜像;如果想要自己搭建私有镜像仓库,官方也提供了registry镜像,使得搭建私有仓库非常简单,过程如下:
1.下载registry镜像并启动
docker pull registry
docker run -d -p5000:5000 --name "myregistry" registry
2. 查看仓库内的所有镜像
curl http://registryIp:5000/v2/_catalog
3. 配置该私有仓库受信任
vi /etc/docker/daemon.json
{"insecure-registries":["registryIp:5000"]}
systemctl restart docker
4. 给镜像打标签,实际上是指定私有仓库的地址
docker tag imageName registryIp:5000/imageName
5. 将该镜像上传到私有仓库
docker push registryIp:5000/imageName
6. 通过访问 http://registryIp:5000/v2/_catalog查看是否上传成功
7. 从私有仓库下载镜像
docker pull registryIp:5000/imageName
2. 公共仓库的使用
1. 注册用户(https://hub.docker.com/)
2. 使用docker login 命令进行登录
3. 给镜像打标签
docker tag imageName dockerId/imageName
5. 上传该镜像
docker push dockerId/imageName
六. 企业级镜像仓库Harbor