Fraktallar uygulama mimarisine giriş

Fraktallar uygulama mimarisine giriş

Bu kısım uygulama mimarisini tanıtır ve genel olarak bulut özelliklerinden ve özel olarak OpenStack’den faydalanmak için nasıl tasarlandığını açıklar. Ayrıca önceki kısımdaki bazı komutları tanımlar.

Bulut uygulama mimarisi prensipleri

Bulut uygulamaları genellikle birçok tasarım prensibini paylaşır. Bu prensipler Fraktallar uygulamasının tasarımını etkilemiştir.

Modülerlik ve mikro servisler

Mikro servisler uygulama modülerliğini elde etmede yardımcı olan önemli tasarım kalıplarıdır. Mantıksal uygulamaları bağımsız servislere ayırmak bakımı ve tekrar kullanımı basitleştirir. Bileşimleri koparma bağımsız bileşenleri gerektiği gibi ayrı ayrı ölçeklendirmeyi kolaylaştırır. Dahası iyi ölçeklenir ve hataya dayanıklı uygulamalar için uygulama modülerliği gerekli bir özelliktir.

Ölçeklenebilirlik

Bulut uygulamaları genellikle birkaç büyük sunucu yerine birçok küçük sunucu kullanırlar. Bir uygulamanın yeterli miktarda modüler olması sağlanırsa, kolaylıkla mikro servisleri istenilen sayıda sunucuya dağıtabilirsiniz. Bu mimari bir uygulamanın sunucu sınırlarını aşabilecek noktaya büyüyebilmesini sağlar. Bu çok sayıda insanı bir yerden bir yere taşımaya benzer; büyük bir otobüse ancak belli miktarda insanı koyabilirsiniz, ama sınırsız sayıda otobüs veya küçük arabalar kullanarak kapasiteyi ihtiyaç kadar ya da daha fazla artırabilirsiniz.

Arızaya dayanıklılık

Bulut programlamada “sığırlara karşı evcil hayvanlar” olarak bilinen bir benzeşim vardır. Daha önce duymadıysanız şu şekilde bir şey:

Evcil hayvanlarla ilgilendiğinizde, onları isimlendirir ve iyi bakarsınız. Hastalanırlarsa, iyileşene kadar bakıcılık yaparsınız ki bu oldukça zor ve zaman alıcı bir iş olabilir. Sığırlarla uğraşırken kulaklarına bir numara etiketi takarsınız. Hastalanırlarsa bir kenara ayırır hayatınıza devam edersiniz.

Bu da programlamanın yeni gerçekliği haline geldi diyebiliriz. Uygulamalar ve sistemler büyük pahalı sunucular üzerinde, sağlıklarını izlemek için adanmış işletici çalışanlarca bakılacak şekilde oluşturulurdu. Bu sunuculardan birine bir şey olursa, çalışanların işi uygulamayı ve sunucuyu kurtarmak için ellerinden geleni yapmaktı.

Bulut programlamada, çok daha farklıdır. Büyük, pahalı sunucular yerine, atılabilir sanal sunucularınız vardır; bir şeyler ters giderse, sunucuyu kapatır ve yeni bir tanesini açarsınız. Yine işletici çalışanlar olur, ama tek tek sunucuları kurtarmaya çalışmak yerine, işleri genel sistem sağlığını izlemektir.

Bu mimarinin belirli avantajları bulunur. Bir sunucunun aylarca hatta yıllarca çalıştığında bir gün karşısına çıkacak sunucular olmadan “yeni” bir sunucu almak kolaydır.

Klasik mimaride olduğu gibi, altta yatan bulut mimarisindeki (donanım, ağlar, ve yazılım) arızalar kaçınılmazdır. Bulut için tasarım yaptığınızda, uygulamanızın her an arızalarla karşılaşabilecek şekilde bu ortama göre tasarlanması çok önemlidir. Bu kulağa bir yükümlülük gibi gelse de; uygulamanızı yüksek derecede hata dayanıklılığına sahip şekilde tasarlamak kendini çabuk toparlayan, değişikliklere daha kolay uyum sağlayan hale getirecektir.

Arızaya dayanıklılık bulut tabanlı uygulama için şarttır.

Otomatikleştirme

Bir uygulama talebi karşılamak için otomatik olarak yukarı aşağı ölçeklenebilir olacaksa, uygulamanın herhangi bir bileşenini kurmada elle yapılması gereken çok fazla işin olması uygulanabilir değildir. Otomatikleştirme ayrıca bileşen arızalarında kurtarma sürelerini azaltır, hata dayanıklılığını ve esnekliği artırır.

