基于阿里云容器的 CI/CD 落地实践

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 团队面对的业务架构是不断增长的微服务集群,基于此,对于CICD的自动化要求以及发布频率不断提出了新的挑战。

作者个人介绍
刘晨 Lorraine

坐标Fintech,精通持续集成与发布,曾具有全平台100+应用持续部署持续发布实战经验,现在立志于成为K8S玩家。

image.png

背景

大家好,笔者所在的团队当前面临落地公司业务数字化转型的重大任务。我们面临的主要研发挑战是如何快速得迭代出不断新增的开发需求,由于没有太多历史包袱,团队选择的技术栈也是相对成熟与流行的,比如我负责的Devops主要是基于阿里云ACK容器以及Jenkins2.0+进行搭建实施。

阿里云ACK容器也是基于K8S1.16.9封装的云服务,我们选择的是托管版本,即master节点托管于阿里云,我们只负责worker节点集群的运维与管理。这样做的好处是使团队力量尽可能得集中在业务层面,基础设施层面的运维工作尽量服务化。选择Jenkins2.0有诸多好处,比如Jenkins是经典的CI实施工具平台,开发测试多数熟悉这种使用方式,无需再次学习。2.0版本以后,引入了声明式的Jenkinsfile语法,这种流水线编排格式与基于声明式API的K8S能够更天然地集成,并且Jenkins生态圈的plugin十分丰富,基本可以通过配置方式满足团队构建多语言多项目CICD任务的使用场景。



核心问题

目前实施CICD的业务,基本都要解决以下核心问题。

交付物是什么?

部署环境有哪些?
环境配置信息是什么?
如何自动化地执行构建,部署任务?
如果构建,部署任务执行失败,或者部署环境的应用运行失败,如何感知故障的发生?

交付物定义与结构

交付物对象是在整个CICD流程中需要最先确定的实体,是开发跟devops之间交互的对接物。开发与devops一同参与交付物实体的定义,再由devops针对定义提供交付物的通用模版。



交付物定义

团队对于交付物的定义是基于dockerfile生成的微服务镜像。

devops提供了基于阿里云容器镜像服务的私有仓库来存放,如图:
image.png
开发基于dockerfile提供镜像打包定义,我们以java应用为例,镜像内容主要包括基于openjdk基础镜像的工作目录定以及指定启动cmd,示例代码如下:

FROM openjdk:11.0.8
WORKDIR /home/demo
COPY target/index-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]

交付物结构

每个应用部署交付物都归档在一个独立的镜像仓库,镜像仓库命名规范为项目名称.应用服务名称,镜像tag的命名规范里应包含每次构建物里所包含的代码变更内容,以latest commit id来表示,以及构建发生的时间信息,以yyyymmddd-hhmm格式表示时间戳,示例如图:

image.png
交付物镜像应是包含了除了环境配置信息以外的应用部署的全部信息的实体。以java应用为例,该交付物是基于openjdk的jar包的镜像实体。环境配置信息可以由环境变量传递并改写。



部署环境与配置

部署环境

CICD理念解决的核心问题之一是在如何在多环境下部署同一交付物。典型的部署环境主要有4种:

dev开发环境

交付物生成的环境。在开发环境内,交付物第一次生成,需要经过必要的单元测试通过率以及代码安全性检查等步骤,该环境的交付物是可提测的部署物。

test测试环境

交付物开始集成测试以及回归测试的环境。该环境的交付物是可上生产的部署物。

stage预发布环境

预发布环境的使用场景会依据需求而有所不同。有些公司会将预发布环境用作demo环境作为poc功能展示;有些公司会在预发布环境中进行流量压力测试,确保上生产之前的服务负载与资源配置相匹配;有些公司做蓝绿发布或者A/B测试时,则会利用stage环境来做流量切换。无论stage环境如何被使用,stage部署环境都需与生产部署环境配置保持一致。

prod生产环境

生产发布环境是交付物最终运行环境,对用户提供服务。

环境配置

