20200811のLinuxに関する記事は5件です。

OCF準拠のリソースエージェントの作り方

自作アプリをPacemakerでクラスタ管理したい

OCFリソースエージェント開発者ガイドを読めば簡単に作ることができますが、文章量が多いので、「とりあえず動くものが作りたいぜ」って人向け。

OCFの基本

OCFはOpenClusterFrameworkの略称で、アプリケーションをクラスタ化する際のインターフェースを定義しています。
クラスタ管理を行うPacemakerなどのクラスタマネージャは、管理対象のアプリケーションや仮想IPアドレスなどを「リソース」として管理します。
Pacemakerはリソースに対して起動・停止・マイグレーション・masterへの昇格・slaveへの降格などを命令します。
Pacemakerなどのクラスタ管理ソフトウェアとリソース間のインターフェースであOCF準拠のプログラムを組むことで、自作アプリをPacemakerを使ってクラスタリングすることができます。
このリソースエージェントを自作していくのが今回の目標です。

具体的には、OCFに準拠したクラスタ管理ソフトウェアは環境変数$__OCF_ACTIONに実行するアクションを入れてリソースエージェントをキックします。
アクションには起動・停止・マイグレーション・masterへの昇格・slaveへの降格などがあり、定義が必須のアクションと必須ではない(オプション)アクションがあります。
リソースの制御の際には、実行ファイルがキックされます。この実行ファイルをリソースエージェントといい、リソースの動作を実際に管理します。
リソースエージェントは環境変数$__OCF_ACTIONを見て、実際にそのアクションを実行するように動作します。
各アクションにおいてパラメータが必要な場合は、$OCF_RESKEYをプレフィックスとする環境変数で渡されます。
実行ファイル形式はOCFのAPI要件さえ満たしていれば、言語などに制限はありませんが、一般的にはシェルスクリプトで実装されるようです。

一番簡単なリソースエージェント

OCF準拠の一番簡単なコード

sample-resource
#!/bin/sh

#Initialize
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs

RUNNING_FILE=/tmp/.running

sample_meta_data() {
    cat << EOF
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="sample-resource" version="0.1">
    <version>0.1</version>
    <longdesc lang="en">sample resource</longdesc>
    <shortdesc lang="en">sample resource</shortdesc>
    <parameters>
    </parameters>
    <actions>
        <action name="meta-data" timeout="5" />
        <action name="start" timeout="5" />
        <action name="stop" timeout="5" />
        <action name="monitor" timeout="5" />
        <action name="validate-all" timeout="5" />
    </actions>
</resource-agent>
EOF
    return $OCF_SUCCESS
}

sample_validate(){
    return $OCF_SUCCESS
}

sample_start(){
    touch ${RUNNING_FILE}
    return $OCF_SUCCESS
}

sample_stop(){
    rm -f ${RUNNING_FILE}
    return $OCF_SUCCESS
}

sample_monitor(){
    if [ -f ${RUNNING_FILE} ];
    then
        return $OCF_SUCCESS
    fi
    return $OCF_NOT_RUNNING
}

sample_usage(){
    echo "Test Resource."
    return $OCF_SUCCESS
}

# Translate each action into the appropriate function call
case $__OCF_ACTION in
meta-data)      sample_meta_data
                exit $OCF_SUCCESS
                ;;
start)          sample_start;;
stop)           sample_stop;;
monitor)        sample_monitor;;
validate-all)   sample_validate;;
*)              sample_usage
                exit $OCF_ERR_UNIMPLEMENTED
                ;;
esac

初期化

OCFリソースエージェント開発者ガイドにも記載されているおまじないです。

#Initialize
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs

必須アクションを実装する

以下は実装が必須になっているアクションです。
これ以外はオプション扱いなので、ひとまず以下のアクションを定義してみます。

  • meta-data
  • start
  • stop
  • monitor
  • validate-all

各アクションの実行時に、適切な返り値を返す必要があります。
返り値はOCFで定義されています。

リソースエージェント内で使用する環境変数

各必須アクションの具体的な定義に入る前に使用する環境変数を説明します。

$__OCF_ACTION変数

リソースエージェントに要求する処理が格納されており、リソースエージェントの呼び出し時にセットされます。
リソースエージェントはまずはじめにこの環境変数を読んで、それぞれのアクションをディスパッチします。

実装例
OCFリソースエージェント開発者ガイドを丸パクリ

case $__OCF_ACTION in
meta-data)      sample_meta_data
                exit $OCF_SUCCESS
                ;;
start)          sample_start;;
stop)           sample_stop;;
monitor)        sample_monitor;;
validate-all)   sample_validate;;
*)              sample_usage
                exit $OCF_ERR_UNIMPLEMENTED
                ;;
esac
$OCF_RESKEY_パラメータ名

リソース作成時に設定されるパラメータが入る変数です。
この例では使っていませんが、後述のTCPサーバのデーモンをクラスタ化する際に使用しています。

meta-data