Programlama arayüzleri (API’ler)

Birçok bulut uygulaması gibi, Fraktallar uygulaması da RESTful API’ye sahiptir. Doğrudan bağlanıp fraktallar oluşturabilirsiniz veya daha büyük bir uygulamanın bileşeni olarak tümleştirebilirsiniz. API gibi standart bir arayüz kullanılabilir olduğunda, otomatik olarak deneme çok daha kolaylaşır, yazılım kalitesi artar.

Fraktallar uygulama mimarisi

Fraktallar uygulaması önceki alt kısım göz önüne alınarak tasarlanmıştır. Bunu Başlangıç kısmında değerlendireceğiz, uygulamayı hepsi bir arada biçiminde kurduk, tek bir sanal makine üzerine. Bu iyi bir yaklaşım değildir, fakat uygumala mantıksal uygulama fonksiyonlarını ayırmak için mikro servisleri kullandığından, bunu kolaylıkla değiştirebiliriz.

digraph {
  API -> Database [color=green];
  API -> Database [color=orange];
  Database -> API [color=red];
  API -> Webinterface [color=red];
  API -> "Queue Service" [color=orange];
  "Queue Service" -> Worker [color=orange];
  Worker -> API [color=green];
}

İleti kuyrukları Fraktal uygulama servisleri arasındaki iletişimi kolaylaştırmak için kullanılır. Fraktal uygulaması görevleri işçi servislere dağıtmak için bir iş kuyruğu (veya görev kuyruğu) kullanır.

İleti kuyrukları birçok yazmanın çalıştığı bir banka kuyruğuyla (veya okyanusun diğer tarafında olan bizler için sırasıyla) aynı şekilde çalışır. Uygulamamızdaki ileti kuyruğu işçi servislerce her seferde bir tane alınabilen iş isteği beslemesi sağlar, bir tane işçi olsa da yüzlerce işçi olsa da bir şey değişmez.

Gelen uzun istek listelerine ve bir kaynak havuzuna sahip çoğu bulut uygulamalarında bu kullanışlı bir kalıptır. Bu ayrıca bir işçi bozulduğunda görevlerin diğer işçilerce işleneceği anlamına gelir.

Not

RabbitMQ ile başlama öğreticisi ileti kuyruklarına çok güzel bir giriş sağlar.

digraph {
  rankdir=LR;
  Queue [shape="doublecircle"];
  API -> Queue;
  Queue -> "Worker 1";
  Queue -> "Worker 2";
}

İşçi servisi iş kuyruğundan iletileri tüketir ve ilgili fraktal imaj dosyasını oluşturmak için bunları işler.

Tabi oluşturulan fraktal imajları görüntülemek için API’ye erişmek için daha insan canlısı bir web arayüzü de bulunur, bir de basit komut satırı arayüzü vardır.

screenshot of the webinterface

Ayrıca birden fazla depolama arka ucu (üretilen fraktal imajları saklamak için) ve bir veritabanı bileşeni (görevlerin durumunu saklamak için) bulunur, ama bunlardan sırasıyla Dayanıklı hale getirin ve :/block_storage kısımlarında söz edeceğiz.

Fraktallar uygulamasının OpenStack ile nasıl etkileşimde bulunacağı

Sihire yeniden ziyaret

Öyleyes önceki kısmın sonundaki istek tam olarak ne yapıyordu? Tekrar bir bakalım. Bu alt kısımda önceki kısımda zaten yaptığınız şeyleri açıklayacağız; bu komutları tekrar çalıştırmanıza gerek yok.

userdata = '''#!/usr/bin/env bash
curl -L -s https://opendev.org/openstack/faafo/raw/contrib/install.sh | bash -s -- \
    -i faafo -i messaging -r api -r worker -r demo
'''

instance_name = 'all-in-one'
testing_instance = conn.create_node(name=instance_name,
                                   image=image,
                                   size=flavor,
                                   ex_keyname=keypair_name,
                                   ex_userdata=userdata,
                                   ex_security_groups=[all_in_one_security_group])

İmaj ve niteliği Başlangıç kısmında açıkladık, ilerleyen kısımlarda, ex_userdata (cloud-init) ve ex_keyname (anahtar çiftleri) dahil diğer parametreleri daha ayrıntılı olarak açıklayacağız.

