掘金 后端 ( ) • 2024-05-14 16:43

序言

近期拜读了孙高飞大佬的《云原生测试实战》,尽管其中涉及不少关于容器的内容,但因自身缺乏相关知识储备,阅读起来颇为费力。然而,考虑到云原生的重要性以及当前主流趋势,我决定深入研究容器技术,于是从Docker开始入门。

容器技术能解决什么问题?

尝试用系统架构的角度解释:我们熟知的两种软件架构方式——传统分层架构和微服务架构。

它们的设计理念、组织结构、部署方式等存在显著差异:

  1. 设计理念:

    • 传统分层架构:  基于传统分层架构的应用通常采用三层结构(展示层、业务逻辑层、数据访问层),各层之间通过明确的接口进行通信和数据交换。
    • 微服务架构:  微服务架构鼓励将应用拆分为一组小型、自治的服务,每个服务专注于单一的业务功能,通过轻量级的通信机制进行交互。
  2. 组织结构:

    • 传统分层架构:  应用通常由单个团队负责开发、部署和维护,各个功能模块在同一代码库中。
    • 微服务架构:  每个微服务通常由一个小团队负责,拥有独立的代码库和部署流程,通过API或消息队列等方式进行通信。
  3. 部署方式:

    • 传统分层架构:  应用通常作为一个整体部署,可能需要停机或者长时间的部署过程。
    • 微服务架构:  微服务可以独立部署,因此可以实现更快速的部署更新,同时具有更好的灵活性和可扩展性。
  4. 可维护性和扩展性:

    • 传统分层架构:  当应用规模增大时,可能面临单体应用难以维护和扩展的问题。
    • 微服务架构:  微服务架构能够更容易实现单个服务的维护和扩展,同时可以根据需求独立扩展不同的服务。
  5. 复杂性和运维成本:

    • 传统分层架构:  管理单体应用的复杂性较低,但随着应用规模增大,可能面临更高的运维成本和管理难度。
    • 微服务架构:  微服务架构可以更好地应对复杂性,但也需要面对分布式系统带来的挑战,如服务发现、治理和监控等。

对于复杂系统而言,微服务架构无疑是较好的选择。以笔者所在公司为例,已采用微服务架构,包含上百个微服务。

那我们设想一个场景:微服务架构,不同人负责不同的子系统,有大量网络调用,1台物理机如果部署上百个微服务,1个服务内存泄漏导致资源被吞噬,其他服务也会挂掉。这个时候怎么办呢?容器就可以很好的解决此类问题。

概括一下,容器技术解决了软件开发和部署中的几个重要问题:

  1. 环境一致性:  容器将应用程序及其依赖项打包在一个独立的运行环境中,确保在不同的开发、测试和生产环境中具有一致的运行环境,避免了由于环境差异导致的问题。
  2. 部署简化:  容器使应用程序的部署变得更加简单和可重复。通过容器,开发人员可以将应用程序、库和其他依赖项一起打包,然后在任何支持容器的环境中轻松部署。
  3. 资源隔离:  容器提供了一种轻量级的虚拟化方式,使不同的应用程序能够在同一台主机上独立运行,彼此之间相互隔离,从而提高了系统的安全性和稳定性。
  4. 扩展性和弹性:  容器化应用程序可以更容易地扩展和缩减,可以根据需求动态调整容器实例的数量,从而更好地适应流量的变化。
  5. 开发效率提升:  容器技术可以提高开发人员的效率,因为他们可以在本地开发和测试应用程序,然后将其部署到生产环境中,而不需要担心环境配置和依赖项管理的问题。

容器和Docker是啥关系呢?

容器是一种轻量级的隔离技术。

Docker可以理解为基于容器技术实现的一个产品,真正将容器技术带火。

虚拟机和容器的区别

虚拟机的虚拟化方案隔离的更彻底,每个虚拟机都拥有独立的内核(即操作系统),容器则专注虚拟化应用没有独立的内核,所有的容器共享宿主机的内核。

