Skip to content

Monitoring exporter improvements, including port configuration, Istio support, and validation #2390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions documentation/domains/Domain.json
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,10 @@
"x-kubernetes-preserve-unknown-fields": "true",
"description": "The configuration for the WebLogic Monitoring Exporter. If WebLogic Server instances are already running and have the monitoring exporter sidecar container, then changes to this field will be propagated to the exporter without requiring the restart of the WebLogic Server instances.",
"$ref": "#/definitions/Map"
},
"port": {
"description": "The port exposed by the WebLogic Monitoring Exporter running in the sidecar container. Defaults to 8080. The port value must not conflict with a port used by any WebLogic Server instance, including the ports of built-in channels or network access points (NAPs).",
"type": "number"
}
}
},
Expand Down
1 change: 1 addition & 0 deletions documentation/domains/Domain.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ The current status of the operation of the WebLogic domain. Updated automaticall
| `configuration` | Map | The configuration for the WebLogic Monitoring Exporter. If WebLogic Server instances are already running and have the monitoring exporter sidecar container, then changes to this field will be propagated to the exporter without requiring the restart of the WebLogic Server instances. |
| `image` | string | The WebLogic Monitoring Exporter sidecar container image name. Defaults to ghcr.io/oracle/weblogic-monitoring-exporter:2.0.2 |
| `imagePullPolicy` | string | The image pull policy for the WebLogic Monitoring Exporter sidecar container image. Legal values are Always, Never, and IfNotPresent. Defaults to Always if image ends in :latest; IfNotPresent, otherwise. |
| `port` | number | The port exposed by the WebLogic Monitoring Exporter running in the sidecar container. Defaults to 8080. The port value must not conflict with a port used by any WebLogic Server instance, including the ports of built-in channels or network access points (NAPs). |

### Server Pod

Expand Down
4 changes: 4 additions & 0 deletions documentation/domains/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1539,6 +1539,10 @@
"x-kubernetes-preserve-unknown-fields": "true",
"description": "The configuration for the WebLogic Monitoring Exporter. If WebLogic Server instances are already running and have the monitoring exporter sidecar container, then changes to this field will be propagated to the exporter without requiring the restart of the WebLogic Server instances.",
"$ref": "#/definitions/Map"
},
"port": {
"description": "The port exposed by the WebLogic Monitoring Exporter running in the sidecar container. Defaults to 8080 unless that port value is in use by a channel or network access point (NAP) of the WebLogic Server instance, in which case the next higher available port is selected. If a port value is specified then it must not conflict with a port used by the WebLogic Server instance.",
"type": "number"
}
}
},
Expand Down
9 changes: 8 additions & 1 deletion kubernetes/crd/domain-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
weblogic.sha256: e091b25f525f2d1a6b90729dcee23d63ead5beb23660912acebf921d1c0499a7
weblogic.sha256: d1191a10f1c4843d11c897002f731292c9f580c6670a84e1ee8b5916e21f0a62
name: domains.weblogic.oracle
spec:
group: weblogic.oracle
Expand Down Expand Up @@ -59,6 +59,13 @@ spec:
restart of the WebLogic Server instances.
type: object
x-kubernetes-preserve-unknown-fields: true
port:
description: The port exposed by the WebLogic Monitoring Exporter
running in the sidecar container. Defaults to 8080. The port
value must not conflict with a port used by any WebLogic Server
instance, including the ports of built-in channels or network
access points (NAPs).
type: number
type: object
configuration:
description: Models and overrides affecting the WebLogic domain configuration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@
import oracle.kubernetes.operator.logging.LoggingFactory;
import oracle.kubernetes.operator.logging.MessageKeys;
import oracle.kubernetes.operator.steps.DefaultResponseStep;
import oracle.kubernetes.operator.wlsconfig.WlsClusterConfig;
import oracle.kubernetes.operator.wlsconfig.WlsDomainConfig;
import oracle.kubernetes.operator.wlsconfig.WlsDynamicServersConfig;
import oracle.kubernetes.operator.wlsconfig.WlsServerConfig;
import oracle.kubernetes.operator.work.NextAction;
import oracle.kubernetes.operator.work.Packet;
import oracle.kubernetes.operator.work.Step;
Expand Down Expand Up @@ -192,6 +195,16 @@ private void validate(DomainPresenceInfo info, WlsDomainConfig wlsDomainConfig)
// in the WebLogic domain
domainSpec.getManagedServers().forEach(
s -> warnIfServerDoesNotExist(wlsDomainConfig, s.getServerName(), info));

