函数计算自动化运维实战1 -- 定时任务

简介: 阿里云函数计算是一个事件驱动的全托管计算服务。通过函数计算,您无需管理服务器等基础设施,只需编写代码并上传。函数计算会为您准备好计算资源,以弹性、可靠的方式运行您的代码,并提供日志查询,性能监控,报警等功能。借助于函数计算,您可以快速构建任何类型的应用和服务,无需管理和运维。更棒的是,您只需要为代码实际运行消耗的资源付费,而代码未运行则不产生费用。

函数计算

阿里云函数计算是一个事件驱动的全托管计算服务。通过函数计算,您无需管理服务器等基础设施,只需编写代码并上传。函数计算会为您准备好计算资源,以弹性、可靠的方式运行您的代码,并提供日志查询,性能监控,报警等功能。借助于函数计算,您可以快速构建任何类型的应用和服务,无需管理和运维。更棒的是,您只需要为代码实际运行消耗的资源付费,而代码未运行则不产生费用。

函数计算中的TimeTrigger

触发器是触发函数执行的方式。有时候您不想手动调用函数执行,您希望当某件事情发生时自动触发函数的执行,这个事情就是事件源。您可以通过配置触发器的方式设置事件源触发函数执行。
例如,设置定时触发器,可以在某个时间点触发函数执行或者每隔5分钟触发函数一次;函数计算timetrigger

专题传送门 => 函数计算进行自动化运维专题

定时任务自动化场景分析

定时任务示例场景1

某些账号ak需要定期更换,以确保ak安全;
在下面的代码示例中,授权service具有访问kms权限的能力,使用kms,先对一个具有创建和删除ak权限的ak加密密文解密,获取具有创建和删除ak权限的AK, 之后利用这个AK进行ak的创建和删除操作

说明: 除了使用kms加密解密来获取较大权限的AK, 通过函数计算环境变量的设置也是一种很好的方法

操作步骤

注:记得给函数的service的role设置访问kms权限

_1

  • 函数代码(函数计算已经内置了相关sdk,直接使用下面的代码即可)
# -*- coding: utf-8 -*-
import logging, time, json
from aliyunsdkcore import client
from aliyunsdkram.request.v20150501.CreateAccessKeyRequest import CreateAccessKeyRequest
from aliyunsdkram.request.v20150501.DeleteAccessKeyRequest import DeleteAccessKeyRequest
from aliyunsdkkms.request.v20160120.EncryptRequest import EncryptRequest
from aliyunsdkkms.request.v20160120.DecryptRequest import DecryptRequest
from aliyunsdkcore.auth.credentials import StsTokenCredential
# ak Encrypt content
AK_CiphertextBlob = "NmQyY2ZhODMtMTlhYS00MTNjLTlmZjAtZTQxYTFiYWVmMzZmM1B1NXhTZENCNXVWd1dhdTNMWVRvb3V6dU9QcVVlMXRBQUFBQUFBQUFBQ3gwZTkzeGhDdHVzMWhDUCtZeVVuMWlobzlCa3VxMlErOXFHWWdXXXHELLwL1NSZTFvUURYSW9lak5Hak1lMnF0R2I1TWUxMEJiYmkzVnBwZHlrWGYzc3kyK2tQbGlKb2lHQ3lrZUdieHN2eXZwSVYzN2Qyd1cydz09"
USER_NAME = "ls-test" # sub-account name
LOGGER = logging.getLogger()
def handler(event, context):
  creds = context.credentials
  sts_token_credential = StsTokenCredential(creds.access_key_id, creds.access_key_secret, creds.security_token)
  # this demo ecs and function in same region, if not in same region, you need change region_id to your ecs instance's region_id
  clt = client.AcsClient(region_id=context.region, credential=sts_token_credential)
  request = DecryptRequest()
  request.set_CiphertextBlob(AK_CiphertextBlob)
  response = _send_request(clt, request)
  ak_info = json.loads(response.get("Plaintext","{}"))
  if not ak_info:
    return "KMS Decrypt ERROR"
  ak_id = ak_info["ak_id"]
  ak_secret = ak_info["ak_secret"]
  LOGGER.info("Decrypt sucessfully with key id: {}".format(response.get("KeyId","{}")))
  clt2 = client.AcsClient(ak_id, ak_secret, context.region)
  request = CreateAccessKeyRequest()
  request.set_UserName(USER_NAME) # 给子账号ls-test创建AK
  response = _send_request(clt2, request)
  create_ak_id = response.get("AccessKey",{}).get("AccessKeyId")
  if not create_ak_id:
    return
  LOGGER.info("create ak {} sucess!".format(create_ak_id))
  
  time.sleep(10)
  
  request = DeleteAccessKeyRequest()
  request.set_UserName(USER_NAME)  
  request.set_UserAccessKeyId(create_ak_id)
  response = _send_request(clt2, request)
  LOGGER.info("delete ak {} sucess!".format(create_ak_id))
  
  return "OK"
  
