整理一下docker的用法与原理
持续更新中。。。
1.基本概念
1-1.关于docker
Docker 是一个开放源代码软件,是一个开放平台,用于开发应用、交付(shipping)应用、运行应用。 Docker允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提高交付软件的速度。[1]
——维基百科
1-2.docker和虚拟机
docker比虚拟机有更少的抽象层。
1-3.为什么用docker
个人理解:
首先虚拟机和docker的最主要作用都是进行应用的隔离,我们不希望各个应用之间相互影响,即一个应用或一个环境坏了,导致另外的应用也有问题。经常出现的问题:
- 开发环境没问题、测试环境没问题、生成环境出问题。
- 开发环境引入了一个新的依赖、或版本的升级,对应其他所有的环境都要同步更新。
- 有一个新的环境要装这个应用,从头到尾安装环境各种依赖,十分繁琐耗时且容易出错。
- 各个应用之间的依赖版本冲突。
- ……
于是,有了虚拟化的技术。
虚拟机,隔离级别最高,不取宿主机的操作系统,每个虚拟机都要模拟一个完整的操作系统,包括各种硬件的模拟、库的模拟等,一开启就占用了所有分配给它的资源。由于相当于一台完整的计算机,所以启动是分钟级的,而且普通的宿主机也装不了几个虚拟机。
docker,还是直接利用宿主机的资源。 docker Engine可以简单看成对Linux的NameSpace、Cgroup、镜像管理文件系统操作的封装 。它还是利用宿主机的操作系统内核,只是进行资源和环境的隔离。启动是秒级的,由于十分轻量,docker容器可以创建很多,新增删除十分便捷。
2.安装docker
自备服务器。
2-1.卸载旧版本
1 | yum remove docker \ |
2-2.安装包管理工具
1 | yum install -y yum-utils |
2-3.配置仓库地址
1 | 官方(国外,慢) |
2-4.安装docker引擎
1 | 默认最新版 |
2-5.启动docker
1 | systemctl start docker |
启动完可以查看一下docker信息
1 | docker info |
2-6.验证
1 | docker run hello-world |
3.配置镜像加速
登录阿里云,打开容器镜像服务,配置镜像加速器。
4.常用命令
5.容器数据卷
容器数据持久化。
容器内的数据会随着容器的删除而被删除,“挂载”是一个很好的保存数据的方法,它将容器内的数据自动同步到宿主机,下面是两种具体的方法。
5-1.bind mount
指定路径挂载。
1 | 例子:将容器内的centos下的/home/test挂载到宿主机的/home/test |
创建完进入宿主机home目录:
可以看到自动创建了test目录,且test内为空。
进入到容器内home目录:
同样,容器内也创建了test目录。
然后,我们在宿主机创建文件test.java:
在容器内:
也能查到这个文件。
同理,在容器内创建文件test2.java,宿主机也查到了这个文件。
然后直接删除这个容器,宿主机依然保留了这些文件:
这样,就有效解决容器内数据持久化的问题。
注意,若文件已存在,已宿主机为准。
- 如果container中的目录已经有内容,那么docker会使用host上的目录将其覆盖掉
5-2.volume
除了指定路径挂载,还有两种方式:
具名挂载。
1
2
3例子:将容器内的/var/lib/mysql地址挂载,取名为mysql-volume
注意mysql设置密码
docker run -itd -p 4306:3306 -v mysql-volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql创建后进入docker volume的路径查看:
这里是容器内mysql的数据。
现在通过可视化工具,直接连到容器内的mysql并创建一个表。(注意防火墙开启端口)
再次查看数据:
发现数据在宿主机上能成功同步。
匿名挂载。
所谓匿名就是在挂载是不指定名称。
1
2
3例子:将容器内的/var/lib/mysql地址挂载,不取名
注意mysql设置密码
docker run -itd -p 4307:3307 -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 mysql结果将以容器id作为volume的名称。
完成测试后删除所有卷:
1 | docker volume rm -f $(docker volume ls -q) |
6.Dockerfile
6-1.关于Dockerfile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
有没有想过,在一个完全干净没有任何依赖的地方,跑起来一个应用?
一般来说,对于java项目,一个开发交付的war包或jar包,都需要有一定的环境要求,比如war包得放进tomcat那起码安装tomcat,比如需要安装mysql、redis等等。
然而,有了上面关于docker的介绍,似乎我们可以直接省略这部分的步骤?那就是把所有东西,打包成一个镜像,运维只需要运行这个镜像,就完事了。
这也是现在的趋势:开发不再交付war包或jar包,而是直接交付一个镜像!
但是,每次手动完成镜像的打包工作那肯定不是上策,于是有了Dockerfile,利用它,一步生成镜像。
- 指令介绍:
(这里从网上找来了一个比较通俗易懂的高清无码大图)
6-2.实践一,制作一个自定义的centos
首先通过官方的centos镜像启动一个容器,发现这个centos镜像仅仅是包含最基础的功能(阉割版centos),连ifconfig、vim等命令都没有:
下面通过Dockerfile来创建一个自定义centos镜像(增强版)。
写一个dockerfile文件,命名为dockerfile01:
1 | FROM centos |
运行它:
1 | docker build -f dockerfile01 -t my-centos:1.0 . #(记得这个点) |
注意:当文件名为Dockerfile时(官方约定),不需要指定-f,会自动在本目录下执行Dockerfile。
构建时,可以看到它以centos为基础,一层一层的往上面叠加,这正是docker核心技术——联合文件系统(后面详细介绍)的体现。
完成后通过这个自定义的镜像启动一个容器:
- 注意,运行时需带上版本号。
该自定义的my-centos:1.0内已包含vim和网络工具,测试成功。
6-2.实践二,制作一个自定义的tomcat
准备两个压缩包:
- apache-tomcat-9.0.45.tar.gz
- jdk-linux-x64.tar.gz
并上传到服务器。按照国际规范创建一个readme.md文件。
编写Dockerfile:
1 | FROM centos |
同上,build命令执行:
1 | docker build -f Dockerfile -t my-tomcat:1.0 . |
启动容器:
1 | docker run -d -p 9090:8080 --name my-tomcat01 -v /home/dockerfile-test/tomcat9/webapps:/usr/local/apache-tomcat-9.0.45/webapps -v /home/dockerfile-test/tomcat9/logs/:/usr/local/apache-tomcat-9.0.45/logs my-tomcat:1.0 |
准备一个简单的项目test,放进宿主机的/home/dockerfile-test/tomcat9/webapps下。项目结构:
test
│
┝ index.html
│
┕ WEB_INFO
│
┕ web.xml
通过公网访问9090端口(记得配置安全组):
成功访问(中文乱码忽略)。
7.上传镜像
7-1.上传至Docker Hub
- 在dockerhub注册个人账户。登录:
1 | docker login |
- 将做好的镜像打好tag并按规范命名:用户名/镜像名,如:
1 | docker tag my-tomcat:1.0 lizxing/my-tomcat:1.0 |
- 推送镜像:
1 | docker push lizxing/my-tomcat:1.0 |
完成后可以在个人的 repositories 处查看到该镜像。
7-2.上传至阿里云Docker镜像仓库
登录阿里云,打开容器镜像服务。创建镜像仓库。在仓库管理中,就可以看到完整的操作指南:
至此,docker基本的使用就算是入门了。
若要了解更深一层,需要学习Docker网络、Docker Compose、Docker Swarm等知识,下次继续研究。。。