Docker

Posted yimiflh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker相关的知识,希望对你有一定的参考价值。

技术分享图片

技术分享图片

什么是docker

Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。
Docker 使用 Google 公司推出的 Go 语言 进行开发实现。
docker是linux容器的一种封装,提供简单易用的容器使用接口。它是最流行的Linux容器解决方案。
docker的接口相当简单,用户可以方便的创建、销毁容器。
docker将应用程序与程序的依赖,打包在一个文件里面。运行这个文件就会生成一个虚拟容器。
程序运行在虚拟容器里,如同在真实物理机上运行一样,有了docker,就不用担心环境问题了。

 docker应用场景

web应用的自动化打包和发布
自动化测试和持续集成、发布
在服务型环境中部署和调整数据库或其他应用

为什么要用docker?

更高效的利用系统资源
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统 资源的利用率更高。
无论是应用执行速度、内存损耗或者文件存储速度,都要比传 统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运 行更多数量的应用。
更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接 运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启 动时间。大大的节约了开发、测试、部署的时间。
一致的运行环境
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环 境不一致,导致有些 bug 并未在开发过程中被发现。
而 Docker 的镜像提供了除内 核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 “这段代码 在我机器上没问题啊” 这类问题。
持续交付和部署
对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意 地方正常运行。
使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员 可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系 统进行集成测试,
而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery
/Deployment) 系统进行自动部署。
而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环 境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
更轻松的迁移
由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在 很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运 行结果是一致的。
因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一 个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。

 docker  VS 传统虚拟机

 

特性

容器

虚拟机

启动

秒级

分钟级

硬盘使用

一般为 MB

一般为 GB

性能

接近原生

系统支持量

单机支持上千个容器

一般几十个

环境配置的难题

让开发人员最头疼的麻烦事之一就是环境配置了,每台计算机的环境都不相同,应该如何确保自己的程序换一台机器能运行起来呢?

用户必须确保的是:

  1. 操作系统的相同
  2. 各种平台库和组件的安装
  3. 例如python依赖包,环境变量等

如何一些低版本的依赖模块和当前环境不兼容,那就头疼了。。。。。

如果环境配置这么痛苦的话,换一台机器,就得重新配置一下,那么在安装软件的时候,带着原始环境一模一样的复制过来。

解决方案一 虚拟机

 

虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在 Windows 系统里面运行 Linux 系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。

虽然用户可以通过虚拟机还原软件的原始环境。但是,这个方案有几个缺点。

(1)资源占用多

虚拟机会独占一部分内存和硬盘空间。它运行的时候,其他程序就不能使用这些资源了。哪怕虚拟机里面的应用程序,真正使用的内存只有 1MB,虚拟机依然需要几百 MB 的内存才能运行。

(2)冗余步骤多

虚拟机是完整的操作系统,一些系统级别的操作步骤,往往无法跳过,比如用户登录。

(3)启动慢

启动操作系统需要多久,启动虚拟机就需要多久。可能要等几分钟,应用程序才能真正运行。

解决方案二  Linux容器

 由于虚拟机的诸多问题,Linux发展出了另一种虚拟化技术:Linux容器(Linux Containers,缩写LXC)

Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离。在正常进程的外面套了一个保护层,对于容器里面进程来说,它接触的资源都是虚拟的,从而实现和底层系统的隔离。

(1)启动快

容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。所以,启动容器相当于启动本机的一个进程,而不是启动一个操作系统,速度就快很多。

(2)资源占用少

容器只占用需要的资源,不占用那些没有用到的资源;虚拟机由于是完整的操作系统,不可避免要占用所有资源。另外,多个容器可以共享资源,虚拟机都是独享资源。

(3)体积小

容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。

总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。

 容器概念

容器三大基本概念
镜像 image
容器 container
仓库 repository
docker整个生命周期就是这三个概念。

docker镜像

image相当于一个root文件系统,比如官方镜像 ubuntu:14.04 就包含了完整的一套 Ubuntu 14.04 最小系统的 root 文件系统。

image的分层存储

因为镜像包含完整的root文件系统,体积是非常庞大的,因此docker在设计时按照Union FS的技术,将其设计为分层存储的架构。
镜像不是ISO那种完整的打包文件,镜像只是一个虚拟的概念,他不是一个完整的文件,而是由一组文件组成,或者多组文件系统联合组成。

 

docker容器