メタデータは、そのリソースエージェントの名前や提供するアクションや、受取可能なパラメータといった、そのリソースエージェントの基本的な情報を提供します。
XMLで記述されており、リソースエージェントはメタデータを要求されると標準出力でメタデータを返します。

start

リソースの起動処理を実装します。具体的にはデーモンの起動スクリプトなどを記述します。
今回は実際のデーモンは起動せずに、とあるファイルを作成するだけの処理にします。
起動に成功した場合は$OCF_SUCCESSを返します。

stop

リソースの終了を実装します。デーモンの停止などを記述します。
今回は、startで作成したファイルを削除する処理をします。

停止処理に問題がなければ$OCF_SUCCESSを返します。($OCF_NOT_RUNNINGではないので注意)

注意点としては、stopアクションはリソースの「強制停止」を意味します。
そのリソースが安全な停止が不可能な場合でも、とにかく停止を行うアクションです。
stopアクションに失敗した場合、致命的な問題が発生する可能性があるため、クラスタマネージャはノードのフェンシング(強制シャットダウンなどによる隔離)を行う場合があります。
stopアクションはリソースの停止にありとあらゆる手を使って、それでも停止ができなかった場合のみエラーコードを返すべきです。

monitor

リソースの状態を取得する処理を実装します。
起動していれば $OCF_SUCCESS を返し、起動していなければ $OCF_NOT_RUNNING を返します。
なにかエラーがあればエラー内容によって、$OCF_ERR_で始まるエラーの定数のうち適切なものを返します。

validate-all

リソースの設定を検証します。
パラメータが正しく設定されているか、リソースで使用するファイルの権限が適切かどうかなどを確認します。
返り値は以下のいずれかでなければなりません。

返り値 意味
$OCF_SUCCESS 問題なし
$OCF_ERR_CONFIGURED 設定に問題有り
$OCF_ERR_INSTALLED 必要なコンポーネントが存在していない(起動対象のデーモンがインストールされていないなど)
$OCF_ERR_PERM  リソース管理に必要なファイルのアクセス権限に問題あり

(今回は簡単のため、常に$OCF_SUCCESSを返します。)

テストしてみる

ocf-testerでテストができます。

#ocf-tester -n [リソース名] [リソースエージェンのパス]

salacia@ha1:~/ocf-scr$ sudo ocf-tester -n sample-resource ./sample-resource
Beginning tests for ./sample-resource...
* Your agent does not support the notify action (optional)
* Your agent does not support the demote action (optional)
* Your agent does not support the promote action (optional)
* Your agent does not support master/slave (optional)
* Your agent does not support the reload action (optional)
./sample-resource passed all tests

実際にPacemakerで起動してみる

リソースエージェントを配置する

Pacemakerのリソースエージェントの配置場所は/usr/lib/ocf/resource.d/配下です。
ここに提供者名でディレクトリを作成し、その中に作成したリソースエージェントを配置します。

ぼくのハンドルネームはかまぼこなので、提供者名はkamabokoとして、上記のsample-resourceを配置します。
(クラスタの全ノードにリソースエージェントを配置する必要があります)

salacia@ha1:~/ocf-scr$ ls -al /usr/lib/ocf/resource.d/kamaboko/
total 16
drwxrwxr-x 2 root root 4096 Aug 11 14:07 .
drwxr-xr-x 6 root root 4096 Jun 21 03:36 ..
-rwxr-xr-x 1 root root 1547 Aug 11 14:07 sample-resource
-rwxrwxr-x 1 root root 2103 Jun 21 03:36 sample-tcp-server

これだけでPacemakerからリソースエージェントが利用可能になるので、pcsコマンドからリソースを作成してみます。

salacia@ha1:~/ocf-scr$ sudo pcs resource create SAMPLE ocf:kamaboko:sample-resource

salacia@ha1:~$ sudo pcs status
Cluster name: c1
Stack: corosync
Current DC: ha2 (version 1.1.18-2b07d5c5a9) - partition with quorum
Last updated: Tue Aug 11 14:15:47 2020
Last change: Tue Aug 11 14:15:45 2020 by root via cibadmin on ha1

2 nodes configured
1 resource configured

Online: [ ha1 ha2 ]

Full list of resources:

 SAMPLE (ocf::kamaboko:sample-resource):        Started ha1

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled

自分で作成したリソースエージェントをPacemakerで動作させることができました。

もう少し実用的な例

サンプルコードはこちらです。
OCF Resource Agent Samle

とりあえず.debパッケージのみ対応しているので、DebianやUbuntu等で動作できると思います。
(開発環境はUbuntu18.04)
Pacemakerは導入済みの前提です。

クラスタ化するアプリ

適当なデーモンを作ればいいので、TCPで接続すると挨拶するだけのアプリを作りました。
(ただのサンプルなのでコードそのものには言及しないで...)
アプリを起動してtelnet等で接続すると、環境変数に設定した挨拶文と、自身のノード名を返します。

daemon/tcp-server.py.py
#!/usr/bin/python3
import os
import socket
import threading
import time
import signal
import sys

