Docker学习笔记

Docker

一、学习背景

1.Docker是什么

​ Docker是解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。

2.Docker与传统虚拟机的区别

  • 传统虚拟机技术

1.传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程

  • Docker容器技术
  1. Docker容器不是模拟一个完整的操作系统,而是对进程进行隔离。有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆绑一整套的操作系统,只需要软件工作所需的库资源和设置。系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。
  2. 容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便
  3. 每个客器之间互相隔离,每个容器有自己的文件系统,容器之间进程不会相互影响,能区分计算资源

3.Docker的好处

  • 更快速的应用交付和部署
  • 更便捷的升级和扩缩容
  • 更简单的系统运维
  • 更高效的计算资源利用

4.Docker相关资源

5.Docker架构图

docker架构图

6.Docker三要素

6.1 镜像(Image)

Docker镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker容器,个镜像可以创建很多容器。

6.2 容器( Container)

Docker利用容器( Container)独立运行的一个或一组应用。容器是用镜像创建的运行实例。
它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
可以把容器看做是一个简易版的 Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。

Docker面向对象
容器对象
镜像
6.3 仓库( Repository)

仓库( Repository)是集中存放镜像文件的场所
仓库( Repository)和仓库注册服务器( Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,
每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public)和私有仓库( Private)两种形式。
最大的公开仓库是 [Docker Hub](htts:/ hub. docker. com/),
存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云网易云

6.4 总结

Docker本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就是 image镜像文件。只有通过这个镜像文件才能生成 Docker容器。 Image文件可以看作是容器的模板。 Docker根据 Image文件生成容器的实例。同一个 Image文件,可以生成多个同时运行的容器实例

  1. Image文件生成的容器实例,本身也是一个文件,称为镜像文件。

  2. 一个容器运行一种服务,当我们需要的时候,就可以通过 docker客户端创建一个对应的运行实例,也就是我们的容器

  3. 至于仓储,就是放了一堆镜像的地方,我们可以把镜像发布到仓储中,需要的时候从仓储中拉下来就可以了。

二、Docker安装

1. CentOS安装环境

  • CentOS 7(64-bit) 要求系统为64位、系统内核版本为3.10以上。

  • CentOS 6.5(64-bit)或更高的版本要求系统为64位、系统内核版本为2.6.32-431或者更高版本

查看自己内核

uname -r

查看已安装的CentOS版本信息

lsb_release -a
#或者
cat /etc/redhad-release

2. centos 6 安装

# 安装环境
yum install -y epel-release
# 以下是日志(阿里云源)
已加载插件:fastestmirror, refresh-packagekit, security
设置安装进程
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * epel: mirrors.yun-idc.com
 * extras: mirror.lzu.edu.cn
 * updates: mirrors.aliyun.com


# 安装docker
# 如果安装出现(No package docker-io available.),先执行以下操作
yum install -y docker-io
# 进入/etc/yum.repos.d目录,然后安装hop5仓库,再次执行docker安装
cd /etc/yum.repos.d
sudo wget http://www.hop5.in/yum/el6/hop5.repo

# 如果错误安装过,需要先删除,然后重新安装
yum list installed | grep docker
yum remove -y docker.x86_64


# 配置文件路径
/etc/sysconfig/docker
# 启动docker后台服务
service docker start
#验证
docker version

3.centos 7 安装

# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息(aliyun源,速度快)
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 2.1:默认源(和aliyun源二选一)
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# Step 3: 更新并安装 Docker-CE
sudo yum makecache fast
sudo yum -y install docker-ce
# Step 4: 开启Docker服务
sudo systemctl start docker
# Step 5: 设置开机启动
sudo systemctl enable docker

注意:其他注意事项在下面的注释中
# 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,你可以通过以下方式开启。同理可以开启各种测试版本等。
vim /etc/yum.repos.d/docker-ce.repo
#   将 [docker-ce-test] 下方的 enabled=0 修改为 enabled=1

# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
yum list docker-ce.x86_64 --showduplicates | sort -r
#   Loading mirror speeds from cached hostfile
#   Loaded plugins: branch, fastestmirror, langpacks
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
#   docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
#   Available Packages
# Step2 : 安装指定版本的Docker-CE: (VERSION 例如上面的 17.03.0.ce.1-1.el7.centos)
sudo yum -y install docker-ce-[VERSION]
# 注意:在某些版本之后,docker-ce安装出现了其他依赖包,如果安装失败的话请关注错误信息。例如 docker-ce 17.03 之后,需要先安装 docker-ce-selinux。
yum list docker-ce-selinux- --showduplicates | sort -r
sudo yum -y install docker-ce-selinux-[VERSION]

# 通过经典网络、VPC网络内网安装时,用以下命令替换Step 2中的命令
# 经典网络:
sudo yum-config-manager --add-repo http://mirrors.aliyuncs.com/docker-ce/linux/centos/docker-ce.repo
# VPC网络:
sudo yum-config-manager --add-repo http://mirrors.could.aliyuncs.com/docker-ce/linux/centos/docker-ce.repo

安装校验

root@iZbp12adskpuoxodbkqzjfZ:$ docker version
Client:
 Version:      17.03.0-ce
 API version:  1.26
 Go version:   go1.7.5
 Git commit:   3a232c8
 Built:        Tue Feb 28 07:52:04 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.03.0-ce
 API version:  1.26 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   3a232c8
 Built:        Tue Feb 28 07:52:04 2017
 OS/Arch:      linux/amd64
 Experimental: false

4. 配置阿里云加速器

​ 登录你的阿里云控制台,找到容器镜像服务 -> 镜像加速器 -> 复制加速器地址。找不到的点这个:容器镜像服务

​ 您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器(如果没有则自己创建一个)

​ https://de3tecik.mirror.aliyuncs.com是我自己的加速器地址

cd /etc/docker
touch daemon.json
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://de3tecik.mirror.aliyuncs.com"] 
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

5. 测试docker是否安装成功

docker run hello-world

6. docker run流程图

docker_run流程图

三、docker常用命令

docker --help

