aoishiの備忘録

備忘録

CentOS7のtcpdumpでインターフェースを指定しないとエラーになる

はじめに

CentOS7のtcpdumpで、ネットワークインターフェースを明示的に指定しない場合に下記のメッセージが出力されたので、その際に対応したことをまとめます。

$ sudo tcpdump
tcpdump: packet printing is not supported for link type NFLOG: use -w

環境

tcpdumpがエラーになった原因

tcpdumpはネットワークインターフェースが指定されなかった場合、インターフェース一覧の先頭のものに対して動作するようです。

利用可能なネットワークインターフェース一覧は、下記コマンドで確認できます。

$ sudo tcpdump -D
1.nflog (Linux netfilter log (NFLOG) interface)
2.nfqueue (Linux netfilter queue (NFQUEUE) interface)
3.usbmon1 (USB bus number 1)
4.usbmon2 (USB bus number 2)
5.ens160
6.any (Pseudo-device that captures on all interfaces)
7.lo [Loopback]

このため、1. のnflogというインターフェースで動作しており、このインターフェースでtcpdumpしようとしたことでエラーとなっていたようです。

なお上記の仕様については、manコマンドで確認できます。

$ man tcpdump
~~~
-i interface
--interface=interface
       Listen on interface.  If unspecified, tcpdump searches the sys‐
       tem  interface  list  for  the  lowest  numbered, configured up
       interface (excluding loopback), which may turn out to  be,  for
       example, ``eth0''.

       On  Linux systems with 2.2 or later kernels, an interface argu‐
       ment of ``any'' can be used to capture packets from all  inter‐
       faces.   Note  that  captures on the ``any'' device will not be
       done in promiscuous mode.

       If the -D flag is supported, an interface number as printed  by
       that  flag  can be used as the interface argument, if no inter‐
       face on the system has that number as a name.
~~~

tcpdumpでインターフェースを指定する方法

今回確認したかったのは、ens160(CentOS7では一般的?)なので、インターフェース名か一覧の番号を指定してtcpdumpし直します。

$ sudo tcpdump -i ens160
or 
$ sudo tcpdump -i 5

また、manの説明にもありましたが、anyを指定すると全インターフェースに対して動作させることができるようです。

$ sudo tcpdump -i any

まとめ

CentOS7のtcpdumpでインターフェースを明示的にしないことで発生したメッセージに対する対応方法をまとめてみました。

普段何気なく使っているtcpdumpですが、改めてmanを読むと新たな気づきとか勉強になることが沢山ありますね。

参考

��2898 CentOS7のtcpdumpがなにやらおかしい - Web Patio - CentOSで自宅サーバー構築

ThinkPad X1 Carbon 2017のFedora26をFedora27にアップグレード

はじめに

ThinkPad X1 Carbon 2017にインストールしていたFedora26をFedora27にアップグレードしてみました。

基本的には下記の公式ページのアップグレード手順に従って勧めましたが、やったことをまとめておきます。

https://fedoraproject.org/wiki/DNF_system_upgrade

環境

手順

バックアップ取得

万が一の場合に備えてバックアップを取得します。

  • プログラムコードはGithubとかに退避する
  • その他ファイルはGoogleドライブ、Dropboxに退避する

起動できなくなった場合は、Liveイメージで起動して/homeディレクトリ配下を回収すればいいかな〜ぐらいで思っているので程々にバックアップしておきます。

私の場合はAnsibleでセットアップ手順をコード化してGithubリポジトリ管理しているので、最悪の場合再セットアップできるだろう!ぐらいの気持ちでやっています。

Fedora27のLiveイメージDVDを作成する

アップグレードする前に、Fedora27のLiveイメージで起動して動作確認するためにLiveイメージDVDを作成します。

下記からFedora27 64bitのLiveイメージをダウンロードします。

getfedora.org

ダウンロードできたら、ISOイメージをDVDに書き込みます。 今回はCLIでやってみます。

まず、wodimコマンドをインストールします。

$ sudo dnf install wodim

インストールしたwodimコマンドで、現在認識されているドライブを表示させます。 事前にCD/DVDドライブを接続して、空のディスクを挿入しておいてください。

$ wodim --devices
wodim: Overview of accessible drives (1 found) :
-------------------------------------------------------------------------
 0  dev='/dev/sr0'  rwrw-- : 'HL-DT-ST' 'DVD-RAM GSA-H55N'
-------------------------------------------------------------------------

上記で確認できたドライブをdevオプションで指定して、ダウンロードしたISOイメージを書き込みます。

$ wodim -v dev=/dev/sr0 speed=4 -eject ~/Downloads/Fedora-Workstation-Live-x86_64-27-1.6.iso

