Skip to content

Include monitoring exporter sidecar and Prometheus annotations for admin server #2365

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 1 commit into from
May 18, 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
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
import oracle.kubernetes.operator.steps.DeleteDomainStep;
import oracle.kubernetes.operator.steps.DomainPresenceStep;
import oracle.kubernetes.operator.steps.ManagedServersUpStep;
import oracle.kubernetes.operator.steps.MonitorExporterSteps;
import oracle.kubernetes.operator.steps.MonitoringExporterSteps;
import oracle.kubernetes.operator.steps.WatchPodReadyAdminStep;
import oracle.kubernetes.operator.work.Component;
import oracle.kubernetes.operator.work.Fiber;
Expand Down Expand Up @@ -1154,7 +1154,7 @@ Step createDomainUpPlan(DomainPresenceInfo info) {
bringManagedServersUp(null),
DomainStatusUpdater.createEndProgressingStep(null),
EventHelper.createEventStep(EventItem.DOMAIN_PROCESSING_COMPLETED),
MonitorExporterSteps.updateExporterSidecars(),
MonitoringExporterSteps.updateExporterSidecars(),
new TailStep());

Step domainUpStrategy =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import io.kubernetes.client.openapi.models.V1Container;
import io.kubernetes.client.openapi.models.V1ContainerPort;
import io.kubernetes.client.openapi.models.V1DeleteOptions;
import io.kubernetes.client.openapi.models.V1EnvVar;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
Expand All @@ -38,12 +35,9 @@
import oracle.kubernetes.operator.work.NextAction;
import oracle.kubernetes.operator.work.Packet;
import oracle.kubernetes.operator.work.Step;
import oracle.kubernetes.weblogic.domain.model.MonitoringExporterSpecification;
import oracle.kubernetes.weblogic.domain.model.ServerSpec;
import oracle.kubernetes.weblogic.domain.model.Shutdown;

import static oracle.kubernetes.operator.KubernetesConstants.DEFAULT_EXPORTER_SIDECAR_PORT;
import static oracle.kubernetes.operator.KubernetesConstants.EXPORTER_CONTAINER_NAME;
import static oracle.kubernetes.operator.LabelConstants.CLUSTERNAME_LABEL;
import static oracle.kubernetes.operator.LabelConstants.SERVERNAME_LABEL;
import static oracle.kubernetes.operator.ProcessingConstants.SERVERS_TO_ROLL;
Expand Down Expand Up @@ -405,26 +399,15 @@ static class ManagedPodStepContext extends PodStepContext {

private final String clusterName;
private final Packet packet;
private final ExporterContext exporterContext;

ManagedPodStepContext(Step conflictStep, Packet packet) {
super(conflictStep, packet);
this.packet = packet;
clusterName = (String) packet.get(ProcessingConstants.CLUSTER_NAME);
exporterContext = createExporterContext();

init();
}

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

// Use the monitoring exporter sidecar if an exporter configuration is part of the domain.
private boolean useSidecar() {
return getDomain().getMonitoringExporterConfiguration() != null;
}

@Override
ServerSpec getServerSpec() {
return getDomain().getServer(getServerName(), getClusterName());
Expand Down Expand Up @@ -513,21 +496,6 @@ protected String getPodReplacedMessageKey() {
return MessageKeys.MANAGED_POD_REPLACED;
}

@Override
V1Pod withNonHashedElements(V1Pod pod) {
V1Pod v1Pod = super.withNonHashedElements(pod);

// Add prometheus annotations. This will overwrite any custom annotations with same name.
// Prometheus does not support "prometheus.io/scheme". The scheme(http/https) can be set
// in the Prometheus Chart values yaml under the "extraScrapeConfigs:" section.
if (exporterContext.isEnabled()) {
final V1ObjectMeta metadata = v1Pod.getMetadata();
AnnotationHelper.annotateForPrometheus(metadata, exporterContext.getBasePath(), exporterContext.getPort());
}

return v1Pod;
}

@Override
protected V1ObjectMeta createMetadata() {
V1ObjectMeta metadata = super.createMetadata();
Expand All @@ -548,13 +516,6 @@ protected List<String> getContainerCommand() {
return new ArrayList<>(super.getContainerCommand());
}

@Override
protected List<V1Container> getContainers() {
List<V1Container> containers = new ArrayList<>(super.getContainers());
exporterContext.addContainer(containers);
return containers;
}

@Override
@SuppressWarnings("unchecked")
List<V1EnvVar> getConfiguredEnvVars(TuningParameters tuningParameters) {
Expand All @@ -564,106 +525,6 @@ List<V1EnvVar> getConfiguredEnvVars(TuningParameters tuningParameters) {
addStartupEnvVars(vars);
return vars;
}

abstract class ExporterContext {
int getWebLogicRestPort() {
return scan.getLocalAdminProtocolChannelPort();
}

boolean isWebLogicSecure() {
return !Objects.equals(getWebLogicRestPort(), getListenPort());
}

abstract boolean isEnabled();

abstract int getPort();

abstract String getBasePath();

abstract void addContainer(List<V1Container> containers);
}

class WebAppExporterContext extends ExporterContext {

@Override
boolean isEnabled() {
return getListenPort() != null;
}

@Override
int getPort() {
return getListenPort();
}

@Override
String getBasePath() {
return "/wls-exporter";
}

@Override
void addContainer(List<V1Container> containers) {
// do nothing
}
}

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

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

@Override
boolean isEnabled() {
return true;
}

@Override
int getPort() {
return metricsPort;
}

@Override
String getBasePath() {
return "";
}

@Override
void addContainer(List<V1Container> containers) {
containers.add(createMonitoringExporterContainer());
}

private V1Container createMonitoringExporterContainer() {
return new V1Container()
.name(EXPORTER_CONTAINER_NAME)
.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));
}

private String createJavaOptions() {
final List<String> args = new ArrayList<>();
args.add("-DDOMAIN=" + getDomainUid());
args.add("-DWLS_PORT=" + getWebLogicRestPort());
if (isWebLogicSecure()) {
args.add("-DWLS_SECURE=true");
}
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;
}
}

}

