Etikettarkiv: amazon ec2

Kör Docker med CoreOS och fleet

Mitt företag Triop AB erbjuder konsulttjänster inom DevOps. Se här: triop.se/devops

Fleet är en av de nyare verktygen som kommer från gänget bakom operativsystemet CoreOS. Fleet är till för att köra din kod på kluster av Dockers som rullar under CoreOS.

fleet ties together systemd and etcd into a distributed init system. Think of it as an extension of systemd that operates at the cluster level instead of the machine level.

Jag tänkte visa när jag startar upp två noder på Amazon EC2 som kör CoreOS och som sedan administreras med hjälp av kommandot fleetctl.

Python-koden för att starta upp nya servrar hittar du längst ner i detta blogginlägg. Det finns några inställningar som du bör göra innan, såsom att nyckelnamnet stämmer och security group har regler som tillåter port 7001, 4001 och 22. Samt EC2 access id och key.

Starta upp klusterchefen

Först och främst startar vi upp en leader. Detta kommuniceras ut via den unika token som återfinnes under discovery i user_data som du bör sätta till ett unikt värde för varje kluster.

$ python ec2-coreos.py
# Starting EC2 server with hostname coreos-roseanne
 - Wait..
 - Wait..
 - Wait..
Found IP: 46.137.21.3

Du kan även kontrollera att det fungerar att ansluta till den nya servern med IP-adress 46.137.21.3:

$ ssh -p 22 [email protected]
CoreOS (alpha)
[email protected] ~ $

Perfekt. Även kan det vara till fördel att se så att etc verkligen lyssnar på tcp port 4001 och 7001 antingen tittar vi via lsof eller testar att ansluta direkt med curl:

$ curl 46.137.21.3:4001
404 page not found
$ curl 46.137.21.3:7001
404 page not found

Och det fungerar bra. Skulle inte etcd starta upp så kan det bero på att din cloudconfig är felaktig (ej unik nyckel) eller så kan du titta på loggen med journalctl -u etc. Även så kan du starta upp etcd med kommandot:

sudo systemctl start etcd.service

Starta upp en arbetsnod

För att vi ska ha någon mer nod i klustret så startar vi upp en till. Precis som ovan så kör vi bara ec2-coreos.py och väntar några sekunder på att vår nya nod ska starta upp:

$ python ec2-coreos.py
# Starting EC2 server with hostname coreos-alia
 - Wait..
 - Wait..
 - Wait..
 - Wait..
Found IP: 54.220.243.180

Om allt gick som det ska så ska denna nya nod automatiskt ansluta till coreos-roseanne som är leader. Du kan även titta på loggen med journalctl -u etcd om något skulle vara fel eller använda den unika discovery URL:en direkt för att lista alla noder i ditt kluster:

curl https://discovery.etcd.io/db7ce1f96d42b24f38b5c96a3018f1ea|python -mjson.tool

CoreOS Fleet

Då var det dags att administrera vår flotta med noder med hjälp av fleetctl. Jag har på min Mac installerat fleetctl från github men det går även bra via homebrew:

$ brew update
$ brew install fleetctl

Om vi har rätt ssh-nycklar är det bara att köra. Du kan installera rätt ssh nyckel via kommandot ssh-add coreos.pem exempelvis.

Vi börjar med att lista alla maskiner:

$ fleetctl --tunnel=46.137.21.3 list-machines
MACHINE IP METADATA
9c62bc5f... 10.73.195.43 -
f9946c83... 10.35.3.231 -

Perfekt. Då är det dags att slänga ut vårat första jobb som ska utföras i klustret. Det är ett simpelt Hello World test som ska exekveras, så vi lägger följande innehåll i filen myapp.service:

[Unit]
Description=MyApp
After=docker.service
Requires=docker.service

[Service]
ExecStart=/usr/bin/docker run busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"

Och startar upp:

$ fleetctl --tunnel=46.137.21.3 start myapp.service
Job myapp.service launched on 9c62bc5f.../10.73.195.43

Perfekt. Nu ska jobbet ha startat och vi kan titta med fleetctl journal myapp.service eller list-nodes.

Så här ser det ut med info:

CoreOS Docker FleetOch nu ligger Hello World och kör under Docker på en av noderna vilket fleetctl list-units kan bevittna.

För delning av jobb och leader/follower genomförs av Raft Consensus algortimen.

 ec2-coreos.py

Här återfinnes koden som jag använder för att starta upp nya noder:

#!/usr/bin/env python
## 
## Jonas Lejon 2014
##
## sudo pip install apache-libcloud names

