14Room

みんな泣きながらオトナになったんだ。

Ubuntu 14.04LTSから16.04.6 LTSにアップデートしてみた

下記コマンドでアップデート

sudo apt-get update
sudo apt-get upgrade

アップグレード可能かチェック

do-release-upgrade -c

アップグレード可能なら下記コマンドで実行

sudo do-release-upgrade

ついでに元々インストールされていたmysql 5.6を5.7にアップデートしました。

apt install mysql-server

んが、エラーが・・・

ERROR: Unable to start MySQL server:
2019-04-14T12:14:49.840340Z 0 [ERROR] unknown variable 'innodb_additional_mem_pool_size=2M'
2019-04-14T12:14:49.843331Z 0 [ERROR] Aborting

とりあえず、my.cnfの innodb_additional_mem_pool_size=2M の部分をコメントアウトしてから気を取り直してアップグレード。

Upgrade process completed successfully.
Checking if update is needed.
Setting up mysql-server (5.7.25-0ubuntu0.16.04.2) ...

今度はうまくいきました。

# cat /etc/issue
Ubuntu 16.04.6 LTS \n \l

# mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.25-0ubuntu0.16.04.2-log (Ubuntu)

td-agentでtemporarily failed to flush the buffer error="could not find a temporary directory" と言われたら

td-agentでログをS3にアップロードって、よくやりますよね。 でも、アップロードされないのです(TT)。

で、td-agentのログを調べたら、

temporarily failed to flush the buffer. next_retry=2016-11-11 07:26:34 +0000 error_class="ArgumentError" error="could not find a temporary directory"

なんて言われてる。バッファをフラッシュできないから、ログがS3に上がらないのは分かるけど、temporary directory ってなんだろ?w

と思って調べたら、/tmp の事らしい。

で、確認したら、この問題が起こったサーバだけパーミッションがおかしい。。。。。

ls -la /
drwxrwxrwt.  12 root root      12288 Oct 10 06:01 tmp

こうなってて欲しいのに実際は、

ls -la
drwxr-xr-x.   4 root root       4096 Oct 10 07:03 tmp

なので、パーミッションを直して、td-agentを再起動したら、無事にログがS3に送られるようになりました。

apt-get updateでAn error occurred during the signature verificationが出たときの対処法

久しぶりに apt-get update しようとしたところ、

W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://packages.treasuredata.com trusty InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 901F9177AB97ACBE

W: Failed to fetch http://packages.treasuredata.com/2/ubuntu/trusty/dists/trusty/InRelease

W: Some index files failed to download. They have been ignored, or old ones used instead.

なんてメッセージが表示されました。 どうもtreasuredataのsha1で作られたGPG keyが廃止になったのが原因で、古いGPG keyを使ってるとerrorになるようです。 なので下記の手順で古いのを消して、新しいのを入れましょう。

% apt-key del A12E206F
% curl -O https://packages.treasuredata.com/GPG-KEY-td-agent
% apt-key add GPG-KEY-td-agent

ansibleのset_factで宣言した変数は、同じset_fact内では参照できない

下記のようなplaybookを作って実行したところ、

- hosts:
  - localhost
  connection: local
  become: False
  gather_facts: False
  tasks:
  - set_fact:
      aaa="naked"
      bbb="{{ aaa }}"

undefined variableとか言われちゃって、エラーになっちゃいます。

# ansible-playbook test.yml
...
TASK [set_fact] ********************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'aaa' is undefined\n\nThe error appears to have been in '/home/naked123/test.yml': line 7, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n  - set_fact:\n    ^ here\n"}

うーん、 aaa は直前で宣言してるんだけどなぁ。 しょうがないので、下記のようにset_factを2つ使うとエラーは無くなりました。

- hosts:
  - localhost
  become: False
  gather_facts: False
  connection: local
  tasks:
  - set_fact:
      aaa="naked"

  - set_fact:
      bbb="{{ aaa }}"

かっこ悪いなぁ。

githubに登録したpublic keyが分からなくなったら

仮の話ですが、例えばgithubに登録していたSSHのprivate keyが外部に流出しちゃった場合は早急にその鍵を使えなくする必要があると思うのですが、たくさん登録してたりすると、どれが流出したprivate keyと対になるpublic keyなのか分からない事があります。(いや、普通は無いと思うのですけどね)

そんな時は下記のようにフィンガープリントを出力して、githubに設定してあるpublic keyの値と比べてみましょう。

$ ssh-keygen -E md5 -lf id_rsa
2048 MD5:xx:yy:zz:ac:cd:de:9a:ad:bb:5c:fc:0d:55:bd:f0:21 naked@local (RSA)

この xx:yy:zz:ac:cd:de:9a:ad:bb:5c:fc:0d:55:bd:f0:21 がフィンガープリントです。

docker execでパイプ「|」を含んだコマンドを実行させたい。

題名のままなのですが、docker execでパイプ「|」を含んだコマンドを実行させたい状況が発生しました。

例えばdockerで動くpostgresに対して、下記のようなコマンドでデータをリストアしようとした場合です。

docker exec postgres_container gunzip -c backup.gz | psql -U postgres mydb

しかし、このまま実行すると、パイプから後のコマンド( psql -U postgres mydb ) はコンテナ内のコマンドではなく、dockerが動いてるホストマシン上のコマンドと認識されてしまい、意図した通りに動きません。

そこで、こんな時は下記のようにsh -c を使うとうまくいきます。

docker exec postgres_container sh -c "gunzip -c backup.gz | psql -U postgres mydb"

単純にダブルクォートで囲んだだけでは上手く行かないところが落とし穴ですね。

参考にしたページ

docs.docker.com

td-agentでログをS3に送る、ついでに暗号化もする。

概要

ある程度の規模になると、日々サーバ上に溜まるログを何処かに集約したくなります。 オートスケールなどを利用するとサーバ停止時にログも一緒に失われるので、サーバ上のストレージ以外の場所に待避した方が良さそうです。 今なら安価で安全なS3に置くのが吉でしょう。また昨今、セキュリティ的に暗号化の機運が高まって来てる?のでS3に置く際に暗号化もしてみました。

td-agentの設定

td-agentのインストールは割愛します。あとログを送る側のサーバはIAM roleでS3のバケツへのフルアクセス権限があるものとします。

<source>
  type tail
  format none
  path /var/log/audit/audit.log
  pos_file /var/tmp/td-agent/aws_s3_logs.audit.audit.pos
  tag aws_s3_logs.audit.audit
  @label @raw
</source>


<label @raw>
  <match aws_s3_logs.**>
      type forest
      subtype s3
      <template>
        format single_value
        s3_bucket "server-logs-naked-com"
        s3_region "#{`curl -s -m 1 http://169.254.169.254/latest/meta-data/placement/availability-zone`.chop}"
        s3_object_key_format "%{path}.%{time_slice}.%{index}.%{file_extension}"
        path "${tag_parts[1]}/%Y/%m/%d/${tag_parts[1]}.${tag_parts[2]}.#{`hostname -s`.chomp}.#{`curl -s -m 1 http://169.254.169.254/latest/meta-data/instance-id`.chomp}"
        time_slice_format "%Y%m%dT%H00Z"
        time_slice_wait 10m
        use_server_side_encryption AES256
        utc
        buffer_type file
        buffer_path "/var/tmp/td-agent/s3.${tag}"
        buffer_chunk_limit 128m
        disable_retry_limit true
      </template>
  </match>
</label>

結果

f:id:naked123:20170522100412p:plain 実際にS3に置かれたログファイルのプロパティを見ると暗号化されたことが確認できる。