2015年9月23日 星期三

利用 FreeTDS 連接 MSSQL

利用 FreeTDS 連接 MSSQL

Linux 的好用方便迅速大家都知道,但是總有些時候對方會跟你說,什麼Linux啊,不是都滑鼠點幾下就好了嗎? 偏偏這時候你要的資料又在對方的機器上,想說不都很難。 只好研究起怎麼利用 Linux 底下的工具來查詢 MSSQL 的資料了。

[more]

要在 Linux 底下連接 MSSQL 需要安裝一些元件,分別是 freetds, unixodbc,我在 ubuntu 跟 CentOS 底下都有找到,應該是沒什麼問題。

安裝完兩個套件之後需要做一點設定讓 freetds 知道怎麼溝通還有去哪裡查資料。

/etc/freetds.conf

[ALIAS_MACHINE_NAME]
    host = MACHINE_NAME_OR_IP
    port = 1433
    tds version = 7.3
    #http://www.freetds.org/userguide/choosingtdsprotocol.htm

/etc/odbc.ini

[ALIAS_MACHINE_NAME]
Driver      = FreeTDS
Description = ODBC connection via FreeTDS
Trace       = No

/etc/odbcinst.ini

[FreeTDS]
Description = MS SQL database access with Free TDS
Driver64    = /usr/lib64/libtdsodbc.so
Setup64     = /usr/lib64/libtdsS.so
FileUsage   = 1

設定完之後就可以在命令列下指令查詢囉

tsql -S ALIAS_MACHINE_NAME -U USERNAME -P PASSWORD

下完之後看有沒有進去,命令列應該會變成像是這樣

1>

比較特別要注意的是,利用這個模式下查詢的話,最後一行要打 go 才會真的去跑,平常 IDE 用太久它會自動幫忙下,卡在這邊卡好久。

他也可以配合 python 來做一些處理,只要用 pip 裝 pymssql 就可以了,至於用法在這邊就不贅述,上面有設定好的話應該都沒有什麼問題才是。

2015年6月10日 星期三

AWS NAT script 實作

最近公司在 AWS 上面需要做 HA-NAT,參考了一下 gslin 大的這篇文章寫了一段 script 來做這件事情

概念上一樣是不做 cross-zone NAT,反正 AWS 宣稱他們頂多是一次掛一個 AZ (?)

script 放在這邊
https://github.com/adaam/AWS-NAT/blob/master/NAT.sh

 基本概念就是,一個 AZ 自己起一個 EC2 來管理自己 AZ 的對外需求,這樣差不多就有達到 HA-NAT 的要求,反正從外面看來你沒有把 AZ 全掛光看起來就還是正常在服務XD

要用這支script有幾個要求
  1. 要指定夠的權限 (IAM Role) 給 NAT 的機器,因為他要可以控制路由表還有改動子網路的路由對應關係。
  2. 要安裝好 jq ,因為需要解析很多 json 文件,這是我目前找到覺得最方便在命令列底下做事情的小程式,就不用在自己寫 python 之類的,簡單來說,就是懶XD
  3. 要先把 subnet 開好,指定好 Tag 的名字是 NeedNAT,值裡面就放 1,考慮到不是每個子網路都需要經過 NAT,就設計了這個 Tag 用來區別需要 NAT 跟不需要 NAT 的子網路
以上條件都滿足之後,應該就可以開開心心地執行這隻程式來架 NAT ,不過畢竟是第一次的概念,或許還有一些地方不完全,裡面也完全沒寫到錯誤處理,有任何問題還麻煩大家在這裡或是 github 那邊跟我說一下。

預計之後應該還是會找方法來實做 cross-zone 的 NAT,不過還需要一點時間來想要怎麼做溝通,heartbeat 感覺太肥,他的需求也不是我要的,我這邊只要簡單的偵測對方掛了沒,然後把路由表切到自己身上,等對方活過來再切回去這樣,不過還要考慮 3AZ 以上的情形,感覺有點棘手。

2015年6月8日 星期一

如何使用加密磁區當作 EC2 的根磁區

最近剛好在處理公司的機器上 AWS 的事情,當然其中一間就會是對資料的安全有疑慮,查呀查的發現 AWS 有佛心的提供了 KMS (Key Management Service) 這個服務,裡頭是宣稱你的資料很安全,他們不會偷偷幫你解密之類的,不過有沒有其他人會就不知道了 XD

