1. 创建持久卷供Halo进行持久化
Halo服务,涉及到本地存储,比如说Halo的插件,需要保存到~/.halo2路径下,因此我们需要找一个地方存放文件,供Halo进行访问。
1.1 安装NFS服务器供文件共享
(1) 安装NFS Sever
对于NFS服务器的安装,可以在独立的NFS服务器的机器安装(生产环境推荐使用),也可以在Master节点或者Worker节点上进行安装(不推荐生产环境使用,平时测试的话随便找个节点安装都行)。
使用如下的命令进行NFS服务器的安装:
sudo apt update
sudo apt install nfs-kernel-server -y # 对于 Debian/Ubuntu 系列
# 或
sudo yum install nfs-utils -y # 对于 CentOS/RHEL 系列
在NFS服务器端创建共享目录,并给予共享文件夹相关的权限,这决定了容器挂载NFS卷时,对于资源有哪些访问权限。
# 创建共享文件夹
sudo mkdir -p /nfssharedata
# 收取权限
sudo chmod 755 /nfssharedata
sudo chown nobody:nogroup /nfssharedata # 对于 Ubuntu/Debian
# 或
sudo chown nfsnobody:nfsnobody /nfssharedata # 对于 CentOS/RHEL
编辑NFS的配置文件/etc/exports
文件,添加共享配置信息
sudo vim /etc/exports
例如如下的配置,配置了允许3个IP可以进行访问(将${ip}
的占位符替换成为允许外部访问的IP即可)。其中:rw 表示读写权限,sync 表示将数据同步写入磁盘,no_subtree_check 用于提高性能。
/nfssharedata ${ip1}(rw,sync,no_subtree_check)
/nfssharedata ${ip2}(rw,sync,no_subtree_check)
/nfssharedata ${ip3}(rw,sync,no_subtree_check)
应用NFS服务器暴露的文件夹的配置,执行这个命令可以让我们修改的/etc/exports
配置文件及时生效。
sudo exportfs -ra # 应用配置
启动NFS服务器。
sudo systemctl start nfs-kernel-server # 对于 Ubuntu/Debian
# 或
sudo systemctl start nfs-server # 对于 CentOS/RHEL
设置NFS服务器开机自启动,保证服务器在开机时就自动将NFS服务自动起来,不然NFS服务挂了,就算NFS服务器重启,其他依赖NFS的服务都会起不来。
sudo systemctl enable nfs-kernel-server # Ubuntu/Debian
# 或
sudo systemctl enable nfs-server # CentOS/RHEL
安装rpcbind。
# 安装 rpcbind
sudo apt update
sudo apt install rpcbind -y # Ubuntu/Debian
sudo yum install rpcbind -y # CentOS/RHEL
# 启动 rpcbind 服务
sudo systemctl start rpcbind
sudo systemctl enable rpcbind
执行完上述的操作之后,nfs-server会在2049端口启动,rpcbind会在111端口启动,注意在防火墙当中放行这两个端口。
可以找一个客户端,去安装NFS服务的软件,并尝试进行连接,将NFS服务器共享的路径挂载到本地进行测试。
(2) NFS客户端的安装
我们执行下面的命令去安装NFS客户端。
sudo apt install nfs-common -y # Ubuntu/Debian
# 或
sudo yum install nfs-utils -y # CentOS/RHEL
执行下面的命令去安装rpcbind
# 安装 rpcbind
sudo apt update
sudo apt install rpcbind -y # Ubuntu/Debian
sudo yum install rpcbind -y # CentOS/RHEL
# 启动 rpcbind 服务
sudo systemctl start rpcbind
sudo systemctl enable rpcbind
在NFS客户端挂载NFS服务器文件夹。
# 创建本地用于挂载NFS服务器的目录
sudo mkdir -p /nfssharedata
# 将NFS服务器的/nfssharedata地址,挂载到本地的/nfssharedata
sudo mount <NFS服务器IP地址>:/nfssharedata /nfssharedata
可以通过下面的命令执行,取消挂载NFS服务器文件夹。
sudo umount /nfssharedata
1.2 创建持久卷(PV)
编写PV持久卷资源清单nfs-pv.yaml
,我们去定义一个持久卷PV,去连接NFS服务器作为一个持久卷,使用kubectl apply -f nfs-pv.yaml
去生效。
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 5Gi # 根据需要调整存储大小
accessModes:
- ReadWriteMany # NFS 通常使用 ReadWriteMany 访问模式
nfs:
path: /nfssharedata # NFS 服务器上共享的目录路径
server: ...... # NFS 服务器的 IP 地址
1.3 创建持久卷申请(PVC)
定义如下的K8S的持久卷申请PVC的资源清单nfs-pvc.yaml
,尝试去申请刚刚我们创建出来的持久卷。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
namespace: wanna-project
spec:
accessModes:
- ReadWriteMany # 确保与 PV 的访问模式匹配
resources:
requests:
storage: 5Gi # 请求的存储大小
后续,我们创建Deployment时,会使用到这个定义的PVC的配置。
2. 创建Deployment部署Halo服务
需要注意的是:虽然使用Deployment进行部署Halo服务,但是Halo天生不支持多机分布式部署,只能部署单实例!!!也就是replicas: 1
。
2.1 使用Docker拉取镜像到本地Harbor仓库(选做)
首先,我们将Halo镜像拉到私有Harbor仓库。这一步并不是必须做的,可以在K8S的Deployment当中配置镜像时,直接配置registry.fit2cloud.com/halo/halo:2.20
就行。
docker pull registry.fit2cloud.com/halo/halo:2.20
使用docker images查看本地镜像情况:
root@ecm-4fe6:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.fit2cloud.com/halo/halo 2.20 a9006b2ae07e 3 days ago 414MB
127.0.0.1:84/library/redis latest f02a7f566928 3 weeks ago 117MB
redis latest f02a7f566928 3 weeks ago 117MB
127.0.0.1:84/library/nginx latest 3b25b682ea82 3 weeks ago 192MB
nginx latest 3b25b682ea82 3 weeks ago 192MB
goharbor/chartmuseum-photon v1.10.19 222e01a0c4f8 6 weeks ago 177MB
goharbor/redis-photon v1.10.19 8abbe7c628db 6 weeks ago 148MB
goharbor/clair-adapter-photon v1.10.19 1f856e990872 6 weeks ago 81.9MB
goharbor/clair-photon v1.10.19 0ccce83decfa 6 weeks ago 181MB
goharbor/notary-server-photon v1.10.19 fe7aae6b169d 6 weeks ago 119MB
goharbor/notary-signer-photon v1.10.19 ca2cfca2baf4 6 weeks ago 116MB
goharbor/harbor-registryctl v1.10.19 fc4186073195 6 weeks ago 109MB
goharbor/registry-photon v1.10.19 b5dc0c94b21e 6 weeks ago 92.1MB
goharbor/nginx-photon v1.10.19 4b6a3a04832e 6 weeks ago 122MB
goharbor/harbor-log v1.10.19 08fa03691200 6 weeks ago 133MB
goharbor/harbor-jobservice v1.10.19 1b5aca7f4143 6 weeks ago 97.8MB
goharbor/harbor-core v1.10.19 85627df50bd9 6 weeks ago 91.6MB
goharbor/harbor-portal v1.10.19 e72ed626ae05 6 weeks ago 130MB
goharbor/harbor-db v1.10.19 c038e2ac8cb3 6 weeks ago 213MB
goharbor/prepare v1.10.19 3abb30b0d645 6 weeks ago 170MB
打tag并push到私有镜像仓库。
docker tag registry.fit2cloud.com/halo/halo:2.20 127.0.0.1:84/library/halo:2.20
docker push 127.0.0.1:84/library/halo
1.2 创建Deployment部署Halo服务Pod
kind: Deployment
apiVersion: apps/v1
metadata:
name: halo-dep
namespace: wanna-project
creationTimestamp: '2024-10-30T20:22:00Z'
labels:
app: halo-dep
annotations:
deployment.kubernetes.io/revision: '60'
kubesphere.io/alias-name: halo-dep
kubesphere.io/creator: admin
kubesphere.io/description: halo-dep
spec:
replicas: 1
selector:
matchLabels:
app: halo-dep
template:
metadata:
creationTimestamp: null
labels:
app: halo-dep
annotations:
kubesphere.io/creator: admin
kubesphere.io/imagepullsecrets: '{"halo-dep-riiqgv":"wanna-project-harbor"}'
kubesphere.io/restartedAt: '2024-11-01T19:47:02.315Z'
logging.kubesphere.io/logsidecar-config: '{}'
spec:
volumes:
- name: host-time
hostPath:
path: /etc/localtime
type: ''
- name: volume-d89mhc
configMap:
name: halo-application-prod
defaultMode: 420
- name: volume-nfs
persistentVolumeClaim:
claimName: nfs-pvc
containers:
- name: halo-dep-riiqgv
image: 'wanna1314y.top:1443/library/halo:2.20'
command:
- /bin/sh
- '-c'
args:
- >-
java ${JVM_OPTS}
org.springframework.boot.loader.launch.JarLauncher ${0} ${@}
--spring.profiles.active=prod
--spring.config.additional-location=optional:/halo/config/application-prod.properties
ports:
- name: tcp-8090
containerPort: 8090
protocol: TCP
env:
- name: HALO_WORK_DIR
value: /halo/nfssharedata/.halo2
resources: {}
volumeMounts:
- name: host-time
readOnly: true
mountPath: /etc/localtime
- name: volume-d89mhc
readOnly: true
mountPath: /halo/config/application-prod.properties
subPath: application-prod.properties
- name: volume-nfs
mountPath: /halo/nfssharedata
livenessProbe:
httpGet:
path: /actuator/health
port: 8090
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 5
periodSeconds: 30
successThreshold: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health
port: 8090
scheme: HTTP
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 15
successThreshold: 1
failureThreshold: 3
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: IfNotPresent
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
serviceAccountName: default
serviceAccount: default
securityContext: {}
imagePullSecrets:
- name: wanna-project-harbor
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600
我们定义了如下内容,去定义需要使用到的PVC成为一个卷Volume,其中的claimName
需要和上面我们定义的PVC的name一致,也就是nfs-pvc
。
volumes:
- name: volume-nfs
persistentVolumeClaim:
claimName: nfs-pvc
在container当中,我们定义了如下的挂载卷信息,通过name指定卷的名称,通过mountPath则指定我们想要将卷挂载到Pod的哪个路径。
volumeMounts:
- name: volume-nfs
mountPath: /halo/nfssharedata
3. 创建Service提供服务发现
创建halo-service
对外提供Halo服务的访问,Deployment在本地部署了一个集群,但是不能外部访问,我们需要通过NodePort的方式,让宿主机(Worker)去暴露一个端口号,才能进行外部的访问。
kind: Service
apiVersion: v1
metadata:
name: halo-service
namespace: wanna-project
labels:
app: halo-service
annotations:
kubesphere.io/alias-name: halo-service
kubesphere.io/creator: admin
kubesphere.io/description: halo-service
spec:
ports:
- name: http-8090
protocol: TCP
port: 8090
targetPort: 8090
selector:
app: halo-dep
type: ClusterIP
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 86400
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
internalTrafficPolicy: Cluster