Advertisement
  1. Code
  2. Docker

Введение в Докер и Кубернетес

Scroll to top
Read Time: 13 min

() translation by (you can also view the original English article)

Широкомасштабные распределенные системы, состоящие из нескольких взаимодействующих сервисов, становятся все более важными. Эти системы работают на кластерах сотен, тысяч и более серверов. Разработка, развертывание и обслуживание этих систем эффективно и экономично требует серьезного  порядка.

Виртуализация и, в последнее время, использование контейнеров позволяют гибко распределять ресурсы и управлять ими. Докер сделал контейнеризацию популярной. Ознакомьтесь с этой статьей Envato Tuts + для отличного введения: «Руководство автостопом по Docker и Modulus».

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

В этой статье я кратко исследую Докер, а затем глубоко погружаюсь в Кубернетес. Я буду использовать в качестве примера пример службы REST API Python 3. Приступим.

Служба цитат

Служба цитат - это REST API, который позволяет добавлять цитаты и получать список всех цитат. Он реализован как веб-сервис Python 3, используя отличную библиотеку hug. Сервис предоставляет один ендпоинт /quotes. Вы можете получить все цитаты или опубликовать новую цитату. Давайте добавим несколько цитат:

1
curl https://localhost:8000/quotes -d "quote=TV is chewing gum for the eyes. ~ Frank Lloyd Wright"
2
curl http://localhost:8000/quotes -d "quote=It is better to die on your feet than live on your knees. ~ Emiliano Zapata"
3
curl http://localhost:8000/quotes -d "quote=We must be very careful when we give advice to younger people: sometimes they follow it! ~ Edsger W. Dijkstra"

Если вы перейдете по ссылке http://localhost:8000/quotes, вы получите: [ "TV is chewing gum for the eyes. ~ Frank Lloyd Wright", "It is better to die on your feet than live on your knees. ~ Emiliano Zapata", "We must be very careful when we give advice to younger people: sometimes they follow it! ~ Edsger W. Dijkstra" ] Если вы просто хотите просмотреть автогенерированную документацию HUG, перейдите по адресу: http://localhost:8000

1
{
2
    "404": "The API call you tried to make was not defined. Here's a definition of the API to help you get going :)",
3
    "documentation": {
4
        "/quotes": {
5
            "GET": {
6
                "examples": [
7
                    "http://localhost:8000/quotes"
8
                ],
9
                "outputs": {
10
                    "content_type": "application/json",
11
                    "format": "JSON (Javascript Serialized Object Notation)"
12
                }
13
            },
14
            "POST": {
15
                "outputs": {
16
                    "content_type": "application/json",
17
                    "format": "JSON (Javascript Serialized Object Notation)"
18
                },
19
                "inputs": {
20
                    "quote": {
21
                        "type": "Basic text / string value"
22
                    }
23
                }
24
            }
25
        }
26
    }
27
}

Основы Docker

Я не буду объяснять слишком много о Docker, а просто буду применять его в сервисе цитат.

Отправляем приложение Python в контейнер

Сначала нам нужен Dockerfile. Он выполняет следующие действия:

  1. Делает основу из последнего образа ubuntu
  2. Устанавливает Python 3 и несколько других зависимостей
  3. Скопирует каталог quot-service
  4. Устанавливает зависимости quot-service из файла require.txt
  5. Предоставляет порт 8000
  6. Запустит сервис цитат через hug
1
FROM ubuntu:latest
2
MAINTAINER Gigi Sayfan "the.gigi@gmail.com"
3
RUN apt-get update -y
4
RUN apt-get install -y python3 python3-pip python3-dev build-essential
5
COPY . /quote-service
6
WORKDIR /quote-service
7
RUN pip3 install -r requirements.txt
8
EXPOSE 8000
9
ENTRYPOINT hug -f app.py

Создаем образ

Следующий шаг - создать образ Docker. Это так просто:

docker build .

Мне также нравится добавлять образам теги:

docker tag 715624b7e22a g1g1/quote-service

g1g1 - мое имя пользователя на Docker Hub.

Чтобы убедиться, что образ был успешно создан, введите:

1
docker ps --all

Вы должны увидеть новый образ:

1
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS                     PORTS                    NAMES
2
715624b7e22a        g1g1/quote-service   "/bin/sh -c 'hug -f a"   4 hours  ago         Up 35 minutes              0.0.0.0:8000->8000/tcp   agitated_northcutt

Отправка образа в Docker Hub

Когда вы создаете образ, вы также можете отправить его в Docker Hub, чтобы его могли использовать другие люди (или самостоятельно на другой машине).

docker push g1g1/quote-service

