Memo Log

PANTO MAIMU 's Personal Blog

今日届いた本

ここのところ、暖かい日が続いています :-)

そんなわけで、今日届いた本...

Effective DevOps

f:id:PANTOMAIMU:20180327200019j:plain
Effective DevOps

Effective DevOps ―4本柱による持続可能な組織文化の育て方

Effective DevOps ―4本柱による持続可能な組織文化の育て方

プログラム開発がメインだった頃に、遅かれ早かれDevOpsの方向に進むことになるだろうなぁ...と思い始めて早6年...
色々ある中、Ops寄りの仕事を取ってきたりして、少しづつ下地を固めてつつ現在に至っているので、こういう本は見逃せなかったりします :-)

これから数年は、このDevOpsという文化の中で仕事をしていくことになるのかなぁと思っています。

会話もメールも 英語は3語で伝わります

会話もメールも 英語は3語で伝わります

会話もメールも 英語は3語で伝わります

今日届いたわけではないのですが、週末に買った本...
英語が超絶苦手で、コンプレックスがあるのですが、たまにこういう本を買って自己満足しています....orz
SVOだけでやってしまえ...という荒っぽい内容ですが、あぁ...こういう考え方もあるなぁ...ってので面白かった
あと、日本語の言語の思考プロセスを変えないと、英語って難しいよなぁ...ってのも再確認したのでしたヾ(:3ノシヾ)ノシ

NotebookからAnsibleを実行してみる

今日は、前のブログで構築したJupyter Notebook環境で、Ansibleを実行してみようと思います。

今回、Ansibleで実行してみる内容は、

  • Ansible実行用アカウント登録
  • sshd設定の変更

です。

Ansibleで運用するノードを新たに追加する場合に必要なオペレーションだと思うので、構築した検証環境で実行してみます。
この2つのオペレーションをplaybookにして、このplaybookをNotebookから実行してみます。

Notebook上のplaybook配置場所の説明

まず、Notebook上でplaybookを配置する場所についての説明をします。
前のブログでJupyter Notebookを環境した際に、ansibleのインベントリファイルを作成しましたが、その時に作成した~/sys-ope/notebooks/ansible にplaybookを配置します。
Notebook上では、以下のように/ansible の下になります。

f:id:PANTOMAIMU:20180321134704p:plain
/ansible

Ansible実行用アカウント登録playbook

まずはAnsible実行用アカウントの登録と公開鍵の登録playbookを作ります。
ファイル名は add_ansible_user.yml として作成します。
作成は、/ansibleの下でNewボタンのプルダウンでテキストファイルを作成してからrenameしてから、Notebook上で編集して下さい。
面倒であれば、PC上で作成したうえでUploadしてもよいです。

add_ansible_user.yml

---
- hosts: all
  become: yes
  tasks:
    - name: add ansible user
      user: name=ansible
 
    - name: add public key
      authorized_key:
        user: ansible
        key: "{{ lookup('file', '/home/bit_kun/.ssh/ansible_id_rsa.pub') }}"
 
    - name: add sudo
      lineinfile:
        dest: /etc/sudoers
        backup: yes
        line: 'ansible ALL=(ALL) NOPASSWD: ALL'

実行しているTaskは

  1. ansibleユーザ追加
  2. 公開鍵配置
  3. sudo権限付与

になります。

公開鍵ファイルであるansible_id_rsa.pubは、Jupyter Notebookを環境した際に生成した鍵セットになります。

sshd設定の変更playbook

次はsshdの設定をplaybookを作ります。
ファイル名は sshd_setup.yml として作成します。

sshd_setup.yml

---
- hosts: all
  become: yes
  tasks:
    - name: disable SELinux
      selinux:
        state: disabled

    - name: disable password ssh login
      lineinfile:
        dest: /etc/ssh/sshd_config
        regexp: "^PasswordAuthentication"
        insertafter: "^#PasswordAuthentication"
        line: "PasswordAuthentication no"

    - name: disable ChallengeResponseAuthentication
      lineinfile:
        dest: /etc/ssh/sshd_config
        regexp: "^ChallengeResponseAuthentication"
        insertafter: "^#ChallengeResponseAuthentication"
        line: "ChallengeResponseAuthentication no"

    - name: disable root login
      lineinfile:
        dest: /etc/ssh/sshd_config
        regexp: "^PermitRootLogin"
        insertafter: "^#PermitRootLogin"
        line: "PermitRootLogin no"

    - name: restart sshd
      service:
        name: sshd
        state: restarted

