Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >从 ”以应用为中心“ 的交付看DevOps平台的演进趋势

从 ”以应用为中心“ 的交付看DevOps平台的演进趋势

作者头像
DevOps在路上
发布于 2025-06-09 13:22:04
发布于 2025-06-09 13:22:04
7700
代码可运行
举报
文章被收录于专栏:DevOps实践之路DevOps实践之路
运行总次数:0
代码可运行

引子-从传统的安装包到云原生时代的应用

过去,在传统的通过shell命令行部署的时代,开发者们习惯于按照面向过程的方式一步步通过代码编译构建打包,然后把安装包远程部署到环境上,安装包就是安装包,环境就是环境,部署脚本就是部署脚本。

随着k8s云原生DevOps的普及,一种新的实践形式“应用” 脱颖而出,它的具体表现是通过一组声明式资源配置(Deployment、Service、ConfigMap 等)定义的容器化服务,可伸缩,可观测,通过GitOps直接从“代码”到“可运行的服务”。

在持续交付中,“应用”是最终要交付给用户的功能性实体,可以是单体应用(Monolithic Application)、云原生应用(Cloud-Native Application)、移动应用,这些仅仅是技术架构层面的解释,那么对于研发生命周期而言,应用又会带来什么不同的价值呢?

本篇文章将带大家从“研发生命周期”和“DevOps平台建设”的角度,诠释“应用新的含义”。

以“应用为中心”-建立“管理过程”和“研发过程”的纽带

如下图,这是一个很典型的产品版本需求迭代,到部署发布的简单示意图。

接着下面的图,当代码提交入库,触发Pipeline,最终形成一个可部署运行的应用服务。

这里我们思考几个问题

  1. 1. 从“产品(需求)” 到“服务应用”之间是什么关系?前者是业务,后者是技术,从业务到技术实现如何表达?
  2. 2. 将”一个市场需求“,快速的实现并且上线,需要多少个步骤?需要几个代码库的变更?涉及哪几个安装包/镜像?又有几个流水线需要编排?
  3. 3. 在复杂且冗长的工具链编排中,如何精准的定位追溯每一次变更,快速的试错和回滚?

看到这里,可能你会习以为常,我们平时就是这样做的,有什么问题?

从“面向过程”到“面向对象”,用“声明方式”描述“产品骨架”

如下图,和上面的图进行对比,是不是有点“面向对象”的感觉?

对照上面的图,再看看下面的术语解释,仔细琢磨下

  1. 1. 产品:提供用户价值(即组织发布活动)的独立单元,是由独立的产、研、测共同维护的功能和服务的集合。
  2. 2. 应用:对应一个可独立运行、发布的线上服务叫做应用,是软件交付和运维的最小单元。应用对应某一个代码库,对应部署发布的应用。
  3. 3. 版本:版本是产品的基础属性,产品每一次发布(可能涉及多个开发团队多个应用),产生该产品(系列需求)的一个新版本(结果)。新版本制作过程包含产研全生命周期。

云原生应用

基于上面的图,AI帮忙编写了对应的配置声明,帮助大家理解(片段有点长, 可以快速跳过)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# ================================================
# 应用部署模板 - Kubernetes 云原生服务编排示例
# 对应架构图左侧「代码库」「制品/镜像」「配置信息」与右侧「部署环境」
# ================================================

---
# 部署环境定义(对应架构图右侧「dev/uat/prod」)
# 使用命名空间隔离不同环境(此处以prod为例)
apiVersion: v1
kind: Namespace
metadata:
  name: prod
  labels:
    env: production

---
# ------------------------------------------------
# 核心部署配置(对应架构图左侧「制品/镜像」+「配置信息」)
# ------------------------------------------------

# 配置信息(ConfigMap对应架构图左侧「配置信息」模块)
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: prod  # 绑定prod环境命名空间
data:
  app.properties: |
    # 应用运行时配置
    db.host=mysql.prod.svc.cluster.local
    cache.enabled=true
    log.level=INFO

---
# 敏感信息配置(Secret属于特殊类型的配置信息)
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
  namespace: prod
type: Opaque
data:
  username: YWRtaW4=  # admin base64编码
  password: cGFzc3dvcmQxMjM=  # password123 base64编码

---
# ------------------------------------------------
# 服务编排核心定义(对应架构图下方「服务编排(云原生)」模块)
# ------------------------------------------------

# 部署控制器(Deployment实现滚动更新策略)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment  # 部署版本标识
  namespace: prod
  labels:
    app: myapp
    track: stable  # 部署策略标识