static class ManagedPodStep extends Step {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,15 @@
import oracle.kubernetes.weblogic.domain.model.Domain;
import oracle.kubernetes.weblogic.domain.model.DomainStatus;
import oracle.kubernetes.weblogic.domain.model.IntrospectorJobEnvVars;
import oracle.kubernetes.weblogic.domain.model.MonitoringExporterSpecification;
import oracle.kubernetes.weblogic.domain.model.ServerEnvVars;
import oracle.kubernetes.weblogic.domain.model.ServerSpec;
import oracle.kubernetes.weblogic.domain.model.Shutdown;
import org.apache.commons.lang3.builder.EqualsBuilder;

import static oracle.kubernetes.operator.IntrospectorConfigMapConstants.NUM_CONFIG_MAPS;
import static oracle.kubernetes.operator.KubernetesConstants.DEFAULT_EXPORTER_SIDECAR_PORT;
import static oracle.kubernetes.operator.KubernetesConstants.EXPORTER_CONTAINER_NAME;
import static oracle.kubernetes.operator.LabelConstants.INTROSPECTION_STATE_LABEL;
import static oracle.kubernetes.operator.LabelConstants.MII_UPDATED_RESTART_REQUIRED_LABEL;
import static oracle.kubernetes.operator.LabelConstants.MODEL_IN_IMAGE_DOMAINZIP_HASH;
Expand All @@ -86,6 +89,7 @@ public abstract class PodStepContext extends BasePodStepContext {

private static final String READINESS_PATH = "/weblogic/ready";
private static String productVersion;
protected final ExporterContext exporterContext;

final WlsServerConfig scan;
@Nonnull
Expand All @@ -108,6 +112,7 @@ public abstract class PodStepContext extends BasePodStepContext {
domainRestartVersion = (String)packet.get(IntrospectorConfigMapConstants.DOMAIN_RESTART_VERSION);
scan = (WlsServerConfig) packet.get(ProcessingConstants.SERVER_SCAN);
this.packet = packet;
exporterContext = createExporterContext();
}

private static boolean isPatchableItem(Map.Entry<String, String> entry) {
Expand Down Expand Up @@ -137,6 +142,15 @@ private Step getConflictStep() {
return new ConflictStep();
}

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

// Use the monitoring exporter sidecar if an exporter configuration is part of the domain.
private boolean useSidecar() {
return getDomain().getMonitoringExporterConfiguration() != null;
}

abstract Map<String, String> getPodLabels();

abstract Map<String, String> getPodAnnotations();
Expand Down Expand Up @@ -617,6 +631,14 @@ V1Pod withNonHashedElements(V1Pod pod) {
getContainer(pod).map(V1Container::getEnv).ifPresent(this::updateEnv);

updateForOwnerReference(metadata);

// Add prometheus annotations. This will overwrite any custom annotations with same name.
// Prometheus does not support "prometheus.io/scheme". The scheme(http/https) can be set
// in the Prometheus Chart values yaml under the "extraScrapeConfigs:" section.
if (exporterContext.isEnabled()) {
AnnotationHelper.annotateForPrometheus(metadata, exporterContext.getBasePath(), exporterContext.getPort());
}

return updateForDeepSubstitution(pod.getSpec(), pod);
}

Expand Down Expand Up @@ -784,7 +806,9 @@ protected List<String> getContainerCommand() {
}

protected List<V1Container> getContainers() {
return getServerSpec().getContainers();
List<V1Container> containers = new ArrayList<>(getServerSpec().getContainers());
exporterContext.addContainer(containers);
return containers;
}

private List<V1VolumeMount> getVolumeMounts() {
Expand Down Expand Up @@ -1132,4 +1156,103 @@ protected V1Pod processResponse(CallResponse<V1Pod> callResponse) {
return newPod;
}
}

abstract class ExporterContext {
int getWebLogicRestPort() {
return scan.getLocalAdminProtocolChannelPort();
}

boolean isWebLogicSecure() {
return !Objects.equals(getWebLogicRestPort(), getListenPort());
}

abstract boolean isEnabled();

abstract int getPort();

abstract String getBasePath();

abstract void addContainer(List<V1Container> containers);
}

class WebAppExporterContext extends ExporterContext {

@Override
boolean isEnabled() {
return getListenPort() != null;
}

@Override
int getPort() {
return getListenPort();
}

@Override
String getBasePath() {
return "/wls-exporter";
}

@Override
void addContainer(List<V1Container> containers) {
// do nothing
}
}

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

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

@Override
boolean isEnabled() {
return true;
}

@Override
int getPort() {
return metricsPort;
}

@Override
String getBasePath() {
return "";
}

@Override
void addContainer(List<V1Container> containers) {
containers.add(createMonitoringExporterContainer());
}

private V1Container createMonitoringExporterContainer() {
return new V1Container()
.name(EXPORTER_CONTAINER_NAME)
.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));
}

private String createJavaOptions() {
final List<String> args = new ArrayList<>();
args.add("-DDOMAIN=" + getDomainUid());
args.add("-DWLS_PORT=" + getWebLogicRestPort());
if (isWebLogicSecure()) {
args.add("-DWLS_SECURE=true");
}
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;
}
}
}
Loading