なんかかきたい

プログラミングなどの個人的なメモやサークル「ゆきいろパラソル」の情報を載せてます

AWSでAZ障害が起きたのでなるべく影響を受けない構成の考えを書いておく

AZ障害は受け入れるしかないクラウド時代のインフラ

ただの日記。 今日の昼、AWSを利用している人たちは大変だったところもあると思う。 AZの一つが丸々機能しなくなる大きなAWSの障害があり、AWSを利用して運用されていたサービスは多かれ少なかれ影響を受けることになった。

完全に雰囲気で書いてしまうが、今回のAZ障害で影響を受けたサービスは思ったより多かったように感じる。 というのもAWSではアベイラビリティーゾーンの障害は発生するものと考え、本番運用するのであれば、マルチAZ構成を取るのがベストプラクティスとされているので、 マルチAZ構成を取っていれば影響なんてないんじゃないの普通、と思ってしまうと思う。 インフラ屋さんでもそう思ってしまうし、インフラ屋さん以外ならなおさらなんで重くなるのかわからないと思う。

幸い自分の運用しているサービスでは影響が軽微だったので、完全に想像にはなってしまうけど、起こりがちなケースを考えてみる。

続きを読む

rsyncでpigzするやつ v2

普段よく使っているのでリモートからローカルにコピーする場合に使えるように機能拡張した。

ほとんど同じコードなのに共通化できなくて辛い。ifで分岐して二つのシェルスクリプトを一個にしたような作りがイケてないが使い勝手はよい。

細かい話だと rsync の出力がOSXLinuxで微妙に違うとかそういうところも吸収した。代わりに awk が必要になった。リストの取得に ./ から空行までをawkで出力する。 tailtac は消えた。

gist.github.com

便利

nginxの設定をrspecでテストする

前略。やや複雑な nginx.conf があります。

nginx の設定はたまに変更する必要がありますが、それなりに重要な位置に配置されたnginxだと設定を書き換える際に、既存の構成を壊さないか、あるいは意図した通りに動作するのか事前に調べておきたいということがあります。

本物のnginxを立ててログを調べてもよいですが、手元で再現できて、テストができると便利じゃないかということで、dockerでnginxのやや複雑な設定をテストする環境を作りました。

github.com

続きを読む

MySQLで定期的に SHOW PROCESSLIST を実行して長時間走っているクエリを探す

前略、大きいMySQLのデータベースがあります。すると、大きなデータベースから多くのデータを取得するため、非常に重いクエリが実行されることがあります。 そうするとデータベースが高負荷になるため重い処理を見つけたくなります。 (innodb_query_queued とかが増えて辛くなる)

MySQLには SHOW PROCESSLIST というものがあり、実行中のMySQLのプロセス一覧を見ることができ、 クエリの実行状況や実行時間をみることができるのでスロークエリログより便利なことがあります。 (スロークエリログはクエリが完了した場合に出力されるため実行中やクエリを中断した場合に見ることができない)

しかし、SHOW PROCESSLIST の出力は多いため毎回見るのは疲れます。そこで以下のようなスクリプトSHOW FULL PROCESSLIST の出力をフィルターすると便利です。

require 'mysql2'

MYSQL_USER = ''
MYSQL_PASS = ''
LONG_QUERY_THRESHOLD = 60

client = Mysql2::Client.new(host: 'localhost', username: MYSQL_USER, password: MYSQL_PASS)
client.query('SHOW FULL PROCESSLIST').each do |row|
  next unless row["Command"] == "Query"
  next if row["Time"] < LONG_QUERY_THRESHOLD

  puts ([Time.now] + row.values.map { |v| v.to_s&.gsub("\n", " ") }).join("\t")
end

実行コマンドがQueryかつ実行時間の閾値を超えた場合にのみ出力します。 複数回の出力をフィルターしないので、時間がかかっているクエリはなんども見ることになります。クエリに長い文字列が来ることもあるので、 実運用のことを考えるとある程度の長さで切った方がいいかもですね。

rsyncで圧縮転送したいけどpigzみたいに並列にならなくて困る

ので、tarとsshをパイプでつないで並列で圧縮しながら転送する君を作りました。

tar には指定したファイルのみをアーカイブに含める -T オプションがあるので、 rsync -nの結果をリストにして渡すことで、rsyncの対象になるファイルだけを転送できるようにしてます。

