大家好,我是前端dog君,一名95后前端小兵。2019年毕业于北京化工大学,天津人,不知道有校友和老乡嘛?对前端的热爱,让我们在此相聚,希望这篇文章,能帮助到您,也同时希望能交到志同道合的小伙伴,共同发展,一起进步。我的微信号dm120225,备注简书,期待您的光临。
大家注意,这是一篇写给前端的docker简明教程,亦可以说是dog君对最近对docker的简单总结。谈到的是一些基础内容,不涉及docker的一些高级用法或k8s容器编排等技术,旨在前端开发工程师扩展知识面,为全栈开发打好基础。dog君水平有限,如果有一些地方写的不太好,您可以联系dog君或评论,dog君非常愿意倾听您的建议,交个朋友嘛~
下面我们就一起来学习docker,揭开docker的神秘面纱。
docker介绍
引言
在我们日常开发中,可能会遇到以下问题:
1.我本地运行没问题啊
环境不一致
2.哪个哥们又写死循环了,怎么这么卡
在多用户的操作系统下,会相互影响
3.淘宝在双11的时候,用户量暴增
运维成本过高的问题
4.学习一门技术,学习安装成本过高
关于软件成本过高
相信大家在日常的开发过程中,也没少遇到这样的问题。以上的问题呢,也是我们工作中的一些场景,很是头疼。那么这就有一款神器,docker来帮助我们解决这些问题。
docker 的由来
2010年的时候,有一帮年轻人创业,创办了一家公司,他们是专门做PASS平台的。那时候市场上PASS平台还比较少,这家公司也是混的风生水起。
但是到了2013年的时候,各大公司也都注意到了PASS这块肉,像亚马逊,微软,Google 等都竞相开始做PASS平台,导致这家公司的营业额直线下降,濒临破产。
那么最后呢,创始人一狠心,既然我们干不过他们,那么我们就为人类做做贡献把。说时迟那时快,2013年,这家公司将核心技术对外开源,那么这个核心技术,就是docker。
docker开源之后,立刻获得了一大片追捧。深受资本家的喜爱。
于是乎,到了2014年的时候,得到了C轮的融资,4000w美元
到了2015年的时候,得到了D轮的融资,9500w美元
这不就有钱了嘛?这家公司开始全神贯注的维护docker。
docker的思想
不是说我们很多情况下是因为环境不一致导致的问题嘛,那么好,我们直接将环境打包,这样就不会出现问题了吧。那么将环境打包都会分为几个步骤呢?这就是docker 的思想。
docker将本地环境打包,发布到远程的一个中央大仓库,其他的用户通过docker拿到其他用户发布上去的环境,运行在自己的机器上,这就是docker的思想。
介绍几个概念吧
1.集装箱
会将所有需要的内容放到不同的集装箱中,谁需要这些环境,直接拿这个集装箱就可以了。
2.标准化:
运输的标准化:Docker 有一个码头,所有上传的集装箱都放在了这个码头上,当谁需要某一个环境,就直接指派docker去搬运这个集装箱就可以了。
命令的标准化:Docker提供了一系列的命令,帮助我们去获取集装箱等等操作。
提供了REST的API:衍生出很多的图形化界面 如Rancher
3.隔离性:
Docker在运行的集装箱内的内容时,会在Linux的内核中,单独的开辟一片空间,这片空间不会影响到其他程序。
注册中心:超级码头,上面放的就是集装箱
镜像:集装箱
容器:运行起来的镜像
docker 基本操作
安装docker
那么我们来聊聊docker的基本操作。我们想要使用docker,首先需要下载docker。因为windows操作系统下载docker需要docker专业版,并且安装过程相对比较麻烦,所以说我们在服务器上来使用下,服务器操作系统是CentOS 7,下面附CentOS 7 安装docker的一些操作步骤,这里给出链接,按照步骤一步步来就可以了。在安装docker的过程中可能会遇到一些问题,这里也给出参考链接,如下:
安装好后,我们在控制台输入docker run hello-world
,出现如下信息,即为安装成功
Docker的中央仓库
我们上面说到docker的思想,是即可。那么我们从哪里下载docker镜像呢?这里我们推荐三个地址:
1.Docker官方的中央仓库:这个仓库是镜像最全的,但是下载速度较慢,还需要登录,也有可能被墙。
地址: http://hub.docker.com
2.国内的镜像网站:网易蜂巢,daoCloud......
网易蜂巢:也是需要进行登录,操作也比较繁琐一点
地址:http://c.163yun.com/hub#/home
daoCloud:免登陆,国内镜像,下载速度较快,推荐使用
地址:http://hub.daocloud.io
3.在公司内部会采用私服的方式拉取镜像,但是需要添加一些配置
# 需要在/etc/docker/daemon.json
{
"registry-mirrors":["https://registry.docker-cn.com"],
"inscure-registries":["ip:port"],
}
# 重启两个服务
systemctl daemon-reload
systemctl restart docker
# 这样我们就在公司内部搭建起来docker的私有中央仓库。具体的一些实践操作,还需要大家来操作哈。
镜像的操作
下面我们开始进行镜像的操作。首先我们回顾下docker的思想:用户上传制作好的镜像,发布到中央仓库,我们从中央仓库下载镜像,运行起来变成一个容器。我们一步步的来。
拉取镜像到本地
docker pull 镜像名称[:tag]
举个例子,我们想从中央仓库拉取tomcat的镜像
- 进入daocloud网站:http://hub.daocloud.io
- 输入tomcat 查找
-
点击版本,找到8.5.14-jre8
点击拉取
- 复制命令,控制台执行
docker pull daocloud.io/library/tomcat:8.5.14-jre8
,控制台显示镜像安装过程
这样我们的镜像就从中央仓库拉取到了我们本地
查看全部本地的镜像
docker images
这里我们可以看到本地的全部镜像,包括tomcat和hello-world
删除本地镜像
docker rmi 镜像的标识
比如说,删除我们刚才下载的tomcat镜像 docker rmi a0
我们在查看下所有镜像
发现tomcat镜像已经被我们从本地删除了
这里我们说下镜像的标识,我们可以看到IMAGE ID这个字段,就是镜像的ID,我们不用全部输入好,只需要前面几位,保证它在我们本地的镜像中是唯一的就好了。
镜像的导入导出
这是一种不规范的行为,但是如果我们遇到外网环境下载,内网环境使用的场景的时候,我们可以采用这种方法。
# 将本地的镜像导出
docker save -o 导出的路径 镜像id
# 加载本地的镜像文件
docker load -i 镜像文件
# 修改镜像名称
docker tag 镜像id 新镜像名称:版本
举个例子,我们将tomcat 镜像导出后再导入到我们本地
- 拉取tomcat镜像(看上面操作)
-
查看本地所有镜像,找到tomcat的镜像id
- 将本地的镜像导出
docker save -o ./tomcat.images a0
- 删除已有的tomcat 镜像
docker rmi a0
- 导入制作好的tomcat镜像
docker load -i tomcat.images
我们可以看到,镜像已经成功被我们导入进去了。但是并没有名字和版本号,这里我们修改下
- 修改名称和版本号
docker tag a0 tomcat:1.0.0
名称已经被我们成功修改过来了
容器的操作
我们来说说容器的操作。老规矩,我们还是来回顾下docker的思想。用户将制作好的镜像发布到中央仓库,我们从中央仓库拉取镜像到本地,运行镜像变成一个容器。
我们运行镜像变成容器后,这个镜像就可以正常的使用了。
运行容器
- 简单操作
docker run 镜像的标识|镜像名称[:tag]
- 常用参数
docker run -d -p 宿主机端口:容器端口 --name 容器名称 镜像的标识|镜像名称[:tag]
# -d:代表后台运行容器
# -p:宿主机端口:容器端口:为了映射当前的Linux的端口和容器的端口
# --name 容器名称:指定容器名称
我们直接使用参数来运行起来我们刚才制作的tomcat镜像
docker run -d -p 8081:8080 --name tomcat a0
然后我们通过浏览器访问下tomcat服务 ip:+8081
正常显示出tomcat服务,表示我们的镜像运行成功,变成一个容器
查看正在运行的容器
docker ps [-qa]
# -a:查看全部容器
# -q:只查看容器的标识
我们来看看目前我们正在运行的容器有哪些docker ps
这里我们看到运行中的容器是tomcat,所有的容器还包含我们之前安装docker使用过的hello-world容器
查看容器日志
docker logs -f 容器id
# -f:可以滚动查看日志的最后几行
进入到容器内部
docker exec -it 容器id bash
比如说,我们进入tomcat容器,查看容器内部样子docker exec -it 4d bash
可以看到,docker容器相当于一个小虚拟机,一些详细内容大家自行查阅相关资料,这里就不做介绍了哈~
删除容器
我们在删除容器前,如果这个容器正在运行,需要先停止当前容器
# 停止指定的容器
docker stop 容器id
# 停止所有容器
docker stop $(docker ps -aq)
# 删除指定容器
docker rm 容器id
# 删除所有容器
docker rm $(docker ps -aq)
我们一起来删除下tomcat还有之前的hello-world容器
- 停止所有容器
docker stop $(docker ps -aq)
我们可以看到,这时已经没有正在运行中的容器了,并且我们用浏览器访问也访问不到
- 删除所有容器
docker rm $(docker ps -aq)
我们可以看到,所有的容器已经全部删除
那么我们想启动停止的容器怎么办呢
docker start 容器id
- 运行tomcat镜像
docker run -d -p 8080:8080 --name tomcat a0
-
查看当前运行容器
docker ps
-
停止当前运行的容器
docker stop ee
-
启动停止的容器
docker start ee
-
我们用浏览器访问下: ip:+8080
tomcat容器又重新启动了
docker 应用
现在我们已经掌握了一些基本的docker操作,那就一起来实践一下吧!我们写一个html文件,部署到服务器上运行感受下,这里我们以tomcat为例。
那么tomcat如何部署web应用呢?我们只需要将编写好的index.html文件放在tomcat的webapps目录下即可正常访问。好,我们首先制作一个index.html文件,这里我们用vim 查看下 vim index.html
-
启动tomcat容器
docker run -d -p 8080:8080 --name tomcat a0
用浏览器访问下可以正常访问
将index.html 文件放到tomcat容器的webapps目录下tomcat目录下
1.进入tomcat容器docker exec -it ee bash
2.新建tomcat目录mkdir tomcat
3.从tomcat容器退出exit
4.将index.html放入tomcat容器中
docker cp 文件名称 容器id:容器内部路径
docker cp index.html ee:/usr/local/tomcat/webapps/tomcat
现在我们已经可以看到tomcat容器中已经有了我们编写的index.html文件,下面我们访问下把! ip:8080/tomcat
显示成功!
那么我们这么操作会不会很麻烦呢?实际上,我们去进入到容器中,修改容器内部的文件是不规范的,因为当我们删除容器,再次运行时,我们的文件就丢失了,达不到持久化的目的。那怎么办呢?这里介绍一个数据卷的概念。
数据卷
我们将容器内部的一些文件夹或目录,和宿主机进行一个映射,我们在宿主机去做一些操作,容器内部也会同步修改,并且当我们删除容器后,再次运行时,只需要指定数据卷,那么这个容器就又会重新加载我们保留在宿主机上的文件了,达到了持久化的目的。下面我们一起来看下数据卷如何使用把!
创建数据卷
docker volume create 数据卷名称
# 创建数据卷后,默认会存放在一个目录下 /var/lib/docker/volumes/数据卷名称/_data
我们来创建一个tomcat数据卷 docker volume create tomcat
进入目录查看 cd /var/lib/docker/volumes/tomcat/_data
我们可以看到,数据卷已经创建成功,目前是空的,没有任何数据。
查看全部数据卷
docker volume ls
我们可以看到刚才创建的tomcat数据卷
查看某个数据卷的详细信息
docker volume inspect 数据卷名称
我们也可以拿到数据卷存放的目录
删除数据卷
docker volume rm 数据卷名称
我们删除下tomcat数据卷看看
我们可以看到,tomcat数据卷已经全部删除
应用数据卷
# 当你映射数据卷时,如果数据卷不存在,Docker会帮助我们自动创建,会将容器内部自带的文件,存储在默认路径中。
docker run -v 数据卷名称:容器内部路径 镜像id
# 直接指定一个路径作为数据卷的存放位置,这个路径下是空的
docker run -v 路径:容器内部路径 镜像id
下面我们以tomcat为例,分别来看下这两种的效果
- Docker自动创建数据卷:
1.查看当前所有镜像docker images
2.自动创建数据卷方式,启动tomcat容器
docker run -d -p 8080:8080 --name tomcat -v tomcat:/usr/local/tomcat/webapps a0
我们可以看到,docker为我们自动创建了tomcat数据卷。我们查看下tomcat数据卷信息,进入到目录看下
我们可以看到,tomcat容器的数据已经保存到宿主机上面了
3.将index.html放到tomcat数据卷的tomcat目录中
mkdir tomcat
cp /dev/project/index.html ./tomcat
我们访问下看看
页面正常显示
4.删除tomcat容器,重新启动看页面是否还能正常显示
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
docker images
docker run -d -p 8080:8080 --name tomcat -v tomcat:/usr/local/tomcat/webapps a0
我们的页面仍然正常显示。说明数据卷具有持久化容器数据能力
我们来试试第二种,将数据卷保存到自定义路径下
- 将数据卷保存到自定义路径下
# 我们先根据如下命令删除容器和数据卷
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
docker volume rm tomcat
# 以自定义路径方式保存数据卷(本地路径只能使用绝对路径)
# 我们在/dev/project 目录下进行
# 在该目录下新建webapps目录
mkdir webapps
docker images
docker run -d -p 8080:8080 --name tomcat -v /dev/project/webapps:/usr/local/tomcat/webapps a0
cd webapps
docker exec -it fe bash
cd webapps
我们可以看到,宿主机的webapps和容器内的webapps都没有文件
我们在宿主机webapps目录下新建ROOT,将index.html复制一份到ROOT目录下
cd /dev/project/webapps
mkdir ROOT
cd ROOT
cp /dev/project/index.html /dev/project/webapps/ROOT
此时我们通过浏览器访问 ip:8080
同样,我们能够正常访问,这也方便我们对容器数据,或者容器日志更好的管理。
docker自定义镜像
下面我们来说说docker自定义镜像。老规矩,我们还是来一起回顾下docker的思想。用户将制作好的镜像发布到中央仓库,我们从中央仓库拿到镜像,运行,变成一个容器。
我们之所以能从中央仓库下载镜像,是因为中央仓库的镜像,也都是用户上传上去的,那么这里我们一起来制作一个自定义镜像。
1.创建一个Dockerfile文件,并且指定自定义镜像信息。
Dockerfile文件中常用的内容:
from:指定当前自定义镜像依赖的环境
copy:将相对路径下的内容复制到自定义镜像中
其他的像workdir cmd run expose等命令在这里就不一一给大家介绍了,下面这个参考链接,可以给大家答案。
Dockerfile文件详解
前面我们演示了使用tomcat部署一个index.html页面,那么我们就制作一个tomcat_index镜像,运行后,我们可以直接访问。一起来看下操作步骤吧。
- 删除所有镜像和容器
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
docker rmi $(docker images -aq)
- 创建Dockerfile文件并编写如下内容
我们是在/dev/project/目录下操作的,我们看下该目录都有什么
- 打包镜像
docker build -t 镜像名称:[tag] .
我们执行docker build -t tomcat:1.0.0 .
注意最后面还有一个. 这个. 的作用就是指明Dockerfile文件所在目录
我们来看下当前所有镜像docker images
已经有了我们的tomcat镜像,下面我们运行起来看下
docker run -d -p 8080:8080 --name tomcat 66
在浏览器中正常访问。
docker-compose 使用
来,老规矩,我们一起来回顾下docker的思想。用户将制作好的镜像发布到一个中央仓库,我们从中央仓库下载好镜像到我们本地,运行镜像变成一个容器。到此为止呢,其实我们已经掌握了docker的基本用法。但是我们有没有发现一个问题,就是在操作docker的时候,有点繁琐,命令太多。我们能不能实现只编写一次,后面直接使用呢?当然可以,这就是我们的docker-compose。我们先来看下它可以解决什么问题。
之前运行一个镜像,需要添加大量的参数
可以通过docker-compose编写这些参数
docker-compose可以帮助我们批量的管理容器
只需要通过一个docker-compose.yml文件去维护即可
安装docker-compose
我们进入github,输入docker/compose,点击进入
我们点击红框内容,找到发行版本
就拿最新版1.28.2 为例。因为我们是在centos 7环境下,我们选择如下画红框部分,点击下载
下载完毕后,我们通过scp命令发送到centos 7 中。这是一个可执行文件,所以我们需要修改一下权限
# 首先修改下名字
mv docker-compose-Linux-x86_64 docker-compose
chmod 777 docker-compose
# 现在我们已经可以使用docker-compose命令了。为了方便后期操作,配置一个环境变量
# 将docker-compose 文件移动到/usr/local/bin
mv docker-compose /usr/local/bin
# 修改/etc/profile 文件
vim /etc/profile
如果没有的话,加上即可。
最后我们应用一下配置文件 source /etc/profile
在任意目录下使用docker-compose
打印出一下信息,说明我们的docker-compose安装完毕
使用docker-compose管理tomcat容器
下面我们就一起来使用docker-compose管理我们的tomcat容器把!
前面提到,使用docker-compose管理我们的容器需要一个docker-compose.yml文件。关于这个文件的配置,这里只做简单的介绍,详细的配置同Dockerfile给出参考链接,大家自行学习哈~
我们新建docker-compose.yml文件,编写内容如下:
我们一起来看下docker-compose的一些常用命令把!
在使用docker-compose的命令时,默认会在当前目录下找docker-compose.yml文件
1.基于dockr-compose.yml启动管理的容器
docker-compose up -d
2.关闭并删除容器
docker-compose down
3.开启|关闭|重启已经存在的由docker-compose维护的容器
docker-compose start|stop|restart
4.查看由docker-compose管理的容器
docker-compose ps
5.查看日志
docker-compose logs -f
我们使用下docker-compose管理tomcat容器
控制台执行docker-compose up -d
我们在浏览器访问下
浏览器能够正常访问。
我们的docker-compose还可以配合Dockerfile来管理自定义镜像,这里我们就不做介绍了,就留给大家去探索吧!
总结
到此为止呢,我们的docker基础教程就结束了。使用docker呢,方便我们安装和管理各种各样的软件,免去了繁琐的配置问题,并且对于我们前端工程师来说,这也是进击大前端和全栈开发的必经之路。
参考链接:
千锋教育-2020版-Docker最新超详细版教程通俗易懂
我是前端dog君,一名95后前端小兵。对前端的热爱,让我们在此相聚,希望这篇文章,能帮助到您,也同时希望能交到志同道合的小伙伴,共同发展,一起进步。我的微信号dm120225,备注简书,期待您的光临。