Docker(入门)

这篇博客详细介绍了Docker的基本概念和操作,包括Docker的系统架构、镜像、容器、仓库、镜像加速器、运行容器、数据卷以及与MySQL的结合使用。通过实例演示了如何安装Docker,构建和运行镜像,以及如何持久化数据。此外,还讲解了Dockerfile的使用和定制镜像的方法,以及容器的启动、停止和数据管理。
摘要由CSDN通过智能技术生成
  • 一种服务器,它是一种称为守护进程并且长时间运行的程序。
  • REST API用于指定程序可以用来与守护进程通信的接口,并指示它做什么。
  • 一个有命令行界面 (CLI) 工具的客户端。

Docker 系统架构

Docker 使用客户端-服务器 (C/S) 架构模式,使用远程 API 来管理和创建 Docker 容器。

Docker 容器通过 Docker 镜像来创建。

容器与镜像的关系类似于面向对象编程中的对象与类。

Docker面向对象
容器对象
镜像

Tomcat 镜像继承了Java镜像,说明该镜像已经装过Java了。复用的体现。

build请求守护进程,守护进程构建一个ubuntu镜像

run请求守护进程,run一个ubuntu镜像,启动ubuntu容器,可以启动多个。

pull请求守护进程,到docker官方仓库,找redis镜像,拉取到docker主机上。

多个容器,负载均衡(Docker又称负载均衡入口)

Docker 镜像

镜像不包含任何动态数据,其内容在构建之后也不会被改变。

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

Docker 容器

按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。

Docker 仓库

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

一个 Docker Registry 中可以包含多个仓库Repository);每个仓库可以包含多个标签Tag);每个标签对应一个镜像。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

公有 Docker Registry

最常使用的 Registry 公开服务是官方的 Docker Hub

国内的一些云服务商提供了针对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为加速器

私有 Docker Registry

Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。只提供了 Docker Registry API 的服务端实现,足以支持 docker 命令,不影响使用。

 

安装

https://www.cnblogs.com/jiyang2008/p/9014960.html

Decker CE 免费版

Docker 镜像加速器

对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件

{
  "registry-mirrors": [
    "https://registry.docker-cn.com"
  ]
}

 

注意,一定要保证该文件符合 json 规范,否则 Docker 将不能启动。

之后重新启动服务。

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

 下载镜像:docker pull tomcat:jre-9   /   docker pull ubuntu:16.04

从下载过程中可以看到我们之前提及的分层存储的概念,镜像是由多层存储所构成。下载也是一层层的去下载,并非单一文件。下载过程中给出了每一层的 ID 的前 12 位。并且下载结束后,给出该镜像完整的 sha256 的摘要,以确保下载一致性。

 

docker images : 查找安装的镜像

启动Tomcat(docker run 相当于 new)会产生新容器

 如果启动其他的端口需要在server.xml中设置(进入docker的tomcat方式,后面内容中有)

运行

有了镜像后,我们就能够以这个镜像为基础启动并运行一个容器。以上面的 ubuntu:16.04 为例,如果我们打算启动里面的 bash 并且进行交互式操作的话,可以执行下面的命令。

$ docker run -it --rm \
    ubuntu:16.04 \
    bash

root@e7009c6ce357:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="16.04.4 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.4 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

 

docker run 就是运行容器的命令,我们这里简要的说明一下上面用到的参数。

  • -it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端
  • --rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 --rm 可以避免浪费空间
  • ubuntu:16.04:这是指用 ubuntu:16.04 镜像为基础来启动容器。
  • bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash

进入容器后,我们可以在 Shell 下操作,执行任何所需的命令。这里,我们执行了 cat /etc/os-release,这是 Linux 常用的查看当前系统版本的命令,从返回的结果可以看到容器内是 Ubuntu 16.04.4 LTS 系统。

最后我们通过 exit 退出了这个容器。

 

docker ps只查看正在运行的容器

docker ps -a查看所有容器

docker rm  <id> 删除容器

虚悬镜像

这个镜像原本是有镜像名和标签的,原来为 mongo:3.2,随着官方镜像维护,发布了新版本后,重新 docker pull mongo:3.2 时,mongo:3.2 这个镜像名被转移到了新下载的镜像身上,而旧的镜像上的这个名称则被取消,从而成为了 <none>。除了 docker pull 可能导致这种情况,docker build 也同样可以导致这种现象。

一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用下面的命令删除。

$ docker image prune