現場からは以上です。

Ansibleのテスト環境をDockerで作ると楽

以前はVagrantを使ってansibleのテスト環境は用意していたんだけど、 vagrantはsnapshotが取れる利点がありつつも、VMを使うのでちょっとというかそれなりに遅くて、 何度も実行するansibleのテスト環境にはちょっと不便だなーと思っていたのですが、 最近Dockerを使ってsshdを起動するだけの環境を用意すれば簡単にテスト環境が作れて便利だったので書いておきます。

Dockerfileを書く

ansibleを流す対象のイメージは DockerfileFROM に書いておけばよくて、 CentOSとかDebianとか好きなOSを選べばいいと思います。

Dockerfileを置いたディレクトリに id_rsa.pub を置いておくと authorized_keys にコピーされるというソリューションです。

FROM amazonlinux:latest

MAINTAINER cyrill

RUN yum install -y sudo shadow-utils
RUN useradd -g wheel ec2-user && echo "ec2-user:ec2-user" | chpasswd ;\
    mkdir /home/ec2-user/.ssh;\
    sed -i -e 's/^\(%wheel\s\+.\+\)/#\1/gi' /etc/sudoers ;\
    echo -e '\n%wheel ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
    echo -e '\nDefaults:root   !requiretty' >> /etc/sudoers && \
    echo -e '\nDefaults:%wheel !requiretty' >> /etc/sudoers
ADD id_rsa.pub /home/ec2-user/.ssh/authorized_keys
RUN yum install -y openssh-server openssh-clients && \
    ssh-keygen -q -b 1024 -N '' -t rsa -f /etc/ssh/ssh_host_rsa_key && \
    ssh-keygen -q -b 1024 -N '' -t dsa -f /etc/ssh/ssh_host_dsa_key && \
    ssh-keygen -q -b 521 -N '' -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key && \
    sed -i -r 's/.?UseDNS\syes/UseDNS no/' /etc/ssh/sshd_config && \
    sed -i -r 's/.?ChallengeResponseAuthentication.+/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config && \
    sed -i -r 's/.?PermitRootLogin.+/PermitRootLogin yes/' /etc/ssh/sshd_config && \
    echo "root:root" | chpasswd
RUN rm -rf /var/cache/yum/* && yum clean all

CMD ["/usr/sbin/sshd", "-D"]

最近気づいたんですが、AmazonLinuxのDocker Imageとか配布されてるんですね。 EC2環境のテストにも便利です。よいですね。

Makefileを書く

毎回 docker build して docker run してもいいんですが、 正直に言えばdockerのコマンドオプションは覚えやすい感じもないので、 シュッと実行できるようにMakefileを書きます。 シェルスクリプトでもいいのではというご意見もあるかなとは思いますが、 make とか make clean とかテスト環境を作ったり消したりするイメージには合ってる感じがして 割と気に入ってます。気にいらないタイプの方は他の好きなツールを使うといいと思います。

.DEFAULT: all

all: container run

container:
    docker build . -t ansible

run:
    docker run -d --name ansible -p 30022:22 ansible

attach:
    docker run -it --name ansible -p 30022:22 ansible /bin/bash

clean:
    docker stop ansible && docker rm ansible

こんな感じのMakefileを置いておいて、makeするとsshができる環境が用意されます。 テスト環境を捨てたいときは make clean して make すると最初からやり直せます。便利ですね。

ansibleのinventoryファイルを書く

docker run するとローカルでsshできる環境ができるので、 localhost:30022SSHするようにinventoryファイルを用意しておいてansibleではこれを指定して実行するようにします。

ansible-playbook -i inventory/local -K -k playbook.yml

終わりに

まあ便利なんですが、Docker環境に移行し切ったらansibleとかいらないのではとか思いつつ、まああってもいいやという感じで悩み中ですね。

お仕事ではMySQLのでかいDBをいい感じにやってるのであんまり関係ないんですが、シュッとかける話がこれくらいしかなかったので今回はこんなところで。

最近、ラ!関係の旅行で福岡と函館に行ってきたのですが、どちらも最の高という感想なので、みんなも行くといいと思います。

月末は沼津花火大会、来月はコミケ。あ、原稿やります。みんな来てくれ〜〜〜〜

現場からは以上です。