image.png 先说结论:Docker容器的本质是一个特殊的进程。 学过操作系统的大家应该知道进程其实是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。 其实在操作系统视角来看,处于运行时的Docker容器本身也是一个进程,只是这个进程比较特殊,下面我们就来说说他特殊在哪里 针对Linux容器来说,为了实现容器间资源隔离与限制,其对容器进程做了下面的处理 第一:其使用Linux提供的NameSpace技术来修改Docker容器进行时视图,实现每个容器有相互隔离的网络命名空间、进程空间等;比如你在Docker容器内查看进程列表,会发现容器自身是1号进程, 其并看不到操作系统视角的其他进程,比如每个docker容器看到的都是各自独立的文件系统,相互之间不会影响。 它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。 总结:针对Linux内核的容器,比如Docker容器来说,其本质是一个特殊的进程。
在前面以Docker项目为例,一步步剖析了Linux容器的具体实现方式。 这个重要假设,正是容器技术圈在Docker项目成功后不久,就迅速走向了“容器编排”这个“上层建筑”的主要原因: 作为云基础设施提供商,只要能够将用户提交的Docker镜像以容器的方式运行,就能成为容器生态图上的一个承载点 在“功能单位”划分上,容器却有着独到的“细粒度”优势: 毕竟容器的本质,只是一个进程而已 就是说,只要你愿意,那些原挤在同一VM里的各个应用、组件、守护进程,都可被分别做成镜像! (spec.template部分)是一个使用Nginx镜像的Pod,而这个Pod的副本数是2(replicas=2)。 所以说,Kubernetes的本质,是为用户提供一个具有普遍意义的容器编排工具。 Kubernetes为用户提供的不仅限于一个工具。
举个例子 NameSpace可以让当前进程只能看到当前Namespace里的进程,看不到宿主机创建的进程。并且运行容器的命令为1号进程。 再次证明容器也只是宿主机中的一个进程而已。 先拷贝一个文件系统出来作为我们容器的根文件系统 docker export 48ab2ddd04dc | tar -C . cgroup的情况 当然docker已经封装好了,直接调用以下命令即可实现上面CPU的限制 docker run -it --cpu-period=100000 --cpu-quota=20000 ubuntu /bin/bash 可以看到在/sys/fs/cgroup/cpu,cpuacct/docker目录下创建了该容器的目录,目录下面包含了资源限制文件 [root@k8s-worker1 docker]
本文结合理论与实战,先是从进程隔离、文件隔离、namespace、cgroups、libcontainer展开介绍容器的本质与概念,然后分析docker的技术架构,最后演示docker的常用操作。 而今天,我们就先从docker的原理开始。 微信图片_20190910094723.jpg 容器本质之进程隔离 1. 容器本质 容器本质上是一种进程隔离的技术。 容器为进程提供了一个隔离的环境,容器内的进程无法访问容器外的进程。 2. 容器及容器中的进程在主机上的呈现 启动一个ubuntu的容器: docker run -it ubuntu ? 2. Docker的发展状况 从goole热度上可以获取到docker的热度如下: ? 容器本质之Namespace 1. 2. LXC、Libcontainer与docker 基于各种进程隔离技术,我们就可以创建一个个满足应用运行要求的容器。但这个过程非常复杂。需要有一个简易的容器管理工具。
什么是容器技术 云原生的基础就是容器化。可以说正是容器技术的快速发展,才推动了云原生的时代浪潮。 要想理解容器的本质,我们先来聊聊是容器技术。 简单来说,镜像就是把应用程序运行所依赖的环境、配置等打包成的一个文件;而仓库则是保存和管理这些镜像的地方。这两个概念我们后面的章节会详细展开,本节就先来说一下容器。 容器的本质 那么到底什么是容器呢? 我们结合 Docker 官方的图片来感性理解下: Docker 的 Logo 是一条小鲸鱼,其实它代表的是码头工人,上面运输的就是一个个标准化、可装卸、互相隔离的集装箱。 其实容器和集装箱做的是同样的事情。结合对集装箱的理解,我们尝试给容器下一个定义: 容器,英文 Container,本质就是对进程的封装。 我们看下 Docker 官方提供的一张对比图: 左边是虚拟机,它的核心就是 Hypervisor 虚拟化技术。 简单来说,就是在底层物理机的基础上,再虚拟化出的是硬件资源,并且在上面创建操作系统。
对于 Docker 等大多数 Linux 容器来说,Cgroups 技术是用来制造约束的主要手段; Namespace 技术则是用来修改进程视图的主要方法; 下面我们使用 C 语言和 Namespace ” 上面其实已经基本实现了一个容器,接下去我们实现一下 Docker 卷的基本原理(假设你已经知道卷是什么了)。 同理,在使用 Docker 的时候,其实也并没有一个真正的 Docker 容器运行在宿主机里面。 相比虚拟机的方式,本质是进程的容器则仅仅是在操作系统上划分出了不同的“运行环境”,从而使得占用资源更少,部署速度更快。 巨人的肩膀 1. 极客时间---《深入剖析 Kubernetes》---张磊老师 2. https://coolshell.cn/articles/17010.html
引言 容器非常神奇。它们允许简单的进程表现得像虚拟机。在这种优雅的底层是一组模式和实践,最终使一切运作起来。在设计的根本是层。层是存储和分发容器化文件系统内容的基本方式。 在今天的帖子[1]中,我将解释什么是层以及它们的概念性工作原理。 Snapshots 在容器可以运行之前,它需要一个文件系统来挂载。本质上,它需要一个目录,其中包含所有需要可用的文件。 创建了一个 layer2 的目录。这个空目录现在是一个活动快照。文件 layer2.tar.gz 被下载、验证(通过比较摘要和文件名),并解压到目录中。 结果是包含 /work/message.txt 的目录。这是第一个提交快照。 创建了一个 layer3 的目录,并将 layer2 的内容复制进去。这是一个新的活动快照。 挂载命令可以原生地接受一个冒号 (:) 分隔的 lowerdir 路径列表,所有这些路径都被合并到一个单一的文件系统中。这是现代容器的本质——容器是使用操作系统的原生特性组合而成的。
Docker容器数据卷 数据卷概述 实际开发中,数据的持久化以及数据交互都是十分重要的功能,所以Docker需要处理以下问题 Docker容器删除后,容器中的应用数据是否被删除 Docker容器与外部机器 (宿主机与网络机器)间如何进行文件交互 Docker容器之间如何进行文件的交换 面对以上问题,Docker提供了数据卷的概念,数据卷是宿主机中的一个目录或文件,当容器与数据卷目录绑定(挂载)后,双方对数据卷的修改会立即同步 ,数据卷与容器不是一一对应的关系,一个数据卷可以挂载多个容器,一个容器也可以被挂载多个数据卷 数据卷的作用 保证容器数据的持久化 实现容器与宿主机之间的文件交换 实现Docker容器之间的文件交换 配置数据卷 配置数据卷只需要在创建容器时利用-v参数指定宿主机路径与容器路径的挂载关系 # 创建容器时,使用-v参数设置数据卷 docker run -it --name test1 -v 宿主机目录(或文件): # 其他容器创建时挂载到该容器上,通过--volumes-from指定数据卷容器 docker run -it --name c2 --volumes-from c1 centos:latest docker
上一篇我们从linux 容器的诞生,与架构对docker 有了初步的了解,这个篇章我们将透过现象看本质,深入的探索Linux容器化与Docker 技术 的原理与本质。 容器的文件系统路径为 /var/lib/docker/overlay2/<container-id>/merged。 Docker 的工作流程在 Docker 中,容器的创建和运行可以分为以下四个步骤:镜像获取 Docker 的镜像是一个文件系统层的集合,包含了应用程序运行所需的所有组件。 然后,Docker 会将容器进程切换到容器的网络命名空间中,以获得独立的网络接口和 IP 地址。 此外,Docker 还会挂载容器的文件系统层,并启动容器中定义的应用程序。
一、Docker容器的基本概念 1.1 Docker容器是什么? Docker容器是一种轻量级、可移植的虚拟化技术,用于打包、运输和运行应用程序及其所有依赖项。 1.2 Docker镜像与容器的关系 Docker镜像和容器之间有着密切的关系,它们是Docker技术中两个核心概念,相辅相成,共同构建了Docker容器化的环境。 Docker容器: Docker容器是Docker镜像的运行实例,它是一个独立的、可执行的进程,具有自己的文件系统、网络和进程空间。 工作原理: 当用户运行一个Docker容器时,Docker引擎会根据指定的镜像创建一个新的容器实例。 以下是一些Docker容器的主要特性: 轻量级: Docker容器与传统的虚拟机相比,具有更低的资源消耗和更快的启动时间。
有Docker的情况下,假设进程1和进程2运行于不同的容器,那么进程1和进程2都觉得自己和对方没有半毛钱关系,都觉得自己拥有自己的根文件系统,自己的网卡等,然后进程1和进程2的PID还可以一样,比如假设 虚拟化,本质上一种虚幻,给你一种幻觉,让你觉得拥有的很多甚至拥有全世界,哪怕你实际是一只蝼蚁。 经过本人多年研究,虚拟化的技术分为2种,一种是虚拟一个世界,第二个是虚拟一个氛围。 Docker的架构 Docker中可能涉及到3个机器或者更多机器,一个运行docker命令的client, 一个包含images并以容器(container)形式运行image的主机,一个docker的 nginx的image下载下来后,拿docker run命令就可以弄容器跑nginx了。 ubuntu14.04这个image的2次实例(得到2个容器), Linux下面的ps命令是看进程的,docker下面就是看image的实例容器了。
例如我们要查看 docker run 指令的具体使用方法: 容器使用 获取镜像 如果我们本地没有 ubuntu 镜像,我们可以使用docker pull 命令来载入 ubuntu 镜像: $ docker ,如果想要关闭它,下面会介绍docker容器的停止以及启动,重启 停止一个容器 $ docker stop <容器 ID> 重启一个容器 $ docker restart <容器 ID> 启动已停止运行的容器 查看所有的容器命令如下: $ docker ps -a 可以看到这个容器是关闭的 Exited (0) 2 seconds ago 使用 docker start 启动一个已停止的容器: $ docker 两种进入容器方法的区别 使用 docker exec ,输入exit不会关闭容器 使用 docker attach。 输入exit会关闭容器 接下来我们从下面这两张图中来查看区别: 删除容器 删除容器使用 docker rm 命令: 这里的例子使用网图,我这里还会用就不卸载了 $ docker rm -f 1e560fca3906
接上篇 docker容器虽然运行起来了。 由于容器本身是无状态的我修改完配置文件,关闭docker,下次在启动后还是原样,我需要保存修改。 然后 docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] 如 docker commit cb439fb2c714 finley/phpenv:tp3.2 : docker exec -it 这样的更改是无法持久化保存的,当容器重启后,更改就丢失了,正确的做法是将需要持久化保存的数据放在挂载的存储卷中,当配置需要改变时直接删除重建。 回顾: # 从别人那拉个镜像 docker pull eriksencosta/php-dev # 基于上面的镜像加入了自己的修改并提交为自己的镜像,还打了tag docker commit cb439fb2c714
containerd.io docker-compose-plugin 2. 是不是很简单,我们可以用命令docker ps查看一下当前运行的容器: 命令行查看运行的容器示例图 CONTAINER ID:是容器的唯一标识,我们除了通过“NAMES”来操作容器外,还可以通过“CONTAINER PORTS:对外暴露的端口 NAMES:容器的名称 docker客户端查看运行的容器示例图 同时也用命令docker images查看下当前本地有哪些镜像: 命令行查看运行的镜像示例图 REPOSITORY 之前没有讲怎么查看容器的启动日志,可通过以下命令查看:docker logs local.mailer,结果如下所示: 命令行查看邮件容器的日志信息示例 桌面的话,点击容器即可查看日志: docker -t:tty,终端的意思,会申请一个伪终端,即讲容器的标准输出打印到主机的终端上。 用了这个参数之后,我们就像进入到容器内部一样,可以进行操作和直接查看(不必通过docker日志查看了)。
容器的管理操作 容器常见的命令:查看、创建、启动、终止和删除 创建容器 docker create docker run 二者的区别在于docker create创建的容器处于停止状态,docker run 创建的容器处于启动状态 用docker create创建一个停止状态的容器 [root@docker ~]# docker create centos:6.7 Unable to find image ~]# 创建成功后,Docker会返回容器的ID,如上述中的:a4cca9f1f77695ef11912963ec60b15e2fb4663c50792583c2e4fe2c375a35b6。 ~]# 这里也可以验证docker ps 以及docker ps –a的区别 docker ps 显示的为正在运行的容器 docker ps –a 显示所有的容器 docker ps的其他参数: docker 查看容器日志 docker logs –f 容器名 可以查看容器的日志 参数: -tail 可以查看输入日志的行数 -f 将只需输入最新的日志 查看容器进程 docker top 容器名 可以查看容器中的进程
问题描述: centos 启动一个容器添加了-d 参数,但是docker ps 或者docker ps -a查看却已经退出了 shell>docker run -d centos a44b2b88559b68a2221c9574490a0e708bff49d88ca21f9e59d3eb245c7c0547 shell>docker ps 退出原因 1、docker容器运行必须有一个前台进程, 如果没有前台进程执行,容器认为空闲,就会自行退出 2、容器运行的命令如果不是那些一直挂起的命令( 运行top ,tail、循环等),就是会自动退出 3、这个是 docker 的机制问题 解决方案 方案1: 网上有很多介绍,就是起一个死循环进程,让他不停的循环下去,前台永远有进程执行,那么容器就不会退出了,以 ,还占用一个终端 方案2: shell>docker run -dit centos /bin/bash 添加-it 参数交互运行 添加-d 参数后台运行 这样就能启动一个一直停留在后台运行的Centos shell>docker ps 容器运行起来了 进入容器的方法: 使用exec,不要使用attach命令 attach命令就是使用现有终端,如果你要退出容器操作,那么bash结束,容器也就退出了
大家好,又见面了,我是你们的朋友全栈君。 在使用-d参数时,容器启动后会进入后台,用户无法看到容器中的信息,也无法进行操作。 1、attach命令 attach命令是Docker自带的命令,命令格式为: docker attach [–detach-keys[=[]]] [–no-stdin] [–sig-proxy[ 2、exec命令 Docker从1.3.0版本起提供了一个更加方便的exec命令,可以在容器内直接执行任意命令。 例如进入到刚创建的容器中,并启动一个bash: 可以看到,一个bash终端打开了,在不影响容器内其他应用的前提下,用户可以很容易与容器进行交互。 ,可以通过下面的命令获取: PID=$(docker inspect --format "{ { .State.Pid }}" ) 通过这个PID,就可以连接到这个容器: $ nsenter -
从测试环境中,你可以将Docker镜像推送到服务器上进行部署。 2)开发和拓展更加简单 Docker的以容器为基础的平台允许高度可移植的工作。 如果镜像已经存在,Docker会使用它来创建新的容器。 2)创建新的容器: 当Docker有了这个镜像之后,Docker会用它来创建一个新的容器。 二者有着本质的差别: 1)Private Registry(私有仓库)是开发者或者企业自建的镜像存储库,通常用来保存企业内部的 Docker 镜像,用于内部开发流程和产品的发布、版本控制。 5)简单来说,Mirror类似CDN,本质是官方的cache;Private Registry类似私服,跟官方没什么关系。 2)docker create 可以通过docker run <image name>命令创建一个容器并运行其中的程序,因为有很多用户要求创建容器的时候不启动容器,所以docker create应运而生了
二、管理Docker容器 2.1 启动和停止容器 启动和停止容器是使用 Docker 运行容器时常见的操作。 使用这些命令,你可以方便地控制 Docker 容器的启动和停止。 2.2 查看容器状态 要查看容器的状态,你可以使用 docker ps 命令。这个命令用于列出当前正在运行的容器。 …" 2 hours ago Up 2 hours 3306/tcp my-mysql-container 在这个示例中,docker ps 命令显示了两个容器,一个是运行中的 四、Docker容器的部署与扩展 4.1 Docker Compose Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。 4.2 使用Docker Swarm进行集群部署 Docker Swarm 是 Docker 官方提供的容器编排工具,它允许你将多个 Docker 主机组合成一个虚拟的容器集群,以便于部署、管理和扩展容器化应用程序
Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。其代码目前在 https://github.com/docker/compose 上开源。 我正在学习Docker容器技术,相关笔记汇总在Docker容器技术 学习笔记汇总 基础介绍 Compose is a tool for defining and running multi-container Compose 定位是 “定义和运行多个 Docker 容器的应用(Defining and runningmulti-container Docker applications)”,其前身是开源项目 Define your app’s environment with a Dockerfile so it can be reproduced anywhere. 2. Compose 项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。