原文网址:K8S--解决访问Harbor私有仓库无权限的问题(401 Unauthorized)-CSDN博客
简介
本文解决K8S访问Harbor私有仓库无权限的问题:401 Unauthorized。
问题复现
用Harbor部署了私有仓库,将镜像推送上去。指定私有仓库的镜像创建Pods时报错了,关键日志是:401 Unauthorized
这个日志是Pods的日志,可以在dashboard上或者通过kubectl describe pod 查看。
原因分析
需要访问权限。
问题解决
需要在 Kubenetes 配置 Secret 访问 Harbor私有仓库。
1.登录并获取密钥
1.登录
docker login 192.168.5.193:15001
结果
2. 查看密钥
cat ~/.docker/config.json
结果
2.创建Harbor机器人账号
Harbor 上创建机器人账号,账号名称与将要创建的 Secret 名称一致。
3.创建Secret
1.生成密钥的base64
cat ~/.docker/config.json | base64 -w 0
结果
2.创建Secret
方式1:yaml 文件创建
创建 harbor-secret.yaml 文件,其中 .dockerconfigjson 的值为上边获得的base64值:
apiVersion: v1
kind: Secret
metadata:
name: harbor-secret
namespace: java-app
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjUuMTkzOjE1MDAxIjogewoJCQkiYXV0aCI6ICJZV1J0YVc0NlNHRnlZbTl5TVRJek5EVT0iCgkJfQoJfQp9Cg==
注意:这里是只有java-app命名空间的应用能用这个secret。
执行:
kubectl apply -f harbor-secret.yaml
结果
方式2:命令行创建
kubectl create secret docker-registry harbor-secret --docker-server="192.168.5.193:15001" \
--docker-email=test@test.com \
--docker-username='admin' \
--docker-password='Harbor12345' \
-n java-app
4.Pod指定Secret
在Deployment的spec.template.spec里添加:
imagePullSecrets:
- name: harbor-secret
整个k8s.yaml文件如下:
# 创建Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-springboot-deployment
namespace: java-app
labels:
app: demo-springboot #与Service的selector对应
spec:
# 副本的数量
replicas: 2
selector:
# 选择Pod
matchLabels:
app: demo-springboot
# 选择或创建的Pod的模板
template:
metadata:
# 与Deployment的selector对应
labels:
app: demo-springboot
spec:
imagePullSecrets:
- name: harbor-secret
containers:
- image: 192.168.5.193:15001/custom_image/custom_docker-springboot:1.0
name: custom-docker-springboot-1-0
ports:
- containerPort: 8080
name: pod-8080
# 容器内的路径
volumeMounts:
- name: log
mountPath: /log/
# 主机的路径
volumes:
- name: log #和volumeMounts中的内容要对应
hostPath:
path: /work/devops/k8s/app/demo-springboot/log/
type: DirectoryOrCreate
---
# 创建Service
apiVersion: v1
kind: Service
metadata:
name: demo-springboot-service
namespace: java-app
labels:
app: demo-springboot
spec:
ports:
- name: demo-springboot-port
port: 9000 # Service监听的端口
targetPort: 8080 # pod自身暴露的端口。对应Deployment的containerPort
# 对外的端口号
nodePort: 30004
# 选择Deployment
selector:
app: demo-springboot
# NodePort类型可以对外暴露端口
type: NodePort
然后再次执行:
kubectl apply -f k8s.yaml
结果:(成功启动)
5.访问测试
看一下SpringBoot的日志:(启动成功)
访问一下SpringBoot的端口:
访问:http://192.168.5.193:30004/doc.html
结果
访问接口:
6.自动关联 Secret
上边每次在创建 Pod 时都需要通过 imagePullSecrets 字段引用相应 namespace 下的 secret。
可以通过 kubectl patch 命令来将 namespace 和对应的 secret 自动关联,执行如下语句,关联后就不需要在 Pod 上指定 imagePullSecrets:
kubectl patch serviceaccount default -n java-app -p \
'{"imagePullSecrets":[{"name":"harbor-secret"}]}'