ton-katsu blog
A10 Networks aFleX Scripting
A10 Networks aFleX Scripting aFleXとは

A10 Networksで採用されている、リクエストパケットを解析して決まったルールでトラフィックコントロールができるスクリプト言語。 (F5 NetworksでいうiRule)

今回の要件

IP定義ファイルを参照し、 グループ1ならtest Poolへ。 それ以外はhttp://www.example.com/へリダイレクトさせる。

グループ分けしたIP定義ファイルの作成

client_ip_listとして以下のようなIPリストを作成。 最後の数字がgroup_idとなる。 以下のように記述するとグループ1,グループ2,グループ3の定義ができる。

172.xxx.xxx.xxx/32 1
192.xxx.xxx.xxx/32 1
10.xxx.xxx.xxx/32 2
10.xxx.xxx.xxx/32 3
IP定義ファイルのインポート

以下のようにして作成したIP定義ファイルをインポートする。

AX(config)#import bw-list client_ip_list
scp://a10@192.168.1.100/home/a10/client_ip_list
Password []?
Importing ... Done.
aFleXの作成

以下のAflexを作成し、適用すると要件を実現できる。

when HTTP_REQUEST {
set client_addr [ IP::client_addr ]
set group_id [ POLICY::bwlist id $client_addr client_ip_list ]
if { $group_id equals 1 } {
    pool test
    } else {
    HTTP::redirect "http://www.example.com/"
    }
}
How to use Vagrant
How to use Vagrant What’s Vagrant?
  • vagrantとはVirtualBoxを使用してコマンドラインでVMを起動できるツール。

  • chefやpuppetとの連携で起動からセットアップ完了まで実施できる。

  • plug-inのvagrant-snapを使用するとコマンドでオンラインでsnapshotを取得したり戻したりできる。

  • 仮想マシンをboxといい、boxを提供しているサイトからdownloadして使用する。

  • 提供されているboxはhttp://vagrantbox.es/で確認できる。

  • boxはveeweeというツールで自身で作成できる。

Why Vagrant?
  • Vagrantfileでマシンタイプを定義でき、コマンド一発で希望のVMの作成が可能。

  • chef、puppetとの連携ができ、snapshotでマシンの状態を記録できるので、recipeやmanifestの練習ができる。

  • boxは自身で作成し、公開、共有できるので、誰もがどこでも同じ環境がすぐに用意できる。

Install vagrant and vagrant-snap

vagrantのインストール

$ sudo gem install vagrant

snapshotを取得するためのvagrant-snapに必要なパッケージのインストール

$ sudo gem install ffi

snapshotを取得するためのvagrant-snapのインストール

$ sudo gem install vagrant-snap
Quick Start

使用する仮想マシンをダウンロード

$ vagrant box add lucid64 http://files.vagrantup.com/lucid64.box

vagrant実行時に読み込むVagrantfileを生成

$ vagrant init lucid64

仮想マシンを起動する

$ vagrant up

仮想マシンのステータス確認

$ vagrant status
Current VM states:

default                  running

The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down forcefully, or you can run `vagrant suspend` to simply
suspend the virtual machine. In either case, to restart it again,
simply run `vagrant up`.

仮想マシンにsshでログイン

$ vagrant ssh
How to use vagrant-snap

仮想マシンのsnapshotを取得

$ vagrant snap take -d 1st-snapshot
[default]
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

仮想マシンのsnapshot確認

$ vagrant snap list
[default]
 0 [ 5 seconds ] 1st-snapshot

仮想マシンのsnapshotへ戻す

$ vagrant snap go 0
[default]
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Restoring snapshot 42717798-afd0-4bc5-97a9-9ae36961860c
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Waiting for VM "4a714c57-af48-4312-a6ad-3b99b458b7c5" to power on...
VM "4a714c57-af48-4312-a6ad-3b99b458b7c5" has been successfully started.
Vagrantfile detail

