什么是Docker?


Docker是由dotcloud公司使用golang语言进行开发的,基于Linux内核的 cgroupnamespace,以及OverlayFS类的Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。

下面的图片比较了 Docker 和传统虚拟化方式的不同之处:

传统虚拟化

Docker

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。


为什么要使用Docker

更高效地利用系统资源

由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。


更快速的启动时间

传统虚拟机在启动的时候是需要启动一个完整的操作系统,所以使用传统虚拟化技术启动一个服务需要数分钟,而Docker容器应用是直接将服务的应用程序启动在宿主机的内核上,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。


一致的运行环境

开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些bug并未在开发过程中被发现。而Docker的镜像提供了除内核以外的完整的运行时环境,确保了应用运行环境一致性,不需要做任何配置就能在任意Linux服务器上运行,即Build Once, Run Anywhere。从而不会再出现「这段代码在我机器上没问题啊」这类问题。


更轻松的迁移与弹性伸缩

由于Docker镜像封装了除操作系统内核外的完整的文件系统,所以Docker应用在进行迁移的时候只需要在新的服务器上将镜像拉取下来或者使用Dockerfile重新Build,然后run一下就迁移完成了,完全不用担心运行环境的变化导致应用无法正常运行的情况。


更轻松的扩展与维护

Docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。


与传统虚拟技术对比总结

特性 容器 虚拟机
启动速度 秒级 分钟级
磁盘使用 MB级 GB级
单机运行数量 支持上千个容器 最多跑几十个虚拟机

Docker基础概念

镜像(Image)

我们都知道,操作系统分为内核和用户空间。对于Linux而言,内核启动后,会挂载 root文件系统为其提供用户空间支持。而 Docker镜像(Image),就相当于是一个 root文件系统。比如官方镜像 ubuntu:18.04 就包含了完整的一套 Ubuntu 18.04 最小系统的 root 文件系统。

Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。


容器(Container)

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

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。


仓库(Registry)

Docker Registry提供的是保存Docker镜像的服务,便于将镜像可以在任意支持Docker引擎的服务器上“实例化”为容器提供服务。

通常一个Registry可以包含多个仓库,每个仓库里又可以包含多个镜像,每个镜像之间使用tag(标签)进行区分,如果镜像没有标签则以默认latest作为该镜像的标签,相同标签的镜像会被新镜像覆盖。

以ubuntu镜像为例,ubuntu是仓库的名字,其内包含有不同的版本标签,如,16.04, 18.04。我们可以通过ubuntu:16.04,或者ubuntu:18.04来具体指定所需哪个版本的镜像。如果忽略了标签,比如ubuntu,那将视为ubuntu:latest

Docker基础命令

01. 使用镜像

获取镜像

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

具体的选项可以通过 docker pull --help 命令看到,这里我们说一下镜像名称的格式。

  • Docker 镜像仓库地址:地址的格式一般是<域名/IP>[:端口号]。默认地址是Docker Hub(docker.io)
  • 仓库名:如之前所说,这里的仓库名是两段式名称,即 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。

例如:

docker pull ubuntu:15.10

列出镜像

docker image ls

删除镜像

docker image rm <镜像id>
docker images rm <镜像名>:<镜像tag> # 例如:
docker images rm 5c64
docker images rm alpine:latest

02. 运行容器

使用docker run命令启动一个ubuntu的容器并在其中输出 Hello World文本,执行完毕后,容器会自动退出。

docker run --name=hello ubuntu:15.10 /bin/echo "Hello, World"

参数解析:

run: y与docker组合启动一个新容器;

--name: 容器的名称;

ubuntu:15.10:启动容器使用的镜像;

/bin/echo:在容器中执行的命令。

03. 运行交互式容器

使用命令行运行以下命令,此命令将启动一个ubuntu容器并在其中运行bash交互命令行界面,你可以尝试运行pwd,ls,ps等命令查看容器内环境,就如同远程操作一台服务器一样。

docker run -i -t ubuntu:latest /bin/bash
root@cd07977c1a22:/#

-i: 以交互模式运行容器,通常与 -t 同时使用;