环境配置信息是CICD过程中,独立与交付物,但依赖于部署环境的一系列环境变量信息。基于K8S集群部署时,实现的主要方式是ConfigMap以及Secret资源对象。

构建自动化

我们有了Dockerfile来描述交付物的定义,简单来说只要docker build 然后docker push到私有镜像仓库就完成了构建。基于Jenkins搭建自动化的构建任务就是将这个过程自动化。后文实施部分会详细讲述。



构建任务自动化主要考虑的问题有:

当main/master branch有代码提交commit生成时,如何自动触发构建任务执行?

不同语言应用,比如java应用或者前端应用的构建流程是怎样的?包含哪些步骤?

生成的交付物镜像如何成功放至到阿里云容器镜像服务的私有仓库里?

交付物传输过程如何确保网络传输的安全性与可靠性?

部署自动化

我们的部署环境是在阿里云容器集群中,当前每个部署环境通过命名空间来进行资源隔离,后续还会做资源隔离升级。目前对于在K8S集群中的应用部署,主流的解决方案有Helm和Kustomize,我们最后选择了HelmV3来实施。Helm与Kustomize之间的选择是另一个有意思的话题,不在本章展开。基于Helm的部署自动化简单来说就是构建一个能够运行helm Install指令的jenkins任务。后文实施部分会详细讲述。



部署自动化主要考虑的问题有:

如何获取到交付物?

部署的是哪个交付物?要部署的目标环境是哪个?

如何定义部署成功?

部署失败了,如何感知到故障?如何快速定位到问题?

如何实现回滚操作?

事件监控与告警机制

CICD的目标是尽可能的自动化全流程,降低人为参与的程度。当自动化程度越高,对于自动任务的故障发现与告警就越有必要。我们的服务部署在阿里云容器集群中,基于Jenkins2.0来搭建自动化CI/CD的任务,构建部署依赖与Jenkins任务执行是否成功,以及集群中的资源按照Helm的定义是否如期更新运行。CI/CD相关的事件监控围绕着集群资源事件监控以及Jenkins任务监控两方面来进行。

阿里云容器集群事件监控与告警

阿里云服务提供了事件监控与告警服务,可以直接配置使用,如图所示,该示例为阿里云集群服务/运维管理/事件列表提供的事件监控仪表盘服务。我们可以轻松得到整个集群资源运行的情况。

image.png
进入“告警配置”服务就能配置基本事件的告警,集群初始化了很多基本事件的告警配置,比如Pod/Node OOM;Pod启动失败,或者资源不足,无法调度等。可以依据业务需求,定制化告警事项。笔者目前采用的是使用默认配置的告警模版,对发生频次做了一定容忍,通过邮件方式进行告警。
image.png
Jenkins任务失败自动发送邮件告警

E-mail Notification Plugin可以帮助实现Jenkins服务对于任务完成自动发送邮件的功能。

首先在Jenkins/configuration/Extended E-mail Notification配置SMTP邮件服务信息,我们使用的是阿里云邮件推送服务, 确保填写了正确的smtp server, smtp port,如果有smtp username/passwrod,也需要正确填写。
image.png
其次在Jenkinsfile里声明使用email extension plugin,对于构建任务失败自动发送邮件的代码块如下:

emailext (

            to: 'XXX@example.com',
            subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
            body: """<p>FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p>
            <p>Check console output at &QUOT;<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>&QUOT;</p>""",
            recipientProviders: [[$class: 'DevelopersRecipientProvider']]
        )

###实施

基于Dockerfile/Jenkinsfile构建CI流水线

交付物由Dockerfile定义,每个应用服务的根目录下都应该有一个Dockerfile文件,定义了该服务的构建过程。本节里我们举java微服务来说明,这也是我们后端微服务的构建流水线。

Java微服务

Java应用的构建逻辑定义在Jenkinsfile里,基于maven实现。Dockerfile模版只定义了如何调用构建好的jar包,即部署指令。这样做的主要目的是尽可能缩小镜像,降低网络数据传输的负载。