PORT = 5678
PID_FILE_DIR = "/var/run/sample-tcp-server"
PID_FILE_NAME = "tcp-server.pid"
PID_FILE = "%s/%s" % (PID_FILE_DIR, PID_FILE_NAME)
EXIT = False
GREET = os.environ.get("GREET", "Hello!")

def signal_handler(signum, stack):
    EXIT = True

def server():
    os.makedirs(PID_FILE_DIR, exist_ok=True)
    if os.path.isfile(PID_FILE):
        raise Exception("Already running")

    with open(PID_FILE, "w") as f:
        f.write(str(os.getpid()))

    print("Create Socket")
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('', PORT))
    s.listen(5)

    try:
        while True:
            if EXIT:
                raise Exception("Stop daemon due to receive signal")

            (con, addr) = s.accept()
            t = threading.Thread(
                target=handler,
                args=(con, addr),
                daemon=False
            )
            t.start()
    except Exception as e:
        sys.stderr.write("%s\n" % e)
    finally:
        print("Close Socket")
        s.close()
        os.remove(PID_FILE)
        return

def handler(con, addr):
    con.send(("%s This is %s!\n" % (GREET, socket.gethostname())).encode())
    con.close()

if __name__ == '__main__':
    signal.signal(signal.SIGINT, handler)
    signal.signal(signal.SIGTERM, handler)
    server()

標準モジュールだけで作ったので、ライブラリのインストール等は必要ありません。
プロセスの起動確認用としてPIDファイルを生成するようにしています。
一応アプリ終了時にPIDファイルを削除するので、PIDファイルの存在でアプリの起動確認ができますが、SIGKILLなどで落とされると削除されないのであまりよくないと思います。(今回はただのテストなので簡単のためにこうしています)

起動

GREET=Hii! python3 tcp-server.py

telnetで接続してみる

salacia@ha1:~$ telnet localhost 5678
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hi!, This is ha1!
Connection closed by foreign host.

サンプルコードでは、このアプリをsystemdで起動・停止ができるようにするためにserviceファイルを含めています。
今回はこのアプリを高可用性クラスタで動作させて、冗長化するようにしてみます。

インストール

ダウンロードしてmakeでパッケージが作成できるので、あとはdpkgからインストールするだけです。
(クラスタの全ノードでインストールする必要があります)

git clone https://github.com/kamaboko123/OCF_resource_agent_sample.git
cd OCF_resource_agent_sample
make
sudo dpkg -i dist/sampletcpserver_1.0_amd64.deb

動作確認

ひとまずVIP(VRRP)を2つのノード間で設定し、故障時にフェイルオーバーさせます。

#VIPをサービス登録
sudo pcs resource create VIP ocf:heartbeat:IPaddr2 ip=172.16.0.50 cidr_netmask=24 op monitor interval=10s on-fail="standby"

#サンプルアプリをサービス登録
sudo pcs resource create TCP-SERVER ocf:kamaboko:sample-tcp-server greet=Hi!

#VIPとサンプルアプリのACTIVEノードが同じになるように制約を設定する
sudo pcs constraint colocation add TCP-SERVER with VIP INFINITY

外部のノードからtelnetで仮想IPアドレス宛に接続します。

salacia@Vega:~$ telnet 172.16.0.50 5678
Trying 172.16.0.50...
Connected to 172.16.0.50.
Escape character is '^]'.
Hi!, This is ha1!
Connection closed by foreign host.

接続しているノードををshutdownして、フェイルオーバーさせ、サービスが継続して提供できていることを確認します。

#現在VIPとTCP-SERVERリソースが起動しているノード(ha1)を落とす
salacia@ha1:~$ sudo pcs status
[sudo] password for salacia:
Cluster name: c1
Stack: corosync
Current DC: ha2 (version 1.1.18-2b07d5c5a9) - partition with quorum
Last updated: Tue Aug 11 14:31:30 2020
Last change: Tue Aug 11 14:17:26 2020 by root via cibadmin on ha1

2 nodes configured
2 resources configured

Online: [ ha1 ha2 ]

Full list of resources:

 VIP    (ocf::heartbeat:IPaddr2):       Started ha1
 TCP-SERVER     (ocf::kamaboko:sample-tcp-server):      Started ha1

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled

salacia@ha1:~$ sudo shutdown -h now
Connection to 172.16.0.51 closed by remote host.
Connection to 172.16.0.51 closed.



#外部ノードからVIP宛でサービスの提供が継続しているか確認する
salacia@Vega:~$ telnet 172.16.0.50 5678
Trying 172.16.0.50...
Connected to 172.16.0.50.
Escape character is '^]'.
Hi!, This is ha2!
Connection closed by foreign host.

#フェイルオーバー先のノード(ha2)で状態確認
salacia@ha2:~$ sudo pcs status
[sudo] password for salacia:
Cluster name: c1
Stack: corosync
Current DC: ha2 (version 1.1.18-2b07d5c5a9) - partition with quorum
Last updated: Tue Aug 11 14:35:51 2020
Last change: Tue Aug 11 14:17:26 2020 by root via cibadmin on ha1

