创建一个用于学习的Kubernetes环境,在Kubernetes上构建Kubernetes专用的私有Docker注册表Harbor环境,并使用Docker和containerd来使用HTTP协议的Docker注册表
首先
请注意:本次创建的环境是为初学者设计的学习用途。
绝对不能按照原来的步骤直接在正式环境或其他外部环境中公开。
此外,存在不安全的配置和违反最佳实践的操作部分。
创建Kubernetes环境的学习是第三部分。
Part 1 学習用Kubernetes環境を作る1 Ubuntu 20.04 LTS+kubeadm+containerd+CalicoなKubernetes環境をHyper-V上にTailscaleの固定IPで構築
Part 2 学習用Kubernetes環境を作る2 動的PVが使えない環境でKubernetes管理WebUIのPortainer環境を作る/データ永続化/NodePortについて
第三部分 创建用于学习的Kubernetes环境:在Kubernetes上构建适用于Kubernetes的私有Docker注册表Harbor环境,使用HTTP的Docker注册表并在Docker和containerd中使用它。
KubernetesでDockerコンテナを利用出来るようにローカルにプライベートDockerレジストリーを作成します.
Kubernetesの環境は,第1回,第2回で構築した環境を前提としています.
创建一个Harbor私有仓库的PV。
在使用Helm之前安装Harbor之前,需要创建Harbor使用的持久卷(PV)。
今回は,個人的に管理しやすいという都合上,全てのPVC毎にSCを作成します.
在创建PV之前,创建PV的实际存储位置。
cd /mnt/kubernetes
sudo mkdir harbor
cd harbor
sudo mkdir chartmuseum database jobservice redis registry trivy
chmod 777 chartmuseum database jobservice redis registry trivy
PVを作成するymlをharbor-vol.ymlという名前で作成します.
内容如下。
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: harbor-registry
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: harbor-registry-pv
spec:
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: harbor-registry
local:
path: /mnt/kubernetes/harbor/registry
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- ノード名
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: harbor-chartmuseum
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: harbor-chartmuseum-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: harbor-chartmuseum
local:
path: /mnt/kubernetes/harbor/chartmuseum
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- ノード名
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: harbor-jobservice
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: harbor-jobservice-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: harbor-jobservice
local:
path: /mnt/kubernetes/harbor/jobservice
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- ノード名
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: harbor-database
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: harbor-database-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: harbor-database
local:
path: /mnt/kubernetes/harbor/database
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- ノード名
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: harbor-redis
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: harbor-redis-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: harbor-redis
local:
path: /mnt/kubernetes/harbor/redis
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- ノード名
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: harbor-trivy
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: harbor-trivy-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: harbor-trivy
local:
path: /mnt/kubernetes/harbor/trivy
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- ノード名
レジストリのPVは,PVCデフォルトの5GBだと少ない気がしたので,20GBに増やしています.
除了注册表的PV以外,指定了PVC所指定的容量。
我将应用此yml文件。
kubectl apply -f harbor-vol.yml
接下来,我们需要添加Harbor的Helm仓库。
helm repo add harbor https://helm.goharbor.io
实际上,将安装Harbor。
helm install --create-namespace -n harbor-system harbor harbor/harbor \
--set expose.type=nodePort --set expose.tls.enabled=false \
--set persistence.persistentVolumeClaim.registry.storageClass=harbor-registry --set persistence.persistentVolumeClaim.registry.size=20Gi \
--set persistence.persistentVolumeClaim.chartmuseum.storageClass=harbor-chartmuseum \
--set persistence.persistentVolumeClaim.jobservice.storageClass=harbor-jobservice \
--set persistence.persistentVolumeClaim.database.storageClass=harbor-database \
--set persistence.persistentVolumeClaim.redis.storageClass=harbor-redis \
--set persistence.persistentVolumeClaim.trivy.storageClass=harbor-trivy \
--set externalURL=http://tailscaleのmagicDNS(小文字):30002 --set harborAdminPassword=パスワード
命名空间是harbor-system。
Portainerと同じくデフォルトSCを使用する場合は,persistence.persistentVolumeClaimをセットする必要はありません.
また,レジストリのサイズをデフォルトの5GBにした場合,persistence.persistentVolumeClaim.registry.sizeの指定は不要です.
ブラウザで,
http://tailscaleのmagicDNS(小文字):30002
当您打开时,您可以使用用户名admin和设置的密码进行登录。
テスト用プロジェクトを作成します
登录后,从“+新项目”创建一个用于操作测试的项目。
今回は,認証のテストをしたいので,Privateなレジストリをtestという名前で作成します.
使私有Docker注册表可用于Docker。
这次我们在NodePort上部署了HTTP,但是默认情况下,Docker需要使用HTTPS才能进行登录和拉取操作。
因此,需要设定以便能够使用本次创建的注册表。
Linux上のDockerであれば以下の通りです.
/etc/docker/daemon.jsonを以下のように編集し,Dockerデーモンの設定を変更します.
既に設定がある場合,前の要素の末尾に『,』を追加して次の行に”insecure-registries”の要素を記述して下さい.
{
"insecure-registries": [
"tailscaleのmagicDNS(小文字):30002"
]
}
重新启动Docker守护程序。
sudo systemctl restart docker
如果使用Docker Desktop,可以点击齿轮图标->进入Docker Engine,然后在现有的insecure-registries上设置”tailscale的magicDNS(小写):30002″,选择应用并重新启动即可。
如果是Windows Server等服务器,请在C:\ProgramData\docker\config\目录下创建与上述相同内容的daemon.json文件(未经验证)。
使用Docker登录
Dockerでログインし,認証が必要なプロジェクトのレジストリにPush出来るようにします.
以下のようなコマンドでログインします.
docker login -u admin -p Helmでインストール時に設定したパスワード http://tailscaleのmagicDNS(小文字):30002
当成功登录时,表示登录成功。
推送测试图像
隨意拉取一個nginx的映像。
docker pull nginx
在指定Push的tag之前(当使用自己的容器映像时,只需在构建时进行指定即可)。
先程,作成したtestプロジェクトのタグを付けます.
docker tag nginx tailscaleのmagicDNS(小文字):30002/test/nginx
按下按钮。
docker push tailscaleのmagicDNS(小文字):30002/test/nginx
Kubernetes(containerd)でもプライベートDockerレジストリを使えるようにする
KubernetesのCRIとして採用したcontainerdも,デフォルトではhttpsでないとPull出来ないので,今回作ったレジストリを使用できるようにcontainerdを,設定する必要があります.
请按照以下方式编辑/etc/containerd/config.toml。
只有使用tailscale的magicDNS部分进行了补充。
(前略)
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://registry-1.docker.io"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."tailscaleのmagicDNS(小文字):30002"]
endpoint = ["http:/tailscaleのmagicDNS(小文字):30002"]
(後略)
如果更改设置,将重新启动containerd。
sudo systemctl restart containerd
我将通过containerd来确认是否可以使用私有注册表。
sudo ctr image pull -u admin:パスワード tailscaleのmagicDNS(小文字):30002/test/nginx
如果能够无问题地解决,我会删除已进行的图像推送。
sudo ctr image rm tailscaleのmagicDNS(小文字):30002/test/nginx
使用Kubernetes创建一个具有注册表认证信息的密钥。
HarborはPullに認証が必要なPrivateと不要なPublicレジストリがありますが,認証が必要な場合は以下のようにして,secretを作る必要があります.
此外,在每个使用的命名空间中,需要创建一个名为“secret”的对象。
如果使用Docker的身份验证信息,则如下所示。
如果在默认命名空间中创建,不需要” -n 命名空间名称”的部分(后文)。
kubectl -n namespace名 create secret generic secret名 \
--from-file=.dockerconfigjson=$HOME/.docker/config.json \
--type=kubernetes.io/dockerconfigjson
创建一个包含其他注册表的认证信息和多个认证信息的secret是最佳方法。
Docker環境で,サーバーのkubectlが使えない場合や,secretの認証情報を単一にしたい場合は,以下の通りです.
kubectl -n namespace名 create secret docker-registry secret名 \
--docker-server=http://tailscaleのmagicDNS(小文字):30002 \
--docker-username=admin \
--docker-password=パスワード
プライベートレジストリのイメージを使用したアプリケーションを実際にデプロイ
テスト用のアプリケーションとして,以下のようなymlをtest.ymlという名前で作成します.
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- name: nginx
image: tailscaleのmagicDNS(小文字):30002/test/nginx
imagePullSecrets:
- name: secret名
---
apiVersion: v1
kind: Service
metadata:
name: test-service
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 32767
protocol: TCP
selector:
app: test
前回のymlのイメージ取得先を変更しています.
kubectl apply -f test.yml
如果与上次确认的情况相同,并且没有问题的话,那么就算成功了。
Pod的状态不是ErrImagePull或ImagePullBackOff是很重要的。
余談:DockerでマルチCPUアーキテクチャ対応のイメージをPushする
Harborは,マルチCPUアーキテクチャ対応のDockerレジストリですが,上記のDockerデーモンの設定変更は,マルチCPUアーキテクチャ対応のイメージについては無意味です.
在使用push命令时,需要设置registry.insecure=true选项。
docker buildx build --platform linux/amd64,linux/arm64 -t tailscaleのmagicDNS(小文字):30002/プロジェクト名/イメージ名 --output=type=image,push=true,registry.insecure=true .