声明式Jenkinsfile的好处是可以通过代码方式定义与管理流水线逻辑。基于代码就拥有了版本管理的能力。

构建Pipeline主要包含了以下步骤:

scm 获取项目源代码

基于maven的构建,生成可部署的jar包

基于maven的单元测试

基于SonarQube的代码检查

基于kaniko的云原生方式,生成image,并推送至阿里云私有镜像仓库

构建Pipeline主流程之外的后置步骤是构建任务执行完成后的downStream任务,链接的是通用部署任务,这种结构解耦了构建与部署逻辑,可以使不同的构建任务复用同一个部署任务。

def branch_name

def revision
def registryIp = "registry-vpc.cn-shanghai-finance-1.aliyuncs.com"
def app = "XXX"
pipeline {

agent{
    node{
        label 'slave-java' // Jenkins Slave Pod Template
    }
}
stages {
    stage ('Checkout') {
        steps {
            script {
                def repo = checkout scm
                revision = sh(script: 'git log -1 --format=\'%h.%ad\' --date=format:%Y%m%d-%H%M | cat', returnStdout: true).trim()
                branch_name = repo.GIT_BRANCH.take(20).replaceAll('/', '_')
                if (branch_name != 'master') {
                    revision += "-${branch_name}"
                }
                sh "echo 'Building revision: ${revision}'" // 获取代码并生成镜像tag(latest-commit-id+timestanp+branch)
            }
        }
    }
    stage('Compile') {
        steps {
            container("maven") {
                sh 'mvn -B -DskipTests clean package' // 基于maven的构建步骤
            }
        }
    }
    //unit test 测试部署
    stage('Unit Test') {
       steps {
           container("maven") {
               sh 'mvn test org.jacoco:jacoco-maven-plugin:0.7.3.201502191951:prepare-agent install -Dmaven.test.failure.ignore=true'
           }
       }
    }
    // 上传Jacoco检测结果
    stage('JacocoPublisher') {
        steps {
            jacoco()
        }
    }
    stage('Build Artifact') {
        steps {
             container("maven") {
                sh 'chmod +x ./jenkins/scripts/deliver.sh'
                sh './jenkins/scripts/deliver.sh'
             }
        }
    }
    stage('SonarQube Analysis'){
        environment {
            scannerHome = tool 'SonarQubeScanner'
        }
        steps {
            withSonarQubeEnv('sonar_server') {
                sh "${scannerHome}/bin/sonar-scanner"
            }
        }
    }
     // 添加stage, 运行容器镜像构建和推送命令
    stage('Image Build and Publish for Dev Branch'){
      when { not { branch 'master' } }
      steps{
          container("kaniko") {
              sh "kaniko -f `pwd`/Dockerfile -c `pwd` --destination=${registryIp}/xxxx/xxx.${app}:${revision} --skip-tls-verify"
          }
      }
    }
     // 添加stage, 运行容器镜像构建和推送命令
    stage('Image Build and Publish for Master Branch'){
      when { branch 'master' }
      steps{
          container("kaniko") {
              sh "kaniko -f `pwd`/Dockerfile -c `pwd` --destination=${registryIp}/xxxx/xxx.${app} --destination=${registryIp}/xxxx/xxx.${app}:${revision} --skip-tls-verify"
          }
      }
    }
}
post {
    always {
        echo 'This will always run'
    }
    success {
        script {
            build job: '../xxx.app.deploy/master', parameters: [string(name: 'App', value: String.valueOf(app)), string(name: 'Env', value: 'dev-show'), string(name: 'Tag', value: String.valueOf(revision))]
        }
    }
    failure {
        emailext (
            to: 'XXX@example.com',
            subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
            body: """<p>FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p>
            <p>Check console output at &QUOT;<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>&QUOT;</p>""",
            recipientProviders: [[$class: 'DevelopersRecipientProvider']]
        )
    }
    unstable {
        echo 'This will run only if the run was marked as unstable'
    }
    changed {
        echo 'This will run only if the state of the Pipeline has changed'
        echo 'For example, if the Pipeline was previously failing but is now successful'
    }
}

}

