Cloud-Configスクリプトの概要

前書き

最近のディストリビューションで利用可能なcloud-initプログラム(この記事の執筆時点ではUbuntu14.04とCentOS7のみ)は、DigitalOcean metadata serviceuser-dataフィールドからのデータを消費して実行できます。 このプロセスは、検出した情報の形式によって動作が異なります。 user-data内のスクリプトで最も一般的な形式の1つは、cloud-configファイル形式です。

cloud-configファイルは、cloud-initプロセスによって実行されるように設計された特別なスクリプトです。 これらは通常、サーバーの最初の起動時の初期構成に使用されます。 このガイドでは、cloud-configファイルの形式と使用方法について説明します。

Cloud-Configに関する一般情報

cloud-config形式は、多くの一般的な構成項目の宣言型構文を実装しているため、多くのタスクを簡単に実行できます。 また、定義済みの宣言機能の範囲外にあるものに任意のコマンドを指定できます。

この「両方のベスト」アプローチにより、ファイルは一般的なタスクの構成ファイルのように機能し、より複雑な機能のスクリプトの柔軟性を維持します。

YAMLフォーマット

ファイルはYAMLデータシリアル化形式を使用して書き込まれます。 YAML形式は、人間が理解しやすく、プログラムで解析しやすいように作成されました。

YAMLファイルは一般に、それらを読むときに理解するのがかなり直感的ですが、それらを支配する実際のルールを知っているのは良いことです。

YAMLファイルの重要なルールは次のとおりです。

  • 空白を含むインデントは、アイテムの構造と相互の関係を示します。 よりインデントされたアイテムは、最初のアイテムのサブアイテムであり、その上のインデントのレベルは低くなります。

  • リストのメンバーは、先頭のダッシュで識別できます。

  • 連想配列エントリは、コロン(:)の後にスペースと値を続けて作成されます。

  • テキストのブロックはインデントされます。 フォーマットを維持したままブロックをそのまま読み込む必要があることを示すには、ブロックの前にパイプ文字(|)を使用します。

これらのルールを使用して、cloud-configファイルの例を分析し、フォーマットのみに注意してみましょう。

#cloud-config
users:
  - name: demo
    groups: sudo
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf0q4PyG0doiBQYV7OlOxbRjle026hJPBWD+eKHWuVXIpAiQlSElEBqQn0pOqNJZ3IBCvSLnrdZTUph4czNC4885AArS9NkyM7lK27Oo8RV888jWc8hsx4CD2uNfkuHL+NI5xPB/QT3Um2Zi7GRkIwIgNPN5uqUtXvjgA+i1CS0Ku4ld8vndXvr504jV9BMQoZrXEST3YlriOb8Wf7hYqphVMpF3b+8df96Pxsj0+iZqayS9wFcL8ITPApHi0yVwS8TjxEtI3FDpCbf7Y/DmTGOv49+AWBkFhS2ZwwGTX65L61PDlTSAzL+rPFmHaQBHnsli8U9N6E4XHDEOjbSMRX [email protected]
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcthLR0qW6y1eWtlmgUE/DveL4XCaqK6PQlWzi445v6vgh7emU4R5DmAsz+plWooJL40dDLCwBt9kEcO/vYzKY9DdHnX8dveMTJNU/OJAaoB1fV6ePvTOdQ6F3SlF2uq77xYTOqBiWjqF+KMDeB+dQ+eGyhuI/z/aROFP6pdkRyEikO9YkVMPyomHKFob+ZKPI4t7TwUi7x1rZB1GsKgRoFkkYu7gvGak3jEWazsZEeRxCgHgAV7TDm05VAWCrnX/+RzsQ/1DecwSzsP06DGFWZYjxzthhGTvH/W5+KFyMvyA+tZV4i1XM+CIv/Ma/xahwqzQkIaKUwsldPPu00jRN [email protected]
runcmd:
  - touch /test.txt

このファイルを見ると、多くの重要なことがわかります。

まず、各cloud-configファイルは、最初の行で#cloud-configのみで始まる必要があります。 これは、これがcloud-configファイルとして解釈されるべきであることをcloud-initプログラムに通知します。 これが通常のスクリプトファイルである場合、最初の行はファイルの実行に使用されるインタープリターを示します。

