📌  相关文章
📜  Google Cloud Platform –无服务器容器

📅  最后修改于: 2021-04-17 03:01:51             🧑  作者: Mango

开发人员喜欢无服务器。他们更喜欢专注于代码,部署,并让平台负责其余的工作。 Cloud Run ,让您在无服务器上运行任何无状态容器。借助Cloud Run,您可以省去基础架构。它专注于可自动感知请求的扩展,因此您可以将其缩减为零,并且仅在使用时付费。

为了解释这个概念,让我们举个例子。在这里,我们将部署无服务器微服务,该服务将Word文档转换为PDF。要执行此转换,我们将需要OpenOffice 。我们将简单地在容器中添加OpenOffice,然后在无服务器环境中运行它。

让我们跳进去。在控制台中,转到“ Cloud Run”,然后打开“ Deployment”页面。

选择或粘贴容器图像的URL,然后单击创建

这就是我们创建无服务器容器所需的全部。没有要预先配置的基础结构,没有YAML文件,也没有服务器。

Cloud Run已导入我们的映像,确保其已启动,并收集了稳定且安全的HTTPS端点。

我们刚刚部署的是可扩展的微服务,可将文档转换为PDF。让我们看一下它的运行情况,方法是为它提供一个文档,该文档可以通过将其上传到正在运行的微服务上进行转换。

OpenOffice并非完全是现代软件。它大约有15年的二进制历史,大约200兆字节。而且我们只是采用了该二进制文件并将其作为Cloud Run部署为无服务器工作负载,因为Cloud Run支持Docker容器。这意味着您可以以无服务器方式运行所需的任何编程语言或任何软件。

让我们看一下代码。我们有一小段Python代码,用于侦听传入的HTTP请求并调用OpenOffice来转换我们的文档。

Python3
# python program to convert
# docs into pdf
  
import os
import shutil
import requests
import tempfile
  
from gevent.pywsgi import WSGIServer
from flask import Flask, after_this_request, render_template, request, send_file
from subprocess import call
  
UPLOAD_FOLDER = '/tmp'
ALLOWED_EXTENSIONS = set(['doc', 'docx', 'xls', 'xlsx'])
  
app = Flask(__name__)
  
  
# Convert using Libre Office
def convert_file(output_dir, input_file):
    call('libreoffice --headless --convert-to pdf --outdir %s %s ' %
         (output_dir, input_file), shell=True)
  
  
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
  
  
@app.route('/', methods=['GET', 'POST'])
def api():
    work_dir = tempfile.TemporaryDirectory()
    file_name = 'document'
    input_file_path = os.path.join(work_dir.name, file_name)
    # Libreoffice is creating files with the same name but .pdf extension
    output_file_path = os.path.join(work_dir.name, file_name + '.pdf')
  
    if request.method == 'POST':
        # check if the post request has the file part
        if 'file' not in request.files:
            return 'No file provided'
        file = request.files['file']
        if file.filename == '':
            return 'No file provided'
        if file and allowed_file(file.filename):
            file.save(input_file_path)
  
    if request.method == 'GET':
        url = request.args.get('url', type=str)
        if not url:
            return render_template('index.html')
        # Download from URL
        response = requests.get(url, stream=True)
        with open(input_file_path, 'wb') as file:
            shutil.copyfileobj(response.raw, file)
        del response
  
    convert_file(work_dir.name, input_file_path)
  
    @after_this_request
    def cleanup(response):
        work_dir.cleanup()
        return response
   
    return send_file(output_file_path, mimetype='application/pdf')
  
  
if __name__ == "__main__":
    http_server = WSGIServer(('', int(os.environ.get('PORT', 8080))), app)
    http_server.serve_forever()


而且我们还有一个非常小的Docker文件。首先定义基本图像。

FROM python:3-alpine
ENV APP_HOME /app
WORKDIR $APP_HOME
RUN apk add libreoffice \
    build-base \ 
    # Install fonts
    msttcorefonts-installer fontconfig && \
    update-ms-fonts && \
    fc-cache -f
RUN apk add --no-cache build-base libffi libffi-dev && pip install cffi
RUN pip install Flask requests gevent
COPY . $APP_HOME
# prevent libreoffice from querying ::1 (ipv6 ::1 is rejected until istio 1.1)
RUN mkdir -p /etc/cups && echo "ServerName 127.0.0.1" > /etc/cups/client.conf
CMD ["python", "to-pdf.py"]

在我们的案例中,这是基于Python的官方映像。后来,我们安装了OpenOffice,并指定了start命令。然后,我们使用Cloud Build将所有这些打包到一个容器映像中,并将其部署到Cloud Run。在Cloud Run上,我们的微服务可以在几秒钟内自动扩展到数千个容器或实例。我们只是使用了一个旧版应用程序,并将其部署到微服务环境中,而无需更改任何代码。

但是有时您可能希望拥有更多控制权。例如,更大的CPU大小,对GPU的访问,更多的内存,或者可能使其在Kubernetes Engine集群上运行。对于GKE上的Cloud Run,它使用完全相同的界面。这次,我们将在GKE中部署完全相同的容器映像。

而且,我们现在选择的是GKE集群,而不是完全托管的区域。我们获得了与以前相同的Cloud Run开发人员体验。我们获得了一个稳定且安全的端点,可以自动扩展我们的微服务。

后台, GKE上的Cloud Run和Cloud Run由Knative提供支持, Knative是一个开源项目,用于运行去年启动的无服务器工作负载。这意味着我们实际上可以将完全相同的微服务部署到在Knative上运行的任何Kubernetes集群上。让我们来看看。

我们将微服务导出到文件service.yaml中。然后,使用以下命令,将其部署到另一个云提供程序上的托管Knative。

kubectl apply - f service.yaml

我们将输入以下命令以检索URL端点。

kubectl get ksvc

现在在另一个云提供商上。让我们通过输入以下命令来查看正在运行的服务:

gcloud beta run services describe pdf service

如果您熟悉Kubernetes,这些API版本和字段可能看起来很熟悉。

在这种情况下,我们不使用Kubernetes。但是由于Cloud Run实现了Knative API(Kubernetes的扩展),因此这是一个看起来像Kubernetes的API对象。 Knative使服务可以在环境之间可移植地运行,而无需供应商锁定。 Cloud Run为您提供了有关无服务器的所有您喜欢的东西。没有要管理的服务器,您可以保留在代码中,并且可以快速扩展,更重要的是,可以缩减为零。当没有周期运行时,您将不支付任何费用。使用任何二进制或语言,因为它取决于容器的灵活性。它使您可以访问Google Cloud生态系统和API。在完全托管的环境中或在GKE上,无论何时何地,您都能获得一致的体验。