2016年8月28日 星期日

[Mac] TOTO LINK N150UA @ MacOSX 10.11.6

MTK Wireless Utility

經過黃色鬼屋買了一張 USB 無線網卡,結果就是一場災難的開始 XD (買的比網路上貴外,設定又如此搞剛)回來用 MacOSX 來測試,然後附贈的安裝 CD 跟 TOTO LINK (Ralink) 官網下載都無法成功設定,且文件上都說只支援 10.6 ~ 10.10 ,看來文件所敘無誤。

接著,開始翻他的硬體資訊,發現有 MediaTek 字樣!追了一下原來是 MediaTek 產出啊,網路上也看了幾篇 MTK 跨入無線網卡的新聞介紹,原來我 lag 那麼久 :P

最後,就是跑去 MediaTek 網站下載驅動程式(內含 Wireless Utility):MT7612_7610U_D5.0.1.25_SDK1.0.2.18_UI5.0.0.27_20151209
總之,裝了 MTK 的那包後,終於可以成功設定網路了 Orz 最大的缺點是安裝軟體時,還得自行閉上眼默認沒有簽署認證的程式包。

透過這次我也才明瞭在 MacOSX 設置 USB 無線網卡時,基本上都是透過第三方軟體設置的,且在 MacOSX 自身的網路偏好設定只能觀看而無法設定

MacOSX Wireless Utility

2016年8月22日 星期一

[Mac] MacPorts: no destroot found @ Mac OSX 10.11.6

前陣子一直在測試相容性問題,不斷地用 sudo port -fp uninstall installed 清光軟體。但一直懶沒把所有相依性刪光,在安裝 py-pip27 時,就會蹦出以下錯誤訊息:

$ sudo port install py27-pip
--->  Computing dependencies for py27-pip
--->  Installing py27-pip @8.1.2_0
Error: org.macports.install for port py27-pip returned: no destroot found at: /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_python_py-pip/py27-pip/work/destroot
Please see the log file for port py27-pip for details:
    /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_python_py-pip/py27-pip/main.log
To report a bug, follow the instructions in the guide:
    http://guide.macports.org/#project.tickets
Error: Processing of port py27-pip failed


解法就是老老實實參考 MacPorts - 2.4. Uninstall 官方文件清資料,仔細做了以下動作:

$ sudo rm -rf /opt/local/ ~/.macports

下載並安裝最新版 MacPorts: https://distfiles.macports.org/MacPorts/MacPorts-2.3.4-10.11-ElCapitan.pkg

重新安裝需要的軟體:

$ sudo port selfupdate
$ sudo port install py27-pip

見山不是山的年代

Sunny

五味雜陳的心事,很容易被接連不斷的事件給淹沒了。偶爾跟同輩的閒聊,成了忙碌中僅存的偷閒。

年過三十之後,莫名地成為家中、社會中的接近第一線衝刺者,要不成家帶小孩、要不事業上也扛了重任,看著社會新聞上不斷起舞的議題,轉過頭跟同輩閒聊,一致的認同,又到了見山不是山的年代。

記得學生時代時,看見八卦是八卦,現在這個年紀,看見八卦開始會反芻成更深一層的心境,什麼帶風向、什麼鼓吹人心等,就像 22k 是個假議題,打房亦是如此,當然想用在工作上老闆的精神喊話也是可以的 XD 八卦看久了還是八卦,知道對人生也是零分,不知道也是零分,唯一留下的卻是激昂的情緒。

唯一不變的還是時間只有 24 小時啊,需要時時提醒自己,投資在哪,成就就在哪邊,把時間花在美好的事物上吧 :)

我想,過個幾年,會再進入見山又是山的年代吧!八卦又變回八卦,風向又將回歸風向,跟著沉淪也沒啥不好的?

2016年8月19日 星期五

AWS 筆記 - 透過 VPN/IPSEC 讓 AWS VPC 與 Microsoft Azure VirtualNetwork 互通

對 Azure 來說,預設建置的 VirtualNetwork 就是 10.0.0.0 開頭的網路環境,大多可以繼續延用下去。在這延續上一篇 AWS 筆記 - 建置自己的 VPC 且透過 VPN/IPSec 讓各個 Region 的 VPC 互通 ,先簡略調整 Azure VirtualNetwork 環境,接著建置 Azure VPC 與 AWS VPC 連線機制。

假設 AWS VPC 為 10.100.0.0/16 網域,而 Azure VirtualNetwork 為 10.50.0.0/16 網域。

設置 Azure VPC:

Azure Portal -> New
-> Resource -> Create -> name=StudyVPN, Location=WestUS
-> Networking -> VirtualNetwork
-> Name=US
-> Address Space=10.50.0.0/16
-> Subnet Name=default
-> Subnet address range=10.50.0.0/24
-> Location = WestUS
-> Virtual Machines -> Ubuntu Server 14.04
-> Name=VPN
-> Location = WestUS
-> DS1_V2 Standard

請先將 AWS EC2 Security Group 跟 Azure Network security group 都設置好、開放對方 VPN IP。此例為 AWS EU-West-1 機器跟 Azure WestUS 機器,設置完防火牆後,先 ping 一下彼此吧。

