企業的のPuppetワークフロー、その一

最近Puppetというソフトウェアを会社で使用になってきました。ネットでPuppetについての説明が大勢ありますが、ゼロから本番環境への説明はかなり見当たりにくいです。そのため、この次の投稿にPuppetのワークフローを説明しようと主ます。

概説

さて、まずPuppetはなんでしょう。Puppetはシステム管理者のためのツールで、システムの状態をプログラミング言語で説明します。例えば、普通のLinuxシステムでウェブサーバーを設定には、以下のコマンドを実行するでしょう。

apt-get install apache2
systemctl start apache2

その後、/etc/apache2/sites-enabled/でVhostを設定する必要があります。一台のサーバーならまだある時間でできますが、10台や100台ならかなり手間かかります。その上、いつか将来で一つの設定を全部のサーバーで変えたい時(例えば、TLSの暗号スイートの変化)に、全部のサーバーにログインして、一々設定する必要があります。ていうことで、多分ただ古いバージョンが残っていそうですね。

しかし、Puppetを使用すると、ただ

include apache

を使って、apacheというモジュールで必要なコマンドなどが書いてあって、将来にそのモジュールだけを変える必要があります。

しかし、そのモジュールの開発に本格的なソフトウェアー開発の技術やワークフローを使用した方がいいです。システ未管理者にはやや捕まえにくいアプローチですが、そのためこのチュートリアルを書いてみようと思いました。

内容と内容ではないもの

このチュートリアルではPuppet言語の説明を少しだけ述べたいと思っています。そのテーマがほかのホームページで十分に書いてあって、もう一度書く必要がないし、内容が長すぎます。

逆に、ベストプラクティスとワークフローを述べてあげたいと思いました。どうやって何百台のサーバーインフラを作れるかということはどこにも書いてありません。

そのためにアトラシアンのJiraやBitbucketやBamboo、Gitなどのツールを用いて、会社でも役に立つ情報を上げたいと思います。アトラシアンのツールは有料ですが、フリーソフトのGitlabやJenkinsでも可能です。

Raspberry Piで少電気のActive Directoryサーバーを設定してみた

最近WindowsとLinuxのデュアルブートのシステムや、バーチャルマシン、ホームサーバーなどが一杯あって、ユーザーの設定は手間になりました。Windowsでドメインという概念があって、サーバーはそのユーザー管理を行うのを覚えましたから、自分の家にもできるかを考えてみました。

問題は、お金ということです。Windowsももちろん使いたいですから、Active DirectoryというMicrosoftの方法しか使えません。しかし、普段それを使うにはWindows Serverは必要で、…相当高いから、無理ですね。そのうえ、ちゃんとのサーバーにインストールしなければなりませんから、電源もかなりかかります。

でもSambaというLinux向けのファイルサーバーソフトはバージョン4からそのActive Directoryのドメインコントローラとして働くことができます。だから、Raspberry Piにやってみました。

必要なもの

  • Raspberry Pi(もちろん、ちゃんとのパソコンでも可能です)
  • DHCPを無効にできるルーター

準備

普段ホームルーターはDHCPサーバーを実行して、IPアドレスを振ります。Active Directoryの基本の概念の一つはDNSなので、すこし変える必要があります。DHCPでDNSサーバーのIPも振られるので、そのホームルーターのDHCPでActive DirectoryのDNSサーバーを降る必要があります。それは出来なかったら、Raspberry PiをDHCPサーバーとして運行し、ルーターのDHCPサーバーを無効する必要があります。それか、クライアントのパソコンそれぞれに手動DNSを設定する必要があります。

Javaは気に入りました

三ヶ月前の投稿にJavaに挑戦すると発表しました。この間に少しずつJavaを試してみて、少し気に入りました。Pythonと異なって、変数の定義は必要ですが、その方面は好きになりました。何かプログラミングする前に一応考える必要があるので、楽しいですね。

しかし、その面も手間がかかります。その前に紹介したシャットダウンのPythonスクリプトをJavaに書きが得てみたら、かなり長くなって、時間かかりました。例えば、ファイルを開いたり、読みこんだりすることはPythonより百倍難しい。その上に、いつもjarのパケージを作らなければなりません。

そういえば、ようやくテストを書く甲斐があるのは理解しました。便利ですよ。

プロバイダーとの冒険

