Статьи

Как развернуть Cloud Foundry v2 на AWS через Vagrant

Stackato 2.10.6
Stackato построен на основе Cloud Foundry (плюс другие пакеты с открытым исходным кодом), поэтому мы рады появлению Cloud Foundry v2 и внимательно следим за его развитием. В этом посте я расскажу о том, как я начал работать с Cloud Foundry v2. Эти заметки основаны на инструкциях моего коллеги, который в настоящее время хорошенько пинает шины Cloud Foundry v2.

Кажется, что самый простой способ развертывания Cloud Foundry версии 2 (он же «ng» или «следующее поколение») — через Vagrant. Официальный путь — через BOSH, но Гастон Рамос из Altoros Systems создал метод, который значительно упрощает раскрутку одного экземпляра Cloud Foundry v2 на Amazon EC2. Мы обнаружили, что с BOSH нам понадобилось 14 экземпляров, чтобы начать работу, и это заняло гораздо больше времени.

Установить установщик

Вы начинаете с git-клонирования репозитория cf-vagrant-installer из GitHub.

$ git clone https://github.com/Altoros/cf-vagrant-installer
$ cd cf-vagrant-installer
$ cat README.md

Как вы увидите в README.md, есть несколько бродячих зависимостей, первой из которых является сам Vagrant.

Установить Vagrant

Если у вас не установлен Vagrant, вы можете установить его с http://downloads.vagrantup.com/ . Я установил .dmg для моего Mac, который был довольно простым.

Установите плагины Vagrant

Требуемые плагины Vagrant (если они не были изменены) были vagrant-berkshelf , который добавляет интеграцию Berkshelf к провайдерам Chef, vagrant-omnibus , который обеспечивает установку нужной версии Chef через пакеты Omnibus для конкретной платформы, и vagrant-aws , который добавляет провайдера AWS в Vagrant, позволяя Vagrant контролировать и предоставлять компьютеры в EC2.

Установка этих плагинов не может быть проще

$ vagrant plugin install vagrant-berkshelf
$ vagrant plugin install vagrant-omnibus
$ vagrant plugin install vagrant-aws

Запустите Bootstrap

Затем убедитесь, что мы находимся в каталоге cf-vagrant-installer (который мы клонировали выше) и выполните команду rake, чтобы загрузить все компоненты Cloud Foundry.

$ rake host:bootstrap

Вывод этой команды rake будет выглядеть примерно так …