spec:
  replicas:   # 初始副本数
  strategy:
    type: RollingUpdate  # 部署策略-滚动更新
    rollingUpdate:
      maxSurge: 
      maxUnavailable: 
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
        env: prod
    spec:
      containers:
      - name: app-container
        image: registry.example.com/myapp:v1.2.3  # 制品/镜像(来自CI/CD流水线构建)
        imagePullPolicy: Always
        ports:
        - containerPort: 
        env:
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: db.host
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: username
        resources:
          requests:
            cpu: "100m"
            memory: "256Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
        livenessProbe:  # 健康检查(可观测性)
          httpGet:
            path: /health
            port: 
          initialDelaySeconds: 
          periodSeconds: 

---
# 服务暴露(Service实现服务发现)
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
  namespace: prod
spec:
  type: ClusterIP  # 生产环境建议使用LoadBalancer
  selector:
    app: myapp
  ports:
  - name: http
    port: 
    targetPort: 
    protocol: TCP

---
# ------------------------------------------------
# 弹性伸缩策略(对应架构图「部署策略」模块)
# ------------------------------------------------
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
  namespace: prod
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp-deployment
  minReplicas: 
  maxReplicas: 
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 

# ================================================
# 部署执行说明:
# 1. 代码库变更触发CI/CD流水线构建镜像(更新image版本)
# 2. 通过kubectl apply -f 应用部署模板文件.yaml
# 3. 监控部署状态:kubectl -n prod get pods,svc,hpa
# ================================================

传统主机部署应用

上面说的是k8s应用,那么传统安装包主机部署呢?怎么通过应用表达?

通过 YAML 定义主机环境、应用包版本和全局配置(对应图中「制品/镜像」「配置信息」模块)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# File: infrastructure.yaml
# 定义主机环境、应用包版本等基础设施信息
environments:
  - name: dev
    hosts:
      - ip: 192.168.1.101
        user: dev-user
        deploy_dir: /opt/apps/dev
    app_version: 1.0.0-SNAPSHOT

  - name: prod
    hosts:
      - ip: 192.168.1.200
        user: prod-admin
        deploy_dir: /opt/apps/prod
    app_version: 1.0.0-RELEASE

# 全局配置模板(与环境解耦)
global_config:
  app_name: "my-spring-boot-app"
  java_opts: "-Xmx512m -Xms256m"
  health_check_url: "/actuator/health"

每个环境(dev/prod)独立维护敏感配置(对应图中「配置信息」与「部署环境」分离)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# File: config/prod.env
# 生产环境数据库配置(敏感信息单独管理)
DB_HOST=mysql.prod.internal
DB_PORT=3306
DB_USER=admin
DB_PASSWORD=encrypted_password_here  # 建议使用加密工具(如Ansible Vault)

# File: config/dev.env
# 开发环境数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_USER=dev
DB_PASSWORD=dev123

通过 Shell 脚本实现自动化部署(对应图中「部署脚本」模块)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/bin/bash
# File: deploy.sh
# 参数化部署:指定环境(dev/prod)和应用包路径
ENV=$1
APP_PACKAGE=$2

# 加载基础设施定义
INFRA_FILE="infrastructure.yaml"
APP_NAME=$(yq eval '.global_config.app_name' $INFRA_FILE)
DEPLOY_DIR=$(yq eval ".environments[] | select(.name == \"$ENV\").hosts[0].deploy_dir" $INFRA_FILE)
REMOTE_USER=$(yq eval ".environments[] | select(.name == \"$ENV\").hosts[0].user" $INFRA_FILE)
REMOTE_IP=$(yq eval ".environments[] | select(.name == \"$ENV\").hosts[0].ip" $INFRA_FILE)

# 加载环境配置
CONFIG_FILE="config/$ENV.env"
source $CONFIG_FILE

# 生成动态应用配置(模板化)
cat > application.properties <<EOF
# Auto-generated configuration for $ENV
spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/${APP_NAME}_${ENV}
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASSWORD}
server.port=8080
EOF

# 执行部署动作
echo "Deploying $APP_NAME ($ENV) to $REMOTE_IP..."
ssh $REMOTE_USER@$REMOTE_IP "mkdir -p $DEPLOY_DIR && systemctl stop $APP_NAME"
scp $APP_PACKAGE $REMOTE_USER@$REMOTE_IP:$DEPLOY_DIR/
scp application.properties $REMOTE_USER@$REMOTE_IP:$DEPLOY_DIR/config/

# 启动服务(假设已配置systemd服务单元)
ssh $REMOTE_USER@$REMOTE_IP "\
  chmod +x $DEPLOY_DIR/$(basename $APP_PACKAGE) && \
  systemctl daemon-reload && \
  systemctl start $APP_NAME && \
  systemctl status $APP_NAME"

通过模板定义应用服务管理(对应「基础设施即代码」)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# File: templates/my-spring-boot-app.service.j2
# Systemd 服务单元模板(由部署脚本动态生成)
[Unit]
Description={{ global_config.app_name }} ({{ env }})
After=network.target

