[admin@k8s-master-01 software]$ helm repo add harbor https://helm.goharbor.io
[admin@k8s-master-01 software]$ helm search repo harbor
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/harbor 26.7.4 2.13.1 Harbor is an opensource trusted cloud-native r...
harbor/harbor 1.17.1 2.13.1 An opensource trusted cloud native registry th...
[admin@k8s-master-01 software]$ helm pull harbor/harbor
[admin@k8s-master-01 software]$ tar -xvf harbor-1.17.1.tgz
2. 配置安装
2.1 部署安装
[admin@k8s-master-01 software]$ helm install harbor ./harbor -n harbor --create-namespace \
--set expose.type=ingress \
--set expose.tls.enabled=true \
--set expose.tls.certSource=secret \
--set expose.tls.secret.secretName="harbor-tls"\
--set expose.ingress.hosts.core=harbor.test.com \
--set expose.ingress.className=nginx \
--set externalURL=https://harbor.test.com \
--set harborAdminPassword="giraffe"\
--set metrics.enabled=true \# 此处,开启了http/https的代理,通过宿主机访问外网
--set proxy.httpProxy=http://192.168.1.24:10809 \
--set proxy.httpsProxy=http://192.168.1.24:10809
NAME: harbor
LAST DEPLOYED: Wed Jul 210:05:57 2025
NAMESPACE: harbor
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Please waitfor several minutes for Harbor deployment to complete.
Then you should be able to visit the Harbor portal at https://harbor.test.com
For more details, please visit https://github.com/goharbor/harbor
2.2 查看安装详情
[admin@k8s-master-01 harbor]$ kubectl get all -n harbor
NAME READY STATUS RESTARTS AGE
pod/harbor-core-8544bd7fb5-4b724 1/1 Running 1(65s ago) 2m15s
pod/harbor-database-0 1/1 Running 0 94s
pod/harbor-exporter-6cddfcd4cb-xp5rz 1/1 Running 1(75s ago) 2m15s
pod/harbor-jobservice-64c6dd9f97-89tl6 1/1 Running 2(38s ago) 2m15s
pod/harbor-portal-5b6b5f7494-bb7gk 1/1 Running 0 2m15s
pod/harbor-redis-0 1/1 Running 0 53s
pod/harbor-registry-6699798969-fqflj 2/2 Running 0 2m15s
pod/harbor-trivy-0 1/1 Running 0 53s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/harbor-core ClusterIP 10.99.230.101 <none>80/TCP,8001/TCP 2m15s
service/harbor-database ClusterIP 10.104.1.42 <none>5432/TCP 2m15s
service/harbor-exporter ClusterIP 10.97.33.210 <none>8001/TCP 2m15s
service/harbor-jobservice ClusterIP 10.111.39.175 <none>80/TCP,8001/TCP 2m15s
service/harbor-portal ClusterIP 10.102.76.21 <none>80/TCP 2m15s
service/harbor-redis ClusterIP 10.103.177.51 <none>6379/TCP 2m15s
service/harbor-registry ClusterIP 10.110.170.132 <none>5000/TCP,8080/TCP,8001/TCP 2m15s
service/harbor-trivy ClusterIP 10.98.157.189 <none>8080/TCP 2m15s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/harbor-core 1/1 11 2m15s
deployment.apps/harbor-exporter 1/1 11 2m15s
deployment.apps/harbor-jobservice 1/1 11 2m15s
deployment.apps/harbor-portal 1/1 11 2m15s
deployment.apps/harbor-registry 1/1 11 2m15s
NAME DESIRED CURRENT READY AGE
replicaset.apps/harbor-core-8544bd7fb5 111 2m15s
replicaset.apps/harbor-exporter-6cddfcd4cb 111 2m15s
replicaset.apps/harbor-jobservice-64c6dd9f97 111 2m15s
replicaset.apps/harbor-portal-5b6b5f7494 111 2m15s
replicaset.apps/harbor-registry-6699798969 111 2m15s
NAME READY AGE
statefulset.apps/harbor-database 1/1 2m15s
statefulset.apps/harbor-redis 1/1 2m15s
statefulset.apps/harbor-trivy 1/1 2m15s
[admin@k8s-master-01 harbor]$ kubectl get pvc -n harbor
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
data-harbor-redis-0 Bound pvc-35ca57ad-c04c-4a0c-9870-0a5a885874a0 1Gi RWO nfs-storage <unset> 3m35s
data-harbor-trivy-0 Bound pvc-471c6917-0609-46f2-9801-b08c80ba0bfb 5Gi RWO nfs-storage <unset> 3m35s
database-data-harbor-database-0 Bound pvc-9ccb211c-51a9-46fa-bfe7-168aeb3d355d 1Gi RWO nfs-storage <unset> 3m35s
harbor-jobservice Bound pvc-db75de4b-3e99-417a-b63e-c0c7c02480fa 1Gi RWO nfs-storage <unset> 3m35s
harbor-registry Bound pvc-07949872-e5c6-4cb0-9bb9-09d0a954775c 5Gi RWO nfs-storage <unset> 3m35s
[admin@k8s-master-01 harbor]$ kubectl get ingress -n harbor
NAME CLASS HOSTS ADDRESS PORTS AGE
harbor-ingress nginx harbor.test.com 10.109.140.92 80, 443 2m58s
3. 网络相关配置
3.1 增加externalIPs
[admin@k8s-master-01 software]$ kubectl edit service/harbor-core -n harbor
spec:
externalIPs:
- 192.168.100.1
type: NodePort
[admin@k8s-master-01 harbor]$ kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.109.140.92 <none>80:30080/TCP,443:30443/TCP 14h
ingress-nginx-controller-admission ClusterIP 10.99.115.202 <none>443/TCP 14h
[admin@k8s-master-01 harbor]$ kubectl get svc,ingress -n harbor
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/harbor-core ClusterIP 10.99.230.101 192.168.100.1 80/TCP,8001/TCP 22m
service/harbor-database ClusterIP 10.104.1.42 <none>5432/TCP 22m
service/harbor-exporter ClusterIP 10.97.33.210 <none>8001/TCP 22m
service/harbor-jobservice ClusterIP 10.111.39.175 <none>80/TCP,8001/TCP 22m
service/harbor-portal ClusterIP 10.102.76.21 <none>80/TCP 22m
service/harbor-redis ClusterIP 10.103.177.51 <none>6379/TCP 22m
service/harbor-registry ClusterIP 10.110.170.132 <none>5000/TCP,8080/TCP,8001/TCP 22m
service/harbor-trivy ClusterIP 10.98.157.189 <none>8080/TCP 22m
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/harbor-ingress nginx harbor.test.com 10.109.140.92 80, 443 22m
3.2 配置集群内部 dns 域名解析
[admin@k8s-master-01 software]$ kubectl edit configmap coredns -n kube-system
# Please edit the object below. Lines beginning with a '#' will be ignored,# and an empty file will abort the edit. If an error occurs while saving this file will be# reopened with the relevant failures.#
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30}
hosts {192.168.100.1 harbor.test.com
192.168.100.2 gitlab.test.com
192.168.100.3 jenkins.test.com
fallthrough
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000}
cache 30{
disable success cluster.local
disable denial cluster.local
}
loop
reload
loadbalance
}
kind: ConfigMap
metadata:
creationTimestamp: "2025-03-12T14:08:21Z"
name: coredns
namespace: kube-system
resourceVersion: "264"
uid: 22bfe350-733d-4d51-ae10-298be5ad9730
# 查看当前coredns的pod[admin@k8s-master-01 harbor]$ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-6766b7b6bb-2k987 1/1 Running 0 11s
coredns-6766b7b6bb-gjk8c 1/1 Running 0 11s
etcd-k8s-master-01 1/1 Running 3(25m ago) 14h
kube-apiserver-k8s-master-01 1/1 Running 3(25m ago) 14h
kube-controller-manager-k8s-master-01 1/1 Running 3(25m ago) 14h
kube-proxy-nq6s6 1/1 Running 3(25m ago) 14h
kube-proxy-xkkff 1/1 Running 3(24m ago) 14h
kube-proxy-xvk5z 1/1 Running 3(23m ago) 14h
kube-scheduler-k8s-master-01 1/1 Running 3(25m ago) 14h
# 删除旧的coredns,删玩会自动重建coreDns[admin@k8s-master-01 harbor]$ kubectl delete pod -n kube-system -l k8s-app=kube-dns
pod "coredns-6766b7b6bb-2k987" deleted
pod "coredns-6766b7b6bb-gjk8c" deleted
3.3 测试访问
3.3.1 验证 dns 解析
获取 dns 的域名解析,期望访问harbor.test.com --> 192.168.100.1
# 测试dns解析[admin@k8s-master-01 harbor]$ kubectl run netshoot --rm -it --image=nicolaka/netshoot -- bash
If you don't see a command prompt, try pressing enter.
netshoot:~# nslookup harbor.test.com;; Got recursion not available from 10.96.0.10
;; Got recursion not available from 10.96.0.10
;; Got recursion not available from 10.96.0.10
;; Got recursion not available from 10.96.0.10
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: harbor.test.com
Address: 192.168.100.1 # 说明DNS配置生效;; Got recursion not available from 10.96.0.10
3.3.2 docker login 测试
在 centos 系统上(k8s 集群外登录)
[admin@k8s-master-01 harbor]$ sudo docker login -u admin -p giraffe https://harbor.test.com
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[admin@k8s-worker-01 ~]$ sudo docker login -u admin -p giraffe https://harbor.test.com
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[admin@k8s-worker-02 ~]$ sudo docker login -u admin -p giraffe https://harbor.test.com
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
在集群内登录
[admin@k8s-master-01 harbor]$ vim harbor-test.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: harbor-test
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: centos-docker
namespace: harbor-test
spec:
replicas: 1
selector:
matchLabels:
app: centos-docker
template:
metadata:
labels:
app: centos-docker
spec:
containers:
- name: centos
image: docker:cli # CentOS 7 + 预装 Docker
securityContext:
privileged: true# 允许操作 Docker
command: ["sleep", "infinity"]# 保持容器运行
volumeMounts:
- name: docker-sock
mountPath: /var/run/docker.sock # 挂载主机 Docker 套接字
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock # 从主机挂载
---
apiVersion: v1
kind: Service
metadata:
name: centos-docker-service
namespace: harbor-test
spec:
selector:
app: centos-docker
ports:
- protocol: TCP
port: 80
targetPort: 30080
externalIPs:
- 192.168.100.1
[admin@k8s-master-01 harbor]$ kubectl apply -f harbor-test.yaml
namespace/harbor-test created
deployment.apps/centos-docker created
service/centos-docker-service created
[admin@k8s-master-01 harbor]$ kubectl get all -n harbor-test
NAME READY STATUS RESTARTS AGE
pod/centos-docker-775f7f545d-f8zmt 1/1 Running 0 29s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/centos-docker-service ClusterIP 10.105.185.169 192.168.100.1 80/TCP 29s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/centos-docker 1/1 11 29s
NAME DESIRED CURRENT READY AGE
replicaset.apps/centos-docker-775f7f545d 111 29s
[admin@k8s-master-01 harbor]$ kubectl exec -it service/centos-docker-service -n harbor-test -- /bin/sh
/ # docker -v
Docker version 28.3.0, build 38b7060
/ # docker login -u admin -p giraffe https://harbor.test.com
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your credentials are stored unencrypted in'/root/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/
Login Succeeded
3.3.3 web 页面访问
4. 基本使用
4.1 镜像的拉取与推送
# docker登录[admin@k8s-master-01 harbor]$ sudo docker login -u admin -p giraffe https://harbor.test.com
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
# docker 查询镜像[admin@k8s-master-01 harbor]$ sudo docker images |grep elasticsearch
bitnami/elasticsearch 8.17.3-debian-12-r0 a45c31148c01 3 months ago 1.46GB
elasticsearch 7.7.1 830a894845e3 5 years ago 804MB
harbor.test.com/kubernetes/elasticsearch 7.7.1 830a894845e3 5 years ago 804MB
# docker镜像打标签[admin@k8s-master-01 harbor]$ sudo docker tag elasticsearch:7.7.1 harbor.test.com/kubernetes/elasticsearch:7.7.1
# 推送标签镜像至harbor仓库[admin@k8s-master-01 harbor]$ sudo docker push harbor.test.com/kubernetes/elasticsearch:7.7.1
The push refers to repository [harbor.test.com/kubernetes/elasticsearch]
4393f37cdb2f: Pushed
8ac4a9f5ad9e: Pushed
ad4d097db096: Pushed
d8a68b01a7b7: Pushed
9834d4b501fc: Pushed
6a0f4e2bf9f9: Pushed
380d64359038: Pushed
bad94484a7e1: Pushed
edf3aa290fb3: Pushed
7.7.1: digest: sha256:85afaf2752085119a3835127a06001aecb2780ef070ce8dc74a1610e64aa5769 size: 2203# docker 拉取镜像[admin@k8s-master-01 harbor]$ sudo docker pull harbor.test.com/kubernetes/elasticsearch:7.7.1
7.7.1: Pulling from kubernetes/elasticsearch
524b0c1e57f8: Pull complete
4f79045bc94a: Pull complete
4602c5830f92: Pull complete
10ef2eb1c9b1: Pull complete
47fca9194a1b: Pull complete
c282e1371ecc: Pull complete
302e1effd34b: Pull complete
50acbec75309: Pull complete
f89bc5c60b5f: Pull complete
Digest: sha256:85afaf2752085119a3835127a06001aecb2780ef070ce8dc74a1610e64aa5769
Status: Downloaded newer image for harbor.test.com/kubernetes/elasticsearch:7.7.1
harbor.test.com/kubernetes/elasticsearch:7.7.1