Saturday, December 10, 2016

AWS EC2 root diski data kaybı olmadan büyütmek

EC2 instance oluştururken EBS volume size olarak 8 GB dan büyük bir size seçtiğiniz halde instance içinde partition'ı gene de 8 GB olarak görüyorsanız data kaybı olmadan diski büyütebilirsiniz.

AWS dökümantasyonu maalesef bu konuda yetersiz bilgi sunuyor : Expanding the Storage Space of an EBS Volume on Linux - Extending a Linux File System

Çünkü dökümantasyonu takip ettiğinizde 3. adımdaki

sudo resize2fs /dev/xvda1

komutundan sonra

The filesystem is already ... blocks long.  Nothing to do!

şeklinde bir uyarı almanız mümkün.

Eğer lsblk ve df -h komutlarının root partition için gösterdiği disk büyüklükleri farklı olmasına rağmen yukarıdaki mesajı alıyorsanız diski genişletmek için aşağıdakileri yapabilirsiniz.

Uyarı : Aşağıdaki komutlar Debian Jessie ile test edilmiştir. Örneklerde root disk partition /dev/xvda1 dir. Ve aşağıdaki işlemlerden önce mutlaka instance'ı durdurup bir snapshot almanız, olası data kayıpları ve boot problemlerinde tekrar bir önceki duruma sistemi getirebilmeniz için gereklidir. Eğer birşey ters giderse elinizde bir snapshot yoksa, instance'ı verileri ile birlikte çöpe atmış olacaksınız.

1. sudo fdisk /dev/xvda1 komutu ile fdisk konsolunu açın
2. p komutu ile mevcut partitionları listeleyin. Default ayarlar ile instance'ı oluşturmuş iseniz sadece 1 partition görünüyor olmalı. (Birden fazla partition görürseniz, sonraki aşamalara devam etmeyin). Bu aşamada "start" yazan sütundaki rakamı mutlaka not etmeniz lazım. Bu örnek için 4096 olsun bu rakam.
3. d komutu ile mevcut partition'ı silin. (fdisk bu işlem sonrasında değişiklikleri kaydetmediğiniz sürece gerçekten partition ı silmeyecek.)
4. n komutu ile yeni bir partition oluşturun. Partition oluştururken primary seçeneğini seçmeyi; first sector/cylinder için 2. aşamada not ettiğiniz değeri (bu örnekte 4096) girmeyi unutmayın. Son sector/cylinder için de bir sayı soracaktır. Eğer diskin tamamına kullanmayı düşünüyorsanız boş bırakarak enter ile geçebilirsiniz. Tamamını kullanmayacaksanız, bir hesap yaparak ona göre bir rakam girmeniz gerekir.
5. a komutu ile partition ı bootable hale getirin.
6. p komutu ile son durumu kontrol edin. Partition önünde * işareti ile bootable olduğu gösterilmeli. Ve start değeri 2. aşamada not ettiğiniz değer ile aynı olmalıdır.
7. Herşey tamamsa, değişiklikleri diske yansıtmak için w komutunu girin.
8. Instance'ı reboot edin.
9 .Bu aşamadan sonra bazen biraz zaman alsa da instance yeniden açılacaktır. AWS console'da EC2 instances sayfasında status checks yeşil görünüyorsa SSH ile instance'a bağlanın.
10. df -h ile mevcut disk durumunu kontrol edin. Eğer disk genişlemiş olarak görünüyorsa, işlem tamam demektir. Eğer halen eski disk boyutu görünüyorsa, sudo resize2fs /dev/xvda1 i tekrar çalıştırın, disk olması gereken büyüklüğe genişlemiş olacaktır.

Eğer instance 8. adımdan sonra bir türlü açılmıyor ve status checks sarı durumda kalıyorsa, öncelikle AWS console'dan instance screenshot talep edip, o anda ekranda ne olduğuna bakabilirsiniz. Eğer grub console'unu görüyorsanız, geçmiş olsun maalesef işlemde bir sorun olmuş demektir.

