Docker

Docker

镜像(image):是一个只读模版,用来运行Docker 容器。
容器(Container):负责应用程序的运行,包括操作系统、用户添加的文件以及元数据,容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。

注:镜像是只读的,容器在启动的时候创建一层可写层作为最上层。

仓库(Repository):仓库是集中存放镜像文件的场所。仓库分为公开仓库(Public)和私有仓库(Private)两种形式。

注:Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务

1.编写好代码:
2.编写Dockerfile
3.构建镜像:docker build -t dockerdemo:Tag .
4.运行容器:docker run -d -p 8080:8080 dockerdemo 或者 docker run -it dockerdemo:Tag
5. 可以与容器内运行的服务器交互:curl http://localhost:8080
6. 创建Docker Hub 存储库:Repositories->Create 输入存储库名称 -> 创建
6.正确命名image 名称:<Your DockerID>/<Repository Name>:<Tag>
运行:docker tag dockerdemo:1.0 abcyang/dockerdemo:1.0
7.将映像推送到Docker Hub:docker push abcyang/dockerdemo:1.0
(如果没有写Tag,默认为latest)

Dockerfile 内容:指令按照从上到下,顺序执行,每条指令都会创建一个新的镜像层,并对镜像进行提交
#: 注释
# FROM: 告诉 Docker 当前镜像使用哪个镜像作为基础
# MAINTAINER: 镜像维护者的信息:姓名和邮箱地址
# RUN: 在创建镜像时运行的操作,即容器构建时需要运行的命令
# CMD: 启动容器后运行的程序,指定一个容器启动时要运行的命令,Dockerfile中可以有多个CMD命令,但只有最后一个生效,CMD会被 docker run 之后的参数替换
# ADD: 复制本地文件到镜像,将主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar 压缩包
# COPY:类似ADD,拷贝文件和目录到镜像中,将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置 :COPY src dest    COPY ["src", "dest"]
# WORKDIR: 设置 dockerfile 命令运行目录,即在创建容器后,终端默认登陆的进来工作目录,一个落脚点
# USER:指定运行镜像所使用的用户:使用USER指定用户时,可以使用用户名、UID 或 GID,或是两者的组合。使用USER指定用户后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT 都将使用该用户。镜像构建完成后,通过 docker run 运行容器时,可以通过 -u 参数来覆盖所指定的用户。:USER user:gid    或者 USER:uid。。。
# ENV:用来在构建镜像过程中设置环境变量,ENV MY_PATH /usr/mytest,这个环境变量可以在后续的任何RUN指令中使用,也可以在其它指令中直接使用这些环境变量:WORKDIR $MY_PATH
# EXPOSE: 对外部开放端口,即当前容器对外暴露出的端口
# VOLUME:容器数据卷,用于数据保存和持久化工作
# ENTRYPOINT:指定一个容器启动时要运行的命令,ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数
# ONBUILD:用于设置镜像触发器:当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发。当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发
# LABEL:用于为镜像添加元数据,元数以键值对的形式指定:LABEL <key>=<value> <key>=<value> <key>=<value> ...使用LABEL指定元数据时,一条LABEL可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。: LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"
# ARG:用于指定传递给构建运行时的变量:ARG <name>[=<default value>]:如,通过ARG指定两个变量:ARG site     ARG build_user=IT笔录
# STOPSIGNAL:用于设置停止容器所要发送的系统调用信号:STOPSIGNAL signal,所使用的信号必须是内核系统调用表中的合法的值,如:SIGKILL。
# SHELL:用于设置执行命令(shell式)所使用的的默认 shell 类型:SHELL ["executable", "parameters"]

CMD 和 RUN:CMD用于指定在容器启动时所要执行的命令。RUN 在构建的时候执行,并生成一个新的镜像,CMD 在容器运行的时候执行,在构建时不进行任何操作。
CMD/ENTRYPOINT 镜像:都是指定一个容器启动时要运行的命令
CMD:dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
ENTRYPOINT:docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合

在这里插入图片描述

# 指定基于的基础镜像
FROM centos

# 维护者信息
MAINTAINER abc<abcd@qq.com>

#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt

#把java与tomcat添加到容器中
ADD apache-tomcat-9.0.22.tar.gz /usr/local
ADD jdk-8u211-linux-x64.tar.gz /usr/local

#按章vim编辑器
RUN yum -y install vim

#设置工作访问时候的WORKDIR路径,登录落脚点
ENV mypath /usr/local
WORKDIR $mypath

# 设置构建时变量,镜像建立完成后就失效
ARG BUILD_LIBAV=false
ARG WITH_DEBUG=false
ARG WITH_PAGESPEED=true
ARG WITH_RTMP=true

