[k8s理论知识]2.docker基础(一)

发布于:2024-10-18 ⋅ 阅读:(10) ⋅ 点赞:(0)

PaaS项目被广泛接受的原因是他们提供了一种应用托管的能力。在PaaS出现之前,虚拟机和云计算已经是很普遍的技术和服务。主流做法是租用一批AWS或openstack的虚拟机,然后像管理物理服务器一样,通过脚本或手工方式在这些虚拟机上部署应用。然而,这种部署方式通常会遇到云端虚拟机和本地环境不一致的问题,导致部署过程复杂且容易出错。

因此,当时云计算服务的核心竞争在于谁能更好的模拟本地服务器环境,提供更好的“上云”体验。PaaS项目的出现解决了这一问题。CloudFundary就是一个典型的PaaS项目,他通过以下方式简化了应用的部署和管理:

1.应用打包分发机制

cloudFundary为每种主流的编程语言定义了一种打包格式。开发者通过cf push命令将本地应用的可执行文件和启动文件一起打成压缩包文件,并上传到cloud Fundary存储中。

2.自动化部署和管理

3.应用隔离

为了在一个虚拟机上同时运行多个来自不同用户的应用,Cloud Foundry 利用操作系统的 Cgroups 和 Namespace 机制为每个应用创建一个“沙盒”环境。

以CloudFundary为事实标准的PaaS平台的缺点很明显,用户必须为每种语言、每种框架,甚至每个版本的应用维护一个打好的包,而且打包过程没有统一的标准,每次都需要重新配置和调试。本地运行良好的PaaS上可能需要大量的修改和配置才能运行,这增加了用户的负担。

Docker的优势

Docker项目的镜像解决了这个根本性的问题。Docker镜像本质上是一个压缩包,但他的内容比PaaS的应用可执行文件+启停脚本的组合要丰富的多。

docker的镜像包含完整的操作系统:大多数Docker镜像是由一个完整的操作系统的所有文件和目录构成的,这意味着镜像中的环境和本地开发测试环境完全一致。

dockerfile提供了一套标准化的打包和分发机制,用户可以使用dockerfile来定义镜像的构建过程,确保每一次构建镜像都是一致的。

当打包docker镜像的时候一般会包含一个基本镜像,比如python镜像或者ubuntu镜像。假设你的应用在本地运行的时候依赖centos 7.2的操作系统,那么可以使用centos 7.2的iso镜像来创建一个docker镜像:

FROM centos:7.2
COPY myapp /usr/local/bin/myapp
CMD ["myapp"]

而如果这个centos 系统需要预装某些软件,如python,那么这里的镜像将包含 Python 镜像的基础文件系统和预装的 Python 环境。

FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 复制应用文件
COPY . /app
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 设置默认命令
CMD ["python", "app.py"]

以上例子指定基础镜像为 python:3.9-slim,这是一个基于 Debian 的轻量级镜像,预装了 Python 3.9。

如果像从基础的操作系统镜像预装某些软件,也可以如下操作,这个和上面是等价的。

