一、 写作背景
近来工作需要,预将公司现有应用服务 Docker
化,并使用 Kubernetes
进行统一资源编排,现将部署过程记录一下。
随着我们服务的全面容器化,代码和配置都以 docker image 的形式存储在 docker registry 中。搭建高可用,安全的企业私有 docker registy 就变得十分必要。 Harbor 作为 CNCF 托管的开源 docker registry 项目是我们的首选。它除了提供存储、签名、扫描镜像的功能,还有常用的功能如鉴权、授权、权限管理等来增强 docker registry 的安全性。 除此之外,Harbor 还有从其他 registry 复制镜像的功能,新版本集成了 chartmuseum 从而可以作为 Helm Charts 的 repository。Harbor 一个重要的特点是它是通过可插拔的方式来 集合第三方组件来提供不同的功能,比如用于镜像签名的 notary;镜像扫描的 clair; 镜像存储,推送和拉取的 docker registry;helm charts 存储,管理的 chartmuseum。
二、 系列文章
- 快速搭建Kubernetes高可用集群一 基础环境初始化
- 快速搭建Kubernetes高可用集群二 Kubeadm 初始化集群
- 快速搭建Kubernetes高可用集群三 Ingress、Dashboard、Metrics-server
- 快速搭建Kubernetes高可用集群四 Rook-Ceph
- 快速搭建Kubernetes高可用集群五 Harbor
- 快速搭建Kubernetes高可用集群六 Prometheus
- 快速搭建Kubernetes高可用集群七 ELK-stack
三、 项目部署
3.1 项目文件
这里使用 helm 来部署 harbor。
3.2 下载 docker image
提前下载 docker image 方便快速部署,最新版本是 dev ,稳定的版本是1.4.2。
docker pull goharbor/nginx-photon:dev
docker pull goharbor/harbor-portal:dev
docker pull goharbor/harbor-core:dev
docker pull goharbor/harbor-jobservice:dev
docker pull goharbor/registry-photon:dev
docker pull goharbor/harbor-registryctl:dev
docker pull goharbor/chartmuseum-photon:dev
docker pull goharbor/clair-photon:dev
docker pull goharbor/clair-adapter-photon:dev
docker pull goharbor/trivy-adapter-photon:dev
docker pull goharbor/notary-server-photon:dev
docker pull goharbor/notary-signer-photon:dev
docker pull goharbor/harbor-db:dev
docker pull goharbor/redis-photon:dev
3.3 创建证书及 secret
- 证书使用
cfssl
方式创建,详见快速搭建Kubernetes高可用集群三 Ingress、Dashboard、Metrics-server的** 4.3.2 创建证书** 小节,我在之前创建证书时使用了 *.kube.uat,所以所有以 kube.uat 为后缀的域名均可使用该证书。 - 使用证书创建 secret
# 采用 Helm 方式部署,需要先创建 namespace "harbor",否则会部署到 namespace "default" 下。
kubectl create namespace harbor
# 进入证书文件目录
cd /etc/kubernetes/pki/
# 创建证书,指定命名空间为 rook-ceph
kubectl -n harbor create secret tls harbor-kube-uat-certs --key kube-uat-key.pem --cert kube-uat.pem
3.4 在 Rook-ceph 中创建 StorageClass
Harbor需要使用数据库等持久化存储,这里使用 pvc 的方式挂载磁盘,首先创建 StorageClass , pv 会在部署的时候自动创建在指定的 StorageClass 上。
创建文件 harbor-storageclass.yaml,在原文件 ./rook/cluster/examples/kubernetes/ceph/csi/rbd/storageclass.yaml
的基础上修改而成。
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
# 这里更改为你需要创建的存储池名称,便于区别与其它存储池
name: harbor-replicapool
namespace: rook-ceph
spec:
failureDomain: host
replicated:
size: 3
requireSafeReplicaSize: true
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
# 这里设置要创建的StorageClass名称。Harbor的相关数据均存储在此StorageClass。
name: harbor-rook-ceph-block
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
clusterID: rook-ceph
# 这里是 StorageClass 所在的存储池,是上面一步创建的。
pool: harbor-replicapool
imageFormat: "2"
imageFeatures: layering
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
# 分区模式选择为 xfs (data-approve-charge7 以上都支持该分区模式)
csi.storage.k8s.io/fstype: xfs
allowVolumeExpansion: true
reclaimPolicy: Delete
部署 StorageClass
kubectl apply -f harbor-storageclass.yaml
查看 rook-ceph dashboard 内容
3.5 修改部署配置文件并部署
3.5.1 修改配置文件
修改配置文件,原文件位于./github/harbor-helm/values.yaml
,仅显示修改部分及相关内容
expose:
type: ingress
tls:
enabled: true
certSource: auto
auto:
commonName: ""
secret:
# 3.3小节创建的证书名称
secretName: "harbor-kube-uat-certs"
notarySecretName: "harbor-kube-uat-certs"
ingress:
hosts:
# 将要使用的域名
core: harbor.kube.uat
notary: notary.kube.uat
controller: default
# web 页面访问的 URL
externalURL: https://harbor.kube.uat
#PV 配置
persistence:
enabled: true
resourcePolicy: "keep"
persistentVolumeClaim:
registry:
existingClaim: ""
# 3.4创建的 storageClass,下面的几个配置要相同
storageClass: "harbor-rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
# 存储资源要占用的大小,根据需求修改
size: 20Gi
chartmuseum:
existingClaim: ""
storageClass: "harbor-rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
size: 20Gi
jobservice:
existingClaim: ""
storageClass: "harbor-rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
size: 4Gi
database:
existingClaim: ""
storageClass: "harbor-rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
size: 4Gi
redis:
existingClaim: ""
storageClass: "harbor-rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
size: 4Gi
trivy:
existingClaim: ""
storageClass: "harbor-rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
size: 20Gi
imageChartStorage:
disableredirect: false
type: filesystem
filesystem:
rootdirectory: /storage
imagePullPolicy: IfNotPresent
imagePullSecrets:
updateStrategy:
type: RollingUpdate
logLevel: info
# 登录 Harbor 使用的密码,用户名是 admin
harborAdminPassword: "Harbor12345"
3.5.2 执行部署
helm -n harbor install kube /etc/kubernetes/gitlab/harbor-helm/ -f /etc/kubernetes/gitlab/harbor-helm/value.yaml
3.6 WEB、k8s 及终端登录 harbor
Harbor 内部使用 SSl 加密认证,一般在内网的做法是把 harbor 的 URL 添加到 docker daemon.json 的 insecure-registry 字段中,这样做会有安全隐患,我使用的方法是,把 Harbor 使用的 CA 证书添加到系统里。
3.6.1 获取证书
可以登录到 dashboard 到 harbor 的 secret 中找到 ingress 所使用的证书进行查看保存,或者登录到 harbor 的 WEB 端,在项目里下载 CA 证书,这里使用命令行直接获取。
kubectl -n harbor get secret $(kubectl -n harbor get secrets |grep ingress |awk '{print $1}') -oyaml |grep ^' ca.crt'| awk '{print $2}'|base64 --decode > ca.crt
3.6.2 Web 端登录 harbor
将刚刚保存的 ca.crt
证书,安装到系统中,详见快速搭建Kubernetes高可用集群三 Ingress、Dashboard、Metrics-server的4.4.4 证书应用小节。
使用浏览器打开前面设置的域名 https://harbor.kube.uat,然后使用配置文件里设置的用户名密码登录Harbor服务。
3.6.3 终端登录 harbor
在终端中,特别是没有安装桌面应用的 Linux 等终端中,无法像桌面系统那样直接安装,那么登录时将会出现 x509: certificate signed by unknown authority 的错误
在此需要将证书直接放入指定目录。即 docker 配置文件目录下,以 harbor 的域名命名的目录中,由于后期所有节点都需要在自建 Harbor 中拉取镜像,所以我们要在所有节点添加此文件。
# 创建目录
mkdir -p /etc/docker/certs.d/harbor.kube.uat
# 写入证书文件
echo 'ca-zhengshu-neirong' > /etc/docker/certs.d/harbor.kube.uat/ca.crt
# 使用 docke login 命令登录
docker login -uadmin -pHarbor12345 harbor.kube.uat
3.6.4 Kubernetes 中使用 自建 Harbor
在执行完上一步,可以正常登录后,就可以使用 Kubernetes 访问 Harbor 了,但是访问过程中需要输入账号密码,所以需要对部署服务的 yaml 文件做适当修改。为 image 添加 imagePullSecrets 字段。
3.6.4.1 创建 secret
kubectl -n test create secret docker-registry registry-secret \
--docker-server harbor.kube.uat \
--docker-username=admin \
--docker-password=Harbor12345
命令或参数 | 说明 |
---|---|
-n test | 要拉取镜像的 namespace |
docker-registry registry-secret | 要创建的 secret 名称,docker-registry:类型,registry-secret:任意名称 |
–docker-server harbor.kube.uat | harbor的域名 |
–docker-username=admin | harbor 用户名 |
–docker-password=Harbor12345 | harbor 密码 |
3.6.4.2 kubernetes 中拉取 image
测试示例: data-approve-charge-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: data-approve-charge-deployment
labels:
appname: data-approve-charge
spec:
replicas: 3
selector:
matchLabels:
appname: data-approve-charge
template:
metadata:
labels:
appname: data-approve-charge
spec:
containers:
- name: data-approve-charge
image: harbor.kube.uat/approve/data-approve-charge:0.0.3 #镜像地址
ports:
- containerPort: 80
imagePullSecrets: #使用的secret
- name: registry-secret
测试一下
kubectl apply -f data-approve-charge-test.yaml -n test
至此,Harbor 已经搭建完毕可以正常使用了。
四、 文章引用
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 long@longger.xin