上記のファイルには、usersruncmdの2つのトップレベルディレクティブがあります。 これらは両方ともキーとして機能します。 これらのキーの値は、キーの後のインデントされたすべての行で構成されます。

usersキーの場合、値は単一のリスト項目です。 次のレベルのインデントはリスト項目を指定するダッシュ(-)であり、このインデントレベルにはダッシュが1つしかないためです。 usersディレクティブの場合、これは偶然にも、単一のユーザーのみを定義していることを示しています。

リスト項目自体には、より多くのキーと値のペアを持つ連想配列が含まれています。 これらはすべて同じレベルのインデントで存在するため、兄弟要素です。 各ユーザー属性は、上で説明した単一のリストアイテムに含まれています。

注意すべき点は、表示される文字列は引用符を必要とせず、関連付けを定義するための不必要な括弧がないことです。 インタプリタはデータタイプをかなり簡単に判断でき、インデントは人間とプログラムの両方のアイテムの関係を示します。

ここまでで、YAML形式の実用的な知識が得られ、上記で説明したルールを使用して情報を快適に操作できるはずです。

これで、cloud-configの最も一般的なディレクティブのいくつかを調べ始めることができます。

ユーザーとグループの管理

システムで新しいユーザーを定義するには、上記のサンプルファイルで見たusersディレクティブを使用できます。

ユーザー定義の一般的な形式は次のとおりです。

#cloud-config
users:
  - first_user_parameter
    first_user_parameter

  - second_user_parameter
    second_user_parameter
    second_user_parameter
    second_user_parameter

新しいユーザーはそれぞれダッシュで始める必要があります。 各ユーザーは、キーと値のペアでパラメーターを定義します。 次のキーを定義に使用できます。

  • name:アカウントのユーザー名。

  • primary-group:ユーザーのプライマリグループ。 デフォルトでは、これはユーザー名に一致するグループが作成されます。 ここで指定するグループは、すでに存在するか、明示的に作成する必要があります(これについてはこのセクションで後述します)。

  • groups:任意の補足グループをコンマで区切ってここにリストできます。

  • gecos:ユーザーに関する補足情報のフィールド。

  • shell:ユーザーに設定する必要のあるシェル。 これを設定しない場合、非常に基本的なshシェルが使用されます。

  • expiredate:アカウントの有効期限が切れる日付(YYYY-MM-DD形式)。

  • sudo:ユーザー名フィールドなしでsudo特権を定義する場合に使用するsudo文字列。

  • lock-passwd:これはデフォルトで「True」に設定されています。 これを「False」に設定して、ユーザーがパスワードでログインできるようにします。

  • passwd:アカウントのハッシュ化されたパスワード。

  • ssh-authorized-keys:このユーザーの.sshディレクトリにあるauthorized_keysファイルに追加する必要がある完全なSSH公開鍵のリスト。

  • inactive:アカウントを非アクティブに設定するブール値。

  • system:「True」の場合、このアカウントはホームディレクトリのないシステムアカウントになります。

  • homedir:デフォルトの/home/<username>をオーバーライドするために使用されます。これは、別の方法で作成および設定されます。

  • ssh-import-id:LaunchPadからインポートするSSHID。

  • selinux-user:これは、このアカウントのログインに使用する必要があるSELinuxユーザーを設定するために使用できます。

  • no-create-home:ユーザーの/home/<username>ディレクトリが作成されないように、「True」に設定します。

  • no-user-group:ユーザーと同じ名前のグループが作成されないようにするには、「True」に設定します。

  • no-log-init:ユーザーログインデータベースを開始しないようにするには、「True」に設定します。

nameキーなどのいくつかの基本情報を除いて、デフォルトから逸脱している領域、または必要なデータを提供している領域を定義するだけで済みます。

ユーザーが理解することが重要なことの1つは、指定された値をすぐに変更するメカニズムがない限り、passwdフィールドを実動システムでnotを使用する必要があるということです。 ユーザーデータとして送信されたすべての情報と同様に、ハッシュはサーバーの存続期間中、システム上のanyユーザーがアクセスできる状態を維持します。 最新のハードウェアでは、これらのハッシュは簡単な時間で簡単に解読できます。 ハッシュでさえ公開することは、使い捨てではないマシンでとるべきではない大きなセキュリティリスクです。

ユーザー定義の例として、上記のcloud-configの例の一部を使用できます。