Обратите внимание, что вам необходимо создать учетную запись на Docker Hub и войти в систему локально, используя:

docker login

Запуск приложения

ОК. Давайте запустим образ сервиса цитат и выставим хосту порт 8000.

docker run -i -t -p 8000 g1g1/quote-service

Вы увидите следующее: /############################################# ############################ `` .---- `` ..------- .. `` .- ---. : / ::::: - ---------: - ::::: //. . + :::: ---- ## // оо +: - ## ---- :::: // `// :: ------- / oosoo ------- ::: //. ## ## ## ## ##### .-: ------./++ o / o -.------ :: - ` ## ## ## ## ## ----.-./+o+:..----. .: ///. ######## ## ## ## `----.- :::::: ------ `.- :::: //. ## ## ## ## ## ####: // :: -. -: ... ----- ... ``: - ::::::.. ############: / ::::::::: -: - `` `. ::::: -. ## ## #### ###### .-- :::::::. . :::. `` .. ::. . :: EMBRACE API OF THE FUTURE :: -.: - -:: ::- VERSION 1.9.6 ::- -:: -::- -::- ######################################################################## Copyright (C) 2015 Timothy Edmund Crosley Under the MIT License

Serving on port 8000… ``` Очень круто. Прежде чем попытаться получить доступ к своей службе awesome quote на порту 8000, вам может потребоваться выполнить дополнительную работу в зависимости от вашей среды.

Если вы работаете под Mac OS X с помощью VirtualBox и док-машины, вам может потребоваться опубликовать порт 8000 на VirtualBox, чтобы сделать его доступным на хосте.

Предполагая, что вы попытались просмотреть http://localhost:8000/quotes. О нет. Внутренняя ошибка сервера! Что случилось?

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

1
redis_host = os.environ.get('QUOTE_STORE_SERVICE_HOST', 'localhost')
2
redis_server = redis.StrictRedis(host=redis_host, port=6379, db=0)

Служба цитат пытается подключиться к серверу redis. Адрес хоста может быть настроен как переменная среды, и если он не установлен, он будет по умолчанию установлен на localhost. К сожалению, redis не установлен по умолчанию, и он не запускается внутри контейнера. Давайте исправим это временно. Чтобы получить доступ к оболочке в контейнере, введите следующую команду:

docker exec -it 715624b7e22a /bin/bash

Затем вы получите доступ к оболочке для контейнера, и вы можете установить redis:

root@715624b7e22a:/quote-service# apt-get install redis-server

Наконец, запустите root@715624b7e22a:/quote-service# redis-server [25] 29 Nov 00:14:24.546 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 2.8.4 (00000000/0) 64 bit .-`` .-. ```\/ ., ‘’-._ ( ‘ , .- | ,) Running in stand alone mode | -._- ... - __...-.-._ | ' .- «| Port: 6379 | -._ . / .- '| PID: 25 -._ -. -. / _.- '_.-' | -.- ._ -..- '_.-'_.-' | | -._-._ _.-'_.- '| Http://redis.io -._ -._-.__.-'_.- '_.-' | -._-._ -..- '_.-' .- '| | -._-._.-'.-' | -._ -.- .__.-'_.- '_.-' -. -.__.- '_.-' -._ _.- '`-.__.-'

[25] 29 Nov 00:14:24.547 # Server started, Redis version 2.8.4 [25] 29 Nov 00:14:24.547 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. Чтобы исправить эту проблему добавьте ‘vm.overcommit_memory = 1’ в файл /etc/sysctl.conf а затем перезагрузите систему и выполните команду ‘sysctl vm.overcommit_memory=1’ чтобы изменения вступили в силу. [25] 29 Nov 00:14:24.547 * DB loaded from disk: 0.000 seconds [25] 29 Nov 00:14:24.547 * The server is now ready to accept connections on port 6379 ``` Теперь вы можете просматривать и добавлять цитаты по адресу http://localhost:8000/quotes.

Размещение приложения (служба цитат) и базы данных (redis) работает на одном сервере. Но, очевидно, это не масштабируется. Войдите в Кубернетес.

Основы Кубернетеса

Кубернетес, a.k.a. K8s, является уместной основой для управления и организации нескольких контейнеров. У этого есть свой собственный способ как делать вещи, которые обычно очень хороши. Он все еще находится в разработке, поэтому иногда могут возникать проблемы. Кубернетес имеет много концепций и очень гибкий. Я объясню и продемонстрирую концепции, применив их к сервису цитат.

Настройка кластера

Существует множество способов создания кластера Kubernetes. Kubernetes может работать на простом сервере, на Google Container, на AWS, и локально на любой ОС с использованием виртуальных машин. Для целей этой статьи я создал кластер из одного мастера и двух миньонов с помощью кластера Core OS OSX GUI k8s. В Mac OS X имеется небольшое меню, в котором вы можете получить доступ ко многим инструментам управления кластерами.

