Harbor私有鏡像倉庫無坑搭建
一、介紹
Docker容器應用的開發和運行路不開可靠的鏡像管理,雖然Docker官方也提供了公共的鏡像倉庫,但是從安全和效率等方面考慮,部署我們私有環境的Registry也是非常必要的。 Harbor是由VMware公司開源的企業級的Docker Registry管理項目,它包括權限管理(RBAC)、LDAP、日志審核、管理界面、自我注冊、鏡像復制和中文支持等功能。
二、組件
用於部署 Harbor 的 Docker Compose 模板位於 /Deployer/docker-compose.yml. 打開這個模板文件,會發現 Harbor 由 5 個容器組成:
proxy:由 Nginx 服務器構成的反向代理。
registry:由 Docker 官方的開源 registry 鏡像構成的容器實例。
ui:即架構中的 core services, 構成此容器的代碼是 Harbor 項目的主體。
mysql:由官方 MySql 鏡像構成的數據庫容器。
log: 運行着 rsyslogd 的容器,通過 log-driver 的形式收集其他容器的日志。
這幾個容器通過 Docker link 的形式連接在一起,這樣,在容器之間可以通過容器名字互相訪問。對終端用戶而言,只需要暴露 proxy (即 Nginx)的服務端口。
三、工作原理
假設我們將 Harbor 部署在主機名為 registry.abcdocker.com 的虛機上。用戶通過 docker login 命令向這個 Harbor 服務發起登錄請求:docker login registry.abcdocker.com當用戶輸入所需信息並點擊回車后,Docker 客戶端會向地址“registry.abcdocker.com/v2/” 發出 HTTP GET 請求。
Harbor 的各個容器會通過以下步驟處理:
(1)Docker login
(a) 首先,這個請求會由監聽 80 端口的 proxy 容器接收到。根據預先設置的匹配規則,容器中的 Nginx會將請求轉發給后端的 registry 容器;
(b) 在 registry 容器一方,由於配置了基於 token 的認證,registry 會返回錯誤代碼 401,提示 Docker客戶端訪問 token 服務綁定的 URL。在 Harbor 中,這個 URL 指向 Core Services;
(c) Docker 客戶端在接到這個錯誤代碼后,會向token服務的URL發出請求,並根據HTTP協議的BasicAuthentication 規范,將用戶名密碼組合並編碼,放在請求頭部(header);
(d)類似地,這個請求通過 80 端口發到 proxy 容器后,Nginx 會根據規則把請求轉發給 ui 容器,ui 容器監聽 token 服務網址的處理程序接收到請求后,會將請求頭解碼,得到用戶名、密碼;
(e) 在得到用戶名、密碼后,ui 容器中的代碼會查詢數據庫,將用戶名、密碼與 mysql 容器中的數據進行比對(注:ui 容器還支持 LDAP 的認證方式,在那種情況下 ui 會試圖和外部 LDAP 服務進行通信並校驗用戶名/密碼)。比對成功,ui 容器會返回表示成功的狀態碼, 並用密鑰生成 token,放在響應體中返回給 Docker 客戶端。這個過程中組件間的交互過程如下圖所示
三、安裝
Harbor 2種安裝方式1.離線安裝
$ wget https://storage.googleapis.com/harbor-releases/harbor-offline-installer-v1.5.0.tgz
$ tar xf harbor-online-installer-v1.5.0.tgz
2.在線安裝
$ wget https://storage.googleapis.com/harbor-releases/harbor-online-installer-v1.5.2.tgz
$ tar xf harbor-online-installer-v1.5.2.tgz
重點:下載那個823M的安裝
復制代碼配置Harbor解壓之后,配置文件名稱harbor.cfg,該文件就是Harbor的配置文件編輯harbor.cfg實際上我們只需要修改Hostname字段[root@harbor harbor]# head harbor.cfg
## Configuration file of Harbor
#This attribute is for migrator to detect the version of the .cfg file, DO NOT MODIFY!
_version = 1.5.0
#The IP address or hostname to access admin UI and registry service.
#DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname = 192.168.1.197
本次我們使用離線安裝,安裝包在上面
tar xf harbor-offline-installer-v1.5.0.tgz
./install
默認端口為80,需要修改端口請修改docker-compose.yaml對應服務的映射
四、訪問Harbor
訪問:192.168.1.197
docker push 需要項目路徑,需要Harbor 創建項目 test
五、客戶端配置免https
[root@localhost ~]# echo '{ "insecure-registries":["192.168.252.213:80"] }' > /etc/docker/daemon.json
[root@localhost ~]# cat /etc/docker/daemon.json
{ "insecure-registries":["192.168.252.213:80"] }
[root@localhost ~]# service docker restart
如果不配置,客戶端使用時候會報錯: Error response from daemon: Get https:// 172.16.1.146:5000/v1/_ping: http: server gave
HTTP response to HTTPS client
客戶端登陸
[root@localhost harbor]# docker login 192.168.252.213:80
Username (admin): admin
Password:
Login Succeeded
五、管理鏡像
下拉鏡像
docker pull nginx
打標簽
docekr tag 鏡像名稱:標簽 你的IP:端口/harbor項目名稱/鏡像名稱:標簽
docker tag nginx:latest 192.168.252.213:80/test/nginx:latest
上傳
docker push 你的IP:端口/harbor項目名稱/鏡像名稱:標簽
docker push 192.168.252.213:80/test/nginx:latest
下拉
docker pull 192.168.252.213:80/test/nginx:latest
六、k8s配置harbor
在k8s中使用harbor倉庫
k8s 默認https訪問harbor,訪問http,需要修改整個集群節點
/etc/docker/daemon.json
文件
# 配置兩個鏡像源文件
# 1.harbor 源/etc/docker/daemon.json 2. 國內源/etc/docker/daemon.conf
# 配置國內鏡像源/etc/docker/daemon.conf 文件
cat > /etc/docker/daemon.conf <<EOF
{
"registry-mirrors": [
"https://kfwkfulq.mirror.aliyuncs.com",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com"
],
{ "insecure-registries":["192.168.252.213:80"] }, # harbor ip地址
"dns": ["8.8.8.8","8.8.4.4"]
}
EOF
最后重啟docker
service docker restart
創建認證secret
由於harbor采用了用戶名密碼認證,所以在鏡像下載時需要配置sercet
#創建
kubectl create secret docker-registry registry-secret --namespace=default \
--docker-server=10.1.210.33 \
--docker-username=admin \
--docker-password=Harbor12345
#查看secret
[root@master demo]# kubectl get secret
NAME TYPE DATA AGE
default-token-gdwgn kubernetes.io/service-account-token 3 2d18h
registry-secret kubernetes.io/dockerconfigjson 1 116s
#刪除
kubectl delete secret registry-secret
部署示例
以一個部署一個nginx為例子,其中需要把containers中的images鏡像指定為harbor倉庫鏡像地址
# kubectl create -f nginx.test.yml
root@k8s-master-2:~# vim /k8s/nginx.test.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment-harbor
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: 192.168.252.213:80/test/nginx:latest # harbor倉庫鏡像地址
imagePullPolicy: Always
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
sessionAffinity: ClientIP
selector:
app: nginx
ports:
- port: 80
nodePort: 30080
訪問nginx
root@k8s-master-2:~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service NodePort 10.68.153.43 <none> 80:30080/TCP 19
root@k8s-master-2:~# curl 10.68.153.43