總之,如果你拿來當資料區使用是完全不會有任何問題的,你可以很方便的再加入磁碟或是創建磁碟的時候勾選加密,在擺到你機器上去,他的效能也完全不會有任何影響,但是文件裡面(http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html)寫到了"
Encrypted boot volumes are not supported at this time."

什麼!!這是晴天霹靂啊,居然都提供了加密的功能,卻又不給根磁區加密,這這這.....不合邏輯啊。

幸好後來有發現,你如果真得想要從根磁區就加密,也不是沒有方法可以做,就是麻煩了一點。我把要做的步驟列在下面:

  1. 先準備好一檯可以用加密磁區的機器,要在 m3.medium 以上
  2. 起一個自己想要用的 AMI 
  3. 在選擇磁區的時候加掛一個加密的磁區
  4. 開心的啟動吧
  5. 假設根磁區掛在 /dev/sda ; 加密磁區掛在 /dev/sdb
  6. 這時候就開始把根磁區複製過去加密磁區,工具看你要用 dd 還是 partclone 都可以,dd比較慢,可是系統內建,partclone會幫忙壓縮還有略過沒資料的地方,應該會比較快。
  7. 結束之後關機,從 AWS 控制台把根磁區跟加密詞曲都卸掉
  8. 這步驟就是重點了,把加密磁區掛載回機器上,路徑記得寫 /dev/xvda
  9. 掛載上去之後就可以開機了,噹噹~~整個系統都加密了
看起來步驟真的是超級麻煩的,不過如果真的有需求要這樣做,我是在想有幾種做法可以因應會需要 auto-scale 之類的需求,如果不靠 AMI 的話,因為現在 AWS 還不支援利用加密的 AMI 起來當作根磁曲,看來要做就都要硬幹。
  1. 起一檯機器當作母機,復製磁區的部分就由它執行。
  2. 有起機器的需求的時候就送訊息給母機,母雞就掛一個加密磁區起來,把自己的資料複製一份
  3. 母機呼叫 API 去起一檯新的子機
  4. 子機起來之後馬上關機,把本來的磁區幹掉,換上母雞做好的加密磁區
  5. 把子機叫起來,噹噹~~,又是一尾活龍
看起來目前要硬幹的話應該只能這樣做了,不過做法真的爆炸麻煩的,還是期待 AWS 什麼時候可以自己偷改我們資料,不是,是自己宣布可以利用加密磁區來當根磁碟。

2015年1月9日 星期五

logstash 對於 RabbitMQ 足夠的知識

logstash 對於 RabbitMQ 足夠的知識

在這邊稍微翻譯一下這篇文章,方便大家使用 rabbitmq 來當作 logstash 的輸出或是輸入,文章網址在這裡,如果有哪邊語義不順或是翻譯錯誤請告訴我
Rabbiemq 的設定已經超出了使用logstash的範圍,但是在使用logstash的時候,它依然扮演了很重要的角色,所以特別寫了這篇文章來使大家能更好的了解AMQP 在RabbitMQ的官方網站也有一篇文章在講解,有興趣可以到這裡來看

交換,佇列與連結

你有很長的一段時間可以了解這短短幾個字的意思

交換器(Exchanges)

交換是給訊息製造者(以下簡稱製造者)使用的,在logstash中,我們把交換器使用到輸出模組,logstash會將訊息送到交換器,我們有許多不同的交換器種類會在下面的文章裡討論。

佇列(Queues)

佇列是給訊息接收者(以下簡稱接收者)使用的,在logstash,我們把佇列使用在輸入的模組,logstash會從佇列讀取訊息,或是讀取佇列裡面一部份的訊息,讀取部分訊息的功能是透過路由關鍵字來達成的。

連結(Bindings)

光有製造者跟接收者是沒用的,我們必須將佇列連結到交換器上面,當我們做這件事的時候,可以另外指定一個路由關鍵字,路由關鍵字會在下面討論。

經紀人 (Broker)

經紀人是個簡單的AMQP伺服器軟體,網路上有許多的AMQP伺服器軟體,我們在這邊會討論到的是RabbitMQ