构建任务一般是根据主分支提交的代码自动触发的任务。为了实现autoTrigger,我们需要使用webHook连接SCM服务和Jenkins服务,我们使用的SCM服务是Bitbucket,通过使用hook插件实现了autoTrigger。

image.png

基于阿里云容器服务的部署环境属于VPC内,即我们使用的容器镜像服务是VPC内的私有镜像服务,VPC外部无法访问。K8S集群也属于该VPC内的资源,故集群内部的CI Jenkins Slave Pod以及目标部署Pod服务都在该VPC的内网内,与私有化的容器镜像服务直接局域网连接,确保了数据传输的安全性与可靠性。

基于Helm/Jenkinsfile构建CD流水线

在K8S上部署一个应用,传统方式一般利用kubectl创建一系列的资源对象(deployment,configMap,secret,serviceAccount, service,ingress 等)。在CICD部署流程中,涉及同一部署物部署到多个环境内,即部署发生多次。举个例子,部署在开发和测试环境的两个Deployment对象,结构基本一致,只有少数属性的赋值依据环境而有所不同。CICD软件实践里有一个重要理念是部署可以重复,确保在各个环境的部署的动作是一致的,以避免在发布流水线中引入差异。Helm是一种适应上述需求的模版式解决方案。Helm的介绍不在本章展开,有兴趣学习的读者可以参考。https://whmzsu.github.io/helm-doc-zh-cn/

helm提供了chart包(一种可以封装K8S资源对象为模版文件的集合)和values.yaml(属性参数的集合)结构,基于Go Template语法,解耦了manifest里属性值与K8S资源对象模版结构。使得一组对应用部署所需资源对象的创建可以通过模版定义加赋值的方式,复用到多个环境,重复部署,解决了K8S资源对象管理的问题。

下来以Java微服务的helm/Chart包举例来说明我们是如何生成应用部署物的

helm包初始化可以使用helm create Name [flags]

image.png
部署物helm包的目录结构如下:
image.png
根目录下的values.yaml是所有环境公共的属性集合,比如关于创建serviceAccount,rbac相关的属性信息,dev/test/stage/production.yaml是与部署环境有关的属性集合。

执行helm install 命令来部署当前Helm包模版,例如


helm upgrade index ./helm/ -i -nbss-dev -f ./helm/values.yaml -f ./helm/dev.yaml --set 'image.tag=latest' --set 'image.repo=bss.index' --set 'ingress.hosts.paths={/index}'

前文提到了我们使用声明式Jenkinsfile语法构建部署流水线逻辑,与传统groovy不一样的是,我们可以通过声明pipeline,agent/node,stages/step等对象,直接将部署流程的定义声明。以部署基于helm的jar包应用为例,部署物为在阿里云私有镜像仓库的镜像文件,上文例子所示。部署流程包括两个步骤:1. 获取helm代码 2. 执行helm install,具体如下:

def branch_name
def revision