Eğer instance'ı eski haline geri getirmeniz gerekiyorsa :

1. snapshots kısmından bu işlemden önce aldığınız snapshot a tıklayın ve Actions menüsünden "Create Volume" opsiyonunu seçin. Ve bir volume oluşturun.
2. Sonra instance'ı durdurun (stop).
3. Sol menüden Volumes sayfasını açarak, instance a bağlı volume'e tıklayıp "Detach volume" seçeneği ile (Actions menüsünde) mevcut instance'dan ayırın.
4. Yeni oluşturduğunuz volume'e tıklayıp "attach volume" seçeneğini tıklayın. Disk olarak /dev/sdf gibi birşey yazıyorsa onu /dev/sda olarak değiştirip onaylayın.
5. Instance'ı başlatın (start).

Bu sayede instance eski haline gelmiş olacaktır.

Eğer en baştaki uyarıya rağmen snapshot almamışsanız ve instance başlayamıyorsa, yapabileceğiniz pek fazla birşey kalmamış oluyor, geçmiş olsun. Başta snapshot almanız konusunda uyarmıştım :)

CentOS, Amazon Linux ya da başka bir işletim sistemi (veya versiyonu) ile bu işlemi yaparken fdisk te DOS compatible mode u kapatmanız ve gene fdisk'te display units i sector e çevirmeniz gerekebilir. Normalde benim test ettiğim Debian Jessie instance'da bu opsiyonlar default olarak olması gerektiği gibi idi.

Friday, July 29, 2016

AWS Elastic Beanstalk Environment URL ve security groups

AWS Elastic Beanstalk ile bir uygulama sunmak istediğinizde önce bir application sonra da bir environment (ortam) oluşturuyoruz. Uygulama ortamı oluşturduğumuzda, o ortama erişimimizi sağlayan bir URL de elde etmiş oluyoruz.

Bu EB ortamını her zaman gerçek bir domaine yönlendirmiyoruz. Çünkü örneğin bir uygulama altında production ortamını gerçek bir domaine yönlendirmek gerekse de, bir test ortamını sadece geliştirme ekibi kullanacağından gerçek bir domaine her zaman ihtiyaç olmuyor.

Test ortamı ile ilgili farklı ihtiyaçlar da ortaya çıkabiliyor elbette. AWS EB ortamları için kabaca şu formatta bir domain oluşturuyor :

ortam_adı.region_adı.elasticbeanstalk.com 

Her ne kadar production da çalışan bir sitenin test ortamının adresini tahmin etmek ve ulaşmak kolay olmasa da gene de güvenlik açısından bir test ortamının adresinin sadece belli IP lerden erişilebilmesini sağlama gerekebiliyor. Bunu sağlamak için de genelde "security groups" lardan bazı ayarlamalar yapmak gerekiyor. Ve bu noktada ortam adresinin tam olarak neyi temsil ettiği konusu önem kazanıyor.

Konumuz bu ayarları nasıl yapacağımız değil daha çok hangi security group'ta bu ayarları yapmamız gerektiği ile ilgili. Çünkü zaten hangi security group'ta ayar yapmak gerektiği belirlendikten sonra, sadece belli IP lere izin vermek çok kolay birşey.

Bir EB ortamı 2 farklı tipte kurulabiliyor. 1) Single instance 2) Load balancing/auto scaling.

İlk tipte kurulan bir EB ortamı arkada sadece bir EC2 instance ile oluşmuş oluyor. Tüm istekleri de bu EC2 instance karşılıyor. Dolayısıyla EB ortam adresi de doğal olarak EC2 instance ile birebir ilişkilendirilmiş oluyor. Ortam adresine sadece belli IP lerin erişimi sağlanmak istenirse, EC2 security group ayarları değiştirilerek yapılabiliyor. (Önde sonradan eklenmiş bir load balancer, cloudfront vb. olmadığını varsayıyorum)

