Argo CDでCalicoをデプロイしているとmetadata.annotations: Too longエラーが出る

はじめに

TL; DR

  • Argo CDのApplicatoinのsyncOptionsServerSideApply=trueを追加すれば良い

github.com

問題

スクショを取っていなくて申し訳ないんですが、CalicoのHelm Chartをアップデートしたところ以下のようなエラーが出るようになりました。

CustomResourceDefinition.apiextensions.k8s.io "installations.operator.tigera.io" is invalid: metadata.annotations: Too long: must have at most 262144 bytes

解決策

こちらの記事が参考になりましたが、Argo CDは大きなCRDを同期する場合にエラーになるようでして、
その場合はServerSideApplyを有効化にすれば良いようです。

www.arthurkoziel.com

おうちクラスタでも、ServerSideApplyを有効化にしたらエラーが出なくなりました。

  syncPolicy:
    syncOptions:
    - CreateNamespace=true
+    - ServerSideApply=true
    automated:
      prune: true
      selfHeal: true

github.com

めでたし、めでたし。

いずれはServerSideApplyがデフォルトの挙動になるような記述がありますが、どうなんでしょうかね。

ルーターの設定ファイルをArgo WorkflowsでS3にバックアップする方法

はじめに

今回は、自宅で使用しているルーターの設定ファイルをArgo Workflowsを使ってS3にバックアップする方法について説明します。

Argo Workflowsとは

Argo Workflowsは、ワークフローエンジンの1つであり、コンテナベースのジョブオーケストレーションを提供します。
Argo Projectの1つであり、Kubernetes上でのジョブ管理に特化しています。

argoproj.github.io

CronWorkflowとは

CronWorkflowは、Argo WorkflowsのCRDの1つで、CronJobのように定義したスケジュールに従ってWorkflowを実行してくれます。
CronWorkflowは、Workflowの定義の中にスケジュールを記述し、指定されたスケジュールに従ってArgo WorkflowsがWorkflowを実行します。

argoproj.github.io

設定をファイルとして出力する

RTX1300の設定をファイルとして出力するためには、Ansibleを使います。

Playbookでは、以下のようにして設定をファイル化しています。

  1. show config で標準出力に設定内容を書きだす
  2. 1の結果をconfig.txtに保存する

これを実行するためのPlaybookをConfigMapとして定義します。

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: backup-playbooks
data:
  backup.yaml: |
    ---
    - hosts: all
      connection: network_cli
      vars:
        ansible_network_os: yamaha_network.rtx.rtx
      tasks:
        - name: get configuration
          yamaha_network.rtx.rtx_command:
            commands:
            - show config
          register: result
        - name: Copy output to file
          ansible.builtin.copy:
            content: "{{ result.stdout[0] }}"
            dest: "config.txt"
        - name: Print config
          ansible.builtin.debug:
            msg:
              - "{{ result.stdout[0] }}"

これで設定をファイルとして出力するためのPlaybookができたので、CronWorkflowを定義してWorkflowが定期的に実行されるようにします。
日本時間の午前0時に実行されるように定義し、volumeMountsで先ほどのPlaybookをマウントして実行するように定義します。

---
apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
metadata:
  name: backup
spec:
  timezone: 'Asia/Tokyo'
  schedule: "0 0 * * *"
  concurrencyPolicy: "Allow"
  startingDeadlineSeconds: 0
  workflowSpec:
    entrypoint: backup
    templates:
    - name: backup
      serviceAccountName: backup
      volumes:
      - name: playbooks
        configMap:
          name: backup-playbooks
      container:
        image: ghcr.io/corrupt952/home/ansible:85f40b4ceff32b809d507d234920ce45b2303a60
        env:
          - name: ANSIBLE_HOST_KEY_CHECKING
            value: "False"
        envFrom:
        - secretRef:
            name: backup-credentials
        volumeMounts:
        - name: playbooks
          mountPath: /playbooks
        command:
        - bash
        - -lc
        # NOTE: When specifying an IP address directly in the i option,
        #       a trailing comma is used to treat it as an IP address instead of a file.
        - >-
            ansible-playbook
            --ssh-common-args="-o StrictHostKeyChecking=no"
            -e "ansible_user=$BACKUP_USERNAME ansible_ssh_pass=$BACKUP_PASSWORD"
            -i "$BACKUP_HOSTNAME,"
            /playbooks/backup.yaml

