Tutorial

Создание приложений в Kubernetes с помощью Okteto

Published on June 11, 2020
Русский
Создание приложений в Kubernetes с помощью Okteto

Автор выбрал Girls Who Code для получения пожертвования в рамках программы Write for DOnations.

Введение

Okteto CLI — это проект с открытым исходным кодом, который предоставляет локальный опыт разработки приложений, работающих на Kubernetes. С его помощью вы можете написать код на вашей локальной IDE. Как только вы сохраняете файл, изменения передаются на ваш кластер Kubernetes, и ваше приложение немедленно обновляется. Весь процесс происходит без необходимости создания образов Docker или использования манифестов Kubernetes, которые занимают достаточно много времени.

В этом обучающем руководстве вы будете использовать Okteto для повышения производительности при разработке родных приложений в Kubernetes. Сначала создайте кластер Kubernetes и используйте его для запуска стандартного приложения «Hello World». Затем используйте Okteto для разработки и автоматического обновления вашего приложения без необходимости локальной установки дополнительных программ.

Предварительные требования

Для прохождения этого обучающего руководства вам потребуется следующее:

Шаг 1 — Создание приложения «Hello World»

Программа «Hello World» — это классическая программа, традиционно используемая в веб-разработке. В нашем случае это простая веб-служба, которая отвечает «Hello World» на каждый запрос. После того, как вы создали кластер Kubernetes, можно создавать приложение «Hello World» на Golang и манифесты, которые вы будете использовать для его развертывания в Kubernetes.

Сначала измените домашний каталог:

  1. cd ~

Теперь создайте новый каталог под названием hello_world и перейдите в него:

  1. mkdir hello_world
  2. cd hello_world

Создайте и откройте новый файл под именем main.go в предпочитаемой IDE или текстовом редакторе:

  1. nano main.go

main.go будет веб-сервером на Golang, который возвращает сообщение Hello world!. Давайте используем следующий код:

main.go
package main

import (
    "fmt"
    "net/http"
)

func main() {
    fmt.Println("Starting hello-world server...")
    http.HandleFunc("/", helloServer)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

func helloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello world!")
}

Код в main.go означает следующее:

  • Первым выражением в исходном файле Go должно быть имя пакета package. Выполняемые команды всегда должны использовать package main.
  • Раздел import указывает, от каких пакетов зависит код. В нашем случае используются fmt для работы со строками и net/http для сервера HTTP.
  • Функция main — это точка входа в бинарный файл. Метод http.HandleFunc используется для настройки сервера для вызова функции helloServer при получении запроса на путь /. http.ListenAndServe запускает сервер HTTP, который прослушивает все сетевые интерфейсы на порту 8080.
  • Функция helloServer содержит логику обработчика запроса. В нашем случае Hello world! будет ответом на запрос.

Вам нужно создать образ Docker и передать его на ваш реестр Docker, чтобы Kubernetes мог его загрузить и запустить приложение.

Откройте новый файл под именем Dockerfile в предпочитаемой IDE или текстовом редакторе:

  1. nano Dockerfile

Файл Dockerfile будет содержать команды, необходимые для создания контейнера Docker вашего приложения. Давайте используем следующий код:

Dockerfile
FROM golang:alpine as builder
RUN apk --update --no-cache add bash
WORKDIR /app
ADD . .
RUN go build -o app

FROM alpine as prod
WORKDIR /app
COPY --from=builder /app/app /app/app
EXPOSE 8080
CMD ["./app"]

Файл Dockerfile​​​ содержит два этапа: builder и prod:

  • Этап builder содержит инструменты Go. Он отвечает за копирование файлов и построение бинарного файла Go.
  • Этап prod — это окончательный образ. Он будет содержать только урезанный вариант ОС и бинарный файл приложения.

Будет полезно следовать данной практике. Она помогает уменьшить производственные контейнеры и сделать их безопаснее, так как в них находится только ваше приложение и то, что нужно для его запуска.

Создайте образ контейнера (замените your_DockerHub_username на ваше имя пользователя Docker Hub):

  1. docker build -t your_DockerHub_username/hello-world:latest

Переместите его на Docker Hub:

  1. docker push your_DockerHub_username/hello-world:latest

Затем создайте новую папку для манифестов Kubernetes:

  1. mkdir k8s

При использовании манифеста Kubernetes вы указываете Kubernetes, как вы хотите запустить ваше приложение. В этот раз вы создадите объект развертывания. Создайте новый файл deployment.yaml в предпочитаемой IDE или текстовом редакторе:

  1. nano k8s/deployment.yaml