私の環境では6分ぐらいで書き込み完了しました。 なお、-ejectオプションをつけると書き込み完了時に自動的にドライブからDVDが取り出されます。

Fedora27のLiveイメージで起動して動作確認する

先ほど作成したFedora27のLiveイメージDVDで、アップグレード対象のPCを起動します。 誤って、クリーンインストールしてしまわないよう注意してください。

下記の観点で簡単に動作確認します。

Fedora26でできていたことは問題なくできて、ThinkPadの売りである赤ポチやトラックパッドの動作も変わりなくスムーズでしたので安心しました。

Fedora26では、トラックパッドでのピンチアウト/インによる拡大/縮小ができなかったので、アップグレードによってできるようになったかなと期待しましたが、こちらは相変わらずダメでした。

アップグレードを進めるために、PCを再起動してFedora26で起動させておきます。

Fedora27へのアップグレード

まず、現在のバージョンでアップデート可能なパッケージを適用します。

$ sudo dnf upgrade --refresh
Copr repo for PyCharm owned by phracek                                                                  60 kB/s |  49 kB     00:00    
メタデータの期限切れの確認は、0:00:00 時間前の 2017年11月25日 15時13分11秒 に実施しました。
依存性が解決されました。
行うべき処理がありません。
完了しました!

Kernelに更新があった場合は、ここで一度再起動したほうが良いようです。 今回は特に更新がなかったため、再起動していません。

次に、dnf-plugin-system-upgradeパッケージをインストールします。

$ sudo dnf install dnf-plugin-system-upgrade
メタデータの期限切れの確認は、0:02:57 時間前の 2017年11月25日 15時13分11秒 に実施しました。
依存性が解決されました。
=======================================================================================================================================
 パッケージ                                        アーキテクチャ         バージョン                     リポジトリ              サイズ
=======================================================================================================================================
インストール:
 python3-dnf-plugin-system-upgrade                 noarch                 2.0.3-1.fc26                   updates                  34 k
依存関係のインストール:
 python3-dnf-plugins-extras-common                 noarch                 2.0.3-1.fc26                   updates                  58 k

トランザクションの要約
=======================================================================================================================================
インストール  2 パッケージ

実際にはインストールされるパッケージ名が違うようですね。 あまり気にせず進みます。

Fedora27に更新するためのパッケージをダウンロードします。

$ sudo dnf system-upgrade download --refresh --releasever=27

Fedora27へアップグレードします。 これにより、直ちにOSが再起動されてアップグレードが開始されます。

$ sudo dnf system-upgrade reboot

下記は、アップグレード後のバージョン確認結果です。

f:id:akihisa_oishi:20171125205026p:plain

Fedora26からFedora27にアップグレードして気づいた点

ibus-mozcで日本語入力ができなくなった

日本語入力にibus-mozcを使っていましたが、アップグレード後に日本語入力ができなくなりました。 半角/全角で切り替えても日本語入力できない状態です。

とりあえず、ibus-mozc関係のセットアップをAnsible化していたのでdry-runすることにしました。 Ansibleのコードは下記です。

- name: install ibus-mozc
  dnf:
    name: ibus-mozc
    state: present

- name: deploy /usr/share/ibus/component/mozc.xml
  template:
    src: usr/share/ibus/component/mozc.xml.j2
    dest: /usr/share/ibus/component/mozc.xml

下記がdry-runの結果です。layoutがjp -> defaultに変わってしまっているため、Fedora27へのアップグレードにより設定ファイルが初期状態に戻ってしまっているようでした。

TASK [deploy /usr/share/ibus/component/mozc.xml] *************************************************************************************************************
--- before: /usr/share/ibus/component/mozc.xml
+++ after: /tmp/tmpk3mzLv/mozc.xml.j2
@@ -16,7 +16,7 @@
   <icon_prop_key>InputMode</icon_prop_key>
   <icon>/usr/share/ibus-mozc/product_icon.png</icon>
   <setup>/usr/libexec/mozc/mozc_tool --mode=config_dialog</setup>
-  <layout>default</layout>
+  <layout>jp</layout>
   <name>mozc-jp</name>
   <longname>Mozc</longname>
 </engine>

changed: [localhost]

Ansibleを実行してファイルを書き換えて再起動(再ログインだけでも良いかも)したところ、無事日本語入力できるようになりました。

ThinkPad X1 CarbonのQWHD解像度が使いやすくなった

Fedora26でThinkPad X1 CarbonのWQHD解像度を有効にすると、ウィンドウのタイトルやGNOME Tweak Toolなど一部のアプリケーションの文字が極端に大きくなり、全体的にバランスが悪かったためFullHD解像度を使っていました。

Fedora27へのアップグレードに再度WQHD解像度を試したところ、文字サイズの問題が解消されて全体的なバランスが良くなったため現在は有効化して使っています。

