<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>kkato.dev</title>
    <link>https://kkato.dev/</link>
    <description>Recent content on kkato.dev</description>
    <image>
      <title>kkato.dev</title>
      <url>https://kkato.dev/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</url>
      <link>https://kkato.dev/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</link>
    </image>
    <generator>Hugo -- 0.146.0</generator>
    <language>en</language>
    <lastBuildDate>Sat, 28 Feb 2026 12:00:00 +0900</lastBuildDate>
    <atom:link href="https://kkato.dev/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>GitHub Container Registry (ghcr.io) の使い方</title>
      <link>https://kkato.dev/posts/ghcr/</link>
      <pubDate>Sat, 28 Feb 2026 12:00:00 +0900</pubDate>
      <guid>https://kkato.dev/posts/ghcr/</guid>
      <description>&lt;p&gt;GitHub Container Registry (ghcr.io) は、GitHub が提供するコンテナイメージのレジストリです。
Public Packages であれば無料で利用でき、GitHub Actions と組み合わせることでデータ転送料金も無料になります。&lt;/p&gt;
&lt;p&gt;ghcr.io は2通りの使い方があります。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ローカルから Docker CLI を使ってイメージをビルドしてプッシュする方法&lt;/li&gt;
&lt;li&gt;GitHub Actions を使ってコードの変更に合わせて自動でイメージをビルドしてプッシュする方法&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;今回はGitHub Actions を使って自動でイメージをビルドしてプッシュする方法を紹介します。&lt;/p&gt;
&lt;h3 id=&#34;github-actions-から自動でプッシュする&#34;&gt;GitHub Actions から自動でプッシュする&lt;/h3&gt;
&lt;p&gt;GitHub Actions を使えば、コードをプッシュするだけで自動的にイメージのビルドとプッシュができます。以下はワークフローの例です。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Docker Build and Push&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;branches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# GHCR へのプッシュには packages: write が必要&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;permissions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;packages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;build-and-push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ubuntu-latest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# ソースコードをチェックアウト&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Check out code&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/checkout@v4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# ghcr.io にログイン&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Log in to GitHub Container Registry&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;docker/login-action@v2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;registry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ghcr.io&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ github.actor }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# デフォルトの GITHUB_TOKEN を利用&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;password&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Docker イメージをビルドしてプッシュ&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Build and push Docker image&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;docker/build-push-action@v6&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ghcr.io/${{ github.repository }}:latest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;トラブルシューティング&#34;&gt;トラブルシューティング&lt;/h3&gt;
&lt;p&gt;GitHub Actions から ghcr.io にプッシュする際に、以下のようなエラーが出ました。&lt;/p&gt;</description>
    </item>
    <item>
      <title>PostgreSQL Operatorの比較</title>
      <link>https://kkato.dev/posts/postgres-operators/</link>
      <pubDate>Fri, 20 Feb 2026 15:00:00 +0900</pubDate>
      <guid>https://kkato.dev/posts/postgres-operators/</guid>
      <description>&lt;p&gt;Kubernetes上でPostgreSQLを運用するためのOperatorが複数存在します。以前どれを選ぶか検討する機会があったので、主要な4つのオペレーターを比較してみました。&lt;/p&gt;
&lt;h3 id=&#34;比較表&#34;&gt;比較表&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;/th&gt;
          &lt;th&gt;&lt;a href=&#34;https://github.com/CrunchyData/postgres-operator&#34;&gt;PGO&lt;/a&gt;&lt;/th&gt;
          &lt;th&gt;&lt;a href=&#34;https://github.com/cloudnative-pg/cloudnative-pg&#34;&gt;CloudNativePG&lt;/a&gt;&lt;/th&gt;
          &lt;th&gt;&lt;a href=&#34;https://github.com/zalando/postgres-operator&#34;&gt;Zalando&lt;/a&gt;&lt;/th&gt;
          &lt;th&gt;&lt;a href=&#34;https://github.com/ongres/stackgres&#34;&gt;StackGres&lt;/a&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;開発元&lt;/td&gt;
          &lt;td&gt;Crunchy Data&lt;/td&gt;
          &lt;td&gt;EDB / CNCF&lt;/td&gt;
          &lt;td&gt;Zalando&lt;/td&gt;
          &lt;td&gt;OnGres&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;GitHub Stars&lt;/td&gt;
          &lt;td&gt;4,400&lt;/td&gt;
          &lt;td&gt;8,000&lt;/td&gt;
          &lt;td&gt;5,100&lt;/td&gt;
          &lt;td&gt;1,400&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;ライセンス (Operator)&lt;/td&gt;
          &lt;td&gt;Apache 2.0&lt;/td&gt;
          &lt;td&gt;Apache 2.0&lt;/td&gt;
          &lt;td&gt;MIT&lt;/td&gt;
          &lt;td&gt;AGPL-3.0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;ライセンス (コンテナイメージ)&lt;/td&gt;
          &lt;td&gt;独自 (制限あり)&lt;/td&gt;
          &lt;td&gt;Apache 2.0&lt;/td&gt;
          &lt;td&gt;MIT&lt;/td&gt;
          &lt;td&gt;AGPL-3.0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Patroni&lt;/td&gt;
          &lt;td&gt;使用&lt;/td&gt;
          &lt;td&gt;不使用 (独自実装)&lt;/td&gt;
          &lt;td&gt;使用 (Patroni開発元)&lt;/td&gt;
          &lt;td&gt;使用&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;CNCF&lt;/td&gt;
          &lt;td&gt;-&lt;/td&gt;
          &lt;td&gt;Sandbox&lt;/td&gt;
          &lt;td&gt;-&lt;/td&gt;
          &lt;td&gt;-&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;star-history&#34;&gt;Star History&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://star-history.com/#CrunchyData/postgres-operator&amp;amp;cloudnative-pg/cloudnative-pg&amp;amp;zalando/postgres-operator&amp;amp;ongres/stackgres&amp;amp;Date&#34;&gt;&lt;img alt=&#34;Star History Chart&#34; loading=&#34;lazy&#34; src=&#34;https://api.star-history.com/svg?repos=CrunchyData/postgres-operator,cloudnative-pg/cloudnative-pg,zalando/postgres-operator,ongres/stackgres&amp;type=Date&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;各オペレーターの特徴&#34;&gt;各オペレーターの特徴&lt;/h3&gt;
&lt;h4 id=&#34;pgo-crunchy-data&#34;&gt;PGO (Crunchy Data)&lt;/h4&gt;
&lt;p&gt;Crunchy Data社が開発するオペレーターで、Patroniを使ったHAに対応しています。Operator自体のソースコードはApache 2.0ですが、Crunchy Data が配布するコンテナイメージは独自のライセンス（&lt;a href=&#34;https://www.crunchydata.com/developers/terms-of-use&#34;&gt;Crunchy Data Developer Program&lt;/a&gt;）で提供されています。50名以上の組織では本番利用に有償サブスクリプションが必要になるため、注意が必要です。自前でイメージをビルドすれば回避できますが、手間がかかります。&lt;/p&gt;
&lt;h4 id=&#34;cloudnativepg&#34;&gt;CloudNativePG&lt;/h4&gt;
&lt;p&gt;EDBが開発を始め、現在はCNCF Sandboxプロジェクトになっています。Patroniに依存せず、独自のInstance Managerが各Pod内で動作し、Kubernetes APIを直接利用してリーダー選出やフェイルオーバーを行います。ライセンスもOperator・コンテナイメージともにApache 2.0で、制限なく利用できます。Star数も最も多く、コミュニティの勢いがあります。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Argo CDをインストールしてみた</title>
      <link>https://kkato.dev/posts/argocd/</link>
      <pubDate>Fri, 20 Feb 2026 11:00:00 +0900</pubDate>
      <guid>https://kkato.dev/posts/argocd/</guid>
      <description>&lt;p&gt;Argo CDはKubernetes向けのGitOpsツールで、Gitリポジトリに置いたマニフェストをクラスタに自動で反映してくれます。
