kubernetes Spring Cloud 微服务架构— (3)Kubernetes spring cloud 微服务-Docker 镜像存储机制

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 第 3 章 Docker 镜像存储机制 本章节是对上章节Docker镜像原理理解的巩固,从Linux系统运行基础到OverlayFS存储机制去了解与分析;在底层,镜像是怎样实现存储的;并且会详细说明存储文件的作用。

3.1  Linux 系统运行基础

Linux 系统正常运行, 通常需要两个文件系统:

3.1.1 boot file system (bootfs)

1)包含 Boot LoaderKernel文件,用户不能修改这些文件。并且在系统启动过程完成之后, 整个系统的内核都会被加载进内存。此时bootfs会被卸载, 从而释放出所占用的系统内存。

2)在容器中可以运行不同版本的Linux, 说明对于同样内核版本的不同的 Linux 发行版的bootfs 都是一致的, 否则会无法启动。因此可以推断, Docker运行是需要内核支持的。

3) Linux系统中典型的bootfs目录: (核心) /boot/vmlinuz(核心解压缩所需 RAM Disk)

/boot/initramfs

 

3.1.2 root file system (rootfs)

1) 不同的Linux发行版本, bootfs相同, rootfs不同(二进制文件)

2)每个容器有自己的 rootfs, 它来自不同的Linux 发行版的基础镜像,包括 Ubuntu

Debian SUSE 等。

3)   使用不同的rootfs 就决定了, 在构建镜像的过程中, 可以使用哪些系统的命令。

4)   典型的rootfs 目录: /dev/proc/bin/etc /lib/usr

3.2  OverlayFS 存储原理

OverlayFS 结构分为三个层: LowerDirUpperdirMergedDir

1)LowerDir (只读) 只读的 image layer,其实就是 rootfs, 在使用 Dockfile 构建镜像的时候, Image Layer 可以分很多层,所以对应的 lowerdir 会很多(源镜像)。

2) Upperdir (读写)

upperdir 则是在 lowerdir 之上的一层, 为读写层。容器在启动的时候会创建, 所有对容器的修改, 都是在这层。比如容器启动写入的日志文件,或者是应用程序写入的临时文件。

3)MergedDir (展示)  merged 目录是容器的挂载点,在用户视角能够看到的所有文件,都是从这层展示的。

3.3 分析镜像存储结构

3.3.1 获取镜像存储路径 #通过镜像信息获取到物理存储位置