import os, sys, time
import names 
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
import libcloud.security
libcloud.security.CA_CERTS_PATH = ['ca-bundle.crt'] # from Mozilla

EC2_ACCESS_ID     = '' # Paste your Amazon EC2 credentials here
EC2_SECRET_KEY    = ''

userdata = """#cloud-config

coreos:
  etcd:
    # generate a new token for each unique cluster from https://discovery.etcd.io/new
    discovery: https://discovery.etcd.io/unique_token_here
    # multi-region and multi-cloud deployments need to use $public_ipv4
    addr: $public_ipv4:4001
    peer-addr: $public_ipv4:7001
  units:
    - name: etcd.service
      command: start
    - name: fleet.service
      command: start
"""

#EC2Driver = get_driver(Provider.EC2)
EC2Driver = get_driver(Provider.EC2_EU_WEST)
conn = EC2Driver(EC2_ACCESS_ID, EC2_SECRET_KEY)

hostname = "coreos-" + names.get_first_name(gender='female').lower()

print "# Starting EC2 server with hostname",hostname

MY_SIZE = 't1.micro'
#MY_IMAGE = "ami-8f30fff8" # CoreOS beta at eu-west-1
MY_IMAGE = "ami-87a769f0" # CoreOS alpha at eu-west-1

sizes = conn.list_sizes()
images = conn.list_images()

size = [s for s in sizes if s.id == MY_SIZE][0]
image = [i for i in images if i.id == MY_IMAGE][0]

node = conn.create_node(name=hostname, image=image, size=size, ex_keyname="coreos", ex_userdata=userdata, ex_securitygroup="coreos")
nodes = conn.list_nodes()
time.sleep(5)
while nodes[-1].state != 0:
	time.sleep(5)
	print " - Wait.."
	nodes = conn.list_nodes()
print "Found IP:",nodes[-1].public_ips[0]

PhantomJS löser mina problem

Ett problem som jag då och då stöter på är problemet med att ladda hem och analysera webbsidor från kommandoraden (CLI) via mina servrar på Amazon EC2 exempelvis. Det går förvisso att köra headless browsing med Xvfb och så men det blir aldrig riktigt bra utan mer ett fulhack.

För några dagar sedan så kom jag i kontakt med PhantomJS som är just precis det som jag söker, en webkit-läsare med JavaScript API och som lirar prefekt från mitt kommandoskal. Det är lätt och enkelt att göra skärmdumpar eller HAR-rapporter (http archive format).

För att exempelvis mäta laddningstiden för en webbsida inklusive samtliga objekt såsom css, javascript så behövs enbart följande kodsnutt:

var page = require('webpage').create(),
t, address;

if (phantom.args.length === 0) {
 console.log('Usage: loadspeed.js <some URL>');
 phantom.exit();
} else {
 t = Date.now();
 address = phantom.args[0];
 page.open(address, function (status) {
 if (status !== 'success') {
  console.log('FAIL to load the address');
 } else {
  t = Date.now() - t;
  console.log('Loading time ' + t + ' msec');
 }
 phantom.exit();
 });
}
Och sen körs sedan med:
$ phantomjs loadspeed.js http://www.google.com
Ladda hem PhantomJS från PhantomJS.org och kolla även in forken CasperJS.
Uppdatering: Ett problem som tyvärr PhantomJS är DNS-timings i HAR-output. Se här.

Dödar gamla buggar på bloggnätverket

I går så fixade jag en fem år gammal bugg som gjorde att cachningen på min sajt BloggVärde fungerade suboptimalt. Felet bestod i att jag använde en sekundräknare som uppdaterades i en SQL-fråga mot databasen.

Dock så cachar jag genom memcache och en md5-summa som beräknas på SQL-frågan, eftersom SQL-frågan blev ny varje sekund så cachades bara frågorna i en sekund. Det sänker förvisso belastningen till SQL-servern lite men när jag hade fixat buggen så gick sajten flera sekunder snabbare.

Jag har även flyttat över BloggNytt till molnet aka Amazon EC2 och håller på att flytta mer av mitt bloggnätverk från 2007.

Du glömmer väl inte att lägga till ping.bloggnytt.se i din lista över XML-RPC tjänster som du pingar från WordPress? Du lägger in http://ping.bloggnytt.se under Inställningar->Skrivinställningar och Uppdateringstjänster.

 

Så programmerar du för molnet

Bild CC http://www.flickr.com/photos/torley/2311784203/in/photostream/Kanske en klyschig rubrik men det finns många saker man bör tänka på när din avsikt är att placera din kodbas i molnet. Och när jag skriver molnet så menar jag exempelvis Amazon EC2 där du hyr en virtuell server. Dessa åsikter är helt subjektiva och kan variera beroende programmeringsspråk eller molntyp.