# send open api request
def _send_request(clt, request):
    request.set_accept_format('json')
    try:
        response_str = clt.do_action_with_exception(request)
        LOGGER.debug(response_str)
        response_detail = json.loads(response_str)
        return response_detail
    except Exception as e:
        LOGGER.error(e)

AK 存在环境变量版本

# -*- coding: utf-8 -*-
import os, logging, time, json
from aliyunsdkcore import client
from aliyunsdkram.request.v20150501.CreateAccessKeyRequest import CreateAccessKeyRequest
from aliyunsdkram.request.v20150501.DeleteAccessKeyRequest import DeleteAccessKeyRequest
USER_NAME = "ls-test" # sub-account name
LOGGER = logging.getLogger()
def handler(event, context):
  ak_id = os.environ['AK_ID']
  ak_secret = os.environ['AK_SECRET']
  clt = client.AcsClient(ak_id, ak_secret, context.region)
  request = CreateAccessKeyRequest()
  request.set_UserName(USER_NAME) # 给子账号USER_NAME创建AK
  response = _send_request(clt, request)
  create_ak_id = response.get("AccessKey", "").get("AccessKeyId")
  if not create_ak_id:
    return
  LOGGER.info("create ak {} sucess!".format(create_ak_id))
  
  time.sleep(5)
  
  request = DeleteAccessKeyRequest()
  request.set_UserName(USER_NAME)  
  request.set_UserAccessKeyId(create_ak_id)
  response = _send_request(clt, request)
  LOGGER.info("delete ak {} sucess!".format(create_ak_id))
  
  return "OK"
  
# send open api request
def _send_request(clt, request):
    request.set_accept_format('json')
    try:
        response_str = clt.do_action_with_exception(request)
        LOGGER.info(response_str)
        response_detail = json.loads(response_str)
        return response_detail
    except Exception as e:
        LOGGER.error(e)

定时任务示例场景2

定期检查自己ecs对应暴露的端口,确保安全,比如你的ecs是一个网站服务器,可能只需要对外暴露80端口就行,如果出现0.0.0.0/0这种允许所有人访问的,需要出现报警或者自动修复

操作步骤

注:记得给函数的service的role设置管理ecs权限

# -*- coding: utf-8 -*-
import logging
import json, random, string, time
from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkecs.request.v20140526.DescribeSecurityGroupAttributeRequest import DescribeSecurityGroupAttributeRequest
from aliyunsdkcore.auth.credentials import StsTokenCredential
LOGGER = logging.getLogger()
clt = None
# 需要检查的ecs列表, 修改成你的ecs id 列表
ECS_INST_IDS = ["i-uf6h07zdscdg9g55zkxx", "i-uf6bwkxfxh847a1e2xxx"]
def handler(event, context):
  creds = context.credentials
  global clt
  sts_token_credential = StsTokenCredential(creds.access_key_id, creds.access_key_secret, creds.security_token)
  # this demo ecs and function in same region, if not in same region, you need change region_id to your ecs instance's region_id
  clt = client.AcsClient(region_id=context.region, credential=sts_token_credential)
  invalid_perssions = {}
  for ecs_id in ECS_INST_IDS:
    ret = check_and_modify_security_rule(ecs_id)
    if ret:
      invalid_perssions[ecs_id] = ret
  return invalid_perssions
def check_and_modify_security_rule(instance_id):
  LOGGER.info("check_and_modify_security_rule, instance_id  is %s ", instance_id)
  request = DescribeInstancesRequest()
  request.set_InstanceIds(json.dumps([instance_id]))
  response = _send_request(request)
  SecurityGroupIds = []
  if response is not None:
    instance_list = response.get('Instances', {}).get('Instance')
    for item in instance_list:
      SecurityGroupIds = item.get('SecurityGroupIds', {}).get("SecurityGroupId", [])
      break
  if not SecurityGroupIds:
    LOGGER.error("ecs {} do not have SecurityGroupIds".format(instance_id))
    return 
  
  invalid_perssions = []
  
  for sg_id in SecurityGroupIds:
    request = DescribeSecurityGroupAttributeRequest()
    request.set_SecurityGroupId(sg_id)
    response = _send_request(request)
    LOGGER.info("Find a securityGroup id {}".format(sg_id))
    permissions = response.get("Permissions", {}).get("Permission",[])
    if not permissions:
      continue
    for permission in permissions:
      if permission["Direction"] == "ingress" and permission["SourceCidrIp"] == "0.0.0.0/0":
        LOGGER.error("ecs {0} , SecurityGroup id {1}, have a risk, need fix; permission = {2}".format(instance_id, sg_id, permission))
        invalid_perssions.append(permission)
        
  return invalid_perssions