root@master jdk]# docker image inspect jre8:1.3 
 "Architecture": "amd64", 
 "Os": "linux", 
 "Size": 136406576, 
 "VirtualSize": 136406576, 
 "GraphDriver": { 
     "Data": { 
         "LowerDir": 
"/var/lib/docker/overlay2/ba469a9497fe6894e9022c2cb8b4217cd5aa1d0b35653ccd927a247bff3d2a81/diff:/var/lib/docker/overlay2/785564c2852e5b5b8f53d84ab4350c7aec6cb5a0 f44e457779877f06a95354ad/diff:/var/lib/docker/overlay2/101c2e9852e1b3e4a593f1b4ca8770fdd2b2c4656b3447dc96799527f03767c6/diff:/var/lib/docker/overlay2/fb940d476e39c
51cace728b5d709fff21c5c6421227c7ec7b2c421875767bc26/diff:/var/lib/docker/overlay2/271a364d00b2aabce86f2cb7d6c1abead3e1c8903cdd25e07a901964e3534978/diff",
         "MergedDir": "/var/lib/docker/overlay2/6700cb0c98e3e7af8bdd97d4e40d673e3a0cf0fc6768323e8d4372afde12aff2/merged",
         "UpperDir": "/var/lib/docker/overlay2/6700cb0c98e3e7af8bdd97d4e40d673e3a0cf0fc6768323e8d4372afde12aff2/diff",
         "WorkDir": "/var/lib/docker/overlay2/6700cb0c98e3e7af8bdd97d4e40d673e3a0cf0fc6768323e8d4372afde12aff2/work"
     }, 
     "Name": "overlay2" 
 }, 
 "RootFS": { 
     "Type": "layers", 
     "Layers": [ 
        "sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10",
        "sha256:3219209e108e14824bd77c247110bbdb0e8ab392a016c634b8f031b610673fac",
        "sha256:d5aea7d9c0743772a38d8d81c4f1be709890827bc915465a7048a7d718fbf859",
        "sha256:3ff10a379107fb9e679ac8c001e5edbc4a01ec7b3bd86162e5932aa5ea2f8808",
        "sha256:c86fc31cf85edab6d1b9aa4750656496e0925186c112092ddd0a5909ba4a8b9b",
        "sha256:27d22f85ea93e4cbdf47b565433be94f6ce46f4e822abe6352c0f5b028bd2150"
     ]

 

3.3.2 分析Lower

#LowerDir 层的存储是不允许创建文件, 此时的LowerDir实际上是其他的镜像的UpperDir层,也就是说在构建镜像的时候, 如果发现构建的内容相同, 那么不会重复的构建目录,而是使用其他镜像的Upper 层来作为本镜像的Lower

[root@master jdk]# touch /var/lib/docker/overlay2/ba469a9497fe6894e9022c2cb8b4217cd5aa1d0b35653ccd927a247bff3d2a81/diff/lower.txt


3.3.3 分析Upper层
#在Upper层创建文件

[root@master jdk]# touch /var/lib/docker/overlay2/6700cb0c98e3e7af8bdd97d4e40d673e3a0cf0fc6768323e8d4372afde12aff2/diff/upper.txt

3.4 运行中容器的存储结构

3.4.1 启动容器

#前台启动,直接进入到容器

[root@master jdk]# docker run -it jre8:1.3 bash

3.4.2 查看容器挂在信息

#容器启动以后,挂载mergedlowerdirupperdir以及workdir目录 #lowerdir是只读的image layer,其实就是rootfs

#获取容器 ID

/

[root@master ~]# docker ps 
CONTAINER ID        IMAGE          COMMAND                  CREATED             STATUS              PORTS                  NAMES 
39d421864be6  jre8:1.3 "bash"                  11 seconds ago      Up 10 seconds              agitated_heyrovsky

 

3.4.3 查看容器存储目录信息

#注意在所有的启动容器中会自动添加init目录, 此目录是存放系统的hostname与域名解析文件

[root@master ~]# docker inspect 39d421864be6 
        "GraphDriver": { 
            "Data": { 
                "LowerDir":   "/var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794dinit/diff:/var/lib/docker/overlay2/6700cb0c98e3e7af8bdd97d4e40d673e3a0cf0fc6768323e8d4372afde12aff2/diff:/var/lib/docker/overlay2/ba469a9497fe6 894e9022c2cb8b4217cd5aa1d0b35653ccd927a247bff3d2a81/diff:/var/lib/docker/overlay2/785564c2852e5b5b8f53d84ab4350c7aec6cb5a0f44e4577798 77f06a95354ad/diff:/var/lib/docker/overlay2/101c2e9852e1b3e4a593f1b4ca8770fdd2b2c4656b3447dc96799527f03767c6/diff:/var/lib/docker/overlay2/f b940d476e39c51cace728b5d709fff21c5c6421227c7ec7b2c421875767bc26/diff:/var/lib/docker/overlay2/271a364d00b2aabce86f2cb7d6c1abead3e1c89
03cdd25e07a901964e3534978/diff", 
                "MergedDir": "/var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d/merged", 
                "UpperDir": "/var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d/diff", 
                "WorkDir": "/var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d/work" 
            }, 
            "Name": "overlay2" 
        }, 
        "Mounts": [], 
        "Config": { 
            "Env": [ 
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/java/jdk/jre1.8.0_211/bin",                 "GLIBC_VERSION=2.31-r0", 
                "JAVA_HOME=/usr/java/jdk/jre1.8.0_211" 
            ], 
            "Cmd": [ 
                "bash" 
            ], 
            "Image": "jre8:1.3", 
            "Volumes": null, 
            "WorkingDir": "/opt", 
            "Entrypoint": null, 
            "OnBuild": null, 
            "Labels": {} 
        }, 
    } 
] 

3.5 容器文件存储解析

3.5.1 容器运行时的UpperDir目录结构

[root@master ~]# touch /var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d/diff/c1.txt 
#在进入到操作查看 
bash-4.3# cat /c1.txt 

3.5.1.1 Work 目录

