Docker 容器概念

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 容器技术的火热, 必将为线上服务运维方式带来变革。中间件集群管理的目标是使中间件运维更轻、更快、更稳定、更简易, docker 容器技术便是我们实现这一目标的有力工具。这一节我们先来介绍 docker 容器概念及其优势。

不玩虚的, 当然更畅快

docker 与虚拟机(vm)对比:

lark_01_vm_vs_dockerlark_01_vm_vs_docker

  1. 虚拟机运行在虚拟硬件上, 应用运行在虚拟机内核上。而 docker daemon 是宿主机上的一个进程, 应用只是 docker daemon 的一个子进程, 换句话说, 应用直接运行在宿主机内核上。

  2. 虚拟机需要特殊硬件虚拟化技术支持, 因而只能运行在物理机上。docker 没有硬件虚拟化, 因而可以运行在物理机、虚拟机, 甚至 docker 容器内(嵌套运行)。

  3. 因为没有硬件虚拟化及多运行一个 Linux 内核的开销, 应用运行在 docker 上比虚拟机上更轻、更快。

那么, 使用 docker 和直接在宿主机上运行一个程序有什么区别呢?答案是 docker 容器使用 cgroup 名字空间实现了 CPU, 内存, 网络, 文件系统等资源隔离。了解 chroot 的同学可以认为 docker 就是一个更优雅的 chroot。

说到隔离, docker 容器的文件系统在哪里呢? 答案就是镜像。

docker 镜像

镜像描述了 docker 容器运行的初始文件系统, 包含运行应用所需的所有依赖。即可以是一个完整的操作系统, 也可以仅包含应用所需的最小 bin/lib 文件集合。

一个问题: 假设一个 docker 容器文件系统大小为 10GiB, 创建 10 个容器需要多少磁盘空间?
100 GiB?错,还是只要 10 GiB!因为 docker 镜像和容器采用分层文件系统结构, 每个容器包含一层薄薄的可写层, 只读部分是共享的。

docker 镜像存储引擎有 aufs, devicemapper, overlay 等多种实现, 请看 devicemapper 实现示意图如下:

lark_01_dm_containerlark_01_dm_container

镜像是只读的, 创建容器时只是在镜像上面新建一个可写层, 不需要复制整个文件系统, 因而可以实现毫秒级创建。

镜像存储在镜像 hub。每个镜像有一个 tag, 如 registry.hub.docker.com/library/ubuntu:14.04。镜像完整 tag 不仅包含镜像名字, 还指明了镜像从哪里来, 要到哪里去, 就像一个 URL。没错, registry.hub.docker.com 就是官方 docker 镜像 hub 的地址。使用官方 library 镜像时, 可省略前缀, 如以上镜像 tag 可简写为 ubuntu:14.04

docker 为运行应用而生

有了镜像,如何创建容器?docker 不加载 kernel (不同于 vm), 也不执行 init (不同于 vm 和 lxc)。“你不执行应用, 空跑一个 kernel 或者 init 有什么意义?”,docker 说。docker 容器为运行应用而生, 要创建 docker 容器, 必须指定镜像 tag 和启动应用的命令行 (或者镜像设置了默认命令行)。

so, 创建一个 docker 容器的命令行如下:

sudo docker create -ti --name test ubuntu:14.04 bash

这只是创建了容器, 还没有运行, 要运行容器, 执行:

sudo docker start test

通常我们把这两条命令合并成一条, 即 docker run:

sudo docker run -dti --name test ubuntu:14.04 bash

在宿主机上看一下我们刚刚运行的 bash 命令的进程树:

$pstree -sa 21811
systemd --switched-root --system --deserialize 21
└─docker daemon ... ...
└─bash

没错, 它只是 docker daemon 的一个子进程.

应用即 docker 主进程

attach 到容器内的应用, 本例中即为 bash 命令行:

sudo docker attach test

ps -ef 看一下:

$sudo docker attach test

root@47c90c3dcbfa:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 17:05 ? 00:00:00 bash
root 18 1 0 17:11 ? 00:00:00 ps -ef

加上 ps 自己, 容器中只有两个进程。 bash 在容器内 PID 为 1, 即是容器主进程。主进程退出后, 容器即自动退出。还是那句话, 容器为运行应用而生, 应用都退出了, 容器留着还有什么用。

手动停止容器:

sudo docker stop test

删除容器:

sudo docker rm test

注意: 删除容器后在镜像上创建的可写层文件系统也将被删除, 所以日志、配置、数据等需要持久保存的文件需要挂接到外部储存。

docker 有多轻

俗话说前人栽树, 后人乘凉, 我们通常是基于一个已有的镜像创建应用镜像。为了演示镜像有多轻,我们可以从 0 开始创建一个镜像。

创建一个文件夹 hello-lark, 进入文件夹, 添加一个 Dockerfile 内容如下:

FROM scratch
COPY Dockerfile hello.c hello /

Dockerfile 描述如何创建镜像:

  • FROM scratch 表示从 0 开始, 即从一个空白文件系统开始创建镜像。
  • COPY Dockerfile hello.c hello / 表示将本地 Dockerfilehello.chello 3 个文件复制到镜像内根目录下。

hello.c 和 hello 是我们的应用源码及编译后的二进制文件。
添加 hello.c 文件内容如下:

#include <stdio.h>

int main(int argc, char* argv[]) {
printf("Hello, Lark!\n");
return 0;
}

静态编译之:

gcc -static hello.c -o hello

执行 docker build 创建镜像:

$sudo docker build -t hello-lark:1.0 .
Sending build context to Docker daemon 881.2 kB
Step 1 : FROM scratch
--->
Step 2 : COPY Dockerfile hello.c hello /
---> b52b3bd2799c
Removing intermediate container bc5dcd332026
Successfully built b52b3bd2799c

镜像在本地仓库打包和存储, 不能直接看到实体文件。但是可以导出为一个 tar 包:

sudo docker save -o ../hello-lark.tar hello-lark:1.0

看看有多大:

$ll -h ../hello-lark.tar 
-rw-r--r-- 1 root root 870K Apr 12 13:41 ../hello-lark.tar

仅有 870K, 差不多就是 hello 这个二进制文件的大小。

docker 有多快

这个镜像能跑吗?我们马上运行看看:

$time sudo docker run --name hello --rm hello-lark:1.0 /hello
Hello, Lark!

real 0m0.486s
user 0m0.078s
sys 0m0.016s

可看到, 这条命令一共经历了容器创建、运行、停止、销毁 4 个过程,共耗时不到 0.5 秒。--rm 表示容器结束后自动删除容器。

如果只是创建:

$time sudo docker create --name hello hello-lark:1.0 /hello
16449a07a0f1377336a879f8136ec7369e07520da1f4a7516128b8d3ba314008

real 0m0.075s
user 0m0.064s
sys 0m0.017s

不到 0.1 秒。毫秒级创建绝非虚言。

当然, 只是 hello world 并没有什么用, 我们打一个 busybox 进去, 镜像大小只有 2MB, 然而已经具备一个基本的 linux shell 环境.

sudo docker run -ti --rm lark-box:1.0 sh

docker 的好处

简单说: 标准化交付,微服务编排,提升资源利用率

  1. 校准化交付

    docker 将应用及其所有依赖打包到镜像内, 包括二进制文件(包括底层基础库), 静态配置文件, 环境变量等。剥离了应用对操作系统和环境的依赖, 松耦合 。只需要拉取镜像, 启动容器即可完成应用部署, 方便 。毫秒级创建销毁容器,从而可以实现快速部署、快速迁移、快速扩容缩容,一键快速回滚 (只依赖应用启动时间)。docker 镜像制定了应用交付标准, 开发人员对应用及其运行环境完全可控,并 有效避免各种环境问题踩坑

  2. 微服务编排

    单机部署多应用时,应用之间完全解耦,可以任意部署编排, 完美支持微服务编排的需求。多个 C 应用混布时, docker 化实现 C 依赖隔离, 避免依赖冲突。

  3. 提升资源利用率

    docker 是轻量级的解决方案, 不做虚拟化, 不运行多余的 kernel 和 init 进程, 能有效提升资源利用率。

目录
相关文章
|
2天前
|
数据库 Docker 容器
docker容器为啥会开机自启动
通过配置适当的重启策略,Docker容器可以在主机系统重启后自动启动。这对于保持关键服务的高可用性和自动恢复能力非常有用。选择适合的重启策略(如 `always`或 `unless-stopped`),可以确保应用程序在各种情况下保持运行。理解并配置这些策略是确保Docker容器化应用可靠性的关键。
136 93
|
1月前
|
监控 NoSQL 时序数据库
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
236 77
|
4天前
|
Ubuntu NoSQL Linux
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
50 6
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
|
3天前
|
监控 Java 应用服务中间件
tomcat相关概念与部署tomcat多实例-zabbix监控(docker部署)
通过上述步骤,您可以在Ubuntu系统上成功编译并安装OpenCV 4.8。这种方法不仅使您能够定制OpenCV的功能,还可以优化性能以满足特定需求。确保按照每一步进行操作,以避免常见的编译问题。
41 25
|
16天前
|
搜索推荐 安全 数据安全/隐私保护
7 个最能提高生产力的 Docker 容器
7 个最能提高生产力的 Docker 容器
88 35
|
3天前
|
数据库 Docker 容器
docker容器为啥会开机自启动
通过配置适当的重启策略,Docker容器可以在主机系统重启后自动启动。这对于保持关键服务的高可用性和自动恢复能力非常有用。选择适合的重启策略(如 `always`或 `unless-stopped`),可以确保应用程序在各种情况下保持运行。理解并配置这些策略是确保Docker容器化应用可靠性的关键。
28 17
|
15天前
|
Ubuntu Linux 开发工具
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖项打包成标准化单元(容器),确保在任何支持 Docker 的操作系统上一致运行。容器共享主机内核,提供轻量级、高效的执行环境。本文介绍如何在 Ubuntu 上安装 Docker,并通过简单步骤验证安装成功。后续文章将探讨使用 Docker 部署开源项目。优雅草央千澈 源、安装 Docker 包、验证安装 - 适用场景:开发、测试、生产环境 通过以上步骤,您可以在 Ubuntu 系统上成功安装并运行 Docker,为后续的应用部署打下基础。
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
|
3天前
|
运维 Java 虚拟化
《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下
《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下
49 12
|
21天前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
107 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
4天前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
40 10