[Service]
User={{ user }}
WorkingDirectory={{ deploy_dir }}
ExecStart=/usr/bin/java {{ global_config.java_opts }} -jar {{ deploy_dir }}/{{ app_package }}
EnvironmentFile={{ deploy_dir }}/config/application.properties
Restart=always

[Install]
WantedBy=multi-user.target

根据环境参数执行相同脚本部署不同的包

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 部署到生产环境
./deploy.sh prod my-app-1.0.0-RELEASE.jar

# 部署到开发环境
./deploy.sh dev my-app-1.0.0-SNAPSHOT.jar

从“应用为中心“看DevOps平台演进的趋势

通过上面对于”应用“在研发生命周期的桥梁作用,再到具体的技术实践,作为DevOps平台或者体系的搭建者,我总结了以下几点趋势:

  1. 1. 越来越多的平台开始通过“应用”来进行“构建编排流程的封装”,从“面向过程”到“面向对象”,通过更简单的声明,屏蔽底层工具和步骤的复杂性,帮助产品更快交付。
  1. 2. DevOps平台的建设从开始的“工具统一”到代码“工程化统一”(应用),最终会向到“研发流程标准化”演进,将更多的研发规范,最佳实践等标准化要求变成“企业的研发模版”。开发者只用专注于业务代码本身,规范和要求在潜移默化中被遵守。
  2. 3. 对于持续交付而言,逐步的从”面向过程“(1.0-脚本编排) 到”面向对象“(2.0-应用配置声明),再到 ”面向业务流程“ (3.0-研发标准流程模版化),这个是必然趋势。特别是在AI时代,更快的代码交付,对于工程化,基础设施,标准规范的快速切实执行提出了更高的要求。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DevOps在路上 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Tekton 与 Argo CD 结合实现 GitOps
前面我们使用 Tekton 完成了应用的 CI/CD 流程,但是 CD 是在 Tekton 的任务中去完成的,现在我们使用 GitOps 的方式来改造我们的流水线,将 CD 部分使用 Argo CD 来完成。
DevOps云学堂
2021/07/15
2.6K0
Tekton 与 Argo CD 结合实现 GitOps
​DevOps - 从渐进式交付说起(含实践 Demo)
如果让你主导一款千万、甚至亿级用户产品的功能迭代,你会怎么做?你需要面对的挑战可能来自于:
腾讯云 CODING
2020/06/04
1.2K0
​DevOps - 从渐进式交付说起(含实践 Demo)
基于Jenkins+Argocd+Argo Rollouts的DevOps实现并用金丝雀发布
本文主要介绍使用Jenkins配合argocd以及argo rollouts实现CI/CD。其中jenkins配合argocd做CI/CD前面已经介绍过了,这里不再赘述,不懂的地方可以移步《使用Jenkins和Argocd实现CI/CD》。
没有故事的陈师傅
2021/01/04
4.8K1
基于Jenkins+Argocd+Argo Rollouts的DevOps实现并用金丝雀发布
基于 KubeVela 的 GitOps 交付
KubeVela 作为一个简单、易用、且高可扩展的云原生应用管理工具,能让开发人员方便快捷地在 Kubernetes 上定义与交付现代微服务应用,无需了解任何 Kubernetes 基础设施相关的细节。
CNCF
2021/10/13
6830
云实验室(22) - kubesphere的springboot流水线
docker仓库 : dockerhub / 私有镜像仓库 前端代码仓库 : git / gitlab / gitee ...
惊羽-布壳儿
2022/06/15
9300
云实验室(22) - kubesphere的springboot流水线
云实验室(21) - kubesphere的vue流水线
docker仓库 : dockerhub / 私有镜像仓库 前端代码仓库 : git / gitlab / gitee ...
惊羽-布壳儿
2022/06/15
1.3K0
云实验室(21) - kubesphere的vue流水线
jenkins X实践系列(1) —— 背景知识
Jenkins X 是一个高度集成化的CI/CD平台,基于Jenkins和Kubernetes实现,旨在解决微服务体系架构下的云原生应用的持续交付的问题,简化整个云原生应用的开发、运行和部署过程。
JadePeng
2018/11/21
2.7K0
云计算运维kubernetes集群里集成Apollo配置中心
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
王先森sec
2023/04/24
1.4K0
云计算运维kubernetes集群里集成Apollo配置中心
基于gitlab ci构建devops平台
devops的概念很多,理解也很多。我的理解,它属于软件工程范畴。它定义了一种理念,基于这种理念,能够快速的开发,交付软件及成果物。各个团队直接在这个体系中,高效的沟通,协作等。
暮雨
2018/10/11
4.7K2
基于gitlab ci构建devops平台
使用 GitLab CI 与 Argo CD 进行 GitOps 实践
在现在的云原生世界里面 GitOps 不断的被提及,这种持续交付的模式越来越受到了大家的青睐,在网上也可以找到很多关于它的资源,但是关于 GitOps 相关的工作流实践的示例却并不多见,我们这里就将详细介绍一个使用示例,希望对大家实践 GitOps 有所帮助。
我是阳明
2020/07/17
6K0
使用 GitLab CI 与 Argo CD 进行 GitOps 实践
使用 VictoriaMetrics 监控 K8s 集群
过去几年,Kubernetes 已经成为容器编排的标准,越来越多的公司开始在生产系统使用 Kubernetes。通常我们使用 Prometheus 对 K8S 集群进行监控,但由于 Prometheus 自身单点的问题。不得不寻求一些联邦方案或者分布式高可用方案,社区热度比较高的项目有 Thanos,Cortex,VictoriaMetrics。本文就介绍使用 VictoriaMetrics 作为数据存储后端对 K8S 集群进行监控,k8s 部署不再具体描述。
米开朗基杨
2021/06/09
3.2K0
使用 VictoriaMetrics 监控 K8s 集群
以应用为中心:开放应用模型(OAM)初探
不久前,Kubernetes 也迎来了他 6 岁的生日,在这 6 年中,从孵化之初的三足鼎立,到后来的一统天下,Kubernetes 成为容器编排领域的事实标准已经有段时间了。在这期间,云原生的概念开始深入人心,越来越的公司组织和开发者开始接受、了解、实践云原生。如今,已有无数的应用以容器的形式运行在各种版本 Kubernetes 中了。
郭旭东
2020/12/30
2.2K0
以应用为中心:开放应用模型(OAM)初探
Tekton系列之实践篇-由Jenkins改成Tekton
整体的Jenkinsfile我做了一些删减,但是整个流程是没变的,咋一看是不是同样很简单?我将步骤整理如下:
没有故事的陈师傅
2022/04/05
1K0
Tekton系列之实践篇-由Jenkins改成Tekton
《前端运维》五、k8s--4机密信息存储与统一管理服务环境变量
  Secret 是 Kubernetes 内的一种资源类型,可以用它来存放一些机密信息(密码,token,密钥等)。信息被存入后,我们可以使用挂载卷的方式挂载进我们的 Pod 内。当然也可以存放docker私有镜像库的登录名和密码,用于拉取私有镜像。