Cloud-init’e giriş

cloud-init bir bulut sunucusunun önyüklenmesi sırasındaki sunucu yapılandırma görevlerini gerçekleştiren bir araçtır, ve çoğu bulut imajında kurulu olarak gelir. create_node’a verilen ex_userdata cloud-init’e geçirilen yapılandırma verisidir.

Bu durumda, userdata olarak bir kabuk betiğini sunuyoruz. create_node sunucuyu oluşturduğunda, cloud-init userdata değişkenindeki kabuk betiğini çalıştırır.

Sunucu oluşturma sırasında bir SSH açık anahtarı sağlandığında, cloud-init bu anahtarı kullanıcı hesabına yükler. (Kullanıcı adı bulut imajlarına göre değişiklik gösterir.) SSH çekerken hangi kullanıcı adını kullanacağınızla ilgili yön gösterme için imaj kılavuzundaki İmajları almak kısmına göz atın. Yine de girişte sorun yaşıyorsanız, bulut sağlayıcınıza kullanıcı adınızı kontrol ettirin.

userdata = '''#!/usr/bin/env bash
curl -L -s https://opendev.org/openstack/faafo/raw/contrib/install.sh | bash -s -- \
    -i messaging -i faafo -r api -r worker -r demo
'''

Sunucu oluşturulduktan sonra, cloud-init install.sh adındaki bir betiği indirir ve çalıştırır. Bu betik Fraktallar uygulamasını kurar. Cloud-init bash betiklerini ve çeşitli farklı türde veriyi tüketebilir. Hatta birden fazla türde veri de sağlayabilirsiniz. Resmi belgelendirmede cloud-init’le ilgili daha fazla bilgi bulabilirsiniz.

Anahtar çiftlerine giriş

Konu sunucularınız olduğunda güvenlik önemlidir; herhangi birinin erişebilmesini istemezsiniz. Sunucuya girişi etkinleştirmek için, sunucu oluşturma sırasında bir SSH anahtar çiftinin açık anahtarını sağlamalısınız. Birinci kısımda OpenStack’e bir anahtar oluşturup yüklediniz, ve cloud-init kullanıcı hesabı için bunu yükledi.

Bir anahtar olsa da, sunucunuza erişmek için uygun güvenlik grubu kurallarına sahip olmalısınız.

Güvenlik gruplarına giriş

Güvenlik grupları bir sunucunun ağına uygulanan ağ erişim kuralları kümesidir. Öntanımlı olarak egress (dışarı yönde) trafiğe izin verilir. Bir güvenlik grubu kuralı oluşturarak özellikle ingress (içe doğru) ağ erişimine izin vermeniz gerekir.

Uyarı

OpenStack tarafından oluşturulan Egress kuralı kaldırmak sunucu ağınızın bozulmasına yol açar.

Herşeyi içeren sunucunuz için bir güvenlik grubu oluşturarak ve uygun kuralları ekleyerek, örneğin HTTP (TCP bağlantı noktası 80) ve SSH (TCP bağlantı noktası 22) başlayın:

all_in_one_security_group = conn.ex_create_security_group('all-in-one', 'network access for all-in-one application.')
conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 80, 80)
conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 22, 22)

Not

ex_create_security_group_rule() bağlantı noktası aralıklarını girdi olarak alır. Bu yüzden 80 ve 22 iki kere geçirilmiştir.

Kullanılabilir güvenlik gruplarını şu şekilde listeleyebilirsiniz:

conn.ex_list_security_groups()

Bir kural veya grup oluşturduktan sonra, silebilirsiniz de:

conn.ex_delete_security_group_rule(rule)
conn.ex_delete_security_group(security_group)

Bir sunucuya hangi güvenlik gruplarının uygulandığını görmek için:

conn.ex_get_node_security_groups(testing_instance)

İzinleri yapılandırdıktan sonra, uygulamaya nerden erişeceğinizi bilmelisiniz.

Değişken IP’lere giriş

Geleneksel IT’de olduğu gibi bulut sunucularına da OpenStack’in atadığı IP adresleri üzerinden erişilir. Bunun nasıl yapılacağı bulutunuzun ağ kurulumuna göre değişir. Bazı durumlarda, sunucunuza doğrudan atanmış internet yönlendirilebilir bir IP adresi alırsınız.

