1. 概要
本記事は、学習用に構築しているRaspberry Piによるk8sクラスタ、いわゆる「おうちk8sクラスタ」の製作記の「Dockerレジストリ編」です。
k8sクラスタでDockerコンテナを起動する場合、ノードにDockerイメージを配布するために、Dockerイメージを格納した「Dockerレジストリ」が必要です。(話を簡単にするために、Docker前提で話を進めます)
今回は、Docker Inc.が提供しているDockerイメージ「registry」を使い、k8sのマスターノードにDockerレジストリを構築しました。
なお、今回のk8sクラスタは限定された環境下でのみアクセスされるため、Dockerレジストリの認証は行っていません。
認証が必要な場合はHarbor、Portusなどのソフトウェアを使ってDockerレジストリを構築するのが良いかと思います。
2. 環境
今回の環境は以下の通りです。詳しい環境、構築方法については別記事『Raspberry Pi 4に64ビット版UbuntuでKubernetes環境を構築する』をご参照ください。
- ハードウェア: Raspberry Pi 4 4GB 4台
- OS: Ubuntu Server 19.10 ARM64(AArch64)版
- ノード構成:
- マスターノード: 1台
- ワーカーノード: 3台
ubuntu@k8s-m1:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="19.10 (Eoan Ermine)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 19.10"
VERSION_ID="19.10"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=eoan
UBUNTU_CODENAME=eoan
ubuntu@k8s-m1:~$ uname -a
Linux ubuntu 5.3.0-1014-raspi2 #16-Ubuntu SMP Tue Nov 26 11:18:23 UTC 2019 aarch64 aarch64 aarch64 GNU/Linux
ubuntu@k8s-m1:~$ cat /proc/cpuinfo
...
Hardware : BCM2835
Revision : c03112
Serial : 10000000794dd63d
Model : Raspberry Pi 4 Model B Rev 1.2
ubuntu@k8s-m1:~$ cat /proc/meminfo
MemTotal: 3882408 kB
MemFree: 1965400 kB
MemAvailable: 3563220 kB
...
ubuntu@k8s-m1:~$ kubectl get nodes --output wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-m1 Ready master 26m v1.17.3 192.168.1.211 <none> Ubuntu 19.10 5.3.0-1017-raspi2 docker://19.3.6
k8s-n1 Ready <none> 17m v1.17.3 192.168.1.212 <none> Ubuntu 19.10 5.3.0-1017-raspi2 docker://19.3.6
k8s-n2 Ready <none> 2m44s v1.17.3 192.168.1.213 <none> Ubuntu 19.10 5.3.0-1017-raspi2 docker://19.3.6
k8s-n3 Ready <none> 2m39s v1.17.3 192.168.1.214 <none> Ubuntu 19.10 5.3.0-1017-raspi2 docker://19.3.6
ubuntu@k8s-m1:~$ kubectl get pods --all-namespaces --output wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system coredns-6955765f44-jz5pv 1/1 Running 0 26m 10.244.0.3 k8s-m1 <none> <none>
kube-system coredns-6955765f44-whxsx 1/1 Running 0 26m 10.244.0.2 k8s-m1 <none> <none>
kube-system etcd-k8s-m1 1/1 Running 0 26m 192.168.1.211 k8s-m1 <none> <none>
kube-system kube-apiserver-k8s-m1 1/1 Running 0 26m 192.168.1.211 k8s-m1 <none> <none>
kube-system kube-controller-manager-k8s-m1 1/1 Running 0 26m 192.168.1.211 k8s-m1 <none> <none>
kube-system kube-flannel-ds-arm64-58rgk 1/1 Running 0 21m 192.168.1.211 k8s-m1 <none> <none>
kube-system kube-flannel-ds-arm64-7gcj5 1/1 Running 0 17m 192.168.1.212 k8s-n1 <none> <none>
kube-system kube-flannel-ds-arm64-b4lc9 1/1 Running 0 3m4s 192.168.1.213 k8s-n2 <none> <none>
kube-system kube-flannel-ds-arm64-skgjw 1/1 Running 0 2m59s 192.168.1.214 k8s-n3 <none> <none>
kube-system kube-proxy-bh8c5 1/1 Running 0 2m59s 192.168.1.214 k8s-n3 <none> <none>
kube-system kube-proxy-shjkv 1/1 Running 0 17m 192.168.1.212 k8s-n1 <none> <none>
kube-system kube-proxy-tngmj 1/1 Running 0 26m 192.168.1.211 k8s-m1 <none> <none>
kube-system kube-proxy-ttx28 1/1 Running 0 3m4s 192.168.1.213 k8s-n2 <none> <none>
kube-system kube-scheduler-k8s-m1 1/1 Running 0 26m 192.168.1.211 k8s-m1 <none> <none>
3. 構築
今回利用するregistry
は単一のDockerイメージで構成されており、とても簡単にデプロイすることができます。今回は以下の設定でデプロイしました。
- Dockerレジストリはマスターノード
k8s-m1
に配置する。 - 永続化が必要なファイルは、マスターノードのストレージに格納する。
- Dockerイメージは
registry:2.7
を使用する。 - ホストネットワークを利用し、
5000/tcp
で待ち受けする。
使用した定義ファイルは以下の通りです。
apiVersion: apps/v1
kind: Deployment
metadata:
name: docker-registry
labels:
app: docker-registry
spec:
replicas: 1
selector:
matchLabels:
app: docker-registry
template:
metadata:
labels:
app: docker-registry
spec:
hostNetwork: true
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
nodeSelector:
kubernetes.io/hostname: k8s-m1
containers:
- name: docker-registry
image: registry:2.7
ports:
- containerPort: 5000
volumeMounts:
- name: registry
mountPath: /var/lib/registry
volumes:
- name: registry
hostPath:
type: Directory
path: /var/lib/registry
定義ファイルの適用、curl
による簡易的な動作確認の手順は以下の通りです。
ubuntu@k8s-m1:~$ kubectl apply -f docker-registry.yaml
ubuntu@k8s-m1:~$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
docker-registry-5c5cb844f-h7mzb 1/1 Running 0 4m34s 192.168.1.211 k8s-m1 <none> <none>
nginx-munin-7kvf8 1/1 Running 12 23d 10.244.3.14 k8s-n3 <none> <none>
nginx-munin-8f88x 1/1 Running 7 23d 10.244.1.9 k8s-n1 <none> <none>
nginx-munin-jw4jd 1/1 Running 5 23d 10.244.0.18 k8s-m1 <none> <none>
nginx-munin-m8flt 1/1 Running 5 23d 10.244.2.8 k8s-n2 <none> <none>
ubuntu@k8s-m1:~$ curl -v http://localhost:5000/
* Trying 127.0.0.1:5000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.65.3
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Cache-Control: no-cache
< Date: Mon, 09 Mar 2020 07:45:47 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact
4. 動作確認
Dockerデーモンは、デフォルトではTLS接続(暗号化あり)のDockerレジストリのみ使用できます。
今回構築したDockerレジストリは非TLS接続(暗号化なし)を用いるため、Dockerデーモンの設定を変更する必要があります。
具体的には、設定ファイル/etc/docker/daemon.json
のinsecure-registries
キーにホスト名、ポート番号を記載する必要があります。
設定ファイルを変更し、Dockerデーモンの再読み込み(再起動は不要)を行うことで、非TLS接続のDockerレジストリに接続できるようになります。なお、この設定はすべてのノードで行う必要があります。
ubuntu@k8s-m1:~$ sudo vim /etc/docker/daemon.json
ubuntu@k8s-m1:~$ cat /etc/docker/daemon.json
{
"insecure-registries": ["k8s-m1.local:5000"]
}
ubuntu@k8s-m1:~$ sudo systemctl reload docker
動作確認の第1ステップとして、マスターノード(k8s-m1
)にてDocker Hubからhello-worldイメージを取得(docker pull
)し、構築したDockerレジストリに転送(docker push
)してみました。
マスターノードの/var/lib/registry
以下に、転送されたDockerイメージが格納されているのが確認できます。
ubuntu@k8s-m1:~$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
256ab8fe8778: Pull complete
Digest: sha256:fc6a51919cfeb2e6763f62b6d9e8815acbf7cd2e476ea353743570610737b752
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest
ubuntu@k8s-m1:~$ docker tag hello-world k8s-m1.local:5000/hello-world
ubuntu@k8s-m1:~$ docker push k8s-m1.local:5000/hello-world
The push refers to repository [k8s-m1.local:5000/hello-world]
167d9097a0a0: Pushed
latest: digest: sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343 size: 525
ubuntu@k8s-m1:~$ ls -l /var/lib/registry/
total 4
drwxr-xr-x 3 root root 4096 Mar 9 16:53 docker
続いて、ワーカーノードの1つ(k8s-n1
)で、構築したDockerレジストリからDockerイメージを取得してみました。
ubuntu@k8s-n1:~$ sudo vim /etc/docker/daemon.json
ubuntu@k8s-n1:~$ sudo systemctl reload docker
ubuntu@k8s-n1:~$ docker pull k8s-m1.local:5000/hello-world
Using default tag: latest
latest: Pulling from hello-world
256ab8fe8778: Pull complete
Digest: sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343
Status: Downloaded newer image for k8s-m1.local:5000/hello-world:latest
k8s-m1.local:5000/hello-world:latest
docker push
、docker pull
ともに正常に動作することが確認できました。なお、認証は行っていないのでdocker login
は不要です。
以上、Dockerレジストリ編でした。
また余裕があれば、他の記事(電源編、ファン編、ケース編)なども書きたいと思います。