Server was too busy and OOM Killer fired

昨日からサーバーに繋がりにくくなっていた。
サーバーに繋がらなくなった。
大方 php-fpm のプロセスがたくさん増えて swap 発生しまくってるんだろうと思った。

1vCPU に 512MB しかない VM にそんなに多くを期待してはいけない。

IP アドレスでアクセス制限かけてたからどうせ外出先からじゃアクセスできないし、戻ったら直そうと思っていた。
メールを確認しようとしたらいよいよ認証も通らなくなったので OOM Killer 発動したかと思ってさくらの VPS のコンソール上からシリアルコンソール接続して
今つないでいる IP のアクセス許可して top を見てみた。

見事に殺されている。
yum-cron のプロセスが死んでるのはいいが、 mysqld (中身は MariaDB )のプロセスまで殺されるのは勘弁してほしい。

[root@mx1 ~]# grep "Out of memory" /var/log/messages
Oct  9 07:10:09 mx1 kernel: Out of memory: Kill process 7192 (yum-cron) score 77 or sacrifice child
Oct  9 08:05:56 mx1 kernel: Out of memory: Kill process 7354 (yum-cron) score 82 or sacrifice child
Oct  9 09:17:09 mx1 kernel: Out of memory: Kill process 7493 (yum-cron) score 73 or sacrifice child
Oct  9 10:07:45 mx1 kernel: Out of memory: Kill process 6905 (mysqld) score 52 or sacrifice child

圧倒的 php-fpm のプロセス数。

OOMKillerTop

圧倒的メモリ不足。

[root@mx1 ~]# vmstat -aS m
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
 2  0   1059     70    223    140    0    0  3632    28   19   14  0  1 99  0  0

ひとまず静かにデーモンリスタート

[root@mx1 ~]# systemctl restart php-fpm

余裕が出てきた。

free

[root@mx1 ~]# vmstat -aS m
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
 2  0     70    342     87     26    0    0  3632    28   19   14  0  1 99  0  0

おしまい。

Samba ファイルサーバーの構築 (CnetOS7.2)

認証無しで共有サーバーに書き込めるのがいいと思っていたけど、しゃべる NetBIOS のプロトコルのバージョンが下がって遅くなるんだよね。
なので pdbedit で認証されているユーザじゃないと書き込めないようになっています。
ちなみに Samba のバージョンは 4 系なので Active Directory ドメインコントローラとして動作させようと思えば構築できる。

[root@phy3 samba]# yum info samba
(snip)
名前                : samba
アーキテクチャー    : x86_64
バージョン          : 4.2.10
リリース            : 6.el7_2
容量                : 1.8 M
リポジトリー        : installed
提供元リポジトリー  : updates
要約                : Server and Client software to interoperate with Windows machines
URL                 : http://www.samba.org/
ライセンス          : GPLv3+ and LGPLv3+
説明                : Samba is the standard Windows interoperability suite of programs for Linux and Unix.

Samba のインストール

sudo yum -y install samba
sudo mkdir /var/samba

自分の共有フォルダを作成

mkdir ~/samba

既存のユーザを追加

こいつで認証を通す。

sudo pdbedit -a wnoguchi
new password:
retype new password:
Unix username:        wnoguchi
NT username:
Account Flags:        [U          ]
User SID:             S-1-5-21-3726826207-3823386518-2277225043-1000
Primary Group SID:    S-1-5-21-3726826207-3823386518-2277225043-513
Full Name:            Wataru Noguchi
Home Directory:       \\phy3\wnoguchi
HomeDir Drive:
Logon Script:
Profile Path:         \\phy3\wnoguchi\profile
Domain:               PHY3
Account desc:
Workstations:
Munged dial:
Logon time:           0
Logoff time:          木, 07  2月 2036 00:06:39 JST
Kickoff time:         木, 07  2月 2036 00:06:39 JST
Password last set:    水, 04  5月 2016 10:11:26 JST
Password can change:  水, 04  5月 2016 10:11:26 JST
Password must change: never
Last bad password   : 0
Bad password count  : 0
Logon hours         : FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

共有フォルダの所有者変更

自分しか使わないけどね。。。

sudo chown nobody:nobody /var/samba

Samba の設定

  • 設定ファイルバックアップ
sudo cp -rp /etc/samba{,.orig}
  • /etc/samba/smb.conf
[global]
unix charset = UTF-8
dos charset = CP932

workgroup = MYGROUP
↓
workgroup = PG1X

アクセス許可設定

;    hosts allow = 127. 192.168.12. 192.168.13.
↓
    hosts allow = 127. 172.16. 172.17. 172.18.