work目录用于联合挂载指定的工作目录,overlay 把文件挂载到 upperdir, work内容会被清空,且在使用过程中(为空)其内容用户不可见。

 

3.5.1.3 用户视角层Merged

#    后给用户展示的层,一般看到为一个完整的操作系统文件系统结构

 

[root@master ~]# ll    /var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d/merged   
total 4 
….省略…… 
-rw-r--r-- 1 root root    0 Mar 14 03:58 lower.txt -rw-r--r-- 1   root root    0 Mar 14 04:03 upper.txt drwxr-xr-x 1 root   root   18 Mar 14 03:10 usr

3.5.2 Lower 层

Lower 包括两个层:

a. 系统的initb.容器的镜像层

Lower 记录父层的链接名称

[root@node-2 ~]# cat /var/lib/docker/overlay2/d4dc057329ecbf5a2f97293b6d49078e9cce6869a9f049ba5bc365f6fba424d2/lower  l/QCXVWDWYPFM5NRVMB2ZC2BE5WU:l/PUSOZBTJKJ2OBNKK2UQDNQLHCU init 层 / 容器镜像层

 

3.5.2.1 查看init层地址指向

#容器在启动的过程中, Lower 会自动挂载init的一些文件

[root@master~]#ls /var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d-init/diff/etc/hostname  hosts mtab  resolv.conf

3.5.2.2 init层主要内容是什么?

init层是以一个uuid+-init结尾表示,放在只读层(Lower)和读写层(upperdir)之间, 作用只是存放/etc/hosts/etc/resolv.conf 等文件,

 

3.4.2.3 为什么需要init层?

1)容器在启动以后, 默认情况下lower层是不能够修改内容的, 但是用户有需求需要修改主机名与域名地址, 那么就需要添加init层中的文件(hostname, resolv.conf), 用于解决此类问题. 2) 修改的内容只对当前的容器生效,而在docker commit提交为镜像时候,并不会将init层提交。

3) init 文件存放的目录为/var/lib/docker/overlay2/<init_id>/diff

 

3.5.2.4 查看init层文件

#hostnameresolv.conf 全部为空文件, 在系统启动以后由系统写入.

 

[root@master ~]# ll   /var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d-init/diff/etc/ 
total 0 
-rwxr-xr-x 1 root root  0 Mar 14 04:09 hostname -rwxr-xr-x 1 root   root  0 Mar 14 04:09 hosts lrwxrwxrwx 1   root root 12 Mar 14 04:09 mtab -> /proc/mounts 
-rwxr-xr-x 1 root   root  0 Mar 14 04:09 resolv.conf

#总结

1)镜像所挂载的目录层为 Lower 层,然后通过 Merged 展示所有的文件目录与文件。用户写入的所有文件都是在 UpperDir 目录,并且会在UpperDir 建立于 Merged 层展示的文件目录结构,所以用户就可以看到写入的文件。并且底层的镜像是不能被修改(如果挂载目录为 UpperDir,则可以修改源镜像)

2)在下次重新启动已经停止的容器的时候, 如果容器的 ID 没有发生改变,那么所写入的文件是存在物理系统中的; 反之就会是一个新的容器,之前手工创建的文件是不存在的。

3)基于容器创建的镜像,就相当于容器的快照, 可以删除原来的容器, 但是不能删除原来的镜像

4) 基于镜像创建的镜像,原来的镜像就是新镜像的low (build), tag 则是没有区别