まとめ

Fedora26からFedora27へのアップグレード手順をまとめてみました。

こんなところでも、Ansibleでセットアップ手順をコード化していたことが役立ってしまったので、コード化重要だなと改めて感じました。

これまではクリーンインストールしたり、さくっとアップグレードしてしまって記録に残さないことが多かったで、今回まとめた内容が次回のアップグレードに活かせたら良いなと思います。

GNOME3でウィンドウを画面の四隅に移動またはサイズ調整する

はじめに

Fedora26で標準のデスクトップマネージャであるGNOME3を使っていますが、Windows10のようにウィンドウをドラッグして画面の四隅に寄せることで画面の1/4サイズに調整させるようなことを実現してみたくて方法を調査してみました。

環境

方法

GNOME3のedge-tilingを有効化する

GNOMEの設定でedge-tilingを有効化することで、画面左右へのドラッグで1/2サイズでの調整ができ、画面上部へのドラッグで最大化ができます。 私の環境では何度か設定変更してしまっているためわかりませんが、デフォルトで有効化されているかもしれません。

下記コマンドで現状の設定が確認できます。

$ gsettings get org.gnome.shell.overrides edge-tiling
true

また、下記コマンドで有効化と無効化できます。

[有効化]
$ gsettings set org.gnome.shell.overrides edge-tiling true 

[無効化]
$ gsettings set org.gnome.shell.overrides edge-tiling false

ただし、この方法では画面四隅へドラッグして1/4サイズで調整することができません。

後述するGNOME拡張機能のShellTileでedge-tilingと同等以上のことができますので、私の環境ではedge-tilingは無効化しています。

GNOME拡張機能 gTile を使う

gTile - GNOME Shell Extensions

ウィンドウをドラッグして調整するような使い方はできませんが、画面を8x6, 6x4, 4x4のセルに区切り、セル単位でのウィンドウ配置または複数セルを組み合わせたウィンドウサイズの調整ができます。 私の環境ではgTileメニューを表示するショートカットキーを Super + Enter に設定して使っています。もしかしたらデフォルト設定かもしれません。

GNOME拡張機能 ShellTile を使う

ShellTile - GNOME Shell Extensions

ウィンドウを画面の上下左右、四隅付近にドラッグすることで、1/2サイズ、1/4サイズでウィンドウを調整することができます。ただ、画面上部にドラッグする場合に限り全画面になるようです。

まとめ

GNOME3環境でウィンドウを四隅に調整する方法をまとめてみました。 人によって使い心地が違うと思うので、実際に使ってみるのが良いと思います。

私の環境ではedge-tilingを無効化し、gTileとShellTileを有効化して組み合わせて使っています。

CircleCI 2.0でDjangoの自動テスト環境を構築する

はじめに

Djangoで作成したWebアプリケーションをCircle CI2.0で自動テストできるようにしてみました。#

環境

また、事前に下記が済んでいることを前提とします。

方法

CI環境用のDjango設定ファイル作成

CircleCI環境用のDjangoの設定ファイルを作成します。

ここでは、mysite/settings/ci.pyにCircleCI環境用の設定を作成し、 下記のように設定ファイルを切り替えてDjangoの管理コマンドを実行できるようにします。

python manage.py makemigrations --settings mysite.settings.ci
python manage.py migrate        --settings mysite.settings.ci
python manage.py test           --settings mysite.settings.ci
python manage.py runserver      --settings mysite.settings.ci

Djangosettings.pyの分割と構造化については下記を参考にしています。

tokibito.hatenablog.com

基本的な設定はmysite/settings/base.pyに記載しておき、下記のようにmysite/settings/ci.py内でimportしてDATABASESなど環境依存な箇所の設定を書き換えます。

from mysite.settings.base import *

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

WSGI_APPLICATION = 'mysite.wsgi.develop.application'

ALLOWED_HOSTS = ['*']

# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
import pymysql
pymysql.install_as_MySQLdb()
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'circle_test',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'OPTIONS': {
            'charset': 'utf8mb4',
        },
    }
}

CircleCIの設定ファイル作成

.circleci/config.ymlに下記の内容でファイルを作成します。

設定ファイルの記載方法や、コンテナイメージについては下記を参考にします。

CircleCIが用意しているイメージ以外も利用可能なようです。