路由關鍵字(Routing Keys)

簡單來說,路由關鍵字是用來把你的訊息打上標簽用的,在以往的經驗裡,我們可以很簡單地利用點(dot)來把訊息放入一個階層式架構當中,像是:
  • messages.servers.production
  • sports.atlanta.baseball
  • company.myorg.mydepartment
路由關鍵字是個好用的設定,它讓你可以利用程式,在特定的事件設定路由關鍵字,像是:
  • logs.servers.production.host1
  • logs.servers.development.host1.syslog
  • logs.servers.application_foo.critical
對於接收者或是佇列來說,路由關鍵字還有兩種萬用字元,#和*
  • *(星號)對應到任意一個字詞(word)
  • #(井號)對應到任意數量的字詞,行為跟傳統的萬用字元一樣
以下將使用一些例子,幫助你了解上面的內容。 如果你想連結到交換,並且只想看有關於production的內容,你應該把路由關鍵字設定成logs.servers.production.* 如果你想看主機host1所發出的任何版本的訊息,你應該將路由關鍵字設定成logs.servers.*.host1.#
使用星號當做萬用字元的結果可能使你困惑,但是當你知道你的訊息階層需要把星號放在哪邊時,他是個很好用的規則,記得它對應到是一個字詞就對了。另一個萬用字元是井號,當你需要比對任意數量的字詞時將會用到它。 要注意的一點是,萬用字元只會在接收者跟佇列連結的時候生效,在製造者跟交換器的時候它是沒有作用的。
下面我們將會更仔細的講解RabbitMQ的組件,到這裡為止,你所獲取的知識已經足夠你了解路由關鍵字的概念了。

交換

以下我們將講解三種交換的差異
直接交換(Direct)
普遍來說,最常使用的交換是直接交換。訊息進來伺服器之後,預期會被放進一個佇列。你可以把一個直接交換連結到許多佇列,你可以想像成有一群工人,正等待著從交換那裡拿到工作來做,但是一個訊息只有一個接收者會看到直接交換裡面的訊息。
你可以設定路由關鍵字給訊息之後,再將它送到直接交換裡面。這個動作讓你可以使用同一個佇列,將工作交給不同的工人,只有特定的工人知道怎麼閱讀特定的(使用路由關鍵字)訊息。
RabbitMQ的官方網站提供了很好的描述,並且以視覺化的方式呈現連結在此
擴散(Fanout)
擴散是另一種交換的形式,跟直接交換不同,每一個連結到擴散交換的都會看到相同的訊息,這個動作很像你去註冊一個郵件論壇,當你註冊上去,他就會把訊息丟給你。這個交換方法在你需要廣播訊息給很多有興趣的組件的時候非常有用。
擴散交換不支援路由關鍵字,所有連結到他的佇列都會看到所有的訊息。
主題(Topic)
主題交換是擴散交換的特別形態,擴散交換不支援路由關鍵字,但主題交換支援它。跟擴散交換有點像,所有連結到他的佇列可以看到所有的訊息,但是會經過路由關鍵字的過濾。

Logstash 裡面的 RabbitMQ

如同先前所說的,在Logstash裡面,我們將logstash的輸出模組對應到RabbitMQ的交換。而從佇列中讀取的輸入模組是連結到交換上。Logstash使用bunny函式庫來當作經紀人,logstash提供許多關於交換跟佇列的設定。它提供了許多你也許會有興趣的設定,像是訊息的持久性或是佇列或交換的持續性。你可以從RabbbitMQ的官方文件裡面查到完整的設定值清單。
設定範例以及小技巧
以下提供幾個範例,幫助你了解如何設定RabbitMQ
檢查你的連結
如果logstash發送了一個訊息,要接收這個訊息的logstash輸入模組必須跟發送的logstash輸出模組設定相同的交換名稱
發送端
input { stdin { type = "test" } }
output {
  rabbitmq {
    exchange => "test_exchange"
    host => "my_rabbitmq_server"
    exchange_type => "fanout"
  }
}
接收端
input {
  rabbitmq {
    queue => "test_queue"
    host => "my_rabbitmq_server"
    exchange => "test_exchange" # This matches the exchange declared above
  }
}
output { stdout { debug => true }}
訊息的持久性
Logstash預設會確保你不遺失訊息,這也反映了RabbitMQ的預設值。但是在某些情況下你或許不想要這樣,像是你的RabbitMQ並不是你的主要訊息來源的時候。
在以下的例子裡面,我們會使用RabbitMQ來當作監聽界面。訊息主要會送到ElasticSearch界面,訊息會複製一份,送到RabbitMQ來當作第二訊息界面。在這個例子裡面,我們關閉了RabbitMQ持續性及持久性的設定,所以訊息不會被堆積在RabbitMQ裡面等待傳送。我們僅僅將RabbitMQ當作一個即時的監控界面。 我們會額外加入路由關鍵藝,讓我們過濾進來的訊息,這個例子裡面我們將輸入模組留給你自己填寫你所想要的資料來源。
input { 
  # 輸入你自己的資料輸入設定
}