今までUnitymediaというISPとの経験はよかったです。公的なIPv4アドレスを受け取れないにもかかわらず、先進的な完全のIPv6をもらえました。ルーターはプロバイダーから上質のAVMのフリツボックス6360 (FRITZ!Box 6360 Cable)も毎月の5ユーロ(700円)の割り増しだけでもらえました。そのフリッツボックスのIPv6のサポートは相当よくて、静的経路も登録できます。満足しました。

しかし、つい最近バグを見つけました。そのフリッツボックスは後ろに設定しているサブネットへの接続を遮断します。わかりやすくするために以下に図を書きました。

Image

OpenWRTでもう一つのネットワークを作りたかったです。非武装地帯を設定して、その中にインターネットから接続できるラズベリーパイにXMPPのサーバーを設定してみたかったです。そのためもちろんOpenWRTに様々なポートを開かなければなりません。しかし、フリッツボックスは既に全部を遮断して、フリッツボックスが自分を管理しているサブネットのみ開くことができます。

インターネットの諸掲示板にその問題が話題になり、AVMというメーカーにも連絡しました。それで、フリッツボックスの6.05のバージョンに解決できたらしいです。嬉しくて、私のバージョンを調べてみたら、6.04です。そのためにアップデートができるでしょう。でも、私は自分でルーターにアップデートできません。ISPだけできます。

ISPのキャスタマーサービスに電話してみると、最初に誰も私のやろうとしていることを理解しなかったらしい。もう一度メールを書いたら、プロバイダーから通話が来て、「独人様のなされようとしていることは少しとても独特ですね」と言われました。ユニーティーメディアが/59のネットワークを提供しますから、32個のサブネット(264-59=25=32) を開くことができるはず(別にできますが、ファイアウォールは遮断すると、意味ないですね…)。アップデートの予定はいつですかと聞いたら、「来ません。そのルーターは既に新客に提供されていませんから、セキュリティーの問題以外はアップデートが提供される確率は相当低いです」。

―では、いまの新型のフリッツボックスもらえますか。(あそこにそのバグは解決されたかもしれません)
―独人様はまだ安い価格を払っていますから、料金をを高くするときだけできます。
―自分のルーターを使用してもいいですか。
―それはできません。
―では、どうすればいいですか。
―申し訳ありません。仕方がありません。

因みに、IPv6はIPv4と違って、あらゆるのポートを後ろのルーターにフォワードできません。ネットワークアドレス変換は存在しないので、全部サブネットでしないといけません。なので、本当に回避する方法がなさそうです。

それで、初めて「強制ルーター」(Zwangsrouter)の弱点を自分自身を経験しました。少しだけ「独特」のことを試そうとしたら、無理です。

そういえば、少しこの強制ルーターのことについて説明したいと思います。

