debian ベースの ディストリ上で openvpn が起動しない場合

ubuntudebianopenvpn をインストールしたときに service restart などが全く効かなかった時の話。

バージョン確認

$ docker run -i -t ubuntu
# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"
$ docker run -i -t debian
# cat /etc/debian_version
8.6

起動してみる

# service openvpn start
[ ok ] Starting virtual private network daemon:.

起動したように見える…が、実際には起動してない。

/etc/systemd/system/multi-user.target.wants/openvpn.service を見ると下記のようになっている。

# This service is actually a systemd target,
# but we are using a service since targets cannot be reloaded.

[Unit]
Description=OpenVPN service
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/true
ExecReload=/bin/true
WorkingDirectory=/etc/openvpn

[Install]
WantedBy=multi-user.target

ExecStart などが 起動につかうコマンドになるはずだが /bin/true になっている…。成功したように見えるのはこのコマンドのせいのようす。とにかく起動したいので下記のように openvpn を直接起動するように変更してみる。

ExecStart=/usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --config /etc/openvpn/server.conf
$ sudo systemctl daemon-reload
$ sudo systemctl start openvpn

一応これで起動するようになった…はず。フラグは不明だが systemd のファイルがいつのまにか巻き戻っていたり、 /usr/sbin/openvpn が起動しなくなったりするのでよくわからない。

Docker for Mac 起動中には Android Emulator (HAXM) が動かない

下記のようなエラーが出た場合で virtualbox そのものを使っている覚えがない場合で Docker for Mac を使っている場合は Android Emulatror の HAXM ありの場合に起動しない可能性がある。

Hax is enabled
Hax ram_size 0x40000000
HAX is working and emulator runs in fast virt mode.
emulator: Listening for console connections on port: 5554
emulator: Serial number of this emulator (for ADB): emulator-5554
Failed to sync vcpu reg
Failed to sync vcpu reg
Failed to sync vcpu reg
emulator: ERROR: Unfortunately, there's an incompatibility between HAXM hypervisor and VirtualBox 4.3.30+ which doesn't allow multiple hypervisors to co-exist.  It is being actively worked on; you can find out more about the issue at http://b.android.com/197915 (Android) and https://www.virtualbox.org/ticket/14294 (VirtualBox)
Internal error: initial hax sync failed

https://forums.docker.com/t/cant-using-docker-for-mac-with-android-emulator-haxm/8939

対処方法は Docker for Mac を停止させるぐらいしか思いつかない。

ISUCON6 予選参加記

ISUCON6 予選 9/17 土曜日に「応答5マイクロセカンド」で take4、Takky と参加していました。

参加当日からずっと風邪引いてたりしてたのでまともな振り返りはしてないですが記録として書いときます。 (箇条書きで同列っぽく書いてますが事実と主観が混在してます)

準備編

やったこと

  • 過去問練習会
    • Azure 環境の確認
  • newrelic のアカウント準備および使い方の確認

準備での雑感

  • azure の初期セットアップおよびリカバリで時間がかかる場合があるのでリストアはしっかりできるようにする
  • newrelic は CPU やメモリは確認できたが MySQL のクエリおよびアプリケーションについては使い方が確認できなかったので当日は使わないことにした
  • 3人のスキルセットから php を使うことを検討したが php.ini のチューニングに時間がかかりすぎる場合があるので Go に変更
    • ここで Go を書ける人が1人しかいないのでアプリ担当が1人になる

当日編

午前

  • 準備を完了する
    • アプリデプロイ
    • メトリクス収集用設定
  • アプリに一通り触れて使用感を確認する
  • アプリやSQLを眺める
  • 方針の決定

わかったこと

  • isuda, isutar, isupam の3つのサービスがある
  • isuda がメインサービスで isutar は http で通信 isupam は外部プロセス呼び出しで連携する
  • newrelic の結果より isuda > mysql >> その他で CPU を消費している
  • MySQL の slow query は出ていない
  • MySQL の general log から一部 SELECT の間隔が遅い
  • 初期状態は fail で 0 points

以上より

  • ボトルネックはアプリケーションとして作業する
  • 最も遅い所は / や /keyword で基本的に htmlify() があるのでこれを何とかする
  • その他こまごまとしたものは最後にまとめて対応か暇になったら都度対応

午後

  • keyword の完全オンメモリ化
    • initialize 時にロードする実装
    • 追加およびソートの実装
    • (削除処理は実はすっかり忘れてた)
  • htmlify のキャッシュ化
    • matcher のキャッシュ
    • アンカータグのキャッシュ
    • キーワード毎の htmlify のキャッシュ
    • キーワード追加時の htmlify キャッシュのパージ
  • SQL の不要なデータの取得をなくす

上記対応後でもずっと 0 点だったためどれがどの程度効果があったかは不明です。