出力した設定ファイルをS3にアップロードする

Argo WorkflowsのWorkflowには、コンテナ上にあるファイルを外部ストレージへ保存するための機能がついています。
この機能を使用して、Argo WorkflowsでS3ファイルにアップロードすることができます。

argoproj.github.io

argoproj.github.io

外部ストレージへの保存設定は各templatesのoutputsに定義します。

---
apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
metadata:
  name: backup
spec:
  timezone: 'Asia/Tokyo'
  schedule: "0 0 * * *"
  concurrencyPolicy: "Allow"
  startingDeadlineSeconds: 0
  workflowSpec:
    entrypoint: backup
    templates:
    - name: backup
      serviceAccountName: backup
      volumes:
      - name: playbooks
        configMap:
          name: backup-playbooks
      container:
        image: ghcr.io/corrupt952/home/ansible:85f40b4ceff32b809d507d234920ce45b2303a60
        env:
          - name: ANSIBLE_HOST_KEY_CHECKING
            value: "False"
        envFrom:
        - secretRef:
            name: backup-credentials
        volumeMounts:
        - name: playbooks
          mountPath: /playbooks
        command:
        - bash
        - -lc
        # NOTE: When specifying an IP address directly in the i option,
        #       a trailing comma is used to treat it as an IP address instead of a file.
        - >-
            ansible-playbook
            --ssh-common-args="-o StrictHostKeyChecking=no"
            -e "ansible_user=$BACKUP_USERNAME ansible_ssh_pass=$BACKUP_PASSWORD"
            -i "$BACKUP_HOSTNAME,"
            /playbooks/backup.yaml

      # ここから下が追記
      outputs:
        artifacts:
          - name: config
            path: /home/ansible/config.txt
            s3:
              endpoint: s3.dualstack.ap-northeast-1.amazonaws.com
              bucket: x
              key: backup/routers/rtx1300/config.txt
              accessKeySecret:
                name: backup-credentials
                key: BACKUP_AWS_ACCESS_KEY_ID
              secretKeySecret:
                name: backup-credentials
                key: BACKUP_AWS_SECRET_ACCESS_KEY

これで毎日設定ファイルをS3ファイルにアップロードすることができました。

実務上の応用例

今回は自宅のルーターの設定ファイルのバックアップについて説明しましたが、Argo Workflowsを使うことで、様々な用途に利用することができます。

  • CronJobをCronWorkflowに置き換え、各種実行ログを外部ストレージへ直接保存する
  • 調査・分析用Worklfow実行後に生成されるファイルを外部ストレージへ保存する
  • 賛否はありますが、アプリケーションのバッチ処理から外部ストレージへの保存処理を分離する

おわりに

今回は、Argo Workflowsを使って、自宅で使用しているルーターの設定ファイルをS3にバックアップする方法について説明しました。
Argo Workflowsは、Kubernetes上でのジョブ管理に特化しており、CronWorkflowという機能を利用することで、定期的に実行されるジョブを簡単に定義することができます。
Argo Workflowsを使って、様々な用途に利用することができるので、ぜひ活用してみてください。

revealerというデバッグ用Webアプリを公開しました

注意事項

この記事は、Notion AIに対して

  • 問題と解決策の概要
  • 例示用のコード

を渡して生成した実験的な記事になります。

はじめに

revealerというHTTPのリクエストデータを表示するWebアプリを公開しました。

revealerとは

revealerは、アクセス元のIPアドレスやリクエストの詳細情報を表示するWebアプリです。
元々は、自分自身が開発中のアプリの検証用途で作成したものを、ブラッシュアップして公開したものになります。

github.com