Asıl mesele load balancing/auto scaling tipinde kurulmuş EB ortamları. Çünkü bu ortamlar kurulduğunda, özel bir müdahale olmamış ise aşağıdakine benzer bir yapı oluşmuş oluyor.

EC2 Instances (Application) -> Load Balancer -> İnternet

Bu yapı ile beraber, default security group haricinde, ayrıca bir EB security group ve ELB security group da otomatik olarak oluşturulmuş oluyor. EB security group içinde ELB security group da özellikle HTTP portu için referans olarak yerini almış oluyor.

Yapıyı biraz daha detaylı göstermek istersek :

EC2 Instances (default + EB security group) -> Load Balancer (ELB security group) -> İnternet

şeklinde ifade edebiliriz.

EB security group (Inbound) kuralı kabaca :

Protocol : TCP
Port : 80
Source : ELB security group

şeklinde görünecektir.

ELB security group'ta ise (Inbound) :

Protocol : TCP
Port : 80
Source : 0.0.0.0/0

şeklinde otomatik bir kural tanımlanmış olacaktır.

EB ortamının kendine ait bir URL'i olduğu gibi, Load Balancer'ın da kendine ait bir domaini bulunmaktadır. Ve load balancer domainini çağırdığınızda, EB ortam adresi çağrılmış gibi uygulamanızı açtığını göreceksiniz. Zaten normal olan da budur.

Peki, EB ortam adresinin sadece belli IP lerden erişilmesini istersek, hangi security group'taki kuralı değiştirmek veya nasıl bir değişiklik yapmak gerekir? Bu soruyu doğru cevaplamak için EB ortam adresinin tam olarak neye karşılık geldiğini bilmemiz gerekiyor.

Otomatik isimlendirmeler nedeniyle EB security group (EC2 ya ait grup) sanki EB adresinden sorumlu olmalı gibi hissediyor olabiliriz. Uygulamanın çalıştığı katmanın adresi olarak düşünüyor olabiliriz. Ve aslında load balancerları kullanıyor olmak için, aslında test adresimizin load balancer domaini olması gerektiği sonucuna da varabiliriz. Bunlar tamamen yanlış değil. Çünkü gerçek bir domain yönlendirmek isteseydik, DNS kaydı ekleyeceğimiz adresin load balancer domaini olmasında bir sakınca bulunmuyor.

Fakat bu düşünce yaklaşık olarak şuna karşılık geliyor olurdu :

EB ortam adresi  = EB Environment [EC2 Instances]
ELB adresi = Load balancers

Yani EB ortamı denilen şey aşağı yukarı oluşturulmuş EC2 instanceların toplamı şeklinde anlaşılabilirdi. Fakat durumun öyle değil şu şekilde olduğu anlaşılıyor :

EB ortam adresi = EB Environment [EC2 Instances + Load balancers (endpoint)]
ELB adresi = Load balancers

Yani eğer load balancer/auto scaling tipinde bir EB ortamı kurmuşsanız, aslında otomatik olarak eklenen load balancerlar sizin bu ortamınızın bir parçası. Dolayısıyla da EB ortam adresiniz, Load balancerları da içine alan bir bütünün toplamının adresi. Bu nedenle de EB ortam adresini bu kurulumda karşılayan EC2 makinaları değil, kurulumun son çıkış noktası olarak load balancerlardır.

Bunu EB ortam domaini ile load balancer domainini nslookup/dig ile çözümleyerek kontrol edebileceğiniz gibi, EB ortam adresine yapmış olduğunuz isteklerin load balancerdan geçip geçmediğini de monitor ederek kontrol edebilirsiniz.

Sonuç olarak EB security group denilen güvenlik kuralları aslında zincirin son halkasını (EC2) tarafını karşılıyorlar, eğer önde bir load balancer otomatik eklenmişse, ortam adresine erişim ilk olarak load balancerlardan geçiyor demektir. Dolayısıyla IP erişim kurallarını ilk olarak orada tanımlamak gereklidir.