Grundfilosofin bör dock alltid vara att skriva portabel kod utan statisk information såsom sökvägar eller annat som kan komma att ändra sig om du ökar eller minskar din kapacitet eller flyttar koden. Det är dock inte alltid helt lätt att skriva flexibel och portabel kod då du alltid någonstans måste inneha ett beroende mot den nuvarande plattformen.

  1. Undvik statiska sökvägar eller URL:er
  2. Dokumentera beroenden såsom Redis, MySQL och eventuella PHP-moduler som används
  3. Undvik versionsspecifika funktioner
  4. Inte direkt specifikt för molntjänster men glöm för all del inte att ta backup (och använd GitHub).
Och glöm framför allt inte säkerheten, som ska vara minst lika viktig i molnet som på din egen server eller VPS. Tyvärr blev detta inlägg inte riktigt så långt och innehållsrikt som jag hade tänkt mig, detta pg.a. att programmering för molnet inte skiljer sig allt för mycket mot ”vanlig” programmering.

Så skickar du E-post med Amazon SES

Amazon SES (Simple Email Service) är en relativt ny tjänst från Amazon som ingår i deras sfär med molntjänster även kallat Amazon Web Services (AWS). Tjänsten är till för dig som inte orkar hålla på att konfigurera Sendmail/qmail och hålla koll på köer osv.

Det tar några timmar att komma igång och köra och i mitt fall så valde jag Amazon SES för att skicka ut E-post då någon gör lösenordsåterställning på BloggBackup och Blogbackupr. Kostnaden är $0.10 per 1000 E-brev vilket jag tycker är okej och det finns ingen bindningstid, uppsägningstid osv.

Så här går du till väga för att börja skicka E-post:

1. Skapa ett Amazon AWS-konto samt Amazon SES-behörighet (jag var tvungen att verifiera mig via telefonen då en automatisk röst läser upp en PIN-kod).

2. Ladda hem Amazon SES scripts där ses-verify-email-address.pl ingår. Du måste ange din AWSAccessKeyId samt AWSSecretKey i en fil som perl-scriptet använder sig av. Dessa uppgifter hittar du Account -> Security Credentials. Verifiera sedan din E-post så du kan börja att skicka från den (Amazon mailar en länk som du måste klicka på).

3. Konfiguera SPF och lägg till include:amazonses.com – Eftersom jag använder Google Apps sedan tidigare så har jag även include:_spf.google.com med i min SPF som ser ut så här:

”v=spf1 mx a include:getanewsletter.com include:_spf.google.com  include:amazonses.com ~all”

4. Ladda hem AWS PHP SDK med hjälp av pear:

# pear channel-discover pear.amazonwebservices.com

# pear install aws/sdk

5. Ladda hem Amazon SES PHP Mailer från GitHub: https://github.com/geoloqi/Amazon-SES-Mailer-PHP

6. Testa att skicka enligt ”Usage” som ser ut enligt följande:

<?php   require_once('AmazonSESMailer.php'); // Create a mailer class with your Amazon ID/Secret in the constructor  $mailer = new AmazonSESMailer('your id', 'your secret'); // Then use this object like you would use PHPMailer normally!  $mailer--->AddAddress('[email protected]');
$mailer->SetFrom('[email protected]');
$mailer->Subject = 'Sent from Amazon SES';
$mailer->MsgHtml('This is a test');
$mailer->Send();
?>

7. Begär fullständig access så du kan skicka E-post till vem som helst (utanför sandbox). En verifiering som tar max 24h.

Observera att Amazon SES har en standardgräns på 1000 st E-post om dagen. Du kan dock begära högre quota. Jag tror även att dessa 1000 dagliga E-postbrev om dagen är gratis om du skickar från en Amazon EC2 instans.

Bloggsök flyttad till molnet

Sakta men säkert så flyttar jag mina bloggprojekt till molnet och Amazon EC2 + RDS. Det rör sig först och främst om bloggsökmotorn Bloggz.se där jag även kommer att öppna upp för ett bloggsök-API med JSON + XML. Fritt för privatpersoner att använda och en mindre summa för kommersiella projekt.

Bloggz var mitt första projekt som skapades år 2007 och har sedan dess indexerat den svenska bloggosfären. Tjänster som använder sig av bloggdata är exempelvis BloggVärde, BloggNytt och BloggBilder.

Jag håller även på att komma ikapp antalet bloggar som är indexerade:

VPS/Dedikerad server pris vs. prestanda