2 nodes configured
2 resources configured

Online: [ ha2 ]
OFFLINE: [ ha1 ]

Full list of resources:

 VIP    (ocf::heartbeat:IPaddr2):       Started ha2
 TCP-SERVER     (ocf::kamaboko:sample-tcp-server):      Started ha2

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled

ちなみに、ocf-testerのテストを行う場合は、フルパスを指定すればOKです。

sudo ocf-tester -n sample-tcp-server /usr/lib/ocf/resource.d/kamaboko/sample-tcp-server

解説

先に説明した通り、リソースエージェントはシェルスクリプトで記述しています。

/usr/lib/ocf/resource.d/kamaboko/sample-tcp-server
#!/bin/sh

#Initialize
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs

#default value
OCF_RESKEY_greet_default="Hello!"
: ${OCF_RESKEY_greet=${OCF_RESKEY_greet_default}}

#environment variables for systemd
DAEMON_PID_FILE=/var/run/sample-tcp-server/tcp-server.pid

sample_meta_data() {
    cat << EOF
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="sample-tcp-server" version="0.1">
    <version>0.1</version>
    <longdesc lang="en">sample tcp server</longdesc>
    <shortdesc lang="en">sample tcp server</shortdesc>
    <parameters>
        <parameter name="greet" unique="0" required="0">
            <longdesc lang="en">greet message</longdesc>
            <shortdesc lang="en">greet message</shortdesc>
            <content type="string"/>
        </parameter>
    </parameters>
    <actions>
        <action name="meta-data" timeout="5" />
        <action name="start" timeout="5" />
        <action name="stop" timeout="5" />
        <action name="monitor" timeout="5" />
        <action name="validate-all" timeout="5" />
    </actions>
</resource-agent>
EOF
    return $OCF_SUCCESS
}

sample_validate(){
    return $OCF_SUCCESS
}

sample_start(){
    mkdir -p /var/run/sample-tcp-server
    echo "GREET=${OCF_RESKEY_greet}" > /var/run/sample-tcp-server/env
    systemctl start sample-tcp-server
    sleep 1
    return $OCF_SUCCESS
}

sample_stop(){
    systemctl stop sample-tcp-server
    return $OCF_SUCCESS
}

sample_monitor(){
    if [ -f ${DAEMON_PID_FILE} ];
    then
        return $OCF_SUCCESS
    fi
    return $OCF_NOT_RUNNING
}

sample_usage(){
    echo "Test Resource."
    return $OCF_SUCCESS
}

# Translate each action into the appropriate function call
case $__OCF_ACTION in
meta-data)      sample_meta_data
                exit $OCF_SUCCESS
                ;;
start)          sample_start;;
stop)           sample_stop;;
monitor)        sample_monitor;;
validate-all)   sample_validate;;
*)              sample_usage
                exit $OCF_ERR_UNIMPLEMENTED
                ;;
esac

meta-dataとデフォルト値

meta-dataでは、必須項目に加えてパラメータの定義をしています。
パラメータはリソースの作成時に設定される値で、リソースエージェント中では変数OCF_RESKEY_パラメータ名で取得できます。
今回は挨拶の文面を、パラメータ名greetで定義しています。
必須パラメータの場合、required属性を1にしますが、今回は0なのでオプション扱いです。
そのため、指定されなかった場合のデフォルト値を定義も含んでいます。
(指定されなかったら、このデフォルト値Hello!$OCF_RESKEY_greetに入る。)

#default value
OCF_RESKEY_greet_default="Hello!"
: ${OCF_RESKEY_greet=${OCF_RESKEY_greet_default}}

sample_meta_data() {
    cat << EOF
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="sample-tcp-server" version="0.1">
    <version>0.1</version>
    <longdesc lang="en">sample tcp server</longdesc>
    <shortdesc lang="en">sample tcp server</shortdesc>
    <parameters>
        <parameter name="greet" unique="0" required="0">
            <longdesc lang="en">greet message</longdesc>
            <shortdesc lang="en">greet message</shortdesc>
            <content type="string"/>
        </parameter>
    </parameters>
    <actions>
        <action name="meta-data" timeout="5" />
        <action name="start" timeout="5" />
        <action name="stop" timeout="5" />
        <action name="monitor" timeout="5" />
        <action name="validate-all" timeout="5" />
    </actions>
</resource-agent>
EOF
    return $OCF_SUCCESS
}

start

systemdでserviceを立ち上げているだけです。
serviceファイルは後ろで説明します。
service起動時の環境変数として、OCFからのパラメータを渡すので、${OCF_RESKEY_greet}をファイルに書き込んでいます。

sample_start(){
    mkdir -p /var/run/sample-tcp-server
    echo "GREET=${OCF_RESKEY_greet}" > /var/run/sample-tcp-server/env
    systemctl start sample-tcp-server
    sleep 1
    return $OCF_SUCCESS
}

stop

