こんにちは、chanyou です。 OpenHands を自宅の Kubernetes クラスタで動かしてみました。 構成や、ハマった点とかをメモしておきます。 あくまで自宅の趣味のクラスタでとりあえず動くようにした構成なので、参考程度にお願いします。 定義した Kubernetes オブジェクト 話が早いと思うので、最初に YAML をペタっと貼っておきます。 apiVersion: v1 kind: Namespace metadata: name: openhands labels: app: openhands --- apiVersion: apps/v1 kind: Deployment metadata: name: openhands namespace: openhands labels: app: openhands spec: replicas: 1 selector: matchLabels: app: openhands template: metadata: labels: app: openhands spec: containers: # dind-daemon の postStart が完了してから openhands-app を起動する - name: dind-daemon image: docker:28.0.1-dind env: - name: DOCKER_TLS_CERTDIR value: "" securityContext: privileged: true lifecycle: postStart: exec: command: - "sh" - "-c" - | echo "Waiting for Docker daemon to be ready..." until docker info; do echo "Docker daemon not ready yet, sleeping..." sleep 1 done echo "Docker daemon is ready." - name: openhands-app image: docker.all-hands.dev/all-hands-ai/openhands:0.28 env: - name: SANDBOX_RUNTIME_CONTAINER_IMAGE value: "docker.all-hands.dev/all-hands-ai/runtime:0.28-nikolaik" - name: LOG_ALL_EVENTS value: "true" - name: DOCKER_HOST value: "tcp://localhost:2375" ports: - containerPort: 3000 volumeMounts: - name: openhands-state mountPath: /.openhands-state hostAliases: - ip: "127.0.0.1" hostnames: - "host.docker.internal" volumes: - name: openhands-state persistentVolumeClaim: claimName: openhands-state --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: openhands-state namespace: openhands spec: storageClassName: longhorn accessModes: - ReadWriteOnce resources: requests: storage: 1Gi --- apiVersion: v1 kind: Service metadata: name: openhands namespace: openhands labels: app: openhands spec: type: ClusterIP selector: app: openhands ports: - name: http port: 80 targetPort: 3000 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: openhands-ingress namespace: openhands labels: app: openhands annotations: kubernetes.io/ingress.class: "nginx" cert-manager.io/cluster-issuer: "letsencrypt-prod" nginx.ingress.kubernetes.io/auth-url: "https://oauth2-proxy.example.com/oauth2/auth" nginx.ingress.kubernetes.io/auth-signin: "https://oauth2-proxy.example.com/oauth2/start?rd=https://openhands.example.com" spec: rules: - host: openhands.example.com http: paths: - path: / pathType: Prefix backend: service: name: openhands port: name: http tls: - hosts: - openhands.example.com secretName: openhands-tls 解説 Docker outside of Docker から Docker in Docker へ OpenHands のドキュメント では、以下のようにホスト側の docker.sock をコンテナに渡すことで、ホスト側の Docker で Runtime コンテナの起動を行えるようにしています。 ...
Data Contract CLI の export コマンドに custom format を実装しました
こんにちは、chanyou です。 2024年の datatech-jp のアドカレ では、Data Contract CLI の実装を読み解く という記事を執筆しました。 記事でも触れていましたが Data Contract CLI へコントリビュートしたいと思いつつも、なかなか実現できずにいました。 が、思い切って以前からあったらいいなと思っていた機能の提案と実装をしまして、無事に v0.10.21 で反映されました。 これにより Data Contract CLI の利用シーンがさらに広がりそうなので、今回はその内容を紹介します。 実装した内容 記事タイトルにもある通り、Data Contract CLI の export コマンドに custom format を追加しました。 これにより、Data Contract から Jinja テンプレートを利用して任意の形式で出力できるようになります。 例えば、以下のような Jinja テンプレートファイル template.txt があるとします。 title: {{ data_contract.info.title }} このテンプレートを custom format として出力すると、以下のように変数 data_contract.info.title が展開されます。 $ datacontract export --format custom --template template.txt datacontract.yaml title: Orders Latest 実装した背景と想定されるユースケース 今回の機能により、固有のロジックを注入した出力が容易になりました。 従来は、独自のロジックを組み込んだ出力を行うために専用の Exporter を実装する必要がありました。 その方法は、Data Contract CLI を Python モジュールとしてインポートし、いくつかのクラスを定義するという手間がかかるものでした。 ...
Data Contract CLI の実装を読み解く
これは datatech-jp Advent Calendar 2024 の20日目の記事です。 こんにちは chanyou です。 先日、 datatech-jp の Data Contract事例共有会 というイベントに登壇させていただきました。 Data Contract の導入の難しさを語り合う貴重な機会でした。 イベントではそこまで触れていなかったですが Data Contract CLI というオープンソースのツールがあります。 Data Contract CLI を使うことで、Data Contract の YAML ファイルの読み書きやカタログ生成が容易に行えます。 Data Contract CLI の実装を読む機会がありましたので、この記事で触れていきたいと思います。 Data Contract CLI とは? ドキュメントは以下から確認できます。 https://cli.datacontract.com ソースコードは以下で、MIT ライセンスで公開されています。 datacontract/datacontract-cli - GitHub Data Contract CLI の基本的な使い方 インストール pip でインストールできます。 pip install 'datacontract-cli' 依存関係が切り出されており、使いたい機能に応じて追加モジュールをインストールできます。 pip install datacontract-cli[bigquery] インストールすると datacontract コマンドが使えるようになっています。 $ datacontract Usage: datacontract [OPTIONS] COMMAND [ARGS]... The datacontract CLI is an open source command-line tool for working with Data Contracts (https://datacontract.com). It uses data contract YAML files to lint the data contract, connect to data sources and execute schema and quality tests, detect breaking changes, and export to different formats. ╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ --version Prints the current version. │ │ --help Show this message and exit. │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Commands ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ init Download a datacontract.yaml template and write it to file. │ │ lint Validate that the datacontract.yaml is correctly formatted. │ │ test Run schema and quality tests on configured servers. │ │ export Convert data contract to a specific format. Saves to file specified by `output` option if present, otherwise prints to stdout. │ │ import Create a data contract from the given source location. Saves to file specified by `output` option if present, otherwise prints to stdout. │ │ publish Publish the data contract to the Data Mesh Manager. │ │ catalog Create an html catalog of data contracts. │ │ breaking Identifies breaking changes between data contracts. Prints to stdout. │ │ changelog Generate a changelog between data contracts. Prints to stdout. │ │ diff PLACEHOLDER. Currently works as 'changelog' does. │ │ serve Start the datacontract web server. │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ できることは出力の通りですが、一通り触ってみましょう。 ...
おもクラ#2 に登壇しました
こんにちは chanyou です。 kaneyasu-san が主催する おもにクラウドの話してます - 広島 #2 - connpass に参加してきました。 クラウドがテーマのイベントですが、若干切り口を変えて Docker Image のタグの打ち方の話を発表しました。 自宅の Kubernetes クラスタでは Docker Image のタグを release-please を使って省力的に SemVer を打ってデプロイしています。発表ではその具体的な方法について紹介しました。 以下が発表したスライドです。 このブログも例に漏れず release-please を使って更新しているので、発表の後半でデモを行いました。 こういったインフラに近いレイヤに特化して話ができる技術コミュニティが広島にもできつつあって、めちゃくちゃいい感じです。 主催の kaneyasu-san, 会場提供のサイボウズさん、ご準備いただきありがとうございました。 引き続き参加したり発表したりして一緒に盛り上げていければと思っています。
タイミーの DRE チームにジョインしました
こんにちは chanyou です。 タイトルの通り、2024年の3月にタイミーの DRE チームにジョインしまして、3ヶ月が経ちました。 仕事にも慣れてきてちょうどよい節目でもあるので、入社までの経緯と、どんなことをしているのかまとめていきたいと思います。 入社までの経緯 前職ではスタートアップでいわゆるデータエンジニアとして、データ基盤のインフラやデータ変換のパイプラインの開発や運用をしていました。BtoBの自社開発の事業でしたが、ユーザー保有のデータを受領して分析しやすい形に加工する作業がかなりの割合を占めていて、自社開発と言いつつも受託の色が濃かったと思います。 それはそれで技術的にどう攻略するか、探索しながら改善していって面白かったのですが、ピボットすることをきっかけに次の環境を探すことにしました。 自分の中では主に以下の軸で探し始めました。1 PMF 後のフェーズで、データによって事業成長に貢献できるか 既に組織にデータ活用の文化があり、データ基盤を育てることに注力できそうか 技術コミュニティに理解があるか、スタッフや登壇活動を支援してもらえそうか いくつかの会社とカジュアル面談等をさせてもらって、最終的にタイミーに入社を決めました。 テックブログの以下の記事を読んで、 Data Reliability Engineering への向き合い方にすごく共感して、ワクワクしたのが理由として大きかったです。 タイミーのデータ基盤品質。これまでとこれから。 - Timee Product Team Blog DREのMissionを合宿で決めた話 - Timee Product Team Blog どんなことをしているのか DRE チームとしての活動 タイミーの DRE チームでは、全社のデータ基盤の開発・運用を通して、より信頼性の高いデータを活用できる状態を追求しています。 直近では GENBA #3 〜DREの現場〜 というイベントで、以下のような発表をチームメンバーがしています。 アプリケーションの RDB のデータをいかに早く正確にデータウェアハウスに転送するとか、手入力データの品質向上とか、そういった取り組みを紹介しています。 信頼性というと守りの印象が強いですが、適時性向上の例のように、今まで1日かかっていた転送がほぼリアルタイムになることでデータ活用の幅が広がる、といった攻めの側面もあります。 ...
Palworld サーバーを Kubernetes で立ててみた
だいぶ前にこういうポストをしていて、諸々環境が整ってきたので実際にやってみました。 @chanyou0311 のポスト 目新しい情報は特になくて、巨人の肩に乗っかると簡単に Kubernetes で起動できるという話です。 Kubernetes で立てるモチベーション CronJob を定義すれば、バックアップなどの任意の処理を定期的に実行できる 設定値を宣言的に定義できる やはり浪漫…浪漫がある… というわけで、カジュアルにおうち k8s クラスタに立ててみます。 まずはネイティブで試す Minecraft などのゲームサーバーを立てたことがなかったので、どう立てるかわかってない状態でした。 まずは Kubernetes を使わずにサーバーを立ててみます。公式ドキュメントの通りに進めるとサクッと起動できました。 専用サーバーの構築 | Palworld tech guide SteamCMD という CLI ツールをインストールして、適切なパラメータを渡して起動するだけです。デフォルトでは UDP 8211 番で待ち受ける形となっています。 外部ネットワークからアクセスするにはルーターのポートフォワードなどの設定を行うことで可能です。Palworld だと 8211 がデフォルトポートで、このポートが使用されることが多いのだと思います。 Kubernetes 起動への道のりを考える Docker Image を用意する SteamCMD は Windows と Linux に対応しているので、 SteamCMD が使える Docker Image を作ってあげれば Kubernetes で起動できそうです。 で、調べると既に有志により palworld-server-docker というリポジトリが公開されており、活発にメンテナンスされているのがわかります。 thijsvanloef/palworld-server-docker - GitHub このリポジトリで管理されている Docker Image に乗っかるのが簡単そうです。 Kubernetes リソースを用意する いい感じの Docker Image が公開されているので、いい感じに Deployment やら PVC やらのリソースを定義して kubectl apply -f palworld.yml すれば起動できそう感があります。 ...
どうして YAPC を広島で開催できたのか
YAPC::Hiroshima 2024 が終わってはや2ヶ月…お疲れさまでした。 現地にご参加いただいたみなさん、配信で見られたみなさん、ありがとうございました。 先日 Findy Engineer Lab さんから YAPC::Hiroshima 2024 の記事が公開されました。取材いただきありがとうございました。 なぜ、YAPCはこれほど愛されるカンファレンスになったのか。運営の裏側をHiroshima 2024スタッフたちに聞いた - Findy Engineer Lab 改めて広島開催について振り返っていきたいと思います。 自分はというと、コアスタッフとして会場や飲食周りの調整など、広島現地の業者との対応を中心に準備を進めておりました。 当日はオープニングを担当させてもらいまして、その後は会場周辺のプチトラブルの対応1などをしておりました。 私個人としては、自分が住む広島で YAPC が開催できたことを光栄に思います。 実はエンジニアを志すきっかけのひとつに YAPC::Asia Tokyo 2010 の 草とPerl というLTを見て、こんな心から技術を楽しんでいる大人たちの輪に自分も入りたい。そう思って勉強したりモノを作ったりしていたのでした。 自分がそんなコミュニティを少しでも支えることができたと思うと、勝手ながら感慨深く思います。 ただ広島には Perl を主軸とした技術コミュニティはなく、 JPA としても Perl コミュニティが根付いていない地域での開催は初めてとのことで、どのようにして広島で開催できたのか、気になる方もいるかもしれません。開催の経緯に触れていきたいと思います。 開催の経緯 2023年の京都の準備と並行して、 JPA 内で2024年の YAPC 開催地の検討が進められていて、細かい議論はあったかと思いますが、広島開催が候補として挙がっていたようでした。その後 JPA から私に相談いただいた流れでした。 元々JPAの理事の xtetsuji さんや YAPC の配信周りを担当している godan さんとは Podcast を録り合う仲で、そこから「広島で開催どうかな?」とお声がけいただきました。 広島開催は大歓迎だったので、すぐに周囲の広島の技術コミュニティの方々を巻き込んで、キックオフしていきました。 それからは、まずは会場候補を洗い出して下見して…と、一般的なカンファレンス準備と変わらずだと思います。 広島で実現できた理由 どうして広島で開催できたんだろう、と振り返ると「多種多様なみなさんの支援や協力があったから」という一言にまとまってしまいそうです。それだと面白くないので、具体的に挙げていこうと思います。 地域コミュニティの支援 すごい広島 を中心とする、広島の技術コミュニティの方々に「 YAPC スタッフやらない?」とお誘いすると、何名も手を挙げていただいて、一緒にコアスタッフとして準備を進めました。 具体的にはコアスタッフや当日スタッフとしての参画、地域の技術イベントでの告知、コワーキングスペースや飲食店などのチラシ配布、ご当地スポンサーの誘致など、地域に関わるほとんど全てをやっていたと思います。 私以上に地域にコネクションのある方が率先して動いてくださってめちゃくちゃ助かりました。地域一丸となって盛り上げていくことができていたんじゃないかと思います。 コンベンションビューローの支援 広島には広島観光コンベンションビューローという公益財団法人があり、大規模カンファレンス開催時に、会場選定などの支援をお願いできます。 今回は400名規模の会場選定でご協力をお願いしました。 いくつか YAPC スタッフから会場候補を出して、各候補に対してフィードバックを受けつつ、下見の日程調整を取り次いでもらうなどスピーディに意思決定を支えていただきました。 ...
connpass API ではじめるデータ分析基盤入門
これは 呉高専 Advent Calendar 2022 - Adventar の14日目の記事です。 大遅刻、大変失礼しました… しっかり埋まっていてすごい。そしてアルゴリズムからハードウェアまで、カバー域広い… 改めて、アドベントカレンダーを通して知らない人とつながれるのでとてもいい文化だなと思ってます。 まえがき 2022年の6月にオープンセミナー2022@広島に「データ分析基盤のはじめかた」というタイトルで登壇させていただきました。 データ分析基盤の構成要素など考え方を中心の内容で、最後にデモを行いました。 セミナーでは実装の詳細に触れることができなかったので、この記事では connpass API をデータソースとしてデータ分析基盤を作って動かす方法を紹介したいと思います。1 この記事を通して、データ分析基盤をもっと身近に感じてもらえると願ったり叶ったりです。 対象読者 データ分析基盤構築の一連の流れが知りたい方 普段は構築済みのデータ分析基盤を使っていて、その実装に興味のある方 デモ こちらにリポジトリを公開しています。 clone して docker-compose build && docker-compose up で動くはずです。気長に待ちながら続きを読んでもらえるとこの上ないです。 データ分析基盤の構成要素 実際に動かす前に、データ分析基盤の構成要素について触れておきます。 基本的な構成要素 データ分析基盤は、基本的には以下の要素で構成されます。 それぞれ、以下のような位置づけになります。 要素名 内容 具体例 データソース データの供給元 Google Analytics の生データやセンサーデータなど データレイク データソースから受け取った生のデータを保存するストレージ S3 や Cloud Storage などのオブジェクトストレージが選定されることが多いです データウェアハウス データレイクの生データを、分析が容易な構造化データとして保存するストレージ BigQuery や Redshift、Snowflake などが選定されることが多いです データマート データを利用しやすいように、データウェアハウス内の構造化データをさらに加工したもの 実体としては、ストレージは基本的にデータウェアハウスと同一になるはずで、データウェアハウス内の一部のビューやテーブルを指してデータマートと呼ぶようになります2 データ活用 データの活用先 機械学習モデルやその実装に利用する Jupyter Notebook、BI ツールなどがこれに当たります データパイプライン 上画像の矢印の部分。データ抽出や変換、ローディングなどを行う役割です fluentd や Embulk、 Airbyte や dbt などの SaaS や OSS がよく挙げられますが、FaaS ベースの独自のスクリプトもデータパイプラインと言えます 具体例としてオブジェクトストレージや列指向データベースなどを挙げていますが、あくまで選定される場合が多いものであって、例えば データレイクにはオブジェクトストレージしか採用してはいけない といったことは全くないです。 ...
Kubernetes でブログを配信するようにした
Kubespray 使ってみた 呉高専 Advent Calendar 2022 の14日目の記事を担当しているんだけど、せっかくなのでこのブログにポストしたい。 mkdocs serve で立ち上げていただけなので、宅鯖に Kubernetes 入れていい感じに稼働させたいということで色々試してみた。 1年くらい前に kubeadm で Kubernetes クラスタ立ち上げたことがあったけど、ステップ数が多くてトラブルシュートが大変だった。 そして先週からこそこそ Kubespray を試してサクッと立てることができた。便利。 こちらは Ansible と kubeadm がベースになっていて、急がば回れで Ansible のチュートリアル入門だけやって Kubespray 触るようにした。 cert-manager とか dashboard とか、一通りお前使うやろ一式が入れられるようになっていて、ホビー用途の自分には合っていそうな感触。 やったこと おうちKubernetesをそれっぽく加工する話 - MetalLBとかExternalDNSとかcert-managerとか - メモ - RyuSA の記事がやりたいことに合致していたので、記事を参考に Kubespray 経由で環境構築した。 あとは今まで mkdocs serve で立ち上げたいたものを mkdocs build して nginx で static に配信する Docker コンテナ作った。 それから雑に Deployment を定義して、 Service やら Ingress やらも定義して apply して終わり。 ちゃんと計測はしていないけど、もっさり感も軽減したと思う。よしよし。
記事にタイトルを設定してみた
深く考えずにブログを立ち上げたが、かれこれ一ヶ月も経ってしまった。 本当に勢いだったので、記事にタイトルすら設定していなかった。 mkdocs-material のリファレンスを読んで設定した。 --- title: 記事にタイトルを設定してみた --- # 記事にタイトルを設定してみた こういう記述でよいらしい。 ついでに HTTPS にリダイレクトするようにして、作成日時と編集日時も末尾に表示するようにしてみた。日時は git から取ってきているみたい。よくできている。 ただ記事を予約投稿する機能は mkdocs-material にはないらしい(そりゃそうだ) 実現するには GitHub ActionsでZenn記事の予約投稿を実現する という記事の方法のように、 git push するタイミングを制御してやるとよさそう。 ちなみに Zenn は公式で予約投稿ができるようになっていた。同じような記載で設定できると楽だな… 実行環境やデプロイ方法は相変わらずお粗末なので、引き続き手を加えていきたい。 おわり。