Näytetään tekstit, joissa on tunniste Amazon Web Services. Näytä kaikki tekstit
Näytetään tekstit, joissa on tunniste Amazon Web Services. Näytä kaikki tekstit

sunnuntai 5. helmikuuta 2012

Apachetop on Amazon Linux

There's handy utility for monitoring Apache logs almost in real time called apachetop. Apachetop shows the traffic your Apache is handling based on the log entries Apache writes. Of course you can read the log files with some file viewer too, but apachetop gives you an overall picture of what's currently happening on your web site, which is not easy to achieve by reading only the log files.

Initially I had some trouble on installing apachetop on EC2 running Amazon Linux, but I managed to do it with these simple commands.

% wget http://www6.atomicorp.com/channels/atomic/centos/5/x86_64/RPMS/libadns-1.4-3.el5.art.x86_64.rpm
% wget http://pkgs.repoforge.org/apachetop/apachetop-0.12.6-3.el5.rf.x86_64.rpm
% yum install libadns-1.4-3.el5.art.x86_64.rpm
% yum install apachetop-0.12.6-3.el5.rf.x86_64.rpm

The commands above download the Centos RPM files and install them using yum. It's better to download the RPMs and install them manually than add some random Centos repositories to your system. Although Amazon is mostly compatible with Centos, it's risky business use standard Centos repositories.

After installing, you can start the apachetop to monitor your Apache. If you have several virtual hosts each writing to different log file, you can add all of them to a single apachetop session. Let's assume you have virtual hosts vhost1 and vhost2, which write logs vhost1_access_log and vhost2_access_log. To monitor both of these, use the following command.

apachetop -f vhost1_access_log -f vhost2_access_log -H 5000 -s 1 -l

I also added some extra parameters here. The -H sets how many total hits the monitoring shows before starting to rotate the log data. The -s sets how many URL path elements are used to distinguish different URLs. For example -s 2 would set mean that /path1/path2/path3 and /path1/path2/path4 would be counted as one URLs. On the other hand, /path1/path3/path2 and /path1/path2/path3 would be different. The last switch -l just says that all URLs should be changed to lowercase before comparing them to each other. Use man apachetop to see more details.

keskiviikko 1. helmikuuta 2012

Remote VisualVM session through SSH tunneling

VisualVM is standard Java profiling&monitoring tool that comes with Oracle's SDK. Probably you knew this already, if you have read this far.

Remote VisualVM session through SSH seems to be quite difficult. I found several instructions on how to do it, but they didn't say what to do exactly, especially in my Amazon EC2 environment. The EC2 host we're monitoring here has public elastic IP as well as private IP address.

VisualVM requires SOCKS tunneling instead of standard SSH port forwarding for some reasons I didn't study too well. And anyway, you don't have to know either to get it working...