FROM ubuntu:20.04
# 更新包列表并安装 Python
RUN apt-get update && \
    apt-get install -y python3 python3-pip && \
    rm -rf /var/lib/apt/lists/*
# 设置工作目录
WORKDIR /app
# 复制应用文件
COPY . /app
# 安装依赖
RUN pip3 install --no-cache-dir -r requirements.txt
# 设置默认命令
CMD ["python3", "app.py"]

所以总结来说,Docker 项目给 PaaS 世界带来的“降维打击”主要是通过提供一种非常便利的打包机制。这种机制直接打包了应用运行所需要的整个操作系统,从而保证了本地环境和云端环境的高度一致,避免了用户通过“试错”来匹配两种不同运行环境之间差异的痛苦过程。

Docker镜像包含了一个完整的操作系统的文件系统,确保了本地和云端环境的高度一致性。开发者不再需要为每种语言、版本和框架的应用维护复杂的打包流程,大大简化了应用的部署过程,这一创新极大的提升了开发者的生产能力。一些机敏的创业公司看到了这一个机会,纷纷推出了基于Docker的容器集群开源管理项目,这些项目通常被称为CaaS,以区别于传统的PaaS。

尽管Docker解决了这些应用打包难的问题,但是它并不能代替PaaS在大规模部署应用方面的职责。只有能为用户提供平台层能力的工具,才是开发者真正愿意付费的产品。因此,Docker 项目作为一个只能用来创建和启停容器的小工具,最终只能充当这些平台项目的“幕后英雄”。为了应对这一挑战,Docker 公司在 DockerCon 上发布了自家的“Docker 原生”容器集群管理项目 Swarm。

Docker向PaaS发展

CoreOS作为一个基础设施领域的创业公司,其核心产品是一个定制化的操作系统,允许用户以分布式集群的方式管理节点。从而简化应用的部署和管理。Docker项目发布后,CoreOS很快认识到容器概念可以无缝的集成到它的方案中,提供更高的PaaS能力,因而成为了Docker项目的主要贡献者。

然而2014年,Docker想要向PaaS发展,因而发布了docker swarm,并且与CoreOS停止了合作。相比于依赖一系列开源项目的CoreOS,使用了swarm的docker项目无缝的集成了docker 容器本身的API,操作更加简单。

docker compose

编排在云计算行业中并不新鲜,他主要指用户通过某些工具或配置来完成一组虚拟机以及关联的资源的定义、配置、创建和删除等工作,然后由云计算平台按照这些指定的逻辑来完成。在容器时代,编排特指对docker容器的一系列定义、配置和创建动作的管理。

Fig是一个容器编排的项目,假设用户需要部署的应用包括应用容器 A、数据库容器 B 和负载均衡容器 C,Fig 允许用户将这些容器定义在一个配置文件中,并指定它们之间的关联关系,例如容器 A 需要访问数据库容器 B。更重要的是,用户还可以在Fig的配置文件中定义各种容器的副本个数等编排参数,结合docker swarm的集群管理能力,Fig实现了一个强大的PaaS平台,能够管理和扩展多个容器。

Fig 项目后来被 Docker 公司收购,并改名为 Docker Compose。Docker Compose 成为了 Docker 公司第二受欢迎的项目,至今仍被广泛使用。它通过一个 YAML 配置文件(通常是 docker-compose.yml)来定义和管理多个容器及其之间的关系,极大地简化了多容器应用的部署和管理。

假设你有一个简单的应用,包含一个 Web 应用(A)、一个数据库(B)和一个负载均衡器(C)。你可以在 docker-compose.yml 文件中定义这些服务及其关系:

version: '3'

services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    depends_on:
      - app
    networks:
      - app-network

  app:
    image: myapp:latest
    environment:
      - DATABASE_HOST=db
    networks:
      - app-network

  db:
    image: postgres:latest
    environment:
      - POSTGRES_DB=mydb
      - POSTGRES_USER=myuser
      - POSTGRES_PASSWORD=mypassword
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - app-network

  lb:
    image: haproxy:latest
    ports:
      - "8080:80"
    depends_on:
      - web
    networks:
      - app-network

volumes:
  db-data:

networks:
  app-network:
    driver: bridge
Mesos

出了Docker以外,另一个PaaS的竞争者是老牌集群管理项目Mesos。对于 Mesos 来说,其天生的两层调度机制使其能够轻松从大数据领域转向支持更广泛的 PaaS 业务。在这种背景下,Mesosphere 公司发布了名为 Marathon 的项目,迅速成为 Docker Swarm 的有力竞争对手。尽管 Marathon 不能提供像 Swarm 那样的原生 Docker API,但 Mesos 社区在超大规模集群管理方面拥有独特优势。早在几年前,Mesos 就已通过万台节点的验证,并在 eBay 等大型互联网公司的生产环境中广泛应用。

所以,在这波容器化浪潮中,最后只剩下Docker和Mesos竞争,而CoreOS公司在和Docker停止合作后推出了自己的容器rkt,仍未挽回颓势,RedHat作为早期Docker项目的主要贡献者之一因为对Docker的平台化战略不满而退出。

Docker与k8s的竞争

在推出swarm和compose后,docker在容器领域一家独大,这引起了行业的不满。Google公司向Docker公司提议,共同推进一个中立的容器运行时项目,作为Docker容器的核心依赖。但是Docker公司不仅没有接受这一提议,还在不久之后发布了自己的容器运行时库:libcontainer。但是libcontainer可读性差而且可维护性不强,让用户叫苦不迭。

在这个基础上,容器领域的其他玩家开始切割Docker的话语权,成立了一个中立的基金会CNCF(cloud native computing fundation),Docker把libcontainer捐出来,改名为runC,然后大家以runc为依据,共同制定一套容器和镜像的标准和规范。这套标准和规范,就是 OCI( Open Container Initiative )。OCI 的提出,意在将容器运行时和镜像的实现从 Docker 项目中完全剥离出来。这样做,一方面可以改善 Docker 公司在容器技术上一家独大的现状,另一方面也为其他玩家不依赖于 Docker 项目构建各自的平台层能力提供了可能。

k8s的优势

容器编排领域,Kubernetes 项目面临来自 Docker 公司的 Swarm 和 Mesos 社区的双重压力。Swarm 擅长与 Docker 生态的无缝集成,而 Mesos 擅长大规模集群的调度与管理。为了在竞争中脱颖而出,Kubernetes 项目选择了与众不同的策略:借鉴 Google 内部的 Borg 系统。pod概念和sidecar模式是k8s的核心特性与设计模式。

K8s中的最小调度单位是pod,一个pod可以包含多个容器,这些容器共享网络和存储资源,这些使得复杂的应用管理更加灵活和高效。sidecar模式允许在一个Pod中添加辅助容器,例如日志收集或监控代理,这些辅助容器可以和主容器紧密协作,而不影响主容器的运行。

为了确保 CNCF 社区能够覆盖足够多的场景,CNCF 以 Kubernetes 项目为核心,逐步纳入了一系列关键的容器生态工具和项目。这不仅增强了 Kubernetes 的生态系统,还为用户提供了一个全面的云原生技术栈。比如k8s加入了Prometheus,istio等著名的插件,并且在各个模块都预留了很多的接口,供用户自主开发或接入插件。

Docker的应对

面对这样的态势,Docker公司在2016年宣布将swam内置到docker当中,这无疑扩大了Docker作为一个内置编排、集群管理和负载均衡的完整PaaS项目的技术难度和维护难度,但是这也最大化了swam的竞争优势,就是和Docker无缝集成。

Docker的妥协

2017 年,Docker 公司将 Docker 项目的容器运行时部分 Containerd 捐赠给 CNCF 社区,标志着 Docker 项目已经全面升级成为一个 PaaS 平台;紧接着,Docker 公司宣布将 Docker 项目改名为 Moby,然后交给社区自行维护,而 Docker 公司的商业产品将占有 Docker 这个注册商标。最后,Docker公司在自己的Docker企业版中内置K8s,从而彻底让出容器编排的市场。