5) 容器启动以后,镜像就存在于容器的 lower层,所有的写入都是在 upper

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
3天前
|
敏捷开发 监控 数据管理
构建高效微服务架构的五大关键策略
【4月更文挑战第20天】在当今软件开发领域,微服务架构已经成为一种流行的设计模式,它允许开发团队以灵活、可扩展的方式构建应用程序。本文将探讨构建高效微服务架构的五大关键策略,包括服务划分、通信机制、数据管理、安全性考虑以及监控与日志。这些策略对于确保系统的可靠性、可维护性和性能至关重要。
|
4天前
|
安全 Java API
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)(上)
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)
23 0
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)(上)
|
4天前
|
Java API 微服务
【Spring Boot系列】通过OpenAPI规范构建微服务服务接口
【4月更文挑战第5天】通过OpenAPI接口构建Spring Boot服务RestAPI接口
24 0
|
15天前
|
API 数据库 开发者
构建高效可靠的微服务架构:后端开发的新范式
【4月更文挑战第8天】 随着现代软件开发的复杂性日益增加,传统的单体应用架构面临着可扩展性、维护性和敏捷性的挑战。为了解决这些问题,微服务架构应运而生,并迅速成为后端开发领域的一股清流。本文将深入探讨微服务架构的设计原则、实施策略及其带来的优势与挑战,为后端开发者提供一种全新视角,以实现更加灵活、高效和稳定的系统构建。
20 0
|
4天前
|
消息中间件 监控 持续交付
构建高效微服务架构:后端开发的进阶之路
【4月更文挑战第20天】 随着现代软件开发的复杂性日益增加,传统的单体应用已难以满足快速迭代和灵活部署的需求。微服务架构作为一种新兴的分布式系统设计方式,以其独立部署、易于扩展和维护的特点,成为解决这一问题的关键。本文将深入探讨微服务的核心概念、设计原则以及在后端开发实践中如何构建一个高效的微服务架构。我们将从服务划分、通信机制、数据一致性、服务发现与注册等方面入手,提供一系列实用的策略和建议,帮助开发者优化后端系统的性能和可维护性。
|
14天前
|
Kubernetes 安全 Java
构建高效微服务架构:从理论到实践
【4月更文挑战第9天】 在当今快速迭代与竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性及容错性,成为众多企业转型的首选。本文将深入探讨如何从零开始构建一个高效的微服务系统,覆盖从概念理解、设计原则、技术选型到部署维护的各个阶段。通过实际案例分析与最佳实践分享,旨在为后端工程师提供一套全面的微服务构建指南,帮助读者在面对复杂系统设计时能够做出明智的决策,并提升系统的可靠性与维护效率。
|
1天前
|
监控 API 持续交付
构建高效微服务架构:后端开发的新趋势
【4月更文挑战第23天】 随着现代软件开发实践的不断演进,微服务架构已经成为企业追求敏捷、可扩展和弹性解决方案的首选。本文深入探讨了如何构建一个高效的微服务架构,涵盖了关键的设计原则、技术选型以及实践建议。通过分析微服务的独立性、分布式特性和容错机制,我们将揭示如何利用容器化、服务网格和API网关等技术手段,来优化后端系统的可维护性和性能。文章旨在为后端开发人员提供一套全面的指南,以应对不断变化的业务需求和技术挑战。
|
6天前
|
机器学习/深度学习 运维 Prometheus
探索微服务架构下的系统监控策略
【4月更文挑战第18天】在当今快速迭代和持续部署盛行的软件工程实践中,微服务架构因其灵活性和可扩展性受到企业青睐。然而,随着服务的细粒度拆分和网络通信的增加,传统的监控手段已不再适用。本文将探讨在微服务环境中实施有效系统监控的策略,包括日志聚合、性能指标收集、分布式追踪以及异常检测等关键技术实践,旨在为读者提供构建稳定、可靠且易于维护的微服务系统的参考指南。
10 0
|
6天前
|
监控 持续交付 开发者
构建高效微服务架构:后端开发的新趋势
【4月更文挑战第18天】在数字化转型的浪潮中,微服务架构已成为企业提升系统灵活性、加速产品迭代的关键。此文深入探讨了构建高效微服务架构的实践方法,包括服务划分原则、容器化部署、持续集成/持续部署(CI/CD)流程以及监控与日志管理等关键技术点。通过分析具体案例,揭示了微服务在提高开发效率、降低维护成本及促进团队协作方面的显著优势。
|
7天前
|
负载均衡 Java 开发者
细解微服务架构实践:如何使用Spring Cloud进行Java微服务治理
【4月更文挑战第17天】Spring Cloud是Java微服务治理的首选框架,整合了Eureka(服务发现)、Ribbon(客户端负载均衡)、Hystrix(熔断器)、Zuul(API网关)和Config Server(配置中心)。通过Eureka实现服务注册与发现,Ribbon提供负载均衡,Hystrix实现熔断保护,Zuul作为API网关,Config Server集中管理配置。理解并运用Spring Cloud进行微服务治理是现代Java开发者的关键技能。