Статьи

Использование API Digital Ocean для управления облачными экземплярами

Конечный продукт
Что вы будете создавать

Digital Ocean является одним из самых быстрорастущих веб-хостингов, отчасти благодаря быстрым SSD-серверам и недорогим тарифным планам на 5 долларов в месяц. Внедрение экземпляров на Digital Ocean для тестирования или долгосрочного использования — это быстро, легко и доступно.

В разделе «Создание образа приложения для перепродажи в Digital Ocean» я рассказывал, как запустить экземпляр WordPress (или другого приложения ) и неоднократно клонировать его для клиентов. В этом руководстве я собираюсь рассказать вам об использовании API Digital Ocean для программного управления нашими экземплярами, также известными как капли, и для автоматизации общих задач. Я также предоставлю пример кодовой базы для выполнения очень простых операций API, написанных на Yii Framework для PHP ; Вы можете получить код здесь на Github .

Digital Ocean API позволяет управлять каплями и ресурсами простым, программным способом, используя HTTP-запросы. Все функции, с которыми вы знакомы в панели управления Digital Ocean, также доступны через API, что позволяет вам создавать сложные действия, необходимые для вашей ситуации.

В этом руководстве мы интегрируем библиотеку PHP API Digital Ocean V2 разработчика Antoine Corcy в консольное приложение на основе Yii. Вам не нужно знание Yii, чтобы использовать приложение, но вы можете узнать больше об этом здесь: Введение в Yii Framework .

Digital Ocean API аутентифицирует вашу учетную запись через OAuth и состоит из почти десятка областей высокого уровня:

  • Учетные записи : предоставляет основную информацию о вашей учетной записи Digital Ocean.
  • Действия : исторический журнал действий над каплями в вашем аккаунте.
  • Домены и записи доменов : позволяет вам управлять доменами, используемыми для капель в вашей учетной записи, а также записями DNS, связанными с ними.
  • Droplets & Droplet Actions : позволяет создавать, выключать, перезагружать, снимки и многое другое для ваших капель.
  • Изображения и действия с изображениями : позволяет перечислять и управлять снимками, снятыми вами из капель на вашей учетной записи.
  • Ключи SSH : позволяет зарегистрировать ключ SSH для установки при создании капли, поэтому защита паролем не требуется.
  • Регионы : перечисляет географические регионы, в которых могут быть созданы капли Digital Ocean.
  • Размеры : перечисляет размеры капель, которые можно использовать при создании капель.

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

Чтобы использовать API, вам необходимо активировать токены личного доступа для вашей учетной записи. Войдите в свою учетную запись и перейдите на страницу приложения настроек: https://cloud.digitalocean.com/settings/applications . Нажмите Generate New Token , как показано ниже:

Digital Ocean API генерирует токен доступа

Запишите свой токен доступа ниже — Digital Ocean покажет его вам только один раз:

Digital Ocean API Ваш новый токен доступа

Теперь перейдем к нашему примеру консольного приложения.

В этом уроке мы собираемся исследовать небольшое консольное приложение, которое я создал и которое выполняет несколько задач, связанных с управлением каплями. Вы можете установить приложение самостоятельно из репозитория Tuts + GitHub и настроить или расширить его для реализации дополнительных функций API, которые вы хотите. Я разместил подробное руководство по установке консольного приложения на своем веб-сайте. Вы также можете ознакомиться с моим общим руководством по установке приложений Digital Ocean .

Опять же, для доступа к API мы используем PHP API-библиотеку Digital Ocean V2 от Antoine Corcy .

Мы создали компонент под названием Ocean.php, который служит моделью для использования его библиотеки. Это на /app/protected/components/Ocean.php .

Yii загружает ваш токен доступа из файла Ocean.ini, описанного в Руководстве по установке приложения Digital Ocean Console , и создает экземпляр digitalOcean API digitalOcean .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?php
 
use DigitalOceanV2\Adapter\BuzzAdapter;
use DigitalOceanV2\DigitalOceanV2;
 
class Ocean extends CComponent
{
  private $adapter;
  private $digitalOcean;
   