在 EU-West-1 的 VPN Server 機器,其 public ip = 52.209.16.24:

$ ping 13.88.186.107

在 Azure WestUS 的 VPN Server 機器,其 public ip = 13.88.186.107:

$ ping 52.209.16.24

先設置 Azure VPN server:

$ sudo apt-get update && sudo apt-get -y upgrade && sudo apt-get -y dist-upgrade && sudo apt-get autoremove && sudo apt-get autoclean

$ sudo apt-get install openswan
$ ls /etc/ipsec*
/etc/ipsec.conf  /etc/ipsec.secrets

/etc/ipsec.d:
aacerts  cacerts  certs  crls  examples  ocspcerts  policies  private
$ sudo ipsec setup version
Linux Openswan U2.6.38/K3.19.0-65-generic (netkey)
See `ipsec --copyright' for copyright information.
$ sudo vim /etc/ipsec.d/AWS-EU-WEST-1.conf
conn Connect-to-AWS-EU-WEST-1
 type=tunnel
 authby=secret

 leftid=13.88.186.107
 left=%defaultroute
 leftsubnet=10.50.0.0/16
 leftnexthop=%defaultroute

 right=52.209.16.24
 rightsubnet=10.100.0.0/16

 pfs=yes
 auto=start
$ sudo vim /etc/ipsec.d/AWS-EU-WEST-1.secrets
13.88.186.107 52.209.16.24 : PSK "IPSEC_PASSWORD"

$ sudo vim /etc/ipsec.conf
#protostack=auto
protostack=netkey

#...
include /etc/ipsec.d/AWS-EU-WEST-1.conf

$ sudo vim /etc/ipsec.secrets
include /etc/ipsec.d/AWS-EU-WEST-1.secrets

$ sudo ipsec setup restart
ipsec_setup: Stopping Openswan IPsec...
ipsec_setup: Starting Openswan IPsec U2.6.38/K3.19.0-65-generic...


更新 AWS VPN server:

$ sudo vim /etc/ipsec.d/AZURE-US-WEST.conf
conn Connect-to-AZURE-EU-WEST
 type=tunnel
 authby=secret

 leftid=52.209.16.24

 left=%defaultroute
 leftsubnet=10.100.0.0/16
 leftnexthop=%defaultroute

 right=13.88.186.107
 rightsubnet=10.50.0.0/16

 pfs=yes
 auto=start
$ sudo vim /etc/ipsec.d/AZURE-US-WEST.secrets
$ sudo ipsec setup restart
ipsec_setup: Stopping Openswan IPsec...
ipsec_setup: Starting Openswan IPsec U2.6.37/K4.4.11-23.53.amzn1.x86_64...
ipsec_setup: /usr/libexec/ipsec/addconn Non-fips mode set in /proc/sys/crypto/fips_enabled


當兩邊的設定好後,並且用 ipsec setup restart 後,另一方才可以用指令連上對方:

Azure VPN server:

$ sudo ipsec auto --up Connect-to-AWS-EU-WEST-1
117 "Connect-to-AWS-EU-WEST-1" #4: STATE_QUICK_I1: initiate
004 "Connect-to-AWS-EU-WEST-1" #4: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP=>0x29ba22d7 <0x68b944dd xfrm=AES_128-HMAC_SHA1 NATOA=none NATD=52.209.16.24:4500 DPD=none}


AWS VPN server:

$ sudo ipsec auto --up Connect-to-AZURE-EU-WEST
117 "Connect-to-AZURE-EU-WEST" #6: STATE_QUICK_I1: initiate
004 "Connect-to-AZURE-EU-WEST" #6: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP=>0x74246b5f <0x7156f72b xfrm=AES_128-HMAC_SHA1 NATOA=none NATD=13.88.186.107:4500 DPD=none}


並且兩邊就可以 ping 彼此的 private ip 囉!

接著還需設定 routing table 以及對 AWS VPN Server機器打開 Change Source/Dest. Check 、對 Azure VPN Server 機器的網卡打開 IP forwarding 後,兩邊機器就可以互相 ping  到啦:

對 AWS 而言,在 VPC Dashboard -> Route 中,將相關的子網域都添加一則 10.50.0.0/16 導向至 AWS VPN Server (別忘了,若第一次設置 EC2 上的 VPN Server,還要從 EC2 Dashboard 修改該機器,取消 Change Source/Dest. Check)

對 Azure 而言,Azure portal -> New -> Networking -> Route table ,建立後,再去設定

Resource -> Route table -> Settings
-> Routes -> Add -> Route name=ToAWS, Address prefix=10.100.0.0/16, Next hop type=Virtual appliance -> Next hop address=10.50.0.4 (Azure VPN Server Private IP)
-> Subnet -> Associate subnet -> 挑選 VirtualNetwork、挑選 Subnet

最後,記得 NAT 相關要設定好,像在 Azure 上的 VPN server 是從一台乾淨的 Ubuntu 14.04 裝後,還必須設定以下:

$ echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
$ echo "net.ipv4.conf.all.accept_redirects = 0" | sudo tee -a /etc/sysctl.conf
$ echo "net.ipv4.conf.all.send_redirects = 0" | sudo tee -a /etc/sysctl.conf
$ for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 | sudo tee $vpn/accept_redirects; echo 0 | sudo tee $vpn/send_redirects; done
$ sudo sysctl -p


其他備註:

$ sudo ipsec setup restart
ipsec_setup: Stopping Openswan IPsec...
ipsec_setup: Starting Openswan IPsec 2.6.38...
ipsec_setup: No KLIPS support found while requested, desperately falling back to netkey
ipsec_setup: NETKEY support found. Use protostack=netkey in /etc/ipsec.conf to avoid attempts to use KLIPS. Attempting to continue with NETKEY


解法 => protostack=netkey

$ sudo ipsec auto --up Connect-to-AWS-EU-WEST-1
022 "Connect-to-AWS-EU-WEST-1": We cannot identify ourselves with either end of this connection.


解法 => 先把一些錯誤訊息修掉,如 sudo ipsec setup restart 看到的問題,接著再看 conn 的設定,當設定錯誤也會看到這段訊息。

2016年8月17日 星期三

AWS 筆記 - 建置自己的 VPC 且透過 VPN/IPSec 讓各個 Region 的 VPC 互通

Amazon VPC 的全名為 Amazon Virtual Private Cloud,就是所謂的內網架構,在此網路架構內的機器可以互通有無。https://aws.amazon.com/tw/vpc/

假設使用情境:
  1. 建立一個 VPC 網段為 10.100.0.0/16
  2. 建立兩個 Subnet 網段 A 跟 B 分別為 10.100.1.0/24, 10.100.2.0/24 且為不同 Availability Zone
  3. 其中 A 網段不給予 Public IP ,而 B 網段會有 Public IP
  4. 其中 A 網段需建立 NAT 運作方式,可以連外,也可以被 B 網段連到
建置方式:

VPC dashboard
-> Your VPCs -> Create VPC
-> 給定 CIDR block,如 10.100.0.0/16
-> Subnets -> Create Subnet
-> 挑選剛剛建立 VPC 以及 Availability Zone (兩個 Subnet 挑不同區),以及給定 CIDR block
-> A 網段 10.100.1.0/24
-> B 網段 10.100.2.0/24 並打開 Auto-Assign Public IP 屬性
-> Internet Gateways -> Create Internet Gateway
-> 勾選後,點擊 Attach to VPC -> 挑剛剛的 10.100.0.0/16
-> Nat Gateways -> Create NAT Gateway
-> 在此只需建立 A 網段的 NAT Gateway,但要建立在 B 網段,才能讓 A 網段的機器連出去 -> 給予 EIP/Create New EIP
-> Route Tables -> Create Route Table
-> 建立 A 網段 10.100.1.0/24 專屬表 -> 並設置 0.0.0.0/0 給予剛剛建立的 NAT   -> 建立 B 網段 10.100.2.0/24 專屬表 -> 並設置 0.0.0.0/0 給予剛剛建立的 Internet Gateway
-> 回到 Subnets 分別挑選 A/B 網段並更新他們的 route table

如此一來,就有一個 VPC = 10.100.0.0/16 ,內有兩個 subnet = A網段 10.100.1.0/24, B網段 10.100.2.0/24,其中 A 網段聯外方式就是透過 NAT 出去(對外會看到NAT IP),而 B 網段則是用 public ip 透過 Internet Gateway 出去。機器們可以用 curl ipino.io 去驗證 IP ,以及使用 ping 來檢驗是不是可以連到彼此。以上就是自建 VPC 且擁有 public ip 跟 private ip 網段的部分。

接著進行不同 Region VPC 溝通方式,不同 Region VPC 要溝通的方式,就只是單純在各個 Region 架設 VPN/IPSEC Server 互連,除了彼此更新 Route Table 外,還需在 VPN 機上打開防火牆、取消封包檢查等,如此一來即可處理封包移動流程。

假設有 10.100.0.0/16 跟 10.200.0.0/16 兩個網段,一處在 EU-West-1 另一處在 SA-EAST-1 ,一樣透過上述先建立完 VPC-EU-West-1 跟 VPC-SA-EAST-1,並且分別建立 Subnet EU-WEST-1 10.100.1.0/24 跟 SA-EAST-1 10.200.1.0/24 且兩者都有 Public IP(在此不做 private subnet),接著分別在這兩各區域,各開一台機器安裝 IPSEC,在此直接挑 Community AMIs -> amzn-ami-vpc-nat -> amzn-ami-vpc-nat-hvm-2016.03.3.x86_64-ebs CentOS ,並且使用 ec2-user 帳號登入。建議先在兩台 VPN server 彼此 ping 一下對方(在 Security Group 可以偷懶開放對方 IP 所有網路流量),接著就設定 IPSEC 的部分:

兩台機器都安裝 openswan 軟體:

$ sudo yum install openswan
$ sudo ls /etc/ipsec*
/etc/ipsec.conf  /etc/ipsec.secrets

/etc/ipsec.d:
policies


在 EU-WEST-1 機器,其 public ip = 52.209.16.24:

$ sudo vim /etc/ipsec.d/SA-EAST-1.conf
conn Connect-to-SA-EAST-1
type=tunnel
authby=secret

leftid=52.209.16.24
left=%defaultroute
leftsubnet=10.100.0.0/16
leftnexthop=%defaultroute

right=52.67.138.147
rightsubnet=10.200.0.0/16

pfs=yes
auto=start
$ sudo vim /etc/ipsec.d/SA-EAST-1.secrets
52.209.16.24 52.67.138.147: PSK "IPSEC_PASSWORD"
$ sudo grep -c "^include /etc/ipsec.d/" /etc/ipsec.conf > /dev/null || (echo "include /etc/ipsec.d/*.conf" | sudo tee --append /etc/ipsec.conf)
$ sudo grep -c "^include /etc/ipsec.d/" /etc/ipsec.secrets > /dev/null || (echo "include /etc/ipsec.d/*.secrets" | sudo tee --append /etc/ipsec.secrets)
$ sudo ipsec setup restart
$ sudo ipsec auto --up Connect-to-SA-EAST-1
117 "Connect-to-SA-EAST-1" #3: STATE_QUICK_I1: initiate
004 "Connect-to-SA-EAST-1" #3: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP=>0xe7553eef <0xa8498182 xfrm=AES_128-HMAC_SHA1 NATOA=none NATD=52.67.138.147:4500 DPD=none}


在 SA-EAST-1 機器上,其 public ip = 52.67.138.147:

$ sudo vim /etc/ipsec.d/EU-WEST-1.conf
conn Connect-to-EU-WEST-1
type=tunnel
authby=secret

leftid =52.67.138.147
left=%defaultroute
leftsubnet=10.200.0.0/16
leftnexthop=%defaultroute

right=52.209.16.24
rightsubnet=10.100.0.0/16

pfs=yes
auto=start
$ sudo vim /etc/ipsec.d/EU-WEST-1.secrets
52.67.138.147 52.209.16.24 : PSK "IPSEC_PASSWORD"
$ sudo grep -c "^include /etc/ipsec.d/" /etc/ipsec.conf > /dev/null || (echo "include /etc/ipsec.d/*.conf" | sudo tee --append /etc/ipsec.conf)
$ sudo grep -c "^include /etc/ipsec.d/" /etc/ipsec.secrets > /dev/null || (echo "include /etc/ipsec.d/*.secrets" | sudo tee --append /etc/ipsec.secrets)
$ sudo ipsec setup restart
$ sudo ipsec auto --up Connect-to-EU-WEST-1
117 "Connect-to-EU-WEST-1" #5: STATE_QUICK_I1: initiate
004 "Connect-to-EU-WEST-1" #5: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP=>0x681a5ce6 <0xcb613471 xfrm=AES_128-HMAC_SHA1 NATOA=none NATD=52.209.16.24:4500 DPD=none}


接著,就可以在兩台機器上,分別 ping 對方的 private ip 來測試,如此一來就算打通一條連線,最後要做的就是設定 VPC 的 route table:

在 EU-WEST-1 VPC (10.100.0.0/16) 的所有 Subnet (例如10.100.1/16),多添加一條 routing rule = 10.200.0.0/16 而 Target 用 EU-WEST-1 上的 VPN Server (可以在 Target 上打 i 關鍵字,就可以看到 EC2 server);在 SA-EAST-1 VPC (10.200.0.0/16) 裡所有的 Subnet (例如 10.200.1.0/16) ,多添加一條 routing rule = 10.100.0.0/16 而 Target 用 SA-EAST-1 上的 VPN Server 。

最後,回到 EC2 Dashboard ,將各區域的 VPN Server 的設定更新一下:Actions -> Networking -> Change Source/Dest. Check -> Disable,如此一來,雙方 VPC 下的機器,就可以互相 ping 和連線了。

在此使用 IPSEC 的做法,是因為後續可以來做跨 ISP 的結合,如 Azure service 等。

2016年8月16日 星期二

[Linux] 查看 Process STDOUT @ Ubuntu 14.04

有一台 server 某個服務一直會掛掉,由於什麼資訊都沒有,就想到有沒有可以偷窺別人程式的 stdout 的方式,接著就出現了 strace - trace system calls and signals  啦 :P

用法:

$ sudo strace -p ProcessID -s OutputStringLength -e write

其中 OutputStringLength 預設是 32 bytes ,所以不知道對方會噴什麼,就填大一點的數字就好。

如此一來,就可以觀察 crash process 最後到底吐了什麼出來。唯一比較難搞的是有些服務掛了會重啟,要不斷追蹤其 pid 再執行上述的指令。

2016年8月15日 星期一

AWS 筆記 - 在 AWS Billing 使用 Tag 關注各個服務的開銷

AWSBillingGroupByTag

前陣子在追一些花費時,跟同事花了不少功夫在節費,同事頗厲害,一下就看到不少可省錢的地方,只是省了一輪後,還是希望能夠查看各項服務的開銷,最好每月追蹤,然而,在 AWS Billing 預設報告都是以 AWS Service 為單位,而非依照我們自己的服務為單位,例如一個服務用到數台 EC2 跟一台 RDS 時,希望把這費用可以記在一起,特別又有流量等問題等。

結果翻一下 AWS Billing ,果然已有這類功能,頗夠用!只需在 EC2/RDS 的機器上都多一個 tag 來辨識,例如 tag=Price 且同一個服務就用一樣的數值(例如服務網址),並且在 Load Balancer 和 Auto Scaling 都可以添加 tag 。

接著在 AWS Billing 的 Cost allocation tags 上,挑選剛剛新增完的 Price 標籤並 Save 起來,等幾天後,就可以用 AWS Billing - Cost Explorer 看到漂亮的圖了(用 Group by Tag => Price),並支援以天或月顯示,並且會有明確地數字表格顯示各個服務花了多少錢。

2016年8月8日 星期一

Command line 批次顯示圖片寬高 @ Mac OS X 10.11.6

使用 sips 指令即可:

$ sips
sips 10.4.4 - scriptable image processing system.
This tool is used to query or modify raster image files and ColorSync ICC profiles.
Its functionality can also be used through the "Image Events" AppleScript suite.
Try 'sips --help' or 'sips --helpProperties' for help using this tool


用法:

$ find . -name "*.jpg" -exec sips -g pixelHeights -g pixelWidth {} \;

2016年8月4日 星期四

Microsoft Azure 管理筆記 - 使用 Image (Resource Manage - template.json) 快速建構、搬遷 Data Center

這個概念是這樣,為了服務世界各地的朋友們,可能一開始在日本服務,過了一陣子想要在美西服務,這時在 AWS 上可以很便利地將 AMI 複製到其他 Region ,而對 Azure 咧?概念是一樣,但在 Azure Resource Manage 的思維下,做法多了很多步。

參考資料:
步驟如下(在此有做 storage account 的切換,若是要沿用同一個 storage account 可以不用做第三步):
  1. 建立新的 Resource:US,歸屬定 West US
  2. 建立 Virtual Network、Subnet
  3. 建立 Storage account,此乃資料儲存帳號
  4. 將原本所在的 Image (vhd) 複製到新的 Storage account
  5. 建立 Network Interface Controller
  6. 將原本的 template.json 修改,把storage account更新至新的區域
  7. 即可建置新機器
細部流程,大多以 Azure cli 運行:

建立位於 West US 的 Resource Group: US

$ azure group create US westus --subscription MySubscription
info:    Executing command group create
+ Getting resource group US                                                  
+ Creating resource group US                                                
info:    Created resource group US
data:    Id:                  /subscriptions/MySubscription/resourceGroups/US
data:    Name:                US
data:    Location:            westus
data:    Provisioning State:  Succeeded
data:    Tags: null
data:  
info:    group create command OK


建立 Virtual Network (也可多用 -a 10.1.0.0/16 來限制 address prefix)

$ azure network vnet create US USVirtualNetwork westus  --subscription MySubscription
info:    Executing command network vnet create
warn:    Using default address prefix: 10.0.0.0/8
+ Looking up the virtual network "USVirtualNetwork"                          
+ Creating virtual network "USVirtualNetwork"                                
data:    Id                              : /subscriptions/MySubscription/resourceGroups/US/providers/Microsoft.Network/virtualNetworks/USVirtualNetwork
data:    Name                            : USVirtualNetwork
data:    Type                            : Microsoft.Network/virtualNetworks
data:    Location                        : westus
data:    Provisioning state              : Succeeded
data:    Address prefixes:
data:      10.0.0.0/8
info:    network vnet create command OK


建立 Subnet

$ azure network vnet subnet create US USVirtualNetwork default -a 10.1.0.0/16 --subscription MySubscription
info:    Executing command network vnet subnet create
+ Looking up the virtual network "USVirtualNetwork"                          
+ Looking up the subnet "default"                                            
+ Creating subnet "default"                                                  
data:    Id                              : /subscriptions/MySubscription/resourceGroups/US/providers/Microsoft.Network/virtualNetworks/USVirtualNetwork/subnets/default
data:    Name                            : default
data:    Provisioning state              : Succeeded
data:    Address prefix                  : 10.1.0.0/16
info:    network vnet subnet create command OK


接著建議從 Azure Portal Web UI 建立 storage account ,大多採預設即可,需留意區域位置以及採用的 resource group,此例帳號名稱為 myusstorageaccount,而使用 azure 操作 storage 行為時,必須使用 storage access key,於是就 azure cli 先列出一下(也可以在 Azure Portal 找到)

$ azure storage account keys list myusstorageaccount --resource-group US --subscription MySubscription
info:    Executing command storage account keys list
+ Getting storage account keys                                              
data:    Name  Key             Permissions
data:    ----  --------------  -----------
data:    key1  111111111111==  Full    
data:    key2  222222222222==  Full    
info:    storage account keys list command OK


建立 system container(後續 AZURE_STORAGE_ACCOUNT 跟 AZURE_STORAGE_ACCESS_KEY 都會接在指令前面,方便 debug 用途)

$ AZURE_STORAGE_ACCOUNT=myusstorageaccount AZURE_STORAGE_ACCESS_KEY=111111111111== azure storage container create system
info:    Executing command storage container create
+ Creating storage container system                                          
+ Getting storage container information                                      
data:    {
data:        name: 'system',
data:        metadata: {},
data:        etag: '"################"',
data:        lastModified: 'Thu, 04 Aug 2016 12:01:14 GMT',
data:        lease: { status: 'unlocked', state: 'available' },
data:        requestId: '############################',
data:        publicAccessLevel: 'Off'
data:    }
info:    storage container create command OK


接著,要把 Image copy 過來,這邊有些小細節要留意的,第一存取權限,第二這是非同步複製的。對於存取權限部分,請先將來源的 storage account 裡的 system container 的存取權限更新為 Blob 模式(此模式是必須知道完整的 URL 才能下載),預設是 private 模式(需搭配AZURE_STORAGE_ACCOUNT/AZURE_STORAGE_ACCESS_KEY才能),還有另一個是 Container 模式(這也是公開的,比 Blob 模式多了 listing 功能)。由於 azure storage blob 指令操作,對於 source 是 private 權限一直沒有成功 orz 且範例都是 Blob 的,只好忍痛跟著用了 Orz

以下是 source 為 private 權限,但 copy 一直沒成功(狀態會顯示success),但找不到資料的:

$ AZURE_STORAGE_ACCOUNT=myusstorageaccount AZURE_STORAGE_ACCESS_KEY=111111111111== azure storage blob copy start https://sourceaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd system -a sourceaccount -k sourceaccount_KEY
info:    Executing command storage blob copy start
- Start copying blob https://sourceaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd
data:    Copy ID                               Status
data:    ------------------------------------  -------
data:    ####################################  success
info:    storage blob copy start command OK


而將 source 更新為 Blob 存取權限後,就可以看到 Status 會顯示 pending 且約2~3分鐘,連 Azure Portal Web UI / Azure cli 都會找到!

$ AZURE_STORAGE_ACCOUNT=myusstorageaccount AZURE_STORAGE_ACCESS_KEY=111111111111== azure storage blob copy start https://sourceaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd system
info:    Executing command storage blob copy start
- Start copying blob https://sourceaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd
data:    Copy ID                               Status
data:    ------------------------------------  -------
data:    ####################################  pending
info:    storage blob copy start command OK

$ AZURE_STORAGE_ACCOUNT=myusstorageaccount AZURE_STORAGE_ACCESS_KEY=111111111111== azure storage blob show
info:    Executing command storage blob show
Container name:  system
Blob name:  Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd
+ Getting storage blob information                                          
data:    Property       Value                                                                                            
data:    -------------  ----------------------------------------------------------------------------------------------------
data:    container      system                                                                                            
data:    name           Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd
data:    blobType       PageBlob                                                                                          
data:    contentLength  1234567890                                                                                      
data:    contentType    application/octet-stream                                                                          
data:    contentMD5     ############==                                                                          
info:    storage blob show command OK


當複製完畢後(其實我也看不懂 azure storage blob show 的回報,也沒寫複製進度...),剩下就是建構一台機器的流程,包含建立 public ip、網路卡(NIC)、使用 template.json 發布。

如果你沒有把 Image 搬過來,直接用原本 template.json 開機器,會看到以下訊息(若同一個 storage account 則沒有問題):

error:   Deployment provisioning state was not successful
error:   Source and destination storage accounts for disk my-vm-osDisk.12345-23456-34567-45678.vhd are different.


若資料還沒搬完,會看到:

error:   Deployment provisioning state was not successful
error:   The resource operation completed with terminal provisioning state 'Failed'.
error:   Disk image https://myusstorageaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd is in Pending state. Please retry when image is ready.


建立 IP:

$ azure network public-ip create US ip-my-server -l westus --subscription MySubscription

建立網卡:

$ azure network nic create US nic-my-server -k default -m USVirtualNetwork -l westus --subscription MySubscription

或給予 public ip:

$ azure network nic create US nic-my-server -k default -m USVirtualNetwork -l westus --subscription MySubscription -p ip-my-server

建立機器:

$ azure group deployment create US -f my-servier-template.json --subscription MySubscription -p '{"vmName":{"value":"my-server"},"networkInterfaceId":{"value":"/subscriptions/MySubscription/resourceGroups/US/providers/Microsoft.Network/networkInterfaces/nic-my-server"}}'

2016年8月2日 星期二

Microsoft Azure 管理筆記 - 使用 Azure CLI 自訂映像檔的維護方式

大部分的潮流都是走 PaaS 架構,然而,有些歷史的包袱只能走 IaaS 的架構 XD 而建立 Image 更是最基本的方式,甚至搭配 rsync 完成發布。而對於 Resource manage 機器來說,每次透過 capture 建立 Image 後,等於報廢回收,所以寫了個簡單的步驟記憶一下:
  1. 登入機器清除基本設定檔: $ sudo waagent -deprovision+user
  2. 透過 azure cli 執行 Shutdown:$ azure vm deallocate -g MyResource -n MyCurrentServer --subscription MySubscription
  3. 透過 azure cli 執行 Generalized:$ azure vm generalize MyResource MyCurrentServer --subscription MySubscription
  4. 透過 azure cli 執行 Capture:$ azure vm capture MyResource MyCurrentServer MyImageName -t MyImageName-Date.json --subscription MySubscription
做完後,原機器就可以下去領便當,可以把它 Delete 囉。

若預設產生的 MyImageName-Date.json 不夠用時,會自行添加資料,因此維護上就會出現麻煩,每次產生新的 template 中,其實只有 storageProfile 的設定,可以用 jq 跟 vimdiff 方便更新一下:

$ jq '' < MyImageName-old.json > old-formated.json
$ jq '' < MyImageName-Date.json > date-formated.json
$ vimdiff old-formated.json date-formated.json


把 old-formated.json 裡的 storageProfile 更新完成即可。

$ mv old-formated.json MyImageName-Date-formated.json

未來要建置原先那台機器時,就可以用以下指令在重建出來:

$ azure group deployment create MyResource -f MyImageName-Date-formated.json --subscription MySubscription

其他提醒:
  1. template.json 有描述 VHD 的資訊,若用上述 azure group deployment create 時,會彈跳出已存在的錯誤訊息,這時除了更新 template.json 資訊外,也可以到 Azure Portal -> Browse -> Storage account -> Blobs -> 沿路去找資料,把舊的、沒在用的砍掉再重跑
  2. 每次建立映像檔時,在 Azure Portal -> Browse -> Storage account -> Blobs -> system -> Microsoft.Compute -> Images -> vhds  會有 Image.vhd 跟 template.json 檔案,想清掉舊的可以去刪掉
  3. 製作完 Image 後的 server ,可以直接把它刪掉,但他的 NIC應當還會在,下次建立時,就可以沿用舊的網卡,通常 private ip 可以沿用,若有 public ip 的,若是 dynamic 配置則會變動
  4. 想使用同一個 template 開機器時,若多道指令一直跑時,指使用同一個 template file 時,會出現 Unable to edit or replace deployment 'filename-template.json' 
    : previous deployment from 'DATETIME' is still active. Please see https://aka.ms/arm-deploy for usage details. 偷懶的解法就是複製出來用 Orz 不知是不是 azure 採用 local file lock 等機制
  5. 若要採用 Availability Set 時,必須一開機就設定了,解法製作兩份 template.json ,一份用來維護 Image ,另一份就是開機就擺進 Availability Set,只需在 resources 中,多添加 : { "availabilitySet": { "id" : "/subscriptions/MySubscription/resourceGroups/MyResource/providers/Microsoft.Compute/availabilitySets/MyAvailabilitySet" } }, 來處理即可

Microsoft Azure 管理筆記 - 使用 Azure CLI 建立自訂的映像檔與開新機器的方式 (create a custom image/launch a server)

由於 Azure Portal 對 Resource manager 機器尚為提供 Web UI 可以方便點擊處理,就還是下海摸一下 command line 啦。

參考文件:

對 server 建立 image 過程中,server 狀態改變後會無法重啟,得用建立好的 Resource template 重新建立,需分外留意!機器就這樣下去領便當了 囧 (Azure/azure-powershell: UN-generalize a VM)

首先,遠端登入機器,執行此道指令

$ sudo waagent -deprovision+user

此命令會嘗試清除系統,使之適合重新佈建。這項作業會執行下列工作:

移除 SSH 主機金鑰 (如果組態檔中的 Provisioning.RegenerateSshHostKeyPair 是 'y')
清除 /etc/resolv.conf 中的名稱伺服器設定
移除 /etc/shadow 中的 root 使用者密碼 (如果組態檔中的 Provisioning.DeleteRootPassword 是 'y')
移除快取的 DHCP 用戶端租用
將主機名稱重設為 localhost.localdomain
刪除最後佈建的使用者帳戶 (取自於 /var/lib/waagent) 和相關聯的資料。


接著,再回到自己的常用的機器,改用 azure cli 對該機器設置以下流程:

$ azure config mode arm
info:    Executing command config mode
info:    New mode is arm
info:    config mode command OK


// Shutdown a virtual machine in a resource group and release the compute resources
$ azure vm deallocate -g MyResource -n MyCurrentVM --subscription MySubscription
info:    Executing command vm deallocate
+ Looking up the VM "MyCurrentVM"                            
+ Deallocating the virtual machine "MyCurrentVM"            
info:    vm deallocate command OK


// Set the state of a VM in a resource group to Generalized.
$ azure vm generalize MyResource MyCurrentVM --subscription MySubscription
info:    Executing command vm generalize
+ Looking up the VM "MyCurrentVM"                            
+ Generalizing the virtual machine "MyCurrentVM"            
info:    vm generalize command OK


$ azure vm capture MyResource MyCurrentVM MyImageID -t MyImageID-base.json --subscription MySubscription
info:    Executing command vm capture
+ Looking up the VM "MyCurrentVM"                            
+ Capturing the virtual machine "MyCurrentVM"                
info:    Saved template to file "MyImageID-base.json"
info:    vm capture command OK


接著,可以建立新開機器!只是開機器前又得好好管理"Resouce"建立,由於我已經有常用的 Resource 跟 Location 了,在此只需建立 IP 跟 NIC 即可!

$ azure network public-ip create MyResource MyImageID-ip-1 -l westus --subscription MySubscription
info:    Executing command network public-ip create
warn:    Using default --idle-timeout 4
warn:    Using default --allocation-method Dynamic
warn:    Using default --ip-version IPv4
+ Looking up the public ip "MyImageID-ip-1"                              
+ Creating public ip address "MyImageID-ip-1"                            
data:    Id                              : /subscriptions/MySubscription/resourceGroups/MyResource/providers/Microsoft.Network/publicIPAddresses/MyImageID-ip-1
data:    Name                            : MyImageID-ip-1
data:    Type                            : Microsoft.Network/publicIPAddresses
data:    Location                        : westus
data:    Provisioning state              : Succeeded
data:    Allocation method               : Dynamic
data:    IP version                      : IPv4
data:    Idle timeout in minutes         : 4
info:    network public-ip create command OK


$ azure network nic create MyResource MyImageID-nic-1 -k default -m MyResource -p MyImageID-ip-1 -l westus --subscription MySubscription
info:    Executing command network nic create
+ Looking up the network interface "MyImageID-nic-1"                    
+ Looking up the subnet "default"                                            
+ Looking up the public ip "MyImageID-ip-1"                              
+ Creating network interface "MyImageID-nic-1"                          
data:    Id                              : /subscriptions/MySubscription/resourceGroups/MyResource/providers/Microsoft.Network/networkInterfaces/MyImageID-nic-1
data:    Name                            : MyImageID-nic-1
data:    Type                            : Microsoft.Network/networkInterfaces
data:    Location                        : westus
data:    Provisioning state              : Succeeded
data:    Internal domain name suffix     : #############.dx.internal.cloudapp.net
data:    Enable IP forwarding            : false
data:    IP configurations:
data:      Name                          : default-ip-config
data:      Provisioning state            : Succeeded
data:      Private IP address            : 10.0.0.6
data:      Private IP version            : IPv4
data:      Private IP allocation method  : Dynamic
data:      Public IP address             : /subscriptions/MySubscription/resourceGroups/MyResource/providers/Microsoft.Network/publicIPAddresses/MyImageID-ip-1
data:      Subnet                        : /subscriptions/MySubscription/resourceGroups/MyResource/providers/Microsoft.Network/virtualNetworks/MyResource/subnets/default
data:  
info:    network nic create command OK


建立機器吧!

$ azure --version
0.10.2 (node: 4.2.4)


$ azure group deployment create MyResource -f MyImageID-base.json --subscription MySubscription
$ azure group deployment create MyResource -f MyImageID-base.json --subscription MySubscription -p '{"vmName":{"value":"MyVM"},"adminUserName":{"value":"ubuntu"},"adminPassword":{"value":"MyPassword"},"networkInterfaceId":{"value":"/subscriptions/MySubscription/resourceGroups/MyResource/providers/Microsoft.Network/networkInterfaces/MyImageID-nic-base"}}'


然而,因為預設產出的 template 定義了以下資訊,以至於開機器必須填寫以下資訊:

$ cat template.json | jq '.parameters'
{
  "vmName": {
    "type": "string"
  },
  "vmSize": {
    "type": "string",
    "defaultValue": "Standard_A1"
  },
  "adminUserName": {
    "type": "string"
  },
  "adminPassword": {
    "type": "securestring"
  },
  "networkInterfaceId": {
    "type": "string"
  }
}


用在這邊:

$ cat template.json | jq '.resources[0].properties.osProfile'
{
  "computerName": "[parameters('vmName')]",
  "adminUsername": "[parameters('adminUsername')]",
  "adminPassword": "[parameters('adminPassword')]"
}


接著,稍微修改來支援 ssh keypair 登入方式,將 template.json 中的 parameters 多增加個 adminPublicKey/adminPublicKeyPath:

$ cat template.json | jq '.parameters'
{
  "vmName": {
    "type": "string"
  },
  "vmSize": {
    "type": "string",
    "defaultValue": "Standard_A1"
  },
  "adminUserName": {
    "type": "string"
  },
  "adminPassword": {
    "type": "securestring",
    "defaultValue": null
  },
  "networkInterfaceId": {
    "type": "string"
  },
  "adminPublicKey": {
    "type": "array"
  },
  "adminPublicKeyPath": {
    "type": "string"
  }
}


並修改 properties.osProfile 區:

$ cat template.json | jq '.resources[0].properties.osProfile'
{
  "computerName": "[parameters('vmName')]",
  "adminUsername": "[parameters('adminUsername')]",
  "adminPassword": "[parameters('adminPassword')]",
  "linuxConfiguration": {
    "disablePasswordAuthentication": true,
    "ssh": {
      "publicKeys": [
         {
           "path": "[parameters('adminPublicKeyPath')]",
           "keyData": "[parameters('adminPublicKey')]"
         }
      ]
    }
  }
}


如此一來,就開機能用 keypair 登入機器:

$ azure group deployment create MyResource -f MyImageID-base.json --subscription MySubscription -p '{"adminPassword":{"value":""},"vmName":{"value":"MyVM"},"adminUserName":{"value":"ubuntu"},"adminPublicKey":{"value":"ssh-rsa ########"},"adminPublicKeyPath":{"value":"/home/ubuntu/.ssh/authorized_keys"},"networkInterfaceId":{"value":"/subscriptions/MySubscription/resourceGroups/MyResource/providers/Microsoft.Network/networkInterfaces/MyImageID-nic-base"}}'