#cloud-config
users:
  - name: demo
    groups: sudo
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf0q4PyG0doiBQYV7OlOxbRjle026hJPBWD+eKHWuVXIpAiQlSElEBqQn0pOqNJZ3IBCvSLnrdZTUph4czNC4885AArS9NkyM7lK27Oo8RV888jWc8hsx4CD2uNfkuHL+NI5xPB/QT3Um2Zi7GRkIwIgNPN5uqUtXvjgA+i1CS0Ku4ld8vndXvr504jV9BMQoZrXEST3YlriOb8Wf7hYqphVMpF3b+8df96Pxsj0+iZqayS9wFcL8ITPApHi0yVwS8TjxEtI3FDpCbf7Y/DmTGOv49+AWBkFhS2ZwwGTX65L61PDlTSAzL+rPFmHaQBHnsli8U9N6E4XHDEOjbSMRX [email protected]
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcthLR0qW6y1eWtlmgUE/DveL4XCaqK6PQlWzi445v6vgh7emU4R5DmAsz+plWooJL40dDLCwBt9kEcO/vYzKY9DdHnX8dveMTJNU/OJAaoB1fV6ePvTOdQ6F3SlF2uq77xYTOqBiWjqF+KMDeB+dQ+eGyhuI/z/aROFP6pdkRyEikO9YkVMPyomHKFob+ZKPI4t7TwUi7x1rZB1GsKgRoFkkYu7gvGak3jEWazsZEeRxCgHgAV7TDm05VAWCrnX/+RzsQ/1DecwSzsP06DGFWZYjxzthhGTvH/W5+KFyMvyA+tZV4i1XM+CIv/Ma/xahwqzQkIaKUwsldPPu00jRN [email protected]

グループを定義するには、groupsディレクティブを使用する必要があります。 このディレクティブは、作成するグループのリストを取得するという点で比較的単純です。

これに対するオプションの拡張機能は、作成しているグループのいずれかのサブリストを作成することです。 この新しいリストは、このグループに配置されるユーザーを定義します。

#cloud-config
groups:
  - group1
  - group2: [user1, user2]

既存のユーザーのパスワードを変更する

すでに存在するユーザーアカウント(rootアカウントが最も適切です)の場合、chpasswdディレクティブを使用してパスワードを指定できます。

Note:このディレクティブはデバッグ状況でonlyを使用する必要があります。これも、サーバーの存続期間中、システム上のすべてのユーザーが値を使用できるためです。 このディレクティブで送信されるパスワードはplain textで指定する必要があるため、これはこのセクションでさらに関連性があります。

基本的な構文は次のようになります。

#cloud-config
chpasswd:
  list: |
    user1:password1
    user2:password2
    user3:password3
  expire: False

このディレクティブには、2つの連想配列キーが含まれています。 listキーには、割り当てたいアカウント名と関連するパスワードを一覧表示するブロックが含まれます。 expireキーは、最初の起動時にパスワードを変更する必要があるかどうかを決定するブール値です。 デフォルトは「True」です。

注意すべき点の1つは、パスワードを「RANDOM」または「R」に設定できることです。これにより、ランダムなパスワードが生成され、/var/log/cloud-init-output.logに書き込まれます。 このファイルはシステム上のすべてのユーザーがアクセスできるため、これ以上安全ではないことに注意してください。

ファイルをディスクに書き込む

ファイルをディスクに書き込むには、write_filesディレクティブを使用する必要があります。

書き込まれる各ファイルは、ディレクティブの下のリスト項目によって表されます。 これらのリスト項目は、各ファイルのプロパティを定義する連想配列になります。

この配列に必要なキーは、ファイルの書き込み先を定義するpathと、ファイルに含めるデータを含むcontentだけです。

write_filesアイテムを構成するために使用できるキーは次のとおりです。

  • path:ファイルを書き込む必要があるファイルシステム上の場所への絶対パス。

  • content:ファイルに配置する必要のあるコンテンツ。 複数行入力の場合、「コンテンツ」行でパイプ文字(|)を使用してブロックを開始し、コンテンツを含むインデントされたブロックを続けます。 バイナリファイルには、「!! binary」とパイプ文字の前にスペースを含める必要があります。

  • owner:ファイルの所有権を付与する必要があるユーザーアカウントとグループ。 これらは「username:group」形式で指定する必要があります。

  • permissions:このファイルに指定する必要がある8進数のアクセス許可セット。

  • encoding:ファイルのオプションのエンコーディング仕様。 これは、Base64ファイルの場合は「b64」、Gzip圧縮ファイルの場合は「gzip」、組み合わせの場合は「gz + b64」です。 これを省略すると、デフォルトの従来のファイルタイプが使用されます。