そのためできることは、

  • アクセス元のIPアドレスの表示
  • リクエストヘッダや、リクエストボディ、クエリストリングが意図した値になっているか

になります。

CloudFlareを使っているため、それ関連のヘッダが余計についていますが無視してください。

実際に試してみる

revealerは、r.zuki.dev もしくは revealer.zuki.dev で実際にアクセスすることができます。

おわりに

今回は、HTTPリクエストデータを表示するWebアプリ「revealer」について紹介しました。
HTTPリクエストデータを確認したい時には、ぜひrevealerをご利用ください。

1周回って個人のタスク管理はGoogle Tasksでもいいかもしれない

昔から自分のタスク管理方法について2,3年に1度見直していますが、1周回ってGoogle Tasksでいいのかもしれないと思い始めてきた。

以下の記事のように必要な機能を洗い出して、その機能が担保できるものを使ってきている。

khasegawa.hatenablog.com

現在はNotionでWeekly Dashboardというのを毎週自動作成されるようにしており、それを使ってタスク管理している。

今の状態で決して不満はないし、管理しやすい方だとは思っているんだけど、 Google Calendarで予定調整をしているのもあって、タスクとスケジュールの2重管理になってしまっている。

Notion以外の会社が提供している有料サービスを使えば、Notionであってもこれを実現できるけど、 別にそこまでしてやりたいわけではない。
となってくると、案外Google Tasksが選択肢としてはいいんじゃないかと思えてきた。

ただ、Googleのサービスは急にサ終する可能性も否定できないから、Notionのままだったり、別のサービス(Mondayとか)のほうがいいかもしれないが、そこまでやるメリットがあるかは検討したい。

www.youtube.com

OpenAI API を使ったChrome 拡張「br1efly」の紹介

注意事項

この記事は、Notion AIに対して

  • 問題と解決策の概要
  • 例示用のコード

を渡して生成した実験的な記事になります。

はじめに

既に多くの方々が似たChrome拡張を作っているため何番煎じかは分かりませんが、Chrome拡張を作成しました。
今回は、自身の勉強のためにOpenAI APIと連携して、選択している文字列を操作する拡張でbr1eflyという名前にしています。

github.com

この記事では、br1eflyの使い方や設定方法などについて紹介します。新しい操作方法に挑戦したい方は、ぜひお試しください。

機能概要

br1eflyが現時点でできる機能は以下になります。

  • 要約
  • 言い換え
  • 言語検出
  • 対案の作成
  • 文章の構成

を行うことができます。
これらの機能は設定画面で選択した言語で出力されるように調整しています。

またOpenAIだけではなく、Azure OpenAI Serviceにも対応しているため、組織で契約している場合でも利用がしやすいです。

br1eflyの使い方

br1eflyを使うには、以下の手順を実行します。

  1. 操作をしたい文章をブラウザ上で選択する
  2. 右クリックをしてコンテキストメニューを開き、br1eflyのメニューから行いたい指示を選ぶ
  3. 選択範囲の1番下に"Processing..."というものが出てくるので、しばらく待つ
  4. エラーがなければ、"Processing..."の代わりに結果の文字列が表示される
  5. Closeを押して閉じる

手順を画像付きでスライドのように表示できるサービスを使っているマニュアルは以下です。(見れない場合があるかも?)

注意事項

  • 出力結果の言語は、設定画面で指定している言語になります
  • それなりに安定していますが、設定を無視して別の言語になることがあります

インストール

bri1eflyは現時点ではStoreに公開しているわけではないため、GitHubからzipをダウンロードして手動でインストールする必要があります。
API Keyなどを不正に取得するようなコードは書いていませんが、不安な方は気軽に質問でもしてください。

  1. br1eflyのリリースから最新版のzipをダウンロードする
  2. zipを展開する
  3. Chrome拡張の画面を開く
  4. Developer modeを有効にする
  5. Load unpackedで展開したディレクトリを選択する

手順を画像付きでスライドのように表示できるサービスを使っているマニュアルは以下です。(見れない場合があるかも?)

設定

br1eflyを使うためには、API Keyとエンドポイントの設定が必要です。

設定方法は以下の通りです。

  1. br1eflyのoptionsを開く
  2. Output Languageで出力結果の言語を指定する
  3. API TypeでOpenAIかAzureを選択する
  4. API Keyを入力する
  5. API Keyを発行したアカウントの利用可能なModelを選択する
  6. 【Azureのみ】 Endpointを入力する
  7. Saveをクリックして保存する

手順を画像付きでスライドのように表示できるサービスを使っているマニュアルは以下です。(見れない場合があるかも?)

追加したい機能

今後追加しておきたいと思っている機能は、以下になります。

  • 履歴機能
    • 元々は特定のプロンプトを特定の文字列に実行した結果を簡単に記録しておいて後から振り替えれるようにしたかったので気が向いたら実装するかも
  • データ構造・プログラミング言語変換機能
    • ブラウザで使うかは怪しいですが、ちょいちょい使うこともあるため実装されると嬉しいかも
  • ユーザが独自にメニューとプロンプトを追加できる機能
    • デフォルトで決まっている指示のみを実行しているが、組み込む前に動作確認をしたかったり、公開したくないプロンプトもあるため、この機能を追加したい
    • 関連してパラメータもプロンプトごとに設定できると嬉しい
  • 設定のExport/Import機能
    • 他の人と共有したい場合に簡単に共有できるようにしておきたい
    • APIキーなどは除外すると思います

ここには書いてないですが、ポップアップで表示されるHTMLをもう少しまともにするか、 任意の文字列を入れれるようにしておくことも検討しておきたいですね。

まとめ

本記事では、OpenAI APIを使ったChrome拡張「br1efly」について紹介しました。
機能の使い方や設定方法、また追加したい機能についても触れました。 仕組みの具体的な話や、TypeScriptで書くにあたって大変だったことなどは別の記事で触れようと思います。

ぜひ、APIの課金には気をつけながらbr1eflyを触ってみてください。

RTX1300の設定をAnsibleで管理する

注意事項

この記事は、Notion AIに対して

  • 問題と解決策の概要
  • 例示用のコード

を渡して生成した実験的な記事になります。

はじめに

この記事では、YAMAHA RTX1300ルーターをAnsibleでプロビジョニングする方法について紹介します。
家で管理している各種デバイスをコード化しているので、RTX1300の設定をAnsibleで管理することを試みました。

本記事では、RTX1300の設定についての簡単な説明と、プロビジョニングの方法について解説します。
無線APとしてWLX222を使っていますが、まだAnsible化できていないため、今回は対象外としています。

前提

  • RTX1300ルーターは趣味なので別のRTXルーターでもできる(はず)
  • 弊宅では通常のv6プラスではなく、「v6プラス」固定IPサービスを契約しているため、それ用の設定が書かれているので注意
  • 以前書いた記事にもある通り、有線・無線に関わらず個人向けと仕事向けのネットワークは分離しており、互いに通信できないようにしている

khasegawa.hatenablog.com

www.jpne.co.jp

平田区のネットワーク構成は、以下を参考にしてみてください。

github.com

Ansibleモジュールの準備

YAMAHA公式のAnsibleモジュールを使用することで、RTX1300の設定を簡単にプロビジョニングすることができます。

以下のURLからAnsibleモジュールをセットアップしてください。

github.com

ただし、基本的にはこの通りセットアップすれば使えるものの、HomebrewやLinuxbrewを使ってAnsibleをインストールしている場合は ansible-pylibssh を別途インストールしないとPlaybookの実行中にエラーが出る場合があります。

pip3 install ansible-pylibssh

また、Apple Siliconの場合は、ansible-pylibsshがインストールできない場合もあるようなので注意してください。

設定のコード化

設定はGUIで設定した内容から不要な内容を削除してコード化しています。
そのため、まだ設定は冗長だったり規則性があまりないコードになっていますがご了承ください。 また、全ての設定ではなく一部の設定は除外するようにしています。

github.com

ここからは一部のコードを抜粋して簡単な解説します。