プリンタ使わない
    load printers = yes
    disable spoolss = yes

[homes]
    comment = Home Directories
    path = %H/samba

    vfs objects = recycle
    recycle:repository = .recycle
    recycle:keeptree = no
    recycle:versions = yes
    recycle:touch = no
    recycle:maxsize = 0
    recycle:exclude = *.tmp ~$*

[public]
    comment = Public Stuff
    path = /var/samba
    public = yes
    writable = yes
    only guest = yes
    vfs objects = recycle
    recycle:repository = .recycle
    recycle:keeptree = no
    recycle:versions = yes
    recycle:touch = no
    recycle:maxsize = 0
    recycle:exclude = *.tmp ~$*

smb, nmb 起動

sudo systemctl start smb
sudo systemctl start nmb
sudo systemctl enable smb
sudo systemctl enable nmb

ごみ箱を定期的に空にするスクリプトを作成

1ヶ月間 = 30 日 = 30 * 24 時間 = 720 時間 アクセスのないものは完全に削除する

sudo cat <<'EOF' >/etc/cron.weekly/recyclewatch
#!/bin/bash
for user in `ls /home/`
do
  if [ -d /home/$user/.recycle ]; then
    tmpwatch -f 720 /home/$user/.recycle/
  fi
done
if [ -d /var/samba/.recycle ]; then
  tmpwatch -f 720 /var/samba/.recycle/
fi
EOF
sudo chmod 744 /etc/cron.weekly/recyclewatch

ファイアウォールの穴を開ける

sudo firewall-cmd --permanent --zone=public --add-service=samba
sudo firewall-cmd --reload

接続の仕方

認証聞かれます。

Windows の場合

\\72.16.216.3
\\72.16.216.3\public\

Mac, Linux の場合

smb://172.16.216.3/
smb://172.16.216.3/public/

トラブルシューティング

認証は通るみたいだが接続はできない。

[root@phy3 samba]# tailf /var/log/samba/log.macbookair-d7e0
[2016/05/04 11:00:01.995083,  0] ../source3/smbd/service.c:798(make_connection_snum)
  canonicalize_connect_path failed for service public, path /home/samba
[2016/05/04 11:00:01.997818,  0] ../source3/smbd/service.c:798(make_connection_snum)
  canonicalize_connect_path failed for service public, path /home/samba
[2016/05/04 11:01:04.905785,  0] ../source3/smbd/service.c:798(make_connection_snum)
  canonicalize_connect_path failed for service public, path /home/samba

Oops… 書き間違い。
そもそも存在しないディレクトリを指定していたりするとこんなエラーになる。
修正する。

[public]
    comment = Public Stuff
    path = /home/samba
↓
[public]
    comment = Public Stuff
    path = /var/samba

そしてリスタート。

sudo systemctl restart smb
sudo systemctl restart nmb

参考サイト

  1. Windowsファイルサーバー構築(Samba) – CentOSで自宅サーバー構築
  2. CentOS7にSambaをインストール | 俺的備忘録 〜なんかいろいろ〜

MariaDB 10.1 を CentOS 7.2 にインストールする

/etc/yum.repos.d/MariaDB.repo を作成する。

# MariaDB 10.1 CentOS repository list - created 2016-05-01 03:05 UTC
# http://mariadb.org/mariadb/repositories/
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.1/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
sudo yum -y install MariaDB-server MariaDB-client
sudo systemctl enable mariadb
sudo systemctl start mariadb
[root@localhost ~]# systemctl status mariadb
● mariadb.service - MariaDB database server
   Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/mariadb.service.d
           └─migrated-from-my.cnf-settings.conf
   Active: active (running) since 日 2016-05-01 03:14:18 UTC; 11s ago
 Main PID: 3783 (mysqld)
   Status: "Taking your SQL requests now..."
   CGroup: /system.slice/mariadb.service
           └─3783 /usr/sbin/mysqld

 5月 01 03:14:18 localhost.localdomain mysqld[3783]: 2016-05-01  3:14:18 140...
 5月 01 03:14:18 localhost.localdomain mysqld[3783]: 2016-05-01  3:14:18 140...
 5月 01 03:14:18 localhost.localdomain mysqld[3783]: 2016-05-01  3:14:18 140...
 5月 01 03:14:18 localhost.localdomain mysqld[3783]: 2016-05-01  3:14:18 140...
 5月 01 03:14:18 localhost.localdomain mysqld[3783]: 2016-05-01  3:14:18 140...
 5月 01 03:14:18 localhost.localdomain mysqld[3783]: 2016-05-01  3:14:18 140...
 5月 01 03:14:18 localhost.localdomain mysqld[3783]: 2016-05-01  3:14:18 140...
 5月 01 03:14:18 localhost.localdomain mysqld[3783]: 2016-05-01  3:14:18 140...
 5月 01 03:14:18 localhost.localdomain mysqld[3783]: Version: '10.1.13-Maria...
 5月 01 03:14:18 localhost.localdomain systemd[1]: Started MariaDB database ...