たとえば、次の内容のファイルを/test.txtに書き込むことができます。

Here is a line.
Another line is here.

これを達成するcloud-configの部分は、次のようになります。

#cloud-config
write_files:
  - path: /test.txt
    content: |
      Here is a line.
      Another line is here.

サーバーでパッケージを更新またはインストールする

パッケージを管理するには、いくつかの関連する設定とディレクティブに留意する必要があります。

Debianベースのディストリビューションでaptデータベースを更新するには、package_updateディレクティブを「true」に設定する必要があります。 これは、コマンドラインからapt-get updateを呼び出すことと同義です。

デフォルト値は実際には「true」であるため、このディレクティブを無効にする場合にのみ、このディレクティブについて心配する必要があります。

#cloud-config
package_update: false

サーバーが初めて起動した後にサーバー上のすべてのパッケージをアップグレードする場合は、package_upgradeディレクティブを設定できます。 これは、手動で実行されるapt-get upgradeに似ています。

これはデフォルトで「false」に設定されているため、機能が必要な場合は必ず「true」に設定してください。

#cloud-config
package_upgrade: true

追加のパッケージをインストールするには、「packages」ディレクティブを使用してパッケージ名をリストするだけです。 各リスト項目はパッケージを表す必要があります。 上記の2つのコマンドとは異なり、このディレクティブはyumまたはapt管理対象ディストリビューションで機能します。

これらのアイテムは、2つの形式のいずれかを取ることができます。 最初は、パッケージの名前を含む単純な文字列です。 2番目の形式は、2つの項目を持つリストです。 この新しいリストの最初の項目はパッケージ名であり、2番目の項目はバージョン番号です。

#cloud-config
packages:
  - package_1
  - package_2
  - [package_3, version_num]

「packages」ディレクティブはapt_updateをtrueに設定し、以前の設定を上書きします。

ユーザーアカウントとSSHデーモンのSSHキーを構成する

SSHキーはusersディレクティブで管理できますが、専用のssh_authorized_keysセクションで指定することもできます。 これらは、最初に定義されたユーザーのauthorized_keysファイルに追加されます。

これは、usersディレクティブ内のキー指定と同じ一般的な形式を取ります。

#cloud-config
ssh_authorized_keys:
  - ssh_key_1
  - ssh_key_2

SSHサーバーの秘密鍵を事前に生成して、ファイルシステムに配置することもできます。 これは、クライアントに事前にこのサーバーに関する情報を提供し、サーバーがオンラインになるとすぐにサーバーを信頼できるようにする場合に便利です。

これを行うには、ssh_keysディレクティブを使用できます。 これは、rsa_privatersa_publicdsa_privatedsa_publicecdsa_private、およびecdsa_publicを使用して、RSA、DSA、またはECDSAキーのキーペアを取得できます。 )のサブアイテム。

秘密鍵ではフォーマットと改行が重要であるため、これらを指定するときは必ずパイプキーを持つブロックを使用してください。 また、mustには、キーを有効にするための開始キーと終了キーの行が含まれています。

#cloud-config
ssh_keys:
  rsa_private: |
    -----BEGIN RSA PRIVATE KEY-----
    your_rsa_private_key
    -----END RSA PRIVATE KEY-----

  rsa_public: your_rsa_public_key

信頼できるCA証明書を設定する

インフラストラクチャが内部認証局によって署名されたキーに依存している場合、証明書情報を注入することにより、CA証明書を信頼するように新しいマシンをセットアップできます。 このために、ca-certsディレクティブを使用します。

このディレクティブには2つのサブアイテムがあります。 1つ目はremove-defaultsで、trueに設定すると、デフォルトで含まれている通常の証明書の信頼情報がすべて削除されます。 これは通常必要ではなく、何をしているのかわからない場合はいくつかの問題を引き起こす可能性があるため、注意して使用してください。

2番目の項目はtrustedです。これはリストであり、それぞれに信頼できるCA証明書が含まれています。

#cloud-config
ca-certs:
  remove-defaults: true
  trusted:
    - |
      -----BEGIN CERTIFICATE-----
      your_CA_cert
      -----END CERTIFICATE-----