雑感

  • メトリクス収集してアタリをつけられるようにするのはやはり必要と思った
    • prometheus + grafana で準備しようとしたけど間に合わなかったので newrelic を採用
    • sort by CPU でプロセスみれたのは便利
    • ただ newrelic の mysql プラグインが頑張っても動かなかったのでうーんという感じ
  • チーム構成にもよるかもだけど 午前方針ぎめ、飯食いながら相談、1時間前まで作業、30 分まえまでに落とし所に収束させる、30 分で再起動確認という流れで考えてたけど間違ってはいないかなと思う。
  • 点数が正の数になって景気つけようとしてたけど Fail 0 だった
    • いつの間にか 307 点ぐらいとったけど気のせいレベル
  • ボトルネック部分把握した所で「競プロ勢有利な問題じゃん」と叫んでいた。
    • 実際にどうかは知らない(競プロ雑魚勢の感想)
  • 途中というか最初から make 叩くだけでは Go アプリのビルドが成功しなかった
  • 今回は複数環境を用意したり linux 上のユーザをわけたりはしなかったが特に不都合はなかった
    • 以前参加したときのように個々で修正して個々でベンチマーク実行などを行うようなことをしなかったため?
  • 秒速5センチメートルは未視聴です(君の名は。は先週観ました)

twitter

昼食

260 円

f:id:nise_nabe:20160926121758j:plain:w300

とりあえず MySQL Connector/J 6.0 をビルドする

MySQL :: MySQL Connector/J 6.0 Developer Guide :: 4.4 Installing from the Development Source Tree

$ git clone -b release/6.0 git@github.com:mysql/mysql-connector-j.git

lib というディレクトリがあるので、最低限必要なものとして hibernate4 を ダウンロードしてきて展開して、中にある lib の jar を含むディレクトリをそのまま lib 以下に設置する。ant dist するだけなら hibernate4 だけがあればよさそう。(動くかは知らない)

$ tar zxvf hibernate-release-4.2.21.Final.tgz
$ ls hibernate-release-4.2.21.Final/lib
envers   jpa      optional osgi     required
$ mkdir /path/to/mysql-connector-j/lib/hibernate4
$ mv hibernate-release-4.2.21.Final/lib/* /path/to/mysql-connector-j/lib/hibernate4

ちなみに mysql-connecotor-j/lib 以下に直接展開すると関係ないファイルが邪魔してビルドに失敗する。

そして以下のように実行する。JAVA_HOME は設定されてなければ自分で設定する。

$ ant dist -Dcom.mysql.cj.build.jdk=$JAVA_HOME

Intellij IDEA 上で Ant の Run Configuration から起動する場合はなぜか文字コードが変になるので下記のように javac のところに encoding="utf8" が必要になる。

diff --git a/build.xml b/build.xml
index a6ba44c..beffab7 100644
--- a/build.xml
+++ b/build.xml
@@ -814,7 +814,8 @@ See also com.mysql.cj.core.conf.PropertyDefinitions.SYSP_* variables for other t
                fork="yes"
                executable="${com.mysql.cj.build.jdk.javac}"
                compiler="modern"
-               includeantruntime="false">
+               includeantruntime="false"
+               encoding="utf8">
             <include name="**/*.java" />
             <exclude name="testsuite/**" />
             <exclude name="com/mysql/cj/jdbc/integration/**" />

とりあえず 5.1 とは違ってちゃんとビルドできる。すばらしい。以上。

MySQL Connector/J 6.0 の Service Provider について

下記 記事は Connector/J 5.1 についての記事。

nisenabe.hatenablog.com

6.0 の場合は

$ curl -L -O https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-6.0.3.tar.gz
$ tar xvf mysql-connector-java-6.0.3.tar.gz
$ cd mysql-connector-java-6.0.3

build.xml を確認してみると下記のようになってます。

 592         <!-- JDBC 4+ support of service provider mechanism. -->
 593         <mkdir dir="${com.mysql.cj.build.dir.driver}/META-INF/services/" />
 594         <echo file="${com.mysql.cj.build.dir.driver}/META-INF/services/java.sql.Driver"
 595               message="com.mysql.cj.jdbc.Driver" />

じゃあどのドライバを使うかというのはどこで決めてるかというと ConnectionString クラスらしい。