Eftersom jag har innehar ett antal VPS:er och dedikerade servrar så tänkte jag att testa hur prestandan förhåller sig till priset på dessa. Som vanligt så har jag inte tagit support i beaktning, inte heller så har jag vägt in ram-minne eller överföringsmängd i detta test.

Till skillnad från DNS-testet så testar jag nu även de leverantörer jag anlitar från andra länder än Sverige: Amazon EC2, GleSYS samt Rackspace.

Resultatet blev enligt följande, desto lägre värde desto bättre vilket indikerar bäst prestanda för pengarna:

Du kan själv genomföra samma test genom att ladda hem http://acelnmp.googlecode.com/files/unixbench-4.1.0-wht.tar.gz och starta testet på följande sätt:

$ wget http://acelnmp.googlecode.com/files/unixbench-4.1.0-wht.tar.gz

$ tar xvfz unixbench-4.1.0-wht.tar.gz

$ cd unixbench-4.1.0-wht-2/

$ ./Run

Vänta sedan medan testet utförs vilket tar mellan 5 och 10 minuter, den sammanlagda summan av alla deltester står längst ner under rubriken FINAL SCORE.

Om du får ett felmeddelande om att time saknas så kan du installera det via: sudo apt-get install time under Ubuntu. Kan även vara bra att kontrollera så att du inte har något som går på servern som redan slukar resurser under tiden då du kör testet.

När du kört testet så kan du rapportera in prestandan i detta Google Docs-formulär så gör jag en sammanställning och publicerar sedan här på bloggen. Fortsätt läsa VPS/Dedikerad server pris vs. prestanda

Lägg inte alla ägg i samma korg

Jag har länge levt efter filosofin att inte lägga alla ägg i samma korg när det gäller serverdrift. Jag använder mig därför av VPS:er samt Co-Location från följande operatörer:

Och när det gäller domändrift såsom DNS och domänregistreringar så använder jag mig av:

Fördelen med detta är att om någon operatör går ner som idag (Hej Binero!) så går inte allt ner.

Att utveckla för molnet

Att utveckla webbtjänster för molnet gör att utvecklingen blir bättre. Jag upplever att jag tvingas att tänka på portabilitet och möjlighet till skalnCC http://commons.wikimedia.org/wiki/File:Bedeckt.gifing på ett annat sätt än när jag vanligtvis skapar webbtjänster.  Detta gör mig troligtvis också till en bättre programmerare.

Låt mig ta några exempel:

1. Istället för att använda Pythons inbyggda köhantering (Queue) så använder jag Redis och får då automatiskt skalning. Dock inte till vilket pris som helst eftersom Redis äter minne. Men med Amazon EC2 och 15GB minne så kommer jag rätt långt. Har testat Amazon SQS för köhantering men prestandan är direkt usel och är inte avsedd för miljoner operationer per sekund.

2. Sökvägar tvingas att sättas dynamiskt eftersom jag använder Amazon EBS där sökvägarna sätts på den extramonteringen som EBS tillhandahåller. Dock är det lite trist att vara låst till en ”zon” hos Amazon.

3. Att inte tänka på begränsningar på samma sätt. Det går alltid att kasta fler servrar, ramminne och hårddisk på problemet så löser det sig utan att behöva införskaffa fysisk hårddvara. Detta är något som jag ser som mycket intressant, att som liten ensam entreprenör kunna bygga stora system med hundratalet servrar. Dock ska ju allt underhållas också..

Finns säkert en drös med andra saker som jag inte kommer på just nu, men lämna gärna en kommentar på vad du ser för fördelar med att använda molntjänster vid utveckling.

Crawler 2.0

Som många vet så har jag två tjänster som visar information om domäner, nämligen DomainDB.com samt DomainTool.se. Jag var i behov av att uppdatera den informationen som fanns så det var dags att starta den crawler som jag skapat för några år sedan.

Crawlern (eller webcrawler, spider som det också heter) var tämligen ouppdaterad så jag tog tillfället i akt och använder nu enbart Redis. Tidigare så använde jag MySQL + Sphinx:

  • db0 – Kö för domäner som skall besökas
  • db1 – Koppling mellan namnserver och IP-nummer
  • db2 – Koppling mellan www.domän och IP-nummer
  • db3 – Sidtitlar

Db0 rensas och fylls på ungefär varannan dag med runt 25 miljoner nya domäner som besöks så efter cirka en vecka så har jag besökt 100 miljoner domäner. För server-kapacitet så använder jag Amazon EC2 och deras spot instances som är lite billigare och utnyttjar oanvända EC2-instanser.