とくに説明することはなくserviceの停止です。

sample_stop(){
    systemctl stop sample-tcp-server
    return $OCF_SUCCESS
}

monitor

今回はPIDファイルを見ています。

sample_monitor(){
    if [ -f ${DAEMON_PID_FILE} ];
    then
        return $OCF_SUCCESS
    fi
    return $OCF_NOT_RUNNING
}

簡単のためこうしていますが、じつはあまり良い実装とは言えないと思います。
プロセス終了時にPIDファイルを削除する実装になっていますが、SIGKILLで殺されるとPIDファイルが削除されません。
serviceファイルの作りにもよりますが、stopアクションはありとあらゆる手段でリソースの停止を行うと考えられるため、最終的にはSIGKILLが発行されるかもしれません。
そうなると、停止してもPIDファイルが残り続けて、monitorアクションでの確認した状態と、実際の状態が異なる可能性が出てきます。
(せっかくサービス管理にsystemd使ってるんだから、systemd経由にすればよかった)

validate-all

特に何もしません。

sample_validate(){
    return $OCF_SUCCESS
}

serviceファイル

特殊なことはしておらず、リソース設定時に作成された環境変数ファイルから環境変数を読みつつ、デーモンを起動するだけです。

/lib/systemd/system/sample-tcp-server.service
[Unit]
Description=Sample TCP Server

[Service]
Type=simple
ExecStartPre=/bin/touch /var/run/sample-tcp-server/env
EnvironmentFile=/var/run/sample-tcp-server/env
ExecStart=/usr/bin/tcp-server.py
ExecStop=/usr/bin/pkill -F /var/run/sample-tcp-server/tcp-server.pid

[Install]
WantedBy=multi-user.target

まとめ

OCFのリソースエージェントは意外と簡単に作れます。
今回は入り口として、まずは必須アクションだけで実際に動作するリソースエージェントを作成しましたが、実際に作成する際には細かな注意点等もあります。
そのあたりは、OCFリソースエージェント開発者ガイドにヒントが色々書かれているので、参考になると思います。

余談

LPIC304勉強してるときにPacemakerが何やってるのかイメージがあまりわかなくて、色々調べてるうちにリソースエージェントが自作できそうなことに気づいて、この記事が生まれました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

OVA でデプロイした Fedora CoreOS のディスクサイズを後から拡張する

公式 から取得した OVA でインストールした Fedora CoreOS のディスクサイズを後から拡張する手順。

手順

とりあえずインストール後、仮想ディスクのサイズを拡張する。

Untitled.png

起動したら以下のコマンドを順に実行する。

  • 拡張したいパーティションの番号を確認(今回は sda4 が対象)
  • 拡張したいデバイスとパーティションを指定して growpart を実行
  • 一旦リブートして再接続
  • パーティションを指定して xfs_growfs を実行
# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0  250G  0 disk
|-sda1   8:1    0  384M  0 part /boot
|-sda2   8:2    0  127M  0 part /boot/efi
|-sda3   8:3    0    1M  0 part
`-sda4   8:4    0  7.5G  0 part /sysroot

# growpart /dev/sda 4
CHANGED: partition=4 start=1050624 old: size=15726559 end=16777183 new: size=523237343 end=524287967

# reboot now

# xfs_growfs /dev/sda4
meta-data=/dev/sda4              isize=512    agcount=14, agsize=146432 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1
data     =                       bsize=4096   blocks=1965819, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 1965819 to 65404667

# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0   250G  0 disk
|-sda1   8:1    0   384M  0 part /boot
|-sda2   8:2    0   127M  0 part /boot/efi
|-sda3   8:3    0     1M  0 part
`-sda4   8:4    0 249.5G  0 part /sysroot

ポイント

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

tarコマンドのエラー(未解決)

はじめに

前回のチュートリアルに引き続き、SageMakerを触ってみたいという思いから資料を探してみたところ、機械学習を利用した画像判定Webアプリケーションの作成を行うハンズオン資料を発見した為、実施してみる事にしました。
しかし、SageMakerの実行途中でエラーが発生し、解消する事が出来なかった為断念しました。本記事では発生したエラー事象について記載します。

以下、構築予定だったアーキテクチャの概要です。

ai-ml01-02.png