def registryIp = "registry-vpc.cn-shanghai-finance-1.aliyuncs.com"
pipeline {

agent{
    node{
        label 'slave-java' // Jenkins Slave Pod Template
    }
}
parameters {
    choice(name: 'App', choices: ['111', '222', '333','444'], description: '选择部署应用')
    choice(name: 'Env', choices: ['dev', 'stage', 'test',], description: '选择部署环境')
    string(name: 'Tag', defaultValue: 'latest', description: '请输入将要部署的构建物镜像Tag')
}
stages {
     stage ('CheckoutHelm') {
        steps {
            script {
                def repo = checkout scm
                revision = sh(script: 'git log -1 --format=\'%h.%ad\' --date=format:%Y%m%d-%H%M | cat', returnStdout: true).trim()
                branch_name = repo.GIT_BRANCH.take(20).replaceAll('/', '_')
                if (branch_name != 'master') {
                    revision += "-${branch_name}"
                }
            }
        }
    }

stage ('Deploy') {

         steps {
            container('helm-kubectl') {
                 sh "chmod +x ./helm/setRevision.sh"
                 sh "./helm/setRevision.sh ${revision}"
                 sh "helm upgrade -i ${params.App} ./helm/ -nxxx-${params.Env} -f ./helm/${params.Env}.yaml --set-file appConfig=./appConfig/${params.Env}/${params.App}.yml --set image.tag=${params.Tag} --set image.repo=bss.${params.App} --set ingress.hosts.paths={/${params.App}}"
            }
        }
    }
}

post {

    always {
        echo 'This will always run'
    }
    success {
        echo 'This will run only if successful'
    }
    failure {
        emailext (
            to: 'XXX@example.com',
            subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
            body: """<p>FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p>
            <p>Check console output at &QUOT;<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>&QUOT;</p>""",
            recipientProviders: [[$class: 'DevelopersRecipientProvider']]
        )
    }
    unstable {
        echo 'This will run only if the run was marked as unstable'
    }
    changed {
        echo 'This will run only if the state of the Pipeline has changed'
        echo 'For example, if the Pipeline was previously failing but is now successful'
    }
}

}

经验总结与展望

流水线自助化改进

笔者团队面对的业务架构是不断增长的微服务集群。基于此,对于CICD的自动化要求以及发布频率不断提出了新的挑战。原先我们的做法是每个微服务拥有独立的helm部署包,但是由于快速增加的微服务数量,对于快速注册新服务到现有CICD流水线中,产生了开发快速构建部署服务的需求。

面临的问题主要是helm部署模版是以应用部署所需的资源对象构建为单元,在不同部署环境做配置。每个应用都会创建一套helm部署包以及的独立的构建和部署任务。当越来越多的微服务部署需求不断增加时,构建helm包以及相应的构建部署任务的配置工作量就会成为CICD流程的效率瓶颈。

解决方案是抽象一个公共helm部署包模版,将各个应用部署时定制化的属性信息集合从原有helm包结构中再抽象出来,以AppConfig File方式独立成一层配置信息,例如:
image.png
这里的模版抽象实现主要是依赖Helm命令里-f 传入values.yaml 时,可以同时-f 多个属性集合文件,并且位于后面的-f 的文件可以覆盖前面的属性参数值。如果定制化配置信息文件不是Go template可以直接使用的格式,可以考虑使用flag --set-file 直接将Config文件里的内容写入某个上层的属性参数。

安全问题

将开发,测试环境都搬到公有云上,访问安全是一个不可忽略的问题。我们的交付物,部署流水线以及目标部署集群都基于一个VPC下,从网络传输角度,数据交互在一个局域网内,是相对安全的公有云网络环境。除此之外,为了保证开发环境,测试环境完全的私有化,在微服务应用部署ingress资源对应的slb上我们也设置了相应的访问控制,只能对公司内部的用户开放网络访问。后续对于公网访问的服务以及外部部署环境和CICD服务之间的数据传输会考虑使用阿里云提供的KMS等数据传输保密服务来保证。