理解了这个知识点,这道题应该很容易回答:部署测试中是否可以使用容器进行测试?

答案是否定的,部署测试需要验证在不同的操作系统环境下能否正常运行。即使使用容器运行不同的操作系统,但内核是一样的。

如何理解Dcoker?

  • 基于 Linux 内核的 Cgroup,Namespace等技术,对进程进行封装隔离

  • 最初的实现是基于 Linux 容器(Linux Containers,LXC)技术的。LXC 是一种操作系统级虚拟化技术,它提供了一种轻量级的虚拟化方式,允许在单个 Linux 系统上运行多个相互隔离的 Linux 容器。Docker 最初使用 LXC 来实现容器化,通过 LXC 提供的功能来创建和管理容器。

    从 Docker 0.7 版本开始,Docker 开始逐步去除对 LXC 的依赖,转而使用自行开发的容器运行时工具 Libcontainer。Libcontainer 是一个用 Go 语言编写的库,用于直接管理容器的生命周期、命名空间、cgroups 等方面的功能,它提供了更灵活、更轻量级的容器管理方案,减少了对 LXC 的依赖。

    随着时间的推移,Docker 进一步演进,从 1.11 版本开始,开始使用 runC 和 Containerd。runC 是一个由 Docker 开发的开源项目,它是一个符合 OCI(Open Container Initiative)标准的容器运行时工具,能够以标准化的方式来创建和运行容器。而 Containerd 则是一个守护进程,负责管理容器的生命周期、镜像的存储和分发等核心功能,它是一个轻量级的容器运行时管理工具。

  • Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容 器的创建和维护,使得 Docker 技术比虚拟机技术更为轻便、快捷。

Docker基本使用

我使用虚拟机搭建了centos系统,以下操作都基于centos系统。

下载docker源

wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo

列出docker所有版本

yum list docker-ce --showduplicates

安装指定docker版本

yum install docker-ce-19.03.15 docker-ce-cli-19.03.15 -y

启动docker并设置开机启动

systemctl enable docker && systemctl start docker

配置国内源

cat > /etc/docker/daemon.json << EOF
{
   "registry-mirrors": ["https://mw86j9k8.mirror.aliyuncs.com"]
}
EOF

重新启动

systemctl daemon-reload
systemctl restart docker

验证

docker info

容器操作

启动
docker run 
-it 交互
-d 后台运行
-p 端口映射
-v 磁盘挂载

案例:

先执行下面命令:

uname -a

执行后,看到当前系统处于Linux k8s-master 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

然后,我们执行下面命令:

docker run -it ubuntu bash

再次执行uname -a,发现当前系统处于Linux 5c38b22033a6 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

这条命令到底干了些啥呢?

docker run先看本地有没有ubuntu镜像,如果没有就会执行docker pull ubuntu 从docker镜像仓库拉取镜像,然后执行下面的bash命令(会将ubuntu包解压然后执行bash)

查看容器进程
docker ps  # 列出当前正在运行的容器
docker ps -a  # 列出所有容器的信息,包括正在运行的和已停止的容器
docker ps | grep ubuntu 
停止容器
docker stop <containerid> # containerid通过docker ps查看
启动已终止容器
docker start <containerid> 
查看容器细节
docker inspect <containerid>
进入容器
docker attach <containerid>
拷贝文件至容器内
docker cp file1 <containerid>:/file-to-path

docker命令使用起来应该是比较简单的,可以参照网上文档进行操作,这里不进行详细介绍。

容器标准

  • Open Container Initiative(OCI) • 轻量级开放式管理组织(项目)

  • OCI 主要定义两个规范

    • Runtime Specification

      • 文件系统包如何解压至硬盘,供运行时运行。

    • Image Specification

      • 如何通过构建系统打包,生成镜像清单(Manifest)、文件系统序列化文件、镜像配置。

最后

Docker的实际运用过程中相对较为简易,只需掌握几项主要的指令即可。然而若要深入理解其精髓,仍需具备相关的Linux操作系统的基础知识作为支持。接下来,让我们共同探讨Docker的核心技术吧!