Ancak OpenStack bulutlarının internet yönlendirilebilir IP adreslerini sunuculara ayırmalarının en yaygın yolu değişken IP’lerin kullanımı iledir. Değişken IP kendi kendine var olan bir adrestir ve belirli sunucu ağ arayüzüyle ilişkilendirilebilir. Bir değişken IP adresi bir sunucu ağ arayüzüyle ilişkilendirildiğinde, OpenStack bu adrese bağlı trafiği sunucunun dahili ağ arayüz adresine yeniden yönlendirir. Bulut sağlayıcınız genellikle kullanımınız için değişken IP adresi havuzları sunacaktır.

Bir değişken IP kullanmak için, önce projenize bir IP ayırmalısınız, ardından bunu sunucunuzun ağ arayüzüyle ilişkilendirmelisiniz.

Not

Bir değişken IP adresini sunucuya ayırmak sunucunun IP adresini değiştirmez, OpenStack ağ dönüşüm kurallarını ek bir IP adresine izin verecek şekilde kurmasına sebep olur.

unused_floating_ip = None
for floating_ip in conn.ex_list_floating_ips():
    if not floating_ip.node_id:
        unused_floating_ip = floating_ip
        print("Found an unused Floating IP: %s" % floating_ip)
        break

Önceden projenize ayrılmış boşta değişken IP’leriniz yoksa, önce sağlayıcınız tarafından sunulan bir değişken IP havuzu seçin. Bu örnekte ilkini seçtik ve kullanılabilir IP adresleri olduğunu varsaydık.

pool = conn.ex_list_floating_ip_pools()[0]

Şimdi bu havuzdan bir adresin projenize ayrılmasını isteyin.

unused_floating_ip = pool.create_floating_ip()

Artık projenize ayrılmış kullanılmayan bir değişken IP adresi olduğuna göre, sunucuya ekleyebilirsiniz.

conn.ex_attach_floating_ip_to_node(instance, unused_floating_ip)

Bu da bizi Başlangıç kısmında kaldığımız noktaya getirir. Peki burdan nereye gideceğiz?

Servisleri birden çok sunucuya ayırmak

Fonksiyonları farklı mikro servislere ayırmayı, ve bunun bizi bulut mimarisini kullanmakta nasıl etkin yaptığını konuştuk. Şimdi bunu eyleme dökelim.

Bu kılavuzun geri kalanı bu kısımda oluşturduğunuz herşeyi içeren sunucuya başvurmayacak. Bu sunucuyu hızlıca silin.

Servisleri birden çok sunucuya ayırmak kolaydır. API, veritabanı ve ileti servislerini sunan app-controller isimli bir kontrol düğümü oluşturacağız. Ayrıca yalnızca fraktalları üreten bir app-worker-1 işçi sunucusu oluşturacağız.

İlk adım kontrol sunucusunu başlatmaktır. Kurulum betiğine geçirilen parametrelerden görebileceğiniz gibi sunucunun API servisi, veritabanı ve ileti servisi bulunur.

Parametre

Açıklama

Değerler

-i

Bir servis kur

messaging (RabbitMQ kur) ve faafo (Faafo uygulamasını kur).

-r

Bir şeyleri etkinleştir/başlat

api (API servisini etkinleştir ve başlat), worker (işçi servisini etkinleştir ve başlat), ve demo (Rasgele fraktallar istemek için demo kipini çalıştır).

worker_group = conn.ex_create_security_group('worker', 'for services that run on a worker node')
conn.ex_create_security_group_rule(worker_group, 'TCP', 22, 22)

controller_group = conn.ex_create_security_group('control', 'for services that run on a control node')
conn.ex_create_security_group_rule(controller_group, 'TCP', 22, 22)
conn.ex_create_security_group_rule(controller_group, 'TCP', 80, 80)
conn.ex_create_security_group_rule(controller_group, 'TCP', 5672, 5672, source_security_group=worker_group)

userdata = '''#!/usr/bin/env bash
curl -L -s https://opendev.org/openstack/faafo/raw/contrib/install.sh | bash -s -- \
    -i messaging -i faafo -r api
'''

instance_controller_1 = conn.create_node(name='app-controller',
                                         image=image,
                                         size=flavor,
                                         ex_keyname='demokey',
                                         ex_userdata=userdata,
                                         ex_security_groups=[controller_group])

conn.wait_until_running([instance_controller_1])
print('Checking for unused Floating IP...')
unused_floating_ip = None
for floating_ip in conn.ex_list_floating_ips():
    if not floating_ip.node_id:
        unused_floating_ip = floating_ip
        break