-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;

第二行表示已经进入了一个ubuntu系统的容器中,可以执行命令。

04. 在容器中运行持续任务并管理容器生命周期

后台启动容器

使用以下命令创建一个以进程方式运行的容器

docker run --name=ubuntu -it -d ubuntu:15.10 /bin/bash

参数解析:

-d: 后台运行容器,并返回容器ID;

/bin/bash: 运行的命令,必须是可以一直挂起的命令,如死循环。

docker run --name=test -d ubuntu:15.10 sh -c "while true; do echo hello world; sleep 1; done"

Docker容器后台运行,就必须有一个前台进程,容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的

查看容器列表

使用docker ps命令查看当前宿主机上运行的容器:

# 查看正在运行的容器
docker ps
# 查看所有容器
docker ps -a

查看容器日志

使用docker logs命令查看容器日志

# 查看容器日志
docker logs <containerid>
# 实时查看容器日志
docker logs -f <containerid>

连接容器

连接容器有两种方法,attachexec -it:

# 使用attach
docker attach <containerid> # 使用exec -it
docker exec -it <containerid> /bin/<bash|sh>

注意事项:

使用attach连接是使用现有终端,ctrl+d退出后容器也跟着退出,需要使用ctrl+p+q;

使用exec -it是使用伪终端,ctrl+d退出后容器会继续运行。

停止及删除容器

停止运行中的容器

docker stop e8c6

删除容器

# 删除已经停止的容器
docker rm e8c6
# 删除正在运行的容器
docker rm -f e86c

删除所有停止的容器

docker container prune

容器重启

启动已经停止的容器

docker start e8c6

重启正在运行的容器

docker restart e8c6

05. 容器端口映射

将容器中服务端口映射到宿主机:

# 指定宿主机端口映射
docker run --name=nginx -d -p 80:80 nginx:1.17.0
# 随机宿主机端口映射
docker run --name=nginx -d -P nginx:1.17.0

-p:将容器目录映射至宿主机,<宿主机端口>:<容器端口>

-P: 将容器中暴露的端口映射到宿主机上的随机端口,防止端口冲突。

06. 容器与宿主机文件传输

目录挂载

# 默认权限为读写
docker run --name=nginx -d -v /data:/data nginx:latest
# 配置权限为只读
docker run --name=nginx -d -v /data:/data:ro nginx:latest

文件cp

使用docker cp命令传输文件

# 将宿主机文件copy至容器
docker cp test.txt nginx:/mnt/ # 将容器文件copy至宿主机
docker cp nginx:/mnt/test.txt /mnt/

07. docker for mac中容器访问宿主机服务

docker在mac上启动后,在宿主机上没有docker-0网桥,所以无法通过访问宿主机ip或者docker-0网桥ip访问宿主机服务。

docker for mac提供了一个宿主机的域名host.docker.internal,所以mac上访问宿主机业务时的格式为host.docker.internal:port,如settings.py中mysql的配置:

MYSQL_HOST = 'host.docker.internal'
MYSQL_PORT = '3306'

nginx容器反向代理宿主机后端服务时的配置:

proxy_pass http://host.docker.internal:8899;

