2014年9月29日 星期一

安裝 OpenStack @ Ubuntu 14.04 (4) - 安裝 Compute Service (Nova)

安裝 OpenStack @ Ubuntu 14.04 (4) - 安裝 Compute Service (Nova)

目錄

1、安裝環境說明

  • OS:Ubuntu 14.04 LTS

  • Controller

    • IP:10.0.0.11 / 24
    • Gateway:10.0.0.1
  • Network

    • Management IP:10.0.0.21 / 24 (eth0)
    • Gateway:10.0.0.1
    • Instance Tunnel IP:10.0.1.21 / 24 (eth1)
    • External Interface (eth2)
      • IP:不指定 IP
      • 設定方式如下:(修改 /etc/network/interfaces)

    auto eth2
    iface eth2 inet manual
    up ip link set dev $IFACE up
    down ip link set dev $IFACE down

  • Compute 1

    • Management IP:10.0.0.31 / 24
    • Gateway:10.0.0.1
    • Instance Tunnel IP:10.0.1.31
  • 修改每個 node 的 /etc/hosts 檔案,並加入以下內容:

    10.0.0.11 controller
    10.0.0.21 network
    10.0.0.31 compute1

    • 使用者身分:root

    2、Compute Service (NOVA) 概觀

    Compute Service 在整個 IaaS 的架構中是屬於最主要的部份,同時會向 Identity Service 進行認證授權、向 Image Service 要求 image、將資料提供給 Dashboard …. 等等。

    而整個 Compute Service (NOVA) 包含了以下幾個重要部分:

    2.1 API

    2.1.1 nova-api service

    用來處理 & 回應終端使用者的 Compute API call,除了支援 OpenStack API 之外,還支援了 Amazon EC2 以及管理用 API。

    2.1.2 nova-api-metadata service

    通常會用在多個 compute node 並安裝 nova-network 時使用,用來回應來自 instance 對 metadata 的要求。

    2.2. Compute core

    這元件包含了幾個重要的 daemon,來共同組成 Compute Core 以提供服務:

    2.2.1 nova-compute

    主要目的是與 hypervisor API 溝通,已建立 / 中止 VM instance。

    簡單來說,這個 daemon 僅接受來自 Message Queue 的訊息並執行相關命令而已,例如啟動一個 KVM instance、更新 instance 在資料庫中的狀態。

    2.2.2 nova-scheduler

    取得 VM instance 的需求後,根據制定的規則 & 目前情況,決定要讓 VM 在哪一台實體主機啟動。

    2.2.3 nova-conductor

    作為 nova-ompute 與 DB 之間的橋樑,目的是為了減少 nova-compute 直接存取 DB 的行為。

    2.3 Networking for VMs

    這個部分的功能已經被移進獨立的 Network Service (Neutron) 了,但還是可以簡單說明一下:

    2.3.1 nova-network

    同樣也是一支 daemon,接收來自 Message Queue 的網路相關需求並處理,例如:設定 bridge 介面 or iptables 規則 …. 等等。

    2.3.2 nova-dhcpbridge script

    用來追蹤在資料庫中 IP 租用 & 釋放的資訊。

    2.4 Console interface

    2.4.1 nova-novncproxy (daemon)

    作為透過 VNC 連線時存取 instance VM 的 proxy 之用,支援 browser-based novnc client。

    2.4.2 nova-xvpnvncproxy (daemon)

    作為透過 VNC 連線時存取 instance VM 的 proxy 之用,支援 Java client 的連線。

    2.4.2 nova-consoleauth (daemon)

    用來驗證由 console proxy (上面的 nova-novncproxy & nova-xvpnvncproxy) 所提供的使用者 token。

    2.5 Command-line clients and other interfaces

    2.5.1 nova client

    允許使用者以 tenant admin or 一般使用者的身分執行命令。

    2.5.2 nova-manage client

    允許 OpenStack 管理者執行命令。

    2.6 Other components

    2.6.1 Message Queue

    任何實作 AMQP 的 message queue 服務,用來作為所有 daemon 通訊的中介,這邊我們所使用的 RabbitMQ。

    2.6.2 SQL Database

    儲存在 OpenStack 上運行的所有 VM instance 的狀態、網路設定、相關專案,任何 SQLAlchemy 支援的 DB 都可以使用,我們這邊所使用的是 MySQL。

    3、安裝 Compute Service

    Compute Service 其實是由好幾個 service 一同合作,讓使用者可以啟用 VM instance。

    安裝的時候可以將這些 service 安裝在不同的機器上,也可以都裝在相同的機器上;在這邊我們將大部分的 service 安裝在 controller node 上,而主要啟動 VM instance 的服務則安裝在 compute node 上。

    首先在 controller node 上安裝 Compute 相關必要套件:

    controller# apt-get -y install nova-api nova-cert nova-conductor nova-consoleauth nova-novncproxy nova-scheduler python-novaclient

    3.1 設定 Message Queue & VNC

    修改 nova 設定檔(/etc/nova/nova.conf),指定 Message Queue 服務 & VNC 相關設定,在 [DEFAULT] 區段中加入以下設定:

    [DEFAULT]
    
    rpc_backend = rabbit
    rabbit_host = controller
    rabbit_password = YOUR_RABBIT_PASS
    
    my_ip = 10.0.0.11
    vncserver_listen = 10.0.0.11
    vncserver_proxyclient_address = 10.0.0.11

    3.2 設定資料庫

    接著準備好 nova 相關 daemon 會用到的 DB & 權限設定:

    controller# mysql -u root -p
    Enter password:
    
    mysql> create database nova;
    mysql> grant all privileges on nova.* to 'nova'@'localhost' identified by 'YOUR_NOVA_DB_PASSWORD';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> grant all privileges on nova.* to 'nova'@'%' identified by 'YOUR_NOVA_DB_PASSWORD';
    Query OK, 0 rows affected (0.00 sec)

    新增 Tables @ Nova DB:

    controller# sh -c "nova-manage db sync" nova

    修改 nova 設定檔(/etc/nova/nova.conf),加入 DB 相關設定:

    [database]
    connection = mysql://nova:YOUR_NOVA_DBPASS@controller/nova

    移除原本存在的 SQLite 檔案:

    controller# rm /var/lib/nova/nova.sqlite

    3.3 設定 Identity Service 認證

    # 建立 nova 用的 user
    controlle# keystone user-create --name=nova --pass=YOUR_NOVA_PASSWORD --email=admin@example.com
    +----------+----------------------------------+
    | Property |              Value               |
    +----------+----------------------------------+
    |  email   |        admin@example.com         |
    | enabled  |               True               |
    |    id    | 5cdbbe2f486641e5966199af5d743441 |
    |   name   |               nova               |
    | username |               nova               |
    +----------+----------------------------------+
    
    # 將 user / service Tenant / admin Role 連結
    controller# keystone user-role-add --user=nova --tenant=service --role=admin

    3.4 向 Identity Service 註冊 Nova 為 Compute Service

    # 建立 service 資訊
    controller# keystone service-create --name=nova --type=compute --description="OpenStack Compute"
    +-------------+----------------------------------+
    |   Property  |              Value               |
    +-------------+----------------------------------+
    | description |        OpenStack Compute         |
    |   enabled   |               True               |
    |      id     | 87c4529e337e45df94a9c101d7097db4 |
    |     name    |               nova               |
    |     type    |             compute              |
    +-------------+----------------------------------+
    
    # 建立 API 服務端點資訊並與 service 連結
    controller# # keystone endpoint-create --service-id=$(keystone service-list | awk '/ compute / {print $2}') --publicurl=http://controller:8774/v2/%\(tenant_id\)s --internalurl=http://controller:8774/v2/%\(tenant_id\)s --adminurl=http://controller:8774/v2/%\(tenant_id\)s
    +-------------+-----------------------------------------------------+
    |   Property  |                        Value                        |
    +-------------+-----------------------------------------------------+
    |   adminurl  |       http://controller:8774/v2/%(tenant_id)s       |
    |      id     |           be0f81e5b41a453a920dd2360c713af6          |
    | internalurl |       http://controller:8774/v2/%(tenant_id)s       |
    |  publicurl  | --publicurl=http://controller:8774/v2/%(tenant_id)s |
    |    region   |                      regionOne                      |
    |  service_id |           87c4529e337e45df94a9c101d7097db4          |
    +-------------+-----------------------------------------------------+

    修改 nova 設定檔(/etc/nova/nova.conf),加入以下設定:

    [DEFAULT]
    auth_strategy = keystone
    
    [keystone_authtoken]
    auth_uri = http://controller:5000
    auth_host = controller
    auth_port = 35357
    auth_protocol = http
    admin_tenant_name = service
    admin_user = nova
    admin_password = YOUR_NOVA_PASS

    3.5 啟動 Compute 相關服務

    controller# service nova-api restart
    controller# service nova-cert restart
    controller# service nova-consoleauth restart
    controller# service nova-scheduler restart
    controller# service nova-conductor restart
    controller# service nova-novncproxy restart

    3.6 驗證安裝是否成功

    # 透過 shell script 匯入 OS_USERNAME / OS_PASSWORD / OS_TENANT_NAME / OS_AUTH_URL 等環境變數
    controller# source ~/OpenStack/admin-openrc.sh
    
    # 查詢目前 compute host 可用的 image list (向 Glance 查詢)
    controller# nova image-list
    +--------------------------------------+---------------------+--------+--------+
    | ID                                   | Name                | Status | Server |
    +--------------------------------------+---------------------+--------+--------+
    | 0985b2f3-058e-4ab9-84e3-65c51f849408 | cirros-0.3.3-x86_64 | ACTIVE |        |
    | 77c0d5f8-1bcc-4937-932c-72f4b0eccbc3 | cirros-0.3.3-x86_64 | ACTIVE |        |
    +--------------------------------------+---------------------+--------+--------+

    4、設定 Compute Node

    設定好 controller 上的 compute service 之後,接著要來設定實際執行 VM instance 的 compute node。

    Compute node 主要的工作是接收來自 controller 的命令,並運行 VM instance。

    4.1 安裝操作 Hypervisor 用套件

    OpenStack 可以兼容多種 hypervisor (KVM / Xen / VMware ESXi / MS Hyper-V … etc),這邊以 KVM 為例,安裝相關操作套件:

    compute1# apt-get -y install nova-compute-kvm

    4.2 修改設定檔 (/etc/nova/nova.conf)

    # 設定 Message Queue 相關資訊
    rpc_backend = rabbit
    rabbit_host = controller
    rabbit_password = YOUR_RABBIT_PASS
    
    # 設定 compute node IP & 相關的 vnc server 位置
    my_ip = 10.0.0.31
    vnc_enabled = True
    vncserver_listen = 0.0.0.0
    vncserver_proxyclient_address = 10.0.0.31
    novncproxy_base_url = http://controller:6080/vnc_auto.html
    
    # 指定以 keystone 進行認證工作
    auth_strategy = keystone
    
    # 指定 Glace 服務所在位置(這邊設定在 controller 上)
    glance_host = controller
    
    # 資料庫相關設定
    [database]
    connection = mysql://nova:YOUR_NOVA_DB_PASSWORD@controller/nova
    
    # keystone 相關設定
    [keystone_authtoken]
    auth_uri = http://controller:5000
    auth_host = controller
    auth_port = 35357
    auth_protocol = http
    admin_tenant_name = service
    admin_user = nova
    admin_password = YOUR_KEYSTONE_PASSWORD

    4.3 檢查 compute node 是否具備硬體加速功能 for 虛擬化

    透過以下指令:

    compute1# egrep -c '(vmx|svm)' /proc/cpuinfo
    1

    若以上指令出現的數字為 0,表示目前 compute node 的 cpu 不支援虛擬化硬體加速,這時候就要編輯 /etc/nova/nova-compute.conf 檔案,將 virt_type 改成 qemu

    [libvirt]
    virt_type = qemu

    4.4 啟動 compute 服務

    # 移除不需要的 SQLite 檔案
    compute1# rm /var/lib/nova/nova.sqlite
    
    # 啟動 nova-compute 服務
    compute1# service nova-compute restart

    5、參考資料

    2014年9月25日 星期四

    安裝 OpenStack @ Ubuntu 14.04 (3) - 安裝 Image Service (Glance)

    安裝 OpenStack @ Ubuntu 14.04 (3) - 安裝 Image Service (Glance)

    目錄

    1、安裝環境說明

    • OS:Ubuntu 14.04 LTS

    • Controller

      • IP:10.0.0.11 / 24
      • Gateway:10.0.0.1
    • Network

      • Management IP:10.0.0.21 / 24 (eth0)
      • Gateway:10.0.0.1
      • Instance Tunnel IP:10.0.1.21 / 24 (eth1)
      • External Interface (eth2)
        • IP:不指定 IP
        • 設定方式如下:(修改 /etc/network/interfaces)

      auto eth2
      iface eth2 inet manual
      up ip link set dev $IFACE up
      down ip link set dev $IFACE down

  • Compute 1

    • Management IP:10.0.0.31 / 24
    • Gateway:10.0.0.1
    • Instance Tunnel IP:10.0.1.31
  • 修改每個 node 的 /etc/hosts 檔案,並加入以下內容:

    10.0.0.11 controller
    10.0.0.21 network
    10.0.0.31 compute1

    • 使用者身分:root

    2、Image Service 概觀

    在 OpenStack 中,Image Service 的用途在於讓使用者可以尋找/註冊/取得虛擬機器的映像檔來使用,而提供這樣的服務的專案稱為 Glance

    Glance 是用來管理虛擬磁碟的 image 之用,除了可以讓使用者新增 image 之外,也可以從正在運作的 server 上取得 snapshop 來作為 image 的備份或者是其他虛擬磁碟的 image。

    Glance 包含了以下四個主要部分:

    • glance-api

      • 接受來自其他服務的 API call
    • glance-registry

      • 管理 image 的 metadata 之用(例如:image 的大小 & 類型)。
    • Database

      • 儲存 image metadata 之用,可選擇 MySQL or SQLite。
    • 存放 image 的 storage repository

      • 存放 image 的位置有很多種不同的選擇,例如:一般的檔案系統、Object Storage、RADOS Block device、甚至是 Amazon S3 也可以。(但某些 repository 僅支援唯讀模式)

    OpenStack conceptual architecture

    以上是 OpenStack 的概念架構圖,從圖中可以看出 Glance 的定位:

    1. 可以將 image 存於 Swift 中
    2. 提供 image 給 Nova 作為執行 VM 之用
    3. 使用者可以透過 Horizon 呼叫 Glance API 來管理 image
    4. 在使用 Glance API 之前,都需要通過 Keystone 的認證

    3、安裝 Glance

    3.1 安裝套件

    這個範例會將 Glance 安裝在 controller 上,執行以下指令:

    $ apt-get install glance python-glanceclient

    3.2 設定資料庫

    原本預設 Glance 會將資料存於 SQLite 中,為了跟其他服務一致,以下把它改成使用 MySQL,首先先在 MySQL 中建立 glance 資料庫並給定權限:

    root@controller:~/OpenStack# mysql -u root -p
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 107
    Server version: 5.5.38-0ubuntu0.14.04.1 (Ubuntu)
    
    Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> create database glance;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> grant all privileges on glance.* to 'glance'@'localohost' identified by 'YOUR_GLANCE_DBPASS';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> grant all privileges on glance.* to 'glance'@'%' identified by 'YOUR_DB_PASSWORD';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> exit

    3.3 修改設定

    接著修改 Glance API & Registry 的設定,分別是以下的兩個檔案:

    • /etc/glance/glance-api.conf
    • /etc/glance/glance-registry.conf

    修改 [database] 區段,移除原本的 SQLite 設定,改為以下內容:

    [database]
    connection = mysql://glance:YOUR_GLANCE_DBPASS@controller/glance

    3.4 建立 Glance 用 MySQL DB

    建立 MySQL DB for Glance:

    $ sh -c "glance-manage db_sync" glance

    3.5 將 Glance 與 Identity Service(Keystone) 連結

    每個 service 都必須跟 Identity Service(Keystone) 進行連結,以下分成兩個步驟:

    3.5.1 建立認證用帳號(Glance 管理者)

    # 建立認證用帳號 & E-Mail
    keystone user-create --name=glance --pass=YOUR_GLANCE_AUTH_PASS \
       --email=admin@example.com
    +----------+----------------------------------+
    | Property |              Value               |
    +----------+----------------------------------+
    |  email   |        admin@example.com         |
    | enabled  |               True               |
    |    id    | ec4848f8a9d342038668029c78f77565 |
    |   name   |              glance              |
    | username |              glance              |
    +----------+----------------------------------+
    
    # 指定使用 service Tenant 並隸屬於 admin Role
    $ keystone user-role-add --user=glance --tenant=service --role=admin

    3.5.2 註冊 Image Service

    同樣修改 API(/etc/glance/glance-api.conf) & Registry(/etc/glance/glance-registry.conf) 兩個設定檔,修改 [keystone_authtoken] & [paste_deploy] 區段內容如下:

    [keystone_authtoken]
    auth_uri = http://controller:5000
    auth_host = controller
    auth_port = 35357
    auth_protocol = http
    admin_tenant_name = service
    admin_user = glance
    admin_password = YOUR_GLANCE_AUTH_PASS
    
    [paste_deploy]
    flavor = keystone

    最後下指令將 Glance 註冊至 Keystone 中並產生 API 服務端點,讓 OpenStack 其他的 service 可以知道 Image Service(Glance) 所在的位置:

    # 註冊 Glance 服務
    $ keystone service-create --name=glance --type=image --description="OpenStack Image Service"
    +-------------+----------------------------------+
    |   Property  |              Value               |
    +-------------+----------------------------------+
    | description |     OpenStack Image Service      |
    |   enabled   |               True               |
    |      id     | 95a34885c3dc486f98153cf2d3740355 |
    |     name    |              glance              |
    |     type    |              image               |
    +-------------+----------------------------------+
    
    # 註冊 Glance API 端點服務
    $ keystone endpoint-create --service-id=$(keystone service-list | awk '/ image / {print $2}') --publicurl=http://controller:9292 --internalurl=http://controller:9292 --adminurl=http://controller:9292
    +-------------+----------------------------------+
    |   Property  |              Value               |
    +-------------+----------------------------------+
    |   adminurl  |      http://controller:9292      |
    |      id     | 4ca758a4fe4049c491a5c5ace5b792f2 |
    | internalurl |      http://controller:9292      |
    |  publicurl  |      http://controller:9292      |
    |    region   |            regionOne             |
    |  service_id | 95a34885c3dc486f98153cf2d3740355 |
    +-------------+----------------------------------+

    3.6 啟動服務

    最後重新啟動 Glance service 讓之前的設定生效:

    $ service glance-registry restart
    $ service glance-api restart

    4、驗證 Glance 安裝是否成功

    我們可以透過下載隨意一個 linux image 並註冊到 Glance 來測試安裝是否成功。

    下載 Linux image:

    $ mkdir /tmp/images
    $ cd /tmp/images/
    $ wget http://cdn.download.cirros-cloud.net/0.3.3/cirros-0.3.3-x86_64-disk.img

    將下載的 Linux image 註冊到 Glance:

    # 透過 shell script 匯入 OS_USERNAME / OS_PASSWORD / OS_TENANT_NAME / OS_AUTH_URL 等環境變數
    $ source ~/OpenStack/admin-openrc.sh
    
    # 註冊 image 至 Glance
    $ glance image-create --name "cirros-0.3.3-x86_64" --disk-format qcow2 --container-format bare --is-public true --progress < cirros-0.3.3-x86_64-disk.img
    [=============================>] 100%
    +------------------+--------------------------------------+
    | Property         | Value                                |
    +------------------+--------------------------------------+
    | checksum         | 133eae9fb1c98f45894a4e60d8736619     |
    | container_format | bare                                 |
    | created_at       | 2014-09-24T23:29:42                  |
    | deleted          | False                                |
    | deleted_at       | None                                 |
    | disk_format      | qcow2                                |
    | id               | 77c0d5f8-1bcc-4937-932c-72f4b0eccbc3 |
    | is_public        | True                                 |
    | min_disk         | 0                                    |
    | min_ram          | 0                                    |
    | name             | cirros-0.3.3-x86_64                  |
    | owner            | 27466ca061e34b469f84da1e57b5605e     |
    | protected        | False                                |
    | size             | 13200896                             |
    | status           | active                               |
    | updated_at       | 2014-09-24T23:29:42                  |
    | virtual_size     | None                                 |
    +------------------+--------------------------------------+

    因為 Linux image 都可以直接在網路上取得,所以我們也不需要真的下載到本機空間,也可以直接透過 copy-from 參數來使用外部的連結來註冊:

    # 使用 copy-from 變數註冊來自外部的 image
    $ glance image-create --name "cirros-0.3.3-x86_64" --disk-format qcow2 --container-format bare --is-public true --copy-from http://download.cirros-cloud.net/0.3.3/cirros-0.3.3-x86_64-disk.img
    +------------------+--------------------------------------+
    | Property         | Value                                |
    +------------------+--------------------------------------+
    | checksum         | None                                 |
    | container_format | bare                                 |
    | created_at       | 2014-09-24T23:36:17                  |
    | deleted          | False                                |
    | deleted_at       | None                                 |
    | disk_format      | qcow2                                |
    | id               | 0985b2f3-058e-4ab9-84e3-65c51f849408 |
    | is_public        | True                                 |
    | min_disk         | 0                                    |
    | min_ram          | 0                                    |
    | name             | cirros-0.3.3-x86_64                  |
    | owner            | 27466ca061e34b469f84da1e57b5605e     |
    | protected        | False                                |
    | size             | 13200896                             |
    | status           | queued                               |
    | updated_at       | 2014-09-24T23:36:17                  |
    | virtual_size     | None                                 |
    +------------------+--------------------------------------+

    最後透過以下指令可以查詢目前 image 的註冊狀況:

    $ glance image-list
    +--------------------------------------+---------------------+-------------+------------------+----------+--------+
    | ID                                   | Name                | Disk Format | Container Format | Size     | Status |
    +--------------------------------------+---------------------+-------------+------------------+----------+--------+
    | 77c0d5f8-1bcc-4937-932c-72f4b0eccbc3 | cirros-0.3.3-x86_64 | qcow2       | bare             | 13200896 | active |
    | 0985b2f3-058e-4ab9-84e3-65c51f849408 | cirros-0.3.3-x86_64 | qcow2       | bare             | 13200896 | active |
    +--------------------------------------+---------------------+-------------+------------------+----------+--------+
    

    2014年9月19日 星期五

    安裝 OpenStack @ Ubuntu 14.04 (2) - 設定 Identity Service (Keystone)

    安裝 OpenStack @ Ubuntu 14.04 (2) - 設定 Identity Service (Keystone)

    目錄

    1、安裝環境說明

    • OS:Ubuntu 14.04 LTS

    • Controller

      • IP:10.0.0.11 / 24
      • Gateway:10.0.0.1
    • Network

      • Management IP:10.0.0.21 / 24 (eth0)
      • Gateway:10.0.0.1
      • Instance Tunnel IP:10.0.1.21 / 24 (eth1)
      • External Interface (eth2)
        • IP:不指定 IP
        • 設定方式如下:(修改 /etc/network/interfaces)

      auto eth2
      iface eth2 inet manual
      up ip link set dev $IFACE up
      down ip link set dev $IFACE down

  • Compute 1

    • Management IP:10.0.0.31 / 24
    • Gateway:10.0.0.1
    • Instance Tunnel IP:10.0.1.31
  • 修改每個 node 的 /etc/hosts 檔案,並加入以下內容:

    10.0.0.11 controller
    10.0.0.21 network
    10.0.0.31 compute1

    • 使用者身分:root

    2、Identity Service 概觀

    Identity Service 在整個 OpenStack 架構中提供了兩項功能:

    1. 認證 &授權
    2. 提供可用服務的 API 服務端點目錄資訊

    Identity Service 提供了 Role-based 的管理概念,並提供傳統的 UserName/Password & Token 的認證方式。

    以下的來自官網的圖,描述了 Identity Service(Keystone) 的完整作業流程:
    Keystone 作業流程

    2.1 重要名詞說明

    Identity Service 有些觀念要先清楚,列出比較容易搞混的:

    2.1.1 Tenant

    tenant 是 identity 服務的操作者用來將特定的 resource 或是 identity objects 區隔。

    每一個 tenant 可能會對應到一個客戶,或是一個帳號,也有可能是一個專案。

    2.1.2 Role

    role 包含了指定功能的使用權限,管理者可以根據不同的 role 給定不同的權限,再將 role 指定給 user,每個 user 可以同時被指定為多個 role 藉以授予系統存取權限。

    Keystone 中已經有一個預設的 Role,名稱為 _member_

    3、安裝 Identity Service

    接著要安裝認證用的服務:

    apt-get -y install keystone

    安裝完一卡車的套件後,這裡先為 keystone 準備儲存認證用的資料庫(MySQL),輸入以下指令:

    # mysql -u root -p
    Enter password: ##########
    
    mysql> create database keystone;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> grant all privileges on keystone.* to 'keystone'@'localhost' identified by 'YOURKEYSTONEDBPASSWORD';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> grant all privileges on keystone.* to 'keystone'@'%' identified by 'YOURKEYSTONEDBPASSWORD';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> exit

    接著修改 keystone 設定,將資料庫指向剛剛建立的 MySQL DB,編輯 /etc/keystone/keystone.conf

    修改 [database] 區段的 connection 設定如下:

    [database]
    connection = mysql://keystone:YOURKEYSTONEDBPASSWORD@controller/keystone

    並移除原本的 SQLite DB:

    rm /var/lib/keystone/keystone.db

    建立認證服務用的資料庫 table:

    su -s /bin/sh -c “keystone-manage db_sync” keystone

    產生 shared secret:

    openssl rand -hex 10

    編輯 keystone 設定(/etc/keystone/keystone.conf),加入以下兩個設定:

    [DEFAULT]
    admin_token = YOUR_SHARED_SECRET   #填入上一個步驟中使用 openssl 指令產生的 shared secret
    log_dir = /var/log/keystone

    重新啟動 keystone 服務:

    service keystone restart

    預設 keystone 的 token 是沒有過期的設定,因此透過以下指令將 token 的過期時間設定為 1 小時:

    (crontab -l -u keystone 2>&1 | grep -q token_flush) || echo ‘@hourly /usr/bin/keystone-manage token_flush >/var/log/keystone/keystone-tokenflush.log 2>&1’ >> /var/spool/cron/crontabs/keystone

    安裝好 Identity Service 之後,接著就要來設定認證相關資訊了。

    4、設定 user / role / tenant

    在建立 user / role / tenant 之前,必須先設定好 OS_SERVICE_TOKEN & OS_SERVICE_ENDPOINT 兩個環境變數,目的是為了以管理者的身分啟用並註冊 Identity Service:

    $ export OS_SERVICE_TOKEN=YOUR_ADMIN_TOKEN
    $ export OS_SERVICE_ENDPOINT=http://controller:35357/v2.0

    4.1 新增 User

    # 新增 user - admin
    $ keystone user-create --name=admin --pass=ADMIN_PASS --email=ADMIN_EMAIL
    
    # 新增 user - demo
    $ keystone user-create --name=demo --pass=DEMO_PASS --email=DEMO_EMAIL

    4.2 新增 Role

    # 新增 role - admin
    $ keystone role-create --name=admin

    Keystone 已經內建 _member_ 為預設 role,之後會將一般的帳號與 _member_ 進行連結。

    4.3 新增 tenant

    最後新增兩個 tenant 類型,分別是管理者(admin)以及一般使用者(demo):

    # 新增 tenant - admin
    $ keystone tenant-create --name=admin --description="Admin Tenant"
    
    # 新增 tenant - demo
    $ keystone tenant-create --name=demo --description="Demo Tenant"

    4.4 將 user / role / tenant 進行連結

    # 將 user(admin) 與 role(admin) & tenant(admin) 連結
    $ keystone user-role-add --user=admin --tenant=admin --role=admin
    
    # 將 user(admin) 與 role(_member_) & tenant(admin) 連結
    $ keystone user-role-add --user=admin --role=_member_ --tenant=admin
    
    # 將 user(demo) 與 role(_member_) & tenant(demo) 連結
    $ keystone user-role-add --user=demo --role=_member_ --tenant=demo

    4.5 設定 OpenStack services 之間用的認證資訊

    同樣的,OpenStack 中不同的 service 也需要 username / role / tenant 來進行認證並存取其他的 service,以下建立 service 用的 username / role / tenant:

    # 建立 service 用 user - service_user
    $ keystone user-create --name=service_user --pass=SERVICE_USER_PASS --email=SERVICE_USER_EMAIL
    
    # 建立 service 用 role
    $ keystone role-create --name=service_role
    
    # 建立 service 用 tenant
    $ keystone tenant-create --name=service --description="Service Tenant"
    
    # 將 user(service_user) 與 role(service_role) & tenant(service) 連結
    $ keystone user-role-add --user=service_user --role=service_role --tenant=service

    5、定義 services & API 服務端點

    之前提過 Identity Service 其中一個重要功能是「提供可用服務的 API 服務端點目錄資訊」,因此安裝好的服務都必須向 Identity Service 註冊,就連 Identity Service 自己也不例外。

    # 註冊 keystone service
    $ keystone service-create --name=keystone --type=identity --description="OpenStack Identity"
    
    # 設定 Identity Service 的 API 服務端點
    $ keystone endpoint-create --service-id=$(keystone service-list | awk '/ identity / {print $2}') --publicurl=http://controller:5000/v2.0 --internalurl=http://controller:5000/v2.0 --adminurl=http://controller:35357/v2.0

    6、驗證 Identity Service 是否安裝成功

    為了確保 Identity Service 安裝正確,首先清除 OS_SERVICE_TOKEN & OS_SERVICE_ENDPOINT 兩個環境變數。

    這兩個環境變數用途只是為了以管理者的身分設定 & 註冊 Identity Service 之用。

    $ unset OS_SERVICE_TOKEN OS_SERVICE_ENDPOINT

    6.1 進行 name-based 認證

    $ keystone --os-username=admin --os-password=YOUR_ADMIN_PASS --os-auth-url=http://controller:35357/v2.0 token-get

    這個指令會取得有效期間為一個小時(上面有設定)的 token,並搭配指定 user 的 id 資訊。

    【註】有 token 資訊表示 Identity Service 正確地被安裝 & 註冊

    6.2 進行 tenant-based 認證

    $ keystone --os-username=admin --os-password=YOUR_ADMIN_PASS --os-tenant-name=admin --os-auth-url=http://controller:35357/v2.0 \
      token-get

    這個指令會取得有效期間為一個小時(上面有設定)的 token,並搭配指定 user & tenant 的 id 資訊。

    【註】有 token 資訊表示 Identity Service 正確地被安裝 & 註冊

    6.3 簡化指令的方式

    看上面這麼一大串指令,看了頭都暈了,其實就是指定了好幾個參數,可以設定一個 bash 檔,指定所需要的環境變數,就可以將指令簡化,建立檔案 admin-openrc.sh,並填入以下內容:

    export OS_USERNAME=admin
    export OS_PASSWORD=YOUR_ADMIN_PASS
    export OS_TENANT_NAME=admin
    export OS_AUTH_URL=http://controller:35357/v2.0

    透過以下指令就可以取得全新的 token:

    $ source admin-openrc.sh
    $ keystone token-get

    最後檢視一下之前設定的 user / role / tenant 是否都有對應正確:

    # 檢視目前的 user 清單 
    $ keystone user-list
    +----------------------------------+--------------+---------+-------------------+
    |                id                |     name     | enabled |       email       |
    +----------------------------------+--------------+---------+-------------------+
    | eb54ed5c89e1411a9db5cadfd825ae42 |    admin     |   True  | admin@example.com |
    | bc1ae50e167f45edb064e582702c5792 |     demo     |   True  | admin@example.com |
    | 877f000de0064ad0a2ef33519af6cc87 | service_user |   True  | admin@example.com |
    +----------------------------------+--------------+---------+-------------------+
    
    # 檢視 role 與 user(admin) 的對應資訊
    $ keystone user-role-list --user admin --tenant admin
    +----------------------------------+----------+----------------------------------+----------------------------------+
    |                id                |   name   |             user_id              |            tenant_id             |
    +----------------------------------+----------+----------------------------------+----------------------------------+
    | 9fe2ff9ee4384b1894a90878d3e92bab | _member_ | afea5bde3be9413dbd60e479fddf9228 | e519b772cb43474582fa303da62559e5 |
    | 5d3b60b66f1f438b80eaae41a77b5951 |  admin   | afea5bde3be9413dbd60e479fddf9228 | e519b772cb43474582fa303da62559e5 |
    +----------------------------------+----------+----------------------------------+----------------------------------+

    7、參考資料

    2014年9月10日 星期三

    安裝 OpenStack @ Ubuntu 14.04 (1) - 基本環境設定

    安裝 OpenStack @ Ubuntu 14.04 (1) - 基本環境設定

    目錄

    1、前言

    這次 OpenStack 的安裝過程中,在網路的部分選擇使用 Neutron 來管理,不使用 nova-network,因此需要額外一個 Network Node 來處理網路的工作,如下圖所示:

    Three-node architecture with OpenStack Networking (Neutron)

    2、安裝環境說明

    • OS:Ubuntu 14.04 LTS

    • Controller

      • IP:10.0.0.11 / 24
      • Gateway:10.0.0.1
    • Network

      • Management IP:10.0.0.21 / 24 (eth0)
      • Gateway:10.0.0.1
      • Instance Tunnel IP:10.0.1.21 / 24 (eth1)
      • External Interface (eth2)
        • IP:不指定 IP
        • 設定方式如下:(修改 /etc/network/interfaces)

      auto eth2
      iface eth2 inet manual
      up ip link set dev $IFACE up
      down ip link set dev $IFACE down

  • Compute 1

    • Management IP:10.0.0.31 / 24
    • Gateway:10.0.0.1
    • Instance Tunnel IP:10.0.1.31
  • 修改每個 node 的 /etc/hosts 檔案,並加入以下內容:

    10.0.0.11 controller
    10.0.0.21 network
    10.0.0.31 compute1

    • 使用者身分:root

    3、套件安裝

    3.1 時間同步

    架設 IaaS 平台,機器間的時間同步是非常重要的,因此這邊要安裝 ntp client 的處理這個部分的需求。

    apt-get -y install ntp

    3.2 資料庫安裝 & 設定

    OpenStack 在很多部分的控制都仰賴資料庫來處理,因此資料庫的安裝 & 設定也是相當重要的一環,這邊使用 MySQL 作為資料庫,而僅有 controller 需要安裝 mysql server,其他 node 則是安裝 python mysql client 即可。

    3.2.1 Controller

    安裝 MySQL Server:

    apt-get -y install python-mysqldb mysql-server

    編輯 /etc/mysql/my.cnf,並將以下內容加到 [mysqld] 區段中:

    bind-address = 10.0.0.11    #原本的 bind-address 要移除
    default-storage-engine = innodb
    innodb_file_per_table
    collation-server = utf8_general_ci
    init-connect = 'SET NAMES utf8'
    character-set-server = utf8

    重新啟動 MySQL Server:

    service mysql restart

    3.2.2 其他 node

    安裝 python mysql client:

    apt-get -y install python-mysqldb

    3.3 OpenStack 套件

    加入 apt 套件庫資訊並更新套件:

    apt-get -y install python-software-properties
    add-apt-repository cloud-archive:icehouse
    apt-get update
    apt-get -y dist-upgrade

    若是 Ubuntu 的其他版本,apt repository 的資訊可以參考此處

    3.4 Messaging Server

    OpenStack 使用 message broker 來整合不同服務之間的運作 & 狀態資訊,一般都是在 contoller node 上執行。

    不同的 Linux 套件有其所支援的 message broker,而 Ubuntu 使用的是 RabbitMQ

    在 contoller node 上使用以下指令安裝 RabbitMQ:

    apt-get -y install rabbitmq-server

    安裝好 RabbitMQ 之後,會自動產生一個名為 guest 的使用者帳號,以下的範例所使用的就是這個帳號(正式環境建議另外建立帳號),因此來改一下密碼:

    rabbitmqctl change_password guest YOURMESSAGEBROKERPASSWORD

    之後有使用到 message broker 的 OpensStack 服務,就可以在設定檔中設定 RabbitMQ 的密碼,就可以使用到 message broker 的服務了!

    4、參考資料

    2014年8月17日 星期日

    Google Cloud Datastore with Go 學習筆記 - Queries

    Google Cloud Datastore with Go 學習筆記 - Queries

    類似關聯式資料庫,應用成是同樣也可以針對 entity 進行查詢 & 排序…等操作。

    • 原本的 where 過濾條件,在 Datastore 中變成了 filters 的方式,而 filter 可用在 property 的 value、keys、或是 ancestor 上。

    • 排序則是使用 sort orders 來進行。

    • 最後的回傳資料可以是完整的 entity 集合,也可以是包含部分屬性的 entity 集合,甚至可以只是 entity keys。

    而標準的查詢包含了以下資訊:

    • entity kind
    • 0 或多個 filter 條件
    • 0 或多個用來排序結果的 sort orders 條件

    為了確保執行的效能 & 節省記憶體,建議盡量每次查詢都限定回傳的資料筆數。

    Query structure

    每個 query 會包含有 entity kind、零或多個 filter、以及零或多個 sort order

    Filters

    filter 可以用在 property / key / ancestor 三種資訊上。

    Property Filter

    以下直接用範例來說明:

    type Person struct {
        Name      string
        City      string
        BirthYear int
        Height    int
    }
    
    func handler_BasicQuery(w http.ResponseWriter, r *http.Request) {
        c := appengine.NewContext(r)
        //查詢 Height 屬性大於 170 的資料
        //根據 Height 屬性進行 desc 排序
        q := datastore.NewQuery("Person").Filter("Height > ", 170).Order("-Height")
        var people []Person
        q.GetAll(c, &people)
        for p := range people {
            fmt.Fprintf(w, `Name=%q, City=%q, BirthYear=%d, Height=%d\n`, people[p].Name, people[p].City, people[p].BirthYear, people[p].Height)
        }
    }

    Key Filter

    若要使用 entity key 來進行 filter,必須使用特別的關鍵字 _key_

    以下舉個例:

    q := datastore.NewQuery("Person").Filter("__key__ >", lastSeenKey)

    key 值在 datastore 中是如何排序的呢? 是依照以下的順序來排:

    1. Ancestor path
    2. Entity kind
    3. Identifier (Numeric ID 排在自訂的 key name 之前)

    Ancestor Filter

    指定 ancestor 也是種 filter 的方式,以下舉個簡單的例子:

    q := datastore.NewQuery("Person").Ancestor(ancestorKey)

    ancestorKey 若是 nil 會產生錯誤,不會回傳 root entities 喔!

    Sort orders

    要進行排序需要指定 property & 排序方式(asc or desc),以下範例說明:

    //Name asc
    q := datastore.NewQuery("Person").Order("Name")
    
    //Height desc
    q := datastore.NewQuery("Person").Order("-Height")
    
    //多個條件排序
    q := datastore.NewQuery("Person").Order("Name").Order("-Height")

    Special query types

    Kindless queries

    若查詢中沒有指定 kind & ancestor,則表示是針對此應用程式在 Datastore 中所有的 entity 進行查詢。

    有些特別的資訊(例如:statistics entities & Blobstore metadata entities)就必須要透過這種方式搜尋。

    而不指定 kind & ancestor 的搜尋方式也是有限制的,就是不能使用 property 進行搜尋 or 將資料排序,只能使用 _key_ 關鍵字來針對 entity key 進行搜尋。

    Keys-only queries

    透過 KeysOnly() 方法取得 entity 的 key 值集合,舉個簡單範例:

    q := datastore.NewQuery("Person").KeysOnly()

    搜尋限制

    在 Datastore 上進行搜尋是有些限制的,說明如下:

    • 在搜尋中沒有包含指定 property 的 entity 都將被忽略
      同樣 kind 底下的 entity 的 property 內容是可以不同的,因此在 filter or sort 時若指定的 property 有可能不會存在於所有的 entity 中,這時沒有該 property 的 entity 都將被忽略。

    • “不等於”的 filter 最多只能用在一個 property 上

    //合法搜尋,兩個 filter 都用在相同的 property 上
    q := datastore.NewQuery("Person").
            Filter("BirthYear >=", minBirthYear).
            Filter("BirthYear <=", maxBirthYear)
    
    //不合法的搜尋,兩個 filter 分別用在不同的 property 上
    q := datastore.NewQuery("Person").
            Filter("BirthYear >=", minBirthYear).
            Filter("Height <=", maxHeight)
    
    //跟"="混用的話,沒有 property 數量限制(但不等於的 filter 還是只能用在同一個 property 上)
    q := datastore.NewQuery("Person").
            Filter("Name =", targetName).
            Filter("City =", targetCity).
            Filter("BirthYear >=", minBirthYear).
            Filter("BirthYear <=", maxBirthYear)
    • “不等於” filter 所指定的 property 必須先進行排序
    //合法搜尋,BirthYear 為第一個排序的 property
    q := datastore.NewQuery("Person").
            Filter("BirthYear >=", minBirthYear).
            Order("BirthYear").
            Order("Name")
    
    //不合法搜尋,BirthYear 必須放置於第一個 property 進行排序
    q := datastore.NewQuery("Person").
            Filter("BirthYear >=", minBirthYear).
            Order("Name")
    
    //不合法搜尋,Name 為第一個排序的 property (必須是 BirthYear)
    q := datastore.NewQuery("Person").
            Filter("BirthYear >=", minBirthYear).
            Order("Name").
            Order("BirthYear")
    • 含有多個 value 的 property 在 filter or sort 時可能會有出乎意料之外的結果
      這個部分等我真的遇到再來寫…..

    • 在 transaction 中的 query,必須包含 ancestor filter
      因為在 transaction 中的 query 必須屬於相同的 entity group,因此必須帶上 ancestor filter 資訊。

    取得查詢結果

    取得查詢結果有幾種方式,介紹如下:

    使用 Run method

    透過 Run method 可以得到一個 Iterator,並搭配 Next method 可以一個一個的取得搜尋結果,範例如下:

    q := datastore.NewQuery("Person")
    t := q.Run(c)
    for {
            var p Person
            k, err := t.Next(&p)
            if err == datastore.Done {
                    break // No further entities match the query.
            }
            if err != nil {
                    c.Errorf("fetching next Person: %v", err)
                    break
            }
            // Do something with Person p and Key k
    }

    使用 GetAll method

    這個方式可以將搜尋結果一次取回來,可參考之前的範例!

    使用 peojection query

    可用來取得 entity 中部分的 property 的資訊。

    使用 keys-only query

    透過 KeyOnly method 僅取得 entity key。

    使用 Limit & Offset (達到資料分頁目的)

    可透過 Limit & Offset 兩個 method 來取得特定範圍的 entity 資料,達到資料分頁效果,範例如下:

    //取得第 6~10 筆的資料
    q := datastore.NewQuery("Person").Order("-Height").Limit(5).Offset(5)

    比較需要注意的是, 雖然 Offset 可以忽略前幾筆資料,但其實資料還是有回傳的(這些都是要收費的),因此若是要 僅回傳 特定筆數資料,就必須使用 query cursor 來處理。

    Query cursors

    透過 query cursor 就可以取得特定範圍的資料而沒有 Offset 的問題。

    當執行了一個取得資料的動作後,應用程式可以取得一個 cursor(base64 編碼過的字串),用來表是上一次取得結果的索引位置,如此一來就可以用 cursor 來取得下一批的資料。

    除了可以透過 cursor 指定取得資料的起始點之外,還可以透過指定 end cursor 來限制回傳資料的範圍。

    使用限制

    cursor 在使用上有些限制存在:

    • cursor 僅有在相同的應用程式內,並使用相同的 query(相同的 kind & ancestor & property filter) 時才有效。

    • 若用在有多個值的 property 上時,cursor 的運作可能會不如預期。

    • 新的 App Engine 功能釋出時,可能會造成某些 cursor 不再有效,此時 Datastore 會回傳 error。

    2014年8月13日 星期三

    Google Cloud Datastore with Go 學習筆記 - Overview

    Google Cloud Datastore with Go 學習筆記 - Overview

    與傳統關聯式資料庫的差異

    與傳統資料庫比較,Google Cloud Datastore(以下簡稱 Datastore) 架構於分散式系統上,擁有高度的可延展性,在裡面存放的資料以 Entity 的形式存在。
    以下有幾項重要的不同:

    • Datastore 是以可延展為前提所設計,在繁忙工作時依然有高效能的表現

      • 寫入 Datastore 的資料會被自動分散到不同的機器上。
      • 讀取 Datastore 的資料時,假設查詢相同數量的資料(例如:50 個 Entity),不論是向擁有 100 個 Entityt 的 Dataset 查詢,或是向有 100 萬個 Entity 的 Dataset 查詢,都會是一樣的快速。
    • 因為所有的查詢都必須有預先定義好的 index 來處理,因此查詢語法的變化就無法像傳統關聯式資料庫一樣多變,以下類型的查詢就不支援:

      • Join
      • 多欄位的 not equal 篩選
      • 子查詢
    • 不同於關聯式資料庫,Table 中的每一筆資料的型態都要是相同的;在 Datastore 中,即使相同 kind 的 Entity 也不一定有要相同的屬性

    Entity

    存放於 Datastore 內的資料以物件(object)的形式存在,這些物件稱為 Entity

    Entity 內可以有一或多個屬性,這些屬性稱為 Property

    每個 Property 都會有其對應的 Value,這些 value 可以是各式不同的型態,包括整數、浮點數、字串
    、日期、二進位資料 …. 等。

    Datastore entity 是 schemaless 的,若是要確保每個 entity 都會有相同的 property set,就必須透過程式自行控制。

    Kind / Key / Identifier

    每個 entity 都屬於特定的 kind,目的是可以在之後進行有分類的查詢,例如:位於人事系統中的職員資料,可能就會屬於 Employee 這個 kind。

    每個 entity 都有專屬且唯一的 key,而 key 是由以下項目所組成:

    • entity 所屬的 kind
    • Identifier,可能是一個 key name 字串,或是整數 ID
    • 若是以階層式存在的 entity,還會包含 ancestor path 資訊

    因為 identifier 是屬於 entity key 的一部分,因此在 entity 建立時就會指派且無法變更,可以有兩種方式指派:

    1. 程式中直接指定 key name 字串給 entity
    2. 讓 Datastore 自動指定整數 ID 給 entity (有兩種產生整數 ID 的 policy,可參考文章1文章2)

    Ancestor path

    就像檔案系統一樣,entity 也可以以階層式的方式存放。(entity 中還包含了 child entity)

    沒有 parent 的 entity 稱為 root entity

    entity 之間的父子關係若是已經給定了就無法再更改,而 Datastore 不會指派相同的整數 ID 給同樣 parent 的 entity 或是兩個 root entity。

    由於 entity 有父子關係,因此要完整表示一個 child entity 的 key,就必須包含類似以下的 ancestor path 資訊:

    [Person:GreatGrandpa, Person:Grandpa, Person:Dad, Person:Me]

    若是 root entity,ancestor path 資訊就大概會像下面這樣:

    [Person:GreatGrandpa]

    Query & Index

    若想要對 Datastore 進行查詢,可以包含以下資訊:

    • 指定要查詢的 kind 資訊之外
    • 根據查詢需求指定 filter,而 filter 資訊可以是 entity 的 key / value / ancestor … 等資訊
    • 用來根據 property 來排序查詢結果用的 sort orders 資訊

    查詢結果可以是完整的 entity 資訊,或是僅有部分 property 的 entity,也可以只有 entity key。

    為了確保查詢效能,建議每個查詢都包含指定有限數量的 entity,避免一次回傳太多資料而影響查詢效能。

    若是要確保回傳的資料達到 strong consistent 的狀態,在規劃資料存放的架構時,就要指定好相關的 entity 都放置於相同的 entity group 中,否則 Datastore 只能確保回傳的資料是 eventually consistent

    App Engine 會預先在 entity 的每個 property 上定義 index,若要定義更複雜的 index 資訊,則可以修改 index.yaml 這個檔案。

    Transaction

    相同於傳統的關聯式資料庫,每一個交易可以包含多個 insert / update / delete 的操作,這些操作最多可以同時分布到 5 個不同的 entity group。

    Datastore 使用 [optimistic concurrency] 的機制來管理 transaction,當多個交易同時針對相同的 entity group 進行修改時,只有第一個 transaction 的 commit 會成功,其餘會失敗,而失敗的 transaction 可以針對第一個 transaction 已經修改好的資料重新嘗試變更操作。也因為這種機制,就限制了對於相同的 entity group 可以同時進行的 transaction 數量。

    同一個 transaction 中若是對多個 entity group 進行操作,就稱為 cross-group (XG) transaction,最多可以同時對 5 個 entity group 進行操作。

    在 cross-group transaction 終無法執行 non-ancestor query,因為此類型的查詢可能會包含部分之前被 commit 後的交易結果。

    而且在 cross-group transaction 中,即使只有讀取 entity group 的資料而未修改,但若有其他 transaction 同時存取相同的 entity group,也是會有衝突錯誤發生的。

    Quotas and limits

    使用 Google Cloud Datastore,有幾種不同的 quota 定義必須了解:

    • Datastore API Calls quota
      每次呼叫 Datastore API 的次數屬於此類 (有些 library 的一次呼叫會包含多次的 Datastore API Call)。

    • Data Send to Datastore API quota
      透過應用程式傳來的資料屬於此類。

    • Data Received from Datastore API quota
      應用程式接收到來自 Datastore 的資料屬於此類。

    • Stored Data quota
      存於 Datastore 的資料(包含 entity 的 property & key,甚至 index 都算)數量屬於此類。若要了解這些資料在 Datastore 中詳細的存放方式,可以參考 How Entities and Indexes Are Stored 這篇文章。

    參考資料

    1. Go Datastore API - Go — Google Developers

    2014年8月12日 星期二

    [VMware] 解決 consolidation 時發生 file locked 錯誤的狀況

    [VMware] 解決 consolidation 時發生 file locked 錯誤的狀況

    今天早上到公司發現 vSphere Web Client 中有提示某台 VM 有 warning,進到 Summary tab 看了一下,出現了訊息如下:

    Virtual machine Consolidation Needed status
    Virtual machine disks consolidation is needed.

    vSphere Web Client 中提示 VM 有狀況,檢視後顯示 "Virtual machine Consolidation Needed status. Virtual machine disks consolidation is needed"


    恩,一看就大概可以知道是 snapshot 時出了點狀況,所以 disk 需要執行 consolidation 的動作,於是很直覺的按照下圖執行:

    VM >> All vCenter Actions >> Snapshots >> Consolidate

    執行 snapshot consolidation @ VM

    結果出現了以下錯誤訊息:

    Consolidate virtual machine disk files
    [VM Name]
    Unable to access file since it is locked

    Consolidate Error


    後來發現原來是 VDP 搞的禍,詢問原廠人員後,他們提到有時候 VDP 在備份的時候會搭配 snapshop 的機制來進行,但有時候會發生秀逗…..

    處理的方式很簡單,因為 VDP 在處理 snapshot 時出了 trouble,因此在 VDP 的 VM 內就會殘留有問題的 snapshot 資訊,可透過以下方式尋找:

    VM >> Edit virtual machine settings >> 尋找有問題的 Hard disk(此處為帶有 warning VM name 的 vmdk 檔案) >> Remove

    (注意! 不要勾選 Delete files from datastore)

    從 VDP 中移除有問題的 VMDK

    當有問題的 vmdk 被移除後,最後再重新做一次 snapshot consolidate,就可以解決此 warning 囉!

    2014年8月8日 星期五

    讓 Sublime Text 3 支援 Auto Complete for Go & Google App Engine Library

    讓 Sublime Text 3 支援 Auto Complete for Go & Google App Engine Library

    首先在 Ubuntu 下安裝 Sublime Text,可以參考以下這篇:

    在 Ubuntu Linux 下安裝及使用 Sublime Text 2 / 3 - 玩物尚誌


    接著讓 Sublime Text 支援 Auto Complete for Go,可以參考以下這篇:

    基礎知識- 在Ubuntu 14.04 中配置Sublime Text 3 的Golang 開發環境- GoLove - 博客園


    最後讓 Sublime Text 支援 Google App Engine Library 的 Auto Complete,步驟如下:

    1、設定 GoSublime

    開啟 Preferences > Package Settings > GoSublime > Settings-User,輸入以下內容:

    {
        "use_legacy_imports": true, 
        "installsuffix": "appengine",
        "env": {
            "GOPATH": "$GOPATH",
    		"GOROOT": "$HOME/google-cloud-sdk/platform/google_appengine/goroot"
        }
    }

    其中 $HOME/google-cloud-sdk/platform/google_appengine/goroot 是 Google Cloud SDK 在我的電腦上安裝後的路徑,必須根據自己的環境去修改。

    此時重新開啟 Sublime Text,還無法自動抓取到 Google App Engine Library 的定義,因為在 $GOROOT 中的 /pkg 目錄中,library 位於 /[GOOS][GOARCH]_appengine 目錄中(我的例子是 ~/google-cloud-sdk/platform/google_appengine/goroot/pkg/linux_amd64_appengine),但預設抓取的是 /[GOOS][GOARCH] 路徑。
    因此下指令建立 symbolic link:

    cd ~/google-cloud-sdk/platform/google_appengine/goroot/pkg
    ln -s ~/google-cloud-sdk/platform/google_appengine/goroot/pkg/linux_amd64_appengine ./linux_amd64

    最後重新開啟 Sublime Text,就會發現 Auto Complete for Google App Engine Library 已經可以正常使用啦!!


    參考文章

    1. 在 Ubuntu Linux 下安裝及使用 Sublime Text 2 / 3 - 玩物尚誌
    2. 基礎知識- 在Ubuntu 14.04 中配置Sublime Text 3 的Golang 開發環境- GoLove - 博客園
    3. Code Completion and Google App Engine (Bug in GoSublime or GoCode?) · Issue #418 · DisposaBoy/GoSublime · GitHub

    2014年7月23日 星期三

    [Go] GoLang 資源整理

    目前正在學 Google Go,慢慢的有發現甚麼不錯的學習資源就擺進來...

    網站

    1. The Go Programming Language
      Go 的官方網站,首頁還有 playground 的環境可以直接寫些簡單的程式做練習用,原生 library 的文件都可以在這邊找到。

    開發工具


    Sublime Text

    1. 在 Ubuntu Linux 下安裝及使用 Sublime Text 2 / 3 - 玩物尚誌
    2. 基礎知識- 在Ubuntu 14.04 中配置Sublime Text 3 的Golang 開發環境- GoLove - 博客園
    3. 在 Sublime Text 2/3 設定 Inconsolata 字型 | akiratw Blog
    4. Code Completion and Google App Engine (Bug in GoSublime or GoCode?) · Issue #418 · DisposaBoy/GoSublime · GitHub


    電子書

    1. Go Web 編程 @ github
      這是對岸的朋友寫的,其實就是「21 世紀的 C 語言:史上最簡潔程式語言 Go Web 開發到底」的原始版本。(書寫的還不錯,有心學習的朋友就買書來支持一下囉!)

    2014年7月13日 星期日

    [Go] 在 Ubuntu 14.04 中設定 Go Syntax Highlight for Vim

    為了在 Ubuntu 用 vim 編輯 *.go 檔案時有 syntax highlight 的效果

    要額外安裝 vim-syntax-go 套件,並做些許設定

    詳細步驟如下:

    1、安裝 vim & vim-syntax-go

    2、找到 go.vim 檔案 (在我的電腦裡是在 /usr/share/vim/addons/syntax 目錄中),並放到 ~/.vim/syntax 目錄中

    3、編輯 ~/.vim/ftdetect/go.vim 檔案,並輸入以下內容
    au BufRead,BufNewFile *.go set filetype=go
    4、編輯 ~/.vimrc 檔案,輸入以下內容

    最後登出再登入就完工囉! 

    2014年5月28日 星期三

    [VMware] 透過 VLAN 的方式在 vSwitch 中設定多個網段

    這功能必須透過 VLAN 的方式來達成,設定步驟如下:

    1、在 vSwitch 中建立 Virtual Machine Port Group,除了設定一個好記的 Network Label 之外,最重要的是設定正確的 VLAN ID (假設此處設定 50)

    2、新增第二個 Virtual Machine Port Group,設定 VLAN ID 為 51

    3、在實體的 Switch 中,將 vSwitch 所對應到實體 switch 的實體 port 上,進行以下設定:
    • Link Type:Trunk
    • PVID:1
    • Tagged Membership:50, 51 
    如此一來,設定就完成囉,分散在不同 Port Group 的 VMs,各自所產生的網路流量都會附帶著 vlan tag 供辨識囉!

    這樣做可以達成兩個目的:
    1. vlan tag 可被實體 switch 與 vSwitch 辨識,廣播流量不會互相干擾。
    2. 可在同一個 vSwitch 中設定多個網段,提升網路管理上的彈性。

    [VMware] vSphere ESXi 5.5 設定 NIC Teaming (搭配 HP A5120 Switch)

    今天把 server 重灌成 5.5 U1 的版本,想說順便把 NIC Teaming 作一作.... 

    測試了半天終於試成功了,為了怕未來又忘了,筆記一下...

     大概分成兩個部分

    vSwitch 設定

    1、新增 vSwitch,並指定多張(2~8)網卡與此 vSwitch 相連。

    2、若有設定 VMKernal Adapter,設定管理用 IP Address,可不指定 VLAN ID,若需要 vMotion / FT / Virtual SAN ... 等功能,可順便開起來。

    3、進入 vSwitch 設定中的 Teaming and failover 的功能,將選項設定如下:

    • Load balancing:Route based on IP hash 
    • Network failure detection:Link status only
    • Notify switches:Yes
    • Failback:Yes
    4、除了上述設定外,還要將所有的 adapters 移動到 Active adapters 中 (放到 standby 就僅能做為 failover 用囉)。

    實體 Switch 設定

    1、在實體 switch 中,將對應的多個 port 設定為同一個 Link Aggregation Group (簡稱 LAG)。

    2、將 LAG 的 Interface Type 設定為 Static (LACP Disabled)。

    3、根據自家環境的設定,將 LAG 指定所需要的 PVID or 設定相對應的 Link Type(Access / Hybrid / Trunk),並 tag 所需要的 VLAN ID。

    以我公司的例子,必須作以下設定:(只給 VLAN 10 的流量走)
    • Link Type:Access
    • PVID:10
    • Untagged Membership:10

    如此一來,VMKernel 的流量就可以自動分散到多條線路上囉!

    參考資料

    2014年5月7日 星期三

    [AngularJS] AngularJS 與 Animation.css 結合

    Animation.css 是一個提供相當多動畫效果的 css library

    裡面提供了很多很酷的動畫效果

    然而透過一些簡單的方式,就可以很快的跟 AngularJS 整合並使用囉!

    詳細的資料可以參考以下連結:

    Easy Animations For AngularJS With Animate.css

    How to create cool animations with AngularJS 1.2 and Animate.css

    Get Moving With Angular 1.2 Animation and Animate.css

    2014年4月29日 星期二

    [Azure] 如何讓 Azure Website 支援 json 檔案的存取

    預設 Azure Website 是沒有支援 json MIME Type 的

    要開啟的方式很簡單,修改 Web.config 檔案即可

    若沒有 Web.Config 這個檔案,直接使用以下內容:

    儲存後,上傳至 /site/wwwroot 目錄下即可

    若是已經有 Web.Config 檔案,則直接加入 這個段落的設定並重新佈署即可

    [Azure] 透過 FTP 上傳靜態網頁至 Azure WebSite

    今天突然有個要將靜態網頁(static html)放到 Azure WebSite 的需求

    想想之前都是用 Visual Studio 佈署的,只是放個網頁應該不需要用到 Visual Studio 這種龐然大物吧......?

    後來發現原來可以透過 FTP 簡單把網頁上傳即可,找到以下資料可供參考!

    Windows Azure Website: Uploading/Downloading files over FTP and collecting Diagnostics logs - Avkash Chauhan's Blog - Site Home - MSDN Blogs

    運用 FTP 上傳檔案至 Windows Azure Web Sites - Tom Lee's blog - Site Home - MSDN Blogs

    透過 FTP 軟體連上後,再把網頁丟到 /site/wwwroot 目錄下就可以囉!

    2014年4月20日 星期日

    [VMware] 學習筆記 - vSphere Installation and Setup

    Introduction to vSphere Installation and Setup

    安裝 vSphere 包含以下部分:
    1. 確認硬體與軟體的需求皆符合
    2. 安裝 vCenter Server
      1. (optional) 安裝 vCenter Server database
        【註】小型環境(5 ESXi host 或 50 VMs 以內) 可使用內建的 MS SQL Server 2008 Express 即可
      2. 安裝完整 vCenter 順序為:
        vCenter Single Sign-On => vSphere Web Client => vCenter Inventory Service => vCenter Server
    3. 安裝 ESXi 
      1. 確認要安裝的位置(Local Disk or USB or .... etc)
      2. 安裝 ESXi 有三種選項:
        (1) 互動式安裝
        (2) 使用 Scritp 安裝 / 升級 / 轉移
        (3) 使用 vSphere Auto Deploy
    4. 安裝完成後,進行開機 & 網路設定
    5. 若本機硬碟儲存空間很有限,建議設定遠端的 syslog server,或是安裝 vSphere Syslog Collector 來收集所有 ESXi Host 上的 log

    System Requirements

    安裝 ESXi 5.5,硬體限制如下:

    • 僅支援 64 位元 x86 架構的 CPU
    • 至少要雙核心的主機
    • 僅支援 LAHF & SAHF CPU 指令集
    • BIOS 中必須啟用 CPU 中的 NX/XD bit
    • 主機至少必須要有 4GB 以上的記憶體,官方建議 8GB 以上
    • 若要支援 64 位元的 VM,x64 CPU 上的虛擬化的功能(Intel VT-x / AMD RVI)必須啟用
    • SATA 裝置會被視為遠端裝置,非本機裝置,因此無法作為 scratch partition 之用
    • ESXi 不支援在本機內的 SATA 硬碟上建立可跨多台 ESXi 主機共同分享的 VMFS datastore

    【註】在 ESXi 5.5 上無法將 SATA-CDROM 連接至 VM,必須改成 IDE emulation mode 才可用

    ESXi Booting Requirements

    vSphere 5.5 支援使用 UEFI 開機,透過 UEFI,可選擇使用硬碟、光碟、甚至於 USB 隨身碟開機。
    若要使用網路開機 or 使用 VMware Auto Deploy 開機,就必須選擇傳統的 BIOS 模式,不能選擇 UEFI。
    【註】安裝完 ESXi 5.5 之後,若更改開機模式(legacy BIOS <-> UEFI) 可能會造成無法正常開機










    zh-CN → zh-TW
    順序

    2014年4月17日 星期四

    [Azure] 解決部署到 Cloud Service Web Role 後,第一次進入網頁速度很慢的問題

    最近開發的一個 Azure 上的專案,發現若是 Cloud Service 上的 web role 重新佈署後,網頁第一次瀏覽都會非常的慢,等個 30 秒以上是常態~

    後來發現原來是 IIS IdleTime 的問題,可以透過 startup command 來解決~

    詳細的原因 & 解決方式可參考以下兩個網頁:

    1. Windows Azure WebSites and Cloud Services Slow on First Request | Simon J.K. Pedersen's SharePoint blog
    2. c# - Disable IIS Idle Timeouts in Azure Web Role - Stack Overflow

    2014年3月26日 星期三

    NexentaStor(ZFS) 與 Windows Storage Server 2012(ReFS + NTFS) 比較



    NexentaStor
    Windows Storage Server 2012 (ReFS + NTFS)
    File System
    ZFS
    ReFS(無法作為開機磁區) + NTFS
    發表年份
    2005
    2012
    Hybrid Storage Pool
    ZFS 原生支援
    支援
    Volume Max Size
    16EB
    256EB(理論) 16EB(實際)
    Hot Spares
    支援
    支援
    Read Cache
    支援,分為 ARC(DRAM) & L2ARC(SSD) 兩層處理
    支援 SSD Cache,但不支援 DRAM Cache(可透過 3-party 的元件解決)
    Write Cache
    支援 SSD
    支援 SSD
    授權方式/費用
    以下價格最多能使用 8TB 的容量:


    共有三種不同的 Support Level,分別為:
    Silver($51,750)
    Gold($83,700)
    Platinum($125,550)


    功能皆相同,磁碟數量、記憶體數量、CPU 數量都沒限制,但有總使用空間的限制(8TB / 16TB / 32TB …. etc)


    每年續約 or 一次買 2 / 4 / 6 年的授權合約(買越長平均價格越便宜)
    分為 Workgroup & Standard 版本:
    === Workgroup ===
    最多 50 個連線
    單一處理器插槽
    最多 32 GB 的記憶體
    最多 6 部磁碟 (不使用外接式 SAS)


    === Standard ===
    連線數量無授權限制
    多重處理器插槽
    記憶體無授權限制
    磁碟數量無授權限制
    解除複寫、虛擬化 (主機外加 2 部虛擬機器,提供存放區及磁碟管理工具) 以及網路服務(無網域控制站)容錯移轉叢集,提供更高可用性
    Microsoft BranchCache,降低 WAN 流量
    支援協定
    CIFS / SMB / NFS / iSCSI …. etc
    CIFS / SMB / NFS / iSCSI …. etc
    ReFS volume 無法使用 NFS,僅有 NTFS 能使用 NFS
    操作介面
    普通,透過 Web Browser
    優,直接在作業系統 GUI 中操作
    Deduplication(重複資料刪除)
    ZFS 原生支援
    支援,但有以下限制:
    1. Windows Server 2012才能用 (沒有Deduplication Feature的Windows會抓不到Deduplicate後的檔案)
    2. Boot 或 System 磁碟不能用
    3. 不是NTFS的磁碟不能用 (新的ReFS也不行)
    4. Cluster Shared Volumes(CSV)不能用
    5. 加密檔案不能用
    6. 暫時不能以群組原則設定
    Snapshot (快照)
    ZFS 原生支援
    支援,但必須與 VSS(Volume Shadow Copy Service) 搭配才可以
    Compress
    ZFS 原生支援
    不支援
    HA(High Availability)
    支援(JBOD + Multiple Servers)
    支援(JBOD + Multiple Servers)
    與 AD 整合
    支援
    支援
    整合雲端
    查無相關資訊
    可與 Windows Azure 雲端服務整合

    【備註】很多一樣的功能其實我並沒有列出來......只是個很簡單的比較...

    心得


    感覺 ReFS 根本就是跟著 ZFS 在走的,成熟度上還不足! (畢竟 ZFS 已經發展十年了....)

    微軟雖然在廣告文宣上把 storage server 2012 的功能寫得很強,但事實上很多限制都沒寫出來.....評估 storage 解決方案時還是要注意一下...

    不過看得出來微軟來勢洶洶啦~希望以後他可以更進步囉!

    參考資料