探讨什么是Docker之前,我们来回顾一下Docker的前世今生。
在过去,公司内比较普遍的模型是系统管理员模型,通俗点来讲就是研发团队和运维团队之间是有比较明显的一条分界线的:研发人员不会参与任何运维工作,运维人员也不会参与任何研发工作。
在公司里面,项目经理接到项目之后,会将任务分发给他底下的研发-运维团队:研发团队(俗称“程序员”)负责系统或者软件的开发,运维团队(俗称“网管”)负责将系统或者软件部署到生产环境中,并对其进行运维,保证其可用性。
现在问题来了,当研发人员辛辛苦苦,熬了几个通宵甚至冒着秃头的风险将代码敲好并打包给运维人员去部署,本以为能好好歇一歇并且今晚去放松一下的时候。运维人员跑过来对研发人员说:“研发兄弟,不对啊。这个部署不了,有问题”。开发人员疑惑道:“不可能,肯定是你弄错了。代码在我自己机器上跑的好好的”。这时候运维人员也不甘示弱,说:“肯定是你代码敲错了!”。于是,运维兄弟就跟开发兄弟产生矛盾,开始扯皮并互相甩锅了。
为了解决这种矛盾,Docker作为一种容器虚拟化技术的代表,对此提供了一个标准化的解决方案,Docker由此应运而生。
什么是Docker
- 基于Go语言实现的一个云开源项目
- 主要目标:在任何地方构建、发布、运行任何应用程序
- 通过对应用组件的封装,分发,部署,运行等生命周期的管理,使一款软件或者应用及其运行环境能够做到一次封装到处运行
- 在LXC(Linux容器技术)的基础上发展过来,将应用运行在Docker容器上面,而Docker容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署好
回到文章刚开始谈到的,在传统的研发运维模型里,往往会出现由于环境不一样而导致一个程序在开发环境能正常使用,但是到了运维那边真正部署到生产环境的时候却用不了,就会导致研发和运维之间产生矛盾。
而有了Docker之后,研发人员就可以将软件和它能够正常运行时的环境一起打包并封装进一个隔离的容器中,直接交给运维人员。运维人员拿到之后一键部署,方便快捷
Docker三要素
在正式开始上手Docker之前,还有一些基础但很重要的知识要讲,不要小看这些,在面试过程中面试官可是很喜欢问的。
镜像
- Docker 镜像类似于虚拟机镜像,可以将它理解为一个只读的模板。
- 镜像自身是只读的。容器从镜像启动的时候,会在镜像的最上层创建一个可写层
容器
- Docker 容器类似于一个轻量级的沙箱, Docker 利用容器来运行和隔离应用。
- 容器是从镜像创建的应用运行实例。它可以启动、开始、停止、删除,而这些容器都是彼此相互隔离、互不可见的。
- 可以把容器看作一个简易版的Linux 系统环境(包括root 用户权限、进程空间、用户空 间和网络空间等)以及运行在其中的应用程序打包而成的盒子
- 容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面一层是可读可写的
仓库
- Docker 仓库类似于代码仓库,是Docker 集中存放镜像文件的场所。
- 仓库(Repository)和仓库注册服务器(Registry) 是有区别的。仓库注册
- 服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
- 仓库分为公开仓库(Public) 和私有仓库(Private) 两种形式。
- 最大的公开仓库是Docker Hup存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云、网易云等
小总结
- Docker本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就似乎镜像文件。只有通过这个镜像文件才能生成Docker容器。镜像文件可以看作是容器的模板。Docker根据镜像文件生成容器的实例。同一个镜像文件,可以生成多个同时运行的容器实例。
- image文件生成的容器实例,本身也是一个文件,称为镜像文件。
- 一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也就是我们的容器。
- 至于仓库,就是放了一堆镜像的地方,我们可以把镜像发布到仓库中,需要的时候从仓库中拉下来就可以了。
Docker初体验
下面来看看 Linux 中如何安装 Docker,这里以 CentOS7 为例。
在测试或开发环境中,Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,执行这个脚本后就会自动地将一切准备工作做好,并且把 Docker 的稳定版本安装在系统中
下载并设置存储库
yum install -y yum-utils
yum-config-manager \
> --add-repo \
> http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装最新版本Docker引擎和容器
yum -y install docker-ce docker-ce-cli containerd.io
安装完成后查看版本信息
docker -v
启动Docker并建议设置成开机自启动
systemctl start docker
##开机自启动
systemctl enable docker
于Docker的官网是国外的网站,我们访问的速度是特别慢的,更别说去下载镜像了,所以我们需要配置一下镜像源加速下载,访问阿里云官网:
根据提示依次执行命令即可
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
> {
> "registry-mirrors": ["https://xxxxxxxxxxxxxxxx"]
> }
> EOF
{
"registry-mirrors": ["https://xxxxxxxxxxxxxxxx"]
}
systemctl daemon-reload
systemctl restart docker
相关命令
帮助命令
作为一名合格的极客,刚学习一样新事物肯定总会遇到点困难的。这时候帮助命令就显得尤为重要
#查看版本信息
docker version
#查看详细信息
docker info
#查看帮助命令
docker --help
镜像命令
Docker需要频繁地操作相关的镜像,所以我们先来了解一下Docker中的镜像。
列出本地镜像
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 2 months ago 13.3kB
centos latest 300e315adb2f 5 months ago 209MB
REPOSITORY:表示镜像仓库源
TAG:镜像标签(版本)
IMAGE ID :镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
也可以指定镜像名称
# 列出Docker中所有MySQL镜像
docker images MySQL
REPOSITORY TAG IMAGE ID CREATED SIZE
MySQL 5.6 0ebb5600241d 11 days ago 302MB
MySQL 5.7.32 f07dfa83b528 11 days ago 448MB
MySQL 5.5 d404d78aa797 20 months ago 205MB
只显示镜像的ID(-p参数)
docker images -q
d1165f221234
0ebb5600241d
f07dfa83b528
搜索镜像
一般在下载镜像之前我们要先查看hub上有哪些镜像,所以我们要用到如下命令:
docker search
我们要搜索tomcat镜像`
docker search tomcat
搜索tomcat镜像,且最多显示3条数据
docker search tomcat --limit 3
搜索tomcat镜像,且点赞数大于30
docker search tomcat --filter=stars=30
下载镜像
当我们找到合适的镜像后,需要将他从Docker Hub上下载到本机上。需要用到如下命令:
docker pull NAME[:TAG]
NAME:镜像名称
TAG:镜像的标签(往往用来表示版本信息)
对于Docker镜像来说, 如果不显式指定TAG, 则默认会选择latest标签,这会下载仓库中最新版本的镜像。
下载CentOS镜像(不加TAGS默认下载最新版本)
docker pull centos
Using default tag: latest
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
下载测试镜像:hello-world镜像
docker pull hello-world
删除镜像
有些镜像我们不想再用,就可以删除它。如下命令:
删除一个镜像,带标签和不带标签(TAG)
docker rmi hello-world
docker rmi tomcat:latest
删除多个镜像,也可指定镜像ID
docker rmi hello-world 300e315adb2f
删除全部镜像
docker rmi -f $(docker images -qa)
如果删除镜像的过程中出现以下情况
这是因为要删除的镜像产生了一个容器实例,而这个容器还在运行中,所以我们要加上 -f 参数来强制删除
docker rmi -f hello-world
容器命令
掌握了镜像的相关指令之后,我们需要了解一下容器的指令。可以把容器看成简易版的 Linux 环境(包括 root 用户权限,进程空间,用户空间和网络空间等)和运行在其中的应用程序。
创建运行容器
以centos镜像为例,我们要创建并运行一个centos容器
docker create centos
docker start centos
其实用一条命令就行了
命令中的 -it 参数是指以交互模式来启动,/bin/bash参数是指启动的终端为bash
# run等价于先执行create再执行start
docker run -it centos /bin/bash
之后可以查看当前正在运行的容器
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
838469f19a01 centos "/bin/bash" 20 seconds ago Up 20 seconds dazzling_hellman
CONTAINER_ ID为容器的id
IMAGE 为镜像名
COMMAND 为容器内执行的命令
CREATED 为容器的创建时间
STATUS 为容器的状态
PORTS 为容器内服务监听的端口
NAMES 为容器的名称
容器端口映射
我们想要后台运行一个tomcat容器(-d参数:后台运行)
docker run tomcat -d
但是这样是访问不到容器内的tomcat的,因为容器具有隔离性,若是想直接通过 8080 端口访问容器内部的 tomcat,则需要对宿主机端口与容器内的端口进行映射
docker run -p 8080:8080 tomcat
-p:指定端口映射
解释一下这两个端口(8080:8080),第一个端口为宿主机的端口,第二个端口为tomcat容器内的端口。
这样有了端口映射之后,外部就能通过访问宿主机的8080端口进而访问到容器内的8080端口了。
我们可以不用指定为8080端口,也可以使用随机端口
这时候系统会随机分配一个端口来进行端口映射
docker run -P -d tomcat
需要注意的是,每次运行的容器都是相互独立的,所以同时运行多个 tomcat 容器并不会产生端口的冲突。
显示正在运行的容器
我们先要查看当前正在运行的容器,可以使用 如下命令:
docker ps
相关选项:
-a:列出正在运行的容器和历史运行过的容器
-l:显示最近创建的容器
-n:显示最近n个创建的容器
-q:静默模式;显示容器编号
--no-trunc:完整显示
显示前三次运行过的容器
docker ps -n 3
列出全部容器
docker ps -a
容器的停止和删除
这些命令比较简单,就不一一赘述了。
停止容器分为强制停止和温柔停止
温柔停止:
docker stop 886a6ae58379
强制停止:
docker kill 886a6ae58379
停止后我们需要删除容器`
docker rm 886a6ae58379
相关选项:
-f:强制删除
-v:删除容器挂载的数据卷
若要删除全部容器
docker rm -f $(docker ps -qa)
查看容器日志
当容器以后台的方式运行时,我们无法知道容器的运行状态,这时候查看容器的日志就很有必要了。
docker logs 886a6ae58379
我们想要实时输出日志信息`
docker logs -f 886a6ae58379
除此之外我们还想让它将时间输出来
docker logs -f -t 886a6ae58379
其他命令
查看容器内运行了哪些进程
docker top 886a6ae58379
进入到容器里面
docker exec -t 886a6ae58379 /bin/bash
不想进入到容器里面就能返回结果
直接在当前终端返回在容器里执行 ls -l /tmp
结果
docker exec -t 886a6ae58379 ls -l /tmp
退出容器
交互模式下:
exit:容器停止并退出
ctrl+P+Q:容器退出但不停止
容器拷贝文件到宿主机
容器内的/etc/passwd文件拷贝到宿主机的/data/test.txt下
若是想将宿主机内的文件拷贝到容器内,反过来写即可
docker cp 4d56fa33ac08:/etc/passwd /data/test.txt
查看容器内部详细信息,比如监听的端口,绑定的ip地址等
docker inspect tomcat