(in /Users/phil/src/cfv2/cf-vagrant-installer)
==> Init Git submodules
Submodule 'cloud_controller_ng' (https://github.com/cloudfoundry/cloud_controller_ng.git) registered for path 'cloud_controller_ng'
Submodule 'dea_ng' (https://github.com/cloudfoundry/dea_ng.git) registered for path 'dea_ng'
Submodule 'gorouter' (https://github.com/cloudfoundry/gorouter.git) registered for path 'gorouter'
Submodule 'health_manager' (https://github.com/cloudfoundry/health_manager.git) registered for path 'health_manager'
Submodule 'uaa' (https://github.com/cloudfoundry/uaa.git) registered for path 'uaa'
Submodule 'warden' (git://github.com/cloudfoundry/warden.git) registered for path 'warden'
Cloning into 'cloud_controller_ng'...
remote: Counting objects: 13057, done.
remote: Compressing objects: 100% (7357/7357), done.
remote: Total 13057 (delta 7851), reused 10513 (delta 5512)
Receiving objects: 100% (13057/13057), 4.07 MiB | 1.34 MiB/s, done.
Resolving deltas: 100% (7851/7851), done.
Submodule path 'cloud_controller_ng': checked out '4b9208900c54181d539c9cc93519277d7c2702b5'
Submodule 'vendor/errors' (https://github.com/cloudfoundry/errors.git) registered for path 'vendor/errors'
Cloning into 'vendor/errors'...
remote: Counting objects: 58, done.
remote: Compressing objects: 100% (45/45), done.
... (truncated) ...

Настройка учетных данных AWS

Далее вам нужно будет отредактировать Vagrantfile

$ vim Vagrantfile

Добавьте следующий раздел непосредственно над файлом config.vm.provider: vmware_fusion :

  config.vm.provider :aws do |aws, override|
    override.vm.box_url = "http://files.vagrantup.com/precise64.box"

    aws.access_key_id = "YOUR AWS ACCESS KEY"
    aws.secret_access_key = "YOUR AWS SECRET KEY"
    aws.keypair_name = "YOUR AWS KEYPAIR NAME"
    aws.ami = "ami-23d9a94a"
    aws.instance_type = "m1.large"
    aws.region = "us-east-1"
    aws.security_groups = ["open"]

    aws.user_data = File.read('ec2-setup.sh')

    override.ssh.username = "vagrant"
    override.ssh.private_key_path = "THE LOCAL PATH TO YOUR AWS PRIVATE KEY"
  end

Затем замените «ВАШ КЛЮЧ НА AWS», «ВАШ СЕКРЕТНЫЙ КЛЮЧ AWS» и «НАЗВАНИЕ КЛАВИАТУРЫ AWS» своими учетными данными AWS.

Открытая группа безопасности

Группа безопасности AWS, использованная в приведенном выше примере, называется «открытой». Это всего лишь один со всеми открытыми портами. Вам нужно будет создать его, если у вас его еще нет. Вы можете сделать это через консоль AWS .

Создать сценарий установки EC2

Затем вам нужно создать файл ec2-setup.sh непосредственно в каталоге cf-vagrant-installer . Это должно выглядеть в точности как следующее …

#!/bin/bash -ex

usermod -l vagrant ubuntu
groupmod -n vagrant ubuntu
usermod -d /home/vagrant -m vagrant
mv /etc/sudoers.d/90-cloudimg-ubuntu /etc/sudoers.d/90-cloudimg-vagrant
perl -pi -e "s/ubuntu/vagrant/g;" /etc/sudoers.d/90-cloudimg-vagrant

Создайте экземпляр EC2, работающий с CFv2

Наконец, запустите «vagrant up —provider = aws», и ваш экземпляр будет построен.

$ vagrant up --provider=aws

Мой вывод выглядел примерно так … (усечено)

Bringing machine 'cf-install' up with 'aws' provider...
[Berkshelf] Updating Vagrant's berkshelf: '/Users/phil/.berkshelf/cf-install/vagrant/berkshelf-20130717-81754-5vjx63-cf-install'
[Berkshelf] Using apt (1.10.0)
[Berkshelf] Using git (2.5.2)
[Berkshelf] Using sqlite (1.0.0)
[Berkshelf] Using mysql (3.0.2)
[Berkshelf] Using postgresql (3.0.2)
[Berkshelf] Using chef-golang (1.0.1)
[Berkshelf] Using java (1.12.0)
[Berkshelf] Using ruby_build (0.8.0)
[Berkshelf] Installing rbenv (0.7.3) from git: 'git://github.com/fnichol/chef-rbenv.git' with branch: 'master' at ref: 'e10f98d5fd07bdb8d212ebf42160b65c39036b90'
[Berkshelf] Using rbenv-alias (0.0.0) at './chef/rbenv-alias'
[Berkshelf] Using rbenv-sudo (0.0.1) at './chef/rbenv-sudo'
[Berkshelf] Using cloudfoundry (0.0.0) at './chef/cloudfoundry'
[Berkshelf] Using dmg (1.1.0)
[Berkshelf] Using build-essential (1.4.0)
[Berkshelf] Using yum (2.3.0)
[Berkshelf] Using windows (1.10.0)
[Berkshelf] Using chef_handler (1.1.4)
[Berkshelf] Using runit (1.1.6)
[Berkshelf] Using openssl (1.0.2)
[cf-install] Warning! The AWS provider doesn't support any of the Vagrant
high-level network configurations (`config.vm.network`). They
will be silently ignored.
[cf-install] Launching an instance with the following settings...
[cf-install]  -- Type: m1.large
[cf-install]  -- AMI: ami-23d9a94a
[cf-install]  -- Region: us-east-1
[cf-install]  -- Security Groups: ["open"]
[cf-install] Waiting for instance to become "ready"...
[cf-install] Waiting for SSH to become available...
[cf-install] Machine is booted and ready for use!
[cf-install] Rsyncing folder: /Users/phil/src/cfv2/cf-vagrant-installer/ => /vagrant
[cf-install] Rsyncing folder: /Users/phil/.berkshelf/cf-install/vagrant/berkshelf-20130717-81754-5vjx63-cf-install/ => /tmp/vagrant-chef-1/chef-solo-1/cookbooks
[cf-install] Installing Chef 11.4.0 Omnibus package...
[cf-install] Running provisioner: chef_solo...
Generating chef JSON and uploading...
Running chef-solo...
stdin: is not a tty
[2013-07-17T19:43:22+00:00] INFO: *** Chef 11.4.0 ***
[2013-07-17T19:43:23+00:00] INFO: Setting the run_list to ["recipe[cloudfoundry::vagrant-provision-start]", "recipe[apt::default]", "recipe[git]", "recipe[chef-golang]", "recipe[ruby_build]", "recipe[rbenv::user]", "recipe[java::openjdk]", "recipe[sqlite]", "recipe[mysql::server]", "recipe[postgresql::server]", "recipe[rbenv-alias]", "recipe[rbenv-sudo]", "recipe[cloudfoundry::warden]", "recipe[cloudfoundry::dea]", "recipe[cloudfoundry::uaa]", "recipe[cloudfoundry::cf_bootstrap]", "recipe[cloudfoundry::vagrant-provision-end]"] from JSON
[2013-07-17T19:43:23+00:00] INFO: Run List is [recipe[cloudfoundry::vagrant-provision-start], recipe[apt::default], recipe[git], recipe[chef-golang], recipe[ruby_build], recipe[rbenv::user], recipe[java::openjdk], recipe[sqlite], recipe[mysql::server], recipe[postgresql::server], recipe[rbenv-alias], recipe[rbenv-sudo], recipe[cloudfoundry::warden], recipe[cloudfoundry::dea], recipe[cloudfoundry::uaa], recipe[cloudfoundry::cf_bootstrap], recipe[cloudfoundry::vagrant-provision-end]]
[2013-07-17T19:43:23+00:00] INFO: Run List expands to [cloudfoundry::vagrant-provision-start, apt::default, git, chef-golang, ruby_build, rbenv::user, java::openjdk, sqlite, mysql::server, postgresql::server, rbenv-alias, rbenv-sudo, cloudfoundry::warden, cloudfoundry::dea, cloudfoundry::uaa, cloudfoundry::cf_bootstrap, cloudfoundry::vagrant-provision-end]
[2013-07-17T19:43:23+00:00] INFO: Starting Chef Run for ip-10-77-71-207.ec2.internal
[2013-07-17T19:43:23+00:00] INFO: Running start handlers
[2013-07-17T19:43:23+00:00] INFO: Start handlers complete.
[2013-07-17T19:43:24+00:00] INFO: AptPreference light-weight provider already initialized -- overriding!
... (truncated) ...
[2013-07-17T19:58:50+00:00] INFO: Processing package[zip] action install (cloudfoundry::dea line 9)
[2013-07-17T19:58:55+00:00] INFO: Processing package[unzip] action install (cloudfoundry::dea line 13)
[2013-07-17T19:58:55+00:00] INFO: Processing package[maven] action install (cloudfoundry::uaa line 1)
[2013-07-17T19:59:38+00:00] INFO: Processing execute[run rake cf:bootstrap] action run (cloudfoundry::cf_bootstrap line 3)
[2013-07-17T20:05:35+00:00] INFO: execute[run rake cf:bootstrap] ran successfully
[2013-07-17T20:05:35+00:00] INFO: Processing bash[emit provision complete] action run (cloudfoundry::vagrant-provision-end line 2)
[2013-07-17T20:05:35+00:00] INFO: bash[emit provision complete] ran successfully
[2013-07-17T20:05:35+00:00] INFO: Chef Run complete in 1332.027903781 seconds
[2013-07-17T20:05:35+00:00] INFO: Running report handlers
[2013-07-17T20:05:35+00:00] INFO: Report handlers complete

Теперь мы можем войти в наш новый экземпляр EC2, который работает под управлением Cloud Foundry v2 …

$ vagrant ssh

Примечание. Все последующие команды предназначены для запуска на экземпляре EC2.

Нажмите приложение

Сначала мы должны инициализировать интерфейс командной строки Cloud Foundry v2 с помощью следующей команды …

$ cd /vagrant
$ rake cf:init_cf_cli

Вот результат этой команды …

==> Initializing cf CLI
Setting target to http://127.0.0.1:8181... OK
target: http://127.0.0.1:8181

Authenticating... OK
There are no spaces. You may want to create one with create-space.
Creating organization myorg... OK
Switching to organization myorg... OK
There are no spaces. You may want to create one with create-space.
Creating space myspace... OK
Adding you as a manager... OK
Adding you as a developer... OK
Space created! Use `cf switch-space myspace` to target it.
Switching to space myspace... OK

Target Information (where will apps be pushed):
  CF instance: http://127.0.0.1:8181 (API version: 2)
  user: admin
  target app space: myspace (org: myorg)

Теперь вы можете развернуть одно из тестовых приложений. Мы будем использовать приложение Node.js «Hello World» …

$ cd test-apps/hello-node
$ cf push

Мы видим вывод

Warning: url is not a valid manifest attribute. Please remove this attribute from your manifest to get rid of this warning
Using manifest file manifest.yml

Creating hello-node... OK

1: hello-node
2: none
Subdomain> hello-node

1: vcap.me
2: none
Domain> 1      

Creating route hello-node.vcap.me... OK
Binding hello-node.vcap.me to hello-node... OK
Uploading hello-node... OK
Preparing to start hello-node... OK
Checking status of app 'hello-node'...........................
  0 of 1 instances running (1 starting)
  0 of 1 instances running (1 starting)
  1 of 1 instances running (1 running)
Push successful! App 'hello-node' available at http://hello-node.vcap.me

Cloud Foundry v2 работает на локальном хосте в нашем экземпляре EC2, поэтому наше приложение недоступно из нашего веб-браузера, но мы можем проверить, существует ли приложение, используя curl из экземпляра EC2.

$ curl http://hello-node.vcap.me/

Вот что выводит curl …

Hello from Cloud Foundry

Удалить приложение

Чтобы удалить приложение, вы можете использовать cf delete

$ cf delete

Следующий вывод виден

Warning: url is not a valid manifest attribute. Please remove this attribute from your manifest to get rid of this warning
Using manifest file manifest.yml

Really delete hello-node?> y

Deleting hello-node... OK

Наизнанку

xip.io

Из заметок мне дали …

Теперь, чтобы выставлять приложения извне, становится сложнее. Во-первых, вам нужно предоставить эластичный IP-адрес в консоли AWS и подключить его к экземпляру EC2, на котором выполняется установка cf v2. Затем вам нужно настроить DNS-запись с подстановочными знаками, чтобы она указывала на этот IP-адрес (* .domain и домен должны указывать на этот IP-адрес). xip.io может работать здесь, но я недостаточно знаком с ним, чтобы знать наверняка.

xip.io на самом деле идеально подходит для этого. Все, что мне нужно, это мой внешний IP, который был 50.19.50.63, и я добавляю «.xip.io», который дает мне «50.19.50.63.xip.io» и подстановочный знак «* .50.19.50.63.xip.io «для Cloud Foundry API и любых приложений, которые я развернул. Это сервис с нулевой конфигурацией. IP-адрес, который вы хотите разрешить, включается в создаваемое вами имя хоста, и служба DNS просто возвращает вам IP-адрес. Это означает, что вы можете мгновенно иметь действительное глобально разрешаемое имя хоста DNS.

Я также могу получить более простое имя хоста, проверив DNS-запись этого имени хоста, которая на самом деле является просто CNAME.

$ host 50.19.50.63.xip.io

Какие выводы …

50.19.50.63.xip.io is an alias for hj8raq.xip.io.
hj8raq.xip.io has address 50.19.50.63
Host hj8raq.xip.io not found: 3(NXDOMAIN)
Host hj8raq.xip.io not found: 3(NXDOMAIN)

… так что вместо этого я могу использовать hj8raq.xip.io, так как он короче и я просто хочу использовать его временно.

Обновление More Config

Поскольку теперь у нас есть внешнее доменное имя, а не только localhost, нам нужно обновить некоторые файлы конфигурации в каталоге custom_config_files .

$ cd /vagrant/custom_config_files

Предполагая, что вы работаете в домене «yourdomain» (или «hj8raq.xip.io» в моем случае), вы должны отредактировать cloud_controller.yml следующим образом …

$ (cd cloud_controller_ng; vim cloud_controller.yml)
  • изменить external_domain к api.yourdomain
  • изменить system_domain к имя_домену
  • изменение app_domains в ваш_домен
  • измените uaa: url на http: // yourdomain: 8080 / uaa

Затем отредактируйте конфигурацию DEA.

$ (cd dea_ng; vim dea.yml)
  • изменить домен для ваш_домена

И, наконец, конфигурация диспетчера работоспособности …

$ (cd health_manager; vim health_manager.yml)
  • измените объем_папки: хост на http: //api.yourdomain: 8181

Ошибка реестра роутера

В моем развертывании AWS была небольшая ошибка, которая могла быть исправлена. Это было связано с несовместимостью с JSON между облачным контроллером и маршрутизатором при регистрации конечной точки API на маршрутизаторе. Вот исправление …

$ cd /vagrant/cloud_controller_ng/lib/cloud_controller
$ vim message_bus.rb

и изменить линию

        :uris => config[:external_domain],

к этому

        :uris => [config[:external_domain]],

Это сделает: uris массив, а не строку. Вероятно, лучше исправить это в gorouter, но сейчас это быстрее.

Перезагрузите CC DB

Теперь нам нужно сбросить базу данных Cloud Controller.

$ cd /vagrant/
$ rake cf:bootstrap

Наконец, перезагрузите машину.

$ sudo reboot

Когда машина возвращается, мы можем вернуться в нее

$ vagrant ssh

и запустите команду ./start.sh, чтобы запустить компоненты Cloud Foundry.

$ cd /vagrant
$ ./start.sh

Теперь Cloud Foundry v2 должен работать с вашей внешней доступной конечной точкой.

Что будет дальше?

Отличительной особенностью Cloud Foundry v2 является то, что базовая архитектура не изменилась с v1. Это дает ActiveState возможность интегрировать один компонент Cloud Foundry v2 в Stackato за один раз и исключить негативное влияние на наших корпоративных клиентов внезапных оптовых изменений. (Например, мы уже используем новый диспетчер работоспособности.) В течение следующих нескольких месяцев вы можете ожидать появления в Stackato новых впечатляющих новых функций и возможностей, основанных на платформе Cloud Foundry v2. Я выложу более подробную информацию, как у меня есть.