Еще в мае компания Cloudflare опубликовала в блоге сообщение о своем новом продукте: рабочих для платформ. Он является естественным развитием существующего продукта edge workers и открывает дверь к новому виду опыта разработчиков для сторонних интеграций. Нам достаточно взглянуть на Slack и их приложения Slack, чтобы понять, насколько ценными стали интеграции. Целые наборы инструментов для повышения производительности продаются как приложения Slack. Тем не менее, одним из ограничивающих факторов интеграций является необходимость для пользователей создавать собственную инфраструктуру и поддерживать ее. Если вы хотите создать приложение Slack, Slack не предоставит вам небольшую часть своей инфраструктуры для использования, вам придется создавать свою собственную. Этим объявлением Cloudflare пытается решить эту проблему, предоставляя своим пользователям возможность интегрироваться с Cloudflare через Cloudflare.
Почему это важно?
С такими продуктами, как Slack, очевидно, что инвестиции в создание и поддержку приложения Slack на собственной облачной инфраструктуре стоят того, потому что их пользовательская база гарантирует, что вы увидите рост, необходимый для оправдания затрат. Такие продукты, как GitHub или Discord, находятся в той же категории; их интеграционные платформы были успешными независимо от того, сколько ресурсов требуется для их запуска. Именно поэтому Savoir является приложением GitHub и поэтому мы рассматриваем возможность создания приложения Slack.
Но что происходит, если вы являетесь небольшим продуктом и не имеете возможности обеспечить возврат инвестиций? На примере Savoir мы являемся новой компанией с еще не успешным продуктом. Для нас очевидно, что интеграция была бы очень ценной. Что если бы мы могли дать пользователям возможность реагировать на Webhooks, которые вызывают изменения в контенте, и даже обновлять этот контент программно? Что если бы вы могли синхронизировать контент, отслеживаемый с помощью Savoir, с такими платформами, как GitBook, Readme или GraphCMS? Мы знаем, что у нас нет ресурсов, чтобы конкурировать с этими платформами, поэтому гораздо разумнее сосредоточиться на том, что делает нас уникальными: отслеживании документации на уровне кода. Очевидно, что интеграция — это путь к успеху.
Для создания интеграций до появления сообщения Cloudflare у нас было бы два варианта: создавать интеграции самостоятельно (и надеяться, что мы создадим их так, как хотят пользователи), или попросить наших пользователей взять на себя расходы по размещению собственной пользовательской интеграции, не имея возможности обещать им рост, необходимый для возврата денег. **Работники для платформ создают третий вариант: мы даем нашим пользователям возможность создавать интеграции, и мы их выполняем. **Тогда мы можем сосредоточиться на предоставлении нашим пользователям наилучшего DX, а они могут сосредоточиться на создании интеграции, соответствующей их потребностям. Это также оставляет дверь открытой для наших собственных интеграций — у нас есть прекрасная возможность создать собственную интеграционную платформу.
Функции для платформ
Короче говоря, мы очень рады потенциалу рабочих для платформ. Настолько, что я решил попробовать создать прототип клона, основываясь только на информации, содержащейся в анонсирующем сообщении в блоге. После этого длинного вступления давайте пройдемся по процессу создания прототипа и узнаем о Fission.io и Kubernetes в процессе.
Рабочие платформы описываются как изолированные и безопасные среды JavaScript, в которые пользователи могут загружать и выполнять функции JavaScript в среде V8. Здесь нет Node.js — он работает в чистой среде JavaScript, как если бы он работал в браузере, но без DOM. Это не бессерверная функция в том смысле, что мы должны отвечать на триггеры, как в более традиционной бессерверной среде (обычно реализуемой в виде экспресс-серверов). Скорее, Cloudflare предоставляет нам набор функций, которые мы можем использовать для прослушивания событий, и они будут выполнять функцию всякий раз, когда произойдет событие, которое мы прослушиваем. Давайте попробуем собрать это.
Я загрузил рабочую версию этого проекта на GitHub, не стесняйтесь следовать коду там, если что-то не работает, как описано в этом посте: https://github.com/Minivera/functions-for-platforms.
Предварительные условия
Проведя много исследований, я остановился на фреймворке Fission.io для поддержки этого проекта. Fission — это бессерверный фреймворк с открытым исходным кодом, работающий в kubernetes. Представьте себе AWS Lambdas, но мы контролируем каждую часть инфраструктуры. Kubernetes дает нам возможность определять среду, в которой будут выполняться контейнеры, и любые другие ресурсы, которые им необходимы. Это дает нам контроль, необходимый для создания нашей собственной среды для выполнения произвольного JavaScript с помощью движка V8. Каждая функция может быть изолирована настолько, насколько нам нужно, и Fission действительно отлично подходит для того, чтобы дать нам возможность быстро создать несколько окружений.
Поскольку Fission построен на Kubernetes, он возьмет на себя большую часть тяжелой работы и позволит нам сосредоточиться на том, что мы хотим. Я постараюсь объяснить все, что я делаю, но этот пост не будет слишком подробно рассказывать о Kubernetes. Вам понадобится Node.js, установленный на вашей машине. Я рекомендую использовать последнюю версию LTS (версия 16 на момент написания этой статьи).
Чтобы иметь возможность использовать Fission, нам сначала нужно настроить кластер kubernetes. Кластер — это «облачная» среда, в которой создаются и управляются все ресурсы. Это как ваш собственный специализированный GCP или AWS, работающий только с контейнерами. В этом посте я буду использовать Minikube для локального управления кластером, так как я нашел его наиболее совместимым с Fission. Это отличный инструмент с множеством утилит, и он запускает весь кластер внутри другого контейнера docker, что позволяет легко его очистить. Давайте приступим к настройке Minikube на нашей машине.
- Во-первых, установите docker в зависимости от вашей ОС. Как было сказано ранее, Minikube запускает кластер внутри контейнера Docker. Docker и Kubernetes являются очень взаимодополняющими инструментами, поэтому Docker, скорее всего, будет полезен, даже если вы не используете Minikube.
- Установите kubectl и helm, чтобы иметь возможность управлять кластером kubernetes.
kubectl
— это официальный инструмент Kubernetes CLI, аhelm
— утилита для создания и развертывания приложений kubernetes. Мы не будем использоватьhelm
непосредственно в этом посте, он является зависимостью Fission. - Установите fission CLI, он будет использовать
kubectl
иhelm
для автоматической настройки Fission. - Наконец, установите Minikube.
Когда все установлено, запустите кластер Minikube с помощью команды minikube start
в любом терминале. Minikube загрузит несколько docker-образов и запустит кластер. После завершения запустите команду eval $(minikube -p minikube docker-env)
в том же терминале. Это позволит этой терминальной сессии выполнять любую команду docker внутри кластера Minikube, что позволит нам делать такие вещи, как выталкивание или вытягивание образов внутри кластера. Без этой команды мы не сможем использовать наш пользовательский образ V8 локально, так как кластер не сможет получить доступ к нашему локальному реестру docker (он работает внутри контейнера). Обратите внимание, что эта команда работает только для текущей сессии терминала, если вы закроете терминал, вам придется запустить ее снова.
Последний шаг — это установка самого Fission на наш новый кластер. Существует несколько способов установки Fission, мы будем использовать helm
и установим его на Minikube. Выполните приведенную ниже команду — скопированную из официальной документации — чтобы Fission был установлен и готов к запуску.
export FISSION_NAMESPACE="fission"
kubectl create namespace $FISSION_NAMESPACE
kubectl create -k "github.com/fission/fission/crds/v1?ref=v1.16.0"
helm repo add fission-charts https://fission.github.io/fission-charts/
helm repo update
helm install --version v1.16.0 --namespace $FISSION_NAMESPACE fission
--set serviceType=NodePort,routerServiceType=NodePort
fission-charts/fission-all
Теперь мы готовы приступить к работе!
Функции загрузки
Одна важная вещь, которую я отметил из сообщения в блоге Cloudflare, это то, насколько важна скорость для их реализации. Очевидно, что они хотели, чтобы их интеграция была такой же быстрой, как и любая другая рабочая функция, работающая на их платформе. Мы не будем углубляться в работу этого проекта на границе или избегать потерь производительности от Fission, но мы хотим сделать как можно больше для повышения производительности.
По этой причине для загрузки файлов JavaScript мы будем использовать сетевой диск, а не что-то вроде CDN. Для выполнения этих файлов потребуется только прямой доступ к файловой системе, что должно быть намного быстрее, чем необходимость совершать путешествие в обе стороны к какому-то серверу CDN. Мы будем использовать файлы спецификаций YAML для управления нашей инфраструктурой и применять их с помощью kubectl
. Хотя мы могли бы использовать только команду CLI, я считаю, что файлы спецификаций гораздо более выразительны и настраиваемы. Изучив официальную документацию Kubernetes, мы обнаружили особый вид ресурса под названием «постоянный том». Постоянный том похож на том docker, но файлы, созданные в этом томе, являются постоянными, а не эфемерными. В Fission наши контейнеры будут постоянно запускаться и останавливаться, поэтому этот постоянный том — отличный способ обмена файлами между контейнерами.
Поскольку единственное, что нам нужно от Kubernetes, это управление этим томом, мы сохраним простые файлы спецификации. Создайте новый каталог kubernetes
и затем создайте файл code-volume.yaml
в этом каталоге. Скопируйте этот YAML в этот файл.
# kubernetes/code-volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: code-volume
namespace: fission-function
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
capacity:
storage: 5Gi
hostPath:
path: /data/code-volume/
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: code-volume-claim
namespace: fission-function
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
Этот файл спецификации YAML определяет сам том — он называется code-volume
— непосредственно в пространстве имен kubernetes для контейнеров функций Fission. Вкратце, пространства имен позволяют нам изолировать части кластера для более легкого управления, и Fission использует их очень часто. Мы хотим, чтобы наш том находился как можно ближе к месту выполнения функций (поскольку нам придется подключать этот диск к контейнерам, используемым функциями), поэтому мы создаем его непосредственно в этом пространстве имен. Это очень маленький диск в 5 гигабайт, но этого достаточно для тестирования.
Вторым созданным элементом является утверждение постоянного тома с именем code-volume-claim
. Отдельные контейнеры используют это утверждение для запроса доступа к постоянному тому, и оно позволяет нам определить базовые разрешения и доступ. Постоянный том в Kubernetes — это ресурс в кластере. Утверждение постоянного тома потребляет этот ресурс и определяет доступ к нему. В нашем случае мы говорим Kubernetes предоставить нам доступ к 3 гигабайтам из 5 доступных в режиме чтения-записи, и что только один узел может читать или писать одновременно через режим доступа ReadWriteOnce
. В реальной ситуации эти ограничения, скорее всего, приведут к блокировке доступа и предотвратят одновременный доступ. Это хорошо для прототипа, но нам придется управлять доступом должным образом, если мы хотим развернуть это в производстве.
Давайте создадим эти ресурсы сейчас. Выполните команду kubectl apply -f ./kubernetes/code-volume.yaml
в терминале. Это прикажет kubectl
взять файл спецификации, который мы только что создали, и применить его содержимое на нашем кластере. Если мы когда-нибудь изменим этот файл, выполнение той же команды обновит кластер, применив все измененные свойства, не создавая все заново. Довольно полезно.
Подобные файлы спецификаций очень полезны и значительно облегчают выполнение команд, поскольку нам не приходится надеяться на лучшее, используя аргументы команд. Fission также поддерживает файлы спецификаций; к любой команде Fission CLI можно добавить --spec
, чтобы создать файл спецификации в каталоге specs
. Затем мы можем выполнить команду fission spec apply --wait
для применения файлов спецификаций на кластере, как мы бы сделали это с помощью kubectl
.
В оставшейся части этой статьи мы будем использовать файлы спецификаций Fission через командные строки, так как это значительно упростит нам работу. Давайте начнем с создания самой папки spec. Выполните команду fission spec init
для инициализации этой папки, Fission добавит туда несколько файлов. Теперь мы можем приступить к созданию окружения и функции для загрузки скриптов. Создайте файл env-nodejs.yaml
в этой директории, скопируйте этот YAML в этот новый файл.
# specs/env-nodejs.yaml
apiVersion: fission.io/v1
kind: Environment
metadata:
creationTimestamp: null
name: nodejs
namespace: default
spec:
builder:
command: build
container:
name: ""
resources: {}
image: fission/node-builder
imagepullsecret: ""
keeparchive: false
poolsize: 3
resources: {}
runtime:
image: fission/node-env
podspec:
containers:
- name: nodejs
image: fission/node-env:latest
volumeMounts:
- name: code-volume
mountPath: /etc/code
volumes:
- name: code-volume
persistentVolumeClaim:
claimName: code-volume-claim
version: 2
Этот YAML определяет окружение Node.js. В fission окружение — это определение контейнеров, в которых будет выполняться каждая функция. Контейнеры работают в блоке, называемом pod, Fission создает произвольное количество pod и масштабирует их в зависимости от спроса. Вы можете рассматривать pods как файлы docker-compose, которые запускают несколько контейнеров с общими ресурсами. Все pods запускаются на узле, который представляет собой виртуальную машину с кучей docker-compose файлов (pods), запущенных на ней. Fission позаботится о создании pods и автоматически сбалансирует запросы для всех pods.
Этот файл был создан путем выполнения команды fission environment create --name nodejs --image fission/node-env --spec
, с некоторыми изменениями. Мы даем имя nodejs
нашей среде в строке 6, затем мы говорим Fission использовать официальный образ Node.js в строке 14 для создания контейнера и официальный образ Node.js runtime для функции в строке 20. Наконец, мы определяем пользовательский объект podspec
в строке 21, где мы монтируем наш постоянный том как том docker, то есть у каждого контейнера теперь будет каталог /etc/code
, где они смогут получить доступ к содержимому постоянного тома. podspec
— это очень мощный инструмент, который дает нам возможность конфигурировать контейнеры в pod. Например, мы можем добавить второй контейнер с redis, если нам понадобится эфемерная база данных redis.
Мы будем использовать Node.js для загрузки кода в наш постоянный том. Fission поддерживает полные проекты NPM с модулями, но нашему коду нужны только базовые модули Node.js, поэтому мы упростим задачу, создав один скрипт. Создайте каталог src
и добавьте в него файл function-upload.js
, скопируйте туда следующий код.
// src/function-upload.js
const { promises } = require('fs');
const path = require('path');
// Path to the persistent volume
const diskPath = `/etc/code`;
// Function to hash a string into a short string.
const hashContent = (content) => {
let hash = 0;
if (content.length === 0) {
return hash;
}
let chr;
for (let i = 0; i < content.length; i++) {
chr = content.charCodeAt(i);
hash = (hash << 5) - hash + chr;
hash |= 0;
}
return hash;
};
// Fission will execute the function we export in the Node.js environment.
// Content contains things like the body and headers
module.exports = async function (context) {
// This function expects a raw body (no JSON) for uploading a JavaScript script
const fileContent = context.request.body;
console.log(`Received function "${fileContent}", hashing.`);
// Create a file name based on the file content. We hash that content so
// the same content will always have the same name.
const fileHash = hashContent(fileContent);
console.log(`Writing file ${fileHash}.js to the persistent volume`);
// Write the file content onto the persistent volume.
await promises.writeFile(path.join(diskPath, `${fileHash}.js`), fileContent);
return {
status: 200,
body: {
message: 'function successfully uploaded',
// We return the filename so we can execute it later
id: fileHash,
},
};
}
Эта функция определяет базовый код API для загрузки скрипта. Мы получаем сценарий в виде необработанного строкового тела вызова POST, затем хэшируем его содержимое для создания уникального имени файла. Наконец, мы создаем файл на постоянном томе для размещения этого файла и возвращаем хэшированное имя для выполнения этой функции в нашей функции V8.
Выполните fission function create --name function-upload --env nodejs --code src/function-upload.js --spec
для создания спецификации функции, а затем fission httptrigger create --url /upload --method POST --name upload-js --function function-upload --spec
для создания спецификации HTTP-триггера. Запустите fission spec apply --wait
, чтобы применить созданные файлы спецификаций на кластере.
В Fission функция — это определение для выполнения кода в среде. В данном случае мы говорим Fission запустить наш код для загрузки скриптов в среде Node.js. Триггер — это то, что заставляет функцию выполняться. В Fission есть несколько типов триггеров, но поскольку это API, мы будем использовать триггеры HTTP. Это говорит Fission запускать функцию всякий раз, когда HTTP-вызов отправляется на указанный URL, /upload
в нашем случае.
Не стесняйтесь проверить выполнение функции с помощью curl
. Для этого экспортируйте URL маршрутизатора Fission (точка входа для вызова HTTP-триггеров) в качестве переменной окружения в терминале с помощью этой команды
export FISSION_ROUTER=$(minikube ip):$(kubectl -n fission get svc router -o jsonpath='{...nodePort}')
В том же терминале попробуйте выполнить эту команду, чтобы отправить POST-запрос нашей функции загрузки. Запрос должен выполниться и вернуть полезную нагрузку в формате JSON с идентификатором файла.
curl -XPOST "http://$FISSION_ROUTER/upload" -H "Content-Type: text/plain" -d 'console.log("Hello, World!")'
В средах MacOS или Windows вам может понадобиться балансировщик нагрузки. Обратитесь к официальной документации Minikube, чтобы настроить его. В репозитории проекта есть готовый файл спецификации kubernetes в папке kubernetes
, если это необходимо.
Выполнение функций
Теперь, когда у нас все готово для загрузки кода, нам нужен способ выполнить этот код в безопасной среде V8. В сообщении блога Cloudflare ясно сказано, что V8 был ключом к разблокированию безопасной и изолированной среды, поэтому мы будем следовать по их стопам. Это означает, что мы не можем использовать среду Node.js по умолчанию из Fission, нам придется создать свою собственную. К счастью, Fission имеет бинарное окружение, которое мы можем частично использовать для этого.
Чтобы создать собственное окружение, нам нужно создать образ контейнера для использования в качестве среды выполнения. В Fission также есть концепция билдеров — образов, которые создают окружения на основе заданного кода (например, окружение Node.js установит зависимости, определенные в файле package.json
). Нам нужно только определить нашу собственную среду выполнения, мы можем повторно использовать бинарный конструктор, поскольку мы будем использовать файл bash в качестве нашего функционального скрипта. Давайте начнем с базового бинарного образа и изменим Dockerfile, чтобы добавить V8 в этот образ.
Загрузите содержимое этой папки в официальном репозитории среды Fission: https://github.com/fission/environments/tree/master/binary и скопируйте два файла .go
и Dockerfile
во вновь созданный каталог image
. Откройте Dockerfile
и замените его содержимое этим кодом:
# image/Dockerfile
# First stage, to copy v8 into the cache. V8 is built for Debian
FROM andreburgaud/d8 as v8
RUN ls /v8
# Second stage, build the Fission server for Debian
FROM golang:buster as build
WORKDIR /binary
COPY *.go /binary/
RUN go mod init github.com/fission/environments/binary
RUN go mod tidy
RUN go build -o server .
# Third stage, copy everything into a slim Debian image
FROM debian:stable-slim
RUN mkdir /v8
COPY --from=v8 /v8/* /v8
WORKDIR /app
RUN apt-get update -y &&
apt-get install coreutils binutils findutils grep -y &&
apt-get clean
COPY --from=build /binary/server /app/server
EXPOSE 8888
ENTRYPOINT ["./server"]
Этот Dockerfile состоит из трех этапов. Сначала мы загружаем и тестируем образ, найденный в реестре Docker под названием andreburgaud/d8
. Этот образ содержит V8, предварительно собранный для Debian (на MacOS может потребоваться сборка V8), поэтому мы можем сэкономить несколько часов, необходимых для его сборки. На втором этапе мы копируем официальные файлы .go
из двоичной среды Fission и собираем их для Debian. Эти файлы go создают сервер, который принимает команды от триггеров и выполняет бинарный файл в ответ, именно так Fission поддерживает любой бинарник. Наконец, третий этап собирает всё вместе, устанавливая контейнер, определённый в исходном бинарном файле Dockerfile
и копируя V8 в определённый каталог, чтобы он был доступен.
Выполните команду docker build --no-cache --tag=functions/v8-env .
в том же терминале, где вы ранее выполняли eval $(minikube -p minikube docker-env)
. Это создаст образ и пометит его под functions/v8-env
внутри кластера Minikube, чтобы Fission мог получить к нему доступ.
Пора создать наше окружение! Снова перейдите в каталог specs
и создайте файл env-v8.yaml
. Скопируйте в него этот YAML.
# specs/env-v8.yaml
apiVersion: fission.io/v1
kind: Environment
metadata:
creationTimestamp: null
name: v8
namespace: default
spec:
builder:
command: build
container:
name: ""
resources: {}
image: fission/binary-builder:latest
imagepullsecret: ""
keeparchive: false
poolsize: 3
resources: {}
runtime:
image: functions/v8-env:latest
podspec:
containers:
- name: v8
image: functions/v8-env:latest
volumeMounts:
- name: code-volume
mountPath: /etc/code
readOnly: true
volumes:
- name: code-volume
persistentVolumeClaim:
claimName: code-volume-claim
version: 2
Эта среда очень похожа на среду Node.js, только мы используем официальный образ fission/binary-builder
из Fission для сборки контейнера и наш собственный functions/v8-env
для времени выполнения контейнера. Как и в случае со средой Node.js, мы также подключаем постоянный том, но на этот раз в режиме readOnly
. Мы не хотим, чтобы наши пользователи могли записывать данные на том из своих скриптов.
Далее перейдите в каталог src
и создайте файл function.sh
. Скопируйте этот код в новый файл.
# src/function.sh
#!/bin/sh
file_id="$(/bin/cat -)"
printf "executing /etc/code/%s.js with /v8/d8nn" "$file_id"
printf "output is: n"
# This will not print errors but instead causes the process to crash, for now
/v8/d8 "/etc/code/$file_id.js"
Когда сервер go из официальной среды Fission запускает скрипт или бинарный файл, он предоставляет тело запроса в стандартном потоке ввода (доступном для чтения из него с помощью /bin/cat -
). Чтобы избежать необходимости разбирать JSON или заголовки, мы возьмем имя файла из предыдущей функции загрузки в качестве необработанного тела и выполним JS-файл из постоянного тома в V8 напрямую.
Давайте теперь создадим функцию и триггер. Запустите fission function create --name run-js --env v8 --code src/function.sh --spec
, затем fission httptrigger create --url /execute --method POST --name run-isolated --function run-js --spec
, чтобы создать два файла спецификации. Запустите fission spec apply --wait
, чтобы применить только что созданные файлы спецификаций на кластере.
Теперь у нас есть функция, которая может загрузить JS-скрипт, загруженный через нашу функцию Node.js, и выполнить его в изолированной и контролируемой среде V8. Мы можем контролировать, сколько ресурсов имеет функция через файл спецификации окружения, а также сколько времени ей разрешено работать. Благодаря Fission и Kubernetes мы имеем полный контроль над тем, сколько ресурсов мы даем нашим пользователям.
Тестирование функций
Последний этап — это тестирование того, что мы только что создали! Если вы еще не сделали этого, экспортируйте URL маршрутизатора Fission как переменную окружения в терминале с помощью этой команды.
export FISSION_ROUTER=$(minikube ip):$(kubectl -n fission get svc router -o jsonpath='{...nodePort}')
В том же терминале, где вы экспортировали URL маршрутизатора, выполните эту команду, чтобы отправить POST-запрос функции upload. Она должна вернуть полезную нагрузку JSON с идентификатором файла в свойстве id
.
curl -XPOST "http://$FISSION_ROUTER/upload" -H "Content-Type: text/plain" -d 'console.log("Hello, World!")'
Скопируйте идентификатор и запустите curl -XPOST -k -d "<ID>" "http://$FISSION_ROUTER/execute"
, заменив им <ID>
. Вы должны увидеть в терминале слова Hello, World!
. Это означает, что все получилось!
Что именно здесь произошло? Когда вы отправили первый запрос, маршрутизатор Fission отправил его нашей функции upload, запущенной в контейнере Node.js, которая затем создала этот файл в нашем постоянном томе. Второй запрос затем направляется к нашей функции выполнения, работающей в наших пользовательских контейнерах V8, которая загружает тот же файл на основе его идентификатора файла из тома и запускает его, печатая результат на стандартный вывод. Бинарное окружение Fission настроено таким образом, что любой вывод отправляется обратно как результат HTTP-вызова.
Не стесняйтесь проверить это с более сложным кодом, код должен печатать все, что вы попросите его записать в журнал. Следующим шагом для этого прототипа будет предоставление переменных окружения и функций нашим пользователям, чтобы они могли реагировать на события, вызванные нашей системой, но об этом в другой раз!
Куда двигаться дальше?
В этом посте мы создали прототип для клонирования продукта Cloudflare для рабочих платформ. Наша реализация показывает некоторые перспективы, но она также очень ограничена и несовершенна. Из-за выбора фреймворков и технологий, а также из-за характера этого проекта, который полностью основан на одной записи в блоге, у этого прототипа есть несколько недостатков, о которых стоит рассказать.
Во-первых, любой человек технически может получить доступ к чужим скриптам. Пользователь потенциально может написать сценарий, который перебирает все файлы в постоянном томе и печатает код каждого файла, что может привести к утечке секретов, сохраненных непосредственно в нем (даже без модуля Node.js fs
). Нам придется убедиться, что каждая функция может видеть только свой сценарий и ничего больше.
Следующая проблема — доступ. На данный момент любой может получить доступ к двум конечным точкам и сделать практически все, что захочет, если мы развернем это в облаке. Первый шаг к развертыванию — убедиться, что эти две конечные точки доступны только для других внутренних служб и защищены. Нам придется создать отдельную службу для маршрутизации запросов к нашему кластеру Fission или что-то подобное, чтобы абстрагировать реализацию.
Наконец, есть вопрос производительности. Этот прототип не настроен для работы на границе, но у него также есть некоторые проблемы с производительностью, которые необходимо улучшить, чтобы удовлетворить требования, изложенные в блоге Cloudflare. Бессерверная природа этого проекта означает, что нам придется иметь дело с холодным стартом и ограниченными ресурсами в наших кластерах kubernetes.
Эти вопросы оптимизации выходят далеко за рамки данного первого поста, но, возможно, мы сможем продолжить их изучение в одном из следующих постов! В любом случае, я надеюсь, что вам понравился этот длинный пост, и я с нетерпением жду, когда сообщество увидит, как будет развиваться workers-for-platforms.
Пожалуйста, загляните в репозиторий, куда я загрузил рабочую версию прототипа: https://github.com/Minivera/functions-for-platforms. Вклад приветствуется.
Пожалуйста, дайте мне знать, что вы думаете об этом сообщении в комментариях ниже, я буду рад узнать, куда мы можем пойти дальше!