前言
环境:centos 7.9 k8s-v1.22.6 harbor--v2.4.3-85ef1409
harbor私有镜像仓库搭建
docker
的私有镜像仓库使用harbor
,harbor的搭建请参考 https://blog.csdn.net/MssGuo/article/details/126210184?
,这里不在陈诉,默认你已经搭建好了harbor,能正常上传下载镜像到harbor。
Secret 的三种类型
查看官方文档我们得知,Secret原来一共有三种类型的,分别是:
Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;但数据也可以通过base64 –decode解码得到原始数据,所有加密性很弱。
kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
kubernetes.io/service-account-token:用于被serviceaccount引用,serviceaccout 创建时Kubernetes会默认创建对应的secret。Pod如果使用了serviceaccount,对应的secret会自动挂载到Pod目录/run/secrets/kubernetes.io/serviceaccount中。
原来,就是使用kubernetes.io/dockerconfigjson
这种类型的Secret
存储私有docker registry
的认证信息
创建私有镜像仓库Secret 的两种方式
1、先在docker上登录harbor镜像仓库地址,得到 /root/.docker/config.json
文件,使用该文件进行创建,可以查看官网: https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/pull-image-private-registry/
2、使用命令行镜像创建;这里主要讲解使用命令行创建。
k8s使用命令行创建Secret 配置harbor私有镜像仓库地址
# 直接使用命令行创建一个名称叫做harbor-registry的secret
# docker-registry是关键字,harbor-registry才是我们起的名称
# 指定命名空间,注意secret资源对象是区分命名空间的
kubectl -n default create secret docker-registry harbor-registry \
--docker-email=baidu.com@example \
--docker-username=admin \
--docker-password=TestHarbor123 \
--docker-server=192.168.118.119:443
#查看secret,已经创建成功
[root@master ~]# kubectl get secret harbor-registry
NAME TYPE DATA AGE
harbor-registry kubernetes.io/dockerconfigjson 1 16s
#查看secret
[root@master ~]# kubectl describe secret harbor-registry
Name: harbor-registry
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson: 141 bytes
[root@master ~]#
# 对.data.dockerconfigjson 内容进行转储并执行 base64 解码可以发现:
[root@master ~]# kubectl get secret harbor-registry -o jsonpath='{.data.*}' | base64 -d
{"auths":{"192.168.118.119:443":{"username":"admin","password":"TestHarbor123","email":"baidu.com@example","auth":"YWRtaW46SGFyYm9yMTIzNDU="}}}[root@master ~]#
#格式化一下,其实这就是一个有效的docker用户配置文件:
{
"auths": {
"192.168.118.119:443": {
"username": "admin",
"password": "TestHarbor123",
"email": "baidu.com@example",
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
}
}
}
还记的当你登陆docker的时候吗, docker login -u admin -p TestHarbor123 192.168.118.119:443 其实生成的用户信息配置文件就
是/root/.docker/config.json,这个文件和上面的基本是一样的。
pod使用imagePullSecrets参数指定镜像拉取秘钥
[root@master deployment]# cat test_nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-nginx
labels:
env: dev
tiar: front
namespace: default #命名空间,要与secret的一致,不要找不到对应的secret
spec:
replicas: 1
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
spec:
imagePullSecrets: #使用imagePullSecrets参数指定镜像拉取秘钥
- name: harbor-registry #使用我们的secret,即harbor-registry
containers:
- image: 192.168.118.119:443/my_harbor/nginx:v1 #指定拉取的镜像,注意这里的镜像名称只需要写到ip地址,端口号,仓库名,镜像名,版本
name: nginx-container
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
[root@master deployment]#
注意:在node节点上需要docker能正常请求到私有镜像仓库地址,还需要将harbor镜像仓库地址添加到/etc/docker/daemon.json
,如下所示:
[root@node1 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": ["192.168.118.119:443"] #添加这一句,不加的话docker login将会报错的
}
[root@node1 ~]#
[root@node1 ~]# systemctl daemon-reload #重载
[root@node1 ~]# systemctl restart docker #重启docker,生产环境不要随便重启docker
[root@master deployment]# kubectl apply -f test_nginx.yaml #创建deployment
[root@master deployment]# kubectl get pods #查看pods
NAME READY STATUS RESTARTS AGE
test-nginx-bcb85475b-6tcwz 0/1 ContainerCreating 0 10s
[root@master deployment]# kubectl describe pods test-nginx-bcb85475b-6tcwz #查看pods,pods被分配到node1上,镜像正常拉取
---- ------ ---- ---- -------
Normal Scheduled 37s default-scheduler Successfully assigned default/test-nginx-75c88cc97d-556lt to node1
Normal Pulling 35s kubelet Pulling image "192.168.118.119:443/my_harbor/nginx:v1"
Normal Pulled 35s kubelet Successfully pulled image "192.168.118.119:443/my_harbor/nginx:v1" in 110.79546ms
Normal Created 35s kubelet Created container nginx-container
Normal Started 35s kubelet Started container nginx-container
[root@master deployment]#
[root@node1 ~]# docker images | grep nginx #到node1上查看,镜像已经正常拉取下来了
192.168.118.119:443/my_harbor/nginx v1 605c77e624dd 9 months ago 141MB
[root@node1 ~]#
总结
1、创建一个secret 用于存储私有镜像的地址账号信息:
# 查看官网的样例 https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/#using-imagepullsecrets
# 没有指定命名空间,默认这个secret 是创建在当前命名空间下
kubectl create secret docker-registry secret-tiger-docker \ #docker-registry是关键字 secret-tiger-docker是自定义的名称
--docker-email=tiger@acme.example \ #定义邮箱
--docker-username=tiger \ #用户名
--docker-password=pass1234 \ #密码
--docker-server=my-registry.example:5000 #仓库地址+端口
#创建完成之后对secret 进行解码可以看到私有仓库的信息
[root@master ~]# kubectl get secret harbor-registry -o jsonpath='{.data.*}' | base64 -d
2、先确保每个node节点都能正常登录harbor私有镜像仓库地址,如果不能正常登录harbor仓库,可以试下配置下面这几行:
[root@node1 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": ["192.168.118.119:443"] #添加这一句,不加的话docker login将会报错的
}
[root@node1 ~]#
[root@node1 ~]# systemctl daemon-reload #重载
[root@node1 ~]# systemctl restart docker #重启docker,生产环境不要随便重启docker
3、 pod使用imagePullSecrets参数指定镜像拉取秘钥,注意pod的所在命名空间要与secret的命名空间一样,不要会找不到secret。
spec:
imagePullSecrets: #使用imagePullSecrets参数指定镜像拉取秘钥,这个秘钥要与pod所在命名空间一样
- name: harbor-registry #使用我们的secret,即harbor-registry
containers:
- image: 192.168.118.119:443/my_harbor/nginx:v1 #注意镜像名称需要写到ip地址,端口号,仓库名,镜像名,版本
name: nginx-container
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
4、官方不建议pod中使用imagePullSecrets进行仓库地址的配置,而是建议使用serveraccount的方式。
排错、经验教训
1、pod一直拉取不了镜像。
首先确保单个node节点是能正常拉取镜像的,其次检查image的名字是否正确,一定要是这样写 ip地址,端口号,仓库名,镜像名,版本
,没有ip地址端口号,只写到仓库名,镜像名,版本
是不行的。
其次,检查secret的命名空间是否与pod的命名空间一致。
最后,检查 你的secret配置,kubectl get secret harbor-registry -o jsonpath='{.data.*}' | base64 -d
解码,确保配置的信息是正确无误的。
检查以上几步,基本能保证一切正常了。