Docker基础知识及入门的更多相关文章

  1. jQuery学习笔记 - 基础知识扫盲入门篇

    jQuery学习笔记 - 基础知识扫盲入门篇 2013-06-16 18:42 by 全新时代, 11 阅读, 0 评论, 收藏, 编辑 1.为什么要使用jQuery? 提供了强大的功能函数解决浏览器 ...

  2. Docker03 Docker基础知识、Docker实战

    1 Docker基础知识 1.1 什么是Docker Docker是一个可以装应用的容器,就像杯子可以装水.书包可以装书一样:docker官网 Docker是Docker公司开发的,并开源到GitHu ...

  3. Angular 4 学习笔记 从入门到实战 打造在线竞拍网站 基础知识 快速入门 个人感悟

    最近搞到手了一部Angular4的视频教程,这几天正好有时间变学了一下,可以用来做一些前后端分离的网站,也可以直接去打包web app. 环境&版本信息声明 运行ng -v @angular/ ...

  4. docker 基础知识分享ppt

    给团队做的docker基础分享ppt, 见下面的附件. https://files.cnblogs.com/files/harrychinese/docker_intro.pptx

  5. 史上最全docker基础知识汇总

    正文 Docker常用命令 run docker run [OPTIONS] IMAGE [COMMAND] [ARG...] -e设置环境变量:-e username=zhj --name为容器指定 ...

  6. PJzhang:docker基础知识的2个疗程-one

    猫宁!!! 参考:http://virtual.51cto.com/art/201805/572135.htm https://www.cnblogs.com/rkit/p/9237696.html ...

  7. docker学习---docker基础知识

    目录 docker的基础 1.安装docker 2.使用镜像 3.镜像迁移|导入和导出 4.docker Hub介绍 5.搭建私有镜像仓库 5.1.docker开源的镜像分发工具--docker Re ...

  8. docker基础知识普及(一)

    背景 这篇内容是之前给部门同事培训时写的文档,旨在传达一些docker相关概念,有个基本印象,当然,以下内容都来自网络,我只是个搬运工.具体操作在下篇文章中 一.什么是docker? 1. Docke ...

  9. [19/09/02-星期一] 基础知识_Python入门

    一.计算机基础 用户界面:TUI-文本交互界面: GUI-图形化交互界面 命令行:就是一种文本交互界面,可以使用一个一个的指令来操作计算机.任何计算机的操作系统都包含命令行(Windows.Linux ...

随机推荐

  1. STM32入门系列-使用C语言封装寄存器

    前面文章介绍了存储器映射.寄存器和寄存器映射,这些都是为了介绍使用 C语言封装寄存器做铺垫.这里我们通过一个实例来对 C 语言封装寄存器进行介绍. 具体实例:控制 GPIOC 端口的第 0 管脚输出一 ...

  2. LWJGL3的内存管理,第三篇,剩下的两种策略

    LWJGL3的内存管理,第三篇,剩下的两种策略 上一篇讨论的基于 MemoryStack 类的栈上分配方式,是效率最高的,但是有些情况下无法使用.比如需要分配的内存较大,又或许生命周期较长.这时候就可 ...

  3. think PHP5.1使用时 session重定向丢失问题

    查了很多资料,也看了redirect底层代码,具体来说,还是多个用的地方不太对.做个笔记防忘记: 遇重定向后丢失session时: 1.php.ini配置文件,不要自动启动,默认是0,session. ...

  4. 1.深入Istio:Sidecar自动注入如何实现的?

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的Istio源码是 release 1.5. 这篇文章打算讲一下sidecar, ...

  5. 浅谈OpenGL之DSA

    今天准备写一篇文章简单介绍一下OpenGL4.5引入的一个新的扩展ARB_direct_state_access,这个扩展为OpenGL引入了一个新的特性就是Direct State Acess,下文 ...

  6. 【Kata Daily 190911】Multiplication Tables(乘法表)

    题目: Create a function that accepts dimensions, of Rows x Columns, as parameters in order to create a ...

  7. 针对DEV XtraReport中没有radiobuttonlist的替代方法

     private void PrintingSystem_EditingFieldChanged(object sender, DevExpress.XtraPrinting.EditingField ...

  8. tp3.2 php sdk上传七牛云

    //获取上传token Vendor('sdk.autoload'); $accessKey='********'; $secretKey='*******'; $auth=new \Qiniu\Au ...

  9. 记在Linux上定位后台服务偶发崩溃的问题

    问题描述 在最近的后台服务中,新增将某个指令的请求数据落盘保存的功能.在具体实现时,采用成员变量来保存请求消息代理头,在接收响应以及消息管理类释放时进行销毁.测试反馈,该服务偶发崩溃. 问题分析 测试 ...

  10. Internet 网络协议族

    1.linux目前支持多种协议族,每个协议族用一个net_porto_family结构实例来表示,在初始化时,会调用sock_register()函数初始化注册到net_families[NPROTO ...