今まで自宅サーバーにはMicrok8sをインストールしてKubernetesクラスターを構築していましたが、今回はK3sをインストールしてみたので、そのメモ。
Synology CSI Driverを使いたかったのですが、Microk8sだとうまく動作しなかったので、実績のあるK3sを試してみました。
Controlplane(兼Worker)ノード1台(192.168.100.50)、Workerノード2台(192.168.100.51,192.168.100.52)の計3台構成でセットアップしました。
Controlplaneノードのセットアップ
まずはControlplaneノードにK3sをインストールします。192.168.11.50のサーバー上で
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.34.2+k3s1 \
K3S_TOKEN=CHANGEME \
sh -s - server \
--node-ip=192.168.100.50 \
--node-name=192.168.100.50 \
--advertise-address=192.168.100.50 \
--disable=traefik \
--disable=local-storage
状態を確認します。
$ sudo systemctl status k3s | cat
● k3s.service - Lightweight Kubernetes
Loaded: loaded (/etc/systemd/system/k3s.service; enabled; preset: enabled)
Active: active (running) since Thu 2025-11-27 14:05:52 UTC; 10s ago
Docs: https://k3s.io
Process: 1036001 ExecStartPre=/sbin/modprobe br_netfilter (code=exited, status=0/SUCCESS)
Process: 1036002 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
Main PID: 1036004 (k3s-server)
Tasks: 48
Memory: 540.8M (peak: 550.0M)
CPU: 15.836s
CGroup: /system.slice/k3s.service
├─1036004 "/usr/local/bin/k3s server"
├─1036025 "containerd "
├─1036367 /var/lib/rancher/k3s/data/96d729345c5cd40a1f306326c270ddd621a6acdf003606e91630f8c8147ba6ac/bin/containerd-shim-runc-v2 -namespace k8s.io -id ae731258755b088fe830f46096c8651229a363412a8ad972d4053c1fdc067761 -address /run/k3s/containerd/containerd.sock
└─1036373 /var/lib/rancher/k3s/data/96d729345c5cd40a1f306326c270ddd621a6acdf003606e91630f8c8147ba6ac/bin/containerd-shim-runc-v2 -namespace k8s.io -id 15269957327d39ec3f431b632afdc71ecee76e185ad672ab204501e37e59e632 -address /run/k3s/containerd/containerd.sock
Nov 27 14:05:59 apricot k3s[1036004]: time="2025-11-27T14:05:59Z" level=info msg="Started tunnel to 192.168.100.50:6443"
Nov 27 14:05:59 apricot k3s[1036004]: time="2025-11-27T14:05:59Z" level=info msg="Connecting to proxy" url="wss://192.168.100.50:6443/v1-k3s/connect"
Nov 27 14:05:59 apricot k3s[1036004]: time="2025-11-27T14:05:59Z" level=info msg="Stopped tunnel to 127.0.0.1:6443"
Nov 27 14:05:59 apricot k3s[1036004]: time="2025-11-27T14:05:59Z" level=info msg="Proxy done" err="context canceled" url="wss://127.0.0.1:6443/v1-k3s/connect"
Nov 27 14:05:59 apricot k3s[1036004]: time="2025-11-27T14:05:59Z" level=info msg="error in remotedialer server [400]: websocket: close 1006 (abnormal closure): unexpected EOF"
Nov 27 14:05:59 apricot k3s[1036004]: time="2025-11-27T14:05:59Z" level=info msg="Handling backend connection request [192.168.100.50]"
Nov 27 14:05:59 apricot k3s[1036004]: time="2025-11-27T14:05:59Z" level=info msg="Connected to proxy" url="wss://192.168.100.50:6443/v1-k3s/connect"
Nov 27 14:05:59 apricot k3s[1036004]: time="2025-11-27T14:05:59Z" level=info msg="Remotedialer connected to proxy" url="wss://192.168.100.50:6443/v1-k3s/connect"
Nov 27 14:06:02 apricot k3s[1036004]: I1127 14:06:02.892827 1036004 kuberuntime_manager.go:1828] "Updating runtime config through cri with podcidr" CIDR="10.42.0.0/24"
Nov 27 14:06:02 apricot k3s[1036004]: I1127 14:06:02.894417 1036004 kubelet_network.go:47] "Updating Pod CIDR" originalPodCIDR="" newPodCIDR="10.42.0.0/24"
kubeconfigをコピーします。
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
chmod 600 ~/.kube/config
NodeとPodの状態を確認します。
$ kubectl get node,pod -owide -A
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node/192.168.100.50 Ready control-plane 35s v1.34.2+k3s1 192.168.100.50 <none> Ubuntu 24.04.2 LTS 6.8.0-87-generic containerd://2.1.5-k3s1
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system pod/coredns-7f496c8d7d-q2qw6 1/1 Running 0 29s 10.42.0.3 192.168.100.50 <none> <none>
kube-system pod/metrics-server-7b9c9c4b9c-xwq2r 1/1 Running 0 29s 10.42.0.2 192.168.100.50 <none> <none>
Workerノードのセットアップ
Worker 1台目 (192.168.11.51)をセットアップします。192.168.11.51のサーバー上で次を実行します。
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.34.2+k3s1 \
K3S_URL=https://192.168.100.50:6443 \
K3S_TOKEN=CHANGEME \
sh -s - agent \
--node-ip=192.168.100.51 \
--node-name=192.168.100.51
Controlplane(192.168.11.50)のサーバー上でNodeとPodの状態を確認します。
$ kubectl get node,pod -owide -A
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node/192.168.100.50 Ready control-plane 85s v1.34.2+k3s1 192.168.100.50 <none> Ubuntu 24.04.2 LTS 6.8.0-87-generic containerd://2.1.5-k3s1
node/192.168.100.51 Ready <none> 8s v1.34.2+k3s1 192.168.100.51 <none> Ubuntu 24.04.2 LTS 6.8.0-87-generic containerd://2.1.5-k3s1
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system pod/coredns-7f496c8d7d-q2qw6 1/1 Running 0 79s 10.42.0.3 192.168.100.50 <none> <none>
kube-system pod/metrics-server-7b9c9c4b9c-xwq2r 1/1 Running 0 79s 10.42.0.2 192.168.100.50 <none> <none>
Worker 2台目 (192.168.11.52)をセットアップします。192.168.11.52のサーバー上で次を実行します。
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.34.2+k3s1 \
K3S_URL=https://192.168.100.50:6443 \
K3S_TOKEN=CHANGEME \
sh -s - agent \
--node-ip=192.168.100.52 \
--node-name=192.168.100.52
Controlplane(192.168.11.50)のサーバー上でNodeとPodの状態を確認します。
$ kubectl get node,pod -owide -A
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node/192.168.100.50 Ready control-plane 2m10s v1.34.2+k3s1 192.168.100.50 <none> Ubuntu 24.04.2 LTS 6.8.0-87-generic containerd://2.1.5-k3s1
node/192.168.100.51 Ready <none> 53s v1.34.2+k3s1 192.168.100.51 <none> Ubuntu 24.04.2 LTS 6.8.0-87-generic containerd://2.1.5-k3s1
node/192.168.100.52 Ready <none> 9s v1.34.2+k3s1 192.168.100.52 <none> Ubuntu 24.04.2 LTS 6.8.0-87-generic containerd://2.1.5-k3s1
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system pod/coredns-7f496c8d7d-q2qw6 1/1 Running 0 2m4s 10.42.0.3 192.168.100.50 <none> <none>
kube-system pod/metrics-server-7b9c9c4b9c-xwq2r 1/1 Running 0 2m4s 10.42.0.2 192.168.100.50 <none> <none>
Synology CSI Driverのインストール
次にSynology CSI Driverをインストールします。次のようにマニフェストを用意します。
git clone https://github.com/SynologyOpenSource/synology-csi.git -b v1.2.1
cd synology-csi
cp config/client-info-template.yml config/client-info.yml
vim config/client-info.yml
client-info.ymlにSynology NASの情報を設定します。
Storage Classの設定ファイルを編集します。
vim deploy/kubernetes/v1.20/storage-class.yml
次の設定にします。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: synology-iscsi-storage
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: csi.san.synology.com
parameters:
fsType: 'btrfs'
dsm: '192.168.100.200'
location: '/volume1'
formatOptions: '--nodiscard'
reclaimPolicy: Delete
allowVolumeExpansion: true
次のコマンドでSynology CSI Driverをインストールします。
./scripts/deploy.sh install --basic
次のような出力が得られます。
==== Creates namespace and secrets, then installs synology-csi ====
Current Server Version: v1.34.2+k3s1
Deploy Version: v1.20
namespace/synology-csi created
secret/client-info-secret created
serviceaccount/csi-controller-sa created
clusterrole.rbac.authorization.k8s.io/synology-csi-controller-role created
clusterrolebinding.rbac.authorization.k8s.io/synology-csi-controller-role created
statefulset.apps/synology-csi-controller created
csidriver.storage.k8s.io/csi.san.synology.com created
namespace/synology-csi unchanged
serviceaccount/csi-node-sa created
clusterrole.rbac.authorization.k8s.io/synology-csi-node-role created
clusterrolebinding.rbac.authorization.k8s.io/synology-csi-node-role created
daemonset.apps/synology-csi-node created
storageclass.storage.k8s.io/synology-iscsi-storage created
synology-csi NamespaceのPodの状態を確認します。
$ kubectl get pod -owide -n synology-csi
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
synology-csi-controller-0 4/4 Running 0 116s 192.168.100.52 192.168.100.52 <none> <none>
synology-csi-node-bhcpf 2/2 Running 0 115s 192.168.100.50 192.168.100.50 <none> <none>
synology-csi-node-p6mq8 2/2 Running 0 115s 192.168.100.52 192.168.100.52 <none> <none>
synology-csi-node-tz6hl 2/2 Running 0 115s 192.168.100.51 192.168.100.51 <none> <none>
Persistent Volumeの動作確認
次のPVCを作成して、動作を確認します。
cat <<EOF > /tmp/pvc.yaml
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-dynamic-volume-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: synology-iscsi-storage
---
EOF
kubectl apply -f /tmp/pvc.yaml
次のようにPVCがBound状態になれば成功です。
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
test-dynamic-volume-claim Bound pvc-6df54034-c251-4184-9d58-cf7b2fa1c039 1Gi RWO synology-iscsi-storage <unset> 7s
Synology NAS側のSAN ManagerでLUNとiSCSI Targetも作成されていることを確認できます。


