什么是docker
1 | Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。 |
docker应用场景
1 | web应用的自动化打包和发布 |
为什么要用docker?
我们先看看很久很久以前,服务器是怎么部署应用的!
由于物理机的诸多问题,后来出现了虚拟机
1 | 但是虚拟化也是有局限性的,每一个虚拟机都是一个完整的操作系统,要分配系统资源,虚拟机多道一定程度时,操作系统本身资源也就消耗殆尽,或者说必须扩容 |
docker与虚拟机的区别
docker VS 传统虚拟机
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为 MB | 一般为 GB |
性能 | 接近原生 | 弱 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
环境配置的难题
让开发人员最头疼的麻烦事之一就是环境配置了,每台计算机的环境都不相同,应该如何确保自己的程序换一台机器能运行起来呢?
用户必须确保的是:
- 操作系统的相同
- 各种平台库和组件的安装
- 例如python依赖包,环境变量等
如何一些低版本的依赖模块和当前环境不兼容,那就头疼了。。。。。
如果环境配置这么痛苦的话,换一台机器,就得重新配置一下,那么在安装软件的时候,带着原始环境一模一样的复制过来。
解决方案一 虚拟机
虚拟机也可以制作模板,基于模板创建虚拟机,保证环境问题一致
虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在 Windows 系统里面运行 Linux 系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。
虽然用户可以通过虚拟机还原软件的原始环境。但是,这个方案有几个缺点。
(1)资源占用多
虚拟机会独占一部分内存和硬盘空间。它运行的时候,其他程序就不能使用这些资源了。哪怕虚拟机里面的应用程序,真正使用的内存只有 1MB,虚拟机依然需要几百 MB 的内存才能运行。
(2)冗余步骤多
虚拟机是完整的操作系统,一些系统级别的操作步骤,往往无法跳过,比如用户登录。
(3)启动慢
启动操作系统需要多久,启动虚拟机就需要多久。可能要等几分钟,应用程序才能真正运行。
解决方案二 Linux容器
现在:自从用上docker容器后,可以实现开发、测试和生产环境的统一化和标准化。
镜像作为标准的交付件,可在开发、测试和生产环境上以容器来运行,最终实现三套环境上的应用以及运行所依赖内容的完全一致。
由于虚拟机的诸多问题,Linux发展出了另一种虚拟化技术:Linux容器(Linux Containers,缩写LXC)
Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离。在正常进程的外面套了一个保护层,对于容器里面进程来说,它接触的资源都是虚拟的,从而实现和底层系统的隔离。
(1)启动快
容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。所以,启动容器相当于启动本机的一个进程,而不是启动一个操作系统,速度就快很多。
(2)资源占用少
容器只占用需要的资源,不占用那些没有用到的资源;虚拟机由于是完整的操作系统,不可避免要占用所有资源。另外,多个容器可以共享资源,虚拟机都是独享资源。
(3)体积小
容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。
总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。
docker容器的优势
1 | 更高效的利用系统资源 |
1 | 持续交付和部署 |
1 | 更轻松的迁移 |
工作中的虚拟化和容器
docker三大概念
1 | 容器三大基本概念 |
docker镜像
1 | Docker镜像就是一个只读的模板。 |
image的分层存储
1 | 因为镜像包含完整的root文件系统,体积是非常庞大的,因此docker在设计时按照Union FS的技术,将其设计为分层存储的架构。 |
docker容器(container)
1 | image和container的关系,就像面向对象程序设计中的 类和实例一样,镜像是静态的定义(class),容器是镜像运行时的实体(object)。 |
docker仓库(repository)
1 | 仓库是集中存放镜像文件的场所。有时候把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。 |
docker Registry
1 | Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服 务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务 供用户管理私有镜像。 |
CentOS安装docker
官方教程如下,最正确安装docker姿势
1 | 1.卸载旧版本 |
docker版本
1 | Docker 是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为 CE)和企业版(Enterprise Edition,缩写为 EE)。 |
系统环境准备
1 | docker最低支持centos7且在64位平台上,内核版本在3.10以上[root@python ~ 10:48:11]#uname -r |
Docker镜像加速器
1 | https://www.daocloud.io/mirror#accelerator-doc |
docker基础命令注释
1 | [root@docker ~]# docker --help |
使用docker镜像
1 | 从仓库获取镜像 |
获取镜像
1 | 从docker registry获取镜像的命令是docker pull。命令格式是: |
镜像文件
docker是把应用程序和其依赖打包在image文件里面,只有通过这个镜像文件才能生成docker容器。
一个image文件可以生成多个容器实例。
image文件是通用,可以共享的,为了节省时间,我们尽量列出服务器所有镜像文件
1 | #列出所有的image文件 |
搜索docker镜像
1 | [root@docker ~]# docker search centos #搜索所有centos的docker镜像 |
获取docker镜像
1 | 可以使用docker pull命令来从仓库获取所需要的镜像。下面的例子将从Docker Hub仓库下载一个Centos操作系统的镜像。 |
查看docker镜像
1 | 镜像的ID唯一标识了镜像,如果ID相同,说明是同一镜像。 |
删除Docker镜像
1 | 如果要移除本地的镜像,可以使用docker rmi命令(在删除镜像之前先用docker rm删除依赖于这个镜像的所有容器)。注意docker rm 命令是移除容器。 |
导出docker镜像
1 | 如果要导出镜像到本地文件,可以使用docker save命令。 |
导入docker镜像
1 | 可以使用docker load从本地文件中导入到本地docker镜像库 |
启动docker容器的方式
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
因为Docker的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。
新建容器并且启动
1 | 所需要的命令主要为docker run |
当利用docker run来创建容器时,Docker在后台运行的标准操作包括
检查本地是否存在指定的镜像,不存在就从公有仓库下载
利用镜像创建并启动一个容器
分配一个文件系统,并在只读的镜像层外面挂在一层可读写层
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
从地址池配置一个ip地址给容器
执行用户指定的应用程序
执行完毕后容器被终止
docker与”hello docker”
hello world是程序员启蒙语言,我们通过最简单的image文件“hello-world”,来感受一下docker。
1 | #获取镜像 hello-world |
运行一个ubuntu容器
咱们要在cenots7操作系统下,以docker下载一个ubuntu image文件,然后以image启动容器
1 | [root@python ~ 11:52:22]#docker pull ubuntu:14.04 |
下载过程可以看出镜像是由多层存储构成的。下载也是一层一层,并非单一的文件。
下载过程中给出每一层的前12位ID。下载结束后会给出sha246的文件一致性校验值。
运行这个乌班图容器!
1 | [root@python ~ 12:18:53]#docker run -it --rm ubuntu:14.04 bash |
1 | docker run就是运行容器的命令。 |
Docker与CentOS
docker允许在容器内运行应用程序,使用docker run命令来在容器内运行应用程序。
1 | #加速docker镜像下载 |
1 | [root@python ~ 15:14:31]#docker pull docker.io/centos |
运行一个交互式的容器
1 | [root@python ~ 15:15:07]#docker run -it centos /bin/bash |
参数解析:
- -t:在新容器内指定一个伪终端或终端。
- -i:允许你对容器内的标准输入 (STDIN) 进行交互。
1 | 此时就进入了centos系统 |
此时想要退出容器,使用exit命令
后台模式启动docker
-d参数:后台运行容器,返回容器ID
1 | [root@python ~ 15:58:14]#docker run -d centos /bin/sh -c "while true;do echo hello centos; sleep 1;done" |
查看容器内的标准输出
1 | docker logs c02 |
停止容器
1 | docker stop c02 |
启动容器
1 | docker start c02 |
Docker镜像常用命令
1 | docker images #列出所有本级镜像 |
构建镜像
1 | 1.通过commit修改镜像 |
进入容器
使用-d参数时,容器启动后会进入后台。某些时候需要进入容器进行操作,有很多种方法,包括使用docker attach命令或nsenter工具等。
1 | docker exec -it 容器id |
提交创建自定义的镜像(docker container commit)
1 | 1.我们进入交互式的centos容器中,发现没有vim命令 |
外部访问容器
容器中可以运行网络应用,但是要让外部也可以访问这些应用,可以通过-p或-P参数指定端口映射。
1 | -P 参数会随机映射端口到容器开放的网络端口 |
检查映射的端口
1 | #宿主机ip:32768 映射容器的5000端口 |
查看容器日志信息
1 | #不间断显示log |
也可以通过-p参数指定映射端口
1 | #指定服务器的9000端口,映射到容器内的5000端口 |
访问服务器的9000端口
查看指定容器的端口映射
1 | [root@python ~ 16:49:01]#docker port c0b |
查看容器内的进程
1 | [root@python ~ 16:49:05]#docker top c0b |
利用dockerfile定制镜像
镜像是容器的基础,每次执行docker run的时候都会指定哪个镜像作为容器运行的基础。我们之前的例子都是使用来自docker hub的镜像,直接使用这些镜像只能满足一定的需求,当镜像无法满足我们的需求时,就得自定制这些镜像。
镜像的定制就是定制每一层所添加的配置、文件。如果可以吧每一层修改、安装、构建、操作的命令都写入到一个脚本,用脚本来构建、定制镜像,这个脚本就是dockerfile。
Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令 构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
1 | FROM scratch #制作base image 基础镜像,尽量使用官方的image作为base image |
发布docker image到仓库
第一种,docker hub公有镜像发布
1 | 1.docker提供了一个类似于github的仓库dockerhub, |
私有仓库
但是这种镜像仓库是公开的,其他人也是可以下载,并不安全,因此还可以使用docker registry官方提供的私有仓库
1 | 1.官方提供的私有仓库docker registry用法 |
docker run –privileged=true -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry
1 | --privileged=true docker容器的安全机制:设置特权级运行的容器 |
打包flask程序与dockerfile
1 | 确保app.py和dockerfile在同一个目录! |
1 | 3.构建镜像image |