何年間前にドイツ政府はISPの機械、すなわち管理している機械は、ルーターを含めて終わると判断しました。なので、自分の家に持っているルーターは自分のものではなくて、ISPのものです(しかし、電気の消費を払うのは私です)。自分でそのルーターを変えることができません(他のDSLを使っているISPで自分の好きなルーターでも使用できますが、特にケーブルテレビを使ってインターネットを提供するISPはそれを必ず禁止します。毎月に料金を少し高く払ったら、もっといい機会もらえます。それか、Wi-Fiは別で払わないといけません。その上に、サポートの面倒がプロバイダーにとって減少します(「私の画面が付かないよ!―電源ボタンをお押ししましたか?―もちろん、そのばかじゃない!―お願いしますが、もう一回ご確認ぐださい。―あ、いまできた。やったと思ったのに!!」の客は99パーセントの人ですね…)。だから、プロバイダーにとって客に自由を与えないほうがいいです(スマホの世界で同じ現象はお馴染みです)。

近々に強制ルーターは法律で禁止されることは一縷の望みです。最近メディアにそう読みましたが、いつか叶いますかな…

Javaに挑戦します

今までPythonのプログラミングしか試みなかったので、果たしてプログラミング能力が少し限定していると思いました。PythonとPyQtでグラフィカルユーザインタフェースは確かにどうにか出来ましたが、スクリプト言語の理由で「ちゃんと」のアプリを作った気持ちはありません。Pythonは私にとって足りると思いますが、変数宣言やオブジェクト指向の概念が少し欠けています。なので、いまからJavaに挑戦します。SWTというGUIのツールキットを使って、自分の個人図書館管理のアプリを作ろうと思います。

Javaの言語自体はともかくとして、JavaでのGUIツールキットの全てが好きじゃないです…LinuxでのKDEのJavaのGUIは殆どいい外見ではありません。Javaの諸ツールキットは私の憎んでいるGTKの真似をしようとしていますが、KDEのOxygenみたいの綺麗な見た目になりません。SWTはせめて日本語入力をサポートしていますが、Swiftなどのツールキットは全く無理です…

OpenWRTを使って見ました

古い D-Link DIR-300 のルーターを手に入れたので、OpenWRT を入れてみました。OpenWRT は Linux に基づくルーターのファームウェアであって、初期のファームウェアと異なって様々な設定の選択を提供します。例えば、ファイアウォールを詳細に設定できたり、3G のモデムなどもサポートします。Linux の OS なので、様々なソフトもインストールできます。通常 3 万円ぐらいのルーターにも入っていない機能が 5000 円のルーターでできるようになります。

しかし、OpenWRT を初めからインストールしているルーターは販売されていません。OpenWRT のホームページにサポートしているルーターの一覧があって、それを見ながら購入すればいいです。後でファームウェアアップの機能などで OpenWRT をインストールしたら簡単です。しかし、私の DIR-300 というルーターはなかなか容易には出来ませんでした。Telnet と TFTP を使って、内蔵フラッシュのどこの場所にブートローダーをアップロードするかをターミナルで細かく挿入する必要がありました。最終的にはできましたが、相当難しかったです。その上、このルーターが内蔵フラッシュが少ないため、USB ポートもないので、インストールしたいソフトも殆ど入りません。したがって、OpenWRT を一瞥できるぐらいの程度だけでした。しかし、近々にちゃんとのルーターを買う気になりました。

日本語のメールアドレスをどう作るか

このドメインを手に入れたが、付属のメールアドレスも作れるかは気になりました。皆様がご存知のようにメール制度は極めて古い制度で、昔のアメリカの開発を理由として英語だけ充分に対応しています。その原因で、日本語の漢字やドイツ語のウムラウトはろくに使えません。ドメイン制度も同じですが、私の変哲もない.みんなのドメインのようにユニコードも少しずつ対応できるようになりました。メール制度はまだ別の話らしいです。

…と思って、メールでも「太郎@変哲もない.みんな」みたいのアドレスができると気づきました。キャッチフレーズは「SMTPUTF8」です。SMTPUTF8 では、メールサーバーとの通信の中にUTF8のメールアドレスを送ることができます。しかし、国際化ドメイン名も不対応な問題があるなら、この国際化メールアドレスが一層不対応しています。国際化ドメイン名は最悪の場合には Punycode(この HP は xn--n8jyd3c767qtje.xn--q9jyb4c です)を使って直接開くことが出来ますが、メールではそんな簡単にはできません。メールプログラム、メールサーバーなど、全ては対応の必要があります。

私の知っている限りには、グーグルの Gmail だけ対応します。私のドメインにメールを送って見ると、

Delivery to the following recipient failed permanently:
独人@変哲もない.みんな
Technical details of permanent failure:
local-part of envelope contains utf8 but remote server did not offer SMTPUTF8

の返事が来ました。残念ながら、私の使っている Uberspace というウェブサーバーは qmail のメールサーバーを使用していますからできません。Postfix はできるらしいですが、メールプログラムなどはできないと、そういうメールアドレスは実際に役に立ちません。あと5年ぐらいにできるのかな?

しかし、特に日本人にとってそういうメールアドレスは便利そうだと思っています。ドメイン名はともかくとして(殆どの日本人はホームページを開くためにグーグルしか使わなさそうです)、メールアドレスは少し覚えやすくなりそうです。「鈴木辰雄@会社.jp」は覚えやすくないですか。ご意見はお聞きしたいです。

ちなみに、前の部分はローマ字だと、メールプログラムがドメインの部分を自動的にプニコードに変更していきます。例えば、「test@変哲もない.みんな」にメールを書くとき、Thunderbird や Outlook などがそのドメインの部分を xn--n8jyd3c767qtje.xn--q9jyb4c に変更して送ります。

自動的なサーバーのシャットダウン

自作の Linux サーバーを使っているので、最初から節電について考えました。以前使用していたパソコンを使っていますので、特定の NAS と異なって電力消費が少し多くなってしまいます。40 ワットぐらいを消費すると、24 時間の起動なら、(0.23 ユーロ/1kWhの電気価格だとすると)毎月 6.50 ユーロにも(900 円くらい)なります。パスコンがオフの時にサーバーが稼働している必要はないですから、どうやって節電できるでしょうか。

うちのサーバーは3台のパソコンと繋がっています。全部のパソコンがオフの時だけサーバーシャットダウンすべきです。そのために小さい Python のプログラムを開発しました。

やり方は相当簡単です。リストに書いてある IP アドレスを全てピングして、いずれかのパソコンから応答があると、スクリプトは直ちに終了します。もし応答がない場合でも、そのパソコンが再起動中の可能性がありますから、90 秒待機してからもう一度ピングします。最後にシャットダウンします。

で、それは一番基本的なやりかたです。段々もっと欲しい機能が思いついたので、それも開発してみました。

  • サーバーを起動しても、まだパソコンはオフの状態であったら、サーバーがすぐシャットダウンしてしまう時がよくありました。そのため、スクリプトが起動してからの時間(/proc/uptime に記載しています)を読み込んで、10 分間は必ず起動してからのみシャットダウンします。
  • たまに消えてほしくない時があります。それでファイルの中に起動すべきの分を書き込めます。そのファイルの変更の時間+中に書いてある時間を合わせたら、現在時間と比べます。例えば、そのファイルは 13:40 に変更して、その中に「120」を書き込んだら、13:40+120 分は 15:40 になります。現在時間は例えば 14:20 だとしたら、スクリプトがすぐ終了します。「touch」をつかって、簡単に現在時点から書けます。

最後にこのスクリプトを root として cron に入れなければなりません。

スクリプトは以下に記載しました。将来に Github にも提供する予定です。コメントが頂けたら、幸いです。

#!/usr/bin/env python3

#バージョン2
#2015年2月6日

import subprocess
import time
import os.path
from datetime import timedelta, datetime

ip_addresses = [ "192.168.0.2", #パソコン1
                "192.168.0.3", #パソコン2
                "192.168.0.4"] #パソコン3

shutdown_command = ["/usr/bin/systemctl", "suspend"]
do_not_shutdown_file = "/home/user/no-shutdown"
shutdown_only_after = timedelta(minutes=10)


def read_shutdown_file_time(dns_file):
    file_modify_date = datetime.fromtimestamp(os.path.getmtime(dns_file))
    with open(dns_file) as f:
        shutdown_after = timedelta(minutes=int(f.readline()))
    return file_modify_date + shutdown_after


def parse_uptime():
    with open("/proc/uptime", "r") as f:
        return timedelta(seconds=float(f.readline().split()[0]))


def main():
    try:
        if datetime.now() < read_shutdown_file_time(do_not_shutdown_file) or parse_uptime() < shutdown_only_after:
            exit()
    except FileNotFoundError as e:
        pass
    except ValueError as e:
        pass

    for computer in ip_addresses:
        if subprocess.call(["ping", "-c1", computer], stdout=subprocess.PIPE) == 0:
            exit()

    time.sleep(90)

    for computer in ip_addresses:
        if subprocess.call(["ping", "-c1", computer], stdout=subprocess.PIPE) == 0:
            exit()

    subprocess.call(shutdown_command)

if __name__ == "__main__":
    main()

新しいブログを始めました。

新しいブログを始めました。目的はもちろん日本語の勉強のためでも、今の私の持っている趣味についても話したい。ですから、これから特にネットワーク、IPv6やLinuxについて話そうと思います。

ブログのタイトルはいつも問題になりますね。こういうブログを書いている人が山積みいるだと思いますから、(今の現在時点で)このブログも何も特別なブログではありませんから、「何の変哲もないブログ」を名乗りました。

ちなみに、このドメインが少し気に入っています。.みんなのドメインはグーグルが2014から提供しますが、私の住んでいるドイツでも手に入れることが出来ます(.jpは日本滞在のみ可能)。そのため、 INWX で申請しました。一年間で11.90ユーロ(1500円ぐらい)をかかります。日本では1890円します。