Hint: Some lines were ellipsized, use -l to show in full.
[root@localhost ~]# mysql -u root
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 10.1.13-MariaDB MariaDB Server

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> exit
Bye

CentOS 7.2.1511 に yum-cron 入れた

yum -y install yum-cron
systemctl start yum-cron
systemctl enable yum-cron

設定ファイル /etc/yum/yum-cron.conf はこれぐらいにしておけば OK 。

CentOS 6 時代は yum-cron を入れたら問答無用でアップデートを適用して再起動が必要だっら再起動する凶悪な仕様だったが、CentOS 7 の yum-cron はダウンロードするのみで止まるようだ。

僕は更新があったらメールを送るようにした。

apply_updates = no

#(snip)

[email]
# The address to send email messages from.
email_from = root@smtp.example.com

# List of addresses to send messages to.
email_to = username@example.com

# Name of the host to connect to to send email messages.
email_host = localhost

RedHat 系 Linux のホスト名を設定する

Vagrant とかでたくさん VM 立ち上げるときホスト名設定しないと何が何だかわからなくなるのでシェルプロビジョニングには以下の様なコマンドセットを紛れ込ませています。

7 系

HOSTNAME=from
sudo hostname $HOSTNAME
echo $HOSTNAME | sudo tee /etc/hostname

6 系

HOSTNAME=from
sudo hostname $HOSTNAME
sudo sed -i -e "s/\\(HOSTNAME=\\).*$/\\1$HOSTNAME/g" /etc/sysconfig/network

CentOS 6.5 に MySQL 5.6 をインストールする

けっこう雑です。

sudo rpm -ivh http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
sudo yum -y install mysql-community-server
sudo service mysqld start
sudo chkconfig mysqld on

以下、開発用の設定。

$ sudo mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!
In order to log into MySQL to secure it, we'll need the current
password for the root user.  If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none):
OK, successfully used password, moving on...
Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.
Set root password? [Y/n]
New password: ← rootパスワードをキーイン
Re-enter new password: ← rootパスワードをキーイン
Password updated successfully!
Reloading privilege tables..
... Success!
By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n]
... Success!
Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n] n ← リモートからの root ログインを許可しないようにしない
... skipping.
By default, MySQL comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n]
- Dropping test database...
ERROR 1008 (HY000) at line 1: Can't drop database 'test'; database doesn't exist
... Failed!  Not critical, keep moving...
- Removing privileges on test database...
... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n]
... Success!
All done!  If you've completed all of the above steps, your MySQL
installation should now be secure.
Thanks for using MySQL!
Cleaning up...

あとは Vagrant で立ち上げた時にホストマシンからアクセスできるように権限設定する。

mysql -u root -pvagrant -e "grant all privileges on *.* to 'root'@'127.0.0.1' identified by 'vagrant' with grant option"
mysql -u root -pvagrant -e "grant all privileges on *.* to 'root'@'%' identified by 'vagrant' with grant option"
mysql -u root -pvagrant -e "flush privileges"

おわり。

References

  1. MySQL :: Download MySQL Yum Repository
  2. MySQL :: A Quick Guide to Using the MySQL Yum Repository

CentOS6.5にDockerインストールしてみた

Dockerすごく流行ってるらしいから今更ながら手を付けてみた。
Vagrantでバシッときれいな環境用意できるのがほんと手軽でいいね。

今回もこれで簡単に仮想マシン用意できました。

vagrant init chef/centos-6.5
vagrant up

インストール

  • CentOS6.5 x86_64

EPEL有効にする

EPEL – FedoraProject

sudo rpm -ivh http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel/6/i386/epel-release-6-8.noarch.rpm

Dockerインストール

  • Docker(1.0.0-6.el6)

  • インストール

sudo yum install docker-io
  • Dockerのサービススタート。
sudo service docker start
Starting cgconfig service:                                 [  OK  ]
Starting docker:                                       [  OK  ]
sudo chkconfig docker on
  • Dockerがちゃんと動いていることを確認するために最新版のCentOSイメージを取得する。
[vagrant@localhost ~]$ sudo docker pull centos:latest
Pulling repository centos
1a7dc42f78ba: Download complete
511136ea3c5a: Download complete
34e94e67e63a: Download complete
  • 取得が完了したらCentOSのイメージの一覧が以下のコマンドでリストに表示されることを確認する。