このPVCをマウントするPodを作成し、読み書きの動作確認を行います。
cat <<EOF > /tmp/pvc-test-pod.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: pvc-test-pod
spec:
securityContext:
runAsUser: 1000
runAsGroup: 100
fsGroup: 100
containers:
- name: test-container
image: busybox:latest
command: ["/bin/sh"]
args:
- -c
- |
echo "=== PVC Read/Write Test Start ==="
echo "Mount point check:"
df -h /mnt/test
echo ""
echo "=== Write Test ==="
echo "Hello from PVC test - $(date)" >> /mnt/test/test-file.txt
echo "File write completed"
echo ""
echo "=== File Verification ==="
ls -lah /mnt/test/
echo ""
echo "=== Read Test ==="
cat /mnt/test/test-file.txt
echo ""
echo "=== Test Completed ==="
sleep infinity
volumeMounts:
- name: test-volume
mountPath: /mnt/test
volumes:
- name: test-volume
persistentVolumeClaim:
claimName: test-dynamic-volume-claim
restartPolicy: Never
---
EOF
kubectl apply -f /tmp/pvc-test-pod.yaml
次のようにPodがReadyになれば成功です。
$ kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pvc-test-pod 1/1 Running 0 24s 10.42.1.4 192.168.100.51 <none> <none>
ログを確認し、読み書きができていることを確認します。
$ kubectl logs pvc-test-pod
=== PVC Read/Write Test Start ===
Mount point check:
Filesystem Size Used Available Use% Mounted on
/dev/sdd 1.0G 5.8M 904.6M 1% /mnt/test
=== Write Test ===
File write completed
=== File Verification ===
total 24K
drwxrwsr-x 1 root users 26 Nov 27 14:22 .
drwxr-xr-x 3 root root 4.0K Nov 27 14:22 ..
-rw-r--r-- 1 1000 users 51 Nov 27 14:22 test-file.txt
=== Read Test ===
Hello from PVC test - Thu Nov 27 14:16:50 UTC 2025
=== Test Completed ===
次のコマンドでPodを再作成し、データが保持されていることを確認します。
kubectl delete pod pvc-test-pod --force
kubectl apply -f /tmp/pvc-test-pod.yaml
ログを確認し、ファイルに行が追記されていることを確認します。
$ kubectl logs pvc-test-pod
=== PVC Read/Write Test Start ===
Mount point check:
Filesystem Size Used Available Use% Mounted on
/dev/sdd 1.0G 5.8M 904.6M 1% /mnt/test
=== Write Test ===
File write completed
=== File Verification ===
total 24K
drwxrwsr-x 1 root users 26 Nov 27 14:22 .
drwxr-xr-x 3 root root 4.0K Nov 27 14:23 ..
-rw-rw-r-- 1 1000 users 102 Nov 27 14:23 test-file.txt
=== Read Test ===
Hello from PVC test - Thu Nov 27 14:16:50 UTC 2025
Hello from PVC test - Thu Nov 27 14:16:50 UTC 2025
=== Test Completed ===
次のコマンドでPodとPVCを削除します。
kubectl delete pod pvc-test-pod --force
kubectl delete pvc test-dynamic-volume-claim
SAN ManagerでLUNとiSCSI Targetも削除されていることを確認できます。
HelmでRedisをインストールして動作確認
次にHelmを使ってRedisをインストールし、動作確認を行います。
helm upgrade --install redis \
oci://registry-1.docker.io/bitnamicharts/redis \
-n redis \
--create-namespace --wait \
--set auth.enabled=false
次のようにPodとPVCが作成されていることを確認します。
$ kubectl get pod,pvc -owide -n redis
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/redis-master-0 1/1 Running 0 2m36s 10.42.1.11 192.168.100.51 <none> <none>
pod/redis-replicas-0 1/1 Running 0 2m36s 10.42.1.12 192.168.100.51 <none> <none>
pod/redis-replicas-1 1/1 Running 0 114s 10.42.2.5 192.168.100.52 <none> <none>
pod/redis-replicas-2 1/1 Running 0 72s 10.42.0.4 192.168.100.50 <none> <none>
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE VOLUMEMODE
persistentvolumeclaim/redis-data-redis-master-0 Bound pvc-5f7792b3-3c49-44d6-8167-0ebc4f4e66fb 8Gi RWO synology-iscsi-storage <unset> 2m36s Filesystem
persistentvolumeclaim/redis-data-redis-replicas-0 Bound pvc-ea541f4a-879a-4ccd-9654-49efc018d87d 8Gi RWO synology-iscsi-storage <unset> 2m36s Filesystem
persistentvolumeclaim/redis-data-redis-replicas-1 Bound pvc-80964ce4-bb0d-4d2d-8b19-881feb82a6ed 8Gi RWO synology-iscsi-storage <unset> 115s Filesystem
persistentvolumeclaim/redis-data-redis-replicas-2 Bound pvc-02e1e1dc-0646-447c-89d5-6f16215d27cf 8Gi RWO synology-iscsi-storage <unset> 72s Filesystem
次のコマンドでRedisマスターにポートフォワードし、redis-cliで接続して動作確認を行います。
kubectl port-forward --namespace redis svc/redis-master 6379:6379
次のようにRedisに接続して、データの読み書きができることを確認します。
$ redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> set foo 100
OK
127.0.0.1:6379> get foo
"100"
次のコマンドでRedisをアンインストールし、PVCも削除します。
helm uninstall -n redis redis --wait
kubectl delete pvc -n redis --all
kubectl delete ns redis
K3sにSynology CSI Driverをインストールして、Synology NASのiSCSI LUNをKubernetesのPersistent Volumeとして利用することができました。
K3sは軽量でセットアップも簡単なので、自宅サーバーでKubernetesクラスターを構築するのに便利です。