用語説明

はじめにコード中に意味の分からない単語についての説明です。
中二病な変数名を設定しています。

  • 高天原(Takamagahara) … 住居用の通常ネットワーク
  • 中つ国(Nakatsukuni) … 仕事用のネットワーク
  • 黄泉(Yomi) … HomeLab用のネットワーク
  • 根の国(Nenokuni) … WAN

※ 私物のデスクトップやラップトップ、スマホに大罪名つけてるような筆者です

高天原からのみルーターにアクセスできる

sshdhttpdなどのサービスは有効化にする場合、高天原からのみのアクセスにしています。
中つ国からのアクセスは今の所許可予定はありません。

commands:
...
- httpd host {{ network.takamagahara.name }}
- sshd host {{ network.takamagahara.name }}
...

高天原と中つ国を分断する

前提でも書きましたが、高天原(個人用)と中つ国(仕事用)間では通信ができないようにしてあります。

これを表現するために、高天原と中つ国の通信を許可しない設定を定義し、中つ国のinoutともに設定しています。
こうすることで高天原と中つ国を分断できます。

# Filters
- ip filter 1000100 reject-nolog {{ network.nakatsukuni.cidr }} {{ network.takamagahara.cidr }} * * *
- ip filter 1000101 pass * * * * *
- ip filter 1000102 reject-nolog {{ network.takamagahara.cidr }} {{ network.nakatsukuni.cidr }} * * *

# Attach filters to Nakatsukuni
- ip {{ network.nakatsukuni.name }} secure filter in 1000100 1000101
- ip {{ network.nakatsukuni.name }} secure filter out 1000101 1000102

「v6プラス」固定IPサービスの設定

「v6プラス」固定IPサービス用の個別の設定はブロックを分けています。

# 「v6プラス」固定IPサービス
# - https://www.jpne.co.jp/service/v6plus-static/
# - http://www.rtpro.yamaha.co.jp/RT/docs/v6plus/#setting4
- name: Configure v6plus
  block:
  - name: Configure v6plus
    yamaha_network.rtx.rtx_config:
      save_when: "{{ network.save_when }}"
      commands:
      # NGN
      - ipv6 prefix 1 ra-prefix@{{ network.nenokuni.name }}::/64
      - ipv6 {{ network.takamagahara.name }} address ra-prefix@{{ network.nenokuni.name }}::{{ network.v6plus.interface_id }}/64
      - ipv6 {{ network.takamagahara.name }} prefix change log on
      - ipv6 {{ network.takamagahara.name }} rtadv send 1 o_flag=on
      - ipv6 {{ network.takamagahara.name }} dhcp service server
      - ipv6 {{ network.nenokuni.name }} dhcp service client ir=on
      - lan linkup send-wait-time {{ network.nenokuni.name }} 5
      # NAT
      - nat descriptor type 20000 masquerade
      - nat descriptor address outer 20000 {{ network.v6plus.ipv4 }}
      - nat descriptor address inner 20000 auto

  - name: Configure IPIP for BR
    yamaha_network.rtx.rtx_config:
      save_when: "{{ network.save_when }}"
      parents:
      - tunnel select 1
      commands:
      - tunnel encapsulation ipip
      - tunnel endpoint remote address {{ network.v6plus.br_address }}
      - ip tunnel nat descriptor 20000
      - ip tunnel tcp mss limit auto
      - tunnel enable 1

基本的には、YAMAHA公式の設定ファイルを参考にしていますが、 LuaスクリプトのみはAnsibleの管理外にしています。

www.rtpro.yamaha.co.jp

もうちょっと設定を作り込んで、中二病力を上げていきたい。

L2TP/IPSec

L2TP/IPSecVPNで接続できるようにしていますが、こちらも個別の設定は切り分けています。