# CircleCI 2.0 を利用する
version: 2
jobs:
  build:

    # Dockerコンテナを利用する
    docker:

      # 後続に記載するstepsを実行するメインとなるDockerコンテナを指定する
      - image: circleci/python:3.6.1

      # 上記のメインとなるDockerコンテナが依存するDockerコンテナを指定する(Databaseなど)
      - image: circleci/mysql:5.7
        command: |
          mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
        environment:
          MYSQL_DATABASE: circle_test
          MYSQL_USER: root
          MYSQL_ROOT_HOST: "%"
          MYSQL_ALLOW_EMPTY_PASSWORD: yes

    working_directory: ~/repo

    steps:
      # リポジトリのコードを working_directory にチェックアウト
      - checkout

      # requirements.txtに変更がなければ、以前作成したPython仮想環境を復元
      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "requirements.txt" }}
          # fallback to using the latest cache if no exact match is found
          - v1-dependencies-

      # 現在のrequirements.txtに基づきPython仮想環境を作成または更新
      - run:
          name: install dependencies
          command: |
            python3 -m venv venv
            . venv/bin/activate
            pip install -r requirements.txt

      # Python仮想環境を保管
      - save_cache:
          paths:
            - ./venv
          key: v1-dependencies-{{ checksum "requirements.txt" }}

      # dockerizeのインストール
      - run:
          name: install dockerize
          command: |
            [ ! -f /usr/local/bin/dockerize ] && wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
            true
          environment:
            DOCKERIZE_VERSION: v0.5.0

      # mysqlコンテナの起動待機
      - run:
          name: Wait for db
          command: dockerize -wait tcp://localhost:3306 -timeout 1m

      # データベースのテーブルの作成などの初期化(データベースはコンテナ初期化時に作成される)
      - run:
          name: initialize db
          command: |
            . venv/bin/activate
            python manage.py makemigrations --settings mysite.settings.ci
            python manage.py migrate        --settings mysite.settings.ci

      # テストの実行
      - run:
          name: run tests
          command: |
            . venv/bin/activate
            python manage.py test --settings mysite.settings.ci

      # テスト結果の報告
      - store_artifacts:
          path: test-reports
          destination: test-reports

リポジトリへpushして自動テスト実行

上記の内容をGithubリポジトリにpushすることで、CircleCIがフックされ.circleci/config.ymlに応じたテストが自動実行されます。

下記のように、stepsの内容が実行時間とともに一覧で表示されます。

f:id:akihisa_oishi:20171112183819p:plain

また、各ステップの箇所の実行結果が確認できます。下記はrun testsの実行結果になります。 まだテストを書いていないので何も表示されていません。

f:id:akihisa_oishi:20171112215205p:plain

まとめ

CircleCI 2.0でDjangoの自動テスト環境を構築してみました。

下記は課題として追加調査して内容更新します。

  • CircleCIで自動テストが実行されるブランチを指定・制限する。

DockerでDjangoの開発環境を作成する(Quickstart: Compose and DjangoのMySQL版)

はじめに

Dockerの公式ページにDocker Composeを使った簡単なDjango/PostgreSQLの環境構築のチュートリアルがあります。

docs.docker.com

普段からMySQLを使うことが多いので、PostgreSQLの代わりにMySQLを使ってチュートリアルをやってみました。

環境

  • OS: Fedora 26
  • Docker: Docker version 1.13.1, build b5e3294/1.13.1
  • Docker Compose: docker-compose version 1.16.1, build 6d1ac219
  • MySQL設定
    • データベース名: django
    • データベース文字コード: utf8mb4
    • データベースコレーション: utf8mb4_general_ci
    • ユーザ名: django
    • ユーザ接続元ホスト: %
    • パスワード: P@ssw0rd_django
    • ポート: 3306

元ネタと違う点

  • データベースをPostgreSQLからMySQLに変更しています。
  • Python実行環境のイメージをデフォルトからalpineに変更しています。

手順

プロジェクト用ディレクトリの作成と移動

適当なプロジェクト用ディレクトリを作成します。

$ mkdir -p ~/working/docker_test/django_mysql
$ cd ~/working/docker_test/django_mysql

各種ファイル作成

Dockerfile

$ cat <<EOF > Dockerfile
FROM python:3-alpine
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
EOF

requirements.txt

$ cat <<EOF > requirements.txt
Django>=1.8,<2.0
PyMySQL
EOF

DB初期化用SQLファイル

$ mkdir sql
$ cat <<EOF > sql/001_setup_application_database.sql
CREATE DATABASE IF NOT EXISTS django CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER IF NOT EXISTS 'django'@'%' IDENTIFIED BY 'P@ssw0rd_django';
GRANT ALL PRIVILEGES ON django.* TO 'django'@'%';
EOF

docker-compose.yml

dbコンテナの起動前にDjango開発サーバが起動してしまうことがあったため、webコンテナのcommandにsleepを追加しています。

$ cat <<EOF > docker-compose.yml
version: '3'

