一、什么是Docker
为什么会有Docker的出现?
在我们开发完一个项目之后,需要将项目部署到Linux系统上。这时就会有一个问题,如果你的项目十分庞大,在你本机Windows系统上安装了相当多的依赖,那么移植到Linux上则需要将这些依赖对应的Linux版本全部重新安装一遍,重新调试测试一遍,这是一个噩梦。Docker的出现就是为了解决这个问题。
Docker的主打特性是系统平滑移植,容器虚拟化技术,什么意思呢?
直白来说,换成Docker之后,我们移植应用到不同的平台上就变成了从只打包源码到将源码以及源码对应的依赖文件全部打包为一个镜像文件,然后将整个镜像文件在新的平台上通过Docker引擎进行拉取,然后直接将整个镜像文件部署到新的平台上去。
每个平台的Docker引擎是一样的,整个过程跟VMware装CentOS镜像文件一致
一句话,Docker解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术
容器虚拟化和虚拟机的区别?
传统的的虚拟机技术基于安装在主操作系统上的虚拟机管理系统,相当于在虚拟机上装了一个从操作系统,这种操作方式具有一些痛点:
- 资源占用过多,直接模拟一个操作系统出来,肯定占用资源较多
- 冗余步骤多,需要模拟硬件环境
- 启动慢
容器虚拟化技术,解决的就是传统虚拟机技术的痛点,它更加的轻量级,除了模拟一些必要的内核文件,其他的如硬件等跟软件运行无关的资源一概不需要模拟,这就大大节约了系统的资源,有了容器,就可以将软件运行所需要的所有资源全部打包为一个单独的隔离容器。然后基于这个单独的容器进行迁移部署。
二、能干嘛?
构建软件更方便,更快速,做到一次构建处处运行
- 更快速的应用交付和部署
- 更便捷的升级和扩缩容
- 更简单的系统运维
- 更高效的计算资源利用
三、如何使用?
Docker并非一个通用的容器工具,它依赖于已存在并允许的Linux内核环境,它实际上是在已经运行的Linux下制造了一个隔离的文件环境,因此它执行的效率等同于所部署的虚拟机主机。因此,Docker必须部署在Linux内核的系统上,如果其他系统想要部署Docker,就必须安装一个虚拟的Linux环境。
如果想要在Windows系统上运行Docker,就需要在安装有Linux系统的虚拟机上部署Docker
前提条件:目前CentOS仅发行版中的内核支持Docker,要求系统为64位、Linux系统的内核版本为CentOS 7以上
查看自己Linux系统的内核(CentOS):
cat /etc/redhat-release
或者是uname -r
3.1、Docker的基本组成
镜像
容器
仓库
存放镜像的地方,类似于maven仓库
Docker的架构图
Docker的工作原理
流程图如下:
总结
3.2、安装
官网:https://www.docker.com/
官方仓库:https://hub.docker.com/
官网教程:https://docs.docker.com/engine/install/centos/
【1】卸载旧版本
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
【2】yum安装gcc相关的软件包
yum -y install gcc
yum -y install gcc-c++
【3】安装所需要的软件包
yum install -y yum-utils
【4】设置Stable镜像仓库,使用阿里云镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
【5】更新yum软件包索引
yum makecache fast
【6】安装Docker执行引擎
yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
【7】启动Docker
systemctl start docker
【8】查看docker进程及其版本
【9】测试
docker run hello-world
【10】配置个人账号下的阿里云镜像加速器
官网教程:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台
注意每个阿里云账号的加速器地址不一致
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://bzwjsqdq.mirror.aliyuncs.com"] } EOF
systemctl daemon-reload
systemctl restart docker
3.3、卸载
【1】停止Docker服务
systemctl stop docker
【2】卸载 Docker 引擎、CLI、Containerd 和 Docker Compose 包
yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
【3】删除所有映像、容器和卷
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
主机上的映像、容器、卷或自定义配置文件不会自动删除
3.4、常用命令
帮助启动类命令
- 启动Docker:
systemctl start docker
- 停止Docker:
systemctl stop docker
- 重启Docker:
systemctl restart docker
- 查看Docker的状态:
systemctl status docker
- 设置Docker开机自启动:
systemctl enable docker
- 停用Docker自动唤醒机制:
systemctl stop docker.socket
- 查看Docker概要信息:
docker info
- 查看Docker总体帮助文档:
docker --help
- 查看Docker命令帮助文档:
docker具体命令 --help
镜像命令
- 查看本机可以运行的镜像:
docker images
参数说明:-a
列出本地所有的镜像(含历史映像层),-q
只显示镜像ID
- 搜索某个镜像的名字:
docker search 镜像名字
只显示前五个:docker search --limit 5 redis
- 拉取镜像:
docker pull 镜像名字[:TAG]
,TAG标签表示拉取的镜像的版本号
- 查看镜像、容器、数据卷所占空间:
docker system df
- 删除docker镜像:
docker rmi 镜像ID -f
,可选参数-f
表示强制删除
- 删除全部镜像:
docker rmi $(docker images -qa)
- 导入导出镜像
docker export 容器ID > 文件名.tar
将当前镜像打包成tar
文件,备份到主机上cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
从主机中将镜像文件导入到docker中
- 查看本地虚悬镜像
docker images ls -f dangling=true
- 删除虚悬镜像
docker image prune
虚悬镜像:仓库名、标签都是的镜像
容器命令
开启一个容器实例
docker run [OPTIONS] IMAGES [COMMAND] [ARG]
OPTIONS说明:
--name="容器新名字"
:为容器指定一个名称(必须为英文)
-d
:后台运行容器并返回容器ID,也即启动守护式容器(后台运行)
需要注意的是,后台开启一个容器实例,对应前台必须有一个启动的进程,否则Docker后台会开启容器实例失败
-i
:以交互模式运行容器,通常与-t
同时使用
-t
:为容器重新分配一个伪输入终端,通常与-i
同时使用
-P
:随机端口映射,大写P
-p
:指定端口映射,小写p
查看正在运行的容器
docker ps [options]
options参数说明:
-a
:列出当前所有正在运行的容器包括历史上运行过的
-l
:显示最近创建的容器
-n
:显示最近n个创建的容器
-q
:静默模式,只显示容器编号
退出容器
两种退出的方式:
exit
:run进去的容器,exit退出后,容器会停止
ctrl+p+q
:run进去的容器,退出后容器不停止
启动已经停止运行的容器实例
docker start 容器ID或容器名
启动已经停止运行的容器
docker restart 容器ID或容器名
重启容器
docker run -d 容器ID
后台开启一个容器实例
停止正在运行容器实例
docker stop 容器ID或容器名
停止容器
docker kill 容器ID或容器名
强制停止
docker start 容器ID或容器名
启动已经停止的容器
删除容器
docker rm 容器ID或容器名
删除已经停止的容器
docker rm -f 容器ID或容器名
强制删除容器,正在运行的也可以直接删除
docker rm -f $(docker ps -a -q)
删除所有历史运行过的容器
其他
docker logs 容器ID
查看容器日志
docker top
容器ID 查看容器内的进程
docker inspect 容器ID
查看容器的内部细节
docker exec -it 容器ID /bin/bash
进入正在运行的容器并以命令行交互
docker attach 容器ID
进入到正在运行的容器
attach和exec有何区别?
attach进入到正在运行的容器终端后,退出时会导致容器的停止,而exec则不会,因此推荐使用exec,一般用-d后台启动程序,再使用exec进入到对应的容器实例中
docker cp 容器ID:容器内的路径 目的主机路径
将容器内的文件拷贝到主机上
3.5、本地镜像发布的阿里云
流程图:
3.6、搭建容器镜像私服
3.7、容器数据卷
是什么?
所谓容器数据卷,其实就是一个文件夹,只不过这个文件夹是属于容器内的,并且与宿主机的某个目录下的文件夹又映射关系,属于容器与宿主机的共享文件。
这样做有什么好处呢?这样做的话,当Docker内的某个容器实例被误删了,在Docker中的数据就全部丢失了,但是由于与宿主机有一个共享文件夹,宿主机内的文件并不会被删除,这就相当于完成了一次数据的备份
一句话,有点类似于Redis中的RDB和AOF文件,可以将容器内的数据备份到主机
能干嘛?
Docker容器产生的数据,如果不备份,那么当容器实例删除之后,容器内的数据自然就没有了,为了能保存数据,在Docker中,我们使用卷。
特点:
- 数据卷看可在容器之间共享或重用数据
- 卷中的更改可以实时生效
- 数据卷的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
如何用?
命令:
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
docker inspect 容器ID
查看容器内部信息,可以看到容器数据卷的挂载信息
3.8、DockerFile
What and Why?
Dockerfile是用来构建Docker的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本,有点类似于Shell脚本,既然类似于Shell脚本,你我们使用它自然是为了减轻重复构建镜像的负担,通过脚本的方式一次性完成。
Docker执行DockerFile大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似于docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有的指令都执行完成
How?
三个步骤
- 编写DockerFile文件
- docker build 命令构建镜像
- docker run 依镜像运行容器实例
常用保留字
官网:Dockerfile reference | Docker Documentation
案例
需求:构建一个增强版的CentOS(带有java8+vim+ifconfig)
【1】编写一个Dockerfile
脚本文件
FROM centos:centos7 MAINTAINER jld<1497359184@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH #安装vim编辑器 RUN yum -y install vim #安装ifconfig命令查看网络IP RUN yum -y install net-tools #安装java8及lib库 RUN yum -y install glibc.i686 RUN mkdir /usr/local/java #ADD 是相对路径jar,把jdk-8u321-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置 ADD jdk-8u321-linux-x64.tar.gz /usr/local/java/ #配置java环境变量 ENV JAVA_HOME /usr/local/java/jdk1.8.0_321 ENV JRE_HOME $JAVA_HOME/jre ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH ENV PATH $JAVA_HOME/bin:$PATH EXPOSE 80 CMD echo $MYPATH CMD echo "success--------------ok" CMD /bin/bash
【2】构建新镜像: docker build -t centosjava8:1.5 .
构建成功!
【3】测试是否构建成功
3.9、微服务实战
【1】将微服务项目打成jar包,并上传到Linux系统中
【2】编写Dockerfile
脚本
# 基础镜像使用java FROM java:8 # 作者 MAINTAINER beim # VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp VOLUME /tmp # 将jar包添加到容器中并更名为beim_docker.jar ADD docker_test-0.0.1-SNAPSHOT.jar beim_docker.jar # 运行jar包 RUN bash -c 'touch /beim_docker.jar' ENTRYPOINT ["java","-jar","/beim_docker.jar"] #暴露8080端口作为微服务 EXPOSE 8080
【3】构建镜像docker build -t docker-test:1.5 .
【4】开启一个容器实例
docker run -d -p 8080:8080 镜像ID
【5】测试接口
3.10、Docker网络
是什么?
Docker容器本质上是一个微型的Linux系统,因此也会有属于自己的网络配置,每启动一个Docker容器实例,都会对应一个虚拟网卡,我们先看未启动Docker服务时,Linux系统的网络配置:
启动Docker服务之后会先开启一个docker0的虚拟网卡
其中,容器实例与docker0以及宿主机之间的网络架构图如下所示:
能干嘛?
- 容器间的互联以及端口的映射
- 容器IP变动的时候可以通过服务名直接修改网络,而网络通信不受影响
常用命令
docker network ls
查看Docker的网络模式
docker network inspect 网络名字
查看网络源数据
docker network rm 网络名字
删除网络