Ниже показано содержание объекта развертывания Kubernetes, который запускает образ Docker okteto/hello-world:latest. Добавьте это содержание в ваш новый файл, заменив в вашем случае okteto после метки image на your_DockerHub_username:

~/hello_world/k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  selector:
    matchLabels:
      app: hello-world
  replicas: 1
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-world
        image: your_DockerHub_username/hello-world:latest
        ports:
        - containerPort: 8080

Манифест развертывания состоит из трех основных разделов:

  • metadata определяет имя для вашего развертывания.
  • replicas определяет количество запускаемых копий.
  • template указывает Kubernetes, что нужно развертывать и какие метки добавлять. В нашем случае это один контейнер с образом okteto/hello-world:latest, прослушивающий порт 8080, с меткой app: hello-world. Обратите внимание, что эта метка используется и в разделе selector.

Теперь вам нужен доступ к приложению. Вы можете открыть приложение в Kubernetes, создав сервисный объект. Продолжим, используя для этого манифесты. Создайте новый файл service.yaml в предпочитаемой IDE или текстовом редакторе:

  1. nano k8s/service.yaml

Следующее содержание описывает службу, которая открывает объект развертывания hello-world, использующий балансировщик нагрузки DigitalOcean:

k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: hello-world
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      name: http
  selector:
    app: hello-world

Манифест службы имеет четыре основных раздела:

  • metadata указывает Kubernetes, как называть службу.
  • type указывает Kubernetes, как вы хотите открывать службу. В нашем случае он будет открывать ее внешним способом через балансировщик нагрузки DigitalOcean.
  • Метка ports указывает Kubernetes, какие порты открывать и как связывать их с развертыванием. В нашем случае вы откроете порт 80 внешним способом и направите его на порт 8080 вашего развертывания.
  • selector указывает Kubernetes, как управлять трафиком. В нашем случае любой под с меткой app: hello-world будет получать трафик.

Теперь у вас все готово для развертывания приложения «Hello World» в Kubernetes. Это будет сделано в следующем шаге.

Шаг 2 — Развертывание приложения «Hello World»

На этом шаге вы развернете приложение «Hello World» в Kubernetes, а затем проверите корректность его работы.

Начнем с развертывания приложения в Kubernetes:

  1. kubectl apply -f k8s

Вывод должен выглядеть так:

Output
deployment.apps "hello-world" created service "hello-world" created

Через минуту вы сможете получить IP-адрес вашего приложения. Используйте команду kubectl для проверки службы:

  1. kubectl get service hello-world

Вы увидите примерно следующий вывод с указанием объектов службы в Kubernetes. Обратите внимание на IP-адрес вашего приложения в столбце EXTERNAL-IP​​​:

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-world ClusterIP your_cluster_ip your_external_ip 8080/TCP 37s

Откройте браузер и перейдите на your_external_ip, указанный для приложения «Hello World». Прежде чем переходить к следующему шагу, убедитесь, что ваше приложение загружено и работает.

Hello World Okteto

До этого момента вы использовали традиционный путь развертывания приложений в Kubernetes. Каждый раз, когда вы захотите изменить код в приложении, вам будет нужно создать и использовать новый образ Docker, а затем получить этот образ из Kubernetes. Этот процесс может занять какое-то время. Okteto был разработан для упрощения внутреннего цикла разработки. Давайте рассмотрим, как Okteto CLI может нам помочь.

Шаг 3 — Установка Okteto CLI

Теперь вы можете повысить продуктивность разработки в Kubernetes, установив Okteto CLI. Интерфейс командной строки Okteto — это проект с открытым исходным кодом, который позволяет синхронизировать изменения кода приложения в Kubernetes. Вы можете продолжать использовать предпочитаемые IDE, отладчики или компиляторы без необходимости выполнения, создания, загрузки или повторного развертывания контейнеров для тестирования вашего приложения, как вы делали на предыдущих шагах.

Для установки Okteto CLI на компьютере с macOS или Linux запустите следующую команду:

  1. curl https://get.okteto.com -sSfL | sh

Давайте рассмотрим эту команду подробнее:

  • Команда curl используется для передачи данных на сервер и с сервера.
  • Флаг -s подавляет любой вывод.
  • Флаг -S показывает ошибки.
  • Флаг -f вызывает сбой запроса при ошибках НТТР.
  • Флаг -L делает переадресации запроса.
  • Оператор | передает вывод команде sh, которая будет загружать и устанавливать последний бинарный файл okteto на ваш локальный компьютер.

Если вы работаете на Windows, вы можете загрузить файл через веб-браузер и вручную добавить его в $PATH.

