自学笔记:Docker


Docker

本次学习以B站Up主狂神说的教学视频学习为主。官网文档,菜鸟教程为辅。

学习前提:掌握基本的linux命令

概述

问题的产生

项目环境问题:程序员开发一个产品,开发时是在开发环境下的。当项目完毕,就需要移植到生产环境。于是就需要先配置能够让项目正常运行的环境,但是配置环境繁琐复杂,例如配置jdk,mysql,redis……一堆东西,让人觉得麻烦。因此就产生一个问题:项目在我的机器正常运行(就是由于不同机器的环境不同导致的)

应用隔离问题:假如想要将两个项目部署在同一个服务器中,如何这两个项目用的不同的技术栈,就可能导致两个项目之间的环境无法兼容。

问题的解决

将整个项目包括环境都打包起来,然后一起部署在服务器上,这个就不需要再为配置环境发愁,同时也解决了隔离问题。

听到这,肯定会想起虚拟机。
但与虚拟机不同的是:虚拟机是模拟成整个电脑,包括硬件+软件,这就导致虚拟机非常的臃肿,并且每次启动也慢。也就意味着服务器的利用率不高。

而docker非常的轻巧,并且启动速度很快。docker就是将项目+环境打包成一个镜像装进docker的库中,然后再其他服务器要部署这个项目时,直接从库中拉取一份。

正如Docker的图标一个,就是一条集装箱船。船(库)的每个集装箱里都装着货物(项目+环境),当其他服务器需要货物时,直接将整个集装箱拉取下来,然后一键部署。并且集装箱,意味着每个货物之间是互不影响的,解决了隔离性问题。
在这里插入图片描述

Docker简介

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

一个完整的Docker有以下几个部分组成:

  1. DockerClient客户端
  2. Docker Daemon守护进程
  3. Docker Image镜像
  4. DockerContainer容器

Docker的架构

Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。Docker 容器通过 Docker 镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。

翻译:把项目+环境打包上传到仓库后,就是镜像;其他服务器从库中拉取下来一份的,叫容器

由此可见容器是根据镜像创建的-----》类比为对象是类 new出来的.


安装Docker

在linux上安装

官网上有详细的步骤:https://docs.docker.com/engine/install/centos/

操作系统要求:Centos 7
在这里插入图片描述

步骤

  1. 先卸载docker旧版本(甭管之前有没有装过,先卸了再说)。

    yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
    
  2. 安装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
    
  3. 安装docker引擎(最新版)

    yum install docker-ce docker-ce-cli containerd.io
    
  4. 验证是否安装:docker version
    在这里插入图片描述

测试一下新安装的docker:

  1. 启动docker

     systemctl start docker
    
  2. 运行hello-world

    docker run hello-world
    

    在这里插入图片描述

  3. 查看目前本地的镜像

    docker images
    

    在这里插入图片描述

  4. 查看目前的容器

    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下有了东西,就可以访问到了
在这里插入图片描述


镜像的简单详解

什么是镜像?

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行的环境以及基于该环境所开发的软件(项目+环境),它包含软件运行所需要的所有内容,代码、库、环境变量、配置文件等。

镜像的获得方法:

  1. 从远程仓库拉取
  2. 拷贝(一般不使用)
  3. 自定义镜像-Dockerfile

镜像加载原理

UnionFS(联合文件系统)

它可以把多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。UnionFS允许只读和可读写目录并存,就是说可同时删除和增加内容。UnionFS应用的地方很多,比如在多个磁盘分区上合并不同文件系统的主目录,或把几张CD光盘合并成一个统一的光盘目录(归档)。另外,具有写时复制(copy-on-write)功能UnionFS可以把只读和可读写文件系统合并在一起,虚拟上允许只读文件系统的修改可以保存到可写文件系统当中。

联合文件系统时docker镜像的基础。

一个完整的liunx系统由bootfsrootfs两部分组成。

bootfs的作用就是引导加载kernel,当kernel被加载到内存中后,bootfs就被卸载了。
rootfs包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件。

为什么虚拟机又大启动又慢,而docker轻巧启动速度又快? 
就是因为虚拟器的镜像包含bootfsrootfs(体积大),每次启动都需要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盘,并且可以同时挂在到多个容器上;而当容器被删除时,不会对容器数据卷造成影响。

数据卷存在于主机中,独立于容器,和容器的生命周期时分开的。容器可以是文件,也可以是目录;容器可以通过容器数据卷于主机进行数据共享,而多个容器之间也可以通过容器数据卷来进行数据共享。

特点

  1. 容器启动的时候初始化的,如果容器使用的镜像包含了数据,这些数据也会拷贝到数据卷中。
  2. 容器对数据卷的修改是及时进行的。
  3. 数据卷的变化不会影响镜像的更新。数据卷是独立于联合文件系统,镜像是基于联合文件系统。镜像与数据卷之间不会有相互影响。
  4. 数据卷是宿主机中的一个目录,与容器生命周期隔离。

添加数据卷

容器数据卷有两种添加方式

  1. docker run -it -v /主机绝对路径目录: /容器内目录 镜像名

    docker inspect 容器id #可以查看是否挂在成功,查看

    挂载之后,主机目录与容器就会对接,数据共享。如果容器停止,主机目录下如果发生改变,当容器启动时会自动同步。

  2. 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 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

步骤:

  1. 编写dockerfile文件
  2. docker build构建一个镜像文件
  3. docker run运行镜像
  4. docker push发布镜像(DockerHub、阿里云镜像仓库)

DockerFile基础知识

  1. 每个指令都是大小的
  2. 执行顺序从上到下
  3. 每个指令都会创建一个镜像层,所以过多无意义的层,会造成镜像膨胀过大。
  4. #表示注释。

指令

  • 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文件夹挂载到主机的一个文件,这样可以直接在主机发布项目。

  1. 环境准备:首先准备tomcat和jdk的tar压缩包。

    [root@ dockerFile-test]# ls
    apache-tomcat-9.0.40.tar.gz  jdk-8u271-linux-x64.tar.gz
    
  2. 创建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
    
    
  3. 构建镜像

    [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指令
    
  4. 运行容器

    [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 接口:
    在这里插入图片描述

  5. 发布项目。因为做了数据卷挂载,所以可以直接在本地编写项目。

    [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

  1. 首先,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
    
  2. 然后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					###推送成功,由于上传太慢,就不等待结果了。
    

阿里云镜像

  1. 登入阿里云—》搜索容器镜像服务

  2. 创建命令空间—》创建镜像仓库

    在这里插入图片描述

  3. 点击创建的镜像。进入其中查看信息。
    在这里插入图片描述

  4. 退出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挺费时间的,就不截出结果了。
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值