いますぐ実践! Linuxシステム管理

いますぐ実践! Linux システム管理 / Vol.260 / 読者数:2607名

こんばんは、うすだです。

いま利用しているVPSのサービスが今年度で終わってしまうため、 移転先となるVPSを1つ、新たに利用してみることにしました。

ありがたいことに、試用期間中は無料なのですが、 最初にセットアップをして最低限の設定をしてからは、 ほぼ放置してしまっています。

そうこうしているうちに、あと数日で試用期間が終わります。
あまりにも予想通りの展開に、我ながら呆れています。

今の契約が7月で切れるため、さすがにそれまでには移行できる (というかせざるをえない)と思っていますが、 ひょっとするとひょっとするのかもしれません。

もし、8月以降、アクセスできなくなっていたら、 あーそういうことかと笑ってやってください。

それは絶対に回避せねばと思いつつ、今回もはりきってまいりますね。

今回のお題 - namespace を使ってみる (レベル:中級)

今は仮想化などの技術が当たり前になり、潤沢なリソースを持つ OS の上に、 たくさんの OS をまるごと動かすことができるようになりました。

ですが、少ないリソースをやりくりしていた頃は、 named などを chrootして起動するなど、 少ない労力でそれなりのセキュリティを確保する努力がなされていたように思います。 (当時の賢いどなたかの努力ですね。)

さて、唐突ですが、Linux には namespace という機能があります。
これをうまく利用すると、 少ない労力でそれなりにシステムを強固にすることができるのではないか、 という気がしております。

そこで今回は、namespace のさわりをご紹介したいと思います。
力及ばず、さわりだけとなっております。ご了承ください。

namespace とは?

プログラム言語における namespace は、 関数や変数などの名前の衝突を避けるためのものです。

壮大なプログラムを開発するときや、多数のライブラリを使用する場合、 それぞれの名前が衝突しないように命名するのは、至難の業です。

そこで、namespace 毎に分けて、その中で衝突しないようにすることで、 そんなわずらわしさから開放されます。

C++ の namespace や、Java の package、XML などを、 少しでもかじった経験がおありでしたら、あああれね、 と思っていただけると思います。

で、Linuxの namespace は、リソースを区切って、 あたかもそれだけしか存在しないように見せるためのものです。

具体的には、mount、UTS、IPC、PID、ネットワークおよびユーザの6つが 対象となるリソースです。

ちなみに、各プロセスの namespace は、 /proc/プロセスID/ns/ を以下のように見ることで、それとなく確認できます。

  $ ls -l /proc/$$/ns/
  total 0K
  lrwxrwxrwx 1 usu weak 0  Jun  1 10:58 ipc -> ipc:[4026531839]
  lrwxrwxrwx 1 usu weak 0  Jun  1 10:58 mnt -> mnt:[4026531840]
  lrwxrwxrwx 1 usu weak 0  Jun  1 10:58 net -> net:[4026531956]
  lrwxrwxrwx 1 usu weak 0  Jun  1 10:58 pid -> pid:[4026531836]
  lrwxrwxrwx 1 usu weak 0  Jun  1 10:58 user -> user:[4026531837]
  lrwxrwxrwx 1 usu weak 0  Jun  1 10:58 uts -> uts:[4026531838]

unshare コマンドで mount namespace を体験してみる

いくつかの namespace は、「unshare」というコマンドで切り替えることができます。

ここでは、mount namespace を試してみようと思います。
mount namespace を変更するには、「--mount」または「-m」オプションと、 コマンドを指定して実行します。
いろいろ試したいので、以下では bash を起動しています。

  $ sudo unshare --mount /bin/bash
  # ls -l /proc/$$/ns/
  ...中略...
  lrwxrwxrwx 1 root root 0  Jun  1 11:26 mnt -> mnt:[4026532536]
  ...後略...

/proc/プロセスID/ns/mnt の値が変わっていることがわかります。
(他の値は、前述の実行結果と同じままなので、省略します。)