# send open api request
def _send_request(request):
    request.set_accept_format('json')
    try:
        response_str = clt.do_action_with_exception(request)
        LOGGER.debug(response_str)
        response_detail = json.loads(response_str)
        return response_detail
    except Exception as e:
        LOGGER.error(e)

“ 阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

相关实践学习
【AI破次元壁合照】少年白马醉春风,函数计算一键部署AI绘画平台
本次实验基于阿里云函数计算产品能力开发AI绘画平台,可让您实现“破次元壁”与角色合照,为角色换背景效果,用AI绘图技术绘出属于自己的少年江湖。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
相关文章
|
5月前
|
存储 关系型数据库 测试技术
玩转n8n测试自动化:核心节点详解与测试实战指南
n8n中节点是自动化测试的核心,涵盖触发器、数据操作、逻辑控制和工具节点。通过组合节点,测试工程师可构建高效、智能的测试流程,提升测试自动化能力。
|
5月前
|
Web App开发 前端开发 JavaScript
Playwright极速UI自动化实战指南
Playwright告别Selenium痛点,以智能等待、强大选择器、网络拦截与多设备模拟四大利器,提升自动化效率与稳定性。本文通过实战代码详解其加速秘籍,助你构建高效、可靠的UI测试方案。
|
4月前
|
数据采集 运维 监控
爬虫与自动化技术深度解析:从数据采集到智能运维的完整实战指南
本文系统解析爬虫与自动化核心技术,涵盖HTTP请求、数据解析、分布式架构及反爬策略,结合Scrapy、Selenium等框架实战,助力构建高效、稳定、合规的数据采集系统。
939 62
爬虫与自动化技术深度解析:从数据采集到智能运维的完整实战指南
|
6月前
|
Web App开发 人工智能 JavaScript
主流自动化测试框架的技术解析与实战指南
本内容深入解析主流测试框架Playwright、Selenium与Cypress的核心架构与适用场景,对比其在SPA测试、CI/CD、跨浏览器兼容性等方面的表现。同时探讨Playwright在AI增强测试、录制回放、企业部署等领域的实战优势,以及Selenium在老旧系统和IE兼容性中的坚守场景。结合六大典型场景,提供技术选型决策指南,并展望AI赋能下的未来测试体系。
|
6月前
|
人工智能 运维 监控
运维也能“先演练后实战”?聊聊数字孪生的那些神操作
运维也能“先演练后实战”?聊聊数字孪生的那些神操作
202 0
|
4月前
|
弹性计算 人工智能 前端开发
在阿里云ECS上部署n8n自动化工作流:U2实例实战
本文介绍如何在阿里云ECS的u2i/u2a实例上部署开源工作流自动化平台n8n,利用Docker快速搭建并配置定时任务,实现如每日抓取MuleRun新AI Agent并推送通知等自动化流程。内容涵盖环境准备、安全组设置、实战案例与优化建议,助力高效构建低维护成本的自动化系统。
1108 5
|
4月前
|
监控 Java BI
《深入理解Spring》定时任务——自动化调度的时间管理者
Spring定时任务通过@Scheduled注解和Cron表达式实现灵活调度,支持固定频率、延迟执行及动态配置,结合线程池与异常处理可提升可靠性,适用于报表生成、健康检查等场景,助力企业级应用自动化。
|
6月前
|
人工智能 缓存 测试技术
Playwright进阶指南 (6) | 自动化测试实战
2025企业级测试解决方案全面解析:从单元测试到千级并发,构建高可用测试体系。结合Playwright智能工具,解决传统测试维护成本高、环境依赖强、执行效率低等痛点,提升测试成功率,内容从测试架构设计、电商系统实战框架、高级测试策略、Docker化部署、CI/CD集成及AI测试应用,助力测试工程师掌握前沿技术,打造高效稳定的测试流程。
Playwright进阶指南 (6) | 自动化测试实战
|
5月前
|
人工智能 数据可视化 测试技术
AI 时代 API 自动化测试实战:Postman 断言的核心技巧与实战应用
AI 时代 API 自动化测试实战:Postman 断言的核心技巧与实战应用
719 11
|
6月前
|
传感器 人工智能 JavaScript
Playwright实战:写UI自动化脚本,速度直接起飞
简介: 测试工程师老王因UI自动化问题深夜奋战,反映出传统测试工具的局限性。微软开源的Playwright凭借智能等待、跨域操作、移动端模拟与网络拦截等强大功能,正迅速取代Selenium,成为新一代自动化测试标准。其稳定高效的设计显著降低维护成本,助力企业构建高质量测试流程。

相关产品

  • 函数计算