【问题标题】:how to prevent excess billing in google cloud platform 2021如何防止谷歌云平台 2021 中的超额计费
【发布时间】:2021-05-04 18:49:47
【问题描述】:

我在谷歌云平台上有多个项目和api,比如地图api、php应用引擎、sql等。

Google 改变了计费的管理方式,现在确实有可能以任何原因(错误、黑客等)导致计费飙升

如何才能在达到限制时禁用每个计费?不仅仅是电子邮件通知,这还不够! 我不能只是关闭我的应用引擎实例,因为地图和其他地方的 api 凭据仍然可以产生费用!

【问题讨论】:

    标签: google-app-engine google-cloud-platform billing google-cloud-billing


    【解决方案1】:

    Set budgets and budget alerts 文档。你有 2 种策略来解决这个问题。

    第一个是设置 API spending limit 或者基于 wuota 或限制每个用户的调用,所以如果您的服务对特定 API 进行过多调用,您只需阻止该 API,以便您的整个服务/项目可以继续服务。

    另一种方法是为整个项目发送automate the disabling of billing。这样做的风险更大,因为它会阻塞整个项目并可能导致数据丢失。

    为此,您将部署一个云函数,类似于文档中由您的预算设置使用的 Pub/Sub 主题触发的函数:

    const {google} = require('googleapis');
    const {GoogleAuth} = require('google-auth-library');
    
    const PROJECT_ID = process.env.GOOGLE_CLOUD_PROJECT;
    const PROJECT_NAME = `projects/${PROJECT_ID}`;
    const billing = google.cloudbilling('v1').projects;
    
    exports.stopBilling = async pubsubEvent => {
      const pubsubData = JSON.parse(
        Buffer.from(pubsubEvent.data, 'base64').toString()
      );
      if (pubsubData.costAmount <= pubsubData.budgetAmount) {
        return `No action necessary. (Current cost: ${pubsubData.costAmount})`;
      }
    
      if (!PROJECT_ID) {
        return 'No project specified';
      }
    
      _setAuthCredential();
      const billingEnabled = await _isBillingEnabled(PROJECT_NAME);
      if (billingEnabled) {
        return _disableBillingForProject(PROJECT_NAME);
      } else {
        return 'Billing already disabled';
      }
    };
    
    /**
     * @return {Promise} Credentials set globally
     */
    const _setAuthCredential = () => {
      const client = new GoogleAuth({
        scopes: [
          'https://www.googleapis.com/auth/cloud-billing',
          'https://www.googleapis.com/auth/cloud-platform',
        ],
      });
    
      // Set credential globally for all requests
      google.options({
        auth: client,
      });
    };
    
    /**
     * Determine whether billing is enabled for a project
     * @param {string} projectName Name of project to check if billing is enabled
     * @return {bool} Whether project has billing enabled or not
     */
    const _isBillingEnabled = async projectName => {
      try {
        const res = await billing.getBillingInfo({name: projectName});
        return res.data.billingEnabled;
      } catch (e) {
        console.log(
          'Unable to determine if billing is enabled on specified project, assuming billing is enabled'
        );
        return true;
      }
    };
    
    /**
     * Disable billing for a project by removing its billing account
     * @param {string} projectName Name of project disable billing on
     * @return {string} Text containing response from disabling billing
     */
    const _disableBillingForProject = async projectName => {
      const res = await billing.updateBillingInfo({
        name: projectName,
        resource: {billingAccountName: ''}, // Disable billing
      });
      return `Billing disabled: ${JSON.stringify(res.data)}`;
    };
    

    依赖关系:

    {
     "name": "cloud-functions-billing",
     "version": "0.0.1",
     "dependencies": {
       "google-auth-library": "^2.0.0",
       "googleapis": "^52.0.0"
     }
    }
    

    然后您将 Billing Admin 权限授予此 Cloud Function 的服务帐户

    如果您想使用这种方法,我建议您在任何一种情况下都尽可能为每个服务设置不同的项目,这样您就可以只关闭部分服务。

    【讨论】:

    • 换句话说,没有像过去那样防止过度计费的简单好方法......
    • 1) 禁用项目计费会停止自动付款。账单可能仍会出现,例如服务不会立即终止。 2) 如果您为某个项目禁用结算功能,您的一些 GCP 资源可能会被移除并变得不可恢复。 3) 您不能禁用使用该 API 部署服务的 API。 4) 从技术上讲,您的答案很好,但有有害的副作用。
    • 我同意 John 的观点,但不再有(或至少我不知道)安全停止对项目收费的好方法
    猜你喜欢
    • 1970-01-01
    • 2018-08-13
    • 2017-10-08
    • 2016-09-27
    • 2020-06-02
    • 2020-08-12
    • 1970-01-01
    • 2018-03-28
    • 1970-01-01
    相关资源
    最近更新 更多