Saturday, May 11, 2013

Virtual Ethernet Tunnel (veth) の組を知りたい

Linux には、OpenVZ由来の Virtual Ethernet Tunnel (veth) というものがある。

名前が示す通り、仮想的な Ethernet Interface の組を作成して、つないでくれる。

これは、VMやContainerを動かす時に便利な機能なのだが、たくさん veth I/F を作っていると、へたをすると、どれが veth なのか?とか、どれとどれが対応するのかわからなくなる。

ip コマンドなどで調べられればいいのだが、ざっと調べた限り発見できなかった。

しかたないので、ソースの

  ./driver/net/veth.c

を軽く調べてみると、以下をの通り、ethtool で veth 特有の統計情報を出力しているらしい。


 39 /*
 40  * ethtool interface
 41  */
 42
 43 static struct {
 44     const char string[ETH_GSTRING_LEN];
 45 } ethtool_stats_keys[] = {
 46     { "peer_ifindex" },
 47 };

peer_ifindex という統計値を出力しているドライバは、少なくとも現状は他に存在しないようだ。

なお、調査を行ったのは CentOS 6.4 で、バージョンはこんな感じ。

# modinfo veth
filename:       /lib/modules/2.6.32-358.el6.x86_64/kernel/drivers/net/veth.ko
alias:          rtnl-link-veth
license:        GPL v2
description:    Virtual Ethernet Tunnel
srcversion:     84BEC28E0EAB8E31E4CACC2
depends:
vermagic:       2.6.32-358.el6.x86_64 SMP mod_unload modversions


それで、実際にやってみた結果が以下。

まず、調査対象のサーバでは以下のようなインタフェースが作成されている。


# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 00:0c:29:ba:96:73 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 00:0c:29:ba:96:7d brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 00:0c:29:ba:96:87 brd ff:ff:ff:ff:ff:ff
5: br-eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN
    link/ether 00:0c:29:ba:96:7d brd ff:ff:ff:ff:ff:ff
6: br-int: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether b2:48:56:9c:8f:43 brd ff:ff:ff:ff:ff:ff
10: qbr88886a31-17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
31: phy-br-eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether e6:f1:56:69:fb:f2 brd ff:ff:ff:ff:ff:ff
32: int-br-eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 76:a5:94:6e:ff:f6 brd ff:ff:ff:ff:ff:ff
42: qbr30aed268-b6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 8e:4c:83:bf:36:df brd ff:ff:ff:ff:ff:ff
43: qvo30aed268-b6: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether d2:c1:85:94:31:83 brd ff:ff:ff:ff:ff:ff
44: qvb30aed268-b6: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 8e:4c:83:bf:36:df brd ff:ff:ff:ff:ff:ff
45: tap30aed268-b6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 500
    link/ether fe:16:3e:b1:6c:03 brd ff:ff:ff:ff:ff:ff

実際は qvo30aed268-b6 と qvb30aed268-b6 が veth で組になっているのだが、この出力ではわからない。

ソース調査の結果からは、ethtool -S でかたっぱしから統計情報を出力してやると、veth だけpeer_ifindex が出力され、相手がわかるはずである。

# ethtool -S  qvo30aed268-b6
NIC statistics:
     peer_ifindex: 44

# ethtool -S qvb30aed268-b6
NIC statistics:
     peer_ifindex: 43

…ということで、少なくとも、上記の2つがペアになっていることはわかった。

他のデバイスについては何も表示されないものと期待できるのだが、代表的なところをやってみると、以下の通り。

Linux Tun/Tap

# ethtool -S  tap30aed268-b6
no stats available


OpenvSwitch で作成した bridge
# ethtool -S  br-int
no stats available

生の ethernet カード
# ethtool -S  eth0
no stats available

brctl で作成した bridge
# ethtool -S  qbr88886a31-17
no stats available


ということで、最低限の目的は遂げることができるようだ。


Monday, May 6, 2013

MySQLの権限設定について


DBMSについてはずぶの素人の告白…というか、メモということで。
(たぶん誤解が入っているはずなので、ご指摘いただけると幸いです...)

さて、自分が使っているソフトが制御データを永続化するためにRDBMSを使っていることも多いと思う。
ご多分にもれず、自分がいじっているOpenStackの各種サービスくんたちもRDBMS(通常はMySQL)に依存しまくりである。

で、まず最近ようやく気が付いたのだが、GRANT を使ってユーザに対してアクセス権を与える時の以下のような注意がある(らしい。なにか誤解があるような気がするのだが...)

まず、

  mysql> create database mydb;

データベースを作るのはいいとして、ユーザ作成/アクセス権限を付与する時に

  mysql> grant all privileges on mydb.* to 'user1'@'%' identified by 'PASSWORD';

としただけでは、実は localhost は含まれないので、localhost(127.0.0.1)でアクセスする可能性もあるなら

  mysql> grant all privileges on mydb.* to 'user1'@'locahost' identified by 'PASSWORD';

も必要というのが1つ。

さらに、ここから誤解が入っている気がしてならないのだが、
上記ではアクセス権は細粒度でやったほうがいいかな?ということで、
データベース名 mydb を指定し、データベース単位での権限を設定しているつもり。

この場合、

  mysql> use mysql
  mysql> select * from mysl.user where user='user1'\G;

とかしてみると、権限が軒並み N になっているのが気になるのだが、
自ホストから(localhost ではなくて) IP やホスト名でアクセスできない。

…ので、上述の grant 文2行に加えて、

  mysql> grant all privileges on mydb.* to 'user1'@'DB_HOST_NAME' identified by 'PASSWORD';

が必要になる。
DB_HOST_NAME は MySQL がまさに動作しているホストのホスト名である。

一方、grant 文の 'on DB_NAME.TABLE_NAME' を指定する際に '*.*' とすると
データベース単位から(MySQLインスタンス内)グローバルになるわけだが、
権限が軒並み Y に変わり、アクセスできるようになる。


さて、何が足りない(or 誤解な)のだろう?

追記
バージョンは、古いのだけど CentOS6.4/EPEL6付属の MySQL 5.1系の話。