Docker

初步认识

Docker是时下热门的容器技术,相信作为一名开发人员,你一定听说过或者使用过,很多人会把Docker理解为一个轻量级虚拟机,但其实Docker与虚拟机(VM)是两种不同的计算机虚拟化技术,也有很多人会觉得,有了虚拟机,那为什么还要使用Docker呢?带着心里的一点点疑问,让我们一起来学习Docker吧。

1、没有虚拟化技术的原始年代

我们仔细想想,在没有计算虚拟化技术的“远古”年代,如果我们要部署一个应用程序(Application),一般的步骤是怎么样的?

第一步肯定是先要准备一台物理服务器,然后在物理服务器上安装一个操作系统(Operating System),有了操作系统之后,便在操作系统上安装运行我们的应用程序,这个过程可以用下面的图来表示:
在这里插入图片描述
那么,这种方式有什么问题呢?其实,在物理机上部署应用有以下几个缺点:

  • 部署非常慢:因为我们得先准备硬件服务器,接着还要安装操作系统,然后再部署应用程序,而且应用程序还有很多的依赖软件,所以这个过程是比较慢的。
  • 成本非常高:主要是物理器成本太高,即使是部署一个简单的应用,也需要一台服务器。
  • 资源浪费:如果应用太简单,也容易浪费硬件资源,比如CPU和内存。
  • 迁移和扩展太慢:如果需要迁移应用,或者扩展应用,都要再准备其他的物理服务器,过程很麻烦,也很慢。

那么有什么办法可以解决这些问题呢?答案便是虚拟化技术。

2、使用虚拟机部署应用程序的年代

谈到计算机的虚拟化技术,我们直接想到的便是虚拟机,虚拟机允许我们在一台物理计算机模拟出多台机器,简单地理解,虚拟化技术就是在一台物理计算机上,通过中间虚拟软件层Hypervisor隔离CPU、内存等硬件资源,虚拟出多台虚拟服务器,这样做的话,一台物理服务器便可以安装多个应用程序,达到资源利用的最大化,而且多个应用之间相互隔离,如下图所示:
在这里插入图片描述
虚拟机的优点:

  • 可以把资源分配到不同的虚拟机,达到硬件资源的最大化利用
  • 与直接在物理机上部署应用,虚拟更容易扩展应用。
  • 云服务:通过虚拟机虚拟出不同的物理资源,可以快速搭建云服务。

虚拟机的不足之处:

虚拟机的不足之外来自于对物理服务器资源的消耗,当我们在物理服务器创建一台虚拟机时,便需要虚拟出一套硬件并在上面运行完整的操作系统,每台虚拟机都占用许多的服务器资源。

3、Docker是什么?

相对于虚拟机的笨重,Docker则更显得轻量化,因此不会占用太多的系统资源。Docker是使用时下很火的Golang语言进行开发的,其技术核心是Linux内核的Cgroup,Namespace和AUFS类的Union FS等技术,这些技术都是Linux内核中早已存在很多年的技术,所以严格来说并不是一个完全创新的技术,Docker通过这些底层的Linux技术,对Linux进程进行封装隔离,而被隔离的进程也被称为容器,完全独立于宿主机的进程。
在这里插入图片描述
所以Docker是容器技术的一种实现,也是操作系统层面的一种虚拟化,与虚拟机的通过一套硬件再安装操作系统完全不同。

4、Docker与虚拟机之间的比较

Docker是在操作系统进程层面的隔离,而虚拟机是在物理资源层面的隔离,两者完全不同,另外,我们也可以通过下面的一个比较,了解两者的根本性差异:
在这里插入图片描述
5、容器解决了开发与生产环境的问题

开发环境与生产环境折射的是开发人员与运维人员之间的矛盾,也许我们常常会听到开发人员对运维人员说的这样一句话:“在我的电脑运行没问题,怎么到了你那里就出问题了,肯定是你的问题”,而运维人员是认为是开发人员的问题。

开发人员需要在本机安装各种各样的测试环境,因此开发的项目需要软件越多,依赖越多,安装的环境也就越复杂。同样的,运维人员需要为开发人员开发的项目提供生产环境,而运维人员除了应对软件之间的依赖,还需要考虑安装软件与硬件之间的兼容性问题。就是这样,所以我们经常看到开发与运维相互甩锅,怎么解决这个问题呢?
在这里插入图片描述

容器就是一个不错的解决方案,容器能成为开发与运维之间沟通的语言,因为容器就像一个集装箱一样,提供了软件运行的最小化环境,将应用与其需要的环境一起打包成为镜像,便可以在开发与运维之间沟通与传输。

基础架构

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

Docker面向对象
镜像
容器对象

我们可以使用下面的图来表示Docker的架构:
在这里插入图片描述
Docker相关的概念如下:

概念说明
Docker 镜像(Images)Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统镜像
Docker 容器(Container)容器是独立运行的一个或一组应用,是镜像运行时的实体
Docker 仓库(Registry)Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub提供了庞大的镜像集合供使用
Docker 客户端(Client)Docker 客户端通过命令行或者其他工具使用 Docker API与 Docker 的守护进程通信
Docker 主机(Host)一个物理或者虚拟的机器用于执行 Docker 守护进程和容器
Docker 守护进程(Daemon)作为服务端接受来自客户端的请求,并处理这些请求(创建、运行、分发容器)

Docker 守护进程一般在宿主主机后台运行,等待接收来自客户端的消息;Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟Docker 守护进程交互。
在这里插入图片描述
Docker也为我们提供了Remote API来操作Docker的守护进程,也意味着我们可以通过自己的程序来控制Docker的运行。客户端和服务端既可以运行在一个机器上,也可通过socket 或者RESTful API 来进行通信:
在这里插入图片描述
至于Docker的客户端与守护进程之间的通信,其连接方式为socket连接。完整的Docker的C/S连接方式的本质可以一般表示为如下:
在这里插入图片描述

环境安装

Docker支持Windows、Liunx操作系统,在Ubuntu系统中安装较为简单:

sudo apt-get update
sudo apt-get install -y docker.io
最后启动docker后台服务:
sudo service docker start

默认情况下docker 命令会使用Unix socket 与Docker 引擎通讯,而只有root 用户和docker 组的用户才可以访问Docker 引擎的Unix socket,故普通用户无法使用Docker:
在这里插入图片描述
出于安全考虑,一般Ubuntu系统上不会直接使用root 用户,因此更好地做法是将需要使用docker 的用户加入docker用户组:

# 建立docker组
sudo groupadd docker
# 将当前用户加入docker组
sudo usermod -aG docker $USER

注销当前用户,重新登录Ubuntu,输入docker images,此时可以返回本地Docker容器信息。如下图所示:
在这里插入图片描述

【备注】 有一个线上平台可创建4小时的Docker供初学者使用:Play-with-Docker,只想了解Docker不想安装的可以使用该平台。

实战使用

Docker核心操作图解:
在这里插入图片描述下面对图示的命令进行演示。

仓库获取

使用pull命令从远程仓库获取一个nginx镜像:
在这里插入图片描述

容器使用

1、使用run命令将镜像运行为一个真正在运行的容器(其中-d是保持后台运行,-p 是端口映射,将docker容器内部的80端口和外部Ubuntu虚拟机的80端口映射,下列命令第二个参数是Docker容器的端口):
在这里插入图片描述
在Ubuntu虚拟机中访问:
在这里插入图片描述
在Win 10物理机中访问:
在这里插入图片描述2、使用docker ps命令来查看正在运行的容器,并使用docker inspect name | id查看指定容器的详细信息:
在这里插入图片描述
3、使用exec命令进入容器里面,对容器进行修改操作( -t参数在新容器内指定一个伪终端或终端;-i参数允许你对容器内的标准输入 (STDIN) 进行交互):
在这里插入图片描述对nginx容器进行修改:
在这里插入图片描述
此时浏览器再访问nginx的默认主页(ctrl+f5强制刷新避免缓存),发现已更改如下:
在这里插入图片描述执行exit可退出当前容器:
在这里插入图片描述4、使用stop命令停止容器:
在这里插入图片描述
5、使用start命令重启容器:
在这里插入图片描述6、使用docker rm -f 容器ID强制删除容器:
在这里插入图片描述

镜像创建

1、使用commit命令向本地主机提交咱们修改后的nginx镜像:
在这里插入图片描述2、我们试试像nginx镜像一样使用new_nginx镜像:
在这里插入图片描述

Dockerfile

下面将演示通过 Dockerfile 文件来 build 镜像 image:

1、先在本地新建nginx文件夹,并在里头新建一个 Dockerfile 文件:
在这里插入图片描述
Dockerfile 文件内容如下:
在这里插入图片描述
2、在 nginx 文件夹下创建一个index.html文件:
在这里插入图片描述内容如下:
在这里插入图片描述
3、使用build命令构建镜像(其中的-t my_nginx指定为 my_nginx 镜像名, 加 . 是指定使用当前本地目录下的 dockerfile 文件构造镜像):
在这里插入图片描述
4、将以上新构建的my_nginx镜像运行跑成容器:
在这里插入图片描述

镜像转移

有时候需要将咱们创建或者修改过后的镜像进行保存、复制到其他机器上使用,可以通过save命令将镜像保存成tar文件,然后在其他机器上使用load命令进行提取恢复即可。

1、使用save命令将上面新建的my_nginx镜像以tar文件格式保存到本地文件夹里:
在这里插入图片描述
2、删除之前存在的my_nginx镜像:
在这里插入图片描述
3、再通过本地的local_nginx.tar文件构建 load 镜像:
在这里插入图片描述
这样之前的my_nginx镜像又重新拿回来了,这就是镜像转移到其他机器使用时保存和恢复的过程。最后看看提取出来的镜像能否正常运行使用:
在这里插入图片描述最后,使用完容器可以将其删除:
在这里插入图片描述关于更多Docker的使用可以学习:w3cschool-DockerDocker教程,此处不再介绍了。