   function __construct() {
     // create an adapter with your access token which can be
     // generated at https://cloud.digitalocean.com/settings/applications
     $this->adapter = new BuzzAdapter(Yii::app()->params[‘ocean’][‘access_key’]);
     // create a digital ocean object with the previous adapter
     $this->digitalOcean = new DigitalOceanV2($this->adapter);
  }
Digital Ocean Console Управляйте своими каплями

Теперь давайте возьмем список наших активных капелек. В /app/protected/models/Droplet.php наш метод sync вызывает компоненты Ocean и получает капли:

1
2
3
4
5
6
7
public function sync() {
   $ocean = new Ocean();
   $droplets = $ocean->getDroplets();
   foreach ($droplets as $d) {
     $droplet_id = $this->add($d);
   }
 }

Вот как getDroplets метод getDroplets Ocean:

1
2
3
4
5
6
7
public function getDroplets() {
   // return the action api
   $action = $this->digitalOcean->droplet();
   // return a collection of Action entity
   $actions = $action->getAll();
   return $actions;
 }

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

Вот функция add нашей модели капли. Если капля уже существует, мы просто обновляем запись:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
public function add($droplet) {
    $d = Droplet::model()->findByAttributes(array(‘droplet_id’=>$droplet->id));
   if (empty($d)) {
     $d = new Droplet;
   }
   $d->user_id = Yii::app()->user->id;
     $d->droplet_id = $droplet->id;
     $d->name = $droplet->name;
     $d->vcpus = $droplet->vcpus;
     $d->memory = $droplet->memory;
     $d->disk = $droplet->disk;
     $d->status = $droplet->status;
     $d->active =1;
    $d->created_at = $d->created_at;
    $d->modified_at =new CDbExpression(‘NOW()’);
    $d->save();
   return $d->id;
  }

Если вы хотите расширить возможности модели, Digital Ocean предлагает широкий спектр действий Droplet API, а у Corcy есть список наглядных примеров здесь .

Далее мы будем использовать API для получения списка наших текущих изображений. Изображения представляют собой моментальные снимки, в основном резервные копии, сделанные экземпляром сервера в данный момент времени.

Digital Ocean Console Управляйте своими изображениями

В нашей модели Snapshot.php есть операция sync которая запрашивает список ваших изображений и добавляет их по отдельности в базу данных:

01
02
03
04
05
06
07
08
09
10
11
public function sync() {
    $ocean = new Ocean();
    $snapshots = $ocean->getSnapshots();
    foreach ($snapshots as $i) {
      $image_id = $this->add($i);
      if ($image_id!==false) {
        echo $image_id;lb();
        pp($i);
      }
    }
  }

Вот код getSnapshots компонента getSnapshots :

1
2
3
4
5
6
7
public function getSnapshots() {
   // return the action api
   $action = $this->digitalOcean->image();
   // return a collection of Action entity
   $actions = $action->getAll();
   return $actions;
 }

Вот код add модели Snapshot — мы игнорируем стандартные изображения приложений Digital Ocean, которые выделяются как общедоступные:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
public function add($snapshot) {
     $i = Snapshot::model()->findByAttributes(array(‘image_id’=>$snapshot->id));
    if (empty($i)) {
      $i = new Snapshot;
      $i->created_at =new CDbExpression(‘NOW()’);
    }
    if (isset($snapshot->public) and $snapshot->public ==1) {
      return false;
    } else
      $i->user_id = Yii::app()->user->id;
      $i->image_id = $snapshot->id;
      $i->name = $snapshot->name;
      $i->region = $snapshot->regions[0];
      $i->active =1;
      $i->modified_at =new CDbExpression(‘NOW()’);
     $i->save();
   return $i->id;
   }

Как мы обсуждали в разделе «Создание образа приложения для перепродажи в Digital Ocean» , полезно автоматизировать создание снимков, которые вы можете передавать клиентам и заказчикам. К сожалению, в настоящее время нет способа клонировать или передать изображение по ссылке; каждый раз, когда вы переносите снимок в другую учетную запись, он исчезает.

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

Поскольку API не принимает запросы, пока другие операции ожидают выполнения, нам необходимо создать таблицу для отслеживания фоновых действий и использовать задание cron для повтора операции отключения питания и создания снимка. Вот как это работает:

Перейдите на страницу « Изображения» и нажмите « Просмотр», чтобы получить снимок, который вы хотите клонировать. Затем щелкните пункт меню « Репликация» справа.

Просмотр снимка и репликации изображения

Это создаст каплю и добавит запись в фоновую таблицу действий с этими image_id и droplet_id . end_stage — это константа, которую вы можете установить, указывая количество end_stage дубликатов.

Строка в таблице действий, представляющая фоновый процесс

Вот метод replicate() модели Snapshot:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
public function replicate($id) {
       // look up image_id
     $snapshot = Snapshot::model()->findByAttributes(array(‘id’=>$id));
     // create the droplet
     $ocean = new Ocean();
     $droplet_id = $ocean->launch_droplet($snapshot->name,$snapshot->region,$snapshot->image_id);
     // add command to action table with droplet_id and image_id
     $a = new Action();
     $a->droplet_id = $droplet_id;
     $a->snapshot_id = $snapshot->image_id;
     $a->action = Action::ACTION_SNAPSHOT;
     $a->status = Action::STATUS_ACTIVE;
     $a->stage = 0;
   // user settable constant for number of replications to make
     $a->end_stage = Snapshot::NUMBER_REPLICATIONS;
     $a->last_checked = 0;
     $a->modified_at =new CDbExpression(‘NOW()’);
     $a->created_at =new CDbExpression(‘NOW()’);
     $a->save();
   }

Задача cron будет пинговать http://ocean.yourdomain.com/daemon/index для регулярной обработки таблицы действий. Любые незаконченные просроченные предметы будут запрашивать еще один снимок.

Вот метод process() модели Action:

01
02
03
04
05
06
07
08
09
10
public function process() {
     set_time_limit(0);
     // look for overdue actions
     $todo = Action::model()->overdue()->findAllByAttributes(array(‘status’=>self::STATUS_ACTIVE));
     foreach ($todo as $item) {
       if ($item->action == self::ACTION_SNAPSHOT) {
         $result = Snapshot::model()->take($item->id);
       }
     }
   }

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

Капля выключения сна и снимок

Вот метод take() модели Snapshot:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
public function take($action_id) {
   $result = false;
     $a = Action::model()->findByPk($action_id);
   $snapshot = Snapshot::model()->findByAttributes(array(‘image_id’=>$a->snapshot_id));
   $ocean = new Ocean();
   // attempt shutdown
   // take snapshot
   $result = $ocean->snapshot($a->stage,$a->droplet_id,$snapshot->name,$snapshot->region,$snapshot->image_id);
   // if snapshot was successful
   if ($result) {
     // increment stage
     $a->stage+=1;
     // if last snapshot replication complete, end action
     if ($a->stage >= $a->end_stage)
       $a->status = Action::STATUS_COMPLETE;
   }
     // either way, update last_checked
   $a->last_checked = time();
   $a->save();
     return $result;
 }

Вот код в компоненте Ocean для выполнения вызовов API:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public function snapshot($stage,$droplet_id,$name,$region,$image_id,$begin=1,$count=3,$size=’512mb’) {
   $no_sleep = false;
   $name = str_replace(«_»,»-«,$name);
   $droplet = $this->digitalOcean->droplet();
     try {
       echo ‘Shutting down ‘.$droplet_id;lb();
       $shutdown = $droplet->shutdown($droplet_id);
     } catch (Exception $e) {
         $err = $e->getMessage();
         echo ‘Caught exception: ‘, $e->getMessage(), «\n»;
         if (stristr ( $err , ‘already powered off’)===false)
           return false;
         else
           $no_sleep = true;
     }
   if (!$no_sleep) {
     echo ‘Sleep 20 seconds for power off…’;lb();
     sleep(20);
   }
   echo ‘Take snapshot of ‘.$droplet_id.’
   try {
     $snapshot = $droplet->snapshot($droplet_id, $name.’-copy-‘.$stage);
   } catch (Exception $e) {
       echo ‘Caught exception: ‘, $e->getMessage(), «\n»;
       return false;
   }
   // shutdown and snapshot successful
   return true;
 }

Если вы посетите веб-сайт Digital Ocean для просмотра капли, вы увидите действие в процессе:

Идет моментальный снимок капли

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

Вы можете посетить страницу изображений на веб-сайте Digital Ocean, чтобы увидеть ваши реплицированные снимки:

Клонированные копии вашего снимка

После создания изображений вы можете удалить каплю вручную или расширить код, чтобы сделать это при STATUS_COMPLETE . Если вы не удалите каплю, с вас будет взиматься плата.

Обратите внимание, что в настоящее время API не предлагает возможность переноса снимка на адрес электронной почты, поэтому вам придется продолжать делать это вручную через веб-интерфейс.

Я надеюсь, что вам понравился этот урок, и вы нашли Digital Ocean в качестве полезной услуги в своем портфеле инструментов и хостинг-провайдеров. В следующем уроке мы рассмотрим DNS-сервис Digital Ocean.

Пожалуйста, не стесняйтесь оставлять свои вопросы и комментарии ниже. Вы также можете связаться со мной в Twitter @reifman или написать мне напрямую. Следуйте за моей страницей инструктора Tuts +, чтобы видеть будущие статьи в этой серии.