vagrantはコマンド実行時にVagrantfileというファイルを読み込み、 その内容にそってコマンドを実行する。 以下Vagrantfileの例。 Vagrantfileに他パラメータや詳しいことは記載されており、 vagrant initで初期ファイルは作成され、そこにも設定例が記載してある。

Vagrant::Config.run do |config|                                                                                                                                                     
  # 起動するVMの設定
  config.vm.box = "lucid64"
  config.vm.network :hostonly, "192.168.86.205"       # ホストのみ(NAT環境)を指定し、VMのIPを指定する
  config.vm.host_name = "sakabuntu"                   # VMのhostname
  config.vm.customize [ 
    "modifyvm", :id,                                  # VBoxManageコマンドを発行するVMのUUID指定
    "--memory", "1024",                               # メモリサイズ
    "--cpus", "2",                                    # 最大CPU数
    "--ioapic", "on",                                 # 割り込みコントローラを有効
  ]    

  # 適用するchefのレシピ(今回はchef-soloで)
    config.vm.provision :chef_solo do |chef|                                                                                                                                        
      chef.cookbooks_path = "chef-repo/cookbooks"            # 使用するcookbooksのパス
      chef.run_list = [                                      # run_listでリスト指定もできる
        "recipe[ntp]",
        "recipe[resolver]",
      ]
      chef.json = {                               
        :ntp => {
          :servers => [ "192.168.1.1", "192.168.1.2" ],
        },
        :reposerver => "192.168.1.1",
        :resolver => {
          :search => "example.com",
          :domain => "example.com",
          :nameservers => [ "192.168.1.1", "192.168.1.2" ]
        }
      }
  end
end
View vagrant up log
$ vagrant up
[default] Importing base box 'lucid64'...
[default] The guest additions on this VM do not match the install version of
VirtualBox! This may cause things such as forwarded ports, shared
folders, and more to not work properly. If any of those things fail on
this machine, please update the guest additions and repackage the
box.

