Docker入门浅谈
Docker介绍
Docker是Docker Inc公司开源的一项基于LXC技术之上的构建应用打包运行引擎,其源代码托管在GitHub上,基于Go语言开发并遵守Apache 2.0协议开源。
为什么选用Docker技术来构建开发环境?
- 轻量化的部署。相比使用虚拟机,Docker构建部署包更小,启动更加快速,占用资源更少,一台机器可以启动的容器远比可以启用的虚拟机多得多
- 快速标准化部署,可以在本地将应用程序和其依赖的运行环境打包到一个镜像文件中,即可一键部署到能够安装Docker的操作系统环境中
- 快速变更,简化管理。
Docker知识体系庞大,但入门却很简单,使用Docker必须知道2个部分、4个概念。
Docker的2个主要部分是:
- Docker server: Docker的服务端。在安装完Docker之后,需要启动88 Docker server,以一个daemon的形式常驻内存
- Docker client:用户使用client进行容器和镜像的管理。
Docker的4个主要概念是:
- Docker镜像(image):
- 镜像是只读的,镜像中打包了服务运行所需的所有环境相关的文件。镜像用来创建容器,一个镜像可以创建多个初始状态相同的容器。
- Docker容器(container):
- 通过启动镜像来创建一个容器,容器是一个相对隔离的环境,自身包含CPU、内存、磁盘资源和网络管理,多个容器之间不会相互影响,以保证容器中的程序运行在一个相对封闭且安全的环境中
- Docker hub/registry:
- 共享和管理Docker镜像,用户可以上传或者下载上面的镜像,官方地址为https://registry.hub.Docker.com/,也可以搭建自己私有的Docker registry
- 层(Layers):
- image的基本组成单位,每个image是由多个文件系统(只读层)叠加而成。镜像和容器的实质区别就体现在层上,当启动一个容器时,Docker会加载镜像层并在其上添加一个可写层。容器上所做的任何更改,如新建文件、更改文件和删除文件,都记录在可写层上
常见的Docker使用与管理命令
使用docker image pull命令从Docker hub上下载MySQL镜像到本地。
使用docker image ls命令查看本地镜像
使用docker container run命令运行容器,这里创建一个名为mysqlcontainer的MySQL容器,并设置root用户的密码为root
$ docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=root -d mysql
命令中的参数说明如下:
--name:表示启动后容器的名称,如果不指定会给予一个默认的名称。 -e:设置容器内的环境变量,好比在Linux中的export命令,上面设置了一个环境变量,即MySQL的root用户的密码MYSQL_ROOT_PASSWORD。 -d:表示后台运行。 mysql:表示步骤1从docker hub上下载的镜像名。
运行结束后会返回一个字符串,表示容器的ID
使用docker container ls命令查看已经运行的容器列表
使用docker container exec与容器交互,进入MySQL容器,看MySQL数据库信息
使用docker container start/stop/restart/kill,来启动、停止、重启、杀死容器
docker image的帮助命令:docker image[command]-help。例如,docker image--help,Docker image pull–help
使用Dockerfile构建Apache服务镜像
Apache Web服务的Dockerfile文件
#第一部分
FROM ubuntu:16.04 MAINTAINER linzhihuang XXX@qq.com
#第二部分
RUN apt-get update
RUN apt-get -y install apache2 supervisor
WORKDIR /var/www/html
RUN mkdir -p /var/log/apache2
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
#第三部分
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.
conf"]
上面的代码分为三部分:
第一部分表示新构建镜像的初始镜像,以及镜像的创建者(MAINTANINER)。
本例使用的是Ubuntu 16.04的初始镜像,这个镜像使用的是Ubuntu 16.04系统构建的镜像
第二部分则是构建新镜像的所有逻辑,每一个命令在编译时会被当成一个层来处理,先记住它的格式,Docker命令为所在操作系统的Shell命令。
例如RUN apt-get update,RUN是Docker的命令,apt-get update是可以直接运行在Ubuntu上操作的命令
第三部分表示容器启动后运行的命令
代码保存到名为Dockerfile的文件中,并在相同的目录下创建一个supervisord.conf文件
内容如下:
[supervisord]
nodaemon=true
[program:apache_server]
command=/etc/init.d/apache2 restart
redirect_stderr=true
stdout_logfile=/var/log/apache2/apache2.log
#supervisord是一个进程管理工具,Docker可以用supervisord实现多任务运行及管理。
在Dockerfile所在的目录下运行如下命令来编译生成的镜像testapache2
代码如下:
$ docker image build -t test-apache2 ./
Sending build context to Docker daemon 3.072kB
Step 1/8 : FROM ubuntu:16.04
---> 4a689991aa24
Step 2/8 : MAINTAINER linzhihuang "XXX@qq.com"
---> Using cache
---> a7d7b8855c73
Step 3/8 : RUN apt-get update
---> Running in 5b3af5e7b540 Get:1 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB]
...//省略非重要的信息
Get:18 http://archive.ubuntu.com/ubuntu xenial-backports/universe amd64
Packages [8532 B]
Fetched 15.5 MB in 7min 3s (36.5 kB/s)
Reading package lists...
Removing intermediate container 5b3af5e7b540
---> abfde8f0bba8
Step 4/8 : RUN apt-get -y install apache2 supervisor
---> Running in 77af568d1a64 Reading package lists...
Building dependency tree...
...//省略非重要的信息
---> ca574b615524
Step 5/8 : WORKDIR /var/www/html Removing intermediate container d9b6e4061d73
---> 428f7603e9de
Step 6/8 : RUN mkdir -p /var/log/apache2
---> Running in a7ea2a8a8ce2
Removing intermediate container a7ea2a8a8ce2
---> dad0a9a8a6a7
Step 7/8 : COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
---> 36a3007d643a
Step 8/8 : CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/ supervisord.conf"]
---> Running in 583c88fa701f
Removing intermediate container 583c88fa701f
---> 2c13d40160c4
Successfully built 2c13d40160c4
Successfully tagged test-apache2:latest
#docker image build–t中,-t指定编译打包后的Docker镜像名
使用Docker container run运行这个容器
命令如下:
$ Docker container run --name apache-server –p 80:80 -it test-apache2
在Docker container run的命令中,
-i以交互模式运行容器,通常与-t同时使用;
-t为容器重新分配一个伪输入终端,通常与-i同时使用;
-name表示指定启动后容器的名称;
-p表示容器端口映射到所在服务器的端口,让用户能够通过服务器的端口访问到对应的容器,上面表示将容器80端口映射到所在服务器80端口,用户可以通过访问服务器IP的80端口来访问容器。
另外,Docker container run后面还可以接受脚本命令,能够覆盖CMD命令中所声明的命令。
访问Apache服务,在浏览器中输入http://localhost:80
Dockerfile语法
Dockerfile常见的命令有FROM、MAINTAINER、ADD、COPYVOLUME、WORKDIR、ENV、EXPOSE、CMD、ENTRYPOINT和USER。
ROM命令
FROM命令用法如下:
#支持如下3种格式
FROM <image> [AS <name>]
Or
FROM <image>[:<tag>] [AS <name>]
Or
FROM <image>[@<digest>] [AS <name>]
From ubuntu:16.04
FROM指定构建镜像的基础源镜像
FROM语句没有指定镜像标签,默认使用latest标签
MAINTAINER命令
用法如下:
MAINTAINER <name>
声明该镜像文件的拥有者
RUN命令
用法如下:
#支持如下两种形式
RUN <command> #Linux 脚本的语法格式
Or RUN ["executable", "param1", "param2"]
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像,后续的RUN指令都以之前RUN指令执行后的镜像为基础。RUN执行的就是所用镜像操作系统的shell脚本,例如,镜像如是构建在centos之上,则执行的语法格式要符合centos脚本的语法。
用法举例:
#创建目录
RUN mkdir -p /var/log/apache2
ADD命令
用法如下:
#支持如下两种形式
ADD <src>... <dest>
Or
ADD ["<src>",... "<dest>"]
复制本地主机文件、目录到目标容器的文件系统中。如果源是一个URL,该URL的内容将被下载并复制到目标容器中。
COPY命令
用法如下:
#支持如下两种形式
COPY <src>... <dest>
Or
COPY ["<src>",... "<dest>"]
复制新文件或者目录到目标容器指定的路径中。
VOLUME命令
用法如下:
VOLUME ["/data"]
将本地主机目录挂载到目标容器中,并将其他容器挂载的挂载点挂载到目标容器中。
WORKDIR命令
用法如下:
WORKDIR /path/to/workdir
切换目录,相当于Linux的cd命令。
ENV命令
用法如下:
#支持两种格式
ENV <key> <value> # 只能设置一个变量
Or
ENV <key>=<value> ... # 允许一次设置多个变量
指定一个环境变量,会被后续RUN指令使用,可以在容器内被脚本或者程序调用。
EXPOSE命令
用法如下:
EXPOSE <port> [<port>...]
告诉Docker服务端容器对外映射的本地端口,需要在Docker run时使用p或者-P选项生效
CMD命令
用法如下:
#支持3种格式
CMD ["executable","param1","param2"]
Or
CMD command param1 param2 (shell form)
Or
CMD ["param1","param2"]
CMD有两种用途:
一是在启动容器时提供了一个默认的命令执行选项,可被Docker run命令所配置的命令覆盖;
二是作为ENTRYPOINT所运行命令的参数。
ENTRYPOINT命令
用法如下:
#支持如下两种形式
ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)
Or
ENTRYPOINT command param1 param2 (shell form)
配置启动容器时所执行的命令,并且不可被docker run命令所配置的命令覆盖。
从镜像中创建容器时只有基础环境,很多服务和配置都需要根据当前环境在启动容器后运行脚本进行初始化,例如启动服务,Docker提供了3种方式:
- 使用docker run shell命令,例如docker run…/bin/bash;
- 在dockerfile中使用CMD关键字,例如CMD[“/bin/bash”];
- 在dockerfile中使用entrypoint,例如entrypoint/bin/bash
USER命令
用法如下:
USER hdfs
指定运行容器时的用户名或UID,在这之后的命令如RUN、CMD和ENTRYPOINT也会使用指定用户。
代码案例
#更新Ubuntu的apt源,就像在Ubuntu系统下直接执行apt-get update
RUN apt-get update
#下载安装apche2和supervisor两个组件
RUN apt-get -y install apache2 supervisor
#切换到/var/www/html目录下,像cd命令一样
WORKDIR /var/www/html
#创建目录
RUN mkdir -p /var/log/apache2
#将本地文件supervisord.conf复制到镜像/etc/supervisor/conf.d中
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
#上面的代码都发生在Docker iamge build阶段
#启动supervisord组件,这部分代码发生在Docker container run 阶段
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]