相关实践学习
通过workbench远程登录ECS,快速搭建Docker环境
本教程指导用户体验通过workbench远程登录ECS,完成搭建Docker环境的快速搭建,并使用Docker部署一个Nginx服务。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
4天前
|
运维 监控 Kubernetes
构建高效自动化运维体系:基于容器技术的持续集成与持续部署(CI/CD)实践
【5月更文挑战第15天】 随着云计算和微服务架构的普及,传统的IT运维模式面临转型压力。为提高软件交付效率并降低运维成本,本文探讨了利用容器技术实现自动化运维的有效策略。重点分析了在持续集成(CI)和持续部署(CD)流程中,容器如何发挥作用,以及它们如何帮助组织实现敏捷性和弹性。通过具体案例研究,文章展示了容器化技术在自动化测试、部署及扩展中的应用,并讨论了其对系统稳定性和安全性的影响。
|
4天前
|
运维 监控 安全
构建高效自动化运维系统:基于容器技术的持续集成与持续部署(CI/CD)实践
【5月更文挑战第14天】 随着DevOps文化的深入人心,持续集成与持续部署(CI/CD)已成为现代软件工程不可或缺的组成部分。本文将探讨如何利用容器技术,尤其是Docker和Kubernetes,构建一个高效、可扩展的自动化运维系统。通过深入分析CI/CD流程的关键组件,我们将讨论如何整合这些组件以实现代码从提交到生产环境的快速、无缝过渡。文章还将涉及监控、日志管理以及安全性策略等运维考量,为读者提供一个全面的自动化运维解决方案蓝图。
|
4天前
|
安全 Devops 测试技术
深入了解阿里云云效DevOps:构建高效软件开发实践
阿里云云效DevOps,集成CI/CD与自动化测试,提升开发效率。支持持续集成确保代码质量,自动化测试加速交付,多环境及灰度发布保障安全可靠性。助团队构建高效开发实践,增强竞争力。
19 1
|
4天前
|
存储 监控 Apache
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
网易的灵犀办公和云信利用 Apache Doris 改进了大规模日志和时序数据处理,取代了 Elasticsearch 和 InfluxDB。Doris 实现了更低的服务器资源消耗和更高的查询性能,相比 Elasticsearch,查询速度提升至少 11 倍,存储资源节省达 70%。Doris 的列式存储、高压缩比和倒排索引等功能,优化了日志和时序数据的存储与分析,降低了存储成本并提高了查询效率。在灵犀办公和云信的实际应用中,Doris 显示出显著的性能优势,成功应对了数据增长带来的挑战。
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
|
4天前
|
测试技术 块存储 开发者
阿里云块存储团队软件工程实践
本文介绍了阿里云团队软件工程实际开发流程,并简述了开发过程中遇到的一些问题。且附带案例,以及遇到案例中出现的情况应当如何应对。
|
4天前
|
运维 Kubernetes 持续交付
构建高效自动化运维体系:基于容器技术的持续集成与持续部署(CI/CD)实践
【4月更文挑战第29天】 随着云计算和微服务架构的兴起,自动化运维已成为提升企业IT效率、确保系统稳定性的关键因素。本文旨在探讨如何利用容器技术构建一套高效的自动化运维体系,实现软件开发过程中的持续集成(CI)与持续部署(CD)。文章首先分析了传统运维模式面临的挑战,然后详细介绍了基于Docker和Kubernetes等容器技术的CI/CD流程设计与实施策略,并通过一个实际案例来展示该方案在提高部署频率、降低人力成本及提升系统可靠性方面的显著优势。
|
4天前
|
运维 Serverless API
Serverless 应用引擎产品使用之在阿里云函数计算中,容器运行过程中的最大内存使用量获取如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
41 2
|
4天前
|
运维 IDE Serverless
Serverless 应用引擎产品使用之阿里函数计算中,阿里云容器镜像服务(Container Registry)中创建自定义镜像,然后将其部署到FC上如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
31 0
|
4天前
|
弹性计算 运维 监控
解密阿里云弹性计算:探索云服务器ECS的核心功能
阿里云ECS是核心计算服务,提供弹性云服务器资源,支持实例按需配置、集群管理和监控,集成安全防护,确保服务稳定、安全,助力高效业务运营。
84 0
|
4天前
|
存储 弹性计算 固态存储
阿里云服务器CPU内存配置详细指南,如何选择合适云服务器配置?
阿里云服务器配置选择涉及CPU、内存、公网带宽和磁盘。个人开发者或中小企业推荐使用轻量应用服务器或ECS经济型e实例,如2核2G3M配置,适合低流量网站。企业用户则应选择企业级独享型ECS,如通用算力型u1、计算型c7或通用型g7,至少2核4G配置,公网带宽建议5M,系统盘可选SSD或ESSD云盘。选择时考虑实际应用需求和性能稳定性。
149 6