(http://www.intellilink.co.jp/article/column/ai-ml01.html より引用)

また、以下が開発するWebアプリケーションの完成形イメージになります。
画面左側で判定したい画像を選択し、画像に何が写っているかの判定結果を画面右側に表示する仕組みです。

ai-ml01-01.png

(http://www.intellilink.co.jp/article/column/ai-ml01.html より引用)

本編

ハンズオン資料を参照し、
- S3作成
- SageMakerによる機械学習部分の実施

と進めていったが、SageMakerを実行した所、エラーが発生している事を確認。

ログを確認すると、以下の実行部分でエラーが表示されている。

%%bash

mkdir -p caltech_256_train_60
for i in 256_ObjectCategories/*; do
    c=`basename $i`
    mkdir -p caltech_256_train_60/$c
    for j in `ls $i/*.jpg | shuf | head -n 60`; do
        mv $j caltech_256_train_60/$c/
    done
done

python im2rec.py --list --recursive caltech-256-60-train caltech_256_train_60/
python im2rec.py --list --recursive caltech-256-60-val 256_ObjectCategories/

エラー文言は以下。

ls: cannot access 256_ObjectCategories/*/*.jpg: No such file or directory

更に確認を続けていると、1つ前の実行部分が、中断はされていないものの以下のメッセージを出力していた。以下は実行部分。

import os
import urllib.request

def download(url):
    filename = url.split("/")[-1]
    if not os.path.exists(filename):
        urllib.request.urlretrieve(url, filename)


# Caltech-256 image files
download('http://www.vision.caltech.edu/Image_Datasets/Caltech256/256_ObjectCategories.tar')
!tar -xf 256_ObjectCategories.tar

# Tool for creating lst file
download('https://raw.githubusercontent.com/apache/incubator-mxnet/master/tools/im2rec.py')

メッセージは以下。

tar: This does not look like a tar archive
tar: Skipping to next header
tar: Exiting with failure status due to previous errors

tarの解凍コマンドを実行しているが、対象ファイルがtar形式ではないので処理をスキップしている、とのこと。

  • tarファイルではない?
    →対象を確認したが、tarファイルだった
  • 権限等の原因でダウンロード出来ていない?
    →tarコマンドなしで実行したが、問題なくダウンロードできた
  • tarコマンドのオプションが間違っている?
    今回のtarコマンドのオプションは以下。
    x:アーカイブされたファイルを解凍し展開・復元を行う
    f:アーカイブファイル名を指定する
    →コマンドfを外して実行してみた所、上記メッセージは出力されなくなったものの終わらず。

調べてみると、tar.gzになっていると上手く解凍できない事があるようだが今回gzip圧縮もされておらず。。。
断念し一旦中断。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Slurm Workload ManagerのUbuntu 18.04LTSへの導入

前書き

これまで数値計算用ワークステーションのジョブスケジューラとしてtorqueを長年使用していましたが、有料になったため、代替案として無料ソフトウェアであるSlurmを導入しました。

SlurmのUbuntu16.04LTSへの導入については、下記の記事
https://qiita.com/JeJeNeNo/items/c545e72373d4d1deb36a
にて丁寧にまとめられており、18.04LTSへのインストールもほぼこの通りで出来ます。
詳細な手順は上の記事を見て頂くとして、一部の変更点をまとめておきます。
1から知りたい方は、まず上の記事を読むことをお勧めします。

Slurmのインストール

インストールまでは上の記事と同じ手順なので省略します。
Slurmのインストールの前に、Slurmの起動に必要なソフトウェアMUNGEをインストールする必要があり、16.04LTSだと大変だったようです。
嬉しいことに18.04LTSではapt installで問題なくインストールできます。

sudo apt install munge

Slurmもapt installでインストールできるようですが、後の設定を考え、上の記事と同様にソースコードから最新版をコンパイルしてインストールしました。prefixは設定しなかったので、デフォルト設定の通り、"/usr/local"にインストールされます。

./configure
make
sudo make install

Slurmの設定ファイル作成

ここも上の記事の手順とほぼ同じですが、一部変更&追加。
具体的には、

  • hyperthreadingを使う場合でも、"Sockets", "CoresPerSocket", "ThreadsPerCore"の設定が必要
  • 追跡をpgidに変更(デフォルト設定はcgroup)

後は上の記事に従って、ポート開放・systemdに設定・起動

使い方

下記サイトにまとまっています。
https://www.j-focus.jp/user_guide/ug0004000000/
とりあえず覚えておくべきは、
・ジョブ実行

sbatch **.sh

・ジョブのステータス確認

squece

・ジョブ強制終了

scancel ***

で、バッチファイルの書き方は下記のサンプルを自分用に改変すれば動きました。
https://www.j-focus.jp/user_guide/ug0004040000/#ug0004040000

おわりに

インストール作業や使い方はtorqueより楽だし、無料なので文句を言うのもアレですが、公式サイトのマニュアルが読みにくくて閉口しました…。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Macへ X Window Systemで GUI表示してみてみた

■ 目的

サーバー管理するにあたって、通常CLIですが、時々GUIも使いたくなります。
そのときはVNCを使うのですが、X Window もやってみたくなります。
ということで、Oracle CloudのLinixコンピュートのGUI表示をMACでX Windowしてみてみます。

■ 構成イメージ

OCIへInternet接続したOn-Premises環境にあるMac Bookから、Xしてみてみます
構成Internet_xeyes.png

■ Mac側設定

● Mac 用の X11 について

X11 は Mac に付属しなくなりましたが、X11 のサーバとクライアントのライブラリは、XQuartz プロジェクトから入手できます。

・XQuartz プロジェクト: https://support.apple.com/ja-jp/HT201341
MAC-HP01.png

● XQuartz ダウンロード

xquartz.org から、XQuartz をダウンロード

・xquartz.org: https://www.xquartz.org/
MAC-HP02.png

●xquartzインストール

1) .dmgファイル実行
ダウンロードした、.dmgファイルをクリックして、XQuartz.pkgをクリック
MAC-HP03.png

2) ようこそXQuartz インストーラーへ画面
[続ける]をクリック
MAC-HP04.png