if not unused_floating_ip:
    pool = conn.ex_list_floating_ip_pools()[0]
    print('Allocating new Floating IP from pool: {}'.format(pool))
    unused_floating_ip = pool.create_floating_ip()


conn.ex_attach_floating_ip_to_node(instance_controller_1, unused_floating_ip)
print('Application will be deployed to http://%s' % unused_floating_ip.ip_address)

Bu sefer bir güvenlik grubu oluştururken yalnızca işçi grubunun parçası olan sunuculara uygulanan bir kural dahil ettiğinize dikkat edin.

Ardından işçi sunucusu olacak ikinci bir sunucuyu başlatın:

instance_controller_1 = conn.ex_get_node_details(instance_controller_1.id)
if instance_controller_1.public_ips:
    ip_controller = instance_controller_1.private_ips[0]
else:
    ip_controller = instance_controller_1.public_ips[0]

userdata = '''#!/usr/bin/env bash
curl -L -s https://opendev.org/openstack/faafo/raw/contrib/install.sh | bash -s -- \
    -i faafo -r worker -e 'http://%(ip_controller)s' -m 'amqp://guest:guest@%(ip_controller)s:5672/'
''' % {'ip_controller': ip_controller}
instance_worker_1 = conn.create_node(name='app-worker-1',
                                        image=image,
                                        size=flavor,
                                        ex_keyname='demokey',
                                        ex_userdata=userdata,
                                        ex_security_groups=[worker_group])

conn.wait_until_running([instance_worker_1])
print('Checking for unused Floating IP...')
unused_floating_ip = None
for floating_ip in conn.ex_list_floating_ips():
    if not floating_ip.node_id:
        unused_floating_ip = floating_ip
        break


if not unused_floating_ip:
    pool = conn.ex_list_floating_ip_pools()[0]
    print('Allocating new Floating IP from pool: {}'.format(pool))
    unused_floating_ip = pool.create_floating_ip()


conn.ex_attach_floating_ip_to_node(instance_worker_1, unused_floating_ip)
print('The worker will be available for SSH at %s' % unused_floating_ip.ip_address)


Kontrolcüye erişebilmesi için bu sunucuyu işçi grubuna eklediğinize dikkat edin.

Kurulum betiğine geçirilen parametrelerden görebileceğiniz gibi, bu sunucuyu işçi sunucu olarak tanımlarsınız. Bunun yanında API sunucusunun adresini ve işçilerin istekleri alabilmesi için ileti kuyruğunun adresini verirsiniz. Fraktallar uygulama kurulum betiği çeşitli parametreler alır.

Parametre

Açıklama

Örnek

-e

API servisinin uç nokta URL’si.

http://localhost/

-m

İleti servisinin aktarım URL’si.

amqp://guest:guest@localhost:5672/

-d

Veritabanı için bağlantı URL’si (burada kullanılmadı).

sqlite:////tmp/sqlite.db

Şimdi bir fraktal isteğinde bulunursanız, app-controller kontrol sunucusuna bağlanırsınız, ama asıl iş ayrı bir app-worker-1 işçi sunucusunda yapılacaktır.

SSH ile giriş yapın ve Fraktal uygulamasını kullanın

Daha önce eklenen “demokey” SSH anahtar çiftini kullanarak SSH ile app-worker-1 işçi sunucusuna giriş yapın. İşçinin IP adresini alarak başlayın:

ip_instance_worker_1 = instance_worker_1.private_ips[0]
print(ip_instance_worker_1)

Şimdi sunucuya SSH yapabilirsiniz:

$ ssh -i ~/.ssh/id_rsa USERNAME@IP_WORKER_1

Not

IP_WORKER_1 anahtarını işçi sunucunun IP adresi ile ve USERNAME anahtarını uygun kullanıcı adı ile değiştirin.

Giriş yaptıktan sonra işçi servis sürecinin beklendiği şekilde çalışıp çalışmadığını kontrol edin. İşçi servisi kayıtlarını /var/log/supervisor/ dizini altında bulabilirsiniz.

worker # ps ax | grep faafo-worker
17210 ?        R      7:09 /usr/bin/python /usr/local/bin/faafo-worker

top uygulamasını açıp faafo-worker sürecinin CPU kullanımını izleyin.