После установки Okteto CLI вы можете перевести приложение «Hello World» в режим разработки.

Шаг 4 — Перевод приложения «Hello World» в режим разработки

Okteto CLI​​​ разработан для подкачки приложения, работающего в кластере Kubernetes, с помощью кода, имеющегося на компьютере. Для этого Okteto использует информацию, полученную из файла Okteto manifest. Этот файл объявляет объект развертывания Kubernetes, который будет подкачиваться с помощью локального кода.

Создайте новый файл okteto.yaml в предпочитаемой IDE или текстовом редакторе:

  1. nano okteto.yaml

Давайте напишем базовый манифест, где вы определите имя объекта развертывания, базовый образ Docker и оболочку. Мы вернемся к этой информации позже. Используйте следующий пример файла содержимого:

okteto.yaml
name: hello-world
image: okteto/golang:1
workdir: /app
command: ["bash"]

Приготовьте переход вашего приложения в режим разработки с помощью запуска следующей команды:

  1. okteto up
Output
✓ Development environment activated ✓ Files synchronized Namespace: default Name: hello-world Welcome to your development environment. Happy coding! default:hello-world /app>

Команда okteto up выполняет подкачку приложения «Hello World» в среду разработки, что означает:

  • Контейнер приложения «Hello World» обновляется с помощью образа Docker okteto/golang:1. Этот образ содержит требуемые инструменты для разработки, тестирования, отладки и запуска приложения «Hello World».

  • Служба синхронизации создана для поддержки обновления изменений между локальной системой файлов и подами приложения.

  • Удаленная оболочка начинается в среде разработки. Теперь вы можете создавать, тестировать и запускать приложение, как если бы вы делали это на локальном компьютере.

  • Какой бы процесс вы ни запустили, удаленная оболочка получит такой же входящий трафик, те же переменные среды, тома или секреты, как и оригинальные поды приложения «Hello World». Это, в свою очередь, обеспечивает вам реалистичную среду разработки, схожую с производственной.

В той же консоли запустите приложение, как вы обычно это делаете (без построения и загрузки образа Docker), например так:

  1. go run main.go
Output
Starting hello-world server...

При первом запуске приложения Go загрузит зависимости и скомпилирует приложение. Дождитесь окончания процесса и проверьте приложение, открыв браузер и обновив страницу приложения, как вы уже это делали ранее.

Теперь вы можете начинать разработку непосредственно в Kubernetes.

Шаг 5 — Разработка непосредственно в Kubernetes

Начнем вносить изменения в приложение «Hello World» и посмотрим, как они отобразятся в Kubernetes.

Откройте файл main.go в предпочитаемой IDE или текстовом редакторе. Например, откройте отдельную консоль и запустите следующую команду:

  1. nano main.go

Затем измените сообщение ответа на Hello world from DigitalOcean! :

main.go
package main

import (
    "fmt"
    "net/http"
)

func main() {
    fmt.Println("Starting hello-world server...")
    http.HandleFunc("/", helloServer)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

func helloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello world from DigitalOcean!")
}

В этом месте ваш рабочий процесс меняется. Вместо создания образов и повторного развертывания контейнеров для обновления приложения «Hello World» Okteto будет синхронизировать изменения в вашей среде разработки в Kubernetes.

В консоли, где вы выполнили команду okteto up, отмените выполнение go run main.go​​​, нажав CTRL + C. Теперь перезапустите приложение:

  1. default:hello-world /app> go run main.go
Output
Starting hello-world server...

Вернитесь в браузер и перезагрузите страницу приложения «Hello World».

"Hello World DigitalOcean"

Изменения в коде были немедленно применены в Kubernetes, и все это без необходимости выполнения, построения или загрузки.

Заключение

Okteto преобразует кластер Kubernetes в полноценную платформу разработки одним нажатием кнопки. С помощью этого обучающего руководства вы установили и настроили Okteto CLI​​​ для итерации изменений кода непосредственно в Kubernetes максимально быстро. Теперь вы можете перейти в репозиторий шаблонов Okteto, чтобы посмотреть, как можно использовать Okteto с разными языками программирования и разными отладчиками.

Если вы поделитесь кластером Kubernetes с вашей командой, не забудьте предоставить каждому доступ к защищенному пространству имен Kubernetes, настроенному изолировано от других разработчиков, работающих в этом же кластере. Эта замечательная функция также предоставляется Okteto App в DigitalOcean Kubernetes Marketplace.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar

CTO @Okteto Inc

Docker Community Leader. Cloud Native Development Advocate.



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel