こんにちは、ナナオです。

k8sを構築してからどう活用しようかいろいろやってるのですが、一つ面倒なのが「複数のノードへ同じことを適用」するという作業です。

今回はこれをAnsibleで共通化していこうと思います。

Ansibleとは

Ansibleだけで書籍になるほどなので、ここではざっと書きます。

Amazon.co.jp: Ansible実践ガイド 第4版[基礎編] (impress top gear) : 北山 晋吾, 佐藤 学, 塚本 正隆, 畠中 幸司, 横地 晃: 本

Ansibleは構成管理ツールの一つで、目的は「環境構築の自動化」です。

ドキュメントを見ながら環境構築したり、shファイルを組んだりすると思いますが、こういった作業を一元的に管理するためのツールがAnsibleです。

そんなAnsibleの特徴としては「冪等性」が挙げられます。

これはつまり、手作業で作ったshでよくある「これを各サーバーで実行する」というようなものではなく、「各サーバーは~~という状態であるべき」というあるべき状態を定義できるという点にあります。

もちろん状態監視など実装的には複雑になるんですが、あるべき姿が定義できる状態って所謂システムの属人化を防ぐという観点からもとてもいいことですね!

環境構築

ではAnsibleをインストールしていきます。

homebrewがインストールされている環境であれば以下のコマンドでインストール可能です。

brew install ansible

インストールできました。

最初の一歩

さて、何から始めればいいか。。

とりあえずチュートリアルも兼ねてhello world的なことをやりたい。

ということで以下のサイトを参考にまずはhosts.yamlを定義しました。

https://zenn.dev/y_mrok/books/ansible-no-tsukaikata/viewer/chapter5

とりあえずk8sで構築したノードは三台あるので、これらの情報をhosts.yamlとして落とし込みました。

---
all:
  vars:
    ansible_user: username
    ansible_password: password
  hosts:
    thinkcentle1:
      ansible_host: 192.168.0.x
    nuc1:
      ansible_host: 192.168.0.x
    mouse1:
      ansible_host: 192.168.0.x

定義出来たら先ほどインストールしたansibleコマンドで簡単なコマンドを書く環境で実行してみます。

ansible all -i hosts.yaml -m ansible.builtin.command -a "df -H"

結果が出力されました。テンション上がる~~

プレイブックの実装

さて、ではAnsibleのメイン機能と言えるプレイブックを実装していきます。

今回は各ノードからnfsを扱えるようにするのと、k8sで構築したDockerイメージ格納用のプライベートレジストリのURLを設定します。

(プライベートレジストリの構築に関してはまた別でブログを書こうと思っています!)

https://docs.k3s.io/ja/installation/private-registry

- hosts: all
  become: yes
  tasks:
    - name: nfs-commonのインストール
      apt:
        name: nfs-common
        state: present
        update_cache: yes

    - name: /etc/rancher/k3s ディレクトリの作成
      file:
        path: /etc/rancher/k3s
        state: directory
        mode: '0755'

    - name: registries.yaml の配置
      copy:
        src: ./registries.yaml
        dest: /etc/rancher/k3s/registries.yaml
        owner: root
        group: root
        mode: '0644'
      notify: restart k3s services

  handlers:
    - name: restart k3s services
      block:
        - name: K3sサーバーの再起動
          systemd:
            name: k3s
            state: restarted
          ignore_errors: yes

        - name: K3sエージェントの再起動
          systemd:
            name: k3s-agent
            state: restarted
          ignore_errors: yes

k8sの再起動処理はハンドラーで実装しました。

これを実行します。

ansible-playbook -i hosts.yaml playbook.yaml -K

-Kオプションはsudoで行う作業がある場合に付けるコマンドです。

実行すると「registries.yaml の配置」の際にエラーが出力されました。

TASK [registries.yaml の配置] ******************************************************************************
[ERROR]: The requested handler 'restart k3s services' was not found in either the main handlers list nor in the listening handlers list

どうやら名前が完全に一致していなかったようです。

空白を使うのがよくないのかな?アンダーバーで埋めるように修正しました。

- hosts: all
  become: yes
  tasks:
    - name: nfs-commonのインストール
      apt:
        name: nfs-common
        state: present
        update_cache: yes

    - name: /etc/rancher/k3s ディレクトリの作成
      file:
        path: /etc/rancher/k3s
        state: directory
        mode: '0755'

    - name: registries.yaml の配置
      copy:
        src: ./registries.yaml
        dest: /etc/rancher/k3s/registries.yaml
        owner: root
        group: root
        mode: '0644'
      notify:
        - restart_k3s

  handlers:
    - name: restart_k3s
      systemd:
        name: k3s
        state: restarted
      ignore_errors: yes

今度は成功しました!(python関係の警告は出てるけど。。)

❯ ansible-playbook -i update-node-ansible/hosts.yaml update-node-ansible/playbook.yaml -K
BECOME password:
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details

PLAY [all] *************************************************************************************************

TASK [Gathering Facts] *************************************************************************************
[WARNING]: Host 'thinkcentle1' is using the discovered Python interpreter at '/usr/bin/python3.12', but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.20/reference_appendices/interpreter_discovery.html for more information.
ok: [thinkcentle1]
[WARNING]: Host 'mouse1' is using the discovered Python interpreter at '/usr/bin/python3.12', but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.20/reference_appendices/interpreter_discovery.html for more information.
ok: [mouse1]
[WARNING]: Host 'nuc1' is using the discovered Python interpreter at '/usr/bin/python3.12', but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.20/reference_appendices/interpreter_discovery.html for more information.
ok: [nuc1]

TASK [nfs-commonのインストール] ****************************************************************************
ok: [thinkcentle1]
ok: [mouse1]
ok: [nuc1]

TASK [/etc/rancher/k3s ディレクトリの作成] *****************************************************************
ok: [thinkcentle1]
ok: [mouse1]
ok: [nuc1]

TASK [registries.yaml の配置] ******************************************************************************
changed: [thinkcentle1]
changed: [mouse1]
changed: [nuc1]

RUNNING HANDLER [restart_k3s] ******************************************************************************
changed: [thinkcentle1]
changed: [nuc1]
changed: [mouse1]

PLAY RECAP *************************************************************************************************
mouse1                     : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
nuc1                       : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
thinkcentle1               : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

感想

ということで非常に簡単に構築できてしまいました。

今後も使用する機会があれば積極的に活用していきたいと思います。

参考

Ansibleとは何か 構成管理ツールの目的〜Ansible導入まで最速で理解する #Python - Qiita

https://zenn.dev/y_mrok/books/ansible-no-tsukaikata