Следуйте инструкциям, и вы быстро все настроите.

Если вы не используете Mac OSX или просто не интересуетесь графическим интерфейсом, вы можете использовать этот проект для настройки тестового кластера в Vagrant VM.

С этого момента я буду использовать командную строку.

Инструмент командной строки kubectl

Kubectl - швейцарский армейский нож Кубернетеса. Вы можете полностью управлять своим кластером с комфортом из своей консоли, используя только kubectl.

Ниже приведен список команд: get Показать один или несколько ресурсов show Показывать детали определенного ресурса create Создайте ресурс по имени файла или stdin update Обновить ресурс по имени файла или stdin. Delete Удалить ресурс по имени файла, stdin, ресурсу и идентификатору, а также по ресурсам и селектору ярлыков. Namespace SUPERCEDED: установить и просмотреть текущий журнал пространства имен Kubernetes.  Roll-update Выполнять текущее обновление данного контроллера репликации. Resize Установите новый размер для контроллера репликации. Exec Выполнить команду в контейнере. port-forward Переместить один или несколько локальных портов в контейнер. proxy Запустить прокси-сервер для сервера-загрузчика API-интерфейса Kubernetes Запустить определенный образ в кластере. stop корректно отключить ресурс по имени или имени файла. expose взять реплицированное приложение и опубликовать его в Kubernetes Service. label обновить метки ресурса config  Изменяет файлы kubeconfig. cluster-info Отображает информацию о кластере  api-versions выводит доступные версии API. version выводит информацию о версии клиента и сервера. help Справка о любой команде

Не стесняйтесь использовать справочную команду или документацию для изучения того, что делает каждая команда. Многие из них используются для выполнения ручных операций, которые лучше выполнять с использованием файлов конфигурации в широкомасштабной масштабируемой распределенной системе, но это может быть необходимо для быстрой разведки и устранения неполадок. Наиболее распространенными командами, которые я буду использовать, являются: get, create, delete и start.

Pods

Пакет является базовой единицей развертывания и управления в Кубернете. Pod представляет собой группу из одного или нескольких контейнеров. Вы можете указать pod, используя выделенный файл YAML или как часть службы Kubernetes (см. ниже). Контейнер всегда развертывается на одном хосте, и все контейнеры внутри pod могут обращаться друг к другу через localhost. Все контейнеры внутри pod всегда запускаются, останавливаются и масштабируются вместе.

Чтобы проверить все pod'ы в кластере, введите:

kubectl get pods

Результатом будет что-то вроде: NAME READY STATUS RESTARTS AGE quote-frontend-4kyns 1/1 Running 0 1h quote-frontend-v4xk1 1/1 Running 0 1h quote-store-controller-y4ya1 1/1 Running 0 23h ### Volumes

Контейнеры не должны поддерживать стойкое состояние. Когда контейнер выходит из строя или перезапускается, его локальная файловая система уничтожается. Если вы хотите сохранить постоянное состояние, вы должны использовать постоянные тома. Поскольку все в Kubernetes основано на pod'ах, вам также нужно определить объемы в pod'е. Вот файл определения pod с постоянным томом: apiVersion: v1 kind: Pod metadata: name: метки-хранилища: app: quote-api role: persistent-storage spec: container: - name: redis image: redis volumeMounts: - Name: quot-store-volume mountPath: / data / redis volume: - name: quote-store-volume emptyDir: {} Обратите внимание, что постоянные тома ограничены узлом и будут сохранение при выходе контейнера из строя и после его перезапуска, но не после сбоя узла/хоста. Вам все еще необходимо выполнить репликацию и резервное копирование важных данных.

Контроллеры репликации

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

Поприветствуем контроллеры репликации. Контроллер репликации имеет шаблон pod'а, который определяет группу контейнеров, набор меток для идентификации этих pod'ов и количество желаемых pod'ов. Контроллер репликации гарантирует, что количество запущенных pod'ов, идентифицированных его метками, всегда совпадает с нужным числом. Если pod завершается, контроллер репликации немедленно создаст новый.

Существует несколько интересных вариантов использования, поддерживаемых контроллерами репликации, таких как высокая доступность, эластичное масштабирование и накатывание обновлений. Например, вы можете добавлять и удалять pod'ы из dominion контроллера репликации, изменяя их метку.