image和container的关系,就像面向对象程序设计中的 类和实例一样,镜像是静态的定义(class),容器是镜像运行时的实体(object)。
容器可以被创建、启动、停止、删除、暂停

docker仓库

镜像构建完成后,可以很容易的在宿主机上运行,如果要在其他服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务。docker registry就是这样的服务。
一个docker registry可以包含多个仓库(repository),每个仓库有多个tag(标签),每个标签对应一个镜像。
一个仓库包含同一个软件不同版本的镜像,标签就是用于标记版本的。

ubantu:14.04
ubantu:16.05
不指定tag的话默认是
ubantu:latest
仓库名海会以 bob/nginx-proxy形式出现,表明docker registry多用户环境下的 用户名/软件名

CentOS安装docker

docker版本

Docker 是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为 CE)和企业版(Enterprise Edition,缩写为 EE)。
企业版包含了一些收费服务,个人开发者一般用不到。本文的介绍都针对社区版。

 系统环境准备

docker最低支持centos7且在64位平台上,内核版本在3.10以上

[[email protected]_python ~ 10:48:11]#uname -r
3.10.0-693.el7.x86_64

yum安装docker

docker软件包和依赖包已经包含在默认的centos-extras软件源里面。
yum install docker

安装完成后检查 docker版本

docker version

Docker镜像加速器

https://www.cnblogs.com/pyyu/p/6925606.html
#一条命令加速
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://95822026.m.daocloud.io

使用docker镜像

从仓库获取镜像
管理本地主机的镜像

获取镜像

从docker registry获取镜像的命令是docker pull。命令格式是:
docker pull [选项][docker registry地址] 仓库名:标签
docker register地址:地址的格式一般是 域名:端口,默认地址是docker hub
仓库名:仓库名是两段格式,用户名/软件名,如果不写用户,默认docker hub用户名是library,也就是官方镜像

镜像文件

docker是把应用程序和其依赖打包在image文件里面,只有通过这个镜像文件才能生成docker容器。
一个image文件可以生成多个容器实例。
image文件是通用,可以共享的,为了节省时间,我们尽量

列出服务器所有镜像文件

#列出所有的image文件
docker image ls
#删除image文件
docker image rm [imagename]

docker与"hello docker"

hello world是程序员启蒙语言,我们通过最简单的image文件“hello-world”,来感受一下docker。
#获取镜像 hello-world
docker pull hello-world
#检查镜像
docker images
#运行image文件,可以用容器id
docker run hello-world
#检查docker容器进程
docker ps
#检查所有运行过的容器
docker ps -a

运行成功后,可以看到结果

技术分享图片

表示你已经成功运行了容器,hello world运行的容器会在完成后,自动终止

 运行一个ubuntu容器 

咱们要在cenots7操作系统下,以docker下载一个ubuntu image文件,然后以image启动容器

[[email protected]y_python ~ 11:52:22]#docker pull ubuntu:14.04
#如图,乌班图的镜像下载,是下载每一层的文件
Trying to pull repository docker.io/library/ubuntu ... 14.04: Pulling from docker.io/library/ubuntu 8284e13a281d: Pull complete 26e1916a9297: Pull complete 4102fc66d4ab: Pull complete 1cf2b01777b2: Pull complete 7f7a2d5e04ed: Pull complete Digest: sha256:4851d1986c90c60f3b19009824c417c4a0426e9cf38ecfeb28598457cefe3f56 Status: Downloaded newer image for docker.io/ubuntu:14.04
下载过程可以看出镜像是由多层存储构成的。下载也是一层一层,并非单一的文件。
下载过程中给出每一层的前12位ID。下载结束后会给出sha246的文件一致性校验值。

运行这个乌班图容器!

[[email protected]_python ~ 12:18:53]#docker run -it --rm ubuntu:14.04 bash
#此时会进入交互式的shell界面,即可以使用乌班图操作系统 [email protected]:
/# cat /etc/os-release NAME="Ubuntu" VERSION="14.04.5 LTS, Trusty Tahr" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 14.04.5 LTS" VERSION_ID="14.04" HOME_URL="http://www.ubuntu.com/" SUPPORT_URL="http://help.ubuntu.com/" BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
#使用exit退出容器
exit
docker run就是运行容器的命令。
参数
 -it : -i 是交互式操作,-t是终端
 -rm  :   容器退出后将其删除。也可以不指定参数,手动docker rm,使用-rm可以避免浪费空间。
