<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Charmed Kubernetes &#8211; SRA OSS Tech Blog</title>
	<atom:link href="https://www.sraoss.co.jp/tech-blog/tag/charmed-kubernetes/feed/index.xml" rel="self" type="application/rss+xml" />
	<link>https://www.sraoss.co.jp/tech-blog/</link>
	<description>OSS専門の技術ブログ。PostgreSQL、Zabbixを中心に10種類以上のOSSの解説、アップデート情報、運用ヒントを提供。</description>
	<lastBuildDate>Fri, 30 Oct 2026 08:23:18 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2018/07/blog-icon-150x150.png</url>
	<title>Charmed Kubernetes &#8211; SRA OSS Tech Blog</title>
	<link>https://www.sraoss.co.jp/tech-blog/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Charmed Kubernetes の永続ストレージ</title>
		<link>https://www.sraoss.co.jp/tech-blog/kubernetes/charmed-kubernetes-persistent-volume/</link>
		
		<dc:creator><![CDATA[彭 博 (Bo Peng)]]></dc:creator>
		<pubDate>Mon, 14 Mar 2022 04:00:50 +0000</pubDate>
				<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Canonical]]></category>
		<category><![CDATA[Charmed Kubernetes]]></category>
		<category><![CDATA[Persistent Volume]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=9008</guid>

					<description><![CDATA[前回の記事では、Canonical Kubernetes ディストリビューション Charmed Kubernetes の特長、構築方法などを紹介しました。 Kubernetes を用いて簡単にコンテナとしてアプリケーシ ...]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.sraoss.co.jp/tech-blog/kubernetes/charmed-kubernetes-intro">前回</a>の記事では、Canonical Kubernetes ディストリビューション Charmed Kubernetes の特長、構築方法などを紹介しました。</p>
<p>Kubernetes を用いて簡単にコンテナとしてアプリケーションをデプロイ・削除をできるのがメリットですが、コンテナを削除するとコンテナ内のデータも削除されてしまいます。そのため、データベースのようなステートフルアプリケーションを利用する場合には、データの永続化が必要となります。</p>
<p><span id="more-9008"></span>今回は Charmed Kubernetes の永続ストレージ機能を紹介し、Charmed Kubernetes 上でのステートフルアプリケーションの構築について紹介します。</p>
<h2>Kubernetes の永続ストレージ</h2>
<p>Kubernetes の Podを削除すると Pod 内に保存されていたデータも一緒に削除されてしまいますので、データの永続化はできません。Kubernetes ノード上の領域を Pod にマウントすることで、Pod を削除した後もデータはノードに残るため、データの永続化は可能ですが、Pod が別ノードに再スケジュールされた場合にはデータの再利用ができないというデメリットがあります。</p>
<p>Kubernetes ノードとは別に外部ストレージを利用することで、Pod が削除されてもデータは外部ストレージに存在するため、データの永続化が可能です。また、外部ストレージはノードとは独立して存在しており、Pod が別のノードで再起動したとしてもデータが外部に存在するため、データの再利用が可能です。</p>
<p>Kubernetes でデータ永続化を実現するために、以下のリソースを利用します。</p>
<ul>
<li>PersistentVolume (PV)</li>
<li>PersistentVolumeClaim (PVC)</li>
<li>StorageClass</li>
</ul>
<p>事前に永続ボリューム (PersistentVolume) リソースを Kubernetes 上に作成しておき、Pod デプロイ時に PersistentVolumeClaim によって PersistentVolume が要求されると、Kubernetes は事前に作成しておいた PersistentVolume から要求に適したものを Pod に割り当てます。このような方法では、予め PersistentVolume を作成する手間がかかり、また、PersistentVolumeClaim の要求以上の容量の PersistentVolume が割り当てられてしまうという問題があります。</p>
<p>これに対して、PersistentVolume を動的に作成する仕組み Dynamic Provisioning を利用することができます。Dynamic Provisioning は StorageClass を利用し、PersistentVolumeClaim によって PersistentVolume が要求されたタイミングで PersistentVolume を動的に作成し、Pod に割り当てます。Dynamic Provisioning を利用することで、事前に PersistentVolume を作成する手間が省けます。また、PersistentVolumeClaim の要求よりも大きい容量の PersistentVolume が作成されることも回避できます。</p>
<p>本稿では Charmed Kubernetes 上で Dynamic Provisioning を利用したデータ永続化のソリューションを紹介します。</p>
<h2>Charmed Kubernetes の永続ストレージ</h2>
<p>Charmed Kubernetes で以下の方法を用いてデータの永続化を実現することができます。</p>
<h3>クラウドのストレージソリューション</h3>
<p>Charmed Kubernetes のクラウド基盤統合機能を利用すると、クラウドベンダーによって提供されているストレージソリューションをすぐに使用できます。</p>
<p>例えば、OpenStack 統合機能を有効にして Charmed Kubernetes をデプロイすると、cdk-cinder という名前の StorageClass が自動的に作成されます。</p>
<h3>Ceph</h3>
<p>Ceph Charm を用いてデプロイした Ceph クラスタを外部ストレージとして使用し、PersistentVolume を作成します。</p>
<h3>NFS</h3>
<p>NFS Charm を用いてデプロイした NFS サーバを外部ストレージとして使用し、PersistentVolume を作成します。</p>
<p>ベアメタルにデプロイされた Kubernetes では、クラウドの機能を利用できないため、Ceph や NFS を利用することになります。本稿では、Juju を用いて Charmed Kubernetes 上に Ceph を構築し、ステートフルアプリケーションのデータの永続化を実現する方法を紹介します。</p>
<h2>前提条件</h2>
<p>Charmed Kubernetes のデプロイが既に完了していることが前提となっています。今回は AWS 上にデプロイした Charmed Kubernetes を利用します。(デプロイ方法は<a href="https://www.sraoss.co.jp/tech-blog/kubernetes/charmed-kubernetes-intro">こちら</a>を参照)</p>
<h2>Ceph ストレージの構築</h2>
<p>Ceph はオープンソースの分散ストレージソフトウェアです。</p>
<p>Kubernetes の永続ストレージに Ceph を利用すると、拡張可能な高可用ストレージを実現することができます。本節では、Juju を用いた Ceph ストレージの構築方法を説明します。</p>
<p>デプロイ済みの Charmed Kubernetes クラスタにアクセスし、ノード状態を確認します。まだデプロイしていない場合は、<a href="https://www.sraoss.co.jp/tech-blog/kubernetes/charmed-kubernetes-intro">こちら</a>のデプロイ手順を参照してください。</p>
<pre>$ kubectl get node
NAME               STATUS   ROLES    AGE     VERSION
ip-172-31-54-236   Ready    &lt;none&gt;   9m48s   v1.23.4
ip-172-31-7-84     Ready    &lt;none&gt;   9m43s   v1.23.4
ip-172-31-90-192   Ready    &lt;none&gt;   9m43s   v1.23.4</pre>
<p>セキュリティの観点から、モデルを分けることをお勧めしますが、本稿は Charmed Kubernetes 上で Ceph による Dynamic Provisioning を検証することが目的なので、Kubernetes と Ceph を同一 モデルにデプロイします。</p>
<p>Charmed Kubernetes がデプロイされているモデルに切り替えます。</p>
<pre>$ juju switch k8s</pre>
<p>Ceph Monitor ノードをデプロイします。</p>
<p>Ceph Monitor はクラスタの管理、状態監視を行うコンポーネントです。高可用性を実現するために、3台以上の奇数台が必要です。ここでは、3台の Ceph Monitor ノードをデプロイします。</p>
<pre>$ juju deploy -n 3 ceph-mon</pre>
<p>Ceph OSD ノードをデプロイします。</p>
<p>Ceph OSD はデータの保存、データの冗長化などを行うコンポーネントです。<br />
Juju の <a href="https://charmhub.io/ceph-osd">ceph-osd</a> Charm では、<code>--storage</code> オプションに2種類のストレージを設定できます。</p>
<ul>
<li><code>osd-devices</code>: データを格納するストレージ</li>
<li><code>osd-journals</code>: ジャーナルを格納するストレージ</li>
</ul>
<p><code>--storage</code> オプションは <code>&lt;storage pool&gt;,&lt;size&gt;,&lt;number&gt;</code> 形式で指定します。</p>
<ul>
<li><code>storage pool</code>: ストレージプールを指定します。ストレージプールはクラウド基盤に依存します。指定しない場合は、クラウド基盤のデフォルトのストレージプールを使用します。AWS のデフォルトのストレージプールは ebs となります。</li>
<li><code>size</code>: 各ボリュームのサイズを指定します。</li>
<li><code>number</code>: ボリュームの数を指定します。</li>
</ul>
<p>ここでは、3台の Ceph OSD ノードをデプロイします。各 OSD ノードに2つのデータ用のボリューム（50GB）と1つのジャーナル用のボリューム（10GB）を作成します。</p>
<pre>$ juju deploy -n 3 ceph-osd --storage osd-devices=50G,2 --storage osd-journals=10G,1</pre>
<p>Ceph Monitor と Ceph OSD の関連付けを行います。</p>
<pre>$ juju add-relation ceph-osd ceph-mon</pre>
<p>RBD で作成した PersistentVolume のアクセスモードが ReadWriteOnce となりますので、アクセスモード ReadWriteMany の PersistentVolume を利用する場合には、CephFS をデプロイする必要があります。利用する場合には、以下のコマンドを実行し、CephFS のデプロイおよび関連付けの設定を行います。</p>
<pre>$ juju deploy -n 1 ceph-fs
$ juju add-relation ceph-fs ceph-mon</pre>
<p>Charmed Kubernetes で Ceph ストレージを利用するために、関連付けの設定を行います。</p>
<pre>$ juju add-relation ceph-mon:admin kubernetes-master
$ juju add-relation ceph-mon:client kubernetes-master</pre>
<p>Charmed Kubernetes と Ceph の関連付けの設定が完了したら、<code>kubectl get sc</code> を実行し、StorageClass が表示されていることを確認します。<br />
※cephfs ストレージクラスは、ceph-fs をデプロイした場合にのみ表示されます。</p>
<pre>$ kubectl get sc
NAME                PROVISIONER         RECLAIMPOLICY   VOLUMEBINDINGMODE  ALLOWVOLUMEEXPANSION  AGE
ceph-ext4           rbd.csi.ceph.com    Delete          Immediate          true                  2m39s
ceph-xfs (default)  rbd.csi.ceph.com    Delete          Immediate          true                  2m39s
cephfs              cephfs.csi.ceph.com Delete          Immediate          true                  2m39s</pre>
<p>Pod の状態を確認します。<br />
※cephfs の Pod は、ceph-fs をデプロイした場合にのみ表示されます。</p>
<pre>$ kubectl get pod
NAME                                            READY   STATUS    RESTARTS   AGE
csi-cephfsplugin-927cv                          3/3     Running   0          18s
csi-cephfsplugin-b6q66                          3/3     Running   0          22s
csi-cephfsplugin-provisioner-6f7ffd894d-b2sh4   6/6     Running   0          101s
csi-cephfsplugin-provisioner-6f7ffd894d-d5b9x   6/6     Running   0          101s
csi-cephfsplugin-provisioner-6f7ffd894d-kqvxn   6/6     Running   0          101s
csi-cephfsplugin-vqgtb                          3/3     Running   0          15s
csi-rbdplugin-fsh7g                             3/3     Running   0          15s
csi-rbdplugin-nt2lq                             3/3     Running   0          22s
csi-rbdplugin-provisioner-7dffff7f4d-8l8l5      7/7     Running   0          101s
csi-rbdplugin-provisioner-7dffff7f4d-wmvct      7/7     Running   0          101s
csi-rbdplugin-provisioner-7dffff7f4d-z7nm9      7/7     Running   0          101s
csi-rbdplugin-ts8rw                             3/3     Running   0          19s</pre>
<p>これで Ceph クラスタを Charmed Kubernetes の外部ストレージとして使用し Dynamic Provisioning を実現するための準備が完了です。</p>
<h3>スケールアウト</h3>
<p>Ceph のスケールアウトとは、新しいノードまたはデバイスを追加することによって利用可能な容量を拡張することです。本節では Ceph のスケールアウト手順について説明します。</p>
<p>Ceph ストレージの容量を拡張するには、Ceph OSD ノードを追加するか、既存の Ceph OSD ノードにストレージを追加します。</p>
<p>まず、既存のストレージの割り当てを確認します。</p>
<pre>$ juju storage
Unit        Storage id      Type   Pool  Size   Status    Message
ceph-osd/0  osd-devices/0   block  ebs   50GiB  attached  
ceph-osd/0  osd-devices/1   block  ebs   50GiB  attached  
ceph-osd/0  osd-journals/2  block  ebs   10GiB  attached  
ceph-osd/1  osd-devices/3   block  ebs   50GiB  attached  
ceph-osd/1  osd-devices/4   block  ebs   50GiB  attached  
ceph-osd/1  osd-journals/5  block  ebs   10GiB  attached  
ceph-osd/2  osd-devices/6   block  ebs   50GiB  attached  
ceph-osd/2  osd-devices/7   block  ebs   50GiB  attached  
ceph-osd/2  osd-journals/8  block  ebs   10GiB  attached</pre>
<p>新しい Ceph OSD ノードを追加します。</p>
<pre>$ juju add-unit ceph-osd -n 1</pre>
<p>新しいノード ceph-osd/3 が追加されていることを確認します。</p>
<pre>$ juju storage
Unit        Storage id       Type   Pool  Size   Status    Message
ceph-osd/0  osd-devices/0    block  ebs   50GiB  attached  
ceph-osd/0  osd-devices/1    block  ebs   50GiB  attached  
ceph-osd/0  osd-journals/2   block  ebs   10GiB  attached  
ceph-osd/1  osd-devices/3    block  ebs   50GiB  attached  
ceph-osd/1  osd-devices/4    block  ebs   50GiB  attached  
ceph-osd/1  osd-journals/5   block  ebs   10GiB  attached  
ceph-osd/2  osd-devices/6    block  ebs   50GiB  attached  
ceph-osd/2  osd-devices/7    block  ebs   50GiB  attached  
ceph-osd/2  osd-journals/8   block  ebs   10GiB  attached  
<strong>ceph-osd/3  osd-devices/10   block  ebs   50GiB  attached  
ceph-osd/3  osd-devices/9    block  ebs   50GiB  attached  
ceph-osd/3  osd-journals/11  block  ebs   10GiB  attached</strong>

$ juju status ceph-osd
Model  Controller      Cloud/Region   Version  SLA          Timestamp
k8s    k8s-controller  aws/us-east-1  2.9.22   unsupported  15:39:18+09:00

App       Version  Status  Scale  Charm     Store     Channel  Rev  OS      Message
ceph-osd  15.2.14  active      4  ceph-osd  charmhub  stable   513  ubuntu  Unit is ready (2 OSD)

Unit         Workload  Agent  Machine  Public address  Ports  Message
ceph-osd/0*  active    idle   13       3.83.100.242           Unit is ready (2 OSD)
ceph-osd/1   active    idle   14       3.238.52.73            Unit is ready (2 OSD)
ceph-osd/2   active    idle   15       3.235.171.220          Unit is ready (2 OSD)
<strong>ceph-osd/3   active    idle   17       54.82.234.9            Unit is ready (2 OSD)</strong>

Machine  State    DNS            Inst id              Series  AZ          Message
13       started  3.83.100.242   i-074dcc388f5b35c1b  focal   us-east-1d  running
14       started  3.238.52.73    i-0b2d721800fd923d6  focal   us-east-1c  running
15       started  3.235.171.220  i-0e9916138314d204b  focal   us-east-1f  running
<strong>17       started  54.82.234.9    i-0cf8cad9824868068  focal   us-east-1a  running</strong></pre>
<p>既存の Ceph OSD ノードにストレージを追加するために、<code>juju add-storage</code> コマンドを実行します。以下のコマンドを実行し、ceph-osd/0 ノードに 50GB の新しいボリュームを追加します。</p>
<pre>$ juju add-storage ceph-osd/0 osd-devices=50G,1</pre>
<p>ceph-osd/0 ノードに 50GB のボリュームが追加されていることを確認します。</p>
<pre>$ juju storage
Unit        Storage id       Type   Pool  Size   Status    Message
ceph-osd/0  osd-devices/0    block  ebs   50GiB  attached  
ceph-osd/0  osd-devices/1    block  ebs   50GiB  attached  
<strong>ceph-osd/0  osd-devices/12   block  ebs   50GiB  attached</strong>  
ceph-osd/0  osd-journals/2   block  ebs   10GiB  attached  
ceph-osd/1  osd-devices/3    block  ebs   50GiB  attached  
ceph-osd/1  osd-devices/4    block  ebs   50GiB  attached  
ceph-osd/1  osd-journals/5   block  ebs   10GiB  attached  
ceph-osd/2  osd-devices/6    block  ebs   50GiB  attached  
ceph-osd/2  osd-devices/7    block  ebs   50GiB  attached  
ceph-osd/2  osd-journals/8   block  ebs   10GiB  attached  
ceph-osd/3  osd-devices/10   block  ebs   50GiB  attached  
ceph-osd/3  osd-devices/9    block  ebs   50GiB  attached  
ceph-osd/3  osd-journals/11  block  ebs   10GiB  attached</pre>
<h2>アプリケーションをデプロイしてみる</h2>
<p>Charmed Kubernetes の永続ストレージの動的プロビジョニング機能を検証するために、ステートフルアプリケーションをデプロイしてみます。</p>
<p>本稿では、ステートフルアプリケーションとして PostgreSQL を扱います。</p>
<p>Kubernetes 上で PostgreSQL を動かすために、PostgreSQL Operator が必要になります。PostgreSQL Operator は PostgreSQL のデプロイや管理を自動化するためのソフトウェアです。</p>
<p>今回は検証目的で Charmed Kubernetes 環境向けに開発された <a href="https://charmhub.io/postgresql-k8s">PostgreSQL Charm</a>を利用して PostgreSQL を構築します。現時点では、PostgreSQL  Charm はスケーリングとフェイルオーバにのみ対応しており、バックアップやリストア・PITR などの管理は手動で行う必要があるため、本番環境での利用はお勧めしません。</p>
<p>本番環境で PostgreSQL をデプロイする場合は、以前の記事で紹介した <a href="https://www.sraoss.co.jp/tech-blog/pgsql/crunchy-postgresql-operator/">Crunchy PostgreSQL Operator</a> または <a href="https://www.sraoss.co.jp/tech-blog/pgsql/zalando-postgres-operator/">Zalando PostgreSQL Operator</a> を利用すると良いと思います。</p>
<p>Charmed Kubernetes  上に Juju チャームをデプロイするために、デプロイ済みの Charmed Kubernetes を Juju に登録する必要があります。</p>
<p><code>juju add-k8s</code> コマンドを実行し、Charmed Kubernetes 環境を登録します。ここでは、my-k8s という名前で 登録します。</p>
<pre>$ juju add-k8s my-k8s</pre>
<p>pg-controller という名前でコントローラーをデプロイします。</p>
<pre>$ juju bootstrap my-k8s pg-controller</pre>
<p>PostgreSQL をデプロイするためのモデルを作成します。モデル名と同じ名前の Namespace が Kubernetes に作成され、PostgreSQL がこの Namespace にデプロイされます。</p>
<p>ここで pg-model という名前のモデルを作成します。</p>
<pre>$ juju add-model pg-model</pre>
<p>次に、PostgreSQL をデプロイします。</p>
<p>PostgreSQL Charm の &#8211;storage オプションに2種類のストレージを設定できます。</p>
<ul>
<li><code>pgdata</code>: データベースのデータを格納するストレージ</li>
<li><code>logs</code>: PostgreSQL のログを格納するストレージ</li>
</ul>
<pre>$ juju deploy postgresql-k8s -n 3 --storage pgdata=20G --storage logs=1G</pre>
<p>上記コマンドを実行すると、primary 1台、replica 2台 の PostgreSQL クラスタが作成されます。</p>
<pre>$ kubectl get pod -n pg-model
NAME                             READY   STATUS    RESTARTS   AGE
modeloperator-7896f7f67d-pwch5   1/1     Running   0          4m17s
postgresql-k8s-0                 1/1     Running   0          2m14s
postgresql-k8s-1                 1/1     Running   0          2m14s
postgresql-k8s-2                 1/1     Running   0          2m14s
postgresql-k8s-operator-0        1/1     Running   0          3m8s</pre>
<p>PersistentVolumeClaim (PVC) と PersistentVolume (PV) を確認してみましょう。<br />
PostgreSQL Charm の PVC によって PV が自動的に作成されていることを確認します。</p>
<pre>$ kubectl get pvc -n pg-model
NAME                               STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
logs-2c7ce802-postgresql-k8s-0     Bound    pvc-265cd94c-77ec-4862-b021-b9d199326ef6   1Gi        RWO            ceph-xfs       2m52s
logs-2c7ce802-postgresql-k8s-1     Bound    pvc-6f71aa9a-77fd-4de5-93a8-bcd4e88fe35d   1Gi        RWO            ceph-xfs       2m52s
logs-2c7ce802-postgresql-k8s-2     Bound    pvc-cbca4843-f12f-49e3-ae89-5436d9791819   1Gi        RWO            ceph-xfs       2m52s
pgdata-2c7ce802-postgresql-k8s-0   Bound    pvc-7b40a98c-6f00-4f64-8c0a-701ccc0515d3   20Gi       RWO            ceph-xfs       2m52s
pgdata-2c7ce802-postgresql-k8s-1   Bound    pvc-cd6415e2-2322-4b5f-89f2-640b8d65d515   20Gi       RWO            ceph-xfs       2m52s
pgdata-2c7ce802-postgresql-k8s-2   Bound    pvc-5eb9547b-e14a-42a3-9746-e012411121a7   20Gi       RWO            ceph-xfs       2m52s

$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                           STORAGECLASS   REASON   AGE
pvc-2572bd8d-286f-4ffd-89b6-e22a95a11873   20Gi       RWO            Delete           Bound    controller-pg-controller/storage-controller-0   ceph-xfs                6m30s
pvc-265cd94c-77ec-4862-b021-b9d199326ef6   1Gi        RWO            Delete           Bound    pg-model/logs-2c7ce802-postgresql-k8s-0         ceph-xfs                3m8s
pvc-5eb9547b-e14a-42a3-9746-e012411121a7   20Gi       RWO            Delete           Bound    pg-model/pgdata-2c7ce802-postgresql-k8s-2       ceph-xfs                3m6s
pvc-6f71aa9a-77fd-4de5-93a8-bcd4e88fe35d   1Gi        RWO            Delete           Bound    pg-model/logs-2c7ce802-postgresql-k8s-1         ceph-xfs                3m7s
pvc-7b40a98c-6f00-4f64-8c0a-701ccc0515d3   20Gi       RWO            Delete           Bound    pg-model/pgdata-2c7ce802-postgresql-k8s-0       ceph-xfs                3m8s
pvc-cbca4843-f12f-49e3-ae89-5436d9791819   1Gi        RWO            Delete           Bound    pg-model/logs-2c7ce802-postgresql-k8s-2         ceph-xfs                3m5s
pvc-cd6415e2-2322-4b5f-89f2-640b8d65d515   20Gi       RWO            Delete           Bound    pg-model/pgdata-2c7ce802-postgresql-k8s-1       ceph-xfs                3m7s</pre>
<p>Replica の数を減らして、データが残るか検証します。</p>
<pre>$ juju remove-unit postgresql-k8s --num-units 1</pre>
<p>Pod が削除されても PVC と PV が削除されないことを確認します。</p>
<pre>$ kubectl get pod -n pg-model
NAME                             READY   STATUS    RESTARTS   AGE
modeloperator-7896f7f67d-pwch5   1/1     Running   0          6m22s
postgresql-k8s-0                 1/1     Running   0          4m19s
postgresql-k8s-1                 1/1     Running   0          4m19s
postgresql-k8s-operator-0        1/1     Running   0          5m13s

$ kubectl get pvc -n pg-model
NAME                               STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
logs-2c7ce802-postgresql-k8s-0     Bound    pvc-265cd94c-77ec-4862-b021-b9d199326ef6   1Gi        RWO            ceph-xfs       4m37s
logs-2c7ce802-postgresql-k8s-1     Bound    pvc-6f71aa9a-77fd-4de5-93a8-bcd4e88fe35d   1Gi        RWO            ceph-xfs       4m37s
<strong>logs-2c7ce802-postgresql-k8s-2     Bound    pvc-cbca4843-f12f-49e3-ae89-5436d9791819   1Gi        RWO            ceph-xfs       4m37s</strong>
pgdata-2c7ce802-postgresql-k8s-0   Bound    pvc-7b40a98c-6f00-4f64-8c0a-701ccc0515d3   20Gi       RWO            ceph-xfs       4m37s
pgdata-2c7ce802-postgresql-k8s-1   Bound    pvc-cd6415e2-2322-4b5f-89f2-640b8d65d515   20Gi       RWO            ceph-xfs       4m37s
<strong>pgdata-2c7ce802-postgresql-k8s-2   Bound    pvc-5eb9547b-e14a-42a3-9746-e012411121a7   20Gi       RWO            ceph-xfs       4m37s</strong>

$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                           STORAGECLASS   REASON   AGE
pvc-2572bd8d-286f-4ffd-89b6-e22a95a11873   20Gi       RWO            Delete           Bound    controller-pg-controller/storage-controller-0   ceph-xfs                8m30s
pvc-265cd94c-77ec-4862-b021-b9d199326ef6   1Gi        RWO            Delete           Bound    pg-model/logs-2c7ce802-postgresql-k8s-0         ceph-xfs                5m8s
<strong>pvc-5eb9547b-e14a-42a3-9746-e012411121a7   20Gi       RWO            Delete           Bound    pg-model/pgdata-2c7ce802-postgresql-k8s-2       ceph-xfs                5m6s</strong>
pvc-6f71aa9a-77fd-4de5-93a8-bcd4e88fe35d   1Gi        RWO            Delete           Bound    pg-model/logs-2c7ce802-postgresql-k8s-1         ceph-xfs                5m7s
pvc-7b40a98c-6f00-4f64-8c0a-701ccc0515d3   20Gi       RWO            Delete           Bound    pg-model/pgdata-2c7ce802-postgresql-k8s-0       ceph-xfs                5m8s
<strong>pvc-cbca4843-f12f-49e3-ae89-5436d9791819   1Gi        RWO            Delete           Bound    pg-model/logs-2c7ce802-postgresql-k8s-2         ceph-xfs                5m5s</strong>
pvc-cd6415e2-2322-4b5f-89f2-640b8d65d515   20Gi       RWO            Delete           Bound    pg-model/pgdata-2c7ce802-postgresql-k8s-1       ceph-xfs                5m7s</pre>
<h2>おわりに</h2>
<p>2回に渡って Canonical Kubernetes ディストリビューション Charmed Kubernetes を紹介しました。</p>
<p>エンタープライズ向けの機能を備えた Charmed Kubernetes は幅広いプラットフォームに対応しており、特にオンプレミスやプライベートクラウドにおいても容易に Kubernetes の環境を構築・管理できるという点は Charmed Kubernetes ならではの強みと言えます。オンプレミスやプライベートクラウドでエンタープライズ向けの Kubernetes を構築したい場合、Charmed Kubernetes は有力な選択肢だと言えるでしょう。</p>
<div>
<a href="https://www.sraoss.co.jp/prod_serv/support/oss-pro-support/?utm_source=sraoss-techblog&utm_medium=referral&utm_campaign=under-article-oss" rel="noopener" style="color:initial;" target="_blank" class="no-ext"></p>
<div style="background-color:#DAEFF6; padding:20px; border-radius:8px; text-align:center;">
SRA OSSでは、各種OSS のサポートを提供しております。<br />
詳しくは<strong style="color:#2581c4;">弊社ホームページ</strong>をご覧ください。
</div>
<p></a>
</div>

]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Canonical Kubernetes ディストリビューション Charmed Kubernetes の紹介</title>
		<link>https://www.sraoss.co.jp/tech-blog/kubernetes/charmed-kubernetes-intro/</link>
		
		<dc:creator><![CDATA[彭 博 (Bo Peng)]]></dc:creator>
		<pubDate>Wed, 09 Mar 2022 05:00:03 +0000</pubDate>
				<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Canonical]]></category>
		<category><![CDATA[Charmed Kubernetes]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=8668</guid>

					<description><![CDATA[クラウドサービスは企業にとって今や欠かせないもののひとつとなっていますが、セキュリティやカスタマイズの自由度の観点から、プライベートクラウドやオンプレミスを選択する企業も増えています。しかし、オンプレミスやプライベートク ...]]></description>
										<content:encoded><![CDATA[<p>クラウドサービスは企業にとって今や欠かせないもののひとつとなっていますが、セキュリティやカスタマイズの自由度の観点から、プライベートクラウドやオンプレミスを選択する企業も増えています。しかし、オンプレミスやプライベートクラウドで Kubernetes 環境を構築し、エンタープライズレベルのセキュリティと信頼性で運用するのは簡単ではないです。</p>
<p><span id="more-8668"></span></p>
<p>Canonical 社が提供する <a href="https://ubuntu.com/kubernetes">Charmed Kubernetes</a> はパブリッククラウドからオンプレミスまで様々なプラットフォームに対応しており、サービスのデプロイツールである Juju を用いてオンプレミスやプライベートクラウドにおいても容易に Kubernetes の環境を構築・管理できます。</p>
<p>本記事では、 Charmed Kubernetes の特長、構築方法および主な機能について紹介します。</p>
<h2>Charmed Kubernetes とは</h2>
<p><a href="https://ubuntu.com/kubernetes">Charmed Kubernetes</a> は Linux ディストリビューション Ubuntu の開発元であるイギリスの Canonical 社が提供するエンタープライズ向けの Kubernetes ディストリビューションです。</p>
<p>パブリッククラウドからオンプレミスのプライベートクラウドや仮想化基盤、ベアメタルまで、幅広いプラットフォームに対応しており、高可用性、スケーリング、ダウンタイムなしのアップグレード、暗号化通信、永続ストレージなど、エンタープライズレベルのセキュリティと管理機能を備えています。</p>
<h2>Charmed Kubernetes の特長</h2>
<p>Charmed Kubernetes には次のような特長があります。</p>
<h3>クラウド基盤との統合</h3>
<p>Charmed Kubernetes は幅広いクラウド基盤と統合することができます。統合することによって、クラウドサービスのネイティブ機能を直接使用することもできます。例えば、AWSと統合することで、AWS が提供しているストレージサービス（EBS）やロードバランサーサービス（ELB）をデフォルトで利用可能です。</p>
<h3>アップストリーム Kubernetes の最新バージョン対応</h3>
<p>Charmed Kubernetes はアップストリーム Kubernetes と並行してリリースされているため、アップストリーム Kubernetes の最新バージョンへアップグレードすることができ、いち早く最新機能を活用することが可能です。</p>
<h3>幅広いプラットフォームに対応</h3>
<p>Charmed Kubernetes は幅広いプラットフォームに対応しています。現時点では以下のプラットフォームに対応しています。</p>
<ul>
<li>パブリッククラウド
<ul>
<li>Amazon AWS</li>
<li>Google GCE</li>
<li>Microsoft Azure</li>
<li>Oracle</li>
<li>Rackspace</li>
<li>Equinix Metal</li>
</ul>
</li>
<li>プライベートクラウド
<ul>
<li>OpenStack</li>
<li>VMware vSphere</li>
<li>MAAS</li>
</ul>
</li>
<li>ローカル
<ul>
<li>LXD</li>
</ul>
</li>
</ul>
<h3>可用性とセキュリティに優れたエンタープライズ向けの Kubernetes</h3>
<p>パブリッククラウドの場合は、クラウドベンダーが提供する機能によって、一部のデータセンターに障害が起きてもサービスが継続して利用できる構成となっています。一方、オンプレミスのプライベートクラウドの場合は、障害対策のためにサーバの冗長化やバックアップなどの措置が必要になります。</p>
<p>Charmed Kubernetes は高可用性機能を提供しており、一部のサーバに障害が起きても、Kubernetes クラスタが動作し続けます。また、Charmed Kubernetes のすべてのコンポーネントが TLS による暗号化通信を行うため、セキュアで堅牢な Kubernetes を実現できます。</p>
<h2>Juju とは</h2>
<p>Juju は Canonical 社が開発しているサービスをデプロイするための自動化ツールです。</p>
<p>Juju を用いて対応しているプラットフォーム上に複数の Ubuntu サーバの作成から、Kubernetes クラスタの構築まで、いくつかのコマンドを実行するだけで、簡単に行えます。</p>
<p>本記事では、Juju を用いて Charmed Kubernetes クラスタを構築し、以下の機能について動作確認を行います。</p>
<ul>
<li>スケーリング</li>
<li>アップグレード</li>
<li>モニタリング</li>
<li>永続ストレージ(<a href="https://www.sraoss.co.jp/tech-blog/kubernetes/charmed-kubernetes-persistent-volume">こちら</a>を参照)</li>
</ul>
<h3>検証環境およびバージョン情報</h3>
<p>Charmed Kubernetes は様々なプラットフォーム上に構築できますが、本記事では気軽に利用できるパブリッククラウド AWS を使って Charmed Kubernetes を構築します。各ソフトウェアは投稿時点での最新バージョンを利用しています。</p>
<p>環境およびバージョン情報は以下の通りです。</p>
<ul>
<li>Kubernetes 1.23</li>
<li>Juju 2.9.22</li>
<li>ローカルの作業環境: Ubuntu 20.04.3 LTS (Focal Fossa)</li>
</ul>
<p>Juju がクラウドにアクセスするために、認証情報の登録が必要になります。<br />
AWS の場合は、アクセスキーとシークレットキーが必要になりますので、事前に確認しておいてください。</p>
<h2>Charmed Kubernetesのデプロイ</h2>
<h3>Juju のインストール</h3>
<p>Juju をインストールします。</p>
<pre>$ sudo snap install juju --classic</pre>
<h3>kubectl のインストール</h3>
<p><code>kubectl</code> をインストールします。</p>
<pre>$ sudo snap install kubectl --classic</pre>
<h3>クレデンシャルの追加</h3>
<p>Juju に AWS にアクセスするためのクレデンシャルを登録します。</p>
<pre>$ juju add-credential aws
Select region [any region, credential is not region specific]: &lt;任意のリージョンを指定&gt;
Using auth-type "access-key".
Enter access-key: &lt;アクセスキー&gt;
Enter secret-key: &lt;シークレットアクセスキー&gt;
Credential "aws" added locally for cloud "aws".</pre>
<p>登録後、以下のコマンドを実行し、AWS が登録されていることを確認します。</p>
<pre>$ juju clouds
...
Clouds available on the client:
Cloud      Regions  Default    Type  Credentials  Source    Description
<strong>aws        22       us-east-1  ec2   1            public    Amazon Web Services</strong>
localhost  1        localhost  lxd   0            built-in  LXD Container Hypervisor</pre>
<h3>Juju コントローラーのデプロイ</h3>
<p>Juju コントローラーをデプロイします。</p>
<p>Juju コントローラーは、Juju を使ってデプロイされたサービスを管理するために使用されます。以下のコマンドを実行すると、us-east-1 リージョンの EC2 インスタンスに Juju コントローラーがデプロイされます。リージョンを指定したい場合には、<code>juju bootstrap aws/&lt;リージョン&gt; &lt;コントローラー名&gt;</code>を実行してください。</p>
<pre>$ juju bootstrap aws k8s-controller</pre>
<p>デフォルトでは、 「mem=4G cores=2 」の <span id="detailsInstanceType" class="">t2.medium</span> タイプの EC2 インスタンスが Juju コントローラーのマシンとして作成されます。CPU やメモリを変更したい場合は、デプロイ時に <code>--bootstrap-constraints</code> を指定することでインスタンスタイプを変更できます。</p>
<pre>$ juju bootstrap --bootstrap-constraints "mem=8G cores=4" aws k8s-controller</pre>
<h3>モデルの作成</h3>
<p>Juju モデルはアプリケーションやマシンがデプロイされるワークスペースです。コントローラーは複数のモデルを持つことができますが、モデルは単一のコントローラーにしか関連付けられません。各モデルは複数のマシン、サービスを持つことができます。</p>
<p>サービスをデプロイする際に、デフォルトでは default というモデルにデプロイされますが、サービスごとにモデルを作成することを推奨されているため、ここでは Kubernetes 専用のモデルを作成します。</p>
<pre>$ juju add-model k8s
</pre>
<p>モデルが作成されていることを確認します。</p>
<pre>$ juju status
Model  Controller      Cloud/Region   Version  SLA          Timestamp
k8s    k8s-controller  aws/us-east-1  2.9.22   unsupported  12:02:03+09:00

$ juju models
Controller: k8s-controller

Model       Cloud/Region   Type  Status     Machines  Cores  Access  Last connection
controller  aws/us-east-1  ec2   available         1      2  admin   just now
default     aws/us-east-1  ec2   available         0      -  admin   53 seconds ago
k8s*        aws/us-east-1  ec2   available         0      -  admin   14 seconds ago</pre>
<h3>Kubernetes のデプロイ</h3>
<p>準備ができましたので、早速 Kubernetes をデプロイしましょう。</p>
<p>Juju を利用してアプリケーションをデプロイするには、Charm または Bundle を使います。</p>
<p>Charm を利用することで任意のマシンにアプリケーションをデプロイできます。複数アプリケーションから構成されるサービスでは、アプリケーションデプロイ後、アプリケーション同士の関連付けを設定する必要があります。Bundle は YAML 形式で記述したスクリプトファイルで、マシンの作成から、アプリケーションのデプロイ、そして関連付けまでの一連の処理を自動的にセットアップしてくれるツールです。</p>
<p>今回は Charm から Kubernetes をデプロイします。また、AWS のストレージサービスなどを利用するために、<code>--overlay</code> を利用してクラウド統合機能を有効にします。<code>--overlay</code> については後述します。デフォルトでは最新版がインストールされます。バージョンを指定してインストールを行う場合は<span class="aCOpRe ljeAnf">後述する</span> Bundle を使用したインストールを参照してください。</p>
<pre>$ wget https://raw.githubusercontent.com/charmed-kubernetes/bundle/master/overlays/aws-overlay.yaml
$ juju deploy charmed-kubernetes --overlay aws-overlay.yaml --trust</pre>
<p>すべてのアプリケーションのデプロイが完了するまで、15分~20分程度かかります。すべてのアプリケーション（App） の「Status」が「active」になったらデプロイ完了です。</p>
<p><code>juju status</code> コマンドで状態を確認してみましょう。</p>
<p>App には Kubernetes の各コンポーネント、Machine には各インスタンスが表示されます。デフォルトでは 11台のマシン（インスタンス）が立ち上がり、マスタノード2台、ワーカーノード3台の Kubernetes クラスタが構成されます。</p>
<pre>$ juju status
Model  Controller      Cloud/Region   Version  SLA          Timestamp
k8s    k8s-controller  aws/us-east-1  2.9.22   unsupported  12:27:04+09:00

App                    Version   Status  Scale  Charm                  Store       Channel   Rev  OS      Message
aws-integrator         1.15.58   active      1  aws-integrator         charmstore  stable    174  ubuntu  Ready
containerd             go1.13.8  active      5  containerd             charmstore  stable    200  ubuntu  Container runtime available
easyrsa                3.0.1     active      1  easyrsa                charmstore  stable    441  ubuntu  Certificate Authority connected.
etcd                   3.4.5     active      3  etcd                   charmstore  stable    655  ubuntu  Healthy with 3 known peers
flannel                0.11.0    active      5  flannel                charmstore  stable    619  ubuntu  Flannel subnet 10.1.6.1/24
kubeapi-load-balancer  1.18.0    active      1  kubeapi-load-balancer  charmstore  stable    866  ubuntu  Loadbalancer ready.
kubernetes-master      1.23.4    active      2  kubernetes-master      charmstore  stable   1106  ubuntu  Kubernetes master running.
kubernetes-worker      1.23.4    active      3  kubernetes-worker      charmstore  stable    838  ubuntu  Kubernetes worker running.

Unit                      Workload  Agent  Machine  Public address  Ports             Message
aws-integrator/0*         active    idle   0        54.196.183.155                    Ready
easyrsa/0*                active    idle   1        34.232.80.105                     Certificate Authority connected.
etcd/0                    active    idle   2        54.204.103.118  2379/tcp          Healthy with 3 known peers
etcd/1                    active    idle   3        3.236.214.69    2379/tcp          Healthy with 3 known peers
etcd/2*                   active    idle   4        44.198.164.226  2379/tcp          Healthy with 3 known peers
kubeapi-load-balancer/0*  active    idle   5        107.22.102.7    443/tcp,6443/tcp  Loadbalancer ready.
kubernetes-master/0*      active    idle   6        44.200.39.125   6443/tcp          Kubernetes master running.
  containerd/3            active    idle            44.200.39.125                     Container runtime available
  flannel/3               active    idle            44.200.39.125                     Flannel subnet 10.1.2.1/24
kubernetes-master/1       active    idle   7        3.83.124.151    6443/tcp          Kubernetes master running.
  containerd/0*           active    idle            3.83.124.151                      Container runtime available
  flannel/0               active    idle            3.83.124.151                      Flannel subnet 10.1.6.1/24
kubernetes-worker/0*      active    idle   8        54.160.123.197  80/tcp,443/tcp    Kubernetes worker running.
  containerd/1            active    idle            54.160.123.197                    Container runtime available
  flannel/1*              active    idle            54.160.123.197                    Flannel subnet 10.1.42.1/24
kubernetes-worker/1       active    idle   9        54.209.207.221  80/tcp,443/tcp    Kubernetes worker running.
  containerd/2            active    idle            54.209.207.221                    Container runtime available
  flannel/2               active    idle            54.209.207.221                    Flannel subnet 10.1.13.1/24
kubernetes-worker/2       active    idle   10       3.81.86.195     80/tcp,443/tcp    Kubernetes worker running.
  containerd/4            active    idle            3.81.86.195                       Container runtime available
  flannel/4               active    idle            3.81.86.195                       Flannel subnet 10.1.35.1/24

Machine  State    DNS             Inst id              Series  AZ          Message
0        started  54.196.183.155  i-02e9a6edcd5ac1cd5  focal   us-east-1a  running
1        started  34.232.80.105   i-05671fd8500a33119  focal   us-east-1f  running
2        started  54.204.103.118  i-0f28aea6be2d08e9d  focal   us-east-1d  running
3        started  3.236.214.69    i-0159b2e42b4b9c24e  focal   us-east-1f  running
4        started  44.198.164.226  i-0fd02e8e11ec1bfef  focal   us-east-1c  running
5        started  107.22.102.7    i-0bbd5a7a0ef45e4ef  focal   us-east-1b  running
6        started  44.200.39.125   i-05096429e51aeaa39  focal   us-east-1c  running
7        started  3.83.124.151    i-07c224c10603b0218  focal   us-east-1d  running
8        started  54.160.123.197  i-03a01a0e7b2bfe073  focal   us-east-1e  running
9        started  54.209.207.221  i-003d3e37b1a655e2e  focal   us-east-1a  running
10       started  3.81.86.195     i-001459c2be09d5db8  focal   us-east-1b  running</pre>
<h3>Charmed Kubernetes 設定のカスタマイズ</h3>
<p>Charmed Kubernetes の設定をカスタマイズする方法は2つあります。</p>
<ul>
<li>Bundle ファイルの使用</li>
<li>Overlay の使用</li>
</ul>
<h4>Bundle ファイルの使用</h4>
<p>Bundle ファイルは各種設定、デプロイの手順などを記載した YAML ファイルです。Bundle ファイルを必要に応じて編集することで、設定のカスタマイズが可能です。</p>
<p>特定の Kubernetes バージョンの Bundle ファイルは、<a href="https://ubuntu.com/kubernetes/docs/install-manual#table">こらち</a>からダウンロードできます。</p>
<p>一例として、v1.21 の Bundle ファイルをダウンロードし、ワーカーノードの数を変更してみます。</p>
<pre>$ wget https://api.jujucharms.com/charmstore/v5/charmed-kubernetes-733/archive/bundle.yaml
$ vi bundle.yaml
(ワーカーノードの数を3-&gt;4に変更)
...
kubernetes-worker:
annotations:
gui-x: '90'
gui-y: '850'
charm: cs:~containers/kubernetes-worker-838
constraints: cores=4 mem=4G root-disk=16G
expose: true
num_units: 4
...</pre>
<p>Bundle ファイルを用いてデプロイします。</p>
<pre>juju deploy ./bundle.yaml</pre>
<p><strong>Overlayの使用</strong></p>
<p><code>--overlay</code> オプションを利用することで、デフォルトの設定にマージ、またはデフォルトの設定を上書きすることができます。</p>
<p>例えば、Google Cloud 統合機能を利用する場合は、以下の設定を <code>--overla</code>y オプションに指定します。</p>
<pre>description: Charmed Kubernetes overlay to add native GCP support.
applications:
  gcp-integrator:
    annotations:
      gui-x: "600"
      gui-y: "300"
    charm: cs:~containers/gcp-integrator
    num_units: 1
    trust: true
relations:
  - ['gcp-integrator', 'kubernetes-master']
  - ['gcp-integrator', 'kubernetes-worker']</pre>
<p>各クラウドサービスむけの機能統合のYAMLファイルは<a href="https://ubuntu.com/kubernetes/docs/install-manual#cloud-integration">こちら</a>からダウンロードできます。</p>
<p>Google Cloud を利用する場合は、以下の手順を実行します。</p>
<pre>$ wget https://raw.githubusercontent.com/charmed-kubernetes/bundle/master/overlays/gcp-overlay.yaml
$ juju deploy charmed-kubernetes --overlay gcp-overlay.yaml --trust</pre>
<p>また、一部の設定を変更したい場合も、<code>--overlay</code> オプションが利用可能です。</p>
<p>例えば、ワーカーノードのデフォルトの制約は「constraints: cores=4 mem=4G root-disk=16G」となりますが、以下の設定を <code>--overlay</code> に設定することで、デフォルトの設定を上書きすることができます。</p>
<pre>$ cat myoverlay.yaml
applications:
  kubernetes-worker:
    constraints: cores=4 mem=8G root-disk=100G
    num_units: 3

$ juju deploy charmed-kubernetes --overlay myoverlay.yaml</pre>
<h3>Kubernetes クラスタへ接続</h3>
<p>Charmed Kubernetes のデプロイが完了したら、Kubernetes に接続してクラスタの状態を確認します。</p>
<p>まず、マスタノードから接続設定ファイルを取得します。</p>
<pre>$ mkdir -p .kube
$ juju scp kubernetes-master/0:config ~/.kube/config</pre>
<p>次に、馴染みのある <code>kubectl get</code> コマンドを実行し、ワーカーノードや Pod の状態を確認してみます。</p>
<pre>$ kubectl get nodes
NAME                            STATUS   ROLES    AGE   VERSION
ip-172-31-26-174.ec2.internal   Ready    &lt;none&gt;   21m   v1.23.4
ip-172-31-42-12.ec2.internal    Ready    &lt;none&gt;   19m   v1.23.4
ip-172-31-49-88.ec2.internal    Ready    &lt;none&gt;   22m   v1.23.4

$ kubectl get pods --all-namespaces
NAME                            STATUS   ROLES    AGE   VERSION
ip-172-31-26-174.ec2.internal   Ready    &lt;none&gt;   21m   v1.23.4
ip-172-31-42-12.ec2.internal    Ready    &lt;none&gt;   19m   v1.23.4
ip-172-31-49-88.ec2.internal    Ready    &lt;none&gt;   22m   v1.23.4

$ kubectl get pods --all-namespaces
NAMESPACE                         NAME                                                      READY   STATUS    RESTARTS   AGE
ingress-nginx-kubernetes-worker   default-http-backend-kubernetes-worker-6cd58d8886-nthsf   1/1     Running   0          21m
ingress-nginx-kubernetes-worker   nginx-ingress-controller-kubernetes-worker-mb75q          1/1     Running   0          21m
ingress-nginx-kubernetes-worker   nginx-ingress-controller-kubernetes-worker-vjp95          1/1     Running   0          19m
ingress-nginx-kubernetes-worker   nginx-ingress-controller-kubernetes-worker-wgbfj          1/1     Running   0          18m
kube-system                       coredns-5564855696-b2fcm                                  1/1     Running   0          25m
kube-system                       kube-state-metrics-5ccbcf64d5-5g49x                       1/1     Running   0          25m
kube-system                       metrics-server-v0.5.1-79b4746b65-bzhm5                    2/2     Running   0          25m
kubernetes-dashboard              dashboard-metrics-scraper-5cd54464bf-kc54z                1/1     Running   0          25m
kubernetes-dashboard              kubernetes-dashboard-55796c99c-r7v76                      1/1     Running   0          25m</pre>
<p>AWS 統合機能によって、デフォルトの StorageClass が自動的に作成されていることを確認します。</p>
<pre>$ kubectl get sc
NAME      PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
cdk-ebs   kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   false                  26m</pre>
<p>これで Kubernetes クラスタのデプロイは完了です。</p>
<h2>スケーリング</h2>
<p>Kubernetes クラスタのスケーリングとは、ワーカーノードを追加または削除することです。</p>
<p>Kubernetes クラスタにワーカーノードを追加することをクラスタのスケールアップ、クラスタからノードを削除することをクラスタのスケールダウンと言います。</p>
<p>Charmed Kubernetes では <code>juju add-unit/remove-unit</code> を実行することで、簡単にクラスタのスケールアップ/スケールダウンを行えます。</p>
<h3><strong>スケールアップ</strong></h3>
<p>新しいノードをクラスタに追加します。</p>
<pre>$ juju add-unit kubernetes-worker -n 1</pre>
<p>新しいワーカーノードが追加されていることを確認します。</p>
<pre>$ juju status
...
kubernetes-worker/0*      active    idle   8        54.160.123.197  80/tcp,443/tcp    Kubernetes worker running.
  containerd/1            active    idle            54.160.123.197                    Container runtime available
  flannel/1*              active    idle            54.160.123.197                    Flannel subnet 10.1.42.1/24
kubernetes-worker/1       active    idle   9        54.209.207.221  80/tcp,443/tcp    Kubernetes worker running.
  containerd/2            active    idle            54.209.207.221                    Container runtime available
  flannel/2               active    idle            54.209.207.221                    Flannel subnet 10.1.13.1/24
kubernetes-worker/2       active    idle   10       3.81.86.195     80/tcp,443/tcp    Kubernetes worker running.
  containerd/4            active    idle            3.81.86.195                       Container runtime available
  flannel/4               active    idle            3.81.86.195                       Flannel subnet 10.1.35.1/24
kubernetes-worker/3       active    idle   11       174.129.117.55  80/tcp,443/tcp    Kubernetes worker running.
  containerd/5            active    idle            174.129.117.55                    Container runtime available
  flannel/5               active    idle            174.129.117.55                    Flannel subnet 10.1.7.1/24


$ kubectl get node -o wide
NAME                            STATUS   ROLES    AGE   VERSION   INTERNAL-IP     EXTERNAL-IP      OS-IMAGE             KERNEL-VERSION    CONTAINER-RUNTIME
ip-172-31-26-174.ec2.internal   Ready       44m   v1.23.4   172.31.26.174   54.209.207.221   Ubuntu 20.04.4 LTS   5.11.0-1028-aws   containerd://1.5.5
ip-172-31-42-12.ec2.internal    Ready       42m   v1.23.4   172.31.42.12    3.81.86.195      Ubuntu 20.04.4 LTS   5.11.0-1028-aws   containerd://1.5.5
ip-172-31-49-88.ec2.internal    Ready       45m   v1.23.4   172.31.49.88    54.160.123.197   Ubuntu 20.04.4 LTS   5.11.0-1028-aws   containerd://1.5.5
ip-172-31-83-85.ec2.internal    Ready       13m   v1.23.4   172.31.83.85    174.129.117.55   Ubuntu 20.04.4 LTS   5.11.0-1028-aws   containerd://1.5.5</pre>
<h3><strong>スケールダウン</strong></h3>
<p>スケールダウンするときには、ノードを安全に停止・削除するために、その Node 上で実行中の Podを退去させてから、スケールダウンを行う必要があります。</p>
<p>検証用の Nginx の Pod をデプロイします。</p>
<pre>$ kubectl create deployment --image=nginx nginx</pre>
<p>Nginx の Pod がデプロイされているワーカーノードを確認します。「ip-172-31-83-85.ec2.internal」というノード（kubernetes-worker/3）にデプロイされています。今回は、kubernetes-worker/3 を削除してみます。</p>
<pre>$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP         NODE                           NOMINATED NODE   READINESS GATES
nginx-85b98978db-hsbvd   1/1     Running   0          2m41s   10.1.7.2   ip-172-31-83-85.ec2.internal</pre>
<p>ノードを安全に停止・削除するために、以下のコマンドを実行し、kubernetes-worker/3 上で動作中の Nginx の Pod を移動させ、新たに Pod がスケジュールされないようにします。</p>
<pre>$ juju run-action kubernetes-worker/3 pause --wait
unit-kubernetes-worker-3:
  UnitId: kubernetes-worker/3
  id: "2"
  results:
    Stderr: |
      WARNING: ignoring DaemonSet-managed Pods: ingress-nginx-kubernetes-worker/nginx-ingress-controller-kubernetes-worker-rwt52
  status: completed
  timing:
    completed: 2022-02-16 04:14:20 +0000 UTC
    enqueued: 2022-02-16 04:14:16 +0000 UTC
    started: 2022-02-16 04:14:17 +0000 UTC</pre>
<p>上記コマンドを実行すると、ノードが SchedulingDisabled になり、Pod が別のノード上で起動していることを確認できます。</p>
<pre>$ kubectl get node -o wide
NAME                            STATUS                     ROLES    AGE   VERSION   INTERNAL-IP     EXTERNAL-IP      OS-IMAGE             KERNEL-VERSION    CONTAINER-RUNTIME
ip-172-31-26-174.ec2.internal   Ready                         55m   v1.23.4   172.31.26.174   54.209.207.221   Ubuntu 20.04.4 LTS   5.11.0-1028-aws   containerd://1.5.5
ip-172-31-42-12.ec2.internal    Ready                         53m   v1.23.4   172.31.42.12    3.81.86.195      Ubuntu 20.04.4 LTS   5.11.0-1028-aws   containerd://1.5.5
ip-172-31-49-88.ec2.internal    Ready                         56m   v1.23.4   172.31.49.88    54.160.123.197   Ubuntu 20.04.4 LTS   5.11.0-1028-aws   containerd://1.5.5
ip-172-31-83-85.ec2.internal    Ready,SchedulingDisabled      24m   v1.23.4   172.31.83.85    174.129.117.55   Ubuntu 20.04.4 LTS   5.11.0-1028-aws   containerd://1.5.5

$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE    IP          NODE                           NOMINATED NODE   READINESS GATES
nginx-85b98978db-x9dzg   1/1     Running   0          2m5s   10.1.35.2   ip-172-31-42-12.ec2.internal</pre>
<p>これで、kubernetes-worker/3 ノードを安全に削除することができます。</p>
<pre>$ juju remove-unit kubernetes-worker/3</pre>
<p>しばらく経つと、kubernetes-worker/3 ノードが削除されていることを確認できます。</p>
<pre>$ juju status
...
kubernetes-worker/0*      active    idle   8        54.160.123.197  80/tcp,443/tcp    Kubernetes worker running.
  containerd/1            active    idle            54.160.123.197                    Container runtime available
  flannel/1*              active    idle            54.160.123.197                    Flannel subnet 10.1.42.1/24
kubernetes-worker/1       active    idle   9        54.209.207.221  80/tcp,443/tcp    Kubernetes worker running.
  containerd/2            active    idle            54.209.207.221                    Container runtime available
  flannel/2               active    idle            54.209.207.221                    Flannel subnet 10.1.13.1/24
kubernetes-worker/2       active    idle   10       3.81.86.195     80/tcp,443/tcp    Kubernetes worker running.
  containerd/4            active    idle            3.81.86.195                       Container runtime available
  flannel/4               active    idle            3.81.86.195                       Flannel subnet 10.1.35.1/24

$ kubectl get node -o wide
NAME                            STATUS   ROLES    AGE   VERSION   INTERNAL-IP     EXTERNAL-IP      OS-IMAGE             KERNEL-VERSION    CONTAINER-RUNTIME
ip-172-31-26-174.ec2.internal   Ready       68m   v1.23.4   172.31.26.174   54.209.207.221   Ubuntu 20.04.4 LTS   5.11.0-1028-aws   containerd://1.5.5
ip-172-31-42-12.ec2.internal    Ready       67m   v1.23.4   172.31.42.12    3.81.86.195      Ubuntu 20.04.4 LTS   5.11.0-1028-aws   containerd://1.5.5
ip-172-31-49-88.ec2.internal    Ready       69m   v1.23.4   172.31.49.88    54.160.123.197   Ubuntu 20.04.4 LTS   5.11.0-1028-aws   containerd://1.5.5
</pre>
<h2>アップグレード</h2>
<p>この節では、Charmed Kubernetes のマスタノードとワーカーノードのアップグレード方法を説明します。その他のコンポーネント containerd、easyrsa、etcd、flannel、kubeapi-load-balancer については、<a href="https://ubuntu.com/kubernetes/docs/upgrading">ドキュメント</a>を参照してください。</p>
<p>Charmed Kubernetes のワーカーノードをアップグレードするために、2つの方法があります。</p>
<ul>
<li><strong>Blue-green アップグレード</strong>: この方法では一時的により多くのリソースを利用しますが、一番安全でダウンタイムのないアップグレードを行えます。</li>
<li><strong>In-place アップグレード</strong>: この方法では既存のノードのアップグレードを行い、追加のリソースは必要ありませんが、サービスの停止が発生します。</li>
</ul>
<p>本番環境で利用する場合は、Blue-green アップグレードを推奨します。</p>
<p>ここでは、Blue-green アップグレードを利用したワーカーノードのアップグレードを検証してみます。</p>
<p>アップグレードする前に、Charmed Kubernetes が対応している Kubernetes の<a href="https://ubuntu.com/kubernetes/docs/supported-versions">バージョン情報</a>を確認します。今回は v1.21 の Charmed Kubernetes を v1.23 にアップグレードします。</p>
<p>検証用の Kubernetes クラスタをデプロイします。</p>
<pre>$ wget https://raw.githubusercontent.com/charmed-kubernetes/bundle/master/releases/1.21/bundle.yaml
$ juju deploy ./bundle.yaml</pre>
<p>マスタノードとワーカーノードのバージョンを確認します。</p>
<pre>$ juju status
...
App                    Version   Status       Scale  Charm                  Store       Channel   Rev  OS      Message
containerd             go1.13.8  active           5  containerd             charmstore  stable    146  ubuntu  Container runtime available
easyrsa                3.0.1     active           1  easyrsa                charmstore  stable    395  ubuntu  Certificate Authority connected.
etcd                   3.4.5     active           3  etcd                   charmstore  stable    607  ubuntu  Healthy with 1 known peer
flannel                0.11.0    active           3  flannel                charmstore  stable    571  ubuntu  Flannel subnet 10.1.78.1/24
kubeapi-load-balancer  1.18.0    active           1  kubeapi-load-balancer  charmstore  stable    814  ubuntu  Loadbalancer ready.
kubernetes-master      1.21.9    active           2  kubernetes-master      charmstore  stable   1034  ubuntu  Restarting snap.kube-proxy.daemon service
kubernetes-worker      1.21.9    active           3  kubernetes-worker      charmstore  stable    788  ubuntu  Waiting for kube-proxy to start.

$ juju scp kubernetes-master/0:config ~/.kube/config
$ kubectl get node
NAME               STATUS   ROLES    AGE    VERSION
ip-172-31-1-0      Ready    &lt;none&gt;   3m1s   v1.21.9
ip-172-31-44-16    Ready    &lt;none&gt;   3m9s   v1.21.9
ip-172-31-92-202   Ready    &lt;none&gt;   3m6s   v1.21.9</pre>
<p>まず、kubeapi-load-balancer をアップグレードします。</p>
<pre>$ juju upgrade-charm kubeapi-load-balancer</pre>
<p>次に、マスタノードをアップグレードします。以下のようにバージョンを指定して、upgrade を実行すると、マスタノードのアップグレードが始まります。</p>
<pre>$ juju upgrade-charm kubernetes-master
$ juju config kubernetes-master channel=1.23/stable

$ juju run-action kubernetes-master/0 upgrade
$ juju run-action kubernetes-master/1 upgrade</pre>
<p>最後に、ワーカーノードをアップグレードします。ワーカーノードのアップグレードを検証するために、アプリケーションをデプロイします。</p>
<pre>$ kubectl create deployment --image=nginx nginx
$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP          NODE              NOMINATED NODE   READINESS GATES
nginx-74d589986c-d8gqr   1/1     Running   0          6m51s   10.1.30.2   ip-172-31-30-80              
</pre>
<p>ワーカーノードのバージョンを設定します。</p>
<pre>$ juju upgrade-charm kubernetes-worker
$ juju config kubernetes-worker channel=1.23/stable</pre>
<pre>$ kubectl get node
NAME               STATUS   ROLES    AGE   VERSION
ip-172-31-14-158   Ready    &lt;none&gt;   25m   v1.21.9
ip-172-31-30-80    Ready    &lt;none&gt;   25m   v1.21.9
ip-172-31-64-109   Ready    &lt;none&gt;   23m   v1.21.9</pre>
<p>新たにワーカーノードを3つ追加します。新しく追加されるワーカーノードは新しいバージョンで作成されます。</p>
<pre>$ juju add-unit kubernetes-worker -n 3</pre>
<pre>$ kubectl get node
NAME               STATUS   ROLES    AGE     VERSION
ip-172-31-14-158   Ready    &lt;none&gt;   44m     v1.21.9
ip-172-31-30-80    Ready    &lt;none&gt;   44m     v1.21.9
ip-172-31-46-231   Ready    &lt;none&gt;   70s     v1.23.4
ip-172-31-46-47    Ready    &lt;none&gt;   4m58s   v1.23.4
ip-172-31-64-109   Ready    &lt;none&gt;   42m     v1.21.9
ip-172-31-81-150   Ready    &lt;none&gt;   2m13s   v1.23.4
</pre>
<p>旧バージョンのワーカーノードを一時停止します。</p>
<pre>$ juju run-action kubernetes-worker/0 pause
$ juju run-action kubernetes-worker/1 pause
$ juju run-action kubernetes-worker/2 pause</pre>
<p>すると、Nginx の Pod が新バージョンのワーカーノードに移動されます。</p>
<pre>$ kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP          NODE               NOMINATED NODE   READINESS GATES
nginx-deployment-74d589986c-d8gqr   1/1     Running   0          17m     10.1.30.2   ip-172-31-81-150              
</pre>
<p>これで、旧バージョンのワーカーノード安全に削除することができます。</p>
<pre>$ juju remove-unit kubernetes-worker/0
$ juju remove-unit kubernetes-worker/1
$ juju remove-unit kubernetes-worker/2

$ kubectl get node
NAME               STATUS   ROLES    AGE   VERSION
ip-172-31-46-231   Ready    &lt;none&gt;   22m   v1.23.4
ip-172-31-46-47    Ready    &lt;none&gt;   26m   v1.23.4
ip-172-31-81-150   Ready    &lt;none&gt;   24m   v1.23.4

$ juju status
App                    Version   Status  Scale  Charm                  Store       Channel  Rev   OS      Message
containerd             go1.13.8  active  4      containerd             charmstore  stable   200   ubuntu  Container runtime available
easyrsa                3.0.1     active  1      easyrsa                charmstore  stable   441   ubuntu  Certificate Authority connected.
etcd                   3.4.5     active  1      etcd                   charmstore  stable   655   ubuntu  Healthy with 1 known peer
flannel                0.11.0    active  4      flannel                charmstore  stable   619   ubuntu  Flannel subnet 10.1.66.1/24
kubeapi-load-balancer  1.18.0    active  1      kubeapi-load-balancer  charmstore  stable   866   ubuntu  Loadbalancer ready.
kubernetes-master      1.23.4    active  1      kubernetes-master      charmstore  stable   1106  ubuntu  Kubernetes master running.
kubernetes-worker      1.23.4    active  3      kubernetes-worker      charmstore  stable   838   ubuntu  Kubernetes worker running.</pre>
<h2>モニタリング</h2>
<p>Charmed Kubernetes では Prometheus によるモニタリング機能が利用可能です。</p>
<p>Kubernetes では Prometheus を利用した監視がよく使われています。Prometheus がクラスタの各種メトリクスを収集し、Grafana と連携して、Grafana のダッシュボードで Kubernetes クラスタとクラスタ上で動作するアプリケーションを監視することができます。</p>
<p>Prometheus によるモニタリング機能を利用するために、Bundleファイルをダウンロードし、デプロイ時に <code>--overlay</code> オプションに指定します。</p>
<pre>$ wget https://raw.githubusercontent.com/charmed-kubernetes/bundle/master/overlays/monitoring-pgt-overlay.yaml
$ juju deploy charmed-kubernetes --overlay monitoring-pgt-overlay.yaml</pre>
<p>prometheus、grafana、telegraf が起動していることを確認できます。</p>
<pre>$ juju status
Model  Controller      Cloud/Region   Version  SLA          Timestamp
k8s    k8s-controller  aws/us-east-1  2.9.22   unsupported  15:17:06+09:00

App                    Version   Status  Scale  Charm                  Store       Channel  Rev   OS      Message
containerd             go1.13.8  active  4      containerd             charmstore  stable   200   ubuntu  Container runtime available
easyrsa                3.0.1     active  1      easyrsa                charmstore  stable   441   ubuntu  Certificate Authority connected.
etcd                   3.4.5     active  1      etcd                   charmstore  stable   655   ubuntu  Healthy with 1 known peer
flannel                0.11.0    active  4      flannel                charmstore  stable   619   ubuntu  Flannel subnet 10.1.24.1/24
<strong>grafana                          active  1      grafana                charmhub    stable   51    ubuntu  Ready</strong>
kubeapi-load-balancer  1.18.0    active  1      kubeapi-load-balancer  charmstore  stable   866   ubuntu  Loadbalancer ready.
kubernetes-master      1.23.4    active  1      kubernetes-master      charmstore  stable   1106  ubuntu  Kubernetes master running.
kubernetes-worker      1.23.4    active  3      kubernetes-worker      charmstore  stable   838   ubuntu  Kubernetes worker running.
<strong>prometheus                       active  1      prometheus2            charmhub    stable   25    ubuntu  Ready</strong>
<strong>telegraf                         active  4      telegraf               charmhub    stable   44    ubuntu  Monitoring kubernetes-worker/1 (source version/commit 26e531a)</strong>
...</pre>
<p>以下のコマンドを実行し、Grafana の URL とログイン情報を取得します。</p>
<pre>$ juju run-action --wait grafana/0 get-login-info
unit-grafana-0:
  UnitId: grafana/0
  id: "4"
  results:
    password: 3cSfb2PshGHPLWJ4
    <strong>url: http://&lt;IP/ Address&gt;:3000/</strong>
    username: admin
  status: completed
...</pre>
<p>ブラウザから上記コマンドで確認した Grafana の URL に接続し、ログインします。Grafana のダッシュボードで Kubernetes クラスタ全体のリソースの使用状況などが確認できます。</p>
<p><img fetchpriority="high" decoding="async" class="alignnone size-large wp-image-9022" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/02/charmed-kubernetes-monitoring-1024x494.png" alt="" width="1024" height="494" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/02/charmed-kubernetes-monitoring-1024x494.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/02/charmed-kubernetes-monitoring-300x145.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/02/charmed-kubernetes-monitoring-768x371.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/02/charmed-kubernetes-monitoring-1536x742.png 1536w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/02/charmed-kubernetes-monitoring-304x147.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/02/charmed-kubernetes-monitoring-282x136.png 282w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/02/charmed-kubernetes-monitoring.png 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>
<h2>おわりに</h2>
<p>今回は Canonical Kubernetes ディストリビューション Charmed Kubernetes の特長、構築方法、スケーリング、アップグレード、モニタリング機能について紹介しましたが、いかがでしたでしょうか。</p>
<p>Juju というアプリケーションのデプロイツールを用いてオンプレミスでもコマンドを実行するだけで容易に Kubernetes 環境を構築できる Charmed Kubernetes は魅力的ではないでしょうか。</p>
<p><a href="https://www.sraoss.co.jp/tech-blog/kubernetes/charmed-kubernetes-persistent-volume">次回</a>はエンタープライズでの利用に欠かせない永続的ストレージについて説明します。</p>
<div>
<a href="https://www.sraoss.co.jp/prod_serv/support/oss-pro-support/?utm_source=sraoss-techblog&utm_medium=referral&utm_campaign=under-article-oss" rel="noopener" style="color:initial;" target="_blank" class="no-ext"></p>
<div style="background-color:#DAEFF6; padding:20px; border-radius:8px; text-align:center;">
SRA OSSでは、各種OSS のサポートを提供しております。<br />
詳しくは<strong style="color:#2581c4;">弊社ホームページ</strong>をご覧ください。
</div>
<p></a>
</div>

]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
