Kubernetes – Serverless computing своими руками
Как правило, вы пишете код в своем окружении разработчика, а затем создаете отдельное окружение для развертывания вашего кода и тестирования его работы. Даже для работы с небольшим количеством кода вам нужно пройти через процессы создания виртуальной машины или контейнера в облаке, деплоймента кода и дальнейшей его поддержки.
Идея безсерверных (serverless) вычислений заключается в том, что она позволяет вам, как разработчику, сосредоточиться только на написании кода. При использовании подхода безсерверных вычислений вы просто загружаете код куда-нибудь, а дальше он сам запускается всякий раз, когда вы или сторонний сервис его вызываете. Проще говоря, безсерверные вычисления освобождают вас от сложностей создания контейнеров Docker или настройки и поддержки кластеров Kubernetes.
В этом руководстве будет показано, как начать работу с бессерверными вычислениями с использованием платформы Kubeless, работающей поверх кластера Kubernetes в нашем уже развернутом кластере.
Введение
Для начала экспериментов с безсерверными вычислениями вам понадобятся:
- Работающий Kubernetes кластер
- Kubeless
- Немного кода (само собой, мы вас им обеспечим)
Если работающий кластер Kubernetes у вас уже есть, то далее мы с вами сделаем следующее:
- Запустим Dashboard в Kubernetes кластере
- Установим Kubeless
- Напишем облачную функцию
- Зарегистрируем нашу функцию в Kubeless
- Вызовем написанную нами функцию
Запуск Kubernetes Dashboard
Если у вас уже есть запущенный кластер Kubernetes, то скорее всего Dashboard у вас уже установлена. Проверить это можно командой:
$ kubectl get pods --all-namespaces | grep dashboard
Если Dashboard отсутствует, выполните следующую команду:
$ kubectl create -f https://git.io/kube-dashboard
Доступ к Dashboard по-умолчанию осуществляется через проксирование к нему запросов командой
$ kubectl proxy Starting to serve on 127.0.0.1:8001
Сам Dashboard при этом становится доступен по адресу http://localhost:8001/ui
.
Как только доступ к Kubernetes Dashboard получен, можно переходить к установке Kubeless.
Установка Kubeless
Kubeless — это приложение, предназначенное для развертывания поверх кластера Kubernetes. Оно принимает команды для регистрации, удаления и отображения списка функций, которые вы хотите запустить.
Используйте следующие команды для установки Kubeless:
$ curl -L https://github.com/skippbox/kubeless/releases/download/0.0.7/kubeless_linux-amd64.zip > kubeless.zip
$ unzip kubeless.zip
$ cd kubeless_linux-amd64
$ ./kubeless install
We are going to install the controller in the kubeless namespace. Are you OK with this: [Y/N]
Y
INFO[0002] Initializing Kubeless controller... pkg=controller
INFO[0002] Installing Kubeless controller into Kubernetes deployment... pkg=controller
INFO[0005] Kubeless controller installation finished! pkg=controller
INFO[0005] Installing Message Broker into Kubernetes deployment... pkg=controller
INFO[0007] Message Broker installation finished! pkg=controller
Далее можно либо скопировать kubeless в /usr/local/bin, либо прописать его расположение в $PATH. Я выберу первый вариант:
$ sudo cp kubeless /usr/local/bin
Протестируйте работу Kubeless, выполнив команду:
$ kubeless function ls
NAME HANDLER RUNTIME TYPE TOPIC NAMESPACE
Если зайти в Kubernetes Dashboard, можно увидеть пространство имен kubeless, которое дополнительно покажет, что Kubeless был успешно установлен.
Написание функции
Теперь, после того, как вас появился запущенный Kubeless, вы можете забыть о контейнерах, виртуальных машинах, Kubernetes и т.д. Все, что вам теперь нужно, это просто писать код.
Вот не сложный пример:
import urllib2
import json
def get_titles(request):
url = «https://jsonplaceholder.typicode.com/posts»
response = urllib2.urlopen(url)
posts = json.loads(response.read())
titles = []
for post in posts:
titles.append(post["title"])
return json.dumps(titles)
ПРИМЕЧАНИЕ: эта функция для простоты понимания сознательно написана без какой-либо обработки ошибок или проверок ввода. Не используйте эту функцию в ваших реальных приложениях.
Это очень простая функция, ее цель — просто вернуть список всех заголовков из ответа сервера. Чтобы добавить похожую функцию в существующее приложение, вы, как правило, интегрируете ее с существующей кодовой базой, создаете новые виртуальные машины или контейнеры и выполняете ее canary деплоймент. Однако, при использовании безсерверных вычислений вы можете просто зарегистрировать эту функцию, затем использовать ее в случае необходимости.
Сохраните эту функцию в файле, например, /tmp/test-function.py
и переходите к следующему разделу.
Регистрация функции в Kubeless
Наш следующий шаг — зарегистрировать функцию с помощью Kubeless. Регистрация функции с помощью Kubeless включает в себя передачу Kubeless следующей информации:
- Имя, которое вы будете использовать для доступа к функции
- Протокол, к которому вы будете обращаться к функции (здесь, HTTP)
- Окружение, в котором будет исполняться запущенный код (здесь, Python)
- Имя файла, содержащего код функции
- Имя функции внутри файла
Вся эта информация легко передается в Kubeless при помощи команды kubeless function create
:
$ kubeless function create get_titles --trigger-http --runtime python27 --handler test-function.get_titles --from-file /tmp/test-function.py
Давайте разберем этот пример:
Команда kubeless create get_titles
сообщает Kubeless зарегистрировать новую функцию с именем get_titles
. Эта функция будет доступна по сети по протоколу HTTP. Обратите внимание, что имя не обязательно должно быть точно таким же, как имя функции в фале.
--trigger-http
сообщает Kubeless, что функция будет вызываться через HTTP. Также можно запускать функцию другими способами, но это не тема данной статьи.
--runtime python27
сообщает Kubeless, что необходимо использовать Python 2.7 для исполения кода.
--handler test-function.get_titles
сообщает Kubeless имя функции для вызова внутри Python модуля. Вы наверняка заметили в приведенном выше коде Python, что функция называется get_titles()
.
--from-file /tmp/test-function.py
сообщает Kubeless, что необходимо загрузить и использовать файл /tmp/test-function.py в качестве исходника для этой функции.
Как только команда завершит выполнение, проверьте, что функция зарегистрирована в Kubeless, используя команду kubeless function ls
:
$ kubeless function ls
Чтобы удалить эту функцию, выполните команду:
$ kubeless function create get_titles --trigger-http --runtime python27 --handler test-function.get_titles --from-file /tmp/test-function.py
Давайте разберем этот пример:
Команда kubeless create get_titles
сообщает Kubeless зарегистрировать новую функцию с именем get_titles
. Эта функция будет доступна по сети по протоколу HTTP. Обратите внимание, что имя не обязательно должно быть точно таким же, как имя функции в фале.
--trigger-http
сообщает Kubeless, что функция будет вызываться через HTTP. Также можно запускать функцию другими способами, но это не тема данной статьи.
--runtime python27
сообщает Kubeless, что необходимо использовать Python 2.7 для исполения кода.
--handler test-function.get_titles
сообщает Kubeless имя функции для вызова внутри Python модуля. Вы наверняка заметили в приведенном выше коде Python, что функция называется get_titles()
.
--from-file /tmp/test-function.py
сообщает Kubeless, что необходимо загрузить и использовать файл /tmp/test-function.py в качестве исходника для этой функции.
Как только команда завершит выполнение, проверьте, что функция зарегистрирована в Kubeless, используя команду kubeless function ls
:
$ kubeless function ls
Чтобы удалить эту функцию, выполните команду:
$ kubeless function delete get_titles
Вызов функции
Давайте посмотрим на код нашей функции. Сразу видно, что функция ожидает, что она будет вызвана методом POST. Таким образом, для для ее вызова необходимо всего лишь отправить этот запрос:
$ curl localhost:8080/api/v1/proxy/namespaces/default/services/get_titles/ --header "Content-Type:application/json"
В ответ вы получите список тем постов демо json-сервиса.