Sadece EB security group'da değişiklik yaparak, EB ortam adresine erişim IP bazında kısıtlanabilir mi? Evet olabilir:) Çünkü bir şeyi yapmanın elbette farklı bir yolu da olacaktır. Fakat ilk akla gelebilecek bazı yöntemler muhtemelen istenildiği gibi çalışmayacaktır.

Örneğin, EB security group'ta yukarıda yazdığım gibi load balancer'a ait güvenlik grubu bir source olarak tanımlanmış durumda. Bu load balancerdan gelen isteklere erişim veren bir kural. Eğer bu kuralı silerseniz, ortam adresi aslında load balancer üzerinden geldiğinden, artık load balancerlar üzerinden gelen isteklere EC2 cevap vermeyecek demektir. Bu da EB ortam adresinin muhtemelen HTTP 503 almasına yol açacaktır.

Load balancer IP lerine izin vermeyi denemek de bir opsiyon değil zira AWS IP lerin değişken olduğunu iletiyor.

ELB security group'u kaldırmadan EB security group içine istediğimiz IP lere erişim veren bir kural da yazmak işe yaramaz. Zira EB ortam adresi load balancer üzerinden geldiği ve buradan gelen herkese izin verdiğiniz için, ekleyeceğiniz IP kuralı hiç bir zaman geçerli olmayacaktır. Zira load balancer tarafında tüm IP lere erişim izni bulunuyor olacak.

EB security group üzerinde load balancer ı direkt kısıtlayan herhangi bir kuralın ayrıca health checkleri engellememesi de gerekir. Bir yandan da auto-scaling tipinde bir ortam kurulduğu için cloudwatch'un da çeşitli kontrollerini sağlıklı bir şekilde yapabilmesi gerekmektedir.

EB ortamınızın adresinin ortamın tüm unsurlarını içeren adres olduğunu unutmayın :)



Sunday, July 17, 2016

Open Shift incelemesi

Yakın bir zamanda Open Shift (https://www.openshift.com/) isimli web sitesi ile karşılaştım. Son dönemde AWS ürünleri üzerinde çalıştığımdan ilgimi çekti. Open Shift kendi sitelerindeki ifade ile, "Red Hat'a ait, yazılımcıların hızlıca geliştirme, barındırma ve ölçeklendirme (scaling) yapabilecekleri "cloud-based" bir "platform-as-a-service, PaaS" sistemi. Bunu okuyunca aklımda canlanan şey, AWS'nin Elastic Beanstalk ürünü oldu.

Open Shift sisteminde herşey bir "cartridge" olarak sunuluyor. Cartridge mantığını bir lego gibi düşünebilirsiniz. Bir web sitesini düşünerek örneklendirecek olursak; bir web sitesi server tarafında çeşitli servislerin birleşimi ile çalışabiliyor. Minimumda size yazdığınız kodu çalıştırıp, isteklere cevap verecek bir "web server" gerekiyor. Statik siteler dışında, doğal olarak bir database katmanına da ihtiyaç duyuyorsunuz. Bazen yoğunluğu dağıtmak için bir load balancer da genel ihtiyaçlardan birisi olabiliyor. İşte bu katmanların her biri, sizin bir araya getirebileceğiniz "cartridge" ler oluyor. Bunları bir araya getirebilmek için de bunların kurulumu, işletim sistemi vs. gibi konularla uğraşmıyorsunuz. Bir listeden seçiyorsunuz, yan yana getiriyorsunuz ve herşey otomatik olarak çalışmaya başlıyor.

Tabii verdiğim bu örnek, olayın detayını anlatmak için biraz basit kaldı. Çünkü Open Shift de seçenekler daha esnek. Örneğin, bir cartridge olarak PHP5.4 seçip, PHP çalışan bir yapıya kavuşabileceğiniz gibi; PHP5.4 gibi birşey seçmek yerine, Codeigniter framework cartridge'i seçip, PHP meselesini es geçerek Codeigniter ile devam edebiliyorsunuz. Ya da PHP framework yerine Wordpress cartridge çalıştırabiliyorsunuz.

Olası cartridge'lerden bazı örnekler de yazayım :

PHP grubu : PHP5.4, CodeIgniter 2, Laravel 5.0, Magento Community Edition, Symfony 2.3.6, ownCloud, Cacti, vb.

Python grubu : Python 2.6/2.7/3.3, Django, Flask, Tornado Web Server, CherryPy, vb.

Ruby grubu : Ruby 1.8/1.9/2.0, Ruby on Rails 3/4, Sinatra, Redmine, Keen IO, Jekyll, vb.

Ve diğerleri : MongoDB, MySQL, PostgreSQL, Cron, Web Load Balancer, JBOSS Application Server, Tomcat, Nodejs, Perl 5, Go Language, MEAN, Clojure, Reveal.js, vb.

Bunlar arasında aradığınızı bulamadıysanız üzülmeyin :) Çünkü Open Shift aynı zamanda kendi "cartridge"lerinizi de evinizde hazırlayıp, bu sisteme yüklemenize izin veriyor. (https://hub.openshift.com/quickstarts/21-cartridge-development-kit)

Güzel bir özelliği daha var bu sistemin, test etmek ve incelemek için kredi kartınızı vermek zorunda değilsiniz. Çünkü ücretsiz hesaplara 3 adet small "gear" kullanabilme hakkı verilmiş. "Gear" sizin seçtiğiniz cartridge'lerin runtime da çalıştığı bir nevi "slot"lara verilen isim. Yani ücretsiz hesapta size verilen 3 gear'a seçtiğiniz 3 cartridge i ekleyip bir "application" çatısı altında çalıştırabilirsiniz. Mesela, ben bir test uygulaması oluşturup altına PHP 5.4 ve PostgreSQL 9.2 cartridge'lerini ekledim.

Benim eklediğim PHP hello world uygulamasına (tek satır bir yazı var sadece :)) şuradan ulaşabilirsiniz :