output {
  elasticsearch { embedded => true }
  rabbitmq {
    exchange => "logtail"
    host => "my_rabbitmq_server"
    exchange_type => "topic" # 我們使用主題交換以搭配下面的路由關鍵字
    key => "logs.%{host}"
    durable => false # 如果RabbitMQ重開,這個交換會被刪除
    auto_delete => true # 如果logstash跟,RabbitMQ的連線斷掉,這個交匯會被刪除
    persistent => false # 訊息不會被儲存到硬碟上
  }
}
現在你如果想要即時傳送記錄檔,你可以用你喜歡的程式語言,把佇列連結到名字叫做logtail的交換上。如果你沒有指定路由關鍵字,你會看到每個訊息都被logstash接收到。你可以指定路由關鍵字像是logs.apache1並且只觀看來自apache1這檯機器的訊息。
注意:任何logstash的變數都是合法的路由關鍵字,這個特性讓你能夠製作複雜的分層式路由關鍵字,用來做進階的過濾器設定。
注意:RabbitMQ對於持續性及持久性有特別的規範,不論是對佇列或是交換而言都是。你需要閱讀RabbitMQ的文件來確保你不會損壞你的RabbitMQ伺服器,造成訊息一直在伺服器裡面持續等待著被取出。

2015年1月2日 星期五

Logstash – 威力強大的日誌收集工具

身為系統管理員,一定對日誌有種深切的體會,那就是又愛又恨。
為什麼愛?因為他是當你在找出問題發生的原因的時候,所必需的東西。
為什麼恨?因為資料量多如牛毛,尤其是伺服器不止一檯的時候更是如此。

Logstash 的功能,主要是用來集中日誌,但是跟傳統的系統日誌差異點在於收集的方式。
傳統系統日誌收集方式必須要透過內部的 unix socket 或是 pipe 或是小程式,來提供管道寫入檔案之中,此外的話就是自己在日誌檔的資料夾下面,自己建立檔案去做讀寫。
這種方法在你有零星幾檯伺服器的時候可行,但是當你有數十檯到數百檯機器的時候,檢查日誌就會變成一種苦差事,即便 syslog 有提供集中管理的功能,但是依舊缺乏結構化,除了自己寫程式檢查之外,只能用工人智慧來監看日誌了。
而 Logstash 的出現一次解決了許多問題,包含日誌集中,結構化日誌,日誌分析,最重要的是社群為他寫了許多的附加程式,可以對接很多種資料來源以及輸出到各種地方,比 較普遍的就是將 Logstash 所收集到的資料,傳送到 ElasticSearch 做儲存以及視覺化的工作。
安裝 Logstash 十分簡單,你只要安裝好 JRE,接下來就是去 http://logstash.net/ 下載 Logstash 的程式檔案,解壓縮之後,進入資料夾裡面執行以下指令

bin/logstash -e 'input { stdin { } } output { stdout {} }'
之後當你隨意打一些字串,按下enter之後,可以看到他在重複一次你所打的字串,就可以確定你的 Logstash 執行成功了。
至於後面所帶的參數是什麼意思?詳細的之後再介紹,在這裡的意思,簡單來說就是將你從標準輸入進來的資料,經過 Logstash 處理之後,傳送到標準輸出來做顯示。
由於我們並沒有對內容做任何動作,所以就會原汁原味地看到你本來所輸入的字串。