目录
Docker
本次学习以B站Up主狂神说的教学视频学习为主。官网文档,菜鸟教程为辅。
学习前提:掌握基本的linux命令。
概述
问题的产生
项目环境问题:程序员开发一个产品,开发时是在开发环境下的。当项目完毕,就需要移植到生产环境。于是就需要先配置能够让项目正常运行的环境,但是配置环境繁琐复杂,例如配置jdk,mysql,redis……一堆东西,让人觉得麻烦。因此就产生一个问题:项目在我的机器正常运行(就是由于不同机器的环境不同导致的)
应用隔离问题:假如想要将两个项目部署在同一个服务器中,如何这两个项目用的不同的技术栈,就可能导致两个项目之间的环境无法兼容。
问题的解决
将整个项目包括环境都打包起来,然后一起部署在服务器上,这个就不需要再为配置环境发愁,同时也解决了隔离问题。
听到这,肯定会想起虚拟机。
但与虚拟机不同的是:虚拟机是模拟成整个电脑,包括硬件+软件
,这就导致虚拟机非常的臃肿,并且每次启动也慢。也就意味着服务器的利用率不高。
而docker非常的轻巧,并且启动速度很快。docker就是将项目+环境
打包成一个镜像
装进docker的库中,然后再其他服务器要部署这个项目时,直接从库中拉取一份。
正如Docker的图标一个,就是一条集装箱船。船(库)的每个集装箱里都装着货物(项目+环境),当其他服务器需要货物时,直接将整个集装箱拉取下来,然后一键部署。并且集装箱,意味着每个货物之间是互不影响的,解决了隔离性问题。
Docker简介
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
一个完整的Docker有以下几个部分组成:
- DockerClient客户端
- Docker Daemon守护进程
- Docker Image镜像
- DockerContainer容器
Docker的架构
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。Docker 容器通过 Docker 镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。
翻译:把
项目+环境
打包上传到仓库后,就是镜像
;其他服务器从库中拉取下来一份的,叫容器
。由此可见容器是根据镜像创建的-----》类比为对象是类 new出来的.
安装Docker
在linux上安装
官网上有详细的步骤:https://docs.docker.com/engine/install/centos/
操作系统要求:Centos 7
步骤:
-
先卸载docker旧版本(甭管之前有没有装过,先卸了再说)。
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
-
安装docker 的存储库。有多种方式安装,官网推荐
设置存储库
的方式,以便简化安装任务。yum install -y yum-utils yum-config-manager \ --add-repo \ # https://download.docker.com/linux/centos/docker-ce.repo(不推荐,这是国外的,下载慢,推荐使用国内镜像) https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
-
安装docker引擎(最新版)
yum install docker-ce docker-ce-cli containerd.io
-
验证是否安装:docker version
在测试一下新安装的docker:
-
启动docker
systemctl start docker
-
运行hello-world
docker run hello-world
-
查看目前本地的镜像
docker images
-
查看目前的容器
docker ps #表示正在运行中的容器 docker ps -a #表示停止的容器。
阿里云镜像加速:打开阿里云的网址----》搜索容器镜像服务----》镜像中心----》镜像加速器----》操作版本:Centos
Docker流程图
docker从仓库拉取镜像流程图:对应Docker使用全流程的pull
。
Docker使用全流程图:如果学完后面的内容,再回过头来看流程图便会非常的清晰。
命令
官网命令文档:https://docs.docker.com/reference/
帮助命令
docker 命令 --help #详细的显示该命令的用法
docker version #显示docker的一些基本信息
docker info #显示更详细的一些信息,包括镜像和容器。
镜像命令
-
docker images:查看本地主机上的镜像
参数:- -a:显示全部镜像
- -q:仅显示数字id
测试:
[root@ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 11 months ago 13.3kB
#REPOSITORY:镜像的仓库源
#TAG:镜像的标签
#IMAGE ID:镜像的数字id
#CREATED:镜像的创建时间
#SIZE:镜像的大小
-
docker search 镜像名:搜索镜像
[root@iZ2ze5tyvtnvvqjgl2ual8Z ~]# docker search mysql NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 10202 [OK]
-
docker pull 镜像名:[tag]:下载镜像,tag表示知道版本,未指定则默认最新版。
-
docker rmi imageID:删除镜像。注意:删除镜像需要先将该镜像的所有容器都删除(删除容器需要先将容器停下来)。即停止容器—》删除容器—》删除镜像。
docker rmi -f imagesId #删除镜像 docker rmi -f imagesId imagesId imagesId #删除多个镜像 docker rmi -f $(docker images -aq) #删除全部镜像
容器命令
容器是由镜像创建的,所以必须要先拉取一个镜像。
-
docker run [参数] image:新建容器并启动
docker run [参数] image #参数 --name="Name" #给容器指定名字,可以用于区分同一个镜像的多个容器 -d #后台方式运行 -it #使用交互的方式运行容器,可以用来查看容器的内容;进入容器后,使用exit命令则可以退回到主机。 -p #端口,重要 -p ip:主机端口:容器端口 -p 主机端口:容器端口(最常用) -p 容器端口 容器端口 -p #随机指定端口
-
docker ps [参数]:查看运行中的容器
docker ps [参数] #参数: -a #查看所有的容器,包括未运行的。 -n=num #显示最近创建的num个容器。 -q #只显示容器的编号
-
退出容器
exit #容器停止退出 ctrl+p+q #容器不停止退出
-
docker rm 容器ID:删除容器 (容器必须先停下)
docker rm -f 容器Id #删除镜像 docker rm -f 容器Id 容器Id 容器Id #删除多个镜像 docker rm -f $(docker ps -aq) #删除全部镜像
-
docker start 容器ID:启动容器
-
docker restart 容器ID:重启容器
-
docker stop 容器ID:停止容器
-
docker kill 容器ID:强制停止容器
其他命令
后台启动命令
docker run -d image
#可能会出现一个问题:当待参数 -d 后台启动容器,再使用 docker ps 会发现容器并没有运行,那是因为它以及结束了
#是因为容器启动后,发现自己并没有提供任何服务,就会自杀。
查看日志
docker logs [参数] 容器
#参数:
--details 显示提供给日志的其他详细信息
-f,--follow 跟踪日志输出
--since 显示自时间戳记以来的日志(例如2013-01-02T13:23:37)或相对记录(例如42m的42分钟)
--tail num 从日志末尾开始显示的num条日志
-t,--timestamps 显示时间戳
--until 在时间戳(例如2013-01-02T13:23:37)或相对(例如42m持续42分钟)之前显示日志
查看容器进程信息
docker top 容器
查看Docker的元数据:默认情况下,docker inspect
将结果呈现在JSON数组中。
docker inspect [参数]NAME|ID [NAME|ID...] #Return low-level information on Docker objects:返回docker对象的一些底层信息
#参数:
--format , -f #使用给定的Go模板格式化输出
--size , -s #如果类型为容器,则显示文件总大小
--type #返回指定类型的JSON
进入正在运行的容器
docker exec [OPTIONS] CONTAINER COMMAND [ARG...] #给正在运行的容器打开一个新的终端,执行新命令。常用
docker attach [OPTIONS] CONTAINER #进入到一个正在运行的容器,已经打开过的终端,并不会再创建一个新的终端。
容器和主机之间的文件拷贝
docker cp [参数] 容器:路径 主机路径 #将文件从容器拷贝进主机
docker cp [参数] 主机路径 容器:路径 #将文件从主机拷贝进容器
小结
上面所学习的命令,可以用一张图来描绘他们的作用在这里插入图片描述
安装镜像的练习(可跳过)
安装Nginx
#1.搜索Nginx的镜像
[root@ ~]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 14063 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker con… 1912 [OK]
#2.拉取nginx的镜像:未指定版本,默认为最新版
[root@ ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
852e50cd189d: Pull complete
571d7e852307: Pull complete
addb10abd9cb: Pull complete
d20aa7ccdb77: Pull complete
8b03f1e11359: Pull complete
Digest: sha256:6b1daa9462046581ac15be20277a7c75476283f969cb3a61c8725ec38d3b01c3
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
#3.运行Nginx的容器
#3.1 查看镜像是否下载成功
[root@ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest bc9a0695f571 7 days ago 133MB
#3.2 运行容器
[root@ ~]# docker run -p 8090:80 nginx
测试:
安装TomCat
#1.拉取tomcat镜像
docker pull tomcat:9.0
#2.运行tomcat
dokcer run -d -p 8090:8080 tomcat:9.0
然后此时访问服务器的8090端口,映射容器的8080,则发现访问不到内容,为404
。
原因:这是因为容器为了尽可能保持小体积,很多东西都被阉割了
#进入容器中
[root@ ~]# docker exec -it b5d69919eb2c /bin/bash
root@b5d69919eb2c:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
root@b5d69919eb2c:/usr/local/tomcat# cd webapps
root@b5d69919eb2c:/usr/local/tomcat/webapps# ls
#则发现tomcat下面的webapps是空的,因此访问不到内容。
将tomcat目录下的webapps.dist的内容拷贝到webapps,则可以访问到内容。
root@b5d69919eb2c:/usr/local/tomcat/webapps# cd ..
#拷贝
root@b5d69919eb2c:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@b5d69919eb2c:/usr/local/tomcat# cd webapps
root@b5d69919eb2c:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
当webapp下有了东西,就可以访问到了
镜像的简单详解
什么是镜像?
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行的环境以及基于该环境所开发的软件(项目+环境),它包含软件运行所需要的所有内容,代码、库、环境变量、配置文件等。
镜像的获得方法:
- 从远程仓库拉取
- 拷贝(一般不使用)
- 自定义镜像-Dockerfile
镜像加载原理
UnionFS(联合文件系统)
它可以把多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。UnionFS允许只读和可读写目录并存,就是说可同时删除和增加内容。UnionFS应用的地方很多,比如在多个磁盘分区上合并不同文件系统的主目录,或把几张CD光盘合并成一个统一的光盘目录(归档)。另外,具有写时复制(copy-on-write)功能UnionFS可以把只读和可读写文件系统合并在一起,虚拟上允许只读文件系统的修改可以保存到可写文件系统当中。
联合文件系统时docker镜像的基础。
一个完整的liunx系统由bootfs
和rootfs
两部分组成。
bootfs的作用就是引导加载kernel,当kernel被加载到内存中后,bootfs就被卸载了。
rootfs包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件。
为什么虚拟机又大启动又慢,而docker轻巧启动速度又快?
就是因为虚拟器的镜像包含bootfs
和rootfs
(体积大),每次启动都需要bootfs先去加载一遍内核(速度慢)。
而docker没有bootfs,它使用主机的内核,只需要提供rootfs
即可。
而且docker能够实现镜像文件的复用
先实际操作演示一下,我先将主机的所有镜像删除掉。然后下载两个不同版本的tomcat。
docker镜像时分层下载的。并且分层下的文件可以被其他镜像复用
例如我先下载的tomcat9.0的镜像,下载了10层。
然后再下载tomcat8.5的镜像,则前5层可以直接复用tomcat9.0的。
可以通过docker inspect
命令查看镜像的分层。
dokcer镜像是只读的
当容器启动时,会在镜像层顶部添加一个可写层,这一层就是容器层。所有操作都是基于容器层的。
然后我们可以通过将这个容器(包括操作)再提交为一个新的镜像。
提交镜像
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:版本
例如,原本tomcat的镜像的weapps是没有内容的,但是我们再使用tomcat的容器时,往webapp中复制了一些内容。
现在我们要把这个容器提交为一个镜像。
[root@ ~]# docker commit -m="webapp中有内容" -a="sixu" d7f6cb3c0d22 tomcat_sixu:1.0
sha256:a58fc7e9993d494f98f7ab296e5e3e849dd87ec2f2c7a4e95b9ffa293ff155e3
[root@ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat_sixu 1.0 a58fc7e9993d 14 seconds ago 654MB #自己提交镜像比原来的打了几兆
tomcat 9.0 e0bd8b34b4ea 13 days ago 649MB
[root@ ~]# docker run -d -p 8090:8080 tomcat_sixu:1.0
5a873a5f048356dd065c9bec3e59623e8c1b88db58b9685476caee66ed8dd100
测试:
[root@iZ2ze5tyvtnvvqjgl2ual8Z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat_sixu 1.0 a58fc7e9993d 18 hours ago 654MB #自定义提交的镜像
tomcat 9.0 e0bd8b34b4ea 13 days ago 649MB
访问:
容器数据卷
容器数据卷简介?
问题产生:镜像
包含了项目+环境,而容器
相当于镜像的一个实例。当容器运行的时候,会产生数据,但是容器可以被轻易的删除,如果是数据库的容器的话,我们绝对不希望删除容器的时候数据库的所有数据也被删除。
因此,出现了容器数据卷技术,它可以实现容器的数据的共享。容器数据卷可以看成是docker挂载到容器上的一个U盘,并且可以同时挂在到多个容器上;而当容器被删除时,不会对容器数据卷造成影响。
数据卷存在于主机中,独立于容器,和容器的生命周期时分开的。容器可以是文件,也可以是目录;容器可以通过容器数据卷于主机进行数据共享,而多个容器之间也可以通过容器数据卷来进行数据共享。
特点:
- 容器启动的时候初始化的,如果容器使用的镜像包含了数据,这些数据也会拷贝到数据卷中。
- 容器对数据卷的修改是及时进行的。
- 数据卷的变化不会影响镜像的更新。数据卷是独立于联合文件系统,镜像是基于联合文件系统。镜像与数据卷之间不会有相互影响。
- 数据卷是宿主机中的一个目录,与容器生命周期隔离。
添加数据卷
容器数据卷有两种添加方式
-
docker run -it -v /主机绝对路径目录: /容器内目录 镜像名
docker inspect 容器id #可以查看是否挂在成功,查看
挂载之后,主机目录与容器就会对接,数据共享。如果容器停止,主机目录下如果发生改变,当容器启动时会自动同步。
-
DockerFile,直接在构建镜像的时候挂载数据卷。
创建一个文件:DockerFile。给文件添加内容,即创建镜像所需要的命令等。
注意:具体有关于DockerFile构建镜像的细节将在后面详解,这里只演示如何在构建镜像时就挂载数据卷。[root@ docker-test]# vim DockerFile #创建文件并编辑,编辑后保存 [root@ docker-test]# cat DockerFile #查看DockerFile文件内容 FROM centos VOLUME "MyVolumes" #定义一个匿名挂载数据卷,如果在运行容器没有手动添加数据卷,则自动挂载一个匿名数据卷。 CMD echo "------------end------------" CMD /bin/bash [root@ docker-test]# docker build -f DockerFile -t sixu/images . #开始构建镜像
[root@iZ2ze5tyvtnvvqjgl2ual8Z docker-test]# docker images # 查看已经存在的镜像 REPOSITORY TAG IMAGE ID CREATED SIZE sixu/images latest 1a6a7150b9df 5 minutes ago 215MB [root@iZ2ze5tyvtnvvqjgl2ual8Z docker-test]# docker run -it -d sixu/images #运行自定义的镜像容器 9940c688e335007bcf6c82236d7355f101ec31ca91c149079cc4c5d1e952c970 [root@iZ2ze5tyvtnvvqjgl2ual8Z docker-test]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9940c688e335 sixu/images "/bin/sh -c /bin/bash" 7 seconds ago Up 6 seconds amazing_engelbart [root@iZ2ze5tyvtnvvqjgl2ual8Z docker-test]# docker inspect 9940c688e335 #查看容器的元数据
则发现自动挂载了一个匿名数据卷。
再进入容器,就会发现有一个自定义的容器内部目录MyVolumes
,用于数据共享。[root@iZ2ze5tyvtnvvqjgl2ual8Z docker-test]# docker exec -it 9940c688e335 /bin/bash [root@9940c688e335 /]# ls MyVolumes dev home lib64 media opt root sbin sys usr bin etc lib lost+found mnt proc run srv tmp var
这种方式到了后期经常使用,因为我们经常需要自己定义镜像。而有关于DockerFile构建镜像的内容,请见DoclFile小节
具名挂载与匿名挂载
数据卷没有指定路径时,默认在:/var/lib/docker/volumes/xxxx/_data
匿名挂载:
docker run -it -v /容器内目录 镜像名
由此可见,-v参数后只指定了容器内部路径。
docker volume ls #查看容器数据卷
如果是匿名挂在,则会发现容器数据卷的名字是一串字符串。
具名挂载:
docker run -it -v 数据卷名:/容器内目录 镜像名 # 注意与指定主机路径区分,如果是路径,则以‘/’开头。
则使用docker volume ls
可以看到指定名称的数据卷。
注意区分:
-v 容器内目录 #匿名挂载
-v 数据卷名:/容器内目录 #具名挂载
-v /主机目录:/容器内目录 #指定路径挂载
数据卷权限
我们在使用数据卷时可以指定权限。
docker run -it -v /主机目录:/容器内目录:ro 镜像名 #ro表示只读,一旦指定,则意味着只有主机可以修改数据卷
docker run -it -v /主机目录:/容器内目录:rw 镜像名 #rw表示读写权限
容器数据卷
多个容器之间如何实现数据共享?
在启动一个新的容器时,可以通过--volumes-from
来从指定容器装载卷。
示例:
[root@ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sixu/images latest 1a6a7150b9df 2 hours ago 215MB ###在学习通过DockersFile添加数据卷时自定义的Docker镜像
[root@ ~]# docker run -it -d --name sixu1 sixu/images ###运行一个容器,并定义名为sixu1
78afa04a71ce7b6f08599625168d7d8ddab596e813625737ff2cb1fb9f5b20f7
[root@ ~]# docker run -it -d --name sixu2 --volumes-from sixu1 sixu/images ###运行第二个容器,名为sixu2,并挂载sixu1的数据卷
ea9f64ea706f1308028b4bffc602b11b96cf6c8385906614836680342ad18ae8
[root@ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea9f64ea706f sixu/images "/bin/sh -c /bin/bash" 6 seconds ago Up 5 seconds sixu2
78afa04a71ce sixu/images "/bin/sh -c /bin/bash" 55 seconds ago Up 54 seconds sixu1
[root@ ~]# docker attach 78afa04a71ce ###进入sixu1容器,看见有个MyVolumes文件
[root@78afa04a71ce /]# ls
MyVolumes dev home lib64 media opt root sbin sys usr
bin etc lib lost+found mnt proc run srv tmp var
[root@78afa04a71ce /]# cd MyVolumes/
[root@78afa04a71ce MyVolumes]# mkdir test ###对这个文件进行一些修改
[root@78afa04a71ce MyVolumes]# ls
test
[root@78afa04a71ce MyVolumes]# read escape sequence
[root@ ~]# docker attach ea9f64ea706f ###进入sixu2容器,也有MyVolumes文件
[root@ea9f64ea706f /]# ls
MyVolumes dev home lib64 media opt root sbin sys usr
bin etc lib lost+found mnt proc run srv tmp var
[root@ea9f64ea706f /]# cd MyVolumes/
[root@ea9f64ea706f MyVolumes]# ls ###发现与sixu1容器同步
test
[root@ea9f64ea706f MyVolumes]# mkdir testSixu2 ###在sixu2容器做改动
[root@ea9f64ea706f MyVolumes]# read escape sequence
[root@iZ2ze5tyvtnvvqjgl2ual8Z ~]# docker attach 78afa04a71ce ###进入sixu1容器
[root@78afa04a71ce MyVolumes]# ls ###发现自动与sixu2容器进行同步
test testSixu2
[root@iZ2ze5tyvtnvvqjgl2ual8Z ~]# docker stop 78afa04a71ce ###停掉sixu1容器,并删除
78afa04a71ce
[root@iZ2ze5tyvtnvvqjgl2ual8Z ~]# docker rm 78afa04a71ce
78afa04a71ce
[root@iZ2ze5tyvtnvvqjgl2ual8Z ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea9f64ea706f sixu/images "/bin/sh -c /bin/bash" 10 minutes ago Up 10 minutes sixu2
[root@iZ2ze5tyvtnvvqjgl2ual8Z ~]# docker attach ea9f64ea706f ###进入sixu2容器,会发现sixu2的数据卷依然存在
[root@ea9f64ea706f MyVolumes]# ls
test testSixu2
根据上面的例子,我们知道,使用--volumes-from
参数后,两个容器之间是相互同步数据的。
哪怕其中一个容器被删除,数据卷依然存在。
如果数据卷没有被持久化本地,那么容器数据卷的生命周期一直持续到没有容器使用为止。
如果持久化到了本地,那么除了手动删除,数据不会消失。
DockerFile
什么是DockerFile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
步骤:
- 编写
dockerfile
文件 docker build
构建一个镜像文件docker run
运行镜像docker push
发布镜像(DockerHub、阿里云镜像仓库)
DockerFile基础知识
- 每个指令都是大小的
- 执行顺序从上到下
- 每个指令都会创建一个镜像层,所以过多无意义的层,会造成镜像膨胀过大。
#
表示注释。
指令:
-
FROM:指定基础镜像,一切的开始。
FROM #默认latest版本
FROM :例:
FROM mysql:5.6 -
MAINTAINER:维护者信息
MAINTAINER
例:
MAINTAINER sixu
MAINTAINER sixu@qq.com -
RUN:镜像构建时需要运行的命令。
-
ADD:添加本地文件到镜像中去,tar类型文件会自动解压。
-
WORKDIR:工作目录,类似于cd命令。通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。
在使用docker run
运行容器时,可以通过-w
参数覆盖
构建时所设置的工作目录。 -
VOLUME:需要持久化的目录
-
EXPOSE:需要暴漏的端口
-
CMD:构建容器后调用,也就是在容器启动时才进行调用。
-
ENTRYPOINT:指定容器启动时需要执行的命令。
注意:ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT(追加)。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。 -
ONBUILD:镜像触发器。当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被触发。
-
COPY:与ADD类似,拷贝文件到进行中去,但是不会自动解压。
-
ENV:设置环境变量
DockerFile实战
目标:在linux系统上构建一个tomcat+java环境的镜像,并且将tomcat的webapps文件夹挂载到主机的一个文件,这样可以直接在主机发布项目。
-
环境准备:首先准备tomcat和jdk的tar压缩包。
[root@ dockerFile-test]# ls apache-tomcat-9.0.40.tar.gz jdk-8u271-linux-x64.tar.gz
-
创建
Dockerfile
文件,官方推荐文件名就是Dockerfile
,这样构建的时候会自动寻找这个文件,不需要-f。[root@ dockerFile-test]# vim Dockerfile [root@ dockerFile-test]# cat Dockerfile FROM centos MAINTAINER sixu<sixu@qq.com> #导入tar包 ADD jdk-8u271-linux-x64.tar.gz /usr/local ADD apache-tomcat-9.0.40.tar.gz /usr/local ENV MYPATH /usr/local WORKDIR $MYPATH #配置环境变量 ENV JAVA_HOME /usr/local/jdk1.8.0_271 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.40 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.40 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.40/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.40/bin/logs/catalina.out
-
构建镜像
[root@ dockerFile-test]# docker build -t dockerfiletest:1.0 . Sending build context to Docker daemon 154.6MB Step 1/13 : FROM centos ---> 0d120b6ccaa8 Step 2/13 : MAINTAINER sixu<sixu@qq.com> ---> Running in 3db31faa03a6 Removing intermediate container 3db31faa03a6 ---> 84e95f4c44d4 Step 3/13 : ADD jdk-8u271-linux-x64.tar.gz /usr/local ---> 118c75ff485a Step 4/13 : ADD apache-tomcat-9.0.40.tar.gz /usr/local ---> 4130e2a839fa Step 5/13 : ENV MYPATH /usr/local ---> Running in ea3e772f8858 Removing intermediate container ea3e772f8858 ---> 896aa134f3e1 Step 6/13 : WORKDIR $MYPATH ---> Running in f0bd14a05656 Removing intermediate container f0bd14a05656 ---> ec91ba9bd976 Step 7/13 : ENV JAVA_HOME /usr/local/jdk1.8.0_271 ---> Running in b47c0b3c0d93 Removing intermediate container b47c0b3c0d93 ---> 7b52bb20ffeb Step 8/13 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ---> Running in fbfcedb35429 Removing intermediate container fbfcedb35429 ---> 83b31947c35c Step 9/13 : ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.40 ---> Running in a88ff07acad9 Removing intermediate container a88ff07acad9 ---> ce4c17469d49 Step 10/13 : ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.40 ---> Running in 59559f5f5899 Removing intermediate container 59559f5f5899 ---> aa30984dc341 Step 11/13 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin ---> Running in 6e74254ace4e Removing intermediate container 6e74254ace4e ---> 4dd469f46633 Step 12/13 : EXPOSE 8080 ---> Running in bf59d2cedfce Removing intermediate container bf59d2cedfce ---> 4f2ecb380178 Step 13/13 : CMD /usr/local/apache-tomcat-9.0.40/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.40/bin/logs/catalina.out ---> Running in ed34009bbbc9 Removing intermediate container ed34009bbbc9 ---> 4adeaaa962e4 Successfully built 4adeaaa962e4 Successfully tagged dockerfiletest:1.0 [root@iZ2ze5tyvtnvvqjgl2ual8Z dockerFile-test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE dockerfiletest 1.0 2dadc2c566fa About a minute ago 586MB #自定义镜像 centos latest 0d120b6ccaa8 3 months ago 215MB #FROM指令
-
运行容器
[root@ dockerFile-test]# docker run -d -p 8090:8080 --name MyDockerFile -v /tmp/dockerFile-test/webapps-test:/usr/local/apache-tomcat-9.0.40/webapps/test dockerfiletest:1.0 0e8be4662c5bac44c1e5f70c9f80805f73e5ae0b22efe7939cb22e71f5f37a82 [root@ dockerFile-test]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0e8be4662c5b dockerfiletest:1.0 "/bin/sh -c '/usr/lo…" 6 seconds ago Up 5 seconds 0.0.0.0:8090->8080/tcp MyDockerFile
此时访问
8090
接口:
-
发布项目。因为做了数据卷挂载,所以可以直接在本地编写项目。
[root@iZ2ze5tyvtnvvqjgl2ual8Z dockerFile-test]# cd webapps-test [root@iZ2ze5tyvtnvvqjgl2ual8Z webapps-test]# pwd /tmp/dockerFile-test/webapps-test #与容器的/usr/local/apache-tomcat-9.0.40/webapps/test目录映射 [root@iZ2ze5tyvtnvvqjgl2ual8Z webapps-test]# vim index.jsp #编写一个简单的网页 [root@iZ2ze5tyvtnvvqjgl2ual8Z webapps-test]# cat index.jsp <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <html> <head> <meta charset="utf-8" /> <title>MyDockerFileTest</title> </head> <body> Hello World!!!<br/> <% System.out.println("-------test------"); %> </body> </html> [root@iZ2ze5tyvtnvvqjgl2ual8Z webapps-test]# vim index.jsp [root@iZ2ze5tyvtnvvqjgl2ual8Z webapps-test]# cat index.jsp <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>MyDockerFileTest</title> </head> <body> Hello World!!!<br/> <% System.out.println("-------test------"); %> </body> </html>
访问
ip:8090/test
测试:
发布镜像
以刚才Dockerfile实战
的自定义镜像为例,将其发布。
DockerHub
-
首先,
docker login
登入自己的DockerHub账号。[root@ ~]# docker login --help Usage: docker login [OPTIONS] [SERVER] Log in to a Docker registry. If no server is specified, the default is defined by the daemon. Options: -p, --password string Password --password-stdin Take the password from stdin -u, --username string Username [root@ ~]# docker login -u 账号 -p 密码 WARNING! Using --password via the CLI is insecure. Use --password-stdin. WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
-
然后
docker push
提交。注意:如果推送到Dockerhub,镜像命名需要符合规范:用户名/镜像名[:tag]
否则可能就会出现如下错误。
[root@ ~]# docker push dockerfiletest:1.0 The push refers to repository [docker.io/library/dockerfiletest] b4d0e3b74cfe: Preparing 1f4320031f5a: Preparing 291f6e44771a: Preparing denied: requested access to the resource is denied #命名不规范,解决方式,使用docker tag重新命名镜像,命名为 用户名/镜像名[:tag] [root@ ~]# docker tag dockerfiletest:1.0 sixujkd/dockerfiletest:1.0 [root@ ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE sixujkd/dockerfiletest 1.0 4adeaaa962e4 11 hours ago 586MB dockerfiletest 1.0 4adeaaa962e4 11 hours ago 586MB centos latest 0d120b6ccaa8 3 months ago 215MB [root@ ~]# docker push sixujkd/dockerfiletest:1.0 ###推送成功,由于上传太慢,就不等待结果了。
阿里云镜像
-
登入阿里云—》搜索
容器镜像服务
-
创建命令空间—》创建镜像仓库
-
点击创建的镜像。进入其中查看信息。
-
退出Dockerhub的账号,然后按照阿里云的操作指南操作。
[root@ ~]# docker logout Removing login credentials for https://index.docker.io/v1/ [root@ ~]# docker login --username=sixujkd registry.cn-shanghai.aliyuncs.com Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded [root@ ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE dockerfiletest 1.0 4adeaaa962e4 12 hours ago 586MB sixujkd/dockerfiletest 1.0 4adeaaa962e4 12 hours ago 586MB centos latest 0d120b6ccaa8 3 months ago 215MB [root@ ~]# docker tag 4adeaaa962e4 registry.cn-shanghai.aliyuncs.com/sixujkd/my-repository:1.0 [root@ ~]# docker push registry.cn-shanghai.aliyuncs.com/sixujkd/my-repository:1.0 The push refers to repository [registry.cn-shanghai.aliyuncs.com/sixujkd/my-repository] ...... ###push挺费时间的,就不截出结果了。