工程化Docker最佳实践:确保应用程序的可靠性、可扩展性和可维护性

2023年 7月 26日 45.5k 0

引言

Docker是一种虚拟化技术的产品,属于一种 容器。容器是将软件打包成标准化单元,以用于开发、交付和部署。Docker镜像是用来启动容器的,也用来创建新的容器,类似于虚拟机的快照。

每个Docker镜像可以实例化出来多个容器

Docker的作用有很多,比如:提高开发效率、简化部署流程、降低运维成本等等。

为什么需要工程化?

采用工程化的方法来开发和管理Docker应用程序有很多好处。首先,Docker可以将应用程序打包成标准化单元,以用于开发、交付和部署,从而提高了开发效率 。其次,Docker可以简化部署流程,降低了运维成本 。此外,Docker还支持多平台、支持自动化部署、支持微服务架构等等 。

Docker镜像

打包Docker镜像需要Dockerfile,这是构建镜像的必需。

Dockerfile文件包含了构建镜像所需的指令和步骤。在Dockerfile中指定基础镜像、安装依赖项、复制应用程序文件等步骤,最后使用docker build命令来构建镜像。

示例:

# 使用基础镜像
FROM node:14

# 设置工作目录
WORKDIR /usr/src/app

# 复制 package.json 和 package-lock.json 文件到工作目录
COPY package*.json ./

# 安装依赖项
RUN npm install

# 复制应用程序代码到工作目录
COPY . .

# 暴露端口号
EXPOSE 8080

# 启动应用程序
CMD [ "node", "app.js" ]

我们使用了Node.js作为基础镜像,并将应用程序代码复制到了容器中的/usr/src/app目录下。然后,我们使用npm install命令来安装应用程序的依赖项,并使用CMD指令来启动应用程序。最后,我们使用EXPOSE指令来暴露应用程序所使用的端口号

docker build -t myapp:latest .来构建镜像。

其中,myapp是镜像的名称,latest是标签名,.表示Dockerfile所在的当前目录。

