因为要测试knative,所以需要使用到docker私有仓库,所以需要自建一个docker registry,主要步骤都是遵循docker hub官方文档来的,只不过我这里使用的是k8s而不是docker compose。
由于私有仓库需要用到存储,因此使用local storage的方式存储数据。
apiVersion: v1
kind: Namespace
metadata:
name: docker-registry
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
apiVersion: v1
kind: PersistentVolume
metadata:
name: docker-registry-pv
labels:
pv: docker-registry-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /data/docker
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- master
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: docker-registry-pvc
namespace: docker-registry
spec:
resources:
requests:
storage: 5Gi
accessModes:
- ReadWriteMany
storageClassName: local-storage
selector:
matchLabels:
pv: docker-registry-pv
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: docker-registry
name: docker-registry
namespace: docker-registry
spec:
replicas: 1
revisionHistoryLimit: 5
selector:
matchLabels:
app: docker-registry
template:
metadata:
labels:
app: docker-registry
spec:
securityContext:
runAsUser: 0
containers:
- name: docker-registry
image: registry:2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000
name: web
protocol: TCP
resources:
requests:
memory: 200Mi
cpu: "0.1"
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/lib/registry/
name: docker-registry-data
volumes:
- name: docker-registry-data
persistentVolumeClaim:
claimName: docker-registry-pvc
apiVersion: v1
kind: Service
metadata:
name: docker-registry-service
namespace: docker-registry
spec:
ports:
- name: port-name
port: 5000
protocol: TCP
targetPort: 5000
selector:
app: docker-registry
type: NodePort
至此,docker registry已经搭建好了。
可使用如下命令查看pod和service状态。但是我们还无法正常使用,因为docker registry默认使用的是https协议,所以如果自己的环境中提供了https的证书,那么就可以跳过以下步骤,但是如果没有证书,比如开发同学搞测试的话,那么建议将service或者pod的endpoint添加到docker的配置文件中,将https转换为http。
kubectl get pods -n docker-registry
NAME READY STATUS RESTARTS AGE
docker-registry-67c8d5b74-5nzsm 1/1 Running 3 30h
[root@master ~]# kubectl get service -n docker-registry
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
docker-registry-service NodePort 10.99.92.139 <none> 5000:31322/TCP 5d5h
记住docker-registry-service的endpoint为
10.99.92.139:5000
需要将此endpoint加入docker的配置文件中,修改文件
/etc/docker/daemon.json
添加如下内容:
"insecure-registries": ["10.99.92.139:5000"]
这里要注意填写自己的service或者pod的endpoint地址。
如果是在mac上,并且使用的是docker自带的kubernetes,那么如下endpoint写入配置也可以。
kubectl get nodes | grep -v 'NAME' | awk -F ' ' '{print$1}'
的结果,比如我这里是master
[root@master ~]# kubectl get nodes | grep -v 'NAME' | awk -F ' ' '{print$1}'
master
那么写入的值就为:
"insecure-registries": ["master:5000"]
然后就可以愉快使用docker registry仓库了。
[root@master ~]# docker tag master:5000/pause:3.2 10.99.92.139:5000/pause:3.2
[root@master ~]# docker push 10.99.92.139:5000/pause:3.2
The push refers to a repository [10.99.92.139:5000/pause]
ba0dae6243cc: Pushed
3.2: digest: sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108 size: 526
[root@master ~]# kubectl get service -n docker-registry
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
docker-registry-service NodePort 10.99.92.139 <none> 5000:31322/TCP 5d5h
可见,docker-registry已经可以正常访问了。
关于存储,我们是将docker-registry的私有仓存储放在了主机上,路径为前面pv定义的地址
local:
path: /data/docker
/data/docker目录,这时候,我们可以去这个目录下面看看,docker镜像是如何存储的。
[root@master ~]# tree /data/docker/docker/
/data/docker/docker/
└── registry
└── v2
├── blobs
│ └── sha256
│ ├── 4a
│ │ └── 4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
│ │ └── data
│ ├── 80
│ │ └── 80d28bedfe5dec59da9ebf8e6260224ac9008ab5c11dbbe16ee3ba3e4439ac2c
│ │ └── data
│ └── c7
│ └── c74f8866df097496217c9f15efe8f8d3db05d19d678a02d01cc7eaed520bb136
│ └── data
└── repositories
└── pause
├── _layers
│ └── sha256
│ ├── 80d28bedfe5dec59da9ebf8e6260224ac9008ab5c11dbbe16ee3ba3e4439ac2c
│ │ └── link
│ └── c74f8866df097496217c9f15efe8f8d3db05d19d678a02d01cc7eaed520bb136
│ └── link
├── _manifests
│ ├── revisions
│ │ └── sha256
│ │ └── 4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
│ │ └── link
│ └── tags
│ └── 3.2
│ ├── current
│ │ └── link
│ └── index
│ └── sha256
│ └── 4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
│ └── link
└── _uploads
27 directories, 8 files
可以看见docker存储的的目录有两部分
[root@master ~]# ls -lh /data/docker/docker/registry/v2/
total 0
drwxr-xr-x. 3 root root 20 Dec 3 10:07 blobs
drwxr-xr-x. 3 root root 19 Dec 3 10:07 repositories
blobs存储元数据
repositories存储的是每个单独的镜像,但是只是元数据的引用。
这样的好处就是一个元数据的层,可以被多个不同的镜像所引用,这样就节省了磁盘占用。缺点就是增加了复杂性。