#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_211
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

#容器运行时监听的端口
EXPOSE 8080

# 指定网站目录挂载点
VOLUME ["${NGINX_SITECONF_DIR}"]

#启动时运行tomcat
#ENTRYPOINT ["/usr/local/apache-tomcat-9.0.22/bin/startup.sh"]
#CMD ["/usr/local/apache-tomcat-9.0.22/bin/startup.sh"]
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out

在这里插入图片描述

Dockerfile,Docker镜像,Docker容器分别代表:
Dockerfile:软件的原材料:定义了进程需要的一切东西。
Docker镜像:软件的交付品:定义了Dockerfile文件后,docker build时会产生一个Docker镜 像,当运行Docker镜像时,会真正开始提供服务。
Docker容器:软件的运行态:容器是直接提供服务的。
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

docker执行dockerfile的大致流程:
①docker从基础镜像运行一个容器
②执行一条指令并对容器做出修改
③执行类似docker commit 的操作提交一个新的镜像层
④docker再基于刚提交的镜像运行一个新容器
⑤执行dockerfile中的下一条指令制导所有指令都执行完成
在这里插入图片描述
Docker命令:
在这里插入图片描述


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

一个完整的Docker的组成:

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

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

Docker面向对象
容器对象
镜像

Docker采用 C/S架构 Docker daemon 作为服务端接受来自客户的请求,并处理这些请求(创建、运行、分发容器)。 客户端和服务端既可以运行在一个机器上,也可通过 socket 或者RESTful API 来进行通信。

Docker daemon 一般在宿主主机后台运行,等待接收来自客户端的消息。 Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker daemon 交互。

docker ps -a    : 列出Docker进程
docker stop ID   :停止Docker进程
docker version :查看docker 的版本
docker  info   :查看docker 的信息
docker image ls   :列出本机所有image 文件
docker image rm [imageName]   : 删除image 文件
docker container run   :新建容器,每运行一次,就会新建一个容器。同样的命令运行俩次,就会生成俩个一摸一样的容器文件。
docker container start [containerID]:  如果希望重复使用容器,就要使用该命令,用来启动已经生成,已经停止运行的容器文件。
docker container kill:  终止容器运行,相当于向容器里面的主进程发出SIGKILL信号。
docker container stop [containerID]:  终止容器运行,相当于向容器里面的主进程发出SIGTERM 信号,然后过一段时间再发出SIGKILL信号。
(俩个信号的区别是:应用程序收到SIGTERM 信号以后,可以自行进行收尾清理工作,但也可以不理会这个信号。如果收到SIGKILL 信号,就会强行立即终止,那些正在进行中的操作会全部丢失。)
docker container logs [containerID] :  用来查看docker 容器的输出,即容器里面Shell 的标准输出。如果docker run命令运行容器的时候,没有使用-it参数,就要用这个命令查看输出。
docker container exec -it [containerID] /bin/bash:   用于进入一个正在运行的docker 容器。如果docker run命令运行容器的时候,没有使用-it参数,就要用这个命令进入容器。一旦进入了容器,就可以在容器的 Shell 执行命令了。
docker container cp [containerID]:[/path/to/file] :   拷贝到当前目录。用于从正在运行的Docker 容器里面,将文件拷贝到本机。

image文件

Docker把应用程序及其依赖,打包在image 文件里面。只有通过这个文件,才能生成Docker容器。image 文件可以看作是容器的模版。Docker 根据image 文件生成容器的实例。同一个image 文件,可以生成多个同时运行的容器实例。

image 是二进制文件,实际开发中,一个image 文件往往通过继承另一个image 文件,加上一些个性化设置而生成。

image 文件是通用的,一台机器的image 文件拷贝到另一台机器,照样可以使用。

一般来说,为了节省时间,我们应该尽量使用别人制作好的 image 文件,而不是自己制作。即使要定制,也应该基于别人的 image 文件进行加工,而不是从零开始制作。

为了方便共享,image 文件制作完成后,可以上传到网上的仓库。Docker的官方仓库Docker Hub 是最重要的,最常用的image 仓库。

实例:
首先,运行下面的命令,将 image 文件从仓库抓取到本地。

$ docker image pull library/hello-world

在这里插入图片描述
docker image pull 是抓取image 文件的命令。
library/hello-world 是image 文件在仓库里面的位置,其中 library 是image 文件所在的组,hello-world 是image 文件的名字。

由于 Docker 官方提供的 image 文件,都放在library组里面,所以它的是默认组,可以省略。因此,上面的命令可以写成下面这样。

$ docker image pull hello-world

抓取成功后,就可以在本地看到这个image 文件了。