実行しているTaskは

  1. SELinux無効化
  2. sshでのパスワードログインの無効化
  3. チャレンジレスポンス認証の無効化
  4. rootログインの無効化
  5. sshd再起動

になります。

Notebookからplaybookを実行してみる

それでは、作成したplaybookをNotebook上で実行してみます。
playbookを実行する前に、インベントリファイルが準備されていることを
確認してください。

インベントリファイルの作成

運用で使えるJupyter Notebookコンテナ構築手順まとめ - Memo Log

まず新規にNotebookを作成します。
Notebook生成手順は、前のブログのここを参照してください。

Notebookからansibleを実行してみる

運用で使えるJupyter Notebookコンテナ構築手順まとめ - Memo Log

Notebookができたら、Ansible実行用アカウント登録playbookを実行してみます。
Notenookのセルに、!付きでansible-playbookコマンドを入力します。

f:id:PANTOMAIMU:20180321144122p:plain
ansible-playbook実行

入力内容は以下の通りです。

!ansible-playbook ansible/add_ansible_user.yml -e 'ansible_user=root ansible_ssh_pass=xxxxxxx'

Ansible実行用アカウント登録ですが、最初はrootでのパスワードログインで実行します。
xxxxxxxには、rootのパスワードを入力します。

入力したコマンドは、Runボタンを押して実行します。
実行すると、セルの下に実行結果が出力されます。

f:id:PANTOMAIMU:20180321145201p:plain
Ansible実行用アカウント登録playbook実行結果

同じように、次はsshd設定の変更playbookを実行してみます。

!ansible-playbook ansible/sshd_setup.yml

実行結果は、以下のようになります。

f:id:PANTOMAIMU:20180321145157p:plain
sshd設定の変更playbook実行結果

この実行結果は、Jupyter Notebook形式のファイルとして保存されます。
GitHubは、このJupyter Notebook形式ファイルに対応しているので、実行手順や結果をGitHubに公開して共有することも出来ます :-)

今回のこのNotebookに、Markdown形式でコメントを追加したものを公開しています。
github.com

Markdown形式のコメントを記述すると、Jupyter Notebookでは左側に目次をツリー形式で表示することができます。

f:id:PANTOMAIMU:20180321150404p:plain
目次の表示
ツリー側で目次を選択すると、その目次のセルにフォーカスが移動するので、ドキュメントを参照するように、手順に沿ってオペレーションができるようになります。

以上が、NotebookからAnsibleを実行してみた内容になります :-)

今日届いた本

三月終盤でもうすぐ4月だというのに雪です...orz
寒い...
f:id:PANTOMAIMU:20180321152325j:plain

そんな中、Amazonに頼んでいた本が届きました。
こんな天気の日に配達させてしまってごめんなさい >クロネコヤマトさん

ソフトウェアデザイン 2018年4月号

f:id:PANTOMAIMU:20180321112327j:plain

今月号は、第1特集の機械学習の始め方と、第2特集のPythonマイツール作成で仕事効率化目当てで買いました。
scikit-learnにちょっとだけ興味があったので、導入になればいいなぁ...って思っていたら、5月号からscikit-learnの連載が始まるらしい...

運用で使えるJupyter Notebookコンテナ構築手順まとめ

ここ1年ぐらい、"Literate Computing for Reproducible Infrastructure" という、Jupyter Notebookを使った運用オペレーションなどをやっていたりします。
今回は、このJupyter NotebookサービスのDockerコンテナのビルド手順や、起動方法について書いてみようと思います。

"Literate Computing for Reproducible Infrastructure"というのは、ざっくりいうと、Jupyter Notebookを使って実行可能なドキュメントを実現しよう...というものです。
ここ最近Ansibleを使って、スイッチ制御を含めたシステム運用をすることが流行ってきていますが、playbookの実行手順や実行結果の証跡を残す方法についてはあまり議論されていないと思っています。
この課題についての一つの解として、"Literate Computing for Reproducible Infrastructure"が有効だと考えていたりします。

"Literate Computing for Reproducible Infrastructure"の詳しい内容については、以下のスライドやブログを読んでみてください。

Jupyter notebook を用いた文芸的インフラ運用のススメ