// log warning if monitoring exporter port is specified and it conflicts with a server port
Optional.ofNullable(domainSpec.getMonitoringExporterPort()).ifPresent(port -> {
wlsDomainConfig.getServerConfigs().values()
.forEach(server -> warnIfMonitoringExporterPortConflicts(port, server, info));
wlsDomainConfig.getClusterConfigs().values()
.forEach(cluster -> Optional.ofNullable(cluster.getDynamicServersConfig())
.map(WlsDynamicServersConfig::getServerTemplate)
.ifPresent(template -> warnIfMonitoringExporterPortConflicts(port, cluster, template, info)));
});
}

private void warnIfClusterDoesNotExist(WlsDomainConfig domainConfig,
Expand All @@ -208,6 +221,43 @@ private void warnIfServerDoesNotExist(WlsDomainConfig domainConfig,
}
}

private void warnIfMonitoringExporterPortConflicts(
Integer port, WlsServerConfig serverConfig, DomainPresenceInfo info) {
warnIfMonitoringExporterPortConflicts(port, null, serverConfig, info);
}

private void warnIfMonitoringExporterPortConflicts(
Integer port, WlsClusterConfig cluster, WlsServerConfig serverConfig, DomainPresenceInfo info) {

if (port.equals(serverConfig.getListenPort())) {
logAndAddValidationWarningExporter(port, cluster, serverConfig, serverConfig.getListenPort(), info);
}
if (port.equals(serverConfig.getSslListenPort())) {
logAndAddValidationWarningExporter(port, cluster, serverConfig, serverConfig.getSslListenPort(), info);
}
if (port.equals(serverConfig.getAdminPort())) {
logAndAddValidationWarningExporter(port, cluster, serverConfig, serverConfig.getAdminPort(), info);
}
Optional.ofNullable(serverConfig.getNetworkAccessPoints()).ifPresent(naps -> naps.forEach(nap -> {
if (port.equals(nap.getListenPort())) {
logAndAddValidationWarningExporter(port, cluster, serverConfig, nap.getListenPort(), info);
}
}));
}

private void logAndAddValidationWarningExporter(
Integer port, WlsClusterConfig cluster, WlsServerConfig serverConfig,
Integer conflictPort, DomainPresenceInfo info) {
if (cluster != null) {
logAndAddValidationWarning(info, MessageKeys.MONITORING_EXPORTER_CONFLICT_DYNAMIC_CLUSTER,
// Note: Using Integer.toString because default logger behavior formats with commas, e.g. "7,001"
Integer.toString(port), cluster.getClusterName(), Integer.toString(conflictPort));
} else {
logAndAddValidationWarning(info, MessageKeys.MONITORING_EXPORTER_CONFLICT_SERVER,
Integer.toString(port), serverConfig.getName(), Integer.toString(conflictPort));
}
}