zaking
2022/05/10
7260
Kubesphere DevOps组件 创建CI/CD流水线
DevOps 提供一系列持续集成 (CI) 和持续交付 (CD) 工具,可以使 IT 和软件开发团队之间的流程实现自动化。在 CI/CD 工作流中,每次集成都通过自动化构建来验证,包括编码、发布和测试,从而帮助开发者提前发现集成错误,团队也可以快速、安全、可靠地将内部软件交付到生产环境。
全栈研发知识库
2025/01/21
3590
厉害了!全CI/CD工具链的实现 | 基于OCP离线: Openshift3.9学习系列第五篇
干货巨献:Openshift3.9的网络管理大全.加长篇---Openshift3.9学习系列第二篇
魏新宇
2018/07/30
2.1K0
厉害了!全CI/CD工具链的实现 | 基于OCP离线: Openshift3.9学习系列第五篇
使用 Kustomize 帮你管理 kubernetes 应用(四):简述核心配置 kustomization.yaml
在前面的文章中已经介绍了 kustomize 是什么,以及如何开始使用和如何简单的在 CI/CD 中使用,本篇文章将会介绍 kustomize 的核心文件 kustomization.yaml。
郭旭东
2020/12/30
1.5K0
kubernetes集群交付一套ELK Stack日志分析
日志,对于任何系统来说都是及其重要的组成部分,在计算机系统中比较复杂,日志有不同的来源,如操作系统,应用服务,业务逻辑等,它们都在不停产生各种各样的日志。 K8S系统里的业务应用是高度 “动态化”的,随着容器编排的进行,业务容器在不断的被创建、被销毁、被迁移、被扩缩容…
王先森sec
2023/04/24
8290
kubernetes集群交付一套ELK Stack日志分析
现代“十二要素应用”与 Kubernetes
“十二要素应用”为开发SaaS应用提供了方法上的指导,而Docker能够提供打包依赖,解耦后端服务等特性,使得两者非常吻合。这篇文章介绍了Docker特性怎样满足了开发“十二要素应用”的对应要点。
张善友
2019/07/02
8810
云计算运维一步步编译安装Kubernetes之交付dubbo微服务
dubbo提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维。
王先森sec
2023/04/24
3870
云计算运维一步步编译安装Kubernetes之交付dubbo微服务
推荐阅读
相关推荐
Tekton 与 Argo CD 结合实现 GitOps
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验