VisualVM connection setup
  1. Create SOCKS tunnel to remote host (in this example it's an EC2 instance)
    % ssh -D 10000 user@remote.host.com
  2. Prepare the process you want to monitor. In this case, we're monitoring a Tomcat process so we're adding the following JAVA_OPTS to the Tomcat process. Notice that the JMX port is set to 9000 and this is the port we're connecting to later.
    JAVA_OPTS="...all_the_required_java_opts_here... -Dcom.sun.management.jmxremote.port=9000 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
    
  3. Start the Tomcat with the JAVA_OPTS given above
  4. Create permissions.txt for jstatsd with the following content
    grant {
      permission java.security.AllPermission;
    };
    
  5. Start jstatsd process
    jstatd -J-Djava.security.policy=permissions.txt
    
  6. Start VisualVM on your localhost
  7. Navigate to Tools -> Options -> Network and set there the following values
    1. SOCKS Proxy: localhost
    2. Port: 10000
  8. Check the local IP of the remote host by executing ifconfig (assuming Linux as operating system) on the remote host. The output below is edited slightly to hide some details
    % ifconfig 
    eth0      Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:XX  
              inet addr:10.1.1.1  Bcast:10.1.205.255  Mask:255.255.255.0
    ...
    
  9. In VisualVM, add new remote monitoring session from File -> Add Remote Host
    1. Host name is the internal IP address of the remote host, in this case 10.1.1.1
  10. Right click the created remote host and select Add JMX Connection
    1. The correct value in this example is 10.1.1.1:9000
  11. Now you're monitoring should start working! SSH was complaining about connection timeouts, but they don't seem to matter too much
What's important to notice is that public elastic IP does not work in VisualVM connection setup!

maanantai 23. tammikuuta 2012

lauantai 21. tammikuuta 2012

Tomcat clustering and session persistency in AWS


Tomcat supports clustering out-of-the-box (see http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html). However, since Amazon EC2 environment has some pecualiar features such as not supporting IP multicasting (http://aws.amazon.com/vpc/faqs/#R4), the traditional(?) way of Tomcat clustering cannot be used. Instead of using direct communication between different cluster nodes, you can use HTTP session sharing via database. Although this is not as fast or flexible as direct communication, it's still better than no clustering.

How session sharing works

Tomcat copies session data to a database when it's shut down. It also makes a periodical copying of idle sessions every now and then (the configuration given below doesn't define the exact maximum session idle time before Tomcat does replication to database. The configured maximum time is about maxIdleBackup + processExpiresFrequency * engine.backgroundProcessorDelay. Google for more details...).

Because all the Tomcats are sharing a commong session repository i.e. database, they all have access to each other's sessions that have been persisted at least once. Whenever a new Tomcat instance starts, it reads the existing sessions from common session repository and is then able to serve any request to any Tomcat in the cluster up to start-up time of the instance.

Because of delays in sharing the sessions, you should enable sticky sessions in you load balancer. This means that each request from a user will be directed to the same Tomcat as long as user HTTP session exists.

Use application generated cookie in ELB

In order to use database session sharing, you must use sticky sessions in your load balancer. Amazon ELB has the options of using either ELB generated session cookie or application generated session cookie. I think that in this case one should use application generated session cookie (JSESSIONID), because ELB generated session cookie may have different expiration time than your application's session. If ELB cookie expires before you application's session, user may get served by different Tomcat, although application's session has not changed. This may lead into nasty problems.

Setup RDS based database for Tomcat session storing

The easiest way of using a common session replication database in Amazon is RDS service. Of course you may also set up your own database on one EC2 instance, but this would be a single point of failure. So, I'm using RDS and MySQL in this example. Create a session database and a session table in the database.
CREATE DATABASE tomcat_data DEFAULT CHARACTER SET UTF8 COLLATE utf8_swedish_ci;
GRANT ALL ON tomcat_data.* TO "tomcat"@"%" IDENTIFIED BY "tomcat";


create table tomcat_data.tomcat_sessions (
  session_id varchar(100) not null primary key,
  valid_session char(1) not null,
  max_inactive int not null,
  last_access bigint not null.
  app_name varchar(255),
  session_data mediumblob,
  KEY kapp_name(app_name)
);

MySQL connection from Tomcat

You need to copy the mysql-connector-java-x.x.xx.jar under $CATALINA/lib (on Ubuntu, it's /usr/share/tomcat6/lib/ depending on your Ubuntu/Tomcat version). This JAR is needed to create connection from Tomcat to MySQL.

Here's context.xml you need. Remember to change localhost to something more meaningful in the XML file.

<Context>

...

    <!-- The idle time in seconds before persisting session is
         maxIdleBackup + processExpiresFrequency * engine.backgroundProcessorDelay.
         The backgroundProcessorDelay is around 10 seconds. This configuration should make Tomcat
         to persist sessions after 20 seconds of idling and hold them in memory as long as each
         instance wants -->
    <Manager className="org.apache.catalina.session.PersistentManager"
      saveOnRestart="true"
      minIdleSwap="-1"
      maxIdleSwap="-1"
      maxIdleBackup="20"
      processExpiresFrequency="1">
      <Store className="org.apache.catalina.session.JDBCStore"
        connectionURL="jdbc:mysql://localhost/tomcat_data"
        driverName="com.mysql.jdbc.Driver"
        connectionName="tomcat"
        connectionPassword="tomcat"
        sessionIdCol="session_id"
        sessionValidCol="valid_session"
        sessionMaxInactiveCol="max_inactive"
        sessionLastAccessedCol="last_access"
        sessionTable="tomcat_sessions"
        sessionAppCol="app_name"
        sessionDataCol="session_data"
      />
    </Manager>
...

</Context>


Problems in this solution

If Tomcat dies unexpectedly, the new sessions served by dead instance are lost. Most likely with the configuration above, sessions newer than 30 seconds will disappear. Also new changes that have been done to session data will be lost.

Session related database traffic could grow quite high in a busy web site. I have no cure for this, but of course you can at least use a different database for sessions than what's being used for other data.

sunnuntai 1. tammikuuta 2012

Amazonin Virtual Private Cloud ja NAT


Tavoitteena luoda kuvan mukainen suljettu verkko (Virtual Private Cloud, VPC), johon on kytketty kuormantasaaja (ELB) ulkoa tulevan liikenteen ohjaukseen ja jos pääsee internetiin vain NAT-koneen kautta. 

Kuvasta näkee, että aliverkko 10.0.1.0/24 on yksityinen verkko, josta ei pääse ulos kuin NAT-koneen kautta. Verkko 10.0.2.0/24 puolestaan on julkinen verkko, jonne sijoitetaan ELB, internet gateway ja NAT-kone. On syytä huomata (jotain mitä en itse heti tajunnut), että ELB:llä on kaksoisrooli internetissä sekä VPC:ssä: ELB näkyy internetiin julkisella IP:llä ja VPC:n sisällä puolestaan VPC:n IP:llä. ELB:n pitää olla VPC:ssä, josta pääsee IGW:n kautta ulos tai ELB ei toimi. Koska NAT-koneelle on annettu julkinen Elastic IP, sekin näkyy ulos suoraan internetiin.

Tekstikuvaus ei johda ihan suoraviivaisesti kuvan tilanteeseen, joten kannattaa lukea huolella, jos jotain kohtaa ajattelee hyödyntää.

Huomaathan, että tämän tekstin ohjeiden kokeilu maksaa! Itselleni kokeilu kustansi $0,93, koska käytin kahta small-instanssia 4 tunnin ajan.

VPC-verkon luominen yhdellä aliverkolla 
Luodaan VPC 10.0.0.0/16 CIDR-lohkolla (Classless Inter-Domain Routing).
$ ec2-create-vpc 10.0.0.0/16
VPC vpc-1cb6db75 pending 10.0.0.0/16 dopt-10b6db79 default

Luodaan aliverkko 10.0.1.0/24. Aliverkossa on 256 IP-osoitetta, joista Amazon varaa 4 ensimmäistä ja viimeisen eli käytettäväksi jää 251 IP-osoitetta.
$ ec2-create-subnet --vpc vpc-1cb6db75 -i 10.0.1.0/24
SUBNET subnet-f3b1dc9a pending vpc-1cb6db75 10.0.1.0/24 251 eu-west-1c

Aliverkko luotiin Amazonin valitsemaan saatavuusalueeseen (Availability Zone, AZ) eu-west-1c.


Internet-yhdyskäytävän luominen VPC:lle 
VPC:ssä olevilla koneilla ei ole pääsyä internetiin ilman, että niille on luotu internet-yhdyskäytävä (Internet gateway, IGW). Luodaan VPC:lle yhdyskäytävä ja liitetään se VPC:hen.
$ ec2-create-internet-gateway
INTERNETGATEWAY igw-ef86eb86
$ ec2-attach-internet-gateway igw-ef86eb86 --vpc vpc-1cb6db75
ATTACHMENT vpc-1cb6db75 attaching

AWS on luonut automaattisesti reititystaulun. Katsotaan taulun tiedot.
$ ec2-describe-route-tables 
ROUTETABLE rtb-1eb6db77 vpc-1cb6db75
ROUTE local  active 10.0.0.0/16
ASSOCIATION rtbassoc-11b6db78 main

Lisätään IGW reititystauluun.
$ ec2-create-route rtb-1eb6db77 -r 0.0.0.0/0 --gateway igw-ef86eb86 
ROUTE igw-ef86eb86   0.0.0.0/0

EC2-instanssin luominen aliverkkoon
Luodaan aluksi pääsyoikeusryhmä, jolla sallitaan pääsy VPC:ssä oleviin koneisiin. Huomaa, että pääsyoikeusryhmä on VPC-kohtainen. Määritetään samalla SSH-portti (22) ja HTTP-portti (80) aukinaisiksi tässä ryhmässä.
$ ec2-add-group vpc_public_access -d "VPC access from public Internet" -vpc vpc-1cb6db75
$ ec2-authorize sg-06acb16a -P tcp -p 22 -s 0.0.0.0/0
GROUP sg-06acb16a    
PERMISSION   ALLOWS tcp 22 22 FROM CIDR 0.0.0.0/0 ingress
$ ec2-authorize sg-06acb16a -P tcp -p 80 -s 0.0.0.0/0
GROUP sg-06acb16a    
PERMISSION   ALLOWS tcp 80 80 FROM CIDR 0.0.0.0/0 ingress

Luodaan aliverkkoon 32-bittinen Ubuntu 10.04-palvelin (AMI löytyy täältä: http://uec-images.ubuntu.com/releases/lucid/release/), jolla pyörii Apache. Käytetään palvelimen luonnissa aiemmin tehtyä (http://pedanttinen.blogspot.com/2011/12/amazon-web-services-ilmainen-kokeilu_29.html) testkeypair-avainta. Annetaan palvelimelle aliverkon ensimmäinen vapaa osoite.
$ ec2-run-instances ami-c00e3cb4 --instance-count 1 --instance-type m1.small --key testkeypair --group sg-06acb16a --subnet subnet-f3b1dc9a --private-ip-address 10.0.1.4
RESERVATION r-3eb35377 093338577702 
INSTANCE i-8cb527c5 ami-c00e3cb4   pending testkeypair 0  m1.small 2011-12-30T08:54:45+0000 eu-west-1c aki-4deec439   monitoring-disabled  10.0.1.4vpc-1cb6db75 subnet-f3b1dc9a ebs     paravirtual xen  sg-06acb16a default

Kuten yltä nähdään, luotu instanssi on tyyppiä small. Small-tyyppinen palvelin maksaa Euroopassa $0,095 tunnilta. Small-tyyppinen palvelin on 32-bittinen ja siksi myös käyttöjärjestelmäksi valittiin 32-bittinen versio.

Tässä vaiheessa luodulle koneelle ei pääse mistään käsiksi. Sille pitää siis antaa hetkeksi julkinen IP-osoite eli VPC Elastic IP -osoite. Huomaa, että myös VPC Elastic IP on maksullinen, mikäli sitä ei ole sidottu mihinkään ajossa olevaan instanssiin ($0.01 tunnilta, jos IP ei ole käytössä kokonaisen tunnin aikana)!
$ ec2-allocate-address -d vpc
ADDRESS 176.34.130.141  vpc eipalloc-d186ebb8
$ ec2-associate-address --allocation-id eipalloc-d186ebb8 --instance i-8cb527c5
ADDRESS  i-8cb527c5 eipalloc-d186ebb8 eipassoc-b486ebdd

Nyt voidaan tehdä yhteyskokeilu palvelimelle SSH:lla.
$ ssh -i ~/aws/certs/testkeypair_private.key ubuntu@176.34.130.141
Jos kaikki meni putkeen, luotu instanssi vastaa huuteluihin. 

Apachen virittäminen instanssille
Kirjaudu sisään instanssille em. komennolla. Jostain syystä nimipalvelu antaa 10-verkon osoitteita Ubuntun päivityspalvelimen osoitteeksi:
$ nslookup eu-west-1.ec2.archive.ubuntu.com
Server:  217.30.180.230
Address: 217.30.180.230#53

Non-authoritative answer:
Name: eu-west-1.ec2.archive.ubuntu.com
Address: 10.228.171.176
Name: eu-west-1.ec2.archive.ubuntu.com
Address: 10.226.230.15

$ nslookup archive.ubuntu.com
Server:  217.30.180.230
Address: 217.30.180.230#53

Non-authoritative answer:
Name: archive.ubuntu.com
Address: 91.189.92.183
...

Tämän takia tehdään "pieni" säätö instanssin hosts-tiedostoon, että päästään sujuvasti eteenpäin. Lisää alla oleva rivi.
91.189.92.183 eu-west-1.ec2.archive.ubuntu.com

Aja seuraavat komennot.
$ sudo apt-get update
$ sudo apt-get install apache2

Nyt Apachen pitäisi vastata osoitteesta http://176.34.130.141/. 

Kuormantasaajan luominen
Luodaan kuormantasaaja (ELB), jonka kautta pitäisi Apachen tarjoilemat sivut näkyviin.
elb-create-lb vpc-lb --subnets subnet-f3b1dc9a --groups sg-06acb16a --listener "protocol=HTTP, lb-port=80, instance-port=80"
elb-create-lb:  Service error: InvalidSubnetID.NotFound 
 AWSRequestId:690642d8-32db-11e1-a58c-ab42d741c3e0

Jostain syystä yllä oleva komento epäonnistuu, mutta täsmälleen sama onnistuu AWS Management Consolen kautta ilman ongelmia. Luodaan kuormantasaaja em. parametrein AWS Management Consolesta (ohjeita täällä: http://docs.amazonwebservices.com/ElasticLoadBalancing/2011-11-15/DeveloperGuide/USVPC_creating_basic_lb.html). Hassua kyllä, netistä ei löytynyt mitään tietoa miksi komentoriviltä homma ei luonnistu.

Kuormantasaajan käynnistymisessä saattaa mennä jonkin aikaa. Joskus instanssit eivät näy heti ELB:llä ja ELB vain sanoo "instance registration is still in progress". Kun kuormantasaaja toimii, näkyy Apache kuormantasaajan läpi: http://vpc-lb-ui-1608557811.eu-west-1.elb.amazonaws.com/.

Palvelu näkyy kuormantasaajan kautta, vaikka Ubuntu-instanssilta poistaisi julkisen IP:n. Kuormantasaajan kautta voi siis päästä käsiksi VPC:n sisälle, vaikka sinne ei muutoin olisi julkista pääsyä.

Ulospäin menevän liikenteen ohjaus NAT:n kautta
Luodaan ensiksi Amazonin tarjoaman VPC NAT AMI:n pohjalta uusi instanssi.
$ ec2-run-instances ami-095b6c7d --instance-count 1 --instance-type m1.small --key testkeypair --group sg-06acb16a --subnet subnet-f3b1dc9a --private-ip-address 10.0.1.5
RESERVATION r-a69272ef 093338577702 
INSTANCE i-3c5dcf75 ami-095b6c7d   pending testkeypair 0  m1.small 2011-12-30T12:15:36+0000 eu-west-1c aki-4deec439   monitoring-disabled  10.0.1.5 vpc-1cb6db75 subnet-f3b1dc9a ebs     paravirtual xen  sg-06acb16a default

Poistetaan SrcDestCheck-attribuutti NAT-instanssilta.
$ ec2-modify-instance-attribute --source-dest-check false i-3c5dcf75
sourceDestCheck i-3c5dcf75 false

Siirretään aiemmin luotu julkinen IP-osoite NAT-instanssille.
$ ec2-describe-addresses
ADDRESS 176.34.130.141 i-8cb527c5 vpc eipalloc-d186ebb8 eipassoc-979cf1fe
$ ec2-disassociate-address --association-id eipassoc-979cf1fe
ADDRESS    eipassoc-979cf1fe
$ ec2-associate-address --allocation-id eipalloc-d186ebb8 --instance i-3c5dcf75
ADDRESS  i-3c5dcf75 eipalloc-d186ebb8 eipassoc-2899f441

Kirjaudutaan sisään NAT-instanssille. SSH valittaa todennäköisesti tässä kohtaa vastapään tunnisteen vaihtuneen. Ongelma ratkeaa .ssh/known_hosts-tiedostoa editoimalla.
ssh -i ~/aws/certs/testkeypair_private.key ec2-user@176.34.130.141

Tämän jälkeen voi kopioida testkeypair_private.key-tiedoston NAT-koneelle ja tehdä seuraavan tempun.
[ec2-user@ip-10-0-1-5 ~]$ ssh -i testkeypair_private.key ubuntu@10.0.1.4

Aliverkon sisällä liikenne toimii siis ok.

NAT-aliverkon luominen
Luodaan uusi aliverkko NAT:lle.
$ ec2-create-subnet --vpc vpc-1cb6db75 -i 10.0.2.0/24
SUBNET subnet-249af74d pending vpc-1cb6db75 10.0.2.0/24 251 eu-west-1c

Poistetaan vanha NAT-kone ja tehdään uusi tilalle uuteen aliverkkoon.
$ ec2-terminate-instances i-3c5dcf75
INSTANCE i-3c5dcf75 running shutting-down
$ ec2-run-instances ami-095b6c7d --instance-count 1 --instance-type m1.small --key testkeypair --group sg-06acb16a --subnet subnet-249af74d --private-ip-address 10.0.2.4
RESERVATION r-189c7c51 093338577702 
INSTANCE i-3648da7f ami-095b6c7d   pending testkeypair 0  m1.small 2011-12-30T13:10:09+0000 eu-west-1c aki-4deec439   monitoring-disabled  10.0.2.4 vpc-1cb6db75 subnet-249af74d ebs     paravirtual xen  sg-06acb16a default

Poistetaan IGW 1-verkon reititystaulusta.
$ ec2-describe-route-tables 
ROUTETABLE rtb-1eb6db77 vpc-1cb6db75
ROUTE local  active 10.0.0.0/16
ROUTE igw-ef86eb86  active 0.0.0.0/0
ASSOCIATION rtbassoc-11b6db78 main
$ ec2-delete-route rtb-1eb6db77 --cidr 0.0.0.0/0
RETURN true

Lisätään NAT-kone 1-verkon reititystauluun.
$ ec2-create-route rtb-1eb6db77 -r 0.0.0.0/0 --instance i-3648da7f
ROUTE  i-3648da7f  0.0.0.0/0

Luodaan uusi reititystaulu uudelle aliverkolle.
$ ec2-create-route-table vpc-1cb6db75
ROUTETABLE rtb-cd95f8a4 vpc-1cb6db75
ROUTE local  active 10.0.0.0/16

Lisätään uuteen reititystauluun aiemmin luotu IGW.
$ ec2-create-route rtb-cd95f8a4 -r 0.0.0.0/0 --gateway igw-ef86eb86 
ROUTE igw-ef86eb86   0.0.0.0/0

Liitetään uusi reititystaulu uuteen aliverkkoon.
$ ec2-associate-route-table rtb-cd95f8a4 --subnet subnet-249af74d
ASSOCIATION rtbassoc-5f94f936 rtb-cd95f8a4 subnet-249af74d

Asetetaan NAT-koneelle julkinen IP.
$ ec2-associate-address --allocation-id eipalloc-d186ebb8 --instance i-3648da7f
ADDRESS  i-3648da7f eipalloc-d186ebb8 eipassoc-6894f901

Poistetaan SrcDestCheck-attribuutti NAT-instanssilta.
$ ec2-modify-instance-attribute --source-dest-check false i-3648da7f
sourceDestCheck i-3648da7f false

Nyt pitäisi olla mahdollista mennä NAT-koneen kautta julkisella IP:llä NAT-koneelle ja siitä suoraan Ubuntu-koneelle. Tämän jälkeen pitää vielä liikuttaa ELB julkiseen (uuteen) aliverkkoon eli samaan, missä NAT-kone asustaa. Kun tämä on tehty, pitäisi liikenteen kulkea myös kuormantasaajan kautta. Kuten aiemmin, uusi kuormantasaaja luodaan AWS Management Consolen kautta.

Lopuksi poistetaan kaikki käytetyt resurssit
$ ec2-terminate-instances i-8cb527c5 i-3648da7f
INSTANCE i-8cb527c5 running shutting-down
INSTANCE i-3648da7f running shutting-down
$ elb-delete-lb vpc-lb-ui
$ ec2-release-address --allocation-id eipalloc-d186ebb8 176.34.130.141
ADDRESS    eipalloc-d186ebb8
$ ec2-disassociate-route-table rtbassoc-5f94f936
RETURN true
$ ec2-delete-subnet subnet-249af74d
SUBNET subnet-249af74d
$ ec2-delete-subnet subnet-f3b1dc9a
SUBNET subnet-f3b1dc9a
$ ec2-delete-route-table rtb-cd95f8a4
RETURN true
$ ec2-delete-route rtb-1eb6db77 -cidr 0.0.0.0/0
RETURN true
$ ec2-detach-internet-gateway --vpc vpc-1cb6db75  igw-ef86eb86
RETURN true
$ ec2-delete-internet-gateway igw-ef86eb86
RETURN true
$ ec2-delete-group sg-06acb16a
RETURN true
$ ec2-delete-group sg-9facb1f3
RETURN true
$ ec2-delete-vpc vpc-1cb6db75
VPC vpc-1cb6db75
$ ec2-delete-volume vol-27d0c94e
VOLUME vol-27d0c94e
$ ec2-delete-volume vol-2bd6cf42
VOLUME vol-2bd6cf42

Kevyt klusterointi Amazon Web Servicessä



Kokeillaan rakentaa kahden weppipalvelimen klusteri yllä olevan kuvan mukaisesti ja käyttää Amazonin tarjoamaa kuormantasaajaa (ELB, Elastic Load Balancing) komentorivikomennoilla. Weppipalvelimena toimivat kaksi Apachea, jotka tarjoilevat molemmat yhtä sivua.

Klusterin palvelimien pystytys
Klusterin palvelimet voisi pystyttää yksitellen edellisen blogauksen ohjeiden perusteella. On kuitenkin mielenkiintoisempaa rakentaa image, jolta molemmat koneet käynnistetään.

Luodaan ensin yksi EC2-instanssi Ubuntu 10.04:n AMI:n pohjalta.

$ ec2-run-instances ami-cc0e3cb8 --instance-count 1 --instance-type t1.micro --key testkeypair --group public_access
RESERVATION r-adfdf5db 093338577702 public_access
INSTANCE i-14cc735d ami-cc0e3cb8 pending testkeypair 0 t1.micro 2011-12-04T16:59:46+0000 eu-west-1a aki-4feec43b monitoring-disabled ebs paravirtual xen sg-12ac4965 default

Asennetaan koneelle Apache-palvelin. Apachen asentaminen vaatii koneelle kirjautumista ja koneelle kirjautuminen edellyttää koneen nimen tietämistä, joten selvitetään nimi ensin.

$ ec2-describe-instances
RESERVATION r-adfdf5db 093338577702 public_access
INSTANCE i-14cc735d ami-cc0e3cb8 ec2-46-137-22-203.eu-west-1.compute.amazonaws.com ip-10-48-9-210.eu-west-1.compute.internal running testkeypair 0 t1.micro 2011-12-04T16:59:46+0000 eu-west-1a aki-4feec43b monitoring-disabled 46.137.22.203 10.48.9.210 ebs paravirtual xen sg-12ac4965 default
BLOCKDEVICE /dev/sda1 vol-7551591c 2011-12-04T17:00:04.000Z

Kirjaudutaan koneelle ja asennetaan Apache.

$ ssh -i certs/testkeypair_private.key ubuntu@ec2-46-137-22-203.eu-west-1.compute.amazonaws.com
$ sudo apt-get update
$ sudo apt-get install apache2

Todetaan selaimella, että Apache toimii eli mennään osoitteeseen http://ec2-46-137-22-203.eu-west-1.compute.amazonaws.com..

Tehdään luodusta Ubuntu-asennuksesta asennusmedia, josta on helppo luoda klusteriin uusia instansseja.

$ ec2-stop-instances i-14cc735d
INSTANCE i-14cc735d running stopping
$ ec2-create-image i-14cc735d --name "weppipalvelin" --description "Klusterin weppipalvelimien luomiseen image"
IMAGE ami-73073b07

Imagen olemassaolon voi vielä tarkistaa näin.

$ ec2-describe-images
IMAGE ami-73073b07 093338577702/weppipalvelin 093338577702 available private x86_64 machine aki-4feec43b ebs paravirtual xen
BLOCKDEVICEMAPPING /dev/sda1 snap-aaef70c2 8

Sitten pitäisi käynnistää klusterin koneet. Poistetaan ensin kuitenkin aiemmin luotu instanssi sotkemasta muuta säätöä.

$ ec2-terminate-instances i-14cc735d

Uusien koneiden käynnistäminen.

$ ec2-run-instances ami-73073b07 --instance-count 2 --instance-type t1.micro --key testkeypair --group public_access
RESERVATION r-2b89815d 093338577702 public_access
INSTANCE i-10bf0059 ami-73073b07 pending testkeypair 0 t1.micro 2011-12-04T18:09:57+0000 eu-west-1c aki-4feec43b monitoring-disabled ebs paravirtual xen sg-12ac4965 default
INSTANCE i-12bf005b ami-73073b07 pending testkeypair 1 t1.micro 2011-12-04T18:09:57+0000 eu-west-1c aki-4feec43b monitoring-disabled ebs paravirtual xen sg-12ac4965 default

Koneiden status käynnistyksen jälkeen.

$ ec2-describe-instance-status
INSTANCE i-10bf0059 eu-west-1c running 16
INSTANCE i-12bf005b eu-west-1c running 16

AWS antoi koneille DNS-nimet ec2-79-125-46-213.eu-west-1.compute.amazonaws.com ja ec2-46-137-144-163.eu-west-1.compute.amazonaws.com. Muutetaan jälkimmäisen koneen tiedostoa /var/www/index.html ja lisätään sinne tunnisteen "Kone 2", jotta koneet voi myöhemmin erottaa kuormantasaajan takaa.

Kuormantasaajan luominen
Aivan ensiksi pitää noutaa kuormantasaajan komentorivityökalut.

$ wget http://ec2-downloads.s3.amazonaws.com/ElasticLoadBalancing.zip

Paketti pitää purkaa ja sen jälkeen vielä editoida aiemmin luotua env.sh-tiedostoa, jotta ELB:n työkalut saadaan polkuun ja jotta ELB:n työkalut tietävät mistä löytyvät. Lisää siis seuraavat rivit.

export AWS_ELB_HOME=~/aws/ElasticLoadBalancing-1.0.15.1
export PATH=$PATH:$EC2_HOME/bin:$AWS_ELB_HOME/bin
export EC2_REGION=eu-west-1

ELB:n luonti.

$ elb-create-lb klusteri-lb --listener "protocol=HTTP, lb-port=80, instance-port=80" --availability-zones eu-west-1c
DNS_NAME klusteri-lb-828561786.eu-west-1.elb.amazonaws.com

Lisätään instanssit ELB:lle.

$ elb-register-instances-with-lb klusteri-lb --instances i-10bf0059,i-12bf005b
INSTANCE_ID i-12bf005b
INSTANCE_ID i-10bf0059

Selaimella voi käydä tarkistamassa, että kuormantasaaja heittelee pyyntöjä molemmille koneille: http://klusteri-lb-828561786.eu-west-1.elb.amazonaws.com.

Jälkien siivoaminen 
Lopuksi poistetaan kaikki varatut resurssit, jotta AWS ei lähettele laskuja perään.

$ elb-delete-lb klusteri-lb
$ ec2-terminate-instances i-12bf005b i-10bf0059

Luodun AMI:n poistaminen on karvan verran hankalampaa.

$ ec2-describe-snapshots
SNAPSHOT snap-aaef70c2 vol-7551591c completed 2011-12-04T17:22:54+0000 100% 093338577702 8 Created by CreateImage(i-14cc735d) for ami-73073b07 from vol-7551591c
$ ec2-deregister ami-73073b07
IMAGE ami-73073b07
$ ec2-delete-snapshot snap-aaef70c2
SNAPSHOT snap-aaef70c2

Voiko kahden koneen klusterin tekeminen mennä vielä paljon helpommaksi?

torstai 29. joulukuuta 2011

Amazon Web Services - ilmainen kokeilu

AWS:n kokeilu on ilmaista ja helppoa. Alla kuvaus Ubuntu-palvelimen luomisesta Amazonin pilveen alkaen AWS-tilin perustamisesta ja päättyen pystytetyn palvelimen tuhoon.

AWS-tilin luominen
Tarvittavat välineet
  • Luottokortti
  • Puhelinliittymä

AWS:n kokeilu on perusjutuissa ilmaista. Kannattaa silti olla tarkkana mihin tiliään käyttää ja minkä verran erilaisia resursseja varaa. Erityisen huolellinen pitää olla tunnusten ja avainten kanssa, koska niiden vuotaminen vääriin käsiin tulee kalliiksi. Ilmaisista palveluista tarkemmin täällä (AWS Free Usage Tier) http://aws.amazon.com/free/

AWS-tilin luonnin aikana joudut syöttämään luottokorttitietosi ja sitoutumaan AWS:n käyttöehtoihin. Tilin luonnin aikana puhelinnumero varmennetaan siten, että AWS soittaa antamaasi numeroon ja pyytää syöttämään selaimessa näkyvän numeron. En tiedä miten tämä parantaa tietoturvaa sinänsä (ei sulje pois esimerkiksi prepaid-numeron käyttöä), mutta näin AWS toimii.

Komentorivityökalujen käyttöönotto
EC2-instanssin (http://en.wikipedia.org/wiki/Amazon_EC2) voi luoda helposti AWS-konsolista selaimella. Hiirenheiluttelun asemesta voi saman tehdä myös näppäimiä takomalla. Alla kuvaus Ubuntu-pohjaisen palvelimen luonnista EC2 Micro -instanssina. Komennot toimivat sellaisenaan Ubuntu-koneessa (bash-shellillä), mutta jos käyttää esimerkiksi Windowsia, joutuu soveltamaan.

Ensiksi pitää hakea EC2-komentorivityökalut. Tämä hoituu helpoiten komentoriviltä: wget http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip. Komentorivityökalujen asennusohjeet löytyvät täältä: http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/index.html?SettingUp_CommandLine.html, mutta myös tämän kuvauksen pitäisi riittää.

Komentorivityökalut tarvitsevat muutaman ympäristömuuttujan toimiakseen sulavasti. Ne tarvitsevat myös X.509-sertifikaatin, jotka voi luoda tai asettaa AWS:n konsolissa (yksityiskohtaiset ohjeet täällä: http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/using-credentials.html#using-credentials-certificate). Luodaan sertifikaatti tässä kohtaa.

Oletetaan, että edellä luotiin private key tiedostoon nimellä pk-merkkijono.pem ja sertifikaatti tiedostoon nimellä cert-merkkijono.pem. Oletetaan myös, että ec2-api-tools.zip on purettu hakemistoon ~/aws/ec2-api-tools-1.5.0.1-2011.11.30. Luo tiedosto env.sh alla olevalla sisällöllä.

export EC2_HOME=~/aws/ec2-api-tools-1.5.0.1-2011.11.30
export PATH=$PATH:$EC2_HOME/bin
export EC2_PRIVATE_KEY=~/aws/certs/pk-merkkijono.pem
export EC2_CERT=~/aws/certs/cert-merkkijono.pem
export JAVA_HOME=/usr/lib/jvm/java-6-sun
export EC2_URL=https://ec2.eu-west-1.amazonaws.com

Ota env.sh-tiedoston asetukset käyttöön: source env.sh.

Kokeile komentorivityökalujen toimivuutta:
$ ec2-describe-regions
Tuloksena pitäisi olla jotain alla olevan näköistä:

REGION eu-west-1       ec2.eu-west-1.amazonaws.com
REGION us-east-1       ec2.us-east-1.amazonaws.com
REGION ap-northeast-1  ec2.ap-northeast-1.amazonaws.com
REGION us-west-2       ec2.us-west-2.amazonaws.com
REGION us-west-1       ec2.us-west-1.amazonaws.com
REGION ap-southeast-1  ec2.ap-southeast-1.amazonaws.com

Tulosteesta näkee, että env.sh-tiedostossa asetettu EC2_URL viittaa eu-west-1-regioonaan. EC2_URL-muuttuja määrittää komentorivityökalujen oletus-regionin.

Pääsyoikeuksien määrittäminen
Kun komentorivityökalut toimivat, voidaan alkaa määrittämään EC2-instanssin tarvitsemia palikoita. Ensimmäisenä pitää luoda pääsyoikeusmääritykset EC2-instanssin käyttämälle ryhmälle (security group). Luodaan avaimet, joilla instanssille pääsee kirjautumaan:
$ ec2-add-keypair testkeypair

Kirjautuneena olevan käyttäjän pitäisi nähdä AWS Management Consolessa juuri luotu avain: https://console.aws.amazon.com/ec2/home?region=eu-west-1&#s=KeyPairs. Talleta komennon koko tulostus tiedostoon lukuunottamatta ensimmäistä riviä, jolla on teksti KEYPAIR... (tämä on luodun avaimen private key).

Luodaan ryhmä, jolle sallitaan pääsy HTTP:n ja SSH:n yli mistä tahansa internetistä. Ensin tehdään pääsyoikeusryhmä, jolle määritellään pääsyoikeudet.
$ ec2-add-group public_access -d "Access from public Internet"

Avataan SSH- ja HTTP-portit.
$ ec2-authorize public_access -P tcp -p 22 -s 0.0.0.0/0
$ ec2-authorize public_access -P tcp -p 80 -s 0.0.0.0/0

Tuloksena syntyneen ryhmän (public_access) voi tarkastaa AWS-konsolista: https://console.aws.amazon.com/ec2/home?region=eu-west-1&#s=SecurityGroups. Huomaa, että ryhmä ei ole mitenkään sidonnainen EC2-instanssiin, mutta se on sidonnainen AWS:n regioniin.

EC2-instanssin luominen
Tavoitteena on luoda EBS image -pohjainen (Elastic Block Store) instanssi (toinen vaihtoehto on S3:lle talletettu image). Koska aiemmin päätettiin tehdä Ubuntu-pohjainen EC2-instanssi, käytetään asennuksessa Ubuntun tarjoamia AMI-tiedostoja (Amazon Machine Image). Ubuntun viimeisin LTS-versio (long term support) on kirjoitushetkellä 10.04, joten otetaan 64-bittinen 10.04 AMI EC2:n pohjaksi. Lista AMI-tiedostoista löytyy täältä: http://uec-images.ubuntu.com/releases/lucid/release/. Listan sopivin löytyy regionista eu-west-1, 64-bittisenä ja EBS-pohjaisena (id: ami-cc0e3cb8).

Alla olevalla komennolla luodaan micro-instanssi, joka käyttää aiemmin luotua avainta sekä pääsyoikeusryhmää.
$ ec2-run-instances ami-cc0e3cb8 --instance-count 1 --instance-type t1.micro --key testkeypair --group public_access

Instanssin käynnistäminen kestää hetken. Instanssin pitäisi ilmestyä AWS:n konsoliin hetken päästä: https://console.aws.amazon.com/ec2/home?region=eu-west-1&#s=Instances. Ajossa olevat instanssit ja niiden tilan näkee myös komentoriviltä.
$ ec2-describe-instances

Pelkän tilatiedon voi listata seuraavasti.
$ ec2-describe-instance-status

Kun instanssi on käynnissä, voi sinne kirjautua sisään testkeypair-avaimella (SSH vaatii, että avaintiedostoon ei ole pääsyä kuin käyttäjällä itsellään. Aja siis chmod go-rwx avaintiedostonimi!).

$ ssh -i certs/testkeypair_private.key ubuntu@ec2-46-51-156-208.eu-west-1.compute.amazonaws.com

Huomaa, että instanssin DNS-nimi on joka luomisella erilainen. Yllä oleva komento ei siis toimi ilman pientä muuttamista.

Apachen virittäminen instanssille
$ sudo apt-get update
$ sudo apt-get install apache2
Koska asennus käynnistää automaattisesti Apache-prosessin, voi selaimella todeta, että Apache todellakin on ajossa: http://ec2-46-51-156-208.eu-west-1.compute.amazonaws.com/

Instanssien poistaminen
Hae ensin instanssin tunnus jo aiemmin kuvatulla komennolla.
$ ec2-describe-instances  --headers 
Type    ReservationID   Owner   Groups  Platform 
RESERVATION     r-3f686049      093338577702    public_access 
INSTANCE        i-62873b2b      ami-cc0e3cb8    ec2-46-51-156-208.eu-west-1.compute.amazonaws.com       ip-10-228-230-131.eu-west-1.compute.internal    running testkeypair     0               t1.micro        2011-12-04T00:10:46+0000        eu-west-1c      aki-4feec43b                    monitoring-disabled     46.51.156.208   10.228.230.131                  ebs                                     paravirtual     xen             sg-12ac4965     default 
BLOCKDEVICE     /dev/sda1       vol-ddf5fcb4    2011-12-04T00:11:06.000Z

Pysäytä luotu instanssi.
$ ec2-stop-instances i-62873b2b

Tuhoa instanssi.
$ ec2-terminate-instances i-62873b2b

Instanssin mukana häviää myös instanssiin kiinnitetty EBS-levy. Kun tähän asti on päästy, ei Amazon laskuta mitään edellä kokeillusta. Tuhottu instanssi näkyy listoissa vielä hetken aikaa, mutta häviää kokoaan alle tunnissa.