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

本文涉及的产品
云原生网关 MSE Higress,422元/月
性能测试 PTS,5000VUM额度
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 阿里云函数计算是一个事件驱动的全托管计算服务。通过函数计算,您无需管理服务器等基础设施,只需编写代码并上传。函数计算会为您准备好计算资源,以弹性、可靠的方式运行您的代码,并提供日志查询,性能监控,报警等功能。借助于函数计算,您可以快速构建任何类型的应用和服务,无需管理和运维。更棒的是,您只需要为代码实际运行消耗的资源付费,而代码未运行则不产生费用。

函数计算

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

函数计算中的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等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
26天前
|
Prometheus 运维 监控
智能运维实战:Prometheus与Grafana的监控与告警体系
【10月更文挑战第26天】Prometheus与Grafana是智能运维中的强大组合,前者是开源的系统监控和警报工具,后者是数据可视化平台。Prometheus具备时间序列数据库、多维数据模型、PromQL查询语言等特性,而Grafana支持多数据源、丰富的可视化选项和告警功能。两者结合可实现实时监控、灵活告警和高度定制化的仪表板,广泛应用于服务器、应用和数据库的监控。
137 3
|
16天前
|
运维 Ubuntu 应用服务中间件
自动化运维工具Ansible的实战应用
【10月更文挑战第36天】在现代IT基础设施管理中,自动化运维已成为提升效率、减少人为错误的关键手段。本文通过介绍Ansible这一流行的自动化工具,旨在揭示其在简化日常运维任务中的实际应用价值。文章将围绕Ansible的核心概念、安装配置以及具体使用案例展开,帮助读者构建起自动化运维的初步认识,并激发对更深入内容的学习兴趣。
38 4
|
14天前
|
机器学习/深度学习 数据采集 人工智能
智能运维:从自动化到AIOps的演进与实践####
本文探讨了智能运维(AIOps)的兴起背景、核心组件及其在现代IT运维中的应用。通过对比传统运维模式,阐述了AIOps如何利用机器学习、大数据分析等技术,实现故障预测、根因分析、自动化修复等功能,从而提升系统稳定性和运维效率。文章还深入分析了实施AIOps面临的挑战与解决方案,并展望了其未来发展趋势。 ####
|
18天前
|
消息中间件 运维 UED
消息队列运维实战:攻克消息丢失、重复与积压难题
消息队列(MQ)作为分布式系统中的核心组件,承担着解耦、异步处理和流量削峰等功能。然而,在实际应用中,消息丢失、重复和积压等问题时有发生,严重影响系统的稳定性和数据的一致性。本文将深入探讨这些问题的成因及其解决方案,帮助您在运维过程中有效应对这些挑战。
24 1
|
23天前
|
机器学习/深度学习 数据采集 运维
智能化运维:机器学习在故障预测和自动化响应中的应用
智能化运维:机器学习在故障预测和自动化响应中的应用
48 4
|
25天前
|
前端开发 数据管理 测试技术
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第27天】本文介绍了前端自动化测试中Jest和Cypress的实战应用与最佳实践。Jest适合React应用的单元测试和快照测试,Cypress则擅长端到端测试,模拟用户交互。通过结合使用这两种工具,可以有效提升代码质量和开发效率。最佳实践包括单元测试与集成测试结合、快照测试、并行执行、代码覆盖率分析、测试环境管理和测试数据管理。
43 2
|
26天前
|
前端开发 JavaScript 数据可视化
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第26天】前端自动化测试在现代软件开发中至关重要,Jest和Cypress分别是单元测试和端到端测试的流行工具。本文通过解答一系列问题,介绍Jest与Cypress的实战应用与最佳实践,帮助开发者提高测试效率和代码质量。
32 2
|
2月前
|
运维 监控 jenkins
运维自动化实战:利用Jenkins构建高效CI/CD流程
【10月更文挑战第18天】运维自动化实战:利用Jenkins构建高效CI/CD流程
|
25天前
|
Prometheus 运维 监控
智能运维实战:Prometheus与Grafana的监控与告警体系
【10月更文挑战第27天】在智能运维中,Prometheus和Grafana的组合已成为监控和告警体系的事实标准。Prometheus负责数据收集和存储,支持灵活的查询语言PromQL;Grafana提供数据的可视化展示和告警功能。本文介绍如何配置Prometheus监控目标、Grafana数据源及告警规则,帮助运维团队实时监控系统状态,确保稳定性和可靠性。
124 0
|
3月前
|
人工智能 自然语言处理 Serverless
阿里云函数计算 x NVIDIA 加速企业 AI 应用落地
阿里云函数计算与 NVIDIA TensorRT/TensorRT-LLM 展开合作,通过结合阿里云的无缝计算体验和 NVIDIA 的高性能推理库,开发者能够以更低的成本、更高的效率完成复杂的 AI 任务,加速技术落地和应用创新。
157 13

相关产品

  • 函数计算
  • 下一篇
    无影云桌面