时间:2020-10-29来源:www.pcxitongcheng.com作者:电脑系统城
本文搭建的 SonarQube 版本是 7.4.9-community,由于在官方文档中声明 7.9 版本之后就不再支持使用 MySQL 数据库。所以此次搭建使用的数据库是 PostgreSQL 11.4 版本。
将 PostgreSQL 和 SonarQube 放在同一个命名空间 ns-sonar 中,创建命名空间的 yaml 文件如下:
Copy
--- |
|
apiVersion: v1 |
|
kind: Namespace |
|
metadata: |
|
name: ns-sonar |
|
labels: |
|
name: ns-sonar |
为了实现 PostgreSQL 数据的持久化存储,需要将数据存放在本地存储中。首先在宿主机的 /opt/ops_ceph_data 目录下创建如下目录:
Copy
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 文件内容如下:
Copy
--- |
|
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,命令如下:
Copy
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 文件内容如下:
Copy
--- |
|
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 文件内容如下:
Copy
--- |
|
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 文件,内容如下:
Copy
--- |
|
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 用户运行的,所以需要确保挂载的目录要允许其他用户读写,否则容器启动会失败。
Copy
chmod -R 777 /opt/ops_ceph_data/sonarqube/sonar_data
使用 NodePort 类型将 SonarQube 端口映射出来,yaml 文件内容如下:
Copy
--- |
|
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 文件内容如下:
Copy
--- |
|
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,那么在宿主机的挂载目录下显示的就是如下形式:
Copy
[@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,那么在宿主机挂载目录下显示的就会是如下形式:
Copy
[@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 插件用于汉化界面,安装完成后需要重启服务(在页面上方会有提示)。
2024-07-18
Centos 7 二进制安装配置 MariaDB数据库2024-07-18
Centos7默认firewalld防火墙使用命令大全2024-07-07
四种执行python系统命令的方法常用权限linux系统内有档案有三种身份 u:拥有者 g:群组 o:其他人这些身份对于文档常用的有下面权限:r:读权限,用户可以读取文档的内容,如用cat,more查看w:写权限,用户可以编辑文档x...
2024-07-07
然而,如果我们遵循通常的 WordPress 最佳实践,这些安全问题可以避免。在本篇中,我们会向你展示如何使用 WPSeku,一个 Linux 中的 WordPress 漏洞扫描器,它可以被用来找出你安装...
2024-07-03