3) 大切な情報画面
[続ける]をクリック
MAC-HP05.png

4) 使用許諾契約画面
使用許諾契約内容を確認し、[続ける]をクリック
MAC-HP06.png

5) ソフトウェア使用許諾の条件に同意する必要があります。画面
使用許諾契約に合意できれば、[同意する]をクリック
MAC-HP07.png

5) インストールの種類画面
[インストール]をクリック
MAC-HP08.png

6)インストール画面
〜インストール中〜
MAC-HP09.png

7) ポップアップ
You will need to log out and log back in to make XQuartz your default X11 server
内容を確認し、[OK]をクリック
MAC-HP11.png

8) インストールが完了しました画面
MAC-HP12.png

■OCI Linuxコンピュート側設定

リモートアクセスするLinuxマシンに、X Windowできるように設定

● xorg-x11パッケージインストール

xorg-x11パッケージがインストールされていない場合、
以下2つを yumコマンドでインストール

・xorg-x11-xauth.x86_64 
・xorg-x11-server-utils.x86_64
[root@oci-inst01 opc]# yum install -y xorg-x11-xauth.x86_64 xorg-x11-server-utils.x86_64

    読み込んだプラグイン:langpacks, ulninfo
    依存性の解決をしています
    --> トランザクションの確認を実行しています。
    ---> パッケージ xorg-x11-server-utils.x86_64 0:7.7-20.el7 を インストール
    --> 依存性の処理をしています: libXxf86misc.so.1()(64bit) のパッケージ: xorg-x11-server-utils-7.7-20.el7.x86_64
    --> 依存性の処理をしています: libXrandr.so.2()(64bit) のパッケージ: xorg-x11-server-utils-7.7-20.el7.x86_64
    --> 依存性の処理をしています: libXinerama.so.1()(64bit) のパッケージ: xorg-x11-server-utils-7.7-20.el7.x86_64
    --> 依存性の処理をしています: libXi.so.6()(64bit) のパッケージ: xorg-x11-server-utils-7.7-20.el7.x86_64
    ---> パッケージ xorg-x11-xauth.x86_64 1:1.0.9-1.el7 を インストール
    --> トランザクションの確認を実行しています。
    ---> パッケージ libXi.x86_64 0:1.7.9-1.el7 を インストール
    ---> パッケージ libXinerama.x86_64 0:1.1.3-2.1.el7 を インストール
    ---> パッケージ libXrandr.x86_64 0:1.5.1-2.el7 を インストール
    ---> パッケージ libXxf86misc.x86_64 0:1.0.3-7.1.el7 を インストール
    --> 依存性解決を終了しました。

    依存性を解決しました

    ==========================================================================================
    Package                      アーキテクチャー
                                                バージョン            リポジトリー       容量
    ==========================================================================================
    インストール中:
    xorg-x11-server-utils        x86_64        7.7-20.el7            ol7_latest        178 k
    xorg-x11-xauth               x86_64        1:1.0.9-1.el7         ol7_latest         29 k
    依存性関連でのインストールをします:
    libXi                        x86_64        1.7.9-1.el7           ol7_latest         40 k
    libXinerama                  x86_64        1.1.3-2.1.el7         ol7_latest         13 k
    libXrandr                    x86_64        1.5.1-2.el7           ol7_latest         27 k
    libXxf86misc                 x86_64        1.0.3-7.1.el7         ol7_latest         19 k

    トランザクションの要約
    ==========================================================================================
    インストール  2 パッケージ (+4 個の依存関係のパッケージ)

    総ダウンロード容量: 305 k
    インストール容量: 629 k
    Downloading packages:
    (1/6): libXi-1.7.9-1.el7.x86_64.rpm                                |  40 kB  00:00:00
    (2/6): libXrandr-1.5.1-2.el7.x86_64.rpm                            |  27 kB  00:00:00
    (3/6): libXxf86misc-1.0.3-7.1.el7.x86_64.rpm                       |  19 kB  00:00:00
    (4/6): libXinerama-1.1.3-2.1.el7.x86_64.rpm                        |  13 kB  00:00:00
    (5/6): xorg-x11-server-utils-7.7-20.el7.x86_64.rpm                 | 178 kB  00:00:00
    (6/6): xorg-x11-xauth-1.0.9-1.el7.x86_64.rpm                       |  29 kB  00:00:00
    ------------------------------------------------------------------------------------------
    合計                                                      4.2 MB/s | 305 kB  00:00:00
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
    インストール中          : libXrandr-1.5.1-2.el7.x86_64                              1/6
    インストール中          : libXxf86misc-1.0.3-7.1.el7.x86_64                         2/6
    インストール中          : libXinerama-1.1.3-2.1.el7.x86_64                          3/6
    インストール中          : libXi-1.7.9-1.el7.x86_64                                  4/6
    インストール中          : xorg-x11-server-utils-7.7-20.el7.x86_64                   5/6
    インストール中          : 1:xorg-x11-xauth-1.0.9-1.el7.x86_64                       6/6
    検証中                  : libXi-1.7.9-1.el7.x86_64                                  1/6
    検証中                  : libXinerama-1.1.3-2.1.el7.x86_64                          2/6
    検証中                  : libXxf86misc-1.0.3-7.1.el7.x86_64                         3/6
    検証中                  : libXrandr-1.5.1-2.el7.x86_64                              4/6
    検証中                  : xorg-x11-server-utils-7.7-20.el7.x86_64                   5/6
    検証中                  : 1:xorg-x11-xauth-1.0.9-1.el7.x86_64                       6/6

    インストール:
    xorg-x11-server-utils.x86_64 0:7.7-20.el7      xorg-x11-xauth.x86_64 1:1.0.9-1.el7

    依存性関連をインストールしました:
    libXi.x86_64 0:1.7.9-1.el7                libXinerama.x86_64 0:1.1.3-2.1.el7
    libXrandr.x86_64 0:1.5.1-2.el7            libXxf86misc.x86_64 0:1.0.3-7.1.el7

    完了しました!