今回はHelmを使ってArgo CDをインストールし、リポジトリの接続からApplicationの作成までを試してみました。&lt;/p&gt;
&lt;h3 id=&#34;argo-cdのインストール&#34;&gt;Argo CDのインストール&lt;/h3&gt;
&lt;p&gt;Helm Chartリポジトリを追加します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm repo add argo https://argoproj.github.io/argo-helm
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;argocd&lt;/code&gt; namespaceにインストールします。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm install argocd argo/argo-cd &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --namespace argocd &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --create-namespace &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --version 7.8.13
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Podが正常に起動していることを確認します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get pods -n argocd
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;argo-cd-uiにアクセスする&#34;&gt;Argo CD UIにアクセスする&lt;/h3&gt;
&lt;p&gt;port-forwardでArgo CDのUIにアクセスできます。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl port-forward svc/argocd-server -n argocd 8080:443
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ブラウザで &lt;code&gt;http://localhost:8080&lt;/code&gt; にアクセスします。&lt;/p&gt;
&lt;p&gt;初期パスワードは以下のコマンドで取得できます。ユーザー名は&lt;code&gt;admin&lt;/code&gt;です。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl -n argocd get secret argocd-initial-admin-secret -o &lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{.data.password}&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; base64 -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://kkato.dev/images/argocd/login.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;gitリポジトリを接続する&#34;&gt;Gitリポジトリを接続する&lt;/h3&gt;
&lt;p&gt;Argo CDがGitリポジトリからマニフェストを取得するために、リポジトリの接続設定が必要です。&lt;/p&gt;
&lt;h4 id=&#34;ssh鍵の作成&#34;&gt;SSH鍵の作成&lt;/h4&gt;
&lt;p&gt;Argo CD専用のSSH鍵を作成します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ssh-keygen -t ed25519 -f ~/.ssh/argocd -C &lt;span class=&#34;s2&#34;&gt;&amp;#34;argocd&amp;#34;&lt;/span&gt; -N &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;githubにdeploy-keyを登録&#34;&gt;GitHubにDeploy Keyを登録&lt;/h4&gt;
&lt;p&gt;生成した公開鍵をリポジトリのDeploy Keyとして登録します。&lt;/p&gt;</description>
    </item>
    <item>
      <title>vim tips</title>
      <link>https://kkato.dev/posts/vim-tips/</link>
      <pubDate>Sun, 01 Feb 2026 17:39:47 +0900</pubDate>
      <guid>https://kkato.dev/posts/vim-tips/</guid>
      <description>&lt;h3 id=&#34;移動&#34;&gt;移動&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;キー&lt;/th&gt;
          &lt;th&gt;説明&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;}&lt;/code&gt; / &lt;code&gt;{&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;次/前の空行へ移動&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;対応する括弧へ移動&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;operator-と-text-object&#34;&gt;Operator と Text Object&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Operator&lt;/th&gt;
          &lt;th&gt;説明&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;c&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;change&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;delete&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;y&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;yank&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;v&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;visual&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Text Object は &lt;code&gt;i&lt;/code&gt;（inner: 内側のみ）と &lt;code&gt;a&lt;/code&gt;（a: 囲み文字も含む）の2種類がある。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Text Object&lt;/th&gt;
          &lt;th&gt;説明&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;iw&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;単語の内側&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;aw&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;単語 + 周囲の空白&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;i&amp;quot;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;&amp;quot;...&amp;quot;&lt;/code&gt; の内側&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;a&amp;quot;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;&amp;quot;...&amp;quot;&lt;/code&gt; 全体（引用符含む）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;i(&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;(...)&lt;/code&gt; の内側&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;a(&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;(...)&lt;/code&gt; 全体（括弧含む）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;i{&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;{...}&lt;/code&gt; の内側&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;a{&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;{...}&lt;/code&gt; 全体（波括弧含む）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;it&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;HTMLタグの内側&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;at&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;HTMLタグ全体（タグ含む）&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;例&lt;/th&gt;
          &lt;th&gt;説明&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;ciw&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;単語を削除して挿入モード&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;di&amp;quot;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;ダブルクォート内を削除&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;ya(&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;括弧ごとコピー&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;参考文献&#34;&gt;参考文献&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gist.github.com/fohte/f99aab472119acd736dfc688bfdf383c&#34;&gt;なれる! Vimmer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>netrwの操作コマンド</title>
      <link>https://kkato.dev/posts/netrw/</link>
      <pubDate>Sun, 01 Feb 2026 17:25:44 +0900</pubDate>
      <guid>https://kkato.dev/posts/netrw/</guid>
      <description>&lt;h3 id=&#34;netrwneovim内蔵ファイルブラウザ&#34;&gt;netrw（Neovim内蔵ファイルブラウザ）&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;キー / コマンド&lt;/th&gt;
          &lt;th&gt;動作&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;:Ex&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;カレントディレクトリを開く&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;:Vex&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;垂直分割で開く&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;:Sex&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;水平分割で開く&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;&amp;lt;CR&amp;gt;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;ファイル/ディレクトリを開く&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;v&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;垂直分割で開く&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;o&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;水平分割で開く&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;t&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;タブで開く&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;新規ファイル作成&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;ディレクトリ作成&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;D&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;削除&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;R&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;リネーム&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;上のディレクトリへ&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;i&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;表示形式を切り替え&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;ペイン操作&#34;&gt;ペイン操作&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;キー / コマンド&lt;/th&gt;
          &lt;th&gt;動作&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;:vs ファイル名&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;垂直分割でファイルを開く&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;:sp ファイル名&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;水平分割でファイルを開く&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;Ctrl+w h/j/k/l&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;左/下/上/右へ移動&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;Ctrl+w c&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;閉じる&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;Ctrl+w o&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;他を全て閉じる&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;Ctrl+w =&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;均等サイズ&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;タブ操作&#34;&gt;タブ操作&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;キー / コマンド&lt;/th&gt;
          &lt;th&gt;動作&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;:tabnew&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;新規タブ&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;:tabe ファイル名&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;ファイルをタブで開く&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;gt&lt;/code&gt; / &lt;code&gt;gT&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;次/前のタブ&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;:tabclose&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;タブを閉じる&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;</description>
    </item>
    <item>
      <title>Kubernetesをv1.30からv1.31にアップグレードした</title>
      <link>https://kkato.dev/posts/k8s-upgrade/</link>
      <pubDate>Sat, 24 Jan 2026 20:11:09 +0900</pubDate>
      <guid>https://kkato.dev/posts/k8s-upgrade/</guid>
      <description>&lt;p&gt;自宅で運用しているKubernetesクラスターをv1.30からv1.31にアップグレードしました。
kubeadmを使った標準的なアップグレード手順ですが、忘れがちなので備忘録として残しておきます。&lt;/p&gt;
&lt;p&gt;公式ドキュメント: &lt;a href=&#34;https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/&#34;&gt;https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;コントロールプレーンノードのアップグレード&#34;&gt;コントロールプレーンノードのアップグレード&lt;/h3&gt;
&lt;p&gt;コントロールプレーンノードから順番にアップグレードしていきます。&lt;/p&gt;
&lt;h4 id=&#34;パッケージリポジトリの変更&#34;&gt;パッケージリポジトリの変更&lt;/h4&gt;
&lt;p&gt;まず、yumリポジトリの設定ファイルをv1.31用に変更します。&lt;/p&gt;
&lt;p&gt;変更前（v1.30）:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;kkato@nuc01 ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cat /etc/yum.repos.d/kubernetes.repo
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;kubernetes&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;Kubernetes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;baseurl&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;enabled&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;gpgcheck&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;gpgkey&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;exclude&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;kubelet kubeadm kubectl cri-tools kubernetes-cni
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;変更後（v1.31）:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ cat /etc/yum.repos.d/kubernetes.repo
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;kubernetes&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;Kubernetes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;baseurl&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;https://pkgs.k8s.io/core:/stable:/v1.31/rpm/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;enabled&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;gpgcheck&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;gpgkey&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;https://pkgs.k8s.io/core:/stable:/v1.31/rpm/repodata/repomd.xml.key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;exclude&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;kubelet kubeadm kubectl cri-tools kubernetes-cni
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;参考: &lt;a href=&#34;https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/change-package-repository/&#34;&gt;https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/change-package-repository/&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;kubeadmのアップグレード&#34;&gt;kubeadmのアップグレード&lt;/h4&gt;
&lt;p&gt;まずkubeadmパッケージをアップグレードします。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo yum upgrade kubeadm --setopt&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;disable_excludes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;kubernetes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;アップグレード可能なバージョンを確認します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo kubeadm upgrade plan
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Components that must be upgraded manually after you have upgraded the control plane with &lt;span class=&#34;s1&#34;&gt;&amp;#39;kubeadm upgrade apply&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;COMPONENT   NODE      CURRENT   TARGET
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubelet     nuc01     v1.30.1   v1.31.14
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubelet     nuc02     v1.30.1   v1.31.14
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubelet     nuc03     v1.30.1   v1.31.14
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubelet     nuc04     v1.30.1   v1.31.14
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Upgrade to the latest stable version:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;COMPONENT                 NODE      CURRENT    TARGET
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kube-apiserver            nuc01     v1.30.4    v1.31.14
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kube-controller-manager   nuc01     v1.30.4    v1.31.14
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kube-scheduler            nuc01     v1.30.4    v1.31.14
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kube-proxy                          1.30.4     v1.31.14
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CoreDNS                             v1.11.1    v1.11.3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;etcd                      nuc01     3.5.12-0   3.5.24-0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;You can now apply the upgrade by executing the following command:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        kubeadm upgrade apply v1.31.14
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;アップグレードを実行します。&lt;/p&gt;</description>
    </item>
    <item>
      <title>GORMの基本的な使い方</title>
      <link>https://kkato.dev/posts/gorm/</link>
      <pubDate>Sat, 17 Jan 2026 22:22:44 +0900</pubDate>
      <guid>https://kkato.dev/posts/gorm/</guid>
      <description>&lt;p&gt;最近、Goを勉強していてGORMを触る機会があったので、基本的な部分を調べてみました。&lt;/p&gt;
&lt;h3 id=&#34;モデル定義&#34;&gt;モデル定義&lt;/h3&gt;
&lt;p&gt;GORMでは構造体をそのままテーブルにマップします。&lt;code&gt;gorm.Model&lt;/code&gt;を埋め込むと&lt;code&gt;ID&lt;/code&gt;や&lt;code&gt;CreatedAt&lt;/code&gt;など便利なカラムが自動で付きます。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;gorm.io/gorm&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;User&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;gorm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Model&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Name&lt;/span&gt;  &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Email&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;`gorm:&amp;#34;uniqueIndex&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Age&lt;/span&gt;   &lt;span class=&#34;kt&#34;&gt;uint&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;db接続とマイグレーション&#34;&gt;DB接続とマイグレーション&lt;/h3&gt;
&lt;p&gt;PostgreSQLを例に、DBへ接続し、モデルに沿ってテーブルを自動生成します。&lt;code&gt;dsn&lt;/code&gt;は環境に合わせて書き換えてください。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;gorm.io/driver/postgres&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;gorm.io/gorm&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;dsn&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;host=localhost user=postgres password=postgres dbname=app port=5432 sslmode=disable&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;gorm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;postgres&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dsn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;gorm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fatal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// モデルに合わせてテーブルを作成・更新&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;AutoMigrate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{});&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fatal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;crud操作&#34;&gt;CRUD操作&lt;/h3&gt;
&lt;p&gt;基本的なCRUD操作は以下のように行います。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;gorm.io/driver/postgres&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;gorm.io/gorm&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;User&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;gorm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Model&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Name&lt;/span&gt;  &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Email&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;`gorm:&amp;#34;uniqueIndex&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Age&lt;/span&gt;   &lt;span class=&#34;kt&#34;&gt;uint&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;dsn&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;host=localhost user=postgres password=postgres dbname=app port=5432 sslmode=disable&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;gorm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;postgres&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dsn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;gorm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fatal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;AutoMigrate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{});&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fatal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// CREATE: レコードを追加&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;alice&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Alice&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Email&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;alice@example.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;28&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;alice&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fatal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// READ: 1件取得（主キーまたは条件指定）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;User&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;First&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;email = ?&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;alice@example.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fatal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;found: %+v\n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// UPDATE: 1カラム更新（モデルを指定）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Age&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;29&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fatal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// DELETE: ソフトデリート（DeletedAtにタイムスタンプが入る）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Delete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fatal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;よく使うクエリの書き方&#34;&gt;よく使うクエリの書き方&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 条件付きで複数取得&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;users&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;User&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Where&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;age &amp;gt;= ?&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;25&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Order&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;age desc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Limit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Find&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;users&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 複数カラムをまとめて更新&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Updates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;interface&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Alice Updated&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;Age&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;参考&#34;&gt;参考&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gorm.io/docs/index.html&#34;&gt;GORM Official Guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gorm.io/docs/connecting_to_the_database.html#PostgreSQL&#34;&gt;GORM PostgreSQL Driver&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Go 1.22のHTTPルーティング改善について</title>
      <link>https://kkato.dev/posts/servemux/</link>
      <pubDate>Mon, 29 Dec 2025 12:56:44 +0900</pubDate>
      <guid>https://kkato.dev/posts/servemux/</guid>
      <description>&lt;p&gt;最近、Goの勉強をしているんですが、その中で Gin・Echo・chi など多くの選択肢があり、どのフレームワーク（ライブラリ）を選ぶべきか迷いました。
そんな中、Go 1.22（2024年2月リリース）から標準ライブラリの&lt;code&gt;http.ServeMux&lt;/code&gt;が強化されたことを知りました。
今回は、Go 1.22でのServeMuxの改善点について調べてみました。&lt;/p&gt;
&lt;h3 id=&#34;これまでのservemuxgo-121以前の課題&#34;&gt;これまでのServeMux（Go 1.21以前）の課題&lt;/h3&gt;
&lt;p&gt;Go 1.21以前のServeMuxには、以下のような制約がありました。&lt;/p&gt;
&lt;h4 id=&#34;httpメソッドを指定できない&#34;&gt;HTTPメソッドを指定できない&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Go 1.21以前: HTTPメソッドの区別ができない&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;mux&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;NewServeMux&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;mux&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HandleFunc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/users&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;w&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ResponseWriter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// GET、POST、PUT、DELETEなど、すべてのHTTPメソッドがこのハンドラに来る&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 自分でメソッドを判定する必要があった&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;switch&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Method&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MethodGet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// GETの処理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MethodPost&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// POSTの処理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Method not allowed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;StatusMethodNotAllowed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このように、メソッドごとに処理を分けたい場合は、自分でswitch文を書く必要がありました。&lt;/p&gt;
&lt;h4 id=&#34;パスパラメータを扱えない&#34;&gt;パスパラメータを扱えない&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Go 1.21以前: パスパラメータが使えない&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// /users/123 のような動的なパスを扱うには、自分でパースが必要&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;mux&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HandleFunc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/users/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;w&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ResponseWriter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// URLからIDを手動で抽出する必要があった&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;strings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;TrimPrefix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;/users/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fprintf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;User ID: %s&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;完全一致が難しい&#34;&gt;完全一致が難しい&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Go 1.21以前: /users にアクセスしたかったが、/users/ も /users/abc もマッチしてしまう&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;mux&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HandleFunc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/users&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// これは /users だけでなく /users/ にもマッチする&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;こうした課題から、多くのプロジェクトでサードパーティのルーターライブラリが使われていました。&lt;/p&gt;
&lt;h3 id=&#34;go-122での新機能&#34;&gt;Go 1.22での新機能&lt;/h3&gt;
&lt;p&gt;Go 1.22では、これらの課題を解決する3つの大きな機能が追加されました。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Helmコマンド まとめ</title>
      <link>https://kkato.dev/posts/helm-command/</link>
      <pubDate>Sat, 27 Dec 2025 09:37:48 +0900</pubDate>
      <guid>https://kkato.dev/posts/helm-command/</guid>
      <description>&lt;p&gt;HelmはKubernetes向けのパッケージマネージャーで、複雑なアプリケーションのデプロイを簡単にしてくれるツールです。
Helmコマンドをよく忘れてしまうので、基本的なコマンドを備忘録としてまとめました。&lt;/p&gt;
&lt;h4 id=&#34;リポジトリの追加&#34;&gt;リポジトリの追加&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# リポジトリを追加する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm repo add stable https://charts.helm.sh/stable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm repo add bitnami https://charts.bitnami.com/bitnami
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;リポジトリの一覧表示&#34;&gt;リポジトリの一覧表示&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 追加されているリポジトリを確認する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm repo list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;リポジトリの更新&#34;&gt;リポジトリの更新&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# リポジトリのインデックスを更新する（新しいチャートバージョンを取得）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;チャートの検索&#34;&gt;チャートの検索&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# リポジトリからチャートを検索する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm search repo nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm search repo mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;チャート情報の表示&#34;&gt;チャート情報の表示&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# チャートの詳細情報を表示する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm show chart bitnami/nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm show values bitnami/nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;インストール&#34;&gt;インストール&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# チャートをインストールする&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm install my-nginx bitnami/nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 名前空間を指定してインストール&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm install my-nginx bitnami/nginx -n production --create-namespace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# カスタム値でインストール&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm install my-nginx bitnami/nginx --set service.type&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;LoadBalancer
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;リリース一覧の表示&#34;&gt;リリース一覧の表示&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# インストール済みのリリースを表示する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm list
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 全ての名前空間のリリースを表示する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm list -A
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 特定の名前空間のリリースを表示する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm list -n production
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;リリース情報の確認&#34;&gt;リリース情報の確認&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# リリースの詳細情報を表示する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm get all my-nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# リリースの設定値を表示する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm get values my-nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# リリースの履歴を表示する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm &lt;span class=&#34;nb&#34;&gt;history&lt;/span&gt; my-nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;アップグレード&#34;&gt;アップグレード&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# リリースをアップグレードする&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm upgrade my-nginx bitnami/nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 新しい値でアップグレード&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm upgrade my-nginx bitnami/nginx --set image.tag&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1.21.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;ロールバック&#34;&gt;ロールバック&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 前のバージョンにロールバックする&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm rollback my-nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 特定のリビジョンにロールバックする&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm rollback my-nginx &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;アンインストール&#34;&gt;アンインストール&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# リリースを削除する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm uninstall my-nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 名前空間を指定して削除&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm uninstall my-nginx -n production
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;ドライラン&#34;&gt;ドライラン&lt;/h4&gt;
&lt;p&gt;実際にはインストールせずに、何が実行されるかを確認できます。&lt;/p&gt;</description>
    </item>
    <item>
      <title>kubectlで全てのリソースをgetする方法</title>
      <link>https://kkato.dev/posts/kubectl-get-all/</link>
      <pubDate>Mon, 11 Aug 2025 13:02:00 +0900</pubDate>
      <guid>https://kkato.dev/posts/kubectl-get-all/</guid>
      <description>&lt;p&gt;&lt;code&gt;kubectl get all&lt;/code&gt;だとCustom Resourceが表示されないので、全てのリソースが表示できずに困ることがありました。&lt;code&gt;kubectl api-resources&lt;/code&gt;を使えば、Custom Resourceを含めた全てのリソースを表示することができます。&lt;/p&gt;
&lt;h3 id=&#34;全てのリソースを表示する&#34;&gt;全てのリソースを表示する&lt;/h3&gt;
&lt;p&gt;以下のコマンドで、特定のnamespaceに存在する、全てのリソース(Custom Resourceも含めて)を表示することができます。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;kubectl api-resources --verbs&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;list --namespaced -o name &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep -v &lt;span class=&#34;s2&#34;&gt;&amp;#34;events&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; tr &lt;span class=&#34;s1&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sed &lt;span class=&#34;s1&#34;&gt;&amp;#39;s/,$//&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; -n openebs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kubectl api-resources&lt;/code&gt;: クラスター内のCustom Resourceを含む全てのKubernetesリソース名を表示&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--verbs=list&lt;/code&gt;: list操作が可能なものに絞る&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--namespaced&lt;/code&gt;: 名前空間に属するリソース名に絞る (NamespaceやNodeなどのcluster-scopedリソースは対象外)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o name&lt;/code&gt;: kubectlでgetできるリソース名だけを出力&lt;/li&gt;
&lt;li&gt;&lt;code&gt;grep -v &amp;quot;events&amp;quot;&lt;/code&gt;: eventsリソースは大量に出力されてしまうため、除外する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tr &#39;\n&#39; &#39;,&#39;&lt;/code&gt;: 出力されたリソース名を、改行区切りからカンマ区切りに変換&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sed &#39;s/,$//&#39;&lt;/code&gt;: 末尾に付いてしまった余分なカンマを削除&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>kubectlとjqコマンドの便利な組み合わせ</title>
      <link>https://kkato.dev/posts/kubectl-jq/</link>
      <pubDate>Sun, 10 Aug 2025 19:52:30 +0900</pubDate>
      <guid>https://kkato.dev/posts/kubectl-jq/</guid>
      <description>&lt;p&gt;jqコマンドとは、JSON形式のデータを処理・変換するためのコマンドです。
普段はkubectlやAWS CLIと組み合わせて使うことが多いのですが、使い方やオプションをきちんと調べたことがなかったため、改めておさらいしようと思います。&lt;/p&gt;
&lt;h3 id=&#34;keys関数&#34;&gt;keys関数&lt;/h3&gt;
&lt;p&gt;これまでは&lt;code&gt;jq &#39;.&#39;&lt;/code&gt;のように全階層をまとめて表示してキーを把握していましたが、keys関数を使うと一階層ずつキーを表示できます。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# labelのキーを取得する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get pod my-pod -o json &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; jq &lt;span class=&#34;s1&#34;&gt;&amp;#39;.metadata.labels | keys&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;select関数&#34;&gt;select関数&lt;/h3&gt;
&lt;p&gt;select関数は条件にマッチした項目のみを抽出します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Running状態ではないPodの一覧を取得する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get pods -A -o json &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; jq &lt;span class=&#34;s1&#34;&gt;&amp;#39;.items[] | select(.status.phase != &amp;#34;Running&amp;#34;) | .metadata.name&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# namespace、Pod名、Podの状態も合わせて表示する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get pods -A -o json &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; jq -r &lt;span class=&#34;s1&#34;&gt;&amp;#39;.items[] | select(.status.phase != &amp;#34;Running&amp;#34;) | &amp;#34;\(.metadata.namespace) \(.metadata.name) \(.status.phase)&amp;#34;&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; column -t
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;2つ目のコマンドではいくつかのオプションや機能を使っているため、それらについて説明します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-r&lt;/code&gt;: ダブルクォートを削除するオプション(デフォルトでは&lt;code&gt;&amp;quot;&lt;/code&gt;が付いてくる)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;quot;\(filter)&amp;quot;&lt;/code&gt;: 文字列の中で &lt;code&gt;\(filter)&lt;/code&gt; を使うことで、抽出した値を文字列に埋め込める。これにより、複数の値を空白区切りで1行に表示できる&lt;/li&gt;
&lt;li&gt;&lt;code&gt;columnt -t&lt;/code&gt;: columnコマンドの&lt;code&gt;-t&lt;/code&gt;オプションを使うことで、区切り文字を基準に列を揃えて表形式で表示できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;contains関数&#34;&gt;contains関数&lt;/h3&gt;
&lt;p&gt;contains関数は指定した文字列が含まれていればtrueを返します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# コンテナ名に&amp;#39;ghr.io&amp;#39;を含むPodを検索する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get pods -o json &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; jq &lt;span class=&#34;s1&#34;&gt;&amp;#39;.items[] | select(.spec.containers[].name | contains(&amp;#34;gcr.io&amp;#34;)) | .metadata.name&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;まとめ&#34;&gt;まとめ&lt;/h3&gt;
&lt;p&gt;kubectl と jq の組み合わせは業務でよく使っていたものの、正直ちゃんと理解できていなかった部分も多かったので、今回改めておさらいできてよかったです。
特に keys や select、contains などの関数を使うと、複雑な JSON から必要な情報をサクッと抜き出せるのが便利だなと感じました。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Renovateの導入方法</title>
      <link>https://kkato.dev/posts/renovate/</link>
      <pubDate>Tue, 06 May 2025 15:27:19 +0900</pubDate>
      <guid>https://kkato.dev/posts/renovate/</guid>
      <description>&lt;p&gt;手動での依存パッケージのアップデートが大変だったので、&lt;a href=&#34;https://docs.renovatebot.com/&#34;&gt;Renovate&lt;/a&gt;を導入してみました。
その手順と設定について簡単にメモします。&lt;/p&gt;
&lt;h3 id=&#34;renovateとは&#34;&gt;Renovateとは？&lt;/h3&gt;
&lt;p&gt;Renovateは、依存関係の更新を自動化してくれるOSSのツールです。元々は個人開発から始まり、現在はイスラエルのセキュリティ企業 Mend社によって開発されています。&lt;/p&gt;
&lt;p&gt;リポジトリ内の依存関係をスキャンし、新しいバージョンが利用可能な場合には自動でPull Request（PR）を作成してくれます。
Node.jsのnpmやyarnはもちろん、Go modules、Docker、Terraformなど多くの言語やパッケージマネージャーに対応しています。&lt;/p&gt;
&lt;p&gt;対応しているパッケージマネージャーの一覧は&lt;a href=&#34;https://docs.renovatebot.com/modules/manager/#supported-managers&#34;&gt;こちら&lt;/a&gt;にあります。&lt;/p&gt;
&lt;h3 id=&#34;導入手順&#34;&gt;導入手順&lt;/h3&gt;
&lt;p&gt;renovateはセルフホストする方法とGitHub Appを使う方法の2通りありますが、手軽に使いたいので、今回はGitHub Appを使って導入します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apps/renovate&#34;&gt;https://github.com/apps/renovate&lt;/a&gt; から「Configure」を押す&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://kkato.dev/images/renovate/configure.png&#34;&gt;&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;全てのリポジトリを選択し、導入する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;全てのリポジトリを選択したとしても、renovateの設定ファイルがあるリポジトリのみrenovateが有効になります。
そのため、renovateの設定ファイルがないリポジトリではrenovateが無効化されます。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://kkato.dev/images/renovate/repository-access.png&#34;&gt;&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;renovateの設定ファイル&lt;code&gt;renovate.json&lt;/code&gt;を作成し、リポジトリのrootにpushする&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;各リポジトリで&lt;code&gt;Configure Renovate&lt;/code&gt;というPull Requestが自動的に作成されます。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://kkato.dev/images/renovate/configure-renovate.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;自動生成された&lt;code&gt;renovate.json&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;$schema&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://docs.renovatebot.com/renovate-schema.json&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;extends&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;config:recommended&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Renovateにおける&lt;code&gt;$schema&lt;/code&gt;は、&lt;code&gt;renovate.json&lt;/code&gt;で使える設定項目やその値の種類・ルールを定義しています。
これにより、どの設定が有効かをエディタが理解できたり、エディタによる補完などが有効になったりします。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;extends&lt;/code&gt;では、Renovateがあらかじめ用意しているルールセットを指定することができます。
上記の例では&lt;code&gt;config:recommended&lt;/code&gt;を指定しています。これには、どの言語やプロジェクトでも使える推奨設定が含まれています。
（以前は&lt;code&gt;config:recommended&lt;/code&gt;ではなく、&lt;code&gt;config:base&lt;/code&gt;と呼ばれていたみたいです。）&lt;/p&gt;
&lt;p&gt;config:recommended の詳細については&lt;a href=&#34;https://docs.renovatebot.com/presets-config/#configrecommended&#34;&gt;こちら&lt;/a&gt; &lt;br&gt;
またその他設定項目については&lt;a href=&#34;https://docs.renovatebot.com/configuration-options/&#34;&gt;こちら&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;まとめ&#34;&gt;まとめ&lt;/h3&gt;
&lt;p&gt;現在業務でRenovate を使ってみて感じたのは、カスタマイズ性が非常に高い反面、設定項目が多くてややとっつきにくいという点でした。しかし、プライベートの時間を使って軽く触ってみたところ、導入自体は想像以上に簡単で、いい意味で期待を裏切られました。最小限の設定でもすぐに使い始めることができましたが、もう少しドキュメントを読んで複雑な設定も試してみたいと思いました。&lt;/p&gt;</description>
    </item>
    <item>
      <title>PostgreSQL16をソースコードからビルドしてみる</title>
      <link>https://kkato.dev/posts/postgresql16-build/</link>
      <pubDate>Wed, 18 Sep 2024 14:47:07 +0900</pubDate>
      <guid>https://kkato.dev/posts/postgresql16-build/</guid>
      <description>&lt;p&gt;PostgreSQL16をソースコードからビルドしてみたのですが、いくつかつまづいたポイントがあるので、それらにご紹介します。&lt;/p&gt;
&lt;p&gt;PostgreSQL16をソースコードからビルドするためのコマンドは以下のとおりです。前提として M1 Mac (macOS 14.4.1) を使っています。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;% git clone git://git.postgresql.org/git/postgresql.git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;% &lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; postgresql
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;% ./configure --enable-debug --enable-cassert --enable-tap-tests --prefix&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$HOME&lt;/span&gt;/pgsql &lt;span class=&#34;nv&#34;&gt;CFLAGS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;-O0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;% make -j &lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;% make install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;configureコマンドには以下のオプションを指定しています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;デバッグしやすくするためのオプション: &amp;ndash;enable-debug &amp;ndash;enable-cassert &amp;ndash;enable-tap-tests&lt;/li&gt;
&lt;li&gt;インストール先のディレクトリを指定するオプション: &amp;ndash;prefix&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;参考: &lt;a href=&#34;https://www.postgresql.jp/document/16/html/install-make.html#CONFIGURE-OPTIONS&#34;&gt;https://www.postgresql.jp/document/16/html/install-make.html#CONFIGURE-OPTIONS&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;icu-uc-icu-i18nのパッケージが見つからない&#34;&gt;&lt;code&gt;icu-uc&lt;/code&gt;, &lt;code&gt;icu-i18n&lt;/code&gt;のパッケージが見つからない&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;icu-uc&lt;/code&gt;, &lt;code&gt;icu-i18n&lt;/code&gt;のパッケージが見つからないと言われました。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;% ./configure --enable-debug --enable-cassert --enable-tap-tests --prefix=$HOME/pgsql CFLAGS=-O0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(省略)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;checking for icu-uc icu-i18n... no
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;configure: error: Package requirements (icu-uc icu-i18n) were not met:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;No package &amp;#39;icu-uc&amp;#39; found
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;No package &amp;#39;icu-i18n&amp;#39; found
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Consider adjusting the PKG_CONFIG_PATH environment variable if you
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;installed software in a non-standard prefix.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Alternatively, you may set the environment variables ICU_CFLAGS
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;and ICU_LIBS to avoid the need to call pkg-config.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;See the pkg-config man page for more details.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;PKG_CONFIG_PATHという環境変数を設定してあげれば良いみたいです。
以下のコマンドを実行すると、どう設定すればいいか教えてくれました。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Rocky Linuxにcontainerdをインストールする方法</title>
      <link>https://kkato.dev/posts/rocky-containerd/</link>
      <pubDate>Sun, 30 Jun 2024 16:46:03 +0900</pubDate>
      <guid>https://kkato.dev/posts/rocky-containerd/</guid>
      <description>&lt;p&gt;以前Kubernetesクラスタを構築するときに、Rocky Linuxでcontainerdをインストールする方法についてあまり情報がなかったので、とても苦労しました。
なので今回はその時に調べた内容を記事にしてみました。&lt;/p&gt;
&lt;p&gt;次のコマンドでcontainerdをインストールできます。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# yumにCentOS用のdockerリポジトリを追加する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo yum config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# docker-ceリポジトリに含まれているcontainerd.ioのパッケージをインストールする&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo yum install -y containerd.io
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# containerdのデフォルト設定ファイルを生成する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo sh -c &lt;span class=&#34;s2&#34;&gt;&amp;#34;containerd config default &amp;gt; /etc/containerd/config.toml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;そして最後にcontainerdを有効化します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl &lt;span class=&#34;nb&#34;&gt;enable&lt;/span&gt; --now containerd.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;参考&#34;&gt;参考&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://medium.com/@DannielWhatever/using-containerd-without-docker-9d08332781b4&#34;&gt;Using containerd without docker&lt;/a&gt; (Installing containerdの部分)&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>NUC上にk8sクラスタを構築する</title>
      <link>https://kkato.dev/posts/nuc-k8s/</link>
      <pubDate>Wed, 05 Jun 2024 21:20:47 +0900</pubDate>
      <guid>https://kkato.dev/posts/nuc-k8s/</guid>
      <description>&lt;p&gt;しばらく放置していたNUC上にk8sをインストールして、おうちクラスタを運用していこうと思います。
今回はkubeadmを使ってk8sをインストールしようと思います。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://kkato.dev/images/nuc-k8s/nuc.jpg&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;前提&#34;&gt;前提&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ベアメタル(Intel NUC11PAHi5)上に構築&lt;/li&gt;
&lt;li&gt;Control Planex1台とWorkerx3台の4台構成&lt;/li&gt;
&lt;li&gt;OSはRocky Linux9.3&lt;/li&gt;
&lt;li&gt;ルーター側の設定で固定IPを割り当て&lt;/li&gt;
&lt;li&gt;各ノードのスペックは以下&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;CPU&lt;/th&gt;
          &lt;th&gt;メモリ&lt;/th&gt;
          &lt;th&gt;ストレージ&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;4コア&lt;/td&gt;
          &lt;td&gt;16GB&lt;/td&gt;
          &lt;td&gt;500GB&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;kubeadmのインストール&#34;&gt;kubeadmのインストール&lt;/h3&gt;
&lt;p&gt;以下の手順を参考にします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/&#34;&gt;kubeadmのインストール&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;「始める前に」にSwapがオフであること、と記載がありますが、swapがオフになっていなかったので無効化します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;sudo swapoff -a
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;ポートの開放&#34;&gt;ポートの開放&lt;/h4&gt;
&lt;p&gt;kubernetesのコンポーネントが互いに通信するために、&lt;a href=&#34;https://kubernetes.io/docs/reference/networking/ports-and-protocols/&#34;&gt;これらのポート&lt;/a&gt;を開く必要があります。
RockyはRHEL系なので&lt;code&gt;firewall-cmd&lt;/code&gt;を使って、Control Planeノードのポートを開放します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;sudo firewall-cmd --add-port=6443/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;sudo firewall-cmd --add-port=2379-2380/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;sudo firewall-cmd --add-port=10250/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;sudo firewall-cmd --add-port=10257/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;sudo firewall-cmd --add-port=10259/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ポートが開放されたことを確認します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;sudo firewall-cmd --reload
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;sudo firewall-cmd --list-ports
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;続いて各Workerノードのポートを開放します。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-coonsole&#34; data-lang=&#34;coonsole&#34;&gt;sudo firewall-cmd --add-port=30000-32767/tcp --permanent
sudo firewall-cmd --add-port=10250/tcp --permanent
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ポートが開放されたことを確認します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;sudo firewall-cmd --reload
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;sudo firewall-cmd --list-ports
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;コンテナランタイムのインストール&#34;&gt;コンテナランタイムのインストール&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://kubernetes.io/ja/docs/setup/production-environment/container-runtimes/&#34;&gt;コンテナランタイム&lt;/a&gt;の手順を参考に、各ノードに設定をしていきます。&lt;/p&gt;</description>
    </item>
    <item>
      <title>ウォンテッドリーに入社しました</title>
      <link>https://kkato.dev/posts/wantedly/</link>
      <pubDate>Tue, 06 Feb 2024 14:31:31 +0900</pubDate>
      <guid>https://kkato.dev/posts/wantedly/</guid>
      <description>&lt;p&gt;ウォンテッドリーに入社して1ヶ月経ったので、色々と振り返ってみようと思います。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://kkato.dev/images/wantedly/wantedly.jpeg&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;転職を考えたきっかけ&#34;&gt;転職を考えたきっかけ&lt;/h3&gt;
&lt;p&gt;前職ではややニッチなテーマに取り組んでいたこともあり、そのまま長く居続けても他の会社でやっていけるか不安でした。また、変化が早い時代なので、会社に依存せず個人でやっていけるだけの実力・スキルを身につけたいと考え、もっと技術力を伸ばせるような会社に移りたいと思うようになりました。&lt;/p&gt;
&lt;h3 id=&#34;企業選びの軸&#34;&gt;企業選びの軸&lt;/h3&gt;
&lt;p&gt;企業選びは以下の軸をもとに考えました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自社でサービスを開発・運用している&lt;/li&gt;
&lt;li&gt;技術力の高いエンジニアが在籍している&lt;/li&gt;
&lt;li&gt;先進的な技術を扱っている&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上記の条件を満たすような会社であれば、もっと技術力を伸ばせると思ったからです。&lt;/p&gt;
&lt;h3 id=&#34;転職に向けて行ったこと&#34;&gt;転職に向けて行ったこと&lt;/h3&gt;
&lt;p&gt;インフラエンジニア / SRE職を希望していたので、主に以下のようなことを行いました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;関連する資格の取得 (AWS SAP、CKA)&lt;/li&gt;
&lt;li&gt;個人ブログでの発信&lt;/li&gt;
&lt;li&gt;簡単なWebアプリの作成&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;前職でPostgreSQL、Kubernetesを触る機会があったものの、AWSやTerraformの経験、それに本番環境の運用経験がなく苦労しました。実務での経験不足を補うために、AWSの資格を取得したり、個人ブログで今まで学んだことのアウトプットなどを行うようにしました。また、SRE職などだと自動化のツールなどをGoで書くこともあると思ったので、Goで簡単なTo-doアプリを作成したりしました。&lt;/p&gt;
&lt;h3 id=&#34;ウォンテッドリーへの入社を決めた経緯&#34;&gt;ウォンテッドリーへの入社を決めた経緯&lt;/h3&gt;
&lt;p&gt;ウォンテッドリーへはスカウト経由で入社しました。（Wantedly Visitに登録したら、ウォンテッドリーからスカウトが来てびっくりしました笑）カジュアル面談で話を聞いていると、PostgreSQLやKubernetesなど今まで培った経験を活かしつつ、新しい挑戦ができそうだったので、選考を受けてみようと思いました。&lt;/p&gt;
&lt;p&gt;選考を受ける前だったか、1次面接の後だったか覚えていませんが、&lt;a href=&#34;https://docs.wantedly.dev/&#34;&gt;Engineering Handbook&lt;/a&gt;と&lt;a href=&#34;https://www.wantedly.com/companies/wantedly/post_articles/883691&#34;&gt;Culture Book&lt;/a&gt;をいただきました。まず、開発や会社の文化に関することがこのような形にまとめられているのが素敵だと思いました。そして、内容に関してもエンジニアリングに対して真摯に向き合う姿勢やエンジニアにとても理解のある会社だということが伝わってきて、こんな会社で働いてみたいと思うようになりました。（個人的にはCulture Bookの「変わるエンジニアの定義」が好きです。)&lt;/p&gt;
&lt;p&gt;また、2次選考として 1 day インターンに参加させていただきました。わずか1日のインターンシップではあるものの、チームメンバーがどんな人なのか、日々どんな業務に取り組んでいるのかなど実際に働くイメージがつき、その後安心して入社することができました。&lt;/p&gt;
&lt;h3 id=&#34;入社してからの感想&#34;&gt;入社してからの感想&lt;/h3&gt;
&lt;p&gt;毎日分からないことだらけですが、その分学ぶことが多くてとても充実しています。周りのエンジニアの方々は技術力が高くて、尊敬できる方ばかりです。&lt;/p&gt;
&lt;p&gt;オンボーディングに関しては、研修や社内のドキュメントが整備されていて、スムーズに環境に馴染むことができました。分からないことがあるとすぐに聞ける雰囲気があり、ちょっとしたことでもSlackやHuddleで相談できて大変ありがたいです。週2出社なので、対面でのコミュニケーションもできて良い感じです。&lt;/p&gt;
&lt;p&gt;びっくりしたことは、会議室の名前がジョジョの奇妙な冒険からつけられていること、白金台のランチの選択肢の少なさ、あとはエンジニアの1割がDvorak使いということですかね笑　&lt;/p&gt;
&lt;h3 id=&#34;今後ウォンテッドリーで取り組みたいこと&#34;&gt;今後ウォンテッドリーで取り組みたいこと&lt;/h3&gt;
&lt;p&gt;今後取り組みたいことは以下の通りです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes, PostgreSQLなどのアップグレード&lt;/li&gt;
&lt;li&gt;インフラの性能監視・運用改善・障害対応&lt;/li&gt;
&lt;li&gt;Goを用いたツールの開発&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;前職だと実運用を経験していなかったので、システム基盤のアップグレードを経験したいという思いがあります。同様に、性能監視や運用改善、障害対応などインフラエンジニアとして求められている基本的な業務も一通り経験してみたいです。また、ウォンテッドリーのインフラチームは様々なツールをGoで実装しているので、それらの実装を理解し改善していけるだけの力をつけていきたいです。&lt;/p&gt;
&lt;p&gt;上記以外にも直近不足している知識(NW、AWS、Terraform、Gitなど)が多いので、日々精進していく所存です！&lt;/p&gt;</description>
    </item>
    <item>
      <title>Alertmanagerのwebhookを試してみる</title>
      <link>https://kkato.dev/posts/webhook-nginx/</link>
      <pubDate>Sun, 13 Aug 2023 13:11:42 +0900</pubDate>
      <guid>https://kkato.dev/posts/webhook-nginx/</guid>
      <description>&lt;p&gt;Kubernetes上でAlertmanagerがちゃんと通知できるか、どんな内容が通知されているのか確認してみようとすると、連携するためのSlackが必要であったり、Emailを送信するにもメールサーバが必要だったりと、意外と気軽に試せないということがありました。&lt;/p&gt;
&lt;p&gt;なので、今回はwebhookの機能を使ってNginxにリクエストを飛ばし、リクエストの内容をログから確認してみようと思います。&lt;/p&gt;
&lt;h3 id=&#34;webhookとは&#34;&gt;webhookとは?&lt;/h3&gt;
&lt;p&gt;Alertmanagerのreceiverには以下が指定できます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Email&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.atlassian.com/software/opsgenie&#34;&gt;Opesgenie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.pagerduty.com/&#34;&gt;PagerDuty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pushover.net/&#34;&gt;Pushover&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://slack.com/intl/ja-jp&#34;&gt;Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://aws.amazon.com/jp/sns/&#34;&gt;AWS SNS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.splunk.com/en_us/about-splunk/acquisitions/splunk-on-call.html&#34;&gt;VictorOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Webhook&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.wechat.com/ja/&#34;&gt;Wechat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://telegram.org/&#34;&gt;Telegram&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.webex.com/ja/index.html&#34;&gt;Webex&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Webhookとは特定のエンドポイントに対してHTTP POSTリクエストでアラートの情報を送信するというものです。
外部サービスではないので、自分自身でエンドポイントを用意し、自分自身で後続の処理を実装する必要があります。&lt;/p&gt;
&lt;p&gt;例えば、以下のように設定します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;receivers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;nginx&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;webhook_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;http://nginx-svc.default:8080/&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;webhookの連携先としてnginxを使う&#34;&gt;webhookの連携先としてnginxを使う&lt;/h3&gt;
&lt;p&gt;今回はwebhookの連携先としてnginxを使用します。&lt;/p&gt;
&lt;p&gt;nginxを使って実現したいことは以下のとおりです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;エンドポイントを用意する&lt;/li&gt;
&lt;li&gt;リクエスト内容を確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;nginx.confの初期設定をベースにしていますが、そのままだとリクエスト内容を確認することができないので、設定を追加しました。
&lt;code&gt;log_format&lt;/code&gt;で&lt;code&gt;$request_body&lt;/code&gt;を指定し、&lt;code&gt;/&lt;/code&gt;にアクセスした時に&lt;code&gt;$request_body&lt;/code&gt;がログとして標準出力に出るように設定しています。&lt;/p&gt;
&lt;p&gt;しかし、&lt;code&gt;$request_body&lt;/code&gt;を有効化するには&lt;code&gt;proxy_pass&lt;/code&gt;などの後続処理が必要になります。なので、&lt;code&gt;proxy_pass&lt;/code&gt;で&lt;code&gt;/trash&lt;/code&gt;というエンドポイントにリクエストを転送し、&lt;code&gt;/trash&lt;/code&gt;で特に意味のない処理(1x1ピクセルのgifを返す)をしています。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The variable’s value is made available in locations processed by the proxy_pass, fastcgi_pass, uwsgi_pass, and scgi_pass directives when the request body was read to a memory buffer.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_body&#34;&gt;http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_body&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-nginx&#34; data-lang=&#34;nginx&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;user&lt;/span&gt;  &lt;span class=&#34;s&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;worker_processes&lt;/span&gt;  &lt;span class=&#34;s&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;error_log&lt;/span&gt;  &lt;span class=&#34;s&#34;&gt;/var/log/nginx/error.log&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;notice&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;pid&lt;/span&gt;        &lt;span class=&#34;s&#34;&gt;/var/run/nginx.pid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;events&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;worker_connections&lt;/span&gt;  &lt;span class=&#34;mi&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;http&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;include&lt;/span&gt;       &lt;span class=&#34;s&#34;&gt;/etc/nginx/mime.types&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;default_type&lt;/span&gt;  &lt;span class=&#34;s&#34;&gt;application/octet-stream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;log_format&lt;/span&gt;  &lt;span class=&#34;s&#34;&gt;main&lt;/span&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$remote_addr&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$remote_user&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$time_local]&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$request&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                      &lt;span class=&#34;s&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$status&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$body_bytes_sent&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$http_referer&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                      &lt;span class=&#34;s&#34;&gt;&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$http_user_agent&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$http_x_forwarded_for&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;access_log&lt;/span&gt;  &lt;span class=&#34;s&#34;&gt;/var/log/nginx/access.log&lt;/span&gt;  &lt;span class=&#34;s&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# -------------------追加設定---------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;kn&#34;&gt;log_format&lt;/span&gt;  &lt;span class=&#34;s&#34;&gt;postdata&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;escape=none&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$request_body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;server&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kn&#34;&gt;listen&lt;/span&gt;   &lt;span class=&#34;mi&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kn&#34;&gt;location&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kn&#34;&gt;access_log&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/dev/stdout&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;postdata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kn&#34;&gt;proxy_pass&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;http://127.0.0.1:8080/trash&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kn&#34;&gt;location&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/trash&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kn&#34;&gt;access_log&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;off&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kn&#34;&gt;empty_gif&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kn&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# ----------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;sendfile&lt;/span&gt;        &lt;span class=&#34;no&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;#tcp_nopush     on;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;keepalive_timeout&lt;/span&gt;  &lt;span class=&#34;mi&#34;&gt;65&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;#gzip  on;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;include&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/etc/nginx/conf.d/*.conf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上記の設定をConfigMapとして作成し、nginxのPodに対してConfigMapをマウントしてあげます。&lt;code&gt;nginx-svc&lt;/code&gt;というServiceも作成します。&lt;/p&gt;</description>
    </item>
    <item>
      <title>KubernetesのCronJobが失敗したときにアラートをあげる</title>
      <link>https://kkato.dev/posts/k8s-job-alert/</link>
      <pubDate>Tue, 08 Aug 2023 19:48:39 +0900</pubDate>
      <guid>https://kkato.dev/posts/k8s-job-alert/</guid>
      <description>&lt;p&gt;CronJobは、指定したcronフォーマットに基づいて定期的にJobを実行するという機能です。
主にバックアップの取得やメール送信など、定期的な処理を実行する際に便利です。&lt;/p&gt;
&lt;p&gt;一方で、CronJobが失敗した際にどのように検知すべきかについては、あまり情報がありませんでした。
なので、今回はそちらについて考えてみたいと思います。&lt;/p&gt;
&lt;h3 id=&#34;kube-state-metricsを活用する&#34;&gt;kube-state-metricsを活用する&lt;/h3&gt;
&lt;p&gt;kube-state-metricsとはKubernetesクラスタ内のリソースの状態をメトリクスとして提供してくれるというものです。
kube-state-metricsではCronJobやJobの状態をメトリクスとして取得することができます。
この方式採用している記事が多かったので、こちらで検討を進めてみたいと思います。&lt;/p&gt;
&lt;p&gt;※記事&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://medium.com/@tristan_96324/prometheus-k8s-cronjob-alerts-94bee7b90511&#34;&gt;https://medium.com/@tristan_96324/prometheus-k8s-cronjob-alerts-94bee7b90511&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.giffgaff.io/tech/monitoring-kubernetes-jobs&#34;&gt;https://www.giffgaff.io/tech/monitoring-kubernetes-jobs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;どのメトリクスを使い監視するか&#34;&gt;どのメトリクスを使い監視するか&lt;/h3&gt;
&lt;p&gt;CronJobはcronフォーマットで指定された時刻にJobを生成し、そのJobがPodを生成するという3層の親子構造になっています。
また、CronJobとJobの関係は1対多で、JobとPodの関係は1対多になります。&lt;/p&gt;
&lt;p&gt;Jobが完了するのは&lt;code&gt;completions&lt;/code&gt;個のPodが正常終了した場合、もしくは&lt;code&gt;backoffLimit&lt;/code&gt;個のPodが異常終了した場合に限ります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;completions
&lt;ul&gt;
&lt;li&gt;completions個のPodが成功すると、Jobが完了したとみなされる&lt;/li&gt;
&lt;li&gt;デフォルトは1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;backoffLimit
&lt;ul&gt;
&lt;li&gt;失敗したと判断するまでの再試行回数で、この回数を超えるとJobは失敗とみなされる&lt;/li&gt;
&lt;li&gt;デフォルトは6&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そして、アラートを上げたいのはJobが失敗した時です。言い換えると、&lt;code&gt;backoffLimit&lt;/code&gt;個のPodが異常終了したときにアラートを上げるということになります。
何個のPodが異常終了したのか監視することも可能だと思いますが、ここではJobのステータスを監視するのが適切かと思います。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;メトリクス&lt;/th&gt;
          &lt;th&gt;対応する項目&lt;/th&gt;
          &lt;th&gt;説明&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;kube_job_status_succeeded&lt;/td&gt;
          &lt;td&gt;.status.succeeded&lt;/td&gt;
          &lt;td&gt;Jobの管理下で正常終了したPodの数&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;kube_job_status_failed&lt;/td&gt;
          &lt;td&gt;.status.failed&lt;/td&gt;
          &lt;td&gt;Jobの管理下で異常終了したPodの数&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;kube_job_complete&lt;/td&gt;
          &lt;td&gt;.status.conditions.type&lt;/td&gt;
          &lt;td&gt;Jobが成功したかどうか&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;kube_job_failed&lt;/td&gt;
          &lt;td&gt;.status.conditions.type&lt;/td&gt;
          &lt;td&gt;Jobが失敗したかどうか&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;参考: &lt;a href=&#34;https://github.com/kubernetes/kube-state-metrics/blob/main/docs/job-metrics.md&#34;&gt;https://github.com/kubernetes/kube-state-metrics/blob/main/docs/job-metrics.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Jobに関するメトリクスは複数ありますが、この中でも特に&lt;code&gt;kube_job_failed&lt;/code&gt;を使ってアラートを上げるのが良さそうです。
以下の設定だと、Jobが失敗したときにアラートが上がります。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kube_job_failed &amp;gt; 0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;アラートが発火し続けてしまう問題&#34;&gt;アラートが発火し続けてしまう問題&lt;/h3&gt;
&lt;p&gt;失敗したJobは削除されずに残り続けるので、アラートが発火し続けてしまいます。
なので、Jobの&lt;code&gt;ttlSecondsAfterFinished&lt;/code&gt;を設定し、数分後にJobが削除されるようにします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ttlSecondsAfterFinished
&lt;ul&gt;
&lt;li&gt;指定秒後にJobを削除できる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CronJobの&lt;code&gt;failedJobsHistoryLimit&lt;/code&gt;を設定するという方法も思いつきましたが、0にしてしまうとそもそもアラートが上がらないと思うので、こちらは1のままにしておきました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;failedJobsHistoryLimit
&lt;ul&gt;
&lt;li&gt;失敗したJobを指定個数分残しておける&lt;/li&gt;
&lt;li&gt;デフォルトは1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;まとめ&#34;&gt;まとめ&lt;/h3&gt;
&lt;p&gt;今回はkube-state-metricsを活用して、CronJobが失敗した時のアラートを設定しました。CronJob失敗時にアラートを上げる方法についてはあまり参考になる記事がなく、私なりに考えてみました。他にもっといい方法をご存知の方は教えていただけるとありがたいです。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linuxで公開鍵認証をする</title>
      <link>https://kkato.dev/posts/pubkey-auth/</link>
      <pubDate>Wed, 12 Jul 2023 21:23:52 +0900</pubDate>
      <guid>https://kkato.dev/posts/pubkey-auth/</guid>
      <description>&lt;p&gt;Linuxでの公開鍵認証の設定をよく忘れてしまうので、備忘録としてメモを残しておきます。&lt;/p&gt;
&lt;h3 id=&#34;接続元での設定&#34;&gt;接続元での設定&lt;/h3&gt;
&lt;p&gt;接続元で鍵を生成し、公開鍵を接続先のサーバーへコピーします。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ssh-keygen
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;scp ~/id_rsa.pub username@server:~/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;接続先の設定&#34;&gt;接続先の設定&lt;/h3&gt;
&lt;p&gt;接続先のサーバーで公開鍵の情報をauthorized_keysに登録し、適切な権限を設定します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mkdir ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;chmod &lt;span class=&#34;m&#34;&gt;700&lt;/span&gt; ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cat id_rsa.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;chmod &lt;span class=&#34;m&#34;&gt;600&lt;/span&gt; ~/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;公開鍵認証を有効化し、パスワード認証を無効化します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo vi /etc/ssh/sshd_config
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PubkeyAuthentication yes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PasswordAuthentication no
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;sshdを再起動します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl restart sshd
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>kubesprayでk8sクラスタを構築する</title>
      <link>https://kkato.dev/posts/kubespray/</link>
      <pubDate>Mon, 01 May 2023 10:07:31 +0900</pubDate>
      <guid>https://kkato.dev/posts/kubespray/</guid>
      <description>&lt;p&gt;k8s構築ツールはいろいろありますが、公式ドキュメントでは以下が紹介されています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/ja/docs/setup/learning-environment/&#34;&gt;学習環境&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Minikube&lt;/li&gt;
&lt;li&gt;Kind&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/ja/docs/setup/production-environment/&#34;&gt;プロダクション環境&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;kubeadm&lt;/li&gt;
&lt;li&gt;kops&lt;/li&gt;
&lt;li&gt;kubespray&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;※各ツールの違いについては&lt;a href=&#34;https://github.com/kubernetes-sigs/kubespray/blob/master/docs/comparisons.md&#34;&gt;こちら&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;今回はその中でも&lt;a href=&#34;https://github.com/kubernetes-sigs/kubespray&#34;&gt;kubespray&lt;/a&gt;というツールを使ってk8sクラスタを構築してみようと思います。kubeadmは1台ずつインストールを実施するのに対し、kubesprayはAnsibleを使い、各ノードで一斉にインストールを実施します。なので、kubesprayは台数が多いときに便利です。&lt;/p&gt;
&lt;p&gt;ちなみに、kubesprayは内部でkubeadmを使っているので、kubespray = kubeadm + Ansibleという感じです。また、kubesprayを使うと、コンテナランタイム(デフォルトはcontainerd)やPod間通信のネットワークプラグイン(デフォルトはcalico)などが自動でインストールされるので、非常に便利です。&lt;/p&gt;
&lt;h3 id=&#34;構築&#34;&gt;構築&lt;/h3&gt;
&lt;p&gt;前提:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ベアメタル(Intel NUC11PAHi5)上に構築&lt;/li&gt;
&lt;li&gt;Control Planex1台とWorkerx3台の4台構成&lt;/li&gt;
&lt;li&gt;OSはRocky Linux9.1&lt;/li&gt;
&lt;li&gt;ルーター側の設定で固定IPを割り当て&lt;/li&gt;
&lt;li&gt;各ノードのスペックは以下&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;CPU&lt;/th&gt;
          &lt;th&gt;メモリ&lt;/th&gt;
          &lt;th&gt;ストレージ&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;4コア&lt;/td&gt;
          &lt;td&gt;16GB&lt;/td&gt;
          &lt;td&gt;500GB&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;ssh公開認証の設定&#34;&gt;ssh公開認証の設定&lt;/h4&gt;
&lt;p&gt;手元のPCからパスワードなしでssh接続できるように公開鍵認証の設定をします。
ssh-keygenのパスワードには空文字を指定します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kkato@bastion:~$ ssh-keygen
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kkato@bastion:~$ scp ~/.ssh/id_rsa.pub 192.168.10.xxx:~/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;公開鍵の情報を各ノードのauthorized_keysに追記します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kkato@nuc01:~$ mkdir ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kkato@nuc01:~$ chmod &lt;span class=&#34;m&#34;&gt;700&lt;/span&gt; /.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kkato@nuc01:~$ cat id_rsa.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kkato@nuc01:~$ chmod &lt;span class=&#34;m&#34;&gt;600&lt;/span&gt; ~/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;etchostsの編集&#34;&gt;/etc/hostsの編集&lt;/h4&gt;
&lt;p&gt;手元のPCから各ノードへホスト名で接続できるように、/etc/hostsを編集します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kkato@bastion:~$ cat /etc/hosts
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;192.168.10.121 nuc01
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;192.168.10.122 nuc02
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;192.168.10.123 nuc03
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;192.168.10.124 nuc04
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;ユーザーの設定&#34;&gt;ユーザーの設定&lt;/h4&gt;
&lt;p&gt;各ノードのユーザーがパスワードなしでsudo実行できるよう設定します。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Raspberry Pi上にk8sクラスタを構築する</title>
      <link>https://kkato.dev/posts/raspi-k8s/</link>
      <pubDate>Sun, 23 Apr 2023 16:13:42 +0900</pubDate>
      <guid>https://kkato.dev/posts/raspi-k8s/</guid>
      <description>&lt;p&gt;最近ラズパイを手に入れたので、kubeadmを使ってk8sクラスタを組んでみたいと思います。
Control Planeノードx1 Workerノードx3の構成です。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://kkato.dev/images/raspi-k8s/raspi-cluster.jpg&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;準備&#34;&gt;準備&lt;/h3&gt;
&lt;p&gt;準備したものは以下のとおりです。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;アイテム&lt;/th&gt;
          &lt;th&gt;個数&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://www.switch-science.com/products/5680&#34;&gt;Raspberry Pi 4 Model B / 4GB&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;4&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://www.switch-science.com/products/7172?_pos=1&amp;amp;_sid=e013ece27&amp;amp;_ss=r&#34;&gt;Raspberry Pi PoE+ HAT&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;4&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://amzn.asia/d/8DQ2Vjn&#34;&gt;ケース&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://amzn.asia/d/1a7lXpn&#34;&gt;microSD 64GB&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;4&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://amzn.asia/d/6lrvPog&#34;&gt;スイッチングハブ&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://amzn.asia/d/cSs0irO&#34;&gt;LANケーブル 0.15m&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;4&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://amzn.asia/d/0IejUmF&#34;&gt;LANケーブル 1m&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://amzn.asia/d/4oTN3E9&#34;&gt;SDカードリーダー&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://amzn.asia/d/a8TZ1OH&#34;&gt;HDMI変換アダプター&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;1&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;PoE(Power over Ethernet)+ HATを使うと、LANケーブルから電源供給できるのでとても便利です。今回はPoE+ HATを使っているので、スイッチングハブもPoE対応のものを購入しています。ラズパイのOSをSDカードにインストールする必要があるので、SDカードリーダーも購入しました。あとは、ディスプレイと繋ぐときにmicro HDMIに変換するためのアダプタも購入しました。&lt;/p&gt;
&lt;h3 id=&#34;osの設定&#34;&gt;OSの設定&lt;/h3&gt;
&lt;h4 id=&#34;osのインストール&#34;&gt;OSのインストール&lt;/h4&gt;
&lt;p&gt;手元のPCはUbuntu 22.04 LTSなので、以下のコマンドでRaspberry Pi Imagerをインストールします。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sudo apt install rpi-imager
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;そして、microSDカード4枚全てにUbuntu Server 22.10 (64-bit)を焼きます。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ rpi-imager
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://kkato.dev/images/raspi-k8s/raspi-imager.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;microSDカードを差し込み、ディスプレイ(micro HDMI)とキーボード(USB)を接続し、OSの初期設定を行います。初期ユーザー名とパスワードはubuntuです。パッケージを最新にしておきます。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sudo spy update
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sudo apt upgrade -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;新しくユーザを作成し、ユーザにsudo権限を付与します。sudoをパスワードなしでできるように追加の設定もします。&lt;/p&gt;</description>
    </item>
    <item>
      <title>ジョージア工科大学 OMSCSを振り返って</title>
      <link>https://kkato.dev/posts/omscentral/</link>
      <pubDate>Mon, 10 Apr 2023 18:05:06 +0900</pubDate>
      <guid>https://kkato.dev/posts/omscentral/</guid>
      <description>&lt;p&gt;2020年8月にジョージア工科大学 コンピューターサイエンス修士課程(通称OMSCS)に入学し、2022年12月に卒業しました。今回は入学から卒業までを振り返ってみようと思います。&lt;/p&gt;
&lt;h3 id=&#34;なぜomscsを始めたのか&#34;&gt;なぜOMSCSを始めたのか&lt;/h3&gt;
&lt;p&gt;実は途中でOMSAからOMSCSに編入していたりしますが、OMSCSを始めた主な目的は以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;専門的な知識を身につける&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;私は物理学の学士課程を卒業していますが、物理を学ぶと選択肢は広がるものの少し中途半端なんですよね。例えば、機械系に行きたいとすると機械工学の学生でいいじゃん、電子系に行きたいとすると電子工学の学生でいいじゃん、IT系に行きたいとすると情報系の学生でいいじゃん、となってしまいます。なので、物理学＋αでより専門的な知識を身につけて、今後のキャリアアップに役立てたいと考えました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;海外で就職する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;実は私はカナダの大学で学士号を取得していますが、卒業当時の私は現地就職するだけの自信と実力がありませんでした。国際的に評価されている大学の修士号であれば、海外で就職するときもプラスに働くと思い、OMSCSを始めることにしました。&lt;/p&gt;
&lt;h3 id=&#34;実際どうだったか&#34;&gt;実際どうだったか&lt;/h3&gt;
&lt;p&gt;正直かなり大変でした。コロナで家にいる時間も多かったですが、平日の仕事終わりと週末は基本的に家でずっと勉強していました。遊びに誘われることもありましたが、毎回断っていたら誰からも誘われなくなりました笑&lt;/p&gt;
&lt;p&gt;どれくらいの時間が必要かというと、前提知識があるかどうかにもよると思いますが、1コースにつき週10-20時間は必要だと思います。ちなみに私は基本的に1学期に2コース取っていたので、休む時間がほとんどありませんでした。&lt;/p&gt;
&lt;p&gt;また、卒業には以下の条件があり、良い成績をとらないと卒業できないというプレッシャーがありました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最初の12ヶ月でfundamental courseを最低2つ履修し、B以上の成績を収めなければならない&lt;/li&gt;
&lt;li&gt;専門分野のコースは全てB以上の成績を収めなければならない&lt;/li&gt;
&lt;li&gt;合計GPAが3.0/4.0以上でなければならない&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;どんな授業を受けたのか&#34;&gt;どんな授業を受けたのか&lt;/h3&gt;
&lt;p&gt;OMSCSではSpecialization&lt;a href=&#34;#%E5%8F%82%E8%80%83&#34;&gt;*1&lt;/a&gt;といって専門分野を決める必要があるのですが、私はComputing Systemsにしました。その理由としては配属された部署がデータベースや分散システムなどのミドルウェアを扱うところだったから、また低レイヤーの技術に興味があったからです。OMSCSでは10コース履修する必要がありますが、そのうち5, 6コースを自分の専門分野から履修しなければなりません(いわゆる必修科目)。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;学期&lt;/th&gt;
          &lt;th&gt;受講したコース&lt;/th&gt;
          &lt;th&gt;難易度&lt;/th&gt;
          &lt;th&gt;作業量&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Fall 2020&lt;/td&gt;
          &lt;td&gt;CSE6040 Computing for Data Anlysis&lt;/td&gt;
          &lt;td&gt;易しい&lt;/td&gt;
          &lt;td&gt;10時間/週&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Fall 2020&lt;/td&gt;
          &lt;td&gt;ISYE6501 Introduction to Analytics Modeling&lt;/td&gt;
          &lt;td&gt;普通&lt;/td&gt;
          &lt;td&gt;15時間/週&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Summer 2021&lt;/td&gt;
          &lt;td&gt;CS6300 Software Development Process&lt;/td&gt;
          &lt;td&gt;普通&lt;/td&gt;
          &lt;td&gt;10時間/週&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Fall 2021&lt;/td&gt;
          &lt;td&gt;CS6250 Computer Networks&lt;/td&gt;
          &lt;td&gt;普通&lt;/td&gt;
          &lt;td&gt;10時間/週&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Fall 2021&lt;/td&gt;
          &lt;td&gt;CS7646 Machine Learning for Trading&lt;/td&gt;
          &lt;td&gt;普通&lt;/td&gt;
          &lt;td&gt;15時間/週&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Spring 2022&lt;/td&gt;
          &lt;td&gt;CS6035 Introduction to Information Security&lt;/td&gt;
          &lt;td&gt;普通&lt;/td&gt;
          &lt;td&gt;15時間/週&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Spring 2022&lt;/td&gt;
          &lt;td&gt;CS6200 Introduction to Operating Systems&lt;/td&gt;
          &lt;td&gt;難しい&lt;/td&gt;
          &lt;td&gt;20時間/週&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Summer 2022&lt;/td&gt;
          &lt;td&gt;CS6262 Network Security&lt;/td&gt;
          &lt;td&gt;普通&lt;/td&gt;
          &lt;td&gt;15時間/週&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Fall 2022&lt;/td&gt;
          &lt;td&gt;CS6515 Introduction to Graduate Algorithms&lt;/td&gt;
          &lt;td&gt;難しい&lt;/td&gt;
          &lt;td&gt;15時間/週&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Fall 2022&lt;/td&gt;
          &lt;td&gt;CS9903-O13 Quantum Computing&lt;/td&gt;
          &lt;td&gt;易しい&lt;/td&gt;
          &lt;td&gt;10時間/週&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;受講したコースについて少し紹介しようと思います。2023年現在、OMSCSでは61コース提供されており&lt;a href=&#34;#%E5%8F%82%E8%80%83&#34;&gt;*2&lt;/a&gt;、定期的に追加・更新されます。また、OMSCSにはOMSCentral&lt;a href=&#34;#%E5%8F%82%E8%80%83&#34;&gt;*3&lt;/a&gt;という非公式のレビューサイトがあるので、そちらも参考にしてみてください。&lt;/p&gt;</description>
    </item>
    <item>
      <title>ジョージア工科大学 OMSCSへの出願方法</title>
      <link>https://kkato.dev/posts/omscs/</link>
      <pubDate>Tue, 21 Mar 2023 18:04:49 +0900</pubDate>
      <guid>https://kkato.dev/posts/omscs/</guid>
      <description>&lt;p&gt;ジョージア工科大学 コンピューターサイエンス修士課程(通称OMSCS)の概要とその出願方法について紹介します。&lt;/p&gt;
&lt;h3 id=&#34;omscsとは&#34;&gt;OMSCSとは&lt;/h3&gt;
&lt;p&gt;Online Master of Science in Computer Science (OMSCS)はアメリカの州立大学であるジョージア工科大学が提供しているプログラムになります。&lt;/p&gt;
&lt;p&gt;このプログラムの特徴としては以下が挙げられます&lt;a href=&#34;#%E5%8F%82%E8%80%83&#34;&gt;*1&lt;/a&gt;。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;全てオンラインで完結すること&lt;/li&gt;
&lt;li&gt;学費が安いこと&lt;/li&gt;
&lt;li&gt;オンキャンパスと同等の学位であること&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;近年、MOOCなどオンラインで取得できる学位プログラムは増えつつありますが、OMSCSは2014に開始され、オンラインの学位プログラムとしては先駆け的な存在です。また、OMSCSは学費が安いことを売りにしており、オバマ元大統領も言及しています&lt;a href=&#34;#%E5%8F%82%E8%80%83&#34;&gt;*2&lt;/a&gt;。そして、OMSCSはオンラインの学位とオンキャンパスの学位を区別せず、同等の学位として扱います。卒業証書には&amp;quot;Master of Science in Computer Science&amp;quot;と記載されます。&lt;/p&gt;
&lt;p&gt;実際に私が支払った金額を参考までに載せておきます。(Spring 2021は諸々の事情により、学期の途中から休学することにしました。)&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;学期&lt;/th&gt;
          &lt;th&gt;米ドル&lt;/th&gt;
          &lt;th&gt;日本円&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Fall 2020&lt;/td&gt;
          &lt;td&gt;$1951&lt;/td&gt;
          &lt;td&gt;21万円&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Spring 2021&lt;/td&gt;
          &lt;td&gt;$455&lt;/td&gt;
          &lt;td&gt;5万円&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Summer 2021&lt;/td&gt;
          &lt;td&gt;$841&lt;/td&gt;
          &lt;td&gt;9万円&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Fall 2021&lt;/td&gt;
          &lt;td&gt;$1381&lt;/td&gt;
          &lt;td&gt;16万円&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Spring 2022&lt;/td&gt;
          &lt;td&gt;$1341&lt;/td&gt;
          &lt;td&gt;17万円&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Summer 2022&lt;/td&gt;
          &lt;td&gt;$841&lt;/td&gt;
          &lt;td&gt;11万円&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Fall 2022&lt;/td&gt;
          &lt;td&gt;$1187&lt;/td&gt;
          &lt;td&gt;17万円&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;合計&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;$8037&lt;/td&gt;
          &lt;td&gt;96万円&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;最近ではOMSCS以外にもOnline Master of Science in Analytics (OMSA)やOnline Master of Science in Cybersecurity (OMS Cybersecurity)などのプログラムが提供されています。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ken Kato</title>
      <link>https://kkato.dev/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://kkato.dev/about/</guid>
      <description>&lt;p&gt;I am an SRE with experience in Kubernetes, PostgreSQL, AWS, Terraform, and Go. &lt;br&gt;
I am interested in contributing to OSS. &lt;br&gt;
In my free time, I enjoy bouldering, cooking, and travelling.&lt;/p&gt;
&lt;h3 id=&#34;experience&#34;&gt;Experience&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Period&lt;/th&gt;
          &lt;th&gt;Position&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;2024/01 - Present&lt;/td&gt;
          &lt;td&gt;Site Reliability Engineer @ Wantedly, Inc.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;2021/01 - 2023/12&lt;/td&gt;
          &lt;td&gt;Database Engineer @ NTT DATA, Inc.&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;education&#34;&gt;Education&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Period&lt;/th&gt;
          &lt;th&gt;Degree&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;2020/08 - 2022/12&lt;/td&gt;
          &lt;td&gt;MSc in Computer Science @ Georgia Institute of Technology&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;2016/09 - 2020/06&lt;/td&gt;
          &lt;td&gt;BSc in Physics @ Queen&amp;rsquo;s University&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;talks&#34;&gt;Talks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://speakerdeck.com/kkato1&#34;&gt;Speaker Deck&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;contributions&#34;&gt;Contributions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://git.postgresql.org/gitweb/?p=postgresql.git&amp;amp;a=search&amp;amp;h=HEAD&amp;amp;st=commit&amp;amp;s=Ken+Kato&#34;&gt;postgresql.git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/pgsql-jp/jpug-doc/pulls?q=is%3Apr+author%3Akkato+&#34;&gt;pgsql-jp/jpug-doc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/prometheus/docs/pulls?q=is%3Apr+author%3Akkato+&#34;&gt;prometheus/docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
  </channel>
</rss>
