Sonar无法通过istio虚拟服务访问,但可以通过端口转发在本地访问
Sonar cannot be access via istio virtual service but can be locally accessed after port forwarding
我正在尝试在 Kubernetes 集群中实施 SonarQube。部署 运行 正确,并且还通过虚拟服务公开。我可以通过 localhost:port/sonar
打开 UI 但我无法通过我的外部 ip 访问它。我知道声纳绑定到本地主机并且不允许从远程服务器外部访问。我 运行 在 GKE 上使用 MYSQL 数据库。这是我的 YAML 文件:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: sonarqube
namespace: sonar
labels:
service: sonarqube
version: v1
spec:
replicas: 1
template:
metadata:
name: sonarqube
labels:
name: sonarqube
spec:
terminationGracePeriodSeconds: 15
initContainers:
- name: volume-permission
image: busybox
command:
- sh
- -c
- sysctl -w vm.max_map_count=262144
securityContext:
privileged: true
containers:
- name: sonarqube
image: sonarqube:6.7
resources:
limits:
memory: 4Gi
cpu: 2
requests:
memory: 2Gi
cpu: 1
args:
- -Dsonar.web.context=/sonar
- -Dsonar.web.host=0.0.0.0
env:
- name: SONARQUBE_JDBC_USERNAME
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: username
- name: SONARQUBE_JDBC_PASSWORD
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: password
- name: SONARQUBE_JDBC_URL
value: jdbc:mysql://***.***.**.*:3306/sonar?useUnicode=true&characterEncoding=utf8
ports:
- containerPort: 9000
name: sonarqube-port
---
apiVersion: v1
kind: Service
metadata:
labels:
service: sonarqube
version: v1
name: sonarqube
namespace: sonar
spec:
selector:
name: sonarqube
ports:
- name: http
port: 80
targetPort: sonarqube-port
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sonarqube-internal
namespace: sonar
spec:
hosts:
- sonarqube.staging.jeet11.internal
- sonarqube
gateways:
- default/ilb-gateway
- mesh
http:
- route:
- destination:
host: sonarqube
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sonarqube-external
namespace: sonar
spec:
hosts:
- sonarqube.staging.jeet11.com
gateways:
- default/elb-gateway
http:
- route:
- destination:
host: sonarqube
---
部署成功完成。我公开的服务提供了一个映射到主机 url 的 public ip,但我无法访问主机 url 上的服务。
我需要更改映射,以便声纳与服务器 ip 绑定,但我无法理解该怎么做。我无法将它绑定到我的集群 ip,也不能绑定到我的内部或外部服务 ip。
我该怎么办?请帮忙!
不要传递参数只是尝试 运行 没有它曾经为我工作。
我的部署文件就是这样希望对你有帮助
apiVersion: v1
kind: Service
metadata:
name: sonarqube-service
spec:
selector:
app: sonarqube
ports:
- protocol: TCP
port: 9000
targetPort: 9000
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: sonarqube
name: sonarqube
spec:
replicas: 1
template:
metadata:
labels:
app: sonarqube
spec:
containers:
- name: sonarqube
image: sonarqube:7.1
resources:
requests:
memory: "1200Mi"
cpu: .10
limits:
memory: "2500Mi"
cpu: .50
volumeMounts:
- mountPath: "/opt/sonarqube/data/"
name: sonar-data
- mountPath: "/opt/sonarqube/extensions/"
name: sonar-extensions
env:
- name: "SONARQUBE_JDBC_USERNAME"
value: "root" #Put your db username
- name: "SONARQUBE_JDBC_URL"
value: "jdbc:mysql://192.168.112.4:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true" #DB URL
- name: "SONARQUBE_JDBC_PASSWORD"
value : password
ports:
- containerPort: 9000
protocol: TCP
volumes:
- name: sonar-data
persistentVolumeClaim:
claimName: sonar-data
- name: sonar-extensions
persistentVolumeClaim:
claimName: sonar-extensions
我最近遇到了同样的问题,今天我设法解决了这个问题。
我希望以下解决方案适用于面临相同问题的任何人!
环境
- 云提供商:Azure - AKS
- 无论您使用什么提供商,这都应该有效。
- Istio 版本:1.7.3
- K8版本:1.16.10
工具 - 调试
kubectl logs -n istio-system -l app=istiod
- 来自 Istiod 的日志和控制平面中发生的事件。
istioctl analyze -n <namespace>
- 这通常会为您提供给定命名空间的任何警告和错误。
- 让您知道配置是否有误。
- 基亚利 -
istioctl dashboard kiali
- 查看您是否获得入站流量。
- 另外,显示任何错误配置。
- 普罗米修斯 -
istioctl dashboard prometheus
- 查询指标 -
istio_requests_total
。这会向您显示进入该服务的流量。
- 如果有任何配置错误,您将看到 destination_app 为 unknown.
问题
- 无法通过外部 IP 访问 sonarqube UI,但可通过本地主机 (port-forward) 访问。
- 无法通过 Istio Ingressgateway 路由流量。
解决方案
Sonarqube 服务清单
apiVersion: v1
kind: Service
metadata:
name: sonarqube
namespace: sonarqube
labels:
name: sonarqube
spec:
type: ClusterIP
ports:
- name: http
port: 9000
targetPort: 9000
selector:
app: sonarqube
status:
loadBalancer: {}
- 你的目标端口是容器端口。为避免任何混淆,只需将服务 port 编号分配为与服务 targetport.
相同的编号
- 端口名称在这里非常重要。 “Istio 要求服务端口遵循‘protocol-suffix’的命名形式,其中‘-后缀’部分是可选的”- KIA0601 - Port name must follow [-suffix] form
sonarqube 的 Istio 网关和虚拟服务清单
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: sonarqube-gateway
namespace: sonarqube
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 9000
name: http
protocol: HTTP
hosts:
- "XXXX.XXXX.com.au"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sonarqube
namespace: sonarqube
spec:
hosts:
- "XXXX.XXXX.com.au"
gateways:
- sonarqube-gateway
http:
- route:
- destination:
host: sonarqube
port:
number: 9000
- 网关协议必须设置为HTTP。
- 网关服务器端口和虚拟服务目标端口相同。如果您有不同的应用 服务端口,那么您的 VirtualService 目标端口 号码应该与应用 服务端口 匹配. 网关服务器端口应该匹配应用服务目标端口。
- 现在到了有趣的时刻! 主机。如果你想访问集群外的服务,那么你需要有你的host-name(无论你想映射sonarqube服务器的host-name)作为DNS A记录 映射到 istio-ingressgateway.
的外部 Public IP 地址
- 获取ingressgateway的EXTERNAL-IP地址,运行
kubectl -n istio-system get service istio-ingressgateway
.
- 如果你做一个简单的 nslookup (运行 -
nslookup <hostname>
),你得到的 IP 地址必须与分配给 istio-ingressgateway 服务的 IP 地址匹配。
在 ingressgateway 中公开一个新端口
- 请注意,您的 sonarqube 网关端口是您要引入 Kubernetes 的新端口,您要告诉集群在该端口上侦听。但是您的负载均衡器不知道这个端口。因此,您需要在您的 kubernetes 外部负载均衡器上打开指定的网关端口。参考 - Info
- 您无需手动更改负载均衡器服务。您只需更新入口网关以包含新端口,这将自动更新负载均衡器。
- 您可以通过 运行ning
istioctl analyze -n sonarqube
确定端口是否导致问题。您应该收到以下警告;
[33mWarn[0m [IST0104] (Gateway sonarqube-gateway.sonarqube) The gateway refers to a port that is not exposed on the workload (pod selector istio=ingressgateway; port 9000) Error: Analyzers found issues when analyzing namespace: sonarqube. See https://istio.io/docs/reference/config/analysis for more information about causes and resolutions.
- 您应该在控制平面中得到相应的错误。 运行
kubectl logs -n istio-system -l app=istiod
.
- 此时您需要更新 Istio ingressgateway 服务以公开新端口。 运行
kubectl edit svc istio-ingressgateway -n istio-system
并将以下部分添加到端口。
绕过创建新端口
- 在上一节中,您了解了如何公开新端口。这是可选的,取决于您的用例。
- 在本节中,您将了解如何使用已公开的端口。
- 如果你看istio-ingressgateway的服务。你可以看到有暴露的默认端口。这里我们将使用端口 80.
- 您的设置如下所示;
- 要避免使用您的主机名指定端口,只需添加匹配的 uri 前缀,如虚拟服务清单中所示。
测试时间
- 如果到目前为止一切正常,那么你就可以开始了。
- 在测试过程中,我犯了一个错误,没有指定端口。如果你得到 404 状态,这仍然是一件好事,通过这种方式你可以验证它使用的是什么服务器。如果你设置正确,它应该使用 istio-envoy 服务器,而不是nginx.
- 不指定端口。这仅在您添加匹配 uri 前缀时有效。
我正在尝试在 Kubernetes 集群中实施 SonarQube。部署 运行 正确,并且还通过虚拟服务公开。我可以通过 localhost:port/sonar
打开 UI 但我无法通过我的外部 ip 访问它。我知道声纳绑定到本地主机并且不允许从远程服务器外部访问。我 运行 在 GKE 上使用 MYSQL 数据库。这是我的 YAML 文件:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: sonarqube
namespace: sonar
labels:
service: sonarqube
version: v1
spec:
replicas: 1
template:
metadata:
name: sonarqube
labels:
name: sonarqube
spec:
terminationGracePeriodSeconds: 15
initContainers:
- name: volume-permission
image: busybox
command:
- sh
- -c
- sysctl -w vm.max_map_count=262144
securityContext:
privileged: true
containers:
- name: sonarqube
image: sonarqube:6.7
resources:
limits:
memory: 4Gi
cpu: 2
requests:
memory: 2Gi
cpu: 1
args:
- -Dsonar.web.context=/sonar
- -Dsonar.web.host=0.0.0.0
env:
- name: SONARQUBE_JDBC_USERNAME
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: username
- name: SONARQUBE_JDBC_PASSWORD
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: password
- name: SONARQUBE_JDBC_URL
value: jdbc:mysql://***.***.**.*:3306/sonar?useUnicode=true&characterEncoding=utf8
ports:
- containerPort: 9000
name: sonarqube-port
---
apiVersion: v1
kind: Service
metadata:
labels:
service: sonarqube
version: v1
name: sonarqube
namespace: sonar
spec:
selector:
name: sonarqube
ports:
- name: http
port: 80
targetPort: sonarqube-port
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sonarqube-internal
namespace: sonar
spec:
hosts:
- sonarqube.staging.jeet11.internal
- sonarqube
gateways:
- default/ilb-gateway
- mesh
http:
- route:
- destination:
host: sonarqube
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sonarqube-external
namespace: sonar
spec:
hosts:
- sonarqube.staging.jeet11.com
gateways:
- default/elb-gateway
http:
- route:
- destination:
host: sonarqube
---
部署成功完成。我公开的服务提供了一个映射到主机 url 的 public ip,但我无法访问主机 url 上的服务。
我需要更改映射,以便声纳与服务器 ip 绑定,但我无法理解该怎么做。我无法将它绑定到我的集群 ip,也不能绑定到我的内部或外部服务 ip。
我该怎么办?请帮忙!
不要传递参数只是尝试 运行 没有它曾经为我工作。
我的部署文件就是这样希望对你有帮助
apiVersion: v1
kind: Service
metadata:
name: sonarqube-service
spec:
selector:
app: sonarqube
ports:
- protocol: TCP
port: 9000
targetPort: 9000
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: sonarqube
name: sonarqube
spec:
replicas: 1
template:
metadata:
labels:
app: sonarqube
spec:
containers:
- name: sonarqube
image: sonarqube:7.1
resources:
requests:
memory: "1200Mi"
cpu: .10
limits:
memory: "2500Mi"
cpu: .50
volumeMounts:
- mountPath: "/opt/sonarqube/data/"
name: sonar-data
- mountPath: "/opt/sonarqube/extensions/"
name: sonar-extensions
env:
- name: "SONARQUBE_JDBC_USERNAME"
value: "root" #Put your db username
- name: "SONARQUBE_JDBC_URL"
value: "jdbc:mysql://192.168.112.4:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true" #DB URL
- name: "SONARQUBE_JDBC_PASSWORD"
value : password
ports:
- containerPort: 9000
protocol: TCP
volumes:
- name: sonar-data
persistentVolumeClaim:
claimName: sonar-data
- name: sonar-extensions
persistentVolumeClaim:
claimName: sonar-extensions
我最近遇到了同样的问题,今天我设法解决了这个问题。
我希望以下解决方案适用于面临相同问题的任何人!
环境
- 云提供商:Azure - AKS
- 无论您使用什么提供商,这都应该有效。
- Istio 版本:1.7.3
- K8版本:1.16.10
工具 - 调试
kubectl logs -n istio-system -l app=istiod
- 来自 Istiod 的日志和控制平面中发生的事件。
istioctl analyze -n <namespace>
- 这通常会为您提供给定命名空间的任何警告和错误。
- 让您知道配置是否有误。
- 基亚利 -
istioctl dashboard kiali
- 查看您是否获得入站流量。
- 另外,显示任何错误配置。
- 普罗米修斯 -
istioctl dashboard prometheus
- 查询指标 -
istio_requests_total
。这会向您显示进入该服务的流量。 - 如果有任何配置错误,您将看到 destination_app 为 unknown.
- 查询指标 -
问题
- 无法通过外部 IP 访问 sonarqube UI,但可通过本地主机 (port-forward) 访问。
- 无法通过 Istio Ingressgateway 路由流量。
解决方案
Sonarqube 服务清单
apiVersion: v1
kind: Service
metadata:
name: sonarqube
namespace: sonarqube
labels:
name: sonarqube
spec:
type: ClusterIP
ports:
- name: http
port: 9000
targetPort: 9000
selector:
app: sonarqube
status:
loadBalancer: {}
- 你的目标端口是容器端口。为避免任何混淆,只需将服务 port 编号分配为与服务 targetport. 相同的编号
- 端口名称在这里非常重要。 “Istio 要求服务端口遵循‘protocol-suffix’的命名形式,其中‘-后缀’部分是可选的”- KIA0601 - Port name must follow [-suffix] form
sonarqube 的 Istio 网关和虚拟服务清单
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: sonarqube-gateway
namespace: sonarqube
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 9000
name: http
protocol: HTTP
hosts:
- "XXXX.XXXX.com.au"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sonarqube
namespace: sonarqube
spec:
hosts:
- "XXXX.XXXX.com.au"
gateways:
- sonarqube-gateway
http:
- route:
- destination:
host: sonarqube
port:
number: 9000
- 网关协议必须设置为HTTP。
- 网关服务器端口和虚拟服务目标端口相同。如果您有不同的应用 服务端口,那么您的 VirtualService 目标端口 号码应该与应用 服务端口 匹配. 网关服务器端口应该匹配应用服务目标端口。
- 现在到了有趣的时刻! 主机。如果你想访问集群外的服务,那么你需要有你的host-name(无论你想映射sonarqube服务器的host-name)作为DNS A记录 映射到 istio-ingressgateway. 的外部 Public IP 地址
- 获取ingressgateway的EXTERNAL-IP地址,运行
kubectl -n istio-system get service istio-ingressgateway
. - 如果你做一个简单的 nslookup (运行 -
nslookup <hostname>
),你得到的 IP 地址必须与分配给 istio-ingressgateway 服务的 IP 地址匹配。
在 ingressgateway 中公开一个新端口
- 请注意,您的 sonarqube 网关端口是您要引入 Kubernetes 的新端口,您要告诉集群在该端口上侦听。但是您的负载均衡器不知道这个端口。因此,您需要在您的 kubernetes 外部负载均衡器上打开指定的网关端口。参考 - Info
- 您无需手动更改负载均衡器服务。您只需更新入口网关以包含新端口,这将自动更新负载均衡器。
- 您可以通过 运行ning
istioctl analyze -n sonarqube
确定端口是否导致问题。您应该收到以下警告;
[33mWarn[0m [IST0104] (Gateway sonarqube-gateway.sonarqube) The gateway refers to a port that is not exposed on the workload (pod selector istio=ingressgateway; port 9000) Error: Analyzers found issues when analyzing namespace: sonarqube. See https://istio.io/docs/reference/config/analysis for more information about causes and resolutions.
- 您应该在控制平面中得到相应的错误。 运行
kubectl logs -n istio-system -l app=istiod
. - 此时您需要更新 Istio ingressgateway 服务以公开新端口。 运行
kubectl edit svc istio-ingressgateway -n istio-system
并将以下部分添加到端口。
绕过创建新端口
- 在上一节中,您了解了如何公开新端口。这是可选的,取决于您的用例。
- 在本节中,您将了解如何使用已公开的端口。
- 如果你看istio-ingressgateway的服务。你可以看到有暴露的默认端口。这里我们将使用端口 80.
- 您的设置如下所示;
- 要避免使用您的主机名指定端口,只需添加匹配的 uri 前缀,如虚拟服务清单中所示。
测试时间
- 如果到目前为止一切正常,那么你就可以开始了。
- 在测试过程中,我犯了一个错误,没有指定端口。如果你得到 404 状态,这仍然是一件好事,通过这种方式你可以验证它使用的是什么服务器。如果你设置正确,它应该使用 istio-envoy 服务器,而不是nginx.
- 不指定端口。这仅在您添加匹配 uri 前缀时有效。