Şimdi daha önceden eklenmiş “demokey” SSH anahtar çiftini kullanarak app-controller kontrol sunucusuna giriş yapın.

$ ssh -i ~/.ssh/id_rsa USERNAME@IP_CONTROLLER

Not

IP_CONTROLLER anahtarını kontrol sunucusunun adresiyle ve USERNAME değerini uygun kullanıcı adıyla değiştirin.

API servis sürecinin beklenen şekilde çalışıp çalışmadığını kontrol edin. API servisi için kayıtları /var/log/supervisor/ dizininde bulabilirsiniz.

controller # ps ax | grep faafo-api
17209 ?        Sl     0:19 /usr/bin/python /usr/local/bin/faafo-api

Şimdi Fraktal uygulamasının komut satırı arayüzünü (faafo) kullanarak birkaç yeni fraktal isteyin. Aşağıdaki komut rasgele parametrelerle birkaç fraktal ister:

controller # faafo --endpoint-url http://localhost --verbose create
2015-04-02 03:55:02.708 19029 INFO faafo.client [-] generating 6 task(s)

İşçi sunucuda top çıktısını izleyin. :code.`faafo` çağrılır çağrılmaz faafo-worker süreci epey CPU tüketiyor olmalı.

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
17210 root      20   0  157216  39312   5716 R 98.8  3.9  12:02.15 faafo-worker

Belirli bir fraktalın ayrıntılarını göstermek için Faafo CLI’nin show alt komutunu kullanın.

controller # faafo show 154c7b41-108e-4696-a059-1bde9bf03d0a
+------------+------------------------------------------------------------------+
| Parameter  | Value                                                            |
+------------+------------------------------------------------------------------+
| uuid       | 154c7b41-108e-4696-a059-1bde9bf03d0a                             |
| duration   | 4.163147 seconds                                                 |
| dimensions | 649 x 869 pixels                                                 |
| iterations | 362                                                              |
| xa         | -1.77488588389                                                   |
| xb         | 3.08249829401                                                    |
| ya         | -1.31213919301                                                   |
| yb         | 1.95281690897                                                    |
| size       | 71585 bytes                                                      |
| checksum   | 103c056f709b86f5487a24dd977d3ab88fe093791f4f6b6d1c8924d122031902 |
+------------+------------------------------------------------------------------+

Kullanılabilir daha fazla komut bulunur; faafo get --help, faafo list --help, ve faafo delete --help ile ayrıntılarını keşfedin.

Not

Uygulama üretilen fraktal imajlarını doğrudan API servisi sunucusu tarafından kullanılan veritabanında saklar. İmaj dosyalarını bir veritabanında tutmak iyi fikir değildir. Burda yalnızca birden çok sunucunun veriye kolay erişimi olması için örnek olarak kullandık. En iyisi nesneleri Dayanıklı hale getirin kısmında kapsandığı gibi Nesne Depolamada tutmaktır.

Sonraki adımlar

Artık bulut tabanlı uygulamaların mimarisiyle ilgili temel şeyleri anlamış olmalısınız. Ek olarak yeni sunucular başlatmak, önyüklemede otomatik olarak yapılandırma ve hatta çalıştırmak için birden çok sunucu kullanabilmek için uygulamayı modülerleştirmeyle ilgili pratik de yaptınız. Bunlar uygulamanızı OpenStack bulutunda çalıştırabilmeniz için hesaplama kaynaklarını isteme ve kullanmanın temel adımlarıdır.

Burdan Dışa ölçekleme kısmına giderek uygulamanızı nasıl ölçekleyeceğinizi öğrenin. Veya öğreticideki şu adımlardan birini deneyin:

Tam kod örneği

Aşağıdaki dosya öğreticinin bu kısmındaki tüm kodu içerir. Bu kapsayıcı kod örneği kodu tek bir betik olarak görüntüleme ve çalıştırma şansı verir.

Bu betiği çalıştırmadan önce, kimlik doğrulama bilgisini, nitelik ve imaj kimliğini ayarladığınızdan emin olun.

# step-1
userdata = '''#!/usr/bin/env bash
curl -L -s https://opendev.org/openstack/faafo/raw/contrib/install.sh | bash -s -- \
    -i faafo -i messaging -r api -r worker -r demo
'''

instance_name = 'all-in-one'
testing_instance = conn.create_node(name=instance_name,
                                   image=image,
                                   size=flavor,
                                   ex_keyname=keypair_name,
                                   ex_userdata=userdata,
                                   ex_security_groups=[all_in_one_security_group])