ubuntu:14.04 这指的是镜像文件
bash : 指定用交互式的shell,因此需要bash命令

Docker与CentOS

docker允许在容器内运行应用程序,使用docker run命令来在容器内运行应用程序。

#加速docker镜像下载
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://95822026.m.daocloud.io
[[email protected]_python ~ 15:14:31]#docker pull docker.io/centos
Using default tag: latest
Trying to pull repository docker.io/library/centos ...
latest: Pulling from docker.io/library/centos
256b176beaff: Pull complete
Digest: sha256:fc2476ccae2a5186313f2d1dadb4a969d6d2d4c6b23fa98b6c7b0a1faad67685
Status: Downloaded newer image for docker.io/centos:latest

运行一个交互式的容器

[[email protected]_python ~ 15:15:07]#docker run -it centos /bin/bash
#此时进入docker容器 [[email protected]
/]# cat /etc/redhat-release

参数解析:

  • -t:在新容器内指定一个伪终端或终端。

  • -i:允许你对容器内的标准输入 (STDIN) 进行交互。

此时就进入了centos系统
可以查看系统相关信息,内核版本信息
cat /proc/version
ls /

此时想要退出容器,使用exit命令

后台模式启动docker

-d参数:后台运行容器,返回容器ID

[[email protected]_python ~ 15:58:14]#docker run -d centos /bin/sh -c "while true;do echo hello centos; sleep 1;done"
c0283f1077d16a2bf2597e269d51a02815334f7390f18a62ed7a4ba07f351b65
#检查容器进程 [[email protected]_python
~ 15:58:22]#docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c0283f1077d1 centos "/bin/sh -c ‘while..." 6 seconds ago Up 5 seconds fervent_turing [[email protected]_python ~ 15:58:28]#

查看容器内的标准输出

docker logs c02

停止容器

docker stop c02
#此时容器进程不存在
docker ps

启动容器

docker start c02
#检查容器进程
docker ps
删除容器
docker rm c02

Docker镜像常用命令

docker images #列出所有本级镜像
docker pull centos #获取新的centos镜像
docker search nginx #搜索nginx镜像

构建镜像

1.通过commit修改镜像
2.编写dockerfile

 外部访问容器

容器中可以运行网络应用,但是要让外部也可以访问这些应用,可以通过-p或-P参数指定端口映射。

-P 参数会随机映射端口到容器开放的网络端口
[[email protected]_python ~ 16:31:37]#docker run -d -P training/webapp python app.py

检查映射的端口

#宿主机ip:32768 映射容器的5000端口
[[email protected]_python ~ 16:34:02]#docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cfd632821d7a training/webapp "python app.py" 21 seconds ago Up 20 seconds 0.0.0.0:32768->5000/tcp brave_fermi

查看容器日志信息

#不间断显示log
docker logs -f cfd

也可以通过-p参数指定映射端口

#指定服务器的9000端口,映射到容器内的5000端口
[[email protected]_python ~ 16:46:13]#docker run -d -p 9000:5000 training/webapp python app.py c0b5a6278d0f4f2e9b9eba8680451111d8b911b61de0c37ea64cb337aefb854e

访问服务器的9000端口

(如果访问失败的话,检查自己的防火墙,以及云服务器的安全组)

技术分享图片

查看指定容器的端口映射

[[email protected]_python ~ 16:49:01]#docker port c0b
5000/tcp -> 0.0.0.0:9000

查看容器内的进程

[[email protected]_python ~ 16:49:05]#docker top c0b
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                3926                3912                0                   16:46               ?                   00:00:00            python app.py

利用dockerfile定制镜像

镜像是容器的基础,每次执行docker run的时候都会指定哪个镜像作为容器运行的基础。我们之前的例子都是使用来自docker hub的镜像,直接使用这些镜像只能满足一定的需求,当镜像无法满足我们的需求时,就得自定制这些镜像。

 

镜像的定制就是定制每一层所添加的配置、文件。如果可以吧每一层修改、安装、构建、操作的命令都写入到一个脚本,用脚本来构建、定制镜像,这个脚本就是dockerfile。
Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令 构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

 

 

 

 

































































以上是关于Docker的主要内容,如果未能解决你的问题,请参考以下文章

markdown docker-compose片段

sh Docker片段

《Docker 源码分析》全球首发啦!

docker 部署 coredns(内部域名解析)

docker 部署 coredns(内部域名解析)

将 Docker 容器限制为单个 cpu 核心