ここで、新たに何かを mount してみましょう。
以下では、/hometmp を作成し、そこに tmpfs を mount しています。

  # mkdir /hometmp
  # mount -t tmpfs tmpfs /hometmp

ここにファイルを作成すると、当然ですが、そのファイルは存在します。

  # touch /hometmp/abc
  # mkdir /hometmp/def
  # ls /hometmp/
  abc  def/

ですが、別のシェルから /hometmp を見ても、namespace が異なるため、 上記のようには見えません。というかからっぽです。

  $ ls /hometmp/
  $ 

ここで、/hometmp を、/home/chestnut に bind mount してみましょう。
/hometmp を mount したシェル(unshare しているシェル)で実行すると、 当然、/hometmp と同じ中身が見えます。

  # mount --bind /hometmp /home/chestnut
  # ls /home/chestnut/
  abc  def/

ですが、別のシェルから参照すると、もとの内容が見えます。

  $ ls /home/chestnut/
  examples.desktop テンプレート/ ドキュメント/ ピクチャ/  公開/
  ダウンロード/    デスクトップ/ ビデオ/       ミュージック/

ですので、たとえば、chrootするほどではない(あるいはできない)けど、 /home などにはアクセスさせたくないというデーモンを動かしたいとき、 namespace が利用できそうです。(ザ・ニッチなニーズです…)

あ、ひと通り試し終えたら、後片付けをしましょう。

  # umount /home/chestnut
  # umount /hometmp
  # exit

ip netns で network namespace を新たに作る

ネットワークも namespace で区切ることができます。

network namespace を管理するには、「ip」コマンドを利用します。
ただし、RHEL6 や CentOS6 の ip コマンドは未対応のため、 下記を試すことができません。ご了承ください。

で、まず、オブジェクトに「netns」を指定して実行すると、一覧が表示されます。

  $ ip netns
  $ 

…えーと、はい、まだ作っていないので、なんにもありません。
新しく作るには、「add namespace名」を指定して実行します。

  $ sudo ip netns add zaccaria
  $ ip netns
  zaccaria