@Override
public NextAction apply(Packet packet) {
DomainPresenceInfo info = packet.getSpi(DomainPresenceInfo.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ private Step getConflictStep() {
}

ExporterContext createExporterContext() {
return useSidecar() ? new SidecarExporterContext() : new WebAppExporterContext();
return useSidecar()
? new SidecarExporterContext(getMonitoringExporterSpecification()) : new WebAppExporterContext();
}

// Use the monitoring exporter sidecar if an exporter configuration is part of the domain.
Expand Down Expand Up @@ -219,6 +220,10 @@ Integer getAsPort() {
.getLocalAdminProtocolChannelPort();
}

MonitoringExporterSpecification getMonitoringExporterSpecification() {
return getDomain().getMonitoringExporterSpecification();
}

/**
* Check if the server is listening on a secure port. NOTE: If the targeted server is a managed
* server, this method is overridden to check if the managed server has a secure listen port rather
Expand Down Expand Up @@ -1295,11 +1300,10 @@ void addContainer(List<V1Container> containers) {
}

class SidecarExporterContext extends ExporterContext {
private static final int DEBUG_PORT = 30055;
private final int metricsPort;

public SidecarExporterContext() {
metricsPort = MonitoringExporterSpecification.getRestPort(scan);
public SidecarExporterContext(MonitoringExporterSpecification specification) {
metricsPort = specification.getRestPort();
}

@Override
Expand Down Expand Up @@ -1328,8 +1332,12 @@ private V1Container createMonitoringExporterContainer() {
.image(getDomain().getMonitoringExporterImage())
.imagePullPolicy(getDomain().getMonitoringExporterImagePullPolicy())
.addEnvItem(new V1EnvVar().name("JAVA_OPTS").value(createJavaOptions()))
.addPortsItem(new V1ContainerPort().name("metrics").protocol("TCP").containerPort(getPort()))
.addPortsItem(new V1ContainerPort().name("debugger").protocol("TCP").containerPort(DEBUG_PORT));
.addPortsItem(new V1ContainerPort()
.name(getMetricsPortName()).protocol("TCP").containerPort(getPort()));
}

private String getMetricsPortName() {
return getDomain().isIstioEnabled() ? "http-metrics" : "metrics";
}

private String createJavaOptions() {
Expand All @@ -1342,13 +1350,8 @@ private String createJavaOptions() {
if (metricsPort != DEFAULT_EXPORTER_SIDECAR_PORT) {
args.add("-DEXPORTER_PORT=" + metricsPort);
}
args.add(getDebugOption());

return String.join(" ", args);
}

private String getDebugOption() {
return "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:" + DEBUG_PORT;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import oracle.kubernetes.weblogic.domain.model.Channel;
import oracle.kubernetes.weblogic.domain.model.ClusterSpec;
import oracle.kubernetes.weblogic.domain.model.Domain;
import oracle.kubernetes.weblogic.domain.model.MonitoringExporterSpecification;
import oracle.kubernetes.weblogic.domain.model.ServerSpec;
import org.apache.commons.lang3.builder.EqualsBuilder;

Expand All @@ -62,7 +61,6 @@
import static oracle.kubernetes.operator.logging.MessageKeys.MANAGED_SERVICE_CREATED;
import static oracle.kubernetes.operator.logging.MessageKeys.MANAGED_SERVICE_EXISTS;
import static oracle.kubernetes.operator.logging.MessageKeys.MANAGED_SERVICE_REPLACED;
import static oracle.kubernetes.weblogic.domain.model.MonitoringExporterSpecification.EXPORTER_PORT_NAME;

public class ServiceHelper {
public static final String CLUSTER_IP_TYPE = "ClusterIP";
Expand Down Expand Up @@ -420,9 +418,15 @@ void addServicePorts(List<V1ServicePort> ports, WlsServerConfig serverConfig) {
addServicePortIfNeeded(ports, "default-admin", serverConfig.getAdminPort());
}

if (getDomain().getMonitoringExporterConfiguration() != null) {
addServicePortIfNeeded(ports, EXPORTER_PORT_NAME, MonitoringExporterSpecification.getRestPort(serverConfig));
}
Optional.ofNullable(getDomain().getMonitoringExporterSpecification()).ifPresent(specification -> {
if (specification.getConfiguration() != null) {
addServicePortIfNeeded(ports, getMetricsPortName(), specification.getRestPort());
}
});
}

private String getMetricsPortName() {
return getDomain().isIstioEnabled() ? "http-metrics" : "metrics";
}

List<NetworkAccessPoint> getNetworkAccessPoints(@Nonnull WlsServerConfig config) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ public class MessageKeys {
public static final String DUPLICATE_COMMON_MOUNT_PATH_FOUND = "WLSDO-0024";
public static final String DUPLICATE_COMMON_MOUNT_VOLUME_FOUND = "WLSDO-0025";
public static final String COMMON_MOUNT_VOLUME_NAME_NOT_DEFINED = "WLSDO-0026";
public static final String MONITORING_EXPORTER_CONFLICT_SERVER = "WLSDO-0027";
public static final String MONITORING_EXPORTER_CONFLICT_DYNAMIC_CLUSTER = "WLSDO-0028";

private MessageKeys() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

import static oracle.kubernetes.operator.ProcessingConstants.SERVER_NAME;
import static oracle.kubernetes.operator.steps.HttpRequestProcessing.createRequestStep;
import static oracle.kubernetes.weblogic.domain.model.MonitoringExporterSpecification.EXPORTER_PORT_NAME;

public class MonitoringExporterSteps {

Expand Down Expand Up @@ -235,9 +234,11 @@ public NextAction apply(Packet packet) {
}

private static class ExporterRequestProcessing extends HttpRequestProcessing {
private final DomainPresenceInfo info;

ExporterRequestProcessing(Packet packet) {
super(packet, getServerService(packet), getServerPod(packet));
info = packet.getSpi(DomainPresenceInfo.class);
}

private static V1Service getServerService(Packet packet) {
Expand Down Expand Up @@ -269,7 +270,15 @@ private List<V1ServicePort> getServicePorts() {
}

private boolean isExporterPort(V1ServicePort servicePort) {
return EXPORTER_PORT_NAME.equals(servicePort.getName());
return getMetricsPortName().equals(servicePort.getName());
}

Domain getDomain() {
return info.getDomain();
}

private String getMetricsPortName() {
return getDomain().isIstioEnabled() ? "http-metrics" : "metrics";
}

private HttpRequest createConfigurationQueryRequest() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,10 @@ public WlsServerConfig getServerTemplate() {
return serverTemplate;
}

public void setServerTemplate(WlsServerConfig serverTemplate) {
this.serverTemplate = serverTemplate;
}

public String getName() {
return this.name;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ protected DomainSpec getDomainSpec() {

public abstract DomainConfigurator withMonitoringExporterImage(String imageName);

public abstract DomainConfigurator withMonitoringExporterPort(Integer port);

/**
* Adds a default server configuration to the domain, if not already present.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,10 @@ public MonitoringExporterConfiguration getMonitoringExporterConfiguration() {
return spec.getMonitoringExporterConfiguration();
}

public MonitoringExporterSpecification getMonitoringExporterSpecification() {
return spec.getMonitoringExporterSpecification();
}

public String getMonitoringExporterImage() {
return spec.getMonitoringExporterImage();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ public DomainConfigurator withMonitoringExporterImage(String imageName) {
return this;
}

@Override
public DomainConfigurator withMonitoringExporterPort(Integer port) {
getDomainSpec().setMonitoringExporterPort(port);
return this;
}

private AdminServer getOrCreateAdminServer() {
return getDomainSpec().getOrCreateAdminServer();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,10 @@ public class DomainSpec extends BaseConfiguration {
+ "have the exporter sidecar or not, as appropriate. See https://github.com/oracle/weblogic-monitoring-exporter.")
private MonitoringExporterSpecification monitoringExporter;

public MonitoringExporterSpecification getMonitoringExporterSpecification() {
return monitoringExporter;
}

MonitoringExporterConfiguration getMonitoringExporterConfiguration() {
return Optional.ofNullable(monitoringExporter).map(MonitoringExporterSpecification::getConfiguration).orElse(null);
}
Expand All @@ -341,6 +345,10 @@ String getMonitoringExporterImagePullPolicy() {
return monitoringExporter == null ? null : monitoringExporter.getImagePullPolicy();
}

public Integer getMonitoringExporterPort() {
return monitoringExporter == null ? null : monitoringExporter.getPort();
}

/**
* Specifies the image for the monitoring exporter sidecar.
* @param imageName the name of the docker image
Expand All @@ -361,6 +369,16 @@ public void setMonitoringExporterImagePullPolicy(String pullPolicy) {
monitoringExporter.setImagePullPolicy(pullPolicy);
}

/**
* Specifies the port for the exporter sidecar.
* @param port port number
*/
public void setMonitoringExporterPort(Integer port) {
assert monitoringExporter != null : "May not set exporter port without configuration";

monitoringExporter.setPort(port);
}

/**
* The configuration for the admin server.
*
Expand Down
Loading