www.slideshare.net

Literate Automation(文芸的自動化)についての考察
enakai00.hatenablog.com

環境構成概要

それでは、これからコンテナ構築手順の説明に入ります。
コンテナを構築するまえに、Jupyter Notebookコンテナを構築するノードなどについて説明します。

f:id:PANTOMAIMU:20180318194757p:plain
検証環境の構成イメージ
上の図は、今回私が検証に使っている環境の構成図です。
運用サーバ(cent-dev)は、Jupyter Notebookコンテナが動作するホストノードで、dev01、dev02、dev03は、Ansibleで制御する運用対象ノードになります。

運用サーバのOSとDockerのバージョンは以下の通りです。

OS CentOS 7.4
Docker CE 17.12
Docker Compose 1.19.0

Jupyter Notebookコンテナのビルド手順

それでは、Jupyter Notebookコンテナのビルド手順の説明を始めます。

まず、Jupyter Notebookコンテナ構築に必要なファイルを、NII(国立情報学研究所)のクラウド運用チームが公開しているGitHubから入手します。
github.com

入手は、上記のGitHubからgit cloneするか、zipファイルをダウンロードして、運用サーバ上のhomeディレクトリに展開してください。
私は、以下のようにgitを使って取得しました。

$ git clone https://github.com/NII-cloud-operation/Jupyter-LC_docker.git

取得が完了したら、以下の手順でJupyter Notebookコンテナをビルドします。
まずは取得したDockerfileをカスタマイズします。

$ cd ~/Jupyter-LC_docker
$ vi Dockerfile

普通は、このDockerfileをこのまま使うこともできるのですが、Jupyter Notebookのユーザアカウントの変更や、コンテナにパッケージを追加する手順を説明します。

最初は、Dockerfileにあるユーザアカウント生成処理の設定を変更します。

...
# Create 'bit_kun' user
ENV NB_USER bit_kun
ENV NB_UID 1000
RUN useradd -m -s /bin/bash -N -u $NB_UID $NB_USER && \
    mkdir /home/$NB_USER/.jupyter && \
    chown -R $NB_USER:users /home/$NB_USER/.jupyter && \
    echo "$NB_USER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$NB_USER
...

ユーザ名称は、ENV NB_USER で設定されています。bit_kun というのは、NIIのマスコットキャラクター(?)ビットくんのことです。
ENV NB_UIDは、ENV NB_USERで指定たユーザのIDを設定します。
あとで説明しますが、ホスト側のディレクトリをコンテナにボリュームマウントするので、ここで指定するユーザ名称やIDは、このコンテナのホスト側のユーザと合わせてください。

次に、コンテナにPythonパッケージの追加です。
特に追加するものがなければこの変更は不要ですが、notebookからSQLを実行する検証がしてみたかったので、今回は追加してみます。

...
## Python kernel with matplotlib, etc...
RUN pip --no-cache-dir install jupyter && \
    pip --no-cache-dir install pandas matplotlib numpy \
                seaborn scipy scikit-learn scikit-image \
                sympy cython patsy pymysql psycopg2 \         <---- 51行目
                statsmodels cloudpickle dill bokeh h5py && \
    apt-get update && apt-get install -yq --no-install-recommends \
    git \
...
### environments for Python3
ENV CONDA3_DIR /opt/conda3
RUN cd /tmp && \
    mkdir -p $CONDA3_DIR && \
    wget --quiet https://repo.continuum.io/miniconda/Miniconda3-4.2.12-Linux-x86_64.sh && \
    echo "c59b3dd3cad550ac7596e0d599b91e75d88826db132e4146030ef471bb434e9a *Miniconda3-4.2.12-Linux-x86_64.sh" | sha256sum -c - && \
    /bin/bash Miniconda3-4.2.12-Linux-x86_64.sh -f -b -p $CONDA3_DIR && \
    rm Miniconda3-4.2.12-Linux-x86_64.sh && \
    $CONDA3_DIR/bin/conda config --system --add channels conda-forge && \
    $CONDA3_DIR/bin/conda config --system --set auto_update_conda false && \
    $CONDA3_DIR/bin/conda install --quiet --yes \
    notebook matplotlib pandas pip pymysql psycopg2 && \        <---- 112行目
    $CONDA3_DIR/bin/conda clean -tipsy
...