# step-2
userdata = '''#!/usr/bin/env bash
curl -L -s https://opendev.org/openstack/faafo/raw/contrib/install.sh | bash -s -- \
    -i messaging -i faafo -r api -r worker -r demo
'''

# step-3
all_in_one_security_group = conn.ex_create_security_group('all-in-one', 'network access for all-in-one application.')
conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 80, 80)
conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 22, 22)

# step-4
conn.ex_list_security_groups()

# step-5
conn.ex_delete_security_group_rule(rule)
conn.ex_delete_security_group(security_group)

# step-6
conn.ex_get_node_security_groups(testing_instance)

# step-7
unused_floating_ip = None
for floating_ip in conn.ex_list_floating_ips():
    if not floating_ip.node_id:
        unused_floating_ip = floating_ip
        print("Found an unused Floating IP: %s" % floating_ip)
        break

# step-8
pool = conn.ex_list_floating_ip_pools()[0]

# step-9
unused_floating_ip = pool.create_floating_ip()

# step-10
conn.ex_attach_floating_ip_to_node(instance, unused_floating_ip)

# step-11
worker_group = conn.ex_create_security_group('worker', 'for services that run on a worker node')
conn.ex_create_security_group_rule(worker_group, 'TCP', 22, 22)

controller_group = conn.ex_create_security_group('control', 'for services that run on a control node')
conn.ex_create_security_group_rule(controller_group, 'TCP', 22, 22)
conn.ex_create_security_group_rule(controller_group, 'TCP', 80, 80)
conn.ex_create_security_group_rule(controller_group, 'TCP', 5672, 5672, source_security_group=worker_group)

userdata = '''#!/usr/bin/env bash
curl -L -s https://opendev.org/openstack/faafo/raw/contrib/install.sh | bash -s -- \
    -i messaging -i faafo -r api
'''

instance_controller_1 = conn.create_node(name='app-controller',
                                         image=image,
                                         size=flavor,
                                         ex_keyname='demokey',
                                         ex_userdata=userdata,
                                         ex_security_groups=[controller_group])

conn.wait_until_running([instance_controller_1])
print('Checking for unused Floating IP...')
unused_floating_ip = None
for floating_ip in conn.ex_list_floating_ips():
    if not floating_ip.node_id:
        unused_floating_ip = floating_ip
        break


if not unused_floating_ip:
    pool = conn.ex_list_floating_ip_pools()[0]
    print('Allocating new Floating IP from pool: {}'.format(pool))
    unused_floating_ip = pool.create_floating_ip()


conn.ex_attach_floating_ip_to_node(instance_controller_1, unused_floating_ip)
print('Application will be deployed to http://%s' % unused_floating_ip.ip_address)

# step-12
instance_controller_1 = conn.ex_get_node_details(instance_controller_1.id)
if instance_controller_1.public_ips:
    ip_controller = instance_controller_1.private_ips[0]
else:
    ip_controller = instance_controller_1.public_ips[0]

userdata = '''#!/usr/bin/env bash
curl -L -s https://opendev.org/openstack/faafo/raw/contrib/install.sh | bash -s -- \
    -i faafo -r worker -e 'http://%(ip_controller)s' -m 'amqp://guest:guest@%(ip_controller)s:5672/'
''' % {'ip_controller': ip_controller}
instance_worker_1 = conn.create_node(name='app-worker-1',
                                        image=image,
                                        size=flavor,
                                        ex_keyname='demokey',
                                        ex_userdata=userdata,
                                        ex_security_groups=[worker_group])

conn.wait_until_running([instance_worker_1])
print('Checking for unused Floating IP...')
unused_floating_ip = None
for floating_ip in conn.ex_list_floating_ips():
    if not floating_ip.node_id:
        unused_floating_ip = floating_ip
        break


if not unused_floating_ip:
    pool = conn.ex_list_floating_ip_pools()[0]
    print('Allocating new Floating IP from pool: {}'.format(pool))
    unused_floating_ip = pool.create_floating_ip()


conn.ex_attach_floating_ip_to_node(instance_worker_1, unused_floating_ip)
print('The worker will be available for SSH at %s' % unused_floating_ip.ip_address)


# step-13
ip_instance_worker_1 = instance_worker_1.private_ips[0]
print(ip_instance_worker_1)

# step-14
Creative Commons Attribution 3.0 License

Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.