$ docker image ls

在这里插入图片描述
现在,运行这个 image 文件。

$ docker container run hello-world

docker container run命令会从 image 文件,生成一个正在运行的容器实例。

注意,docker container run命令具有自动抓取 image 文件的功能。如果发现本地没有指定的 image 文件,就会从仓库自动抓取。因此,前面的docker image pull命令并不是必需的步骤。

如果运行成功,你会在屏幕上读到下面的输出。在这里插入图片描述
输出这段提示以后,hello world就会停止运行,容器自动终止。

有些容器不会自动终止,因为提供的是服务。比如,安装运行 Ubuntu 的 image,就可以在命令行体验 Ubuntu 系统。

$ docker container run -it ubuntu bash

对于那些不会自动终止的容器,必须使用docker container kill 命令手动终止。

$ docker container kill [containID]

容器文件

**image 文件生成的容器实例,本省也是一个文件,称为容器文件。**一旦容器生成,就会同时存在两个文件: image 文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已。

# 列出本机正在运行的容器
$ docker container ls

# 列出本机所有容器,包括终止运行的容器
$ docker container ls --all

上面命令的输出结果之中,包括容器的 ID。很多地方都需要提供这个 ID,比如上一节终止容器运行的docker container kill命令。

终止运行的容器文件,依然会占据硬盘空间,可以使用docker container rm命令删除。

$ docker container rm [containerID]

运行上面的命令之后,再使用docker container ls --all命令,就会发现被删除的容器文件已经消失了。

Dockerfile 文件

如何生成image 文件,如果你要推广自己的软件,势必要自己制作image 文件。

这就需要用到 Dockerfile 文件。它是一个文本文件,用来配置image。Docker 根据该文件生成二进制的image 文件。

制作自己的Docker 容器

下面我以 koa-demos 项目为例,介绍怎么写 Dockerfile 文件,实现让用户在 Docker 容器里面运行 Koa 框架。

作为准备工作,请先下载源码。

$ git clone https://github.com/ruanyf/koa-demos.git
$ cd koa-demos

1.编写Dockerfile 文件
1.首先,在项目的根目录下,新建一个文本文件 .dockerigore,写入下面的内容。
在这里插入图片描述

.git
node_modules
npm-debug.log

上面的代码表示,这三个路径要排除,不要打包进入image 文件。如果你没有路径要排除,这个文件可以不新建。

2.然后,在项目的根目录下,新建一个文本文件 Dockerfile, 写入下面的内容。

在这里插入图片描述

FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000

上面代码一共五行,含义如下。

FROM node:8.4:该 image 文件继承官方的 node image,冒号表示标签,这里标签是8.4,即8.4版本的 node。
COPY . /app:将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的/app目录。
WORKDIR /app:指定接下来的工作路径为/app。
RUN npm install:在/app目录下,运行npm install命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。
EXPOSE 3000:将容器 3000 端口暴露出来, 允许外部连接这个端口。

2.创建image 文件
有个Dockerfile 文件以后,就可以使用docker image build 命令创建文件了。
在这里插入图片描述

$ docker image build -t koa-demo .
# 或者
$ docker image build -t koa-demo:0.0.1 .

上面代码中,-t参数用来指定 image 文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是latest。最后的那个点表示 Dockerfile 文件所在的路径,上例是当前路径,所以是一个点。

如果运行成功,就可以看到新生成的 image 文件koa-demo了。

$ docker image ls

在这里插入图片描述

3.生成容器
docker container run 命令会从image 文件生成容器。

在这里插入图片描述

$ docker container run -p 8000:3000 -it koa-demo /bin/bash
# 或者
$ docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash

上面命令的各个参数含义如下:

-p参数:容器的 3000 端口映射到本机的 8000 端口。
-it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。
koa-demo:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。
/bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。

如果一切正常,运行上面的命令以后,就会返回一个命令行提示符。

root@66d80f4aaf1e:/app#

这表示你已经在容器里面了,返回的提示符就是容器内部的 Shell 提示符。执行下面的命令。

root@66d80f4aaf1e:/app# node demos/01.js

这时,Koa 框架已经运行起来了。打开本机的浏览器,访问 http://127.0.0.1:8000,网页显示"Not Found",这是因为这个 demo 没有写路由。

这个例子中,Node 进程运行在 Docker 容器的虚拟环境里面,进程接触到的文件系统和网络接口都是虚拟的,与本机的文件系统和网络接口是隔离的,因此需要定义容器与物理机的端口映射(map)。

现在,在容器的命令行,按下 Ctrl + c 停止 Node 进程,然后按下 Ctrl + d (或者输入 exit)退出容器。此外,也可以用docker container kill终止容器运行。