如何构建最小化镜像,避免包含不必要的文件

  • 减少镜像层数:在Dockerfile中,一个RUN会在镜像上构建一层,因此需要将多个RUN合并执行,减少镜像层数。
  • 移除不必要的文件:在Dockerfile中,可以使用COPY和ADD指令来复制应用程序代码和依赖项到容器中。在复制之前,需要先判断该文件是否是应用程序所必需的,如果是则复制到容器中,否则不复制。
  • 使用多阶段构建:多阶段构建可以将构建过程分为多个阶段,每个阶段只编译应用程序所需的部分代码,从而减小最终镜像的大小。
  • Docker容器编排

    Docker容器编排是指对Docker容器的配置和管理。

    Docker Compose是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。Compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组,定义和运行多容器的应用,可以一条命令启动多个容器 。我们开源的项目是基于docker-compose来进行管理的,主要优点是方便易用。

    Docker Swarm是Kubernetes的前身之一,是Google开发的一个开源容器编排引擎。Swarm可以将多个Docker主机组成一个集群,对集群中的容器进行管理和编排。

    Kubernetes是一个开源的容器编排平台,可以自动完成在部署、管理和扩展容器化应用过程中涉及的许多手动操作。它是Google 2014年创建管理的,是Google 10多年大规模容器管理技术Borg的开源版本 。

    Kubernetes可以实现容器集群的自动化部署、自动扩缩容、维护等功能。它可以将运行Linux容器的多组主机聚集在一起,由Kubernetes帮助您轻松高效地管理这些集群。
    Kubernetes集群可跨本地、公共云、私有云或混合云部署主机。因此,对于要求快速扩展的云原生应用而言(例如借助Apache Kafka进行的实时数据流处理),Kubernetes是理想的托管平台 。

    容器网络配置

    Docker容器网络配置有以下几种模式:

  • Bridge模式:这是默认的网络模式,它将容器连接到一个虚拟的bridge网络上,该网络由宿主机上的docker0桥接器创建。这种模式下,容器之间可以直接通信,但是无法访问外部网络。

  • Host模式:在这种模式下,容器共享宿主机的网络栈,可以使用宿主机的IP地址和端口号。这种模式下,容器可以直接访问外部网络。

  • Overlay模式:这种模式下,Docker使用Linux内核中的overlay协议来创建容器网络。这种模式下,容器之间的通信需要通过overlay网络进行,因此可以实现更高效的网络通信。

  • Macvlan模式:这种模式下,Docker使用Macvlan驱动程序来创建虚拟网卡,并将其绑定到指定的物理网卡上。这种模式下,容器可以直接访问外部网络。

  • None模式:这种模式下,容器没有自己的网络接口,也不能访问外部网络。如果需要访问外部网络,必须使用其他容器作为代理 。

  • 我们开源项目目前的网络模式是bridge模式。预先新建一个docker网络。提供给compose内所有容器使用。在容器之间是可以直接通信的。

    docker network create  --subnet=1.1.38.0/24 \
    --ip-range=1.1.38.0/24 \
    --gateway=1.1.38.254 \
    docker_netaxe
    

    在compose中,引入预先创建的docker网络,并配置external:true

    external是Docker网络模式之一,它允许容器使用宿主机的网络堆栈,从而可以直接访问外部网络。在external模式下,Docker会为容器创建一个虚拟网卡,并将其绑定到宿主机的一个网络接口上。这样,容器就可以直接使用该网络接口来发送和接收数据包,从而实现与外部网络的通信。这并不是必须的。

    存储管理

    Docker卷是Docker容器生产和使用持久化数据的首选机制。与绑定挂载相比,卷更容易备份或迁移。您可以使用Docker CLI命令或Docker API来管理卷。在Linux和Windows容器上都可以使用卷,而且可以更安全地在多个容器之间共享。 目前我们Kubernetes上的容器存储都是采用绑定数据挂载的。相比较单机而言,Kubernetes是集群部署的,数据挂载也是在专用的数据盘,会更安全更稳定。

    要使用Docker卷或持久化存储来管理应用程序的数据,您需要执行以下步骤:

  • 创建一个Docker卷。您可以使用docker volume create命令来创建一个新的卷。例如,要创建一个名为mydata的卷,您可以运行以下命令:

    docker volume create mydata
    
  • 将Docker卷挂载到容器中。您可以使用-v选项将卷挂载到容器中。例如,要将名为mydata的卷挂载到名为/app/data的目录中,您可以运行以下命令:

    docker run -v mydata:/app/data myimage
    
  • 在容器中访问数据。现在,您可以在容器中访问/app/data目录中的数据了。

  • 或直接在docker-compose.yml文件中指定绑定卷

  • volumes:
              - ./victoriametrics:/victoriametrics
    

    当前也可以定期备份数据、使用加密存储等手段。

    日志和监控

    使用Docker日志和监控工具来追踪应用程序的运行情况,并及时发现和解决问题。

    基础用法

    将容器内部的app日志映射到宿主机,排查故障时候可以直接在宿主机进行日志信息查询。

    高级用法

    将docker容器的日志打到日志组件,并在grafana或者kibana上进行日志可视化展示

    docker容器可以配置日志驱动,--log-driver=logstash或者--log-driver=loki

    安全性考虑

    Docker容器的安全性主要包括以下几个方面:

  • 容器漏洞管理:选择信任的基础镜像,定期更新镜像以获取最新的安全补丁,避免使用未经验证的第三方镜像。借助安全扫描工具,对容器镜像进行漏洞扫描和分析,及时发现并修复潜在的安全风险 。

  • 容器权限管理:确保容器运行所需的权限,避免不必要的权限开放。例如,如果您只需要读取某个目录下的文件,则不要将该目录设置为可写。

  • 容器网络隔离:使用隔离网络来隔离容器之间的通信,避免恶意攻击者通过网络渗透到您的系统。

  • 容器日志管理:记录容器的日志信息,并对其进行监控和分析。这有助于及时发现异常情况并采取相应措施。

  • 容器安全扫描工具:使用容器安全扫描工具对容器进行全面扫描,及时发现并修复潜在的安全风险 。

  • 限制容器访问

  • 仅在容器中运行必要的服务,像ssh等服务绝对不能开启。
  • Docker远程API访问控制,至少应该限制外网访问。
  • 限制流量流向,使用iptables过滤器显示docker容器的源IP地址范围和外界通信。
  • 使用普通用户启动Docker。
  • 使用安全的镜像源

  • 使用官方镜像源。
  • 使用第三方镜像源时,应该选择可信的镜像源,并定期更新镜像以获取最新的安全补丁。
  • 持续集成与交付(CI/CD)

    Docker和CI/CD工具结合使用可以实现自动化的构建、测试和部署应用程序,提高开发效率和软件交付质量。以下是使用Docker进行CI/CD的一般步骤:

  • 准备Docker镜像:在CI环境中,可以使用Docker镜像来构建和测试应用程序。首先,根据项目的要求选择合适的基础镜像,例如包含特定编程语言和工具的镜像。然后,编写Dockerfile文件,该文件定义了如何构建应用程序的容器。最后,使用docker build命令构建Docker镜像。

  • 注册Runner服务器:为项目注册执行部署任务的Runner服务器。

  • 提交更新,自动部署:提交代码到git master分支,等待Job任务完成。

  • 测试结果:查看测试结果并进行必要的调整。

  • 总结

    本文介绍了在使用Docker进行应用程序开发和部署时采用一系列工程化的最佳实践。通过使用Dockerfile、多阶段构建、容器编排工具、持久化存储和健康检查等技术,可以确保应用程序的可靠性、可扩展性和可维护性 。

    这些最佳实践包括:

    • 使用Dockerfile来定义应用程序的构建过程。
    • 使用多阶段构建来减小镜像大小并提高构建速度。
    • 使用容器编排工具来管理容器集群。
    • 使用持久化存储来保存数据,以便在容器重启后仍然可用。
    • 使用健康检查来检测容器是否正常运行。

    最后:检验真理最佳的途径是实践,鼓励大家在实践中不断尝试不断学习新的技术,来提高应用程序稳定和可靠性。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论