特定のDNSサーバーを使用するようにresolv.confを構成する

使用する独自のDNSサーバーを構成している場合は、resolv_confディレクティブを使用してサーバーのresolv.confファイルを管理できます。 これは現在、RHELベースのディストリビューションでのみ機能します。

resolv_confディレクティブでは、nameserverssearchdomainsdomain、およびoptionsの項目を使用して設定を管理できます。

nameserversディレクティブは、ネームサーバーのIPアドレスのリストを取得する必要があります。 searchdomainsディレクティブは、ユーザーがドメインではなくホストを指定した場合に検索するドメインとサブドメインのリストを取得します。

domainは、解決できない要求に使用する必要があるドメインを設定し、optionsには、resolv.confファイルで定義できる一連のオプションが含まれています。

resolv_confディレクティブを使用している場合は、manage-resolv-confディレクティブもtrueに設定されていることを確認する必要があります。 そうしないと、設定が無視されます。

#cloud-config
manage-resolv-conf: true
resolv_conf:
  nameservers:
    - 'first_nameserver'
    - 'second_nameserver'
  searchdomains:
    - first.domain.com
    - second.domain.com
  domain: domain.com
  options:
    option1: value1
    option2: value2
    option3: value3

より詳細な制御のための任意のコマンドの実行

cloud-configが提供する管理対象アクションのいずれも、実行したいことに対して機能しない場合は、任意のコマンドを実行することもできます。 これは、runcmdディレクティブを使用して実行できます。

このディレクティブは、実行するアイテムのリストを取ります。 これらのアイテムは、2つの異なる方法で指定できます。これは、アイテムの処理方法に影響します。

リストアイテムが単純な文字列の場合、アイテム全体がshシェルプロセスに渡されて実行されます。

もう1つのオプションは、リストを渡すことです。リストの各項目は、execveがコマンドを処理する方法と同様の方法で実行されます。 最初の項目は実行するコマンドまたはスクリプトとして解釈され、次の項目はそのコマンドの引数として渡されます。

ほとんどのユーザーはこれらの形式のいずれかを使用できますが、柔軟性があるため、特別な要件がある場合は最適なオプションを選択できます。 すべての出力は、標準出力と/var/log/cloud-init-output.logファイルに書き込まれます。

#cloud-config
runcmd:
  - [ sed, -i, -e, 's/here/there/g', some_file]
  - echo "modified some_file"
  - [cat, some_file]

サーバーのシャットダウンまたは再起動

場合によっては、他の項目を実行した後にサーバーをシャットダウンまたは再起動する必要があります。 これを行うには、power_stateディレクティブを設定します。

このディレクティブには、設定可能な4つのサブアイテムがあります。 これらは、delaytimeoutmessage、およびmodeです。

delayは、将来どのくらいの期間、再起動またはシャットダウンが発生するかを指定します。 デフォルトでは、これは「今」になり、手順がすぐに開始されることを意味します。 遅延を追加するには、ユーザーは+<num_of_mins>形式を使用して経過する時間を分単位で指定する必要があります。

timeoutパラメーターは、delayカウントダウンを開始する前にcloud-initが完了するのを待機する秒数を表す単位なしの値を取ります。

messageフィールドでは、システムのすべてのユーザーに送信されるメッセージを指定できます。 modeは、開始する電源イベントのタイプを指定します。 これは、サーバーをシャットダウンする「poweroff」、サーバーを再起動する「reboot」、またはシステムに最適なアクションを決定させる「halt」(通常はシャットダウン)です。

#cloud-config
power_state:
  timeout: 120
  delay: "+5"
  message: Rebooting in five minutes. Please save your work.
  mode: reboot

結論

上記の例は、cloud-configファイルを実行するときに使用できる一般的な構成項目の一部を表しています。 このガイドでは説明しなかった追加機能があります。 これらには、構成管理のセットアップ、追加のリポジトリの構成、およびサーバーの初期化時に外部URLでの登録さえ含まれます。

/usr/share/doc/cloud-init/examplesディレクトリを確認すると、これらのオプションのいくつかについて詳しく知ることができます。 cloud-configファイルに慣れるための実用的なガイドについては、こちらのhow to use cloud-config to complete basic server configurationに関するチュートリアルに従うことができます。

Related