# 在本机的另一个终端窗口,查出容器的 ID
$ docker container ls

# 停止指定的容器运行
$ docker container kill [containerID]

容器停止运行之后,并不会消失,用下面的命令删除容器文件。

# 查出容器的 ID
$ docker container ls --all

# 删除指定的容器文件
$ docker container rm [containerID]

也可以使用docker container run命令的--rm参数,在容器终止运行后自动删除容器文件。

$ docker container run --rm -p 8000:3000 -it koa-demo /bin/bash

4.CMD 命令
上一节的例子里面,容器启动以后,需要手动输入命令node demos/01.js。我们可以把这个命令写在 Dockerfile 里面,这样容器启动以后,这个命令就已经执行了,不用再手动输入了。


FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000
CMD node demos/01.js

上面的 Dockerfile 里面,多了最后一行CMD node demos/01.js,它表示容器启动后自动执行node demos/01.js

你可能会问,RUN命令与CMD命令的区别在哪里?简单说,RUN命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件;CMD命令则是在容器启动后执行。另外,一个 Dockerfile 可以包含多个RUN命令,但是只能有一个CMD命令。

注意,指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash),否则它会覆盖CMD命令。现在,启动容器可以使用下面的命令。

$ docker container run --rm -p 8000:3000 -it koa-demo:0.0.1

5.发布image 文件
容器运行成功后,就确认了 image 文件的有效性。这时,我们就可以考虑把 image 文件分享到网上,让其他人使用。

首先,去 hub.docker.comcloud.docker.com 注册一个账户。然后,用下面的命令登录。

$ docker login

接着,为本地的 image 标注用户名和版本。

$ docker image tag [imageName] [username]/[repository]:[tag]
# 实例
$ docker image tag koa-demos:0.0.1 ruanyf/koa-demos:0.0.1

也可以不标注用户名,重新构建一下 image 文件。

$ docker image build -t [username]/[repository]:[tag] .

最后,发布 image 文件。

$ docker image push [username]/[repository]:[tag]

发布成功以后,登录 hub.docker.com,就可以看到已经发布的 image 文件。

如何在一台计算机上实现多个服务,让它们相互配合,组合出一个应用程序。

示例软件是 WordPress,它是一个常用软件。同时它又非常简单,只要两个容器就够了(业务容器 + 数据库容器)。而且,这种"业务 + 数据库"的容器架构,具有通用性,许多应用程序都可以复用。

本文采用三种方法,演示如何架设 WordPress 网站。

方法 A:自建 WordPress 容器
方法 B:采用官方的 WordPress 容器
方法 C:采用 Docker Compose 工具

http://www.ruanyifeng.com/blog/2018/02/docker-wordpress-tutorial.html

Docker Compose 工具

Mac和Windows 在安装docker 的时候,会一起安装docker compose。

查看是否安装成功:

$ docker-compose --version

Compose可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器。

# 启动所有服务
$ docker-compose up
# 关闭所有服务
$ docker-compose stop

在docker-demo 目录下,新建docker-compose.yml 文件,写入下面的内容。

mysql:
    image: mysql:5.7
    environment:
     - MYSQL_ROOT_PASSWORD=123456
     - MYSQL_DATABASE=wordpress
web:
    image: wordpress
    links:
     - mysql
    environment:
     - WORDPRESS_DB_PASSWORD=123456
    ports:
     - "127.0.0.3:8080:80"
    working_dir: /var/www/html
    volumes:
     - wordpress:/var/www/html
MYSQL_ROOT_PASSWORD=123456:向容器进程传入一个环境变量MYSQL_ROOT_PASSWORD,该变量会被用作 MySQL 的根密码。
MYSQL_DATABASE=wordpress:向容器进程传入一个环境变量MYSQL_DATABASE,容器里面的 MySQL 会根据该变量创建一个同名数据库(本例是WordPress)。
links :mysql,表示 WordPress 容器要连到wordpressdb容器,冒号表示该容器的别名是mysql。
ports:127.0.0.2:8080:80:将容器的 80 端口映射到127.0.0.28080端口。

上面代码中,两个顶层标签表示有两个容器mysql和web。每个容器的具体设置,前面都已经讲解过了,还是挺容易理解的。

启动两个容器:

$ docker-compose up

浏览器访问 http://127.0.0.3:8080,应该就能看到 WordPress 的安装界面。

现在关闭两个容器:

$ docker-compose stop

关闭以后,这两个容器文件还是存在的,写在里面的数据不会丢失。下次启动的时候,还可以复用。下面的命令可以把这两个容器文件删除(容器必须已经停止运行)。

$ docker-compose rm
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值