src/main/java/com/mysql/cj/core/ConnectionString.java
 55         SINGLE_CONNECTION("jdbc:mysql://") {
 58         LOADBALANCING_CONNECTION("jdbc:mysql:loadbalance://") {
 70         FAILOVER_CONNECTION("jdbc:mysql://") {
 82         REPLICATION_CONNECTION("jdbc:mysql:replication://") {
144         FABRIC_CONNECTION("jdbc:mysql:fabric://") {
155         X_SESSION("mysql:x://") {

ちなみに 5.1 では下記のように場所がばらけているうえにわりと力技っぽく解決してるので 6.0 でだいぶ綺麗に書きなおされているらしいということがわかる。

src/com/mysql/jdbc/NonRegisteringDriver.java
 63     private static final String REPLICATION_URL_PREFIX = "jdbc:mysql:replication://";
 65     private static final String URL_PREFIX = "jdbc:mysql://";
 67     private static final String MXJ_URL_PREFIX = "jdbc:mysql:mxj://";
 69     public static final String LOADBALANCE_URL_PREFIX = "jdbc:mysql:loadbalance://";
src/com/mysql/fabric/jdbc/FabricMySQLDriver.java
 97         if (!url.startsWith("jdbc:mysql:fabric://")) {

DragonFlyBSD + letsencrypt インストールログ

環境

  • DragonFly v4.4.3-RELEASE

ログ

letsencrypt 日本語ドキュメント certbot ドキュメント

ものによっては certbot-auto とか letsencrypt-auto とかよくわからんのでまずは検索。

$ sudo pkg search letsencrypt
letsencrypt.sh-0.2.0           Pure BASH/ZSH Lets Encrypt client

https://letsencrypt.org/docs/client-options/

中身から察するにおそらくこれらしい https://github.com/lukas2511/letsencrypt.sh

$ cd /usr/local/etc/letsencrypt.sh/

とりあえず下記のものがサンプルとしてあるので .sample を消したものを設置

config.sh               domains.txt             hook.sh

今回の場合はすでに nginx + php-fpm で動いてるドメインに対して 証明書が欲しいので既存の server ディレクティブに letsencrypt.sh が作るファイルが読めるような設定を追加します。 nginx についてそんなに詳しくないので、今回は .well-known/acme-challenge 以下に来るアクセスをそのまま letsencrypt.sh が生成するディレクトリのパスにしてしまう設定にします。

  # for letsencrypt
  location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /usr/local/etc/letsencrypt.sh/.acme-challenges/;
  }

/usr/local/etc/letsencrpyt.sh/config.sh

#WELLKNOWN="${BASEDIR}/.acme-challenges"
WELLKNOWN="${BASEDIR}/.acme-challenges/.well-known/acme-challenge"

一応 nginx を再起動などしたあと、下記コマンドを実行して取得する。

# /usr/local/bin/letsencrypt.sh --cron

取得した後は下記のように設定すると良いと思います。最低限の設定しかいれてないのでもっと安全にするにはググッてください。

  listen 443 ssl;
  ssl_certificate /usr/local/etc/letsencrypt.sh/certs/example.com/fullchain.pem;
  ssl_certificate_key /usr/local/etc/letsencrypt.sh/certs/example.com/privkey.pem;

ここまででとりあえず https でアクセスできるようになると思います。

証明書の更新についてですが、インストールしたときに下記のように表示が出ますが、この通りに /etc/periodic.conf に設定を追加すると勝手に更新されるようです。まだ動作確認まではしてません。

To use this script you should copy the examples in
/usr/local/etc/letsencrypt.sh/ and at least add a
domain and a contact mail address.

You should also copy the openssl.cnf.sample file in
/usr/local/openssl so you won't get warnings about
it missing.

In order to run the script regularly to update
the certificates add this line to /etc/periodic.conf

weekly_letsencrypt_enable="YES"

Additionally the following parameters can be added to
/etc/periodic.conf

To run the certification renenewal as a different user
weekly_letsencrypt_user="_letsencrypt"
To run a script after the renewal (as root)
weekly_letsencrypt_deployscript="/usr/local/etc/letsencrypt.sh/deploy.sh"

DragonFlyBSD + owncloud インストールログ

(途中)

環境

  • DragonFly v4.4.3-RELEASE
  • nginx 1.10.0
  • PHP 7.0.6

ログ

以前に owncloud 8.2 で運用していたものを一旦動かすのと、 php7 を使いたいため pkg にあるものではなく src からインストールする。構成は nginx + php-fpm。そして news アプリを動かしたい。

https://owncloud.org/changelog/#latest8.2

とりあえず設置位置は /var/local/www 以下に置く。

# cd /usr/local/www
# curl -OJL https://download.owncloud.org/community/owncloud-8.2.5.tar.bz2
# tar xvf owncloud-8.2.5.tar.bz2

下記 URL を参考に nginx 設定をする。 https://doc.owncloud.org/server/8.0/admin_manual/installation/nginx_configuration.html

pkg から インストールしたままの nginx だとそこに nginx.conf に設定を書くしか無いのでほかの linux ディストリなどで入るように conf.d を作って include する構成にする。

(後で書く)

実際に動かすと幾つか undefined error が出るので下記で入れる。

# pkg install php70-hash php70-json php70-pdo php70-pdo_mysql php70-session php70-zip php70-dom php70-xml php70-ctype php70-gd php70-zlib php70-curl php70-xmlwriter php70-simplexml

このままだと owncloud が生成する data ディレクトリなどに書き込み権限がないので書き込み権限をなんとかする。

(後で書く)

News アプリを動かす場合。

# pkg isntall php70-iconv

あと直接エラーは出てないけど下記のものが必要かもしれない。news-updater のほうで動かした時にエラーになりました。

# pkg install php70-mbstring php70-pcntl

後始末

# rm /usr/local/www/owncloud-8.2.5.tar.bz2

ついでに owncloud 8 -> 9 の際に必要なパッケージは下記の通り。

# pkg install php70-filter

そして全部終わって cron.php を動かそうとした時には下記パッケージが必要でした。

# pkg install php70-xmlreader php70-posix php70-xmlwriter