Guest Additions Version: 4.1.0
VirtualBox Version: 4.1.8
[default] Matching MAC address for NAT networking...
[default] Clearing any previously set forwarded ports...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Running any VM customizations...
[default] Booting VM...
[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!
[default] Configuring and enabling network interfaces...
[default] Setting host name...
[default] Mounting shared folders...
[default] -- v-root: /vagrant
[default] -- v-csc-1: /tmp/vagrant-chef-1/chef-solo-1/cookbooks
[default] Running provisioner: Vagrant::Provisioners::ChefSolo...
[default] Generating chef JSON and uploading...
[default] Running chef-solo...
stdin: is not a tty
[Sat, 24 Mar 2012 17:37:52 -0700] INFO: *** Chef 0.10.2 ***
[Sat, 24 Mar 2012 17:37:52 -0700] INFO: Setting the run_list to ["recipe[ntp]", "recipe[resolver]"] from JSON
[Sat, 24 Mar 2012 17:37:52 -0700] INFO: Run List is [recipe[ntp], recipe[resolver]]
[Sat, 24 Mar 2012 17:37:52 -0700] INFO: Run List expands to [ntp, resolver]
[Sat, 24 Mar 2012 17:37:52 -0700] INFO: Starting Chef Run for sakabuntu
[Sat, 24 Mar 2012 17:37:52 -0700] WARN: found a directory nova in the cookbook path, but it contains no cookbook files. skipping.
[Sat, 24 Mar 2012 17:37:52 -0700] INFO: Processing package[ntpdate] action install (ntp::default line 22)
[Sat, 24 Mar 2012 17:37:53 -0700] INFO: Processing package[ntp] action install (ntp::default line 27)
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: package[ntp] installed version 1:4.2.4p8+dfsg-1ubuntu2.1
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: Processing template[/etc/ntp.conf] action create (ntp::default line 31)
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: template[/etc/ntp.conf] backed up to /var/chef/backup/etc/ntp.conf.chef-20120324173758
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: template[/etc/ntp.conf] mode changed to 644
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: template[/etc/ntp.conf] updated content
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: Processing service[ntp] action enable (ntp::default line 39)
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: Processing service[ntp] action start (ntp::default line 39)
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: Processing template[/etc/resolv.conf] action create (resolver::default line 22)
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: template[/etc/resolv.conf] backed up to /var/chef/backup/etc/resolv.conf.chef-20120324173758
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: template[/etc/resolv.conf] mode changed to 644
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: template[/etc/resolv.conf] updated content
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: template[/etc/ntp.conf] sending restart action to service[ntp] (delayed)
[Sat, 24 Mar 2012 17:37:58 -0700] INFO: Processing service[ntp] action restart (ntp::default line 39)
[Sat, 24 Mar 2012 17:37:59 -0700] INFO: service[ntp] restarted
[Sat, 24 Mar 2012 17:37:59 -0700] INFO: Chef Run complete in 6.854106 seconds
[Sat, 24 Mar 2012 17:37:59 -0700] INFO: Running report handlers
[Sat, 24 Mar 2012 17:37:59 -0700] INFO: Report handlers complete
Markdownとは
Markdownとは

読みやすく書きやすいプレーンテキストで書き、HXTML or HTML に変換できるフォーマット

  • テキストも読みやすく、HTMLにも変換できるマークアップ言語。

  • 拡張子は.md .markdown

  • markdownのsyntaxや記法は以下を参照

wikipedia markdown
どこかのブログ


どうしてMarkdownなのか

以下の利点があります。

  • テキストとしても読みやすい。

  • テキストなのでvimでかける。

  • vimでシンタックスハイライトされて見やすい。

  • blueclothでhtmlに変換できる。

    # gem install bluecloth
    
  • gimliでpdfに変換できる。

    # gem install gimli
    
  • tumblrでmarkdownがそのまま使える。

  • githubでもMarkdownを使ってREADMEを書いている人が多い。


    なのでみなさん、Markdown使いましょう。

nscd のキャッシュをクリアする方法
nscd のキャッシュをクリアする方法

nscdプロセス起動中に以下を実行

ex) hostsファイルのキャッシュを削除したいとき

# nscd -i hosts


nscd -i [クリアしたいキャッシュ名] とすると、
/var/db/nscd/[キャッシュ名] の内容がクリアされる。

nscdのキャッシュはnscd.confのenable-cache項でコントロールしており、
デフォルトはpasswd,group,hostsファイルがキャッシュ対象となっている。

GlusterFS FileLock Test
GlusterFS FileLock Test


確認すること

2クライアントで同じファイルに書き込みしようとしたとき、
後から書き込みしようとしたクライアントで遅延が発生し、ロックが機能していることを確認。


結果

ロックが効いており、後から書き込みをしようとしたクライアントは、 先に書き込みをしているクライアントが完了するのを待ってから書き込みを完了する。


Glusterfsの構成
  • GlusterfsのマウントはFUSEを使っているGluster Native Client を使用する(NFSやCIFSは実施しない)
  • Glusterfsサーバ側のファイルフォーマットはext3
  • Glusterfsクライアント2台
  • Glusterfsサーバ4台
  • Gluster Volume用のディスクは一台10GB
  • サーバはすべてVMwareのゲストOS
  • OSはUbuntu10.04 LTS 64bit
  • Glusterfs 3.2.3を使用
  • インストールはオフィシャルで用意されているglusterfs_3.2.3-1_amd64.debを使用
  • Glusterfsサーバボリュームは「Distributed Volume」と「Distributed Replicated Volume」の2つで確認。(他にはStripedなどがある)


確認パターン
  1. 一台のサーバ上でターミナルを2つ起動して、ローカルファイルに対して書き込み。

  2. 一台のGlusterfsクライアント上からターミナルを2つ起動して、Glusterfsサーバ上のファイルに対して書き込み。

  3. 二台のGlusterfsクライアント上から、Glusterfsサーバ上のファイルに対して書き込み。

  4. 一台のGlusterfsクライアント上と、Glusterfsサーバ上から、Glusterfsサーバ上のファイルに対して書き込み。


結果 Distributed Volume
  1. はじめにアクセスしたクライアントを待ってから後のクライアントが書き込みをするのでロックが効いている。

  2. はじめにアクセスしたクライアントを待ってから後のクライアントが書き込みをするのでロックが効いている。

  3. はじめにアクセスしたクライアントを待ってから後のクライアントが書き込みをするのでロックが効いている。

  4. 遅延しなかった。

Distributed Replicated Volume

上記と同じ結果になった。


書き込み実行シェル

テストは以下シェルを実行。時間はtimeコマンドで計測。
ファイルパスはローカルとGlusterfs上とで変更する。
file_write.pyを実行したあとでfile_write2.pyを実行する。

file_write.py

#!/usr/sbin/env python
import time
import fcntl
def file_write():
        str = """ at file_write\n """
        f = open('/mnt/glusterfs/test.txt', 'w')
        fcntl.flock(f.fileno(),fcntl.LOCK_EX)
        time.sleep(30.0)
        f.write(str)
        fcntl.flock(f.fileno(),fcntl.LOCK_UN)
        f.close()
file_write()

file_write2.py

#!/usr/sbin/env python
import time
import fcntl
def file_write():
        str = """ at file_write2\n """
        f = open('/mnt/glusterfs/test.txt', 'a')
        fcntl.flock(f.fileno(),fcntl.LOCK_EX)
        time.sleep(0.0)
        f.write(str)
        fcntl.flock(f.fileno(),fcntl.LOCK_UN)
        f.close()
file_write()



glusterfs 3.2.3 Install
  • Gluserfs Client sakabuntu07,sakabuntu08
  • Glusterfs Server sakabuntu03,sakabuntu04,sakabuntu05,sakabuntu06

install package

# apt-get install nfs-common portmap libevent-1.4-2 libgssglue1 libnfsidmap2 librpcsecgss3
# dpkg -i glusterfs_3.2.3-1_amd64.deb
# /etc/init.d/glusterd start


Storage Server Setting

To add a server to the storage pool

# gluster peer probe sakabuntu03
# gluster peer probe sakabuntu04
# gluster peer probe sakabuntu05
# gluster peer probe sakabuntu06

ex) Remove a server from the storage pool

# gluster peer detach sakabuntu03


Creating Distributed Volumes

Create the volume

# gluster volume create test-volume transport tcp sakabuntu03:/data sakabuntu04:/data sakabuntu05:/data sakabuntu06:/data
Creation of volume test-volume has been successful. Please start the volume to access data.

display the volume information

# gluster volume info

Volume Name: test-volume
Type: Distribute
Status: Created
Number of Bricks: 4
Transport-type: tcp
Bricks:
Brick1: sakabuntu03:/data
Brick2: sakabuntu04:/data
Brick3: sakabuntu05:/data
Brick4: sakabuntu06:/data

Start the volume

# gluster volume start test-volume
Starting volume test-volume has been successful

Display information about all volumes

# gluster volume info all

Volume Name: test-volume
Type: Distribute
Status: Started
Number of Bricks: 4
Transport-type: tcp
Bricks:
Brick1: sakabuntu03:/data
Brick2: sakabuntu04:/data
Brick3: sakabuntu05:/data
Brick4: sakabuntu06:/data

To manually mount a Gluster volume

# mkdir /mnt/glusterfs
# mount -t glusterfs sakabuntu03:/test-volume /mnt/glusterfs
# df -h
ファイルシステム            サイズ  使用 残り 使用% マウント位置
/dev/sda1              29G  1.2G   26G   5% /
none                  496M  164K  495M   1% /dev
none                  500M     0  500M   0% /dev/shm
none                  500M   80K  500M   1% /var/run
none                  500M     0  500M   0% /var/lock
none                  500M     0  500M   0% /lib/init/rw
sakabuntu03:/test-volume
                       40G  603M   37G   2% /mnt/glusterfs

To test mounted volumes

# mount
sakabuntu03:/test-volume on /mnt/glusterfs type fuse.glusterfs (rw,allow_other,default_permissions,max_read=131072)


Creating Distributed Replicated Volumes

Create the volume

# gluster volume create test-volume replica 2 transport tcp sakabuntu03:/data sakabuntu04:/data sakabuntu05:/data sakabuntu06:/data
Creation of volume test-volume has been successful. Please start the volume to access data.

Display information about all volumes

# gluster volume info all
Volume Name: test-volume
Type: Distributed-Replicate
Status: Created
Number of Bricks: 2 x 2 = 4
Transport-type: tcp
Bricks:
Brick1: sakabuntu03:/data
Brick2: sakabuntu04:/data
Brick3: sakabuntu05:/data
Brick4: sakabuntu06:/data

Start the volume

# gluster volume start test-volume
Starting volume test-volume has been successful

Display information about all volumes

# gluster volume info all
Volume Name: test-volume
Type: Distributed-Replicate
Status: Started
Number of Bricks: 2 x 2 = 4
Transport-type: tcp
Bricks:
Brick1: sakabuntu03:/data
Brick2: sakabuntu04:/data
Brick3: sakabuntu05:/data
Brick4: sakabuntu06:/data

To manually mount a Gluster volume

# mkdir /mnt/glusterfs
# mount -t glusterfs sakabuntu03:/test-volume /mnt/glusterfs
# df -h
ファイルシステム            サイズ  使用 残り 使用% マウント位置
/dev/sda1              29G  1.2G   26G   5% /
none                  496M  164K  495M   1% /dev
none                  500M     0  500M   0% /dev/shm
none                  500M   84K  500M   1% /var/run
none                  500M     0  500M   0% /var/lock
none                  500M     0  500M   0% /lib/init/rw
sakabuntu03:/test-volume
                       20G  302M   19G   2% /mnt/glusterfs

To test mounted volumes

# mount
sakabuntu03:/test-volume on /mnt/glusterfs type fuse.glusterfs (rw,allow_other,default_permissions,max_read=131072)


Delete Volume

umount glusterfs volume

# umount /mnt/glusterfs

Gluster volume stop test-volume

# gluster volume stop test-volume
Stopping volume will make its data inaccessible. Do you want to continue? (y/n) y
Stopping volume test-volume has been successful

Display information about all volumes

# gluster volume info all

Volume Name: test-volume
Type: Distribute
Status: Stopped
Number of Bricks: 4
Transport-type: tcp
Bricks:
Brick1: sakabuntu03:/data
Brick2: sakabuntu04:/data
Brick3: sakabuntu05:/data
Brick4: sakabuntu06:/data

Gluster volume delete

# gluster volume delete test-volume
Deleting volume will erase all information about the volume. Do you want to continue? (y/n) y
Deleting volume test-volume has been successful

Display information about all volumes

# gluster volume info all
No volumes present


Failure Test


Distributed Volume
  • クライアントがマウント先に指定しているサーバを落とす

    そのサーバ上に乗っているファイルは見えなくなったが、他サーバに乗っているファイルは操作できた。


Distributed Replicated Volume
  • クライアントがマウント先に指定しているサーバを落とす

    特に見れなくなるファイルはない。

マウント時にport24009ですべてのGlusterfsサーバにセッションを貼ってヘルスチェックを実施しているため、指定したサーバが落ちても問題ない。
すべてのボリュームにまたがっているbrickの数だけ、24009から順にportが割当てられる。


参考文献

Glusterfs 3.2 Administration Guide