http://test-uguraslan.rhcloud.com/

Uygulamanın yönetim panelinde aşağıdaki şekilde görünmektedir.


Open Shift konusunda anlatmak istediğim başka bir sürü konu var ama genel bir bilgi vermek amacıyla bu kadarı yeterli olacaktır.




Yeni blog sayfam

Uzun yıllardır başka bir alan adı üzerinden blog sitemi yayınlıyordum. Fakat son zamanlar da, artık biraz da çocukca gelen eski alan adımı kullanmak yerine kendi ismimle yeni blog adresine geçmenin zamanı geldiğine karar verdim. Zaten içerik olarak da çok eskimiş yazılar vardı. Çok eskiyen ve bugün artık anlamı kalmamış yazılarımı da sunmanın bir mantığı olmadığını düşündüm.

Yeni blog sitesi için başlarda gene kendi sunucum üzerinden host edebileceğim Wordpress haricinde birşeyler bakıyordum ama sadece bir blog sitesi için onlarca ücretsiz alternatif servis varken, boşu boşuna zahmet ve kaynak israfı yapmak mantıklı gelmedi. Zaten Wordpress ve bazı benzerlerinin varsayılan veritabanı olarak MySQL kullanıyor olması benim için sıkıntı idi. Çünkü ben uzun yıllardır MySQL yerine PostgreSQL tercih ediyorum. Bir blog sitesi yayınlamak için MySQL in boş yere sistemde kaynak tüketmesi de mantıklı gelmedi.

Bu site çok okunsun, birileri gelsin filan gibi beklentilerim ve amacım olmadığından online servislerin hangisini seçsem diye de çok düşünmedim. Hatta çok da incelemedim ve karşılaştırmadım. Muhtemelen Google, temel ihtiyaçları karşılayan birşey sunuyordur diye Blogger'ı tercih ettim.

Yeni sayfamın ilk içeriği için birşeyler karalamak lazımdı :) Sanıyorum ki çok da manası olmayan bu yazı ilk içerik olarak yeterli olacaktır :)