51行目と112行目にpymysql psycopg2を追加します。

最後に、AWSクライアントの追加です。
これも必要なければ不要です。

...
### aws client
RUN apt-get update && apt-get install -y groff && \
    pip --no-cache-dir install awscli

### Add files
RUN mkdir -p /etc/ansible && cp /tmp/ansible.cfg /etc/ansible/ansible.cfg
...

97行目あたりに、apt-getを呼び出してawscliをインストールする定義を追加します。

以上で、Dockerfileの変更が完了です。
次のコマンドを実行して、コンテナのビルドを行います。

$ sudo docker build -t sys-ope/notebook:1.0 ~/Jupyter-LC_docker/

ビルドが完了したら、以下のコマンドでイメージのビルドに成功したことを確認します。

$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sys-ope/notebook    1.0                 357f73ee4430        7 days ago          4.64GB
debian              jessie              ce40fb3adcc6        4 weeks ago         123MB

これで、Jupyter Notebookコンテナのビルドは完了です。
次に、このコンテナを起動するための事前準備の手順を説明します。

マウント先ディレクトリ作成

ここでは、Jupyter Notebookコンテナからボリュームマウントする、ホスト側のディレクトリ作成を行います。

f:id:PANTOMAIMU:20180318194759p:plain
コンテナへのボリュームマウント構成
notebookやAnsibleのplaybookといった定義ファイルは、上の図のようにホスト側のディレクトリに配置し、コンテナからマウントして参照する方法にします。
この方が、定義ファイルのバックアップといった運用が簡単になるのと、コンテナの更新作業が簡単になるからです。
※コンテナは使い捨てなので、ステートレスな使い方をするのを前提にした方がよいと考えています。

コンテナ側のディレクトリと、その概要は以下の通り。

コンテナ側 概要
/notebooks Notebookファイルを保存するディレクト
/etc/ansible Ansibleのディレクトリ。ansible.cfgを配置する。
/home/bit_kun/.ssh Ansibleのssh実行に使用する秘密鍵を配置するディレクト

ホスト側のディレクトリはコンテナから参照されるので、Dockerfileで指定したユーザのIDと同じユーザIDになるようにしてください。

Ansible実行用鍵ファイル作成と配置

ここでは、Ansibleのssh実行に使用する秘密鍵の作成と配置を説明します。
まずは以下の手順でsshの鍵を生成します。

$ cd ~/sys-ope/.ssh
$ ssh-keygen -t rsa -f ansible_id_rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again:
...

Ansibleは、パスワード付き鍵ファイルに対応していないので、鍵生成時に入力を要求されるパスワードは未入力(リターンキー入力)にしてください。
次に、生成した秘密鍵と公開鍵のユーザIDとグループIDを設定します。

$ sudo chown 1000:100 ansible_id_rsa
$ sudo chown 1000:100 ansible_id_rsa.pub

ユーザIDは、各自の環境に合わせて下さい。

Jupyter Notebookコンテナの実行

ここまでで、コンテナを起動するための事前準備が終わったので、これからJupyter Notebookコンテナを実行します。
まずはdockerコマンドで実行してみます。

$ sudo docker run -it --rm -p 8888:8888 \
> -v ~/sys-ope/notebooks:/notebooks \
> -v ~/sys-ope/ansible:/etc/ansible \
> -v ~/sys-ope/.ssh:/home/bit_kun/.ssh \
> -e PASSWORD=xxxxxx sys-ope/notebook:1.0

環境変数PASSWORDのxxxxxxは、Jupyter Notebookのログイン時に入力するパスワードを設定します。
コンテナの起動に成功すると、以下のようにJupyter Notebookの起動完了と、アクセス先のURLを出力してきます。

...
[I 07:43:37.156 NotebookApp] 0 active kernels
[I 07:43:37.156 NotebookApp] The Jupyter Notebook is running at:
[I 07:43:37.156 NotebookApp] http://[all ip addresses on your system]:8888/
...