$ docker --help
Usage:	docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
      --config string      Location of client config files (default "/root/.docker")
  -c, --context string     Name of the context to use to connect to the daemon (overrides
                           DOCKER_HOST env var and default context set with "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level ("debug"|"info"|"warn"|"error"|"fatal")
                           (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/root/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/root/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/root/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Management Commands:
  builder     Manage builds
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  engine      Manage the docker engine
  image       Manage images
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

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
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

容器生命周期管理

  • run 创建一个新的容器并运行一个命令
  • start/stop/restart 启动/停止/重启容器
  • kill 杀掉一个运行中的容器
  • rm 删除一个或多个容器
  • pause/unpause 暂停/恢复容器中所有的进程
  • create 创建一个新的容器但不启动它
  • exec 在运行的容器中执行命令

容器操作

  • ps 列出容器
  • inspect 获取容器/镜像的元数据
  • top 查看容器中运行的进程信息,支持 ps 命令参数
  • attach 连接到正在运行中的容器
  • events 从服务器获取实时事件
  • logs 获取容器的日志
  • wait 阻塞运行直到容器停止,然后打印出它的退出代码
  • export 将文件系统作为一个tar归档文件导出到STDOUT
  • port 列出指定的容器的端口映射,或者查找将PRIVATE_PORT NAT到面向公众的端口

容器rootfs命令

  • commit 从容器创建一个新的镜像
  • cp 用于容器与主机之间的数据拷贝
  • diff 检查容器里文件结构的更改

镜像仓库

  • login/logout 登陆/登出到一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub
  • pull 从镜像仓库中拉取或者更新指定镜像
  • push 将本地的镜像上传到镜像仓库,要先登陆到镜像仓库
  • search 从Docker Hub查找镜像

本地镜像管理

  • images 列出本地镜像
  • rmi 删除本地一个或多少镜像
  • tag 标记本地镜像,将其归入某一仓库
  • build 命令用于使用 Dockerfile 创建镜像
  • history 查看指定镜像的创建历史
  • save 将指定镜像保存成 tar 归档文件
  • load 导入使用 docker save 命令导出的镜像
  • import 从归档文件中创建镜像

info|version

  • info 显示 Docker 系统信息,包括镜像和容器数
  • version 显示 Docker 版本信息

结构图

docker命令图片

四、docker内容器操作

从镜像市场pull一个centos

# 查询dockerhub中star数在100以上的镜像
$ docker search -s 100 centos
# 拉取镜像
$ docker pull centos
# 启动镜像并进入容器
# -i:与容器进行交互 -t:为容器分配伪终端 --name:为容器设置别名 
# /bin/bash:进入容器的命令行,centos可以不加,但是有些容器需要加
$ docker run -it --name mycentos centos /bin/bash
# 1.在容器中退出并关闭容器
$ exit
# 2.在容器中离开但不关闭容器
ctrl+P+Q
# 启动镜像不进入容器(后台守护运行)
# 注意事项:docker容器后台运行必须有一个前台进程,容器运行的命令如果不是那些一直挂起的命令(top,tail)
# 就是会自动退出的
$ docker run -d centos
# 如果要重新进入暂时退出的容器
# 进入容器启动命令的终端,不启动新进程
$ docker attach 容器id
# 如果只是需要执行容器中的命令(不进入容器)
# 在容器中打开新的终端,可以启动新的进程(如果容器后的命令是/bin/bash则效果和attach相同,都是进入容器)
$ docker exce -t 容器id ls -l /tmp	# -t 为容器分配伪终端

运行tomcat并访问

# 查看tomcat imageID
$ docker images tomcat
# 1.进入伪终端运行tomcat并指定映射宿主机端口(host:8888,tomcat:8080)
$ docker run -it -p 8888:8080 tomcat#(或imageID)
# 2.进入伪终端运行tomcat并随机映射宿主机端口
$ docker run -it -P tomcat#(或imageID)
# 访问localhost:8888既可访问到容器中的tomcat

# 通过另个一远程终端查看运行中的docker容器,可以看到所映射的端口号
$ docker ps

注意:在docker中,如果后台运行的容器没有跟前台有可进行的交互或端口映射,容器会自动退出。所以,如果启动tomcat,不论是-it前台启动还是-d后台启动,都需要指定映射端口,不然会自动退出。

docker容器commit成为新的镜像

# 先把容器运行起来,并进行一定的修改
$ docker run -it -P tomcat
# 查看容器id
$ docker ps tomcat
# 提交镜像 -a:作者 -m:说明 mytomcat:自定义名称(REPOSITORY) v1.0:自定义版本号(TAG)
$ docker commit -a "helin" -m "tomcat without docs" 容器ID mytomcat:v1.0
# 查看打包好的镜像
$ docker images
# 删除启动的容器
$ docker rm -f $(docker ps -q)
# 启动自己的容器
$ docker run -it -p 8888:8080 mytomcat:v1.0 #(如果不用id的话一定要带版本号,不然默认找的是latest版本)

五、Docker镜像加载原理

Union FS 联合文件系统

Union FS(联合文件系统): Union文件系统( Union FS)是一种分层、轻量级并且髙性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem) 。 Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

docker镜像加载原理

​ docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统 UnionFS(联合文件系统)
​ **bootfs( boot file system)**主要包含 bootloaderkernel, bootloader主要是引导加载 kernel, Linux刚启动时会加载 bootfs文件系统,在Docker镜像的最底层是 bootfs。这一层与我们典型的 Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载 bootfs
rootfs( root file system),在 bootfs之上。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不
同的操作系统发行版,比如 Ubuntu, Centos等等

docker镜像原理1

docker镜像原理2

docker镜像原理3

docker镜像原理4

为什么docker中的centos比虚拟机中的centos要小那么多

​ 对于一个精简的OS, rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host(宿主机)的 kernel,自己只需要提供 rootfs就行了。由此可见对于不同的linux发行版,bootfs本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

六、Docker容器数据卷

​ 卷就是目录或文件,存在于一个或多个容器中,由 docker挂载到容器,但不属于联合文件系统,因此能够绕过 Union File System提供一些用于持续存储或共享数据的特性:
​ 卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此 Docker不会在容器删除时删除其挂载的数据卷
特点:

  1. 数据卷可在容器之间共享或重用数据
  2. 卷中的更改可以直接生效
  3. 数据卷中的更改不会包含在镜像的更新中
  4. 数据卷的生命周期一直持续到没有容器使用它为止

简单来说:容器数据卷就是容器和宿主机之间的共享移动硬盘

作用就是做容器的持久化和容器之间的继承和数据共享

添加数据卷

# 设置共享劵的方式启动 
# -v:绑定一个卷 /mydata:宿主机目录 /containerdata:容器目录
# 宿主机目录和容器目录都会在启动容器时创建
$ docker run -it -v /mydata:/containerdata centos
# 查看容器详细信息
$ docker inspect 容器id
# 如果看到如下内容,则绑定成功
"HostConfig":{
            "Binds":[
                "/mydata:/containerdata"
            ],

"Mounts":[
            {
                "Type":"bind",
                "Source":"/mydata",
                "Destination":"/containerdata",
                "Mode":"",
                "RW":true,		# 是否可以读写 如果为false则只读
                "Propagation":"rprivate"
            }
        ],
# 启动容器并以只读的方式绑定一个卷 ro:只读
$ docker run -it -v /mydata:/containerdata:ro centos

用dockerFile的方式添加容器数据卷

# 在根目录创建mydocker文件夹并进入
$ cd /
$ mkdir mydocker
$ cd mydocker/
# 编写dockerFile文件
$ vim Dockerfile


# 写入如下内容
# from:源于centos这个镜像
# volume:给容器中的centos挂载dataContainer1和dataContainer2两个卷
FROM centos		
VOLUME ["/dataContainer1","/dataContainer2"]
CMD echo "finished-------success1"
CMD /bin/bash
# 以上类似于命令
# docker run -it -v /host1:/dataContainer1 -v /host2:/dataContainer2 centos


# 使用该Dockerfile创建镜像
# -f:设置dockerfile的文件路径 -t:镜像名字和标签
# 最后一定要加“ .”
$ docker build -f /mydocker/Dockerfile -t fcentos:v1.1 .
# 查看创建好的镜像
$ docker images
# 运行新创建的镜像
$ docker run -it fcentos:v1.1
# 在主机中使用inspect
$ docker inspect 容器ID


# 查询主机中的默认卷对应目录
"Mounts": [
            {
                "Type": "volume",
                "Name": "2ed954dae14cfc7358b51f43312054b802028accbbd95fe998213bb4a16a3597",
                "Source": "/var/lib/docker/volumes/2ed954dae14cfc7358b51f43312054b802028accbbd95fe998213bb4a16a3597/_data",
                "Destination": "/dataContainer1",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "de03e4a5f6fe082616bf29d1d0db84e69a1031cc28e1423768c666a16fbd7341",
                "Source": "/var/lib/docker/volumes/de03e4a5f6fe082616bf29d1d0db84e69a1031cc28e1423768c666a16fbd7341/_data",
                "Destination": "/dataContainer2",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

# 从以上内容可以看到
#/var/lib/docker/volumes/2ed954dae14cfc7358b51f43312054b802028accbbd95fe998213bb4a16a3597/_data和/dataContainer1进行了绑定,这是docker给主机的默认目录

数据卷容器(容器间传递共享–volumes-from)

命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共亨,挂载数据卷的容器,称之为数据卷容器

# 创建运行新的容器
$ docker images
$ docker run -it --name dc01 fcentos:v1.1
# dc02继承自dc01 --volumes-from:当前容器需要继承挂载的容器,会自动传递其中的卷内容
# 这时候无论是修改父容器dc01还是子容器dc02中的文件都会相互共享
# 但是如果删除dc01中的文件,dc02不受影响,反之同理
$ docker run -it --name dc02 --volumes-from dc01 fcentos

结论:容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止

七、DockerFile

什么是 Dockerfile?

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

Dockerfile 基础知识

  • 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
  • 指令按照从上到下,顺序执行
  • #表示注释
  • 每条指令都会创建一个新的镜像层,并对镜像进行提交
  • FROM scrath中的**scrath(空镜像)**是基础容器,即所有容器的父容器

Docker执行Dockerfile的大致流程

  1. docker从基础镜像运行一个容器
  2. 执行一条指令并对容器作出修改
  3. 执行类似 docker commit的操作提交一个新的镜像层
  4. docker再基于刚提交的镜像运行一个新容器
  5. 执行 dockerfile中的下一条指令直到所有指令都执行完成

保留字指令详解

FROM

定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。

MAINTAINER

镜像维护者的姓名和邮箱地址

RUN

容器构建时需要执行的命令。

  • shell 格式:
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。
  • exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径。

  • 格式:
COPY [--chown=<user>:<group>] <源路径1>...  <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",...  "<目标路径>"]
  • [–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。

  • <源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:

COPY hom* /mydir/
COPY hom?.txt /mydir/
  • <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
ADD

ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:

  • ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>,同时也会处理url。
  • ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

  • CMD 在docker run 时运行。
  • RUN 在 docker build时运行。

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

  • 格式:
CMD <shell 命令> 
CMD ["<可执行文件或命令>","<param1>","<param2>",...] 
CMD ["<param1>","<param2>",...]  # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数

推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。

ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

  • 格式:
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。

  • 示例:

    假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参 
  1. 不传参运行
$ docker run  nginx:test

​ 容器内会默认运行以下命令,启动主进程。

nginx -c /etc/nginx/nginx.conf
  1. 传参运行
$ docker run  nginx:test -c /etc/nginx/new.conf

​ 容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)

nginx -c /etc/nginx/new.conf
ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

  • 格式:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

​ 以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:

ENV NODE_VERSION 7.2.0

RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
  && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
ARG

构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。

格式:

ARG <参数名>[=<默认值>]
VOLUME

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

作用:

  • 避免重要的数据,因容器重启而丢失,这是非常致命的。
  • 避免容器不断变大。
  • 格式:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

​ 在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。

EXPOSE

声明服务对外暴露的端口。
作用:

  • 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
  • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
  • 格式:
EXPOSE <端口1> [<端口2>...]
WORKDIR

指定在创建容器后,终端默认登陆进来的工作目录,一个落脚点。

docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。

  • 格式:
WORKDIR <工作目录路径>
USER

用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。

  • 格式:
USER <用户名>[:<用户组>]
HEALTHCHECK

用于指定某个程序或者指令来监控 docker 容器服务的运行状态。

  • 格式:
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
ONBUILD

用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。

  • 格式:
ONBUILD <其它指令>

编写Dockerfile案例

1. 案例1:mycentos
  • 修改登陆后默认路径
  • 增加vim编辑器
  • 支持ifconfig
  • Dockerfile
FROM centos
MAINTAINER helin9s<1024633414@qq.com>

ENV mypath /tmp		# 设置环境变量,mypath=/tmp
WORKDIR $mypath		# 设置登陆时的默认工作目录。

RUN yum -y install vim	# 运行安装vim
RUN yum -y install net-tools # 运行安装net工具(ifconfig)

EXPOSE 80			# 暴露出80端口
CMD /bin/bash		# 进入控制台
  • 执行
# 在根目录下创建mydocker文件夹
cd /
mkdir mydocker
cd mydocker/
# 复制以上文件到Dockerfile-mycentos中,并保存
vim Dockerfile-mycentos
# 构建镜像
$ docker build -f /mydocker/Dockerfile-mycentos -t mycentos:latest .

# 当看到日志显示如下内容表示构建成功
Successfully built e5734b457e6e
Successfully tagged mycentos:latest

# 进入容器测试
docker run -it mycentos
# 退出容器后,查看镜像历史
docker history mycentos
2. 案例2:CMD/ENTRYPOINT 区别
  • CMD会被docker run之后的命令替换
  • docker run之后的参数会被当做参数传递给ENTRYPOINT,之后形成新的命令组合
# 例如tomcat
$ docker run -it -P tomcat ls -l
# 由于有ls -l把tomcat的Dockerfile最后启动的CMD覆盖了,所以tomcat没有启动成功
  • 制作CMD版可以查询IP信息的容器
  • Dockerfile
FROM centos
MAINTAINER helin9s<1024633414@qq.com>

RUN yum -y install curl	# 安装curl。一个利用URL语法在命令行下工作的文件传输工具
CMD [ "curl","-s","http://www.cip.cc/"] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数。http://ip.cn如果不行就换成cip.cc
  • 执行
# 在根目录下创建mydocker文件夹
cd /
mkdir mydocker
cd mydocker/
# 复制以上文件到Dockerfile-myip中,并保存
vim Dockerfile-myip
# 构建镜像
$ docker build -f /mydocker/Dockerfile-myip -t myip .
# 运行测试
$ docker run -it myip

# 如果这时候我们还想看到报文头
$ docker run -it myip -i 
# 这样请求会报错。因为把Dockerfile的CMD命令给覆盖掉了
# 所以CMD命令的Dockerfile无法满足我们的需求
  • 制作ENTRYPOINT版可以查询IP信息的容器
  • Dockerfile
FROM centos
MAINTAINER helin9s<1024633414@qq.com>

RUN yum -y install curl	# 安装curl。一个利用URL语法在命令行下工作的文件传输工具
ENTRYPOINT [ "curl","-s","http://www.cip.cc/"] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数。http://ip.cn如果不行就换成cip.cc
  • 执行
# 在根目录下创建mydocker文件夹
cd /
mkdir mydocker
cd mydocker/
# 复制以上文件到Dockerfile-myip2中,并保存
vim Dockerfile-myip2
# 构建镜像
$ docker build -f /mydocker/Dockerfile-myip2 -t myip2 .
# 运行测试
$ docker run -it myip2
# 如果这时候我们还想看到报文头
$ docker run -it myip -i 
# 由于Dockerfile是ENTRYPOINT,所以能够把docker run中添加的指令添加到默认指令之后
3. 案例3: ONBUILD 指令
  • Dockerfile
FROM centos
MAINTAINER helin9s<1024633414@qq.com>

RUN yum -y install curl	
ENTRYPOINT [ "curl","-s","http://www.cip.cc/"] 
ONBUILD RUN echo "father onbuild---------886" # 该镜像被继承时执行
  • 执行
# 在根目录下创建mydocker文件夹
cd /
mkdir mydocker
cd mydocker/
# 复制以上文件到Dockerfile-father中,并保存
vim Dockerfile-father
# 构建镜像
$ docker build -f /mydocker/Dockerfile-father -t myip-father .
  • 然后继续创建Dockerfile继承myip-father
FROM myip-father	# 继承myip-father
MAINTAINER helin9s<1024633414@qq.com>

RUN yum -y install curl	
ENTRYPOINT [ "curl","-s","http://www.cip.cc/"] 
  • 执行
# 复制以上文件到Dockerfile-son中,并保存
vim Dockerfile-son
# 构建镜像
$ docker build -f /mydocker/Dockerfile-son -t myip-son .


# 执行时可以看到控制台打印的日志有以下内容
step 0: FROM myip-father
\# Executing 1 build triggers
Trigger 0, RUn echo "father onbuild---------886"
Step 0: RUN echo "father onbuild---------886"
4. 案例4:自定义镜像Tomcat9
  • 自定义一个Tomcat9的镜像
FROM centos
MAINTAINER helin9s<1024633414@qq.com>

ENV MYPATH /usr/local
# 把宿主机当前上下文的COPY演示.txt拷贝到容器/usr/local/路径下并改名为cincontainer.txt
COPY COPY演示.txt $MYPATH/cincontainer.txt
ADD jdk-8u171-linux-x64.tar.gz $MYPATH/
ADD apache-tomcat-9.0.8.tar.gz $MYPATH/
# 安装vim
RUN yum -y install vim
# 设置工作路径
WORKDIR $MYPATH
# 配置java和tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME $MYPATH/apache-tomcat-9.0.8
ENV CATALINA_BASE $MYPATH/apache-tomcat-9.0.8
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行 tomcat
# ENTRYPOINT["/usr/local/apache-tomcat-9.0.8/bin/startup.sh"]
# CMD["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F
/usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out
  • 执行
# 创建并进入目录
mkdir -p /mydockerfile/tomcat9/
cd /mydockerfile/tomcat9/
# 创建COPY演示.txt
touch COPY演示.txt
# 将jdk和tomcat安装的压缩包拷贝进/tomcat9目录
# 构建之前/tomcat9目录中需要有jdk和tomcat9的压缩包以及一个COPY演示.txt文件
# 复制以上文件到Dockerfile-tomcat9中,并保存
vim Dockerfile-tomcat9
# 构建镜像
$ docker build -f /mydockerfile/tomcat9/Dockerfile-tomcat9 -t mytomcat9 .
# 如果在本目录,并且Dockerfile是默认"Dockerfile"名字,可以简写成
$ docker build -t mytomcat9 .
# 运行测试 
# --privileged:设置写权限
$ docker run -d -p 9080:8080 --name mytomcat9 -v /mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/
test -v /mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0 .8/logs --privileged=true mytomcat9
  • 测试发布一个项目
# 准备一个a.jsp和WEB-INF文件夹到共享文件夹中,并在WEB-INF中创建web.xml
cd /mydockerfile/tomcat9/test/
vim a.jsp
mkdir WEB-INF
vim web.xml
# 重启后tomcat后即可访问
$ docker restart 容器ID
http://localhost:9080/test/a.jsp

八、Docker安装常用软件

Tomcat

$ docker search tomcat
$ docker pull tomcat
$ docker run -d -p 8080:8080 -v --name tomcat /mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/
test -v /mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0 .8/logs --privileged=true tomcat

Mysql

$ docker search mysql
$ docker pull mysql:5.7
$ docker run -p 3306:3306 --name mysql -v/usr/local/mysql/conf:/etc/mysql/conf.d -v /usr/local/mysql/logs:/logs -v /usr/local/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
# -e:初始化root用户的密码

Redis

$ docker search redis
$ docker pull redis:3.2
$ docker run -p 6379:6379 -v /usr/local/redis/data:/data -v /usr/local/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf -d redis:3.2 redis-server /usr/local/etc/redis/redis.conf --appendonly yes
# redis-server:加载redis.conf目录的文件
# --appendonly yes:开启Redis的AOF持久化
# 在/usr/local/etc/redis/redis.conf下创建redis.conf并写入配置
vim /usr/local/etc/redis/redis.conf/redis.conf

九、Docker本地镜像发布到阿里云流程

docker本地镜像发布到阿里云流程

  • 操作
$ docker run -it mycentos:1.3
$ docker ps
$ docker commit -a helin9s -m "new mycentos1.4 with vim and ifconfig" 容器ID mycentos:1.4
$ docker images
# 登陆阿里云镜像仓库
# https://cr.console.aliyun.com/cn-hangzhou/instances/repositories
# 配置阿里云镜像仓库

# 登录阿里云Docker Registry
$ sudo docker login --username=自己的账号 registry.cn-hangzhou.aliyuncs.com
# 从Registry中拉取镜像
$ sudo docker pull registry.cn-hangzhou.aliyuncs.com/helin9s/test_tomcat:[镜像版本号]
# 将镜像推送到Registry
$ sudo docker login --username=自己的账号 registry.cn-hangzhou.aliyuncs.com
$ sudo docker tag 容器ID registry.cn-hangzhou.aliyuncs.com/helin9s/test_tomcat:[镜像版本号]
$ sudo docker push registry.cn-hangzhou.aliyuncs.com/helin9s/test_tomcat:[镜像版本号]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值