Разумеется, контроллеры репликации указаваются в файле YAML. Вот пример: `` `apiVersion: v1 kind: ReplicationController

metadata: name: quote-frontend spec: replicas: 2 # selector identifies the set of Pods that this # replication controller is responsible for managing selector: app: quote-api role: frontend # podTemplate defines the ‘cookie cutter’ used for creating # new pods when necessary template: metadata: labels: # Important: these labels need to match the selector above # The api server enforces this constraint. app: quote-api role: frontend spec: containers: - name: quote-service image: g1g1/quote-service env: - name: GET_HOSTS_FROM # value: dns value: env ports: - containerPort: 8000 ``` Спецификация шаблона для контейнера quote-service используется образ g1g1/quote-service, который я ранее выложил на Docker Hub. Обратите внимание на раздел env, в котором обмен информацией между контейнерами может происходить через переменные DNS или среды.

Чтобы создать контроллер репликации, введите:

kubectl create -f <имя файла контроллера репликации>

Чтобы просмотреть текущие контроллеры репликации в кластере, введите:

kubectl get rc

Вы должны увидеть что-то вроде: CONTROLLER CONTAINER (S) IMAGE (S) SELECTOR REPLICAS AGE quote-frontend quote-service g1g1 / quote-service app = quote-api, role = frontend 2 1h quote-store-controller master redis app = quote -api, role = persistent-storage 1 1d ### Services

Служба предоставляет свой пакет для остальной части кластера и, доступна извне через переменные среды или DNS. Например, служба цитат состоит из двух типов pod'ов: redis store pod и front-end pod. Фронтенд контейнер должен иметь возможность находить контейнер для хранения, а клиенты должны иметь возможность отправить запрос по одной публичной конечной точке для доступа к службе.

Услуга Kubernetes реализована в еще одном файле YAML. Каждый компонент вашей системы, к которому должны обращаться другие компоненты, должен иметь свой собственный служебный файл. Вот два служебных файла для компонентов сервиса цитат:

srv-quote-frontend.yaml

1
apiVersion: v1
2
kind: Service
3
metadata:
4
  name: quote-frontend
5
spec:
6
  type: NodePort
7
  ports:
8
  - port: 8000 # the port that this service should serve on
9
    # the container on each pod to connect to, can be a name
10
    # (e.g. 'www') or a number (e.g. 80)
11
    targetPort: 80
12
    protocol: TCP
13
  # just like the selector in the replication controller,
14
  # but this time it identifies the set of pods to load balance
15
  # traffic to.
16
  selector:
17
    app: quote-api
18
    role: frontend

#### srv-quote-store.yaml apiVersion: v1 kind: Service metadata: name: quote-store spec: ports: - port: 6379 # the port that this service should serve on targetPort: 6379 # just like the selector in the replication controller, # but this time it identifies the set of pods to load balance # traffic to. selector: app: quote-api role: persistent-storage  Хост и порт каждой службы становятся доступными для каждого контейнера в кластере. Например, если вы запускаете интерактивную оболочку на одном из контейнеров фронтенда:

kubectl quote-frontend-4kyns exec -i -t bash

Затем вы можете проверить, что среда содержит необходимую информацию о хосте и порте для подключения к хранилищу цитат. Root @ quote-frontend-4kyns: / quote-service # env | Grep STORE QUOTE_STORE_PORT_6379_TCP_ADDR = 10.100.234.192 QUOTE_STORE_PORT_6379_TCP_PROTO = ТСР QUOTE_STORE_SERVICE_PORT = 6379 QUOTE_STORE_PORT_6379_TCP_PORT = 6379 QUOTE_STORE_PORT = ТСР: //10.100.234.192: 6379 QUOTE_STORE_PORT_6379_TCP = ТСР: //10.100.234.192: 6379 QUOTE_STORE_SERVICE_HOST = 10.100.234.192 Просто, чтобы освежить вашу память, Это именно то, что делает frontend: redis_host = os.environ.get ('QUOTE_STORE_SERVICE_HOST', 'localhost') redis_server = redis.StrictRedis (host = redis_host, port = 6379, db = 0) ## Заключение

Докер и Кубернетес - захватывающие технологии. Эта статья едва поцарапала поверхность того, что возможно. Преимущества огромны, но инфраструктура, инструменты и лучшие практики все еще развиваются. Если вы даже дистанционно подключены к крупномасштабным распределенным системам, я рекомендую вам по крайней мере оставаться на вершине этих технологий и в идеале окунуться в них и попытаться их использовать. Существует множество способов экспериментировать и учиться без массово миграции всей вашей производственной инфраструктуры.

Что касается Кубернетеса, есть несколько других альтернатив для управления несколькими контейнерами и оркестровки, такие как Mesos и Docker compose. Я считаю, что Кубернетес более архитектурно обоснован, имеет большой импульс и лучше, чем остальные его альтернативы.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.