「exec namespace名 コマンド」で、コマンドを実行できます。
いろいろやりたいので、先ほどと同様に、bash を起動します。
(わかりづらいので、以降では、 起動した bash のプロンプトを「new#」と表しています。)

  $ sudo ip netns exec zaccaria /bin/bash
  new# 

どうやら、インタフェースは「lo」のみで、しかも up されていません。

  new# ip link list
  1: lo:  mtu 65536 qdisc noop state DOWN mode DEFAULT group default
      link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

せめて lo を up しておきましょう。

  new# ip link set lo up
  new# ping 127.0.0.1
  PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
  64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.046 ms
  64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.045 ms
  ...中略...

netstat で待ち受けている人がいないか見てみましたが、案の定、 そんなひとはいませんでした。元の lo とも独立しているのですね。

  new# netstat -an
  Active Internet connections (servers and established)
  Proto Recv-Q Send-Q Local Address     Foreign Address   State
  Active UNIX domain sockets (servers and established)
  Proto RefCnt Flags       Type       State         I-Node   Path

しかし、他の人と通信できないのは困りますよね。
そこで、「veth」という、仮想的な Ethernet のインタフェースを作り、 つないでしまいましょう。

ip netns exec した方ではなく、元の世界で作成します。

  $ sudo ip link add name veth1 type veth peer name veth2

元の世界側を veth1、ペアの反対側を veth2 と命名しておきました。
そして、veth2 を、先ほど作った namespace に移動させます。

  $ sudo ip link set veth2 netns zaccaria

すると、veth2 が新しい方に出現します。

  new# ip link show veth2
  3: veth2:  mtu 1500 qdisc noop state DOWN \
  mode DEFAULT group default qlen 1000
    link/ether c6:ec:c5:f3:3d:26 brd ff:ff:ff:ff:ff:ff

それぞれにIPアドレスを設定し、up します。
ここでは、192.168.111.1/24 と 192.168.111.2/24 にしています。

  $ sudo ifconfig veth1 192.168.111.1/24 up
  new# ifconfig veth2 192.168.111.2/24 up

これで、通信できるようになりました。

  new# ping 192.168.111.1
  ...後略...

これ以降の、たとえば ip forwarding や iptables などの設定は、 紙面の都合により割愛させていただきます。

あ、これも、後始末をお忘れなく。

  new# exit
  $ sudo ip netns delete zaccaria

他にも namespace があるよ

unshare コマンドでは、UTS や IPC の namespace も変更できます。
さらさらっとご紹介しておきます。

UTS では、ホスト名やドメイン名を変更できます。

  $ hostname
  sally
  $ sudo unshare --uts /bin/bash
  # hostname
  sally
  # hostname derry
  # hostname
  derry

もとのホスト名は sally ですが、unshare で切り替え後、 derry に変更しています。
このホスト名は、新たな namespace だけで有効ですので、 unshareで起動したシェルを終了すると、ホスト名はもとに戻ります。

  # exit
  $ hostname
  sally

 

また、IPC では、共有メモリやセマフォなどのIPCを別にできます。

  $ ipcs -m

  ------ Shared Memory Segments --------
  key        shmid     owner    perms   bytes     nattch    status
  0x00000000 0         root     644     80        2
  0x00000000 32769     root     644     16384     2
  ...中略...
  0x00000000 1966090   usu      600     524288    2         dest
  0x00000000 1474571   usu      600     4194304   2         dest

  $ sudo unshare --ipc /bin/bash
  # ipcs -m

  ------ Shared Memory Segments --------
  key        shmid     owner    perms   bytes     nattch    status

  # 

namespace 切り替え後は、からっぽになっています。
たとえば、ipcmk コマンドで共有メモリを作ると、表示されます。

  # ipcmk -M 256
  # ipcs -m

  ------ Shared Memory Segments --------
  key        shmid     owner    perms   bytes     nattch    status
  0x5e109c1d 0         root     644     256       0

作った共有メモリは、他のシェルからは、見えません。
IDが0番の共有メモリ確認しても、サイズが違うので、別物のようです。

  $ ipcs -mi 0

  Shared memory Segment shmid=0
  uid=0	 gid=0  cuid=0  cgid=0
  mode=0644     access_perms=0644
  bytes=80      lpid=1117      cpid=1113      nattch=2
  ...後略...

おわりに

以上、namespace について、簡単にご説明しました。

namespace に関して、そもそも私がまだ理解できていないことがたくさんあります。 暴動が起こらなければ、次回も namespace で引っ張ります。

ちなみに、主な元ネタは、下記のページです。
前者は、きっかけです。わかりやすいです。日本語ですし。
後者は、英語が読めない私でも、例を眺めるだけでわりと理解できましたので、 もっと詳しく知りたいと思う貴兄は、ぜひご覧ください。

第2回 コンテナの仕組みとLinuxカーネルのコンテナ機能[1]名前空間とは?
LXCで学ぶコンテナ入門 - 軽量仮想化環境を実現する技術 - 技術評論社
http://gihyo.jp/admin/serial/01/linux_containers/0002

Namespaces in operation, part 1: namespaces overview [LWN.net]
http://lwn.net/Articles/531114/

宿題の答え

前回の宿題は、

  仮想ディスクのサイズを減らしてみましょう。

でした。

ここでは、VirtualBox のゲストOS が CentOS で、 LVM で構成されているファイルシステムのサイズを減らしてみたいと思います。
減らす手順は、このようになります。

  1. ファイルシステムのサイズを減らす
  2. LVMの論理ボリュームのサイズを減らす
  3. パーティションサイズを減らす
  4. 仮想ディスクのサイズを減らす

まず、mount しっぱなしで操作はできないため、前回と同様、 Ubuntu のインストール兼ライブ起動用イメージなどで起動します。

起動したら、lvscan コマンドで現状を確認します。

  $ sudo lvscan /dev/sda
    ACTIVE            '/dev/VolGroup/lv_root' [13.54 GiB] inherit
    ACTIVE            '/dev/VolGroup/lv_swap' [1.97 GiB] inherit

ここで、lv_root のサイズを 10GB に減らしたいとしましょう。
まず最初に、ファイルシステムのサイズを削る必要があります。
ファイルシステムのサイズ変更には、resize2fs コマンドを使用します。

  $ sudo resize2fs /dev/VolGroup/lv_root 10G

お次は、lvreduce コマンドで、論理ボリュームを削ります。
ファイルシステムのサイズを 10GB としましたので、 念のため少し冗長なサイズにしておきます。

  $ sudo lvreduce -L10.1G /dev/VolGroup/lv_root
    Rounding size to boundary between physical extents: 10.10 GiB
    WARNING: Reducing active logical volume to 10.10 GiB
    THIS MAY DESTROY YOUR DATA (filesystem etc.)
  Do you really want to reduce lv_root? [y/n]: y <= yと入力
    Reducing logical volume lv_root to 10.10 GiB
    Logical volume lv_root successfully resized

警告されますが、勇気を持って(?) y と答えます。
そして、確認のため mount してみます。

  $ sudo mount /dev/VolGroup/lv_root /mnt
  $ ls /mnt
  bin  cgroup etc  lib   lost+found misc net proc sbin    srv
  ...中略...
  $ sudo umount /mnt

大丈夫そうです。

パーティションサイズの変更は、前回と同様、GParted や fdisk などで行います。 (ので、割愛します。)

最後に、仮想ディスクのサイズ変更です。
やっぱり、同様に VBoxManage コマンドの modifyhd で行う…と思う…のですが…。

  $ VBoxManage modifyhd ~/VirtualBox\ VMs/CentOS/CentOS.dvi --resize 10400
  0%...
  Progress state: VBOX_E_NOT_SUPPORTED
  VBoxManage: error: Resize hard disk operation for this format is not implemented yet!

対応していないと言われてしまいました。OTZ
ちなみに、--compact オプションを指定すると、ディスクサイズは変わりませんが、 圧縮してリアルなファイルサイズを縮めてくれます。

  $ ls -l ~/VirtualBox\ VMs/CentOS/CentOS.vdi 
  -rw------- 1 usu usu 6931087360 Jun  1 00:31 CentOS.vdi
  $ VBoxManage modifyhd ~/VirtualBox\ VMs/CentOS/CentOS.vdi --compact
  0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
  $ ls -l ~/VirtualBox\ VMs/CentOS/CentOS.vdi 
  -rw------- 1 usu usu 6921650176 Jun  1 00:31 CentOS.vdi

…今回は、長い間待った割には、9MB 減っただけでした。

というわけで、VirtualBox では、大きくはできても、 小さくすることはできないようでした。 (将来できるようになるかもしれませんね。)

今回の宿題

今回の宿題は、

  unshareで作られたnamespaceは、unshare終了後どうなるのでしょうか?

です。

明示的に削除しないといけないのであれば、上記で試した namespace は今もなお、 カーネルの中をさまよい続けていることになりますね。

unshare 終了後、自動的に消されるのか、そうでないのか、 調べておこうと思います。…じゃなくて、調べてみてください。

あとがき

Ubuntu 14.04 LTS と、その日本語Remix が、リリースされています。

TrustyTahr/ReleaseNotes/Ja - Ubuntu Wiki
https://wiki.ubuntu.com/TrustyTahr/ReleaseNotes/Ja

Ubuntu 14.04 LTS 日本語 Remix リリース | Ubuntu Japanese Team
https://www.ubuntulinux.jp/News/ubuntu1404-ja-remix

早速、13.10 からアップグレードしてみましたが、大きな混乱やつまづきなどなく、 今までで最もスムースに移行できています。

さしあたって、カーソル付近にMozcのプロパティパネルが表示されるようになり、 半角入力か全角入力か、ひと目でわかるようになったのが、便利だなと感じてます。

それ以外には、前バージョンとの違いをあまり感じていませんが、 それはそれで安定しているということでもあり、いいことなのかもしれません。

いえ、いろいろ変わっているのにも関わらず、 その違いを感じられるほど使いこなせていない、という気がしてきました。

OpenStackLXCOpen vSwitchもあれもこれも、 やろう!と思ってやってない状態が、数年続いてしまっています。

期限を決めないと着手すらしないという癖を、 いい加減やめないといかんと思っております。

裏を返せば、すべてにおいて期限を決めれば、少なくとも着手はする、 ということでもあるのですが…。

ただ、自分で決めた期限は、基本的には守れません。
ですので、期限を決めて、守れなかったら、すごい怖い人に叱られる、 というサービスがあったらいいんじゃないかと思いました。

 

…嘘です。そんなサービスは使いたくありません…。

 

あ、以上ではなく、お知らせがあります。
次回は、諸般の事情(こればっか)により、お休みをいただきます。

某誌の何かが絡んでおりますが、 それに追い打ちをかけるように、個人的な用事が重なったことが、主な原因です。 (ああ歯切れが悪い…)

毎回発行を待ち望んでいる… なんていう貴兄はほとんどいらっしゃらないと思いますが、そんな奇特な方も、 待ち望んでいない普通の方も、7月6日までお待ちいただけますと幸いです。

 

今回も、ここまで読んでいただき、誠にありがとうございました。
次回は、7月6日(日) 未明にお会いしましょう!

 

「いますぐ実践! Linux システム管理」の解除は、以下からできます。
http://www.usupi.org/sysad/ (まぐまぐ ID:149633)

バックナンバーは、こちらにほぼ全部そろっています。
http://www.usupi.org/sysad/backno.html

「栗日記」- 冨嶽三十六景をやろう! …有言実行するため書きます。
http://www.usupi.org/kuri/ (まぐまぐ ID:126454)
http://usupi.seesaa.net/ (栗日記ブログ)
http://usupi.org/k/ (モバイル栗日記)
http://twitter.com/kuriking/ (栗つぶやき)
http://facebook.com/kuriking3 (栗顔本)


[バックナンバーのトップへ] [Linux システム管理のトップへ]

トップ

バックナンバー
    [日付順] [目的別]

プロフィール

▼ リンク

独学Linux
Linuxデスクトップ環境に関する情報が満載です。 メルマガもありますよ。
Server World
CentOS 6をサーバとしたときの設定例が、これでもかというくらいたくさん載っています。 CentOS以外のディストリビューション(Fedora, Ubuntu)も充実しています。
LINUXで自宅サーバーを構築・導入(Fedora9)
Fedora9のインストールの仕方から管理方法まで、詳しく載っています。 SearchManには情報がもりだくさんです。
マロンくん.NET
〜サーバ管理者への道〜
Linuxをサーバとして使用するための、いろいろな設定方法が載っています。 マロンくんもかわいいです。 なんといっても、マロンくんという名前がいいですね!!
日経Linux
今や数少なくなってしまったLinuxの雑誌。ニュースやガイドもあります。
Linux Square − @IT
@ITが提供する、Linux の情報が満載。 載っていない設定方法はないんじゃないでしょうか。
gihyo.jp…技術評論社
Linuxに限らず様々な技術情報が満載のサイト。 SoftwareDesign誌も、 ソフトウェア技術者は必見です。
SourceForge.JP Magazine
Linux に限らず、オープンソース関連の記事が網羅されています。
ITmediaエンタープライズ:Linux Tips 一覧
Tips というより FAQ 集でしょうか。わからないことがあれば覗きましょう。
IBM developerWorks : Linux
開発者向けですが、勉強になりますよ。
Yahoo!ニュース - Linux
Yahoo!のLinuxに関するニュース一覧です。
栗日記
システム管理とかと全然関係ありませんが、毎日栗の絵を描いています。
システム管理につかれちゃったとき、癒されたいときに、ご覧ください。:-)
WEB RANKING - PC関連
ランキングに参加してみました。押してやってください。

▼ 作ってみました

Add to Google

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本