services:

  # https://hub.docker.com/r/mysql/mysql-server/
  db:
    image: mysql/mysql-server:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=P@ssw0rd
      - MYSQL_ROOT_HOST=%
    volumes:
      - ./db-datadir:/var/lib/mysql
      - ./sql:/docker-entrypoint-initdb.d
    ports:
      - "3306:3306"

  web:
    build: .
    command: sh -c "sleep 3; ./manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
EOF

DBの初期化

dbコンテナをバックグランドで起動して、MySQLのデータベースを初期構築します。

このとき、コンテナ側の/var/lib/mysqlにホスト側の./db-datadirがマッピングされ、db-datadirが空であれば初期化されてMySQLデータディレクトリ相当のファイルが生成されます。

$ docker-compose up -d db

$ ls -al db-datadir

元ネタのチュートリアルでは、この段階ではdbコンテナは起動しておらず、次のDjangoプロジェクト作成時にwebコンテナと一緒に起動させています。

しかし、今回はMySQLを利用して初回起動後にデータベースやユーザを作成したりMySQLの起動に時間がかかることもあり、webとdbを一緒に初回起動してしまうとDjangoからMySQLへの接続に失敗してしまうことがあったため、先にdbコンテナだけ起動させています。

Djangoプロジェクトの作成

webコンテナを起動して、Djangoプロジェクトを作成します。

$ sudo docker-compose run web django-admin.py startproject mysite .

私の環境ではsudoをつけないとwebコンテナビルド時にエラーで失敗してしまいました。 下記が発生したエラーの内容です。

Building web
ERROR: Error processing tar file(exit status 1): time="2017-11-04T17:24:03+09:00" level=info msg="SUSE:secrets :: enabled"
unexpected EOF

権限の変更

コンテナ側で作成されたMySQLのデータディレクトリやDjangoプロジェクトのファイルはrootユーザで作成されるため、所有者をホスト側のユーザに変更します。

$ sudo chown -R $USER:$USER mysite manage.py

MySQLのデータディレクトリにマッピングするdb-datadirも含めて所有者を変更してしまうと、DjangoからMySQL接続する際に下記のエラーが発生しますので注意してください。

django.db.utils.InternalError: (1018, "Can't read dir of './django/' (errno: 13 - Permission denied)")

settings.py の編集

webコンテナ内のDjangoプロジェクトからdbコンテナ内のMySQLに接続するために、settings.pyのDATABASESを書き換えます。

$ vi mysite/settings.py

---
import pymysql
pymysql.install_as_MySQLdb()
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',
        'USER': 'django',
        'PASSWORD': 'P@ssw0rd_django',
        'HOST': 'db',
        'PORT': 3306,
        'OPTIONS': {
            'charset': 'utf8mb4',
        },
    }
}
---

DBマイグレーション

Djangoのデフォルトアプリケーションのテーブルを作成します。 デフォルト以外のアプリケーションが追加されていないのであれば、makemigrationsは不要です。

$ docker-compose run web ./manage.py makemigrations
$ docker-compose run web ./manage.py migrate

管理者ユーザの作成

Django管理サイトにログインするためのスーパーユーザを作成します。

$ docker-compose run web ./manage.py createsuperuser --username admin --email admin@localhost

[自動化する場合]
$ docker-compose run web ./manage.py shell -c "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@localhost', 'admin')"

Django開発サーバの起動

webコンテナをdocker-composeで起動し、Djangoの開発サーバを起動します。

$ docker-compose up -d

ブラウザで動作確認

下記URLにアクセスして、作成したスーパーユーザで管理サイトにログインできることを確認します。

http://localhost:8000/admin

その他参考手順

バックグラウンドで起動したコンテナの出力を確認

フォアグラウンドで起動した際に出力されるログを表示させます。

[すべてのコンテナ]
$ docker-compose logs -tf

[webのみ]
$ docker-compose logs -tf web

[dbのみ]
$ docker-compose logs -tf db

DBを作成し直す場合の手順

$ docker-compose down
$ sudo rm -rf db-datadir
$ docker-compose up -d db
$ docker-compose run web ./manage.py makemigrations
$ docker-compose run web ./manage.py migrate
$ docker-compose run web ./manage.py shell -c "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@localhost', 'admin')"
$ docker-compose up -d

Dockerコンテナ、イメージ削除一括方法

$ docker container rm $(docker container ls -q)
$ docker image rm $(docker image ls -q)

まとめ

Dockerの公式ページのDjangoチュートリアルMySQL版をやってみました。

次は、ApahceかNginxでプロキシサーバを追加し、uWSGIでDjangoを起動させてよりプロダクション環境に近い構成を作ってみたいと思います。

参考

今回利用したDockerImage

ESXi上の仮想マシンでLVMのXFSファイルシステムを拡張する

はじめに