# L2TP/IPSec
# - <https://network.yamaha.com/setting/router_firewall/vpn/vpn_client/vpn-smartphone-setup_rtx1200>
- name: Configure VPN
  when:
  - network.vpn.username != ''
  - network.vpn.password != ''
  block:
  - name: Configure VPN
    yamaha_network.rtx.rtx_config:
      save_when: "{{ network.save_when }}"
      commands:
      - ip {{ network.takamagahara.name }} proxyarp on
      - ipsec auto refresh on
      - ipsec transport 2 1 udp 1701
      # NAT
      - nat descriptor masquerade incoming 20000 reject
      - nat descriptor masquerade static 20000 1 {{ network.takamagahara.gateway }} esp
      - nat descriptor masquerade static 20000 2 {{ network.takamagahara.gateway }} udp 500
      - nat descriptor masquerade static 20000 3 {{ network.takamagahara.gateway }} udp 4500

  - name: Configure L2TP
    yamaha_network.rtx.rtx_config:
      save_when: "{{ network.save_when }}"
      parents:
      - pp select anonymous
      commands:
      - pp bind tunnel2
      - pp auth request mschap-v2
      - pp auth username {{ network.vpn.username }} {{ network.vpn.password }}
      - ppp ipcp ipaddress on
      - ppp ipcp msext on
      - ppp ccp type none
      - ip pp remote address pool dhcp
      - ip pp mtu 1258
      - pp enable anonymous

  - name: Configure L2TP Tunnel
    yamaha_network.rtx.rtx_config:
      save_when: "{{ network.save_when }}"
      parents:
      - tunnel select 2
      commands:
      - tunnel encapsulation l2tp
      - l2tp tunnel disconnect time off
      - l2tp keepalive use on 10 3
      - l2tp keepalive log on
      - l2tp syslog on
      - ip tunnel tcp mss limit auto
      - tunnel enable 2

  - name: Configure L2TP Tunnel
    yamaha_network.rtx.rtx_config:
      save_when: "{{ network.save_when }}"
      parents:
      - tunnel select 2
      - ipsec tunnel 1
      commands:
      - ipsec sa policy 1 1 esp aes256-cbc sha256-hmac
      - ipsec ike keepalive use 1 off
      - ipsec ike nat-traversal 1 on
      - ipsec ike pre-shared-key 1 text {{ network.vpn.pre_shared_key }}
      - ipsec ike remote address 1 any

今は高天原につながるようにしていますが、設定としては黄泉につながるようにしておきたいですね。

こちらも同様に設定を作り込んで、中二病力を上げていきたい。

おわりに

この記事では、RTX1300ルーターをAnsibleでプロビジョニングする方法について詳しく解説しました。
Ansibleを使用することで、ルーターの設定を簡単かつ迅速に行うことができます。
RTX1300を使用している場合は、ぜひ本記事を参考にして、ルーターの設定を効率化してください。

Pixel 7aを購入

Google I/Oで発表されたPixel 7aを購入しました。
元々はPixel 5aを使っていたのですが、スマホを触り始めてから初めて画面をバキバキに割ってしまったこともあり、購入することに決めました。

他にもTensor G2チップが使われていることもあり、モバイルでの機械学習の検証に使えそうという点も魅力的でした。

1日使ってみての所感

1日しか使っていないのと、ゲームはスマホでやらないのでそこまで参考にはならないと思います。

  • 良い点
    • Pixel同士の移行は楽
      • ホーム画面に追加しているWebサイトへのリンクは何故か使えなくなったので再登録が必要
    • Pixel 5aと比べてかなり快適
    • Magic Eraserは見れば不自然だけどそこまで気にならない
    • 指紋認証はフィルムをつけると若干認識しづらい
      • ただし即認証が通る角度と位置はある
    • 顔認証はかなり早くて快適
  • 気になる点
    • アップデートするまではめちゃくちゃ動作が重かった
    • 重量もそこそこ重い
    • 指紋認証のライトが強いので暗いところでは迷惑かも

ベンチマーク

友人から「ベンチマークよろ」って言われていたので、Benchmark 6と3DMarkベンチマーク結果を載せておきます。

Pixel 5a

元々使っていたPixel 5aのベンチマークも載せておきます。
比較してみるとGPU周りの性能向上が顕著なのかもしれません。