[vagrant@localhost ~]$ sudo docker images centos
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              latest              1a7dc42f78ba        7 days ago          236.4 MB
  • イメージのテストをするためにbashを立ち上げてみよう。
sudo docker run -i -t centos /bin/bash

ちなみに -i はアタッチされていなくても標準入力を開いたままにしておくオプション。
-t は擬似端末(pseudo-tty)を割り当てることを意味する。
あいかわらずもやもやしている。

  -i, --interactive=false    Keep stdin open even if not attached
-t, --tty=false            Allocate a pseudo-tty

で、結果が以下。

[vagrant@localhost ~]$ sudo docker run -i -t centos /bin/bash
bash-4.2#

うん、プロンプト表示された。

実験

このままじゃ面白く無いからMySQL(クライアント)入れてみる。

bash-4.2# yum -y install mysql

当然ながらホストには全く影響がない。

[vagrant@localhost ~]$ mysql
-bash: mysql: コマンドが見つかりません
[vagrant@localhost ~]$ sudo -i
[root@localhost ~]# mysql
-bash: mysql: コマンドが見つかりません

本当はMySQLサーバ入れてみたかったんだけど、コンテナの中で

yum -y install mysql-server

すると「そんなのねぇ!」って怒られる。

mysql-server がどのリポジトリに入っているのか調べると updates リポジトリに入っていることが分かる。

[root@localhost ~]# yum info mysql-server
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: centos.mirror.secureax.com
* epel: ftp.jaist.ac.jp
* extras: centos.mirror.secureax.com
* updates: centosv4.centos.org
Available Packages
Name        : mysql-server
Arch        : x86_64
Version     : 5.1.73
Release     : 3.el6_5
Size        : 8.6 M
Repo        : updates
Summary     : The MySQL server and related files
URL         : http://www.mysql.com
License     : GPLv2 with exceptions
Description : MySQL is a multi-user, multi-threaded SQL database server. MySQL is a
: client/server implementation consisting of a server daemon (mysqld)
: and many different client programs and libraries. This package contains
: the MySQL server and some accompanying files and directories.

ホスト側をupdatesでgrepするとヒットする。

[root@localhost ~]# cat /etc/yum.repos.d/CentOS-Base.repo | grep updates
# geographically close to the client.  You should use this for CentOS updates
#released updates
[updates]
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/

コンテナ内でgrepしてもヒットする。

bash-4.2# cat /etc/yum.repos.d/CentOS-Base.repo | grep updates
# geographically close to the client.  You should use this for CentOS updates
#released updates
[updates]
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/

うーん。なんで?

決定的違いを発見。

  • ホスト
[root@localhost ~]# cat /etc/redhat-release
CentOS release 6.5 (Final)
  • コンテナ
bash-4.2# cat /etc/redhat-release
CentOS Linux release 7.0.1406 (Core)

なんじゃこりゃ。

コンテナではmariadbとか出てたし、CentOS7になってなんか変わったのだろうか。
追って色々調べよう。

とりあえず開発パッケージとか入れたりしてホストとコンテナの間で影響が無いことを確認して終了。

  • docker ps コマンドを発行してみる。

-a オプションは終了したコンテナ環境も一覧表示してくれる。

[vagrant@localhost ~]$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
59d7660a51a8        centos:latest       /bin/bash           33 minutes ago      Exited (0) 3 minutes ago                       clever_nobel

さっきのあるね。アタッチしてみよう。

[vagrant@localhost ~]$ sudo docker attach 59d7660a51a8
2014/07/16 14:30:54 You cannot attach to a stopped container, start it first

停止したコンテナはアタッチできないって言われた。では開始しよう。

[vagrant@localhost ~]$ sudo docker start 59d7660a51a8
59d7660a51a8

docker ps してみる。

[vagrant@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
59d7660a51a8        centos:latest       /bin/bash           42 minutes ago      Up 25 seconds                           clever_nobel

おお動いてる。アタッチする。

[vagrant@localhost ~]$ sudo docker attach 59d7660a51a8
bash-4.2# which gcc
/usr/bin/gcc
bash-4.2#

ちゃんと環境復元できてる!そして exit したら

[vagrant@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

でもコンテナは削除してないから

[vagrant@localhost ~]$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
59d7660a51a8        centos:latest       /bin/bash           43 minutes ago      Exited (0) 4 seconds ago                       clever_nobel

残ってる。
やばいおもしろい。

References

  1. CentOS 6.5 で Docker を使ってみる | CUBE SUGAR STORAGE
  2. CentOS – Docker Documentation