Docker现在是一门非常流行的技术,其实之前就一直想学,不过一是没什么时间;二是没有结合实践,官方文档又介绍的不是很清楚,导致其中很多命令都看不懂,于是就没有继续下去了。
而这次我接了一个外包项目,实践Docker的时候终于到了!!!让我们开始吧。
一、Docker的介绍
Docker是一种虚拟化技术,用于解决开发环境的配置难题。可以把Docker就理解成一种虚拟机,不过比VirtualBox和VMware等的虚拟机要轻量很多,它没有图像化界面,并且与系统深度融合,运行效率非常高,可以说在使用它的时候几乎察觉不出是虚拟机,和真机体验很相似。
为什么要用Docker?很多服务端软件的运行环境配置起来非常麻烦,而最好的办法就是把配置好的环境存起来,保存成一个类似操作系统镜像的东西,同时在需要运行这些软件的地方运行这个虚拟机镜像,再在这个虚拟机里运行这些服务端软件,从而就避免了配置运行环境的麻烦。其次,它还封装好了装好tomcat、mysql等常用开发环境的镜像,使用起来方便很多。
Docker有两个核心概念,Image和Container。Image就是类似操作系统镜像一样的东西,是静态的,可以对Image进行启动和删除。而Container则是正在运行的Image,是动态的,可以对Container进行停止、继续和删除。同样可以把Image和Container理解成面向对象中的类和对象。
二、Docker的安装
Windows和Mac的Docker安装起来都比较简单,有图形化界面,用起来很简单,这里就直接跳过,不过安装后记得配置国内镜像源,不然下载镜像的速度会非常慢。
至于镜像源地址的话,登录阿里云,搜索容器镜像服务,进入镜像加速器,就可以看到给每个用户分配的镜像加速器
Linux的Docker安装起来则比较麻烦,这里只介绍服务端常用Linux发行版CentOS如何安装Docker。
常规安装流程
- 设置 repository
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
- 安装Docker Community
$ sudo yum install docker-ce docker-ce-cli containerd.io
- 开启服务并试运行
$ sudo systemctl start docker
$ sudo docker run hello-world
可能遇到的坑
本来按照上面的步骤是照着官网教程来的,应该是没什么问题的,但我在运行下面这句的时候却报错了
$ sudo systemctl start docker
Job for docker.service failed because start of the service was attempted too often. See "systemctl status docker.service" and "journalctl -xe" for details.
但我按照提示输入systemctl status docker.service
和journalctl -xe
只看到提示异常退出,但没有说具体是什么问题,把输出内容在百度和谷歌上都也都没什么用,好几天都没解决这个问题。
后来不知道哪天看到有条命令,journalctl --since "2019-12-12 13:12:00"
可以看系统某个时刻之后的所有日志,我这才找到了错误原因!!
Apr 4 22:09:06 localhost_02 dockerd: time="2019-04-04T22:09:06.128742412+08:00" level=info msg="Creating filesystem xfs on device docker-8:3-67789151-base, mkfs args: [-m crc=0,finobt=0 /dev/mapper/docker-8:3-67789151-base]" storage-driver=devicemapper
Apr 4 22:09:06 localhost_02 dockerd: time="2019-04-04T22:09:06.131080987+08:00" level=info msg="Error while creating filesystem xfs on device docker-8:3-67789151-base: exit status 1" storage-driver=devicemapper
Apr 4 22:09:06 localhost_02 dockerd: time="2019-04-04T22:09:06.131103910+08:00" level=error msg="[graphdriver] prior storage driver devicemapper failed: exit status 1"
核心错误就是这个Error while creating filesystem xfs on device docker-8:3-67789151-base: exit status 1
然后在谷歌上一搜,果然找到了解决方案,具体看这个链接https://my.oschina.net/yuanhaohao/blog/3032396就可以解决,真是太激动了!
最后重新运行docker服务:
$ sudo systemctl daemon-reload
$ sudo systemctl start docker.service
三、Docker的常用命令
在命令行输入docker --help
就可以查看所有docker命令
Management Commands:
builder Manage builds
config Manage Docker configs
container Manage containers
image Manage images
network Manage networks
node Manage Swarm nodes
...
Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
...
是不是有点眼花撩乱?没事,我们慢慢来。
首先常用的命令有两大类,分别是针对Image和针对Container的。
Docker Image命令
$ docker image build xxx
这个用于根据xxx目录下的Dockerfile生成镜像,下面一节会讲解Dockerfile是什么,现在只需要认为是一个自动执行脚本,可以根据需求自动生成Docker镜像文件
$ docker image ls
这条命令则用来查看所有镜像的信息
参数名称 | 解释 |
---|---|
仓库位置 | 就像我前面几个镜像,是把我的镜像存储在阿里云上,后面没有域名地址的则是来则Docker Hub官方仓库 |
标签 | 就像软件有不同的版本一样,镜像也有不同的版本,区分他们的就是镜像标签 |
镜像ID | 每个镜像独有的ID |
创建时间 | |
镜像大小 |
最后是一些比较简单的命令:
$ docker image rm 镜像ID或镜像名
删除镜像
$ docker image tag 源镜像名 目标镜像名
重新已经存在的镜像指定一个重名
$ docker image push 镜像ID或镜像名
将镜像上传到云端(如果没指定域名就默认是官方的Docker Hub)
$ docker image pull 镜像名
从云端下载镜像
PS:上面说的镜像名都是指“仓库位置:标签”
Docker Container命令
$ docker container run xxxx
这个命令比较复杂,直接用一个例子来介绍:
- 红色:docker run是docker container run的同义词,后面部分会介绍
- 橙色:每个容器基本都会指定一个需要运行的命令,用来开启某个服务,而容器和这条命令是同生共死的,而这个参数就是表示让这条命令可以后台运行,也就是让容器能够后台运行。
- 绿色:由于Docker类似于虚拟机,容器与外部之间是默认不共享端口的,需要开放什么端口需要指定,格式是"外部端口:容器内端口"
- 蓝色:设置容器内的环境变量,我这里是设置MySql数据库的root密码以及默认创建的数据库名称
- 紫色:运行的镜像名,没有指定标签的话默认就是latest
还有很多其他参数,可以输入docker container run --help
查看帮助
$ docker container ls
它的用途是查看所有容器的信息
参数名称 | 解释 |
---|---|
容器ID | 与镜像ID差不多,每个容器都独一无二 |
来源的镜像名 | |
运行的指令 | 这个在后面的Dockerfile里会介绍 |
创建时间 | |
容器状态 | 开启还是暂停还是运行结束 |
开放的端口 | 容器开放给外部的端口 |
容器名 | 不设置容器名称的话系统会随机给你一个 |
上面参数中的-a
表示显示所有容器,包括停止运行的容器,而不加这个只会显示正在运行的和暂停的容器
$ docker container exec [OPTIONS] 容器ID或容器名 命令
这条命令则是用于在已经运行的容器中运行某条命令
[OPTIONS]有很多,这里只介绍两个最常用的:
-d:表示在后台运行命令,与上面的类似
-it:表示会开启一个交互式终端,我一般用下面的命令来进入容器内部的终端:
docker container exec -it 容器ID bash
最后是一些比较简单的命令:
$ docker container commit 容器ID或容器名 镜像名
将运行中的容器保存成镜像
$ docker container rm 容器ID或容器名
删除已经停止的容器(注意此命令不能删除正在运行的容器)
$ docker container kill 容器ID或容器名
强行停止正在运行的容器
$ docker container start/pause/restart 容器ID或容器名
这些一看就知道是什么意思就不解释了
真正常用的命令
真正常用的命令?难道意思是前面的都不常用??
对的,前面这些命令都太长了,我们一般都用它们的简写,替换规则如下:
docker run = docker container run
docker ps = docker container ls
docker commit = docker container commit
docker images = docker image ls
docker pull = docker image pull
docker push = docker image push
docker build = docker image build
docker rm = docker container rm
docker rmi = docker image rm
...