ESXi上の仮想マシンで、ディスク拡張してLVMのXFSファイルシステムを拡張したときのメモです。

環境

  • ESXi 6.0.0 Update 2 (Build 3620759)
  • VMware Host Client 1.23.0 (Build 6360286)

拡張対象

OS パーティション 論理ボリューム マウントパス ファイルシステム
CentOS 7.4 /dev/sda2 /dev/mapper/cl-root / xfs

現状確認

LVM

LVMのの構成を確認します。

今回は物理ボリュームが1つあり、そこからボリュームグループが1つ作成されており、さらのそのボリュームグループから/とswap用の論理ボリュームが作成されていることがわかります。

# export LANG=C

# pvs
  PV         VG Fmt  Attr PSize   PFree
  /dev/sda2  cl lvm2 a--  <99.00g    0 

# vgs
  VG #PV #LV #SN Attr   VSize   VFree
  cl   1   2   0 wz--n- <99.00g    0 

# lvs
  LV   VG Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root cl -wi-ao---- <94.00g                                                    
  swap cl -wi-ao----   5.00g

ディスク

作業前の情報を取得し忘れてしまいましたが、事前にfdiskコマンドで確認しておきましょう。

# fdiks -l

マウント

今回の拡張したいのは/配下です。論理ボリューム名とファイルシステムが確認できますね。

# df -PT
Filesystem          Type     1024-blocks     Used Available Capacity Mounted on
/dev/mapper/cl-root xfs         98539524 98020788    518736     100% /
devtmpfs            devtmpfs     3994444        0   3994444       0% /dev
tmpfs               tmpfs        4005420        0   4005420       0% /dev/shm
tmpfs               tmpfs        4005420     8840   3996580       1% /run
tmpfs               tmpfs        4005420        0   4005420       0% /sys/fs/cgroup
/dev/sda1           xfs          1038336   189676    848660      19% /boot
tmpfs               tmpfs         801084        0    801084       0% /run/user/55557
tmpfs               tmpfs         801084        0    801084       0% /run/user/55556

手順

ESXiで対象ディスクを拡張する

VMware Host Client経由で対象ディスクを拡張します。 この作業は仮想マシンを停止することなくできますが、OS上での認識はOS再起動が必要でした。

なお、仮想マシンSCSIドライバは「LSI Logic Parallel」でしたので、準仮想ドライバを使えばOS再起動することなく認識できるのかもしれません。

仮想マシンをOS再起動する

ESXiで拡張されたディスクを認識させるために、OS再起動します。

# reboot

ディスク認識状態の確認

もともと100GBのディスクでしたが、ESXiで拡張して200GBにしました。 OSでは214GBと若干大きめのサイズが表示されていますが、拡張されていることは確認できました。

# fdisk -l

Disk /dev/sda: 214.7 GB, 214748364800 bytes, 419430400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x000b15fd

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200   209715199   103808000   8e  Linux LVM

Disk /dev/mapper/cl-root: 100.9 GB, 100927537152 bytes, 197124096 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト


Disk /dev/mapper/cl-swap: 5368 MB, 5368709120 bytes, 10485760 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト

パーティションの拡張

拡張対象のパーティション情報を一度削除し、新しいサイズでパーティションを定義することでパーティションを拡張します。

下記コマンドでパーティションを再作成した際に、/dev/sda2のStartは変化せずにEndとBlocksのみが変化することを確認してください。ESXiでのディスク拡張によりディスク後方に空きブロックが発生するので、そこを新しいパーティションで含めるようにしています。

# fdisk /dev/sda
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): m
Command action
   a   toggle a bootable flag
   b   edit bsd disklabel
   c   toggle the dos compatibility flag
   d   delete a partition
   g   create a new empty GPT partition table
   G   create an IRIX (SGI) partition table
   l   list known partition types
   m   print this menu
   n   add a new partition
   o   create a new empty DOS partition table
   p   print the partition table
   q   quit without saving changes
   s   create a new empty Sun disklabel
   t   change a partition's system id
   u   change display/entry units
   v   verify the partition table
   w   write table to disk and exit
   x   extra functionality (experts only)

Command (m for help): p

Disk /dev/sda: 214.7 GB, 214748364800 bytes, 419430400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000b15fd

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200   209715199   103808000   8e  Linux LVM

Command (m for help): d
Partition number (1,2, default 2): 2
Partition 2 is deleted

Command (m for help): p

Disk /dev/sda: 214.7 GB, 214748364800 bytes, 419430400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000b15fd

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     2099199     1048576   83  Linux

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (2-4, default 2): 2
First sector (2099200-419430399, default 2099200): 
Using default value 2099200
Last sector, +sectors or +size{K,M,G} (2099200-419430399, default 419430399): 
Using default value 419430399
Partition 2 of type Linux and of size 199 GiB is set

