背景介绍
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可抑制的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器完全使用沙盒机制,相互之间不会存在任何接口。几乎没有性能开销,可以很容易的在机器和数据中心运行。最重要的是,他们不依赖于任何语言、框架或者包装系统。
Docker是dotCloud公司开源的一个基于LXC的高级容器引擎,源码托管在Github上,基于go语言并且遵从Apache2.0协议开源。
GitHub地址:https://github.com/moby/moby
docker官网:https://www.docker.com
docker中文库:https://www.docker.org.cn/
Docker容器技术与虚拟机的区别
虚拟机:
docker:
虚拟机的Guest OS层和Hypervisor层在docker中被Docker Engine层所替代。虚拟机的Guest OS即为虚拟机安装的操作系统,它是一个完整操作系统内核;虚拟机的Hypervisor层可以简单理解为一个硬件虚拟化平台,它在Host OS是以内核态的驱动存在的。
虚拟机实现资源隔离的方法是利用独立的OS,并利用Hypervisor虚拟化CPU、内存、IO设备等实现的。
对比虚拟机实现资源和环境隔离的方案,docker就显得简练很多。docker Engine可以简单看成对Linux的NameSpace、Cgroup、镜像管理文件系统操作的封装。docker并没有和虚拟机一样利用一个完全独立的Guest OS实现环境隔离,它利用的是目前linux内核本身支持的容器方式实现资源和环境隔离。简言之,docker利用namespace实现系统环境的隔离;利用Cgroup实现资源限制;利用镜像实现根目录环境的隔离。
一个容器的镜像通常都很小,不用和存储大量数据,存储可以通过外部挂载等方式使用。简单来说,docker只用于计算,存储交给别人。
新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个过程,因此新建一个docker容器只需要几秒钟。
基本概念
Docker 包括三个基本概念:
镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
Docker 容器通过 Docker 镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。
docker特性:
-
文件系统隔离:每个进程容器运行在一个完全独立的根文件系统里。
-
资源隔离:系统资源,像CPU和内存等可以分配到不同的容器中,使用cgroup。
网络隔离:每个进程容器运行在自己的网路空间,虚拟接口和IP地址。 -
日志记录:Docker将收集到和记录的每个进程容器的标准流(stdout/stderr/stdin),用于实时检索或者批量检索
-
变更管理:容器文件系统的变更可以提交到新的镜像中,并可重复使用以创建更多的容器。无需使用模板或者手动配置。
-
交互式shell:Docker可以分配一个虚拟终端并且关联到任何容器的标准输出上,例如运行一个一次性交互shell。
docker架构图
工作流程:
1、启动docker
2、下载镜像到本地
3、启动docker容器实例
docker安装
网上教程很多,此处不再赘述
docker命令
(笔者是在kali上进行操作)
查看版本信息:docker version
查看存放docker镜像和仓库的地址:docker info
帮助命令:docker --help
搜索镜像:docker search
拉取镜像:docker pull
默认是拉去docker hub上搜索到的最新版本(第一个)
查看镜像:docker images
镜像命令:
docker images #查看所有本地主机的镜像
docker search 镜像名 #搜索镜像
docker pull 镜像名 [标签] #下载镜像(如果不写tag,默认是latest)
docker rmi 镜像名 [标签] #删除镜像 docker rmi -f $(docker images -aq) 删除全部镜像
docker tag 镜像名:版本 新镜像名:版本 #复制镜像并且修改名称
docker commit -a "xxx" -c "xxx" 镜像ID 名字:版本 #提交镜像
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;
docker load -i /xxx/xxx.tar #导入镜像
docker save -o /xxx/xxx.tar #保存一个镜像为一个tar包
容器命令:
docker run [可选参数] image 命令 #启动容器(无镜像会先下载镜像)
#参数说明
--name = "Name" 容器名字
-c 后面跟待完成的命令
-d 以后台方式运行并且返回ID,启动守护进程式容器
-i 使用交互方式运行容器,通常与t同时使用
-t 为容器重新分配一个伪输入终端。也即启动交互式容器
-p 指定容器端口 -p 容器端口:物理机端口 映射端口
-P 随机指定端口
-v 给容器挂载存储卷
docker build #创建镜像 -f:指定dockerfile文件路径 -t:镜像名字以及标签
docker logs 容器实例的ID #查看容器日志
docker rename 旧名字 新名字 # 给容器重新命名
docker top 容器实例的ID #查看容器内进程
docker ps -a #列出所有容器(不加-a就是在运行的)
docker rm 容器实例的ID #删除容器(正在运行容器不能删除,除非加-f选项)
docker kill 容器实例的ID #杀掉容器
docker history 容器实例的ID #查看docker镜像的变更历史
docker start 容器实例的ID #启动容器
docker restart 容器实例的ID #重启容器
docker stop 容器实例的ID #停止正在运行的容器
docker attach /docker exec 容器实例的ID #同为进入容器命令,不同的是attach连接终止会让容器退出后台运行,而exec不会。并且,docker attach是进入正在执行的终端,不会情动新的进程,而docker exec则会开启一个新的终端,可以在里面操作。
docker image inspect 容器名称:容器标签 #查看容器内源数据
docker cp 容器id:容器内路径 目的主机路径 #从容器内拷贝文件到主机(常用)或者从主机拷贝到容器(一般用挂载)
exit #直接退出容器
crlt + P + Q #退出容器但是不终止运行
比如此处我想启动这个:
输入命令:docker run -ti -p 127.0.0.1:5000:5000 blabla1337/owasp-skf-lab:xss-attribute
端口为5000
查看容器
访问
总结:
-
第一种:交互方式创建容器,退出后容器关闭。
docker run -it 镜像名称:标签 /bin/bash -
第二种:守护进程方式创建容器。
docker run -id 镜像名称:标签
通过这种方式创建的容器,我们不会直接进入到容器界面,而是在后台运行了容器
如果我们需要进去,则还需要一个命令。
docker exec -it 镜像名称:标签 /bin/bash
通过这种方式运行的容器,就不会自动退出了。
docker网络
eth0:本机的外网地址
lo:本地环回地址,可以代表localhost
我们每启动一个docker容器,docker就会给docker容器分配一个ip,安装docker之后,会产生一个叫docker0的网卡,使用的就是veth-pair技术
想要在宿主机访问我们在虚拟机中搭建的docker
首先用docker ps
找到容器内对象的ID,然后docker inspect ID
虚拟机的配置:如为nat方式,修改虚拟机的IP为同网段IP
(借用了其他blog的示意图)
然后在windows中添加路由,以管理员身份运行powershell
ROUTE add 172.17.0.0 mask 255.255.0.0 192.168.209.155
然后在宿主机上就能访问到了
参考:
https://blog.csdn.net/m0_61503020/article/details/125456520
https://www.sohu.com/a/273017267_649850