Docker 删除本地镜像

docker image rm ubuntu:18.04 / docker rmi <id> (两种方式

使用 Dockerfile 定制镜像

从刚才的 docker commit 的学习中,我们可以了解到,镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

 

进入tomcat

 

run 交互的方式启动容器

 

exec 交互的方式进入容器

docker run :根据镜像创建一个容器并运行一个命令,操作的对象是 镜像

docker exec :在运行的容器中执行命令,操作的对象是 容器

进入容器对其中内容进行修改。

=================================================================================

定制

还以之前定制Tomcat镜像为例,这次我们使用 Dockerfile 来定制。

其内容为:

这个 Dockerfile 很简单,一共就两行。涉及到了两条指令,FROMRUN

FROM 指定基础镜像:以一个镜像为基础,在其上进行定制。

RUN 执行命令:RUN 指令是用来执行命令行命令的。由于命令行的强大能力,RUN 指令在定制镜像时是最常用的指令之一。

RUN 执行命令

RUN 指令是用来执行命令行命令的。由于命令行的强大能力,RUN 指令在定制镜像时是最常用的指令之一。其格式有两种:

  • shell 格式:RUN <命令>,就像直接在命令行中输入的命令一样。刚才写的 Dockerfile 中的 RUN 指令就是这种格式。
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

构建镜像(.不表示当前目录,这边这么写便于理解)

 

一共两层,原有的基础上加了一层。

 

构建过程:

启动:

工作目录已设置,启动后直接进入工作目录。

启动以上自己定制的镜像:

 

注意删除虚悬镜像时,需要先把容器删掉。保护机制,想删镜像先删容器。

 

以上是简单的构建镜像的过程了。

 

镜像构建上下文(Context)

如果注意,会看到 docker build 命令最后有一个 .. 表示当前目录,而 Dockerfile 就在当前目录,因此不少初学者以为这个路径是在指定 Dockerfile 所在路径,这么理解其实是不准确的。如果对应上面的命令格式,你可能会发现,这是在指定上下文路径。那么什么是上下文呢?

首先我们要理解 docker build 的工作原理。Docker 在运行时分为 Docker 引擎(也就是服务端守护进程)和客户端工具。Docker 的引擎提供了一组 REST API,被称为 Docker Remote API ,而如 docker 命令这样的客户端工具,则是通过这组 API 与 Docker 引擎交互,从而完成各种功能。因此,虽然表面上我们好像是在本机执行各种 docker 功能,但实际上,一切都是使用的远程调用形式在服务端(Docker 引擎)完成。也因为这种 C/S 设计,让我们操作远程服务器的 Docker 引擎变得轻而易举。

当我们进行镜像构建的时候,并非所有定制都会通过 RUN 指令完成,经常会需要将一些本地文件复制进镜像,比如通过 COPY 指令、ADD 指令等。而 docker build 命令构建镜像,其实并非在本地构建,而是在服务端,也就是 Docker 引擎中构建的。那么在这种客户端/服务端的架构中,如何才能让服务端获得本地文件呢?

这就引入了上下文的概念。当构建的时候,用户会指定构建镜像上下文的路径,docker build 命令得知这个路径后,会将路径下的所有内容打包(让服务端获得本地文件,然后上传给 Docker 引擎。这样 Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。

现在就可以理解刚才的命令 docker build -t myshop . 中的这个 .,实际上是在指定上下文的目录,docker build 命令会将该目录下的内容打包交给 Docker 引擎以帮助构建镜像。

 

再测试一下:

修改Dockerfile

左边index.html是相对路径,当前路径,右边是镜像中的文件夹的位置。

构建

以交互的方式启动一个容器(进入)

 

原先项目部署

1.拷贝myshop.zip -> tomcat/webapps/ROOT

2.修改访问端口号为80

WORKDIR 指定工作目录

之前提到一些初学者常犯的错误是把 Dockerfile 等同于 Shell 脚本来书写,这种错误的理解还可能会导致出现下面这样的错误:

RUN cd /app
RUN echo "hello" > world.txt

 

如果将这个 Dockerfile 进行构建镜像运行后,会发现找不到 /app/world.txt 文件,或者其内容不是 hello。原因其实很简单,在 Shell 中,连续两行是同一个进程执行环境,因此前一个命令修改的内存状态,会直接影响后一个命令;而在 Dockerfile 中,这两行 RUN 命令的执行环境根本不同,是两个完全不同的容器。这就是对 Dockerfile 构建分层存储的概念不了解所导致的错误。

之前说过每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。第一层 RUN cd /app 的执行仅仅是当前进程的工作目录变更,一个内存上的变化而已,其结果不会造成任何文件变更。而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。

因此如果需要改变以后各层的工作目录的位置,那么应该使用 WORKDIR 指令。

 

创建镜像docker build

构建 : docker build -t myshop .

启动镜像:成功部署项目

普通方法启动和docker启动的区别

当然也可将宿主机的9999端口映射到容器默认的8080,而每一个容器也是一个独立的服务器。

docker run -p 9999:8080 myshop

 

 

ADD 更高级的复制文件

在 Docker 官方的 Dockerfile 最佳实践文档 中要求,尽可能的使用 COPY因为 COPY 的语义很明确,就是复制文件而已,而 ADD 则包含了更复杂的功能,其行为也不一定很清晰。最适合使用 ADD 的场合,就是所提及的需要自动解压缩的场合。

 

docker ps列出所有运行中的容器

docker restart <id>重启容器

 

可以给容器取名字

停止

 

Docker 守护态运行

更多的时候,需要让 Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加 -d 参数来实现。

容器会把输出的结果 (STDOUT) 打印到宿主机上面

注意要把端口打开(防火墙中)。

清理所有处于终止状态的容器

docker container ls -a 命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦,用下面的命令可以清理掉所有处于终止状态的容器。

$ docker container prune

 

Docker 数据卷

解决此类问题

数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 数据卷 可以在容器之间共享和重用
  • 数据卷 的修改会立马生效
  • 数据卷 的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除

在docker/tomcat下建一个ROOT/index.html

docker exec进入容器,可以看到ROOT只有一个index.html

-v (ROOT下的内容用来创建不同的容器)

宿主机目录/usr/local/docker/tomcat/ROOT对应容器中的目录/usr/local/tomcat/webapps/ROOT。

宿主机ROOT中有index.html

-v /usr/local/tomcat/ROOT:/usr/local/tomcat/webapps/ROOT 

以上为容器数据持久化

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

MySQL

下载MySQL镜像

启动MySQL

 

并自动新建了目录:

/sbin/iptables -I INPUT -p tcp --dport 3308 -j ACCEPT
端口打开后,连接服务器的数据库(原3306端口已被占用),容器化的mysql

 

部署数据库

docker exec进入容器,追加之后,重新启动。

往容器的mysql数据库导入外界数据库

将容器中的文件复制进入宿主机

以上为容器中内容。

将容器中的内容放入(复制)宿主机。

/usr/local/docker/mysql/conf中文件已配置,可以使用了。配置文件已经在数据卷中。

root@abc:/usr/local/docker/mysql/conf# docker run -p 3308:3306 --name mysql \
> -v /usr/local/docker/mysql/conf:/etc/mysql \
> -v /usr/local/docker/mysql/logs:/var/log/mysql \
> -v /usr/local/docker/mysql/data:/var/lib/mysql \
> -e MYSQL_ROOT_PASSWORD=112358 \
> -d mysql:5.7.22

开启一个新的容器

 以上为容器化部署数据库。

=====================================================================================

项目部署

把打包的项目导入ROOT中解压。

修改数据源

启动容器

查看日志docker logs myblog

以上用docker部署了项目

 

==============================================================================================

部署数据库

1.进入mysql容器中修改/etc/mysql中的配置

2.将容器中的/etc/mysql复制到宿主机的/usr/local/docker/mysql/conf中

3.启动mysql

root@abc:/usr/local/docker/mysql/conf# docker run -p 3308:3306 --name mysql \
> -v /usr/local/docker/mysql/conf:/etc/mysql \
> -v /usr/local/docker/mysql/logs:/var/log/mysql \
> -v /usr/local/docker/mysql/data:/var/lib/mysql \
> -e MYSQL_ROOT_PASSWORD=112358 \
> -d mysql:5.7.22

/usr/local/docker/mysql/conf中已经修改好可以映射到容器的/etc/mysql

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

项目部署

1.把打包的项目导入ROOT中解压  /usr/local/docker/tomcat/ROOT/

2.修改数据源jdbc.properties

3.启动tomcat(别忘挂载数据卷

docker run -p 9999:8080 --name myblog -v /usr/local/docker/tomcat/ROOT/:/usr/local/tomcat/webapps/ROOT -d tomcat

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值