发布时间:2023-11-01 08:30
推荐阅读
Helm3(K8S 资源对象管理工具)视频教程:https://edu.csdn.net/course/detail/32506
Helm3(K8S 资源对象管理工具)博客专栏:https://blog.csdn.net/xzk9381/category_10895812.html
本文原文链接:https://blog.csdn.net/xzk9381/article/details/109535821,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。
本文搭建的 SonarQube 版本是 7.4.9-community,由于在官方文档中声明 7.9 版本之后就不再支持使用 MySQL 数据库。所以此次搭建使用的数据库是 PostgreSQL 11.4 版本。
将 PostgreSQL 和 SonarQube 放在同一个命名空间 ns-sonar 中,创建命名空间的 yaml 文件如下:
---
apiVersion: v1
kind: Namespace
metadata:
name: ns-sonar
labels:
name: ns-sonar
为了实现 PostgreSQL 数据的持久化存储,需要将数据存放在本地存储中。首先在宿主机的 /opt/ops_ceph_data 目录下创建如下目录:
mkdir -p /opt/ops_ceph_data/sonarqube/{PostgreSQL_data,sonar}
在我的机器环境中,/opt/ops_ceph_data 是挂载的 cephfs 文件系统,所以在任意节点上创建目录后,其他节点上都会存在。这也保证了 PostgreSQL 容器可以在任意节点上进行漂移。
同时由于我是将 cephfs 直接挂载到物理机上,所以在下面创建 pv 的时候,指定的存储类型是 local。
如果希望学习如何搭建 Ceph 集群,可以参考我的另一篇博文:CentOS 7 搭建 Ceph 集群(nautilus 版本)
创建 PV 和 PVC 的 yaml 文件内容如下:
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgresql-pv
namespace: ns-sonar
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 5Gi
local:
path: /opt/ops_ceph_data/sonarqube/PostgreSQL_data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: sonar-node
operator: In
values:
- "true"
persistentVolumeReclaimPolicy: Retain
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: postgresql-pvc
namespace: ns-sonar
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
由于上面配置的 PV 存储类型是 local,所以需要在允许运行 PostgreSQL 容器的 Node 上设置 labels,labels 为 sonar-node=true
,这里我是将所有的 Node 节点上都添加了这个 label,命令如下:
for i in 1 2 3 4 5
do
kubectl label nodes k8s-node${i} sonar-node=true
done
注意,PV 中配置的 matchExpressions 一定要与 labels 一致,不然会无法匹配。
接下来需要配置用于映射 PostgreSQL 容器端口的 Service 文件,这里我使用 NodePort 类型,yaml 文件内容如下:
---
apiVersion: v1
kind: Service
metadata:
name: postgresql-service
namespace: ns-sonar
labels:
app: postgresql
spec:
type: NodePort
ports:
- port: 5432
targetPort: 5432
nodePort: 30543
protocol: TCP
selector:
app: postgresql
因为我搭建的环境中,PostgreSQL 使用的单点模式,所以直接使用 Deployment 类型来创建 Pod,yaml 文件内容如下:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgresql
namespace: ns-sonar
labels:
app: postgresql
spec:
replicas: 1
selector:
matchLabels:
app: postgresql
template:
metadata:
labels:
app: postgresql
spec:
containers:
- name: postgresql-for-sonar
image: postgres:11.4
imagePullPolicy: "IfNotPresent"
ports:
- containerPort: 5432
env: # 这里设置 PostgreSQL 启动时候所需要的环境变量
- name: POSTGRES_DB # 定义要创建的数据库名称
value: sonarDB
- name: POSTGRES_USER # 定义要创建访问数据库的用户
value: sonarUser
- name: POSTGRES_PASSWORD # 定义数据库的密码
value: sonar_admin
resources:
limits:
cpu: 1000m
memory: 2048Mi
requests:
cpu: 500m
memory: 1024Mi
volumeMounts:
- mountPath: /var/lib/postgresql/data # 这个目录是 PostgreSQL 容器内默认的数据存储路径
name: postgredb
volumes:
- name: postgredb
persistentVolumeClaim:
claimName: postgresql-pvc # 将上面创建的 PVC 挂载到 PostgreSQL 的数据目录下
在环境变量设置的部分,我一开始使用的是引用 Secret 的方式,但是在容器启动后没有正确创建用户和密码。所以还是使用了直接指定 value 的方式。具体为什么 Secret 没有生效现在还不清楚,后续查出原因后再补充。
使用容器搭建 PostgreSQL 服务,默认会在容器内监听 0.0.0.0 地址,所以像传统方式部署那样去手动修改监听地址。
在其他机器中验证连接 PostgreSQL,IP 地址为任意 Node 节点 IP。用户名密码和数据库名称参考上面的 yaml 文件。测试是否可以正常连接即可。
用于 SonarQube 的持久化存储目录已经在前面创建好了,下面直接编写 yaml 文件,内容如下:
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: sonar-pv
namespace: ns-sonar
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 20Gi
local:
path: /opt/ops_ceph_data/sonarqube/sonar_data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: sonar-node
operator: In
values:
- "true"
persistentVolumeReclaimPolicy: Retain
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: sonar-pvc
namespace: ns-sonar
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
需要注意的是,PV 中匹配的 labels 已经在前面创建好了,所以此处不需要重复设置 labels。
另外 SonarQube 容器运行的时候,不是以 root 用户运行的,所以需要确保挂载的目录要允许其他用户读写,否则容器启动会失败。
chmod -R 777 /opt/ops_ceph_data/sonarqube/sonar_data
本文原文链接:https://blog.csdn.net/xzk9381/article/details/109535821,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。
使用 NodePort 类型将 SonarQube 端口映射出来,yaml 文件内容如下:
---
apiVersion: v1
kind: Service
metadata:
name: sonarqube-service
labels:
app: sonarqube-service
spec:
type: NodePort
ports:
- port: 9000
targetPort: 9000
nodePort: 30900
protocol: TCP
selector:
app: sonarqube
SonarQube 的 Pod 使用 Deployment 来创建,yaml 文件内容如下:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sonarqube
namespace: ns-sonar
labels:
app: sonarqube
spec:
replicas: 1
selector:
matchLabels:
app: sonarqube
template:
metadata:
labels:
app: sonarqube
spec:
initContainers: # 设置初始化镜像,用于执行 system 命令,此处的配置在下文会有说明
- name: init-sysctl
image: busybox
imagePullPolicy: IfNotPresent
command: ["sysctl", "-w", "vm.max_map_count=262144"] # 设置vm.max_map_count这个值调整内存权限,否则启动可能报错
securityContext:
privileged: true # 设置可以以 root 权限执行命令
containers:
- name: sonarqube
image: sonarqube:7.9.4-community
ports:
- containerPort: 9000
env:
- name: SONARQUBE_JDBC_USERNAME # 设置 SonarQube 连接数据库使用的用户名
value: sonarUser
- name: SONARQUBE_JDBC_PASSWORD # 设置 SonarQube 连接数据库使用的密码
value: sonar_admin
- name: SONARQUBE_JDBC_URL # 设置 SonarQube 连接数据库使用的地址
value: "jdbc:postgresql://10.16.12.206:30543/sonarDB" # 这里可以指定 Node 节点的 IP 地址和 PostgreSQL 映射出来的端口
livenessProbe: # 设置容器存活检查策略,如果失败将杀死容器,然后根据 Pod 的 restartPolicy 来决定是否进行重启操作
httpGet:
path: /sessions/new
port: 9000
initialDelaySeconds: 60 # 设置在容器启动多长时间后开始探针检测,此处设置为 60s
periodSeconds: 30 # 设置探针检查的频率,此处设置为每 30s 检查一次
readinessProbe: # 设置容器的就绪检查策略,查看容器是否准备好接受 HTTP 请求
httpGet:
path: /sessions/new
port: 9000
initialDelaySeconds: 60 # 设置在容器启动多长时间后开始探针检测,此处设置为 60s
periodSeconds: 30 # 设置探针检查的频率,此处设置为每 30s 检查一次
failureThreshold: 6 # 在检查失败的情况下,重复检查的次数,此处设置为 6
resources:
limits:
cpu: 2000m
memory: 2048Mi
requests:
cpu: 1000m
memory: 1024Mi
volumeMounts:
- mountPath: /opt/sonarqube/conf
name: sonarqube
subPath: conf # 使用 subPath 在宿主机的挂载目录上设置一个子目录,用于存放上面指定目录的数据
- mountPath: /opt/sonarqube/data
name: sonarqube
subPath: data
- mountPath: /opt/sonarqube/extensions
name: sonarqube
subPath: extensions
volumes:
- name: sonarqube
persistentVolumeClaim:
claimName: sonar-pvc #绑定上面创建的 PVC
对于上面的 yaml 文件有些配置需要进行如下说明。
initContainers 就是初始化容器,也就是在主容器启动之前,首先启动初始化容器。如果有多个初始化容器,会按照定义的顺序依次启动。只有在初始化容器启动完成后,主容器才会启动。
使用初始化容器有如下几个作用:
需要注意的是,initContainers 是以 sideCar 模式运行在 Pod 中的。
关于健康检查策略,上面的 yaml 文件中已经给出了一些注释。其他的配置项可以参考官网文档:配置存活探针和就绪探针
上面的 yaml 文件中在存储挂载的部分使用了 subPath 配置,这是因为 SonarQube 中一共有三个需要挂载的目录:
而宿主机上的存储目录只提供了一个 /opt/ops_ceph_data/sonarqube/sonar_data,默认情况下,以上三个目录的数据都会存储在宿主机这一个目录下,这样就会造成数据混乱,没有办法区分某个数据文件或目录具体是哪个父目录下的。可以使用 subPath 配置解决这个问题,这个配置的功能就是在宿主机的挂载目录下创建一个子目录来存放对应目录的数据。
例如上面的 subPath 配置项分别创建了三个子目录:conf、data、extensions,那么在宿主机的挂载目录下显示的就是如下形式:
[@k8s-master1 ~]# ll /opt/ops_ceph_data/sonarqube/sonar_data/
总用量 0
drwxrwxrwx 1 root root 0 10月 29 11:41 conf
drwxrwxrwx 1 root root 2 10月 29 15:57 data
drwxrwxrwx 1 root root 2 10月 29 16:01 extensions
这三个子目录的名称可以随意指定,上面的 yaml 文件中 subPath 指定的子目录名称与容器中的目录名称一致是为了更方便的区分。如果将 subPath 的配置分别改为:sonar_conf、sonar_data、sonar_extensions,那么在宿主机挂载目录下显示的就会是如下形式:
[@k8s-master1 ~]# ll /opt/ops_ceph_data/sonarqube/sonar_data/
总用量 0
drwxrwxrwx 1 root root 0 10月 29 11:41 sonar_conf
drwxrwxrwx 1 root root 2 10月 29 15:57 sonar_data
drwxrwxrwx 1 root root 2 10月 29 16:01 sonar_extensions
SonarQube 部署完成后,可以通过任意 Node 节点的 IP 地址加上映射的端口访问。
默认的登录用户名和密码均为 admin。登录完成后,首先点击 Administration --> Marketplace ,在 Plugin 部分查找 chinese 插件和 Codehawk Java 进行安装。chinese 插件用于汉化界面,安装完成后需要重启服务(在页面上方会有提示)。
本文原文链接:https://blog.csdn.net/xzk9381/article/details/109535821,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。