Command (m for help): p

Disk /dev/sda: 214.7 GB, 214748364800 bytes, 419430400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000b15fd

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200   419430399   208665600   83  Linux

Command (m for help): t
Partition number (1,2, default 2): 2
Hex code (type L to list all codes): L

 0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris        
 1  FAT12           27  Hidden NTFS Win 82  Linux swap / So c1  DRDOS/sec (FAT-
 2  XENIX root      39  Plan 9          83  Linux           c4  DRDOS/sec (FAT-
 3  XENIX usr       3c  PartitionMagic  84  OS/2 hidden C:  c6  DRDOS/sec (FAT-
 4  FAT16 <32M      40  Venix 80286     85  Linux extended  c7  Syrinx         
 5  Extended        41  PPC PReP Boot   86  NTFS volume set da  Non-FS data    
 6  FAT16           42  SFS             87  NTFS volume set db  CP/M / CTOS / .
 7  HPFS/NTFS/exFAT 4d  QNX4.x          88  Linux plaintext de  Dell Utility   
 8  AIX             4e  QNX4.x 2nd part 8e  Linux LVM       df  BootIt         
 9  AIX bootable    4f  QNX4.x 3rd part 93  Amoeba          e1  DOS access     
 a  OS/2 Boot Manag 50  OnTrack DM      94  Amoeba BBT      e3  DOS R/O        
 b  W95 FAT32       51  OnTrack DM6 Aux 9f  BSD/OS          e4  SpeedStor      
 c  W95 FAT32 (LBA) 52  CP/M            a0  IBM Thinkpad hi eb  BeOS fs        
 e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a5  FreeBSD         ee  GPT            
 f  W95 Ext'd (LBA) 54  OnTrackDM6      a6  OpenBSD         ef  EFI (FAT-12/16/
10  OPUS            55  EZ-Drive        a7  NeXTSTEP        f0  Linux/PA-RISC b
11  Hidden FAT12    56  Golden Bow      a8  Darwin UFS      f1  SpeedStor      
12  Compaq diagnost 5c  Priam Edisk     a9  NetBSD          f4  SpeedStor      
14  Hidden FAT16 <3 61  SpeedStor       ab  Darwin boot     f2  DOS secondary  
16  Hidden FAT16    63  GNU HURD or Sys af  HFS / HFS+      fb  VMware VMFS    
17  Hidden HPFS/NTF 64  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE 
18  AST SmartSleep  65  Novell Netware  b8  BSDI swap       fd  Linux raid auto
1b  Hidden W95 FAT3 70  DiskSecure Mult bb  Boot Wizard hid fe  LANstep        
1c  Hidden W95 FAT3 75  PC/IX           be  Solaris boot    ff  BBT            
1e  Hidden W95 FAT1 80  Old Minix      
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'

Command (m for help): p

Disk /dev/sda: 214.7 GB, 214748364800 bytes, 419430400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000b15fd

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200   419430399   208665600   8e  Linux LVM

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.

ここで、OSに新しいパーティション情報を認識させるためにOS再起動します。

# reboot

上記のWARNINGに記載の通り、partprobeやkpartxコマンドを使うことでOS再起動不要かもしれません。

物理ボリュームの拡張

物理ボリュームを拡張し、新しいパーティションの全ブロックをLVMで使えるようにします。

# pvs
  PV         VG Fmt  Attr PSize   PFree
  /dev/sda2  cl lvm2 a--  <99.00g    0 

# pvresize /dev/sda2
  Physical volume "/dev/sda2" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized

# pvs
  PV         VG Fmt  Attr PSize    PFree  
  /dev/sda2  cl lvm2 a--  <199.00g 100.00g

ボリュームグループの確認

物理ボリュームが拡張されたことで、ボリュームグループに空き領域ができたことを確認します。

# vgs
  VG #PV #LV #SN Attr   VSize    VFree  
  cl   1   2   0 wz--n- <199.00g 100.00g

論理ボリュームの拡張

今回拡張した/配下に該当する論理ボリュームに対して、ボリュームグループの全空き領域を割り当てます。

これにより、ボリュームグループの空きが0になり、対象の論理ボリュームが100GB拡張されたことが確認できます。

# lvs
  LV   VG Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root cl -wi-ao---- <94.00g                                                    
  swap cl -wi-ao----   5.00g

# lvextend -l +100%FREE /dev/mapper/cl-root 
  Size of logical volume cl/root changed from <94.00 GiB (24063 extents) to <194.00 GiB (49663 extents).
  Logical volume cl/root successfully resized.

# vgs
  VG #PV #LV #SN Attr   VSize    VFree
  cl   1   2   0 wz--n- <199.00g    0 

# lvs
  LV   VG Attr       LSize    Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root cl -wi-ao---- <194.00g                                                    
  swap cl -wi-ao----    5.00g 

ファイルシステムの拡張

最後にファイルシステムを拡張します。

今回は xfs というファイルシステムだったので、xfs_growfs というコマンドを使います。

このコマンドによる拡張はすぐに終わりました。

df コマンドでファイルサイズを確認すると、/配下の領域が約200GB程度にまで拡張されていることが確認できます。

# xfs_growfs /
meta-data=/dev/mapper/cl-root    isize=512    agcount=9, agsize=2883328 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=24640512, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=5631, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 24640512 to 50854912


# df -PT
Filesystem          Type     1024-blocks     Used Available Capacity Mounted on
/dev/mapper/cl-root xfs        203397124 98038144 105358980      49% /
devtmpfs            devtmpfs     3994444        0   3994444       0% /dev
tmpfs               tmpfs        4005420        0   4005420       0% /dev/shm
tmpfs               tmpfs        4005420     8832   3996588       1% /run
tmpfs               tmpfs        4005420        0   4005420       0% /sys/fs/cgroup
/dev/sda1           xfs          1038336   189676    848660      19% /boot
tmpfs               tmpfs         801084        0    801084       0% /run/user/55557
tmpfs               tmpfs         801084        0    801084       0% /run/user/55556

まとめ

ESXi上の仮想マシンでLVMのXFSファイルシステムを拡張する手順をまとめてみました。

ディスクのパーティションやLVMの構成次第では、今回の方法では拡張できない場合もあるので注意が必要です。

その場合は、素直にディスクを追加してボリュームグループを拡張する方法が良いと思います。

参考

fdisk でパーティションのサイズを変更する - Red Hat Customer Portal

8.4. XFS ファイルシステムのサイズの拡大 - Red Hat Customer Portal

Grafana-ZabbixでDirect DB Connectionを使ってみた

はじめに

Grafana-ZabbixでDirect DB Connectionを使ってみたのでまとめてみました。

Gfarana-ZabbixはZabbixのデータをGrafanaで可視化するためのデータソースプラグインです。

α版ではありますがGrafana 4.3以降でMySQLがデータソースとしてサポートされ、Grafana-Zabbix 3.6以降でDirect DB Connectionという、時系列データをZabbixのデータベースから直接取得する機能が実装されました。

Direct DB Connectionの利点

Zabbix API経由で時系列データを取得する場合は、指定した時間範囲すべてのデータを取得し、クライアント側で大量データからグラフ表示枠に収まるよう調整しながら描画します。

Direct DB Connectionでは、この調整する作業をサーバサイドに任せることで、クライアント側のデータ読み込みサイズと描画の計算量を削減し、より効率よくグラフ表示できるようにしています。

具体的には、MySQLのクエリで上手く調整しているようです。

設定方法

環境

  • Zabbix 3.2.7
  • MySQL 5.7.18
  • Grafana 4.6.1
  • Grafana-Zabbix 3.7.0

MySQLデータソースの設定

今回はZabbixのデータベースにMySQLを使っていますので、GrafanaがZabbixのデータベースにアクセスできるようにMySQLのデータソース設定をします。

下記を参考にします。

SQL Data Source Configuration - Grafana-Zabbix Documentation

注意点としては、GrafanaがデータベースにアクセスするユーザはZabbixサーバがアクセスするユーザとは分けて作成し、不具合などで誤ってデータ更新しないよう、SELECT権限のみを付与することを推奨しているようです。

また、ここで入力したホストにはGrafanaサーバから接続されるようです。Zabbix API経由の場合はProxyとDirectでアクセス方法を選択できたので念のため確認してみました。

Zabbixデータソースの設定

次にZabbixのデータソース設定でDirect DB Connectionを有効化します。

下記を参考にします。

Configuration - Grafana-Zabbix Documentation

「Direct DB Connection」という項目がありますので、チェックを入れて先ほど作成したMySQLのデータソースを選択します。

これで、グラフ描画時の時系列データがZabbix API経由ではなくDBから直接取得されるようになります。

まとめ

Grafana-Zabbixで新しく実装されたDirect DB Connectionとその設定方法を紹介しました。

私のZabbixサーバはそこまで大量のデータがあるわけではないため、体感できるほどの効果は確認できませんでしたが、ダッシュボードに大量のグラフを並べると効果を実感できるかもしれないです。

またDirect DB Connectionを有効化した状態では、グラフ描画時にZabbixサーバにアクセスログが出力されなかったことから、MySQLに直接接続していることがわかります。

参考

Direct DB Connection - Grafana-Zabbix Documentation

What's New in Grafana v4.3 | Grafana Documentation