● xeyes インストール

X動作確認用 GUIツール xeyesをインストール
これによりxclockなどもインストールされます

[root@tokyo-inst01 opc]# yum install xeyes
    読み込んだプラグイン:langpacks, ulninfo
    ol7_UEKR5                                                          | 2.8 kB  00:00:00
    ol7_addons                                                         | 2.8 kB  00:00:00
    ol7_developer                                                      | 2.8 kB  00:00:00
    ・・・
    インストール:
    xorg-x11-apps.x86_64 0:7.7-7.el7

    依存性関連をインストールしました:
    dejavu-fonts-common.noarch 0:2.33-6.el7      dejavu-sans-fonts.noarch 0:2.33-6.el7
    fontconfig.x86_64 0:2.13.0-4.3.el7           libICE.x86_64 0:1.0.9-9.el7
    libSM.x86_64 0:1.2.2-2.el7                   libX11.x86_64 0:1.6.7-2.el7
    libX11-common.noarch 0:1.6.7-2.el7           libXau.x86_64 0:1.0.8-2.1.el7
    libXaw.x86_64 0:1.0.13-4.el7                 libXcursor.x86_64 0:1.1.15-1.el7
    libXext.x86_64 0:1.3.3-3.el7                 libXfixes.x86_64 0:5.0.3-1.el7
    libXft.x86_64 0:2.3.2-2.el7                  libXmu.x86_64 0:1.1.2-2.el7
    libXpm.x86_64 0:3.5.12-1.el7                 libXrender.x86_64 0:0.9.10-1.el7
    libXt.x86_64 0:1.1.5-3.el7                   libXxf86vm.x86_64 0:1.1.4-1.el7
    libfontenc.x86_64 0:1.1.3-3.el7              libxcb.x86_64 0:1.13-1.el7
    libxkbfile.x86_64 0:1.0.9-3.el7

    完了しました!

● sshd設定

・sshd_config設定
以下を設定
(#はコメントアウトなので、はずしましょ)

[root@oci-inst01 ssh]# vi /etc/ssh/sshd_config | grep X11
    ・・・
    X11Forwarding yes
    X11DisplayOffset 10
    X11UseLocalhost no
    ・・・

・sshd_config設定確認

[root@oci-inst01 ssh]# cat /etc/ssh/sshd_config | grep X11
    X11Forwarding yes
    X11DisplayOffset 10
    X11UseLocalhost no
    #   X11Forwarding no

・sshd 再起動

[root@oci-inst01 ssh]# systemctl restart sshd

■ MACからOCI LinuxコンピュートへX window実行

● XQuartz 起動

1) XQuartzターミナル起動
Launchpad の [その他]の中にある XQuartzアイコンをクリックし、ターミナル起動
MAC-HP14.png

ターミナル起動が起動します
00.png

1) OCIインスタンスへssh接続
ssh接続は、X11 forwarding機能を有効にする -X オプションをつけて実行

bash-3.2$ ssh -X -i id_rsa opc@1.2.3.4
    Last login: Mon Aug 10 12:50:03 2020 from 192.168.0.2

2) DISPLAY環境変数確認
DISPLAY環境変数が自動登録されていることを確認
自動登録されていない場合は、sshd等の設定を見直します

[opc@oci-inst01 ~]$ env | grep DISP
    DISPLAY=10.0.0.2:11.0

3) xclock実行
xeyesコマンドで、GUI表示できることを確認

[opc@oci-inst01 ~]$ xeyes 

xeyes実行できず、error: "Can't open display"等が表示された場合は、ポート6000が空いているかFirewall等の環境見直しをします
xeyes01.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む