Java进阶篇-简单理解Docker容器隔离原理

前言

在开始阅读本篇文章之前,如果您对Docker使用场景和概念并不了解,请先看我这篇博客:通俗易懂的去理解Docker概念

在了解了Docker的概念和基础原理后,那么我们再深入的研究一下Docker的容器隔离功能是通过什么手段去实现的呢?

现在假设我们的一个Java项目中,它同时依赖了Node、Mysql、Redis、RocketMQ等多种框架。那么每个服务打包成容器后,它们之间是否会产生影响?会产生什么样的影响?

Docker容器隔离机制

1.容器之间不相互干扰

上面可以了解到,Redis、Mysql、Node、Java程序等一系列的服务,都是通过Docker打包成了不同的容器,那为什么还需要去做容器隔离呢?原因如下

1. 每个服务之间都可以看到其它服务的进程,也可以随意访问本地的任意文件,基于这种情况下,如果服务器的其中一个服务被入侵,那么其它服务也就都被入侵了。

2.不同容器就是在服务器上的几个不同的特殊进程,进程之间就会存在一种关系:竞争关系。它们会持续消耗服务器资源,若其中一个容器将系统资源占光了,那么其它服务出现连锁反应也就随之宕机。

为了避免以上情况,所以容器之间要有所谓的“边界”,那么Docker是如何让容器之间保持边界的呢?

主要还是利用Linux的两种方式

        2.1 Cgroups

        Linux内核所提供,主要是一个用于为进程分配资源的技术。

        2.2 NameSpace

扫描二维码关注公众号,回复: 14913833 查看本文章

        NameSpace中文直译为命名空间,它就好比模拟了当前容器的运行环境,让当前容器的进程ID始终不变。并且容器只能访问Docker给它挂载的一个虚拟文件系统。这样就实现了容器之间的隔离。

综上所述:NameSpace限制了容器的视野,Cgroup限制了容器的资源

2.虚拟文件系统是什么?

它其实就是服务于容器的独立文件系统,也称“容器镜像”或者更专业的名词:“rootfs”。

它其中包含了一个操作系统所需要的文件配置还有目录。但是注意:它并不包含系统内核。

因为在Linux中,文件和内核是分开存放的。操作系统只有在启动时才会加载内核。这就代表着所有的容器都会共享服务器上操作系统的内核

同时rootfs还解决了一个问题:“可重用性”。

假设一下,现在我们打包了一个包含JavaWeb项目的Centos容器镜像,但是后续需要引入一个Nginx反向代理进行访问,那我们是否要重新整合进行打包容器呢?这时会引入一个新的概念:layer。

3.layer是什么?

layer(层)。它是一个概念性的,我们每次对rootfs进行更改时,都只保留”增量“的内容,而不是重新去打包一个镜像。它同样来自Linux的操作:union file system(联合文件系统)

4.Docker命令扩展

1.docker create <image_id>

解释:为指定的镜像添加一个可读可写层,并构建出一个的容器。

注意:此时容器是未启动的

2.docker start <container_id>

解释:为容器文件系统创建一个新的进程隔离空间。

注意:每个容器只能有一个进程隔离空间.不可多次创建

3.docker run <image_id>

解释:简单的理解为容器启动。

扩展:它与docker start有什么区别呢?其实docker run 是docker create和docker start的结合命令。它会先通过create去利用镜像创建一个容器,然后去运行它。就好比git pull是 fetch和merge的结合命令一样。

4.docker ps

解释:罗列出所有运行中的容器。如果需要看未运行的容器需要使用docker ps -a。

5.docker commit <container_id>

解释:它会将容器中的可读可写层变成一个只读层,这样就把容器转为一个不可变的镜像了

猜你喜欢

转载自blog.csdn.net/qq_33351639/article/details/129197393