容器靶场

下面将基于 Github 上的项目演示如何使用 Docker 容器来搭建 bWAPP Web靶场环境。

Dockerfile

语法解释
FROM定义容器的基础系统来自哪个 image, 如: FROM ubuntu:14.04, image 仓库为 ubuntu tag 为 14.04的系统
MAINTAINER作者相关信息说明, 一般书写方式为: MAINTAINER <作者名称> <作者邮箱地址>
ADD从宿主机拷贝文件到容器内, 一般格式: ADD ./lib /home/lib, 将当前目录下的 lib 目录中的内容拷贝到容器的 /home/lib/目录下
RUN在容器内运行命令, 如: RUN apt-get -y update
WORKDIR切换容器内的当前工作目录, 如: WORKDIR /home/lib/,当你登陆到容器内后,默认就进入 /home/lib目录
EXPOSE暴漏端口, 把容器端口暴漏给宿主机, 方便在宿主机访问, 如:EXPOSE 1000
CMD执行一系列命令, 如: CMD ["sh", "./startup.sh"]

Dockerfile 样例

Github地址: https://github.com/MyKings/docker-vulnerability-environment/blob/master/bWAPP/Dockerfile

FROM ubuntu:14.04
MAINTAINER MyKings 
# 使用国内淘宝源
ADD sources.list /etc/apt/
# 安装服务
RUN apt-get -y update
RUN apt-get -y install php5 php5-mysqlnd mysql-server wget unzip
# 启动 mysql 并设置 root 密码
RUN /etc/init.d/mysql start &&\
    mysql -e "grant all privileges on *.* to 'root'@'localhost' identified by 'bug';"&&\
    mysql -u root -pbug -e "show databases;"
# 切换工作目录
WORKDIR /var/www/html
# 本地拷贝
#ADD ./bWAPP_latest.zip /var/www/html/bWAPP_latest.zip
#RUN unzip /var/www/html/bWAPP_latest.zip
# 下载 bWAPP
RUN wget http://jaist.dl.sourceforge.net/project/bwapp/bWAPP/bWAPP_latest.zip && unzip bWAPP_latest.zip
# 删除默认首页
RUN rm /var/www/html/index.html
# 拷贝启动脚本
ADD ./startup.sh ./
EXPOSE 80
CMD ["/bin/bash", "/var/www/html/startup.sh"]

bWAPP靶场

1、克隆项目

$ git clone https://github.com/MyKings/docker-vulnerability-environment.git
# 进入到 bWAPP 目录
$ cd ./docker-vulnerability-environment/bWAPP

如下图所示:
在这里插入图片描述
2、创建镜像

使用命令docker build -t bwapp .,开始创建 image 镜像,创建后如下:
在这里插入图片描述
3、创建容器

创建容器并启动交互模式,把容器的 80 端口映射到宿主机的 8080 端口上,并执行 sh ./startup.sh 启动后端服务:
在这里插入图片描述4、开始测试

使用浏览器访问 http://127.0.0.1:8080/bWAPP/ ,开始你的 Hack 之旅吧!
在这里插入图片描述

现成靶场镜像

以上实际上到最后一步的时候我找不到 ./startup.sh文件……以上最后两图是某大佬的成功截图。但是事实上大佬们已经提供了现成的 bWAPP 靶场容器的镜像并保存在 Docker 公用仓库里,我们可以直接搜索并下载使用即可。

1、首先要去搜索一下,看一下有哪些镜像可以下载 :docker search bwapp,如下图所示:
在这里插入图片描述
2、上面有很多镜像可选,我们一般去选择第一个,因为第一个通常都是官方封装的镜像,比较稳定。下面使用docker pull NAME开始下载镜像:
在这里插入图片描述

3、下载好了之后直接看一下存不存在本地,使用docker images 显示所有下载过的镜像(你可能会有疑问为何 441MB 这么大,从网上下载的源码才十几MB,因为镜像中还包含了运行环境和数据库以及一些中间件、所有能用到的东西都被封装在Docker镜像里面了):
在这里插入图片描述
4、接着我们运行一下镜像开启容器看一下效果 docker run -d -p 8080:80 raesene/bwapp
在这里插入图片描述

5、第一次访问需要安装:
在这里插入图片描述
6、访问IP 端口/install.php安装数据库:
在这里插入图片描述
7、点击就自动安装好了,然后再访问IP+8080端口+login.php就可以访问 bWAPP 登录页面了:
在这里插入图片描述

8、输入Bwapp默认账密登入:bee/bug,成功登入后就可以愉快地玩耍啦!
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