このURLにアクセス(今回の環境では、http://10.0.0.1:8888/)すると、Jupyter Notebookのログイン画面が表示されます。

f:id:PANTOMAIMU:20180318194754p:plain
Jupyter Notebookログイン画面
環境変数PASSWORDに設定したパスワードを入力してログインすると、Jupyter Notebookのホーム画面が開きます。
f:id:PANTOMAIMU:20180318194750p:plain
Jupyter Notebookホーム 画面
これで、Jupyter Notebookコンテナのビルドと動作確認は完了です。
一旦、Ctrl-Cでコンテナを停止させ、このコンテナをdocker-composeで起動するようにします。

docker-composeの定義ファイル作成

まずはviでdocker-compose.ymlを開いて、新規に作成します。

$ vi ~/sys-ope/docker-compose.yml

内容は以下の通りです。

version: "2"

services:
    jupyter:
        image: sys-ope/notebook:1.0
        ports:
            - 8888:8888
        environment:
            TZ: JST-9
            HOST_HOSTNAME: "${HOSTNAME}"
            hostname: "${HOSTNAME}"
            PASSWORD: xxxxxx
        volumes:
            - ./ansible:/etc/ansible/
            - ./.ssh:/home/bit_kun/.ssh/
            - ./notebooks:/notebooks
        logging:
          driver: journald

PASSWORDのxxxxxxは、Jupyter Notebookのログイン時に入力するパスワードになるので、各自で決めて設定してください。

まずはdocker-compose upで起動します。

$ cd ~/sys-ope
$ sudo docker-compose up -d
Recreating sysope_jupyter_1 ... done

これで、docker-composeでJupyter Notebookコンテナが起動するようになりました。
あとは、docker-compose start、stopを使って、起動停止を行ってください。

インベントリファイルの作成

ここでは、NotebookからAnsibleを実行するための環境設定や、インベントリファイルの配置の手順を説明します。

まずは、インベントリファイルを配置するディレクトリを作成します。

$ mkdir ~/sys-ope/notebooks/ansible
$ mkdir ~/sys-ope/notebooks/ansible/inventory
$ mkdir ~/sys-ope/notebooks/ansible/inventory/host_vars
$ mkdir ~/sys-ope/notebooks/ansible/inventory/group_vars

次に、ansible.cfgを設定します。

$ vi ~/sys-ope/ansible/ansible.cfg

ansible.cfgには、以下の設定を行います。

[defaults]
host_key_checking = False
forks = 3
record_host_keys = False
remote_user = ansible

private_key_file = /home/bit_kun/.ssh/ansible_id_rsa
inventory = /notebooks/ansible/inventory/inventory.ini

次は、以下の構成でインベントリファイルを作成します。

~/sys-ope/notebooks/ansible
|--inventory
|  |--group_vars
|  |--host_vars
|  |  |--cent-dev.yml
|  |  |--dev01.yml
|  |  |--dev02.yml
|  |  |--dev03.yml
|  |--inventory.ini

まず先に、host_varsの下に、ノードごとの情報を定義するyaml形式のファイルを作成します。
ファイル名称がAnsible内で使用されるホスト名称となり、定義のansible_hostに、ssh接続するIPアドレスを設定します。
例:dev01.yml

---
ansible_host: 10.0.0.10

host_varsに、今回の対象ノードの定義ファイルを作成し終わったら、inventory.iniを作成します。

$ vi ~/sys-ope/notebooks/ansible/inventory/inventory.ini

このインベントリファイルは、先ほど作成したansible.cfgに定義したinventory で設定したファイルになります。
内容は、こんな感じになります。

[dev]
dev01
dev02
dev03

[ope]
cent-dev

インベントリファイルの作成が終わったら、ファイルの所有者設定を行っておきます。

$ sudo chown 1000:100 -R ~/sys-ope/notebooks/ansible

以上で、Ansibleの設定を含めた、Jupyter Notebookコンテナ構築は完了です。
それでは、Jupyter Notebookから、お試しでAnsibleを実行してみます。

Notebookからansibleを実行してみる

まずは、先ほどのログイン画面からログインしてホーム画面に入ります。

f:id:PANTOMAIMU:20180318194922p:plain
新規Notebook作成
ホーム画面の右側にあるNewのプルダウンから、Python2を選択すると、Untitledという名前の、Python2のコードが実行できるNotebookが生成されます。
次に、Notebook上でAnsibleを実行してみます。
まだ、対象のノードに公開鍵配置やAnsible実行用アカウントの生成を行っていないので、パスワード入力のrootでlsコマンドを実行してみます。
f:id:PANTOMAIMU:20180318194914p:plain
Ansible実行コマンド入力
左側が”In []:”となっているところに、先頭に"!"をつけて実行するコマンドを入力します。
この"!"をつけることで、Jupyter Notebook上でコマンドを実行することができるようになります。
こんな感じです。

!ansible -m shell -a 'ls -la '  -e 'ansible_user=root ansible_ssh_pass=xxxxxxx' all 

ansible_ssh_passのxxxxxxxには、rootアカウントのパスワードを入力してください。
【補足】Notebook上で実行するコマンドは、対話形式のものが使用できないので、-kを使うことができません。

コマンドの入力ができたら、上のRunボタンを押してコマンドを実行します。

f:id:PANTOMAIMU:20180318194909p:plain
実行結果
実行すると、コマンドの出力が下の方にリアルタイムに出力されます。
この出力結果は、Notebookファイルに保存されるので、実行結果のエビデンスとして残すことができます :-)
そんなわけで、ちょっと長くなってしまいましたが、運用で使えるJupyter Notebookコンテナの構築手順と、ちょっとだけですがNotebookでAnsibleを実行する手順の説明をしてみました。

次はこの環境に対して、ansible実行ユーザの追加や、パスワードログインが出来ないようにsshdの設定を変更するplaybookを実行する手順などを書いてみようと思います。

それでは :-)

本日届いた本

久しぶりのブログです。
デザインとか色々整理して、少しづつ再開して行く予定です :-)

そんなわけで、今日密林から届いた本

アプリケーションエンジニアのためのApache Spark入門

f:id:PANTOMAIMU:20180315202623j:plain

www.shuwasystem.co.jp

Apache Spark 単体というより、それを含めたシステム全体について書かれている本だったので購入。
特に、”Chapter 4 Fluentd、Kafka によるデータ収集”と”Chapter 8 Spark SQL によるデータ処理”に興味があったりします。

さよならの朝に約束の花をかざろう 公式設定資料集

f:id:PANTOMAIMU:20180315202627j:plain

現時点で、映画館で2回観ていますw
設定資料集を買うほど入れ込むのは、多分シン・ゴジラ以来です :-)

早く円盤が出てくれないかな...

systemdでのサービス起動シーケンスの確認方法(systemd-analyze)

そんなわけで、久しぶりのブログ更新(∩´∀`)∩

最近、serviseファイルを作ってオリジナルサービスを作ることになって、systemdで起動されるサービスの起動順序を調べる必要が出てきました。
色々調べていたら、systemd-analyzeというコマンドが使えることが分かったので、ちょっと使ってみました。
このsystemd-analyzeは、systemdで起動する各サービスの起動に掛かった時間などを調べて、OS起動速度のボトルネック解析に使うものです。

このコマンド、起動シーケンスやサービスの起動時間を、SVG形式のガントチャート(?)イメージで出力することができます。

以下のように、plot を指定して実行すると、SVG形式のテキストを出力してくれるので、その出力を適当なファイルに保存します。

$ systemd-analyze plot > systemd_plot.svg

保存したSVGファイルをブラウザで表示してみると、サービスの起動順序と時間が一目瞭然で確認できるチャートとして表示できます。

f:id:PANTOMAIMU:20170802204608p:plain

チャート全体のイメージはこんな感じ。
f:id:PANTOMAIMU:20170802204522j:plain


以下のイメージは、ネットワークサービスの起動完了後に実行されるサービス部分を拡大したものです。
f:id:PANTOMAIMU:20170802204549p:plain
赤い色の部分が、起動に掛かった時間を示しています。

試しにnetwork.targetの起動後に起動している、postfixのserviceファイルを確認してみると、以下のようにAfterにnetwork.targetが定義されていました。

[Unit]
Description=Postfix Mail Transport Agent
After=syslog.target network.target
Conflicts=sendmail.service exim.service

[Service]
Type=forking
PIDFile=/var/spool/postfix/pid/master.pid
EnvironmentFile=-/etc/sysconfig/network
ExecStartPre=-/usr/libexec/postfix/aliasesdb
ExecStartPre=-/usr/libexec/postfix/chroot-update
ExecStart=/usr/sbin/postfix start
ExecReload=/usr/sbin/postfix reload
ExecStop=/usr/sbin/postfix stop

[Install]
WantedBy=multi-user.target


こんな感じで、systemdで制御されているサービスの起動順序をお手軽に(?)確認することができました(`・ω・´)