-
Notifications
You must be signed in to change notification settings - Fork 202
Issue#968 - Multi Container Support with Resource Fragments #969
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,9 +17,11 @@ | |
package io.fabric8.maven.enricher.api; | ||
|
||
import io.fabric8.kubernetes.api.builder.TypedVisitor; | ||
import io.fabric8.kubernetes.api.model.ContainerBuilder; | ||
import io.fabric8.kubernetes.api.model.KubernetesListBuilder; | ||
import io.fabric8.kubernetes.api.model.Probe; | ||
import io.fabric8.kubernetes.api.model.*; | ||
import io.fabric8.kubernetes.api.model.extensions.Deployment; | ||
import io.fabric8.maven.core.util.Configs; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* Enriches containers with health check probes. | ||
|
@@ -30,25 +32,67 @@ public AbstractHealthCheckEnricher(EnricherContext buildContext, String name) { | |
super(buildContext, name); | ||
} | ||
|
||
// Available configuration keys | ||
protected enum Config implements Configs.Key { | ||
|
||
probeMode {{ d = "all";}}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can decide to enrich all containers here, or we can rely here on the concept of "project's main container", or list the containers that should be enriched using a configuration option (also a global one if this enricher is not the only one that should be scoped to a specific container). I'd not go for "first" / "last" as it relies too much on what the current implementation does but it may change in the future (with plugin updates or with "fragments" added in other ways e.g. #941). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nicolaferraro i agree with you on the first/last/all, how does something like this
when the probes is empty then we assume "all" and add probes to all containers There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd keep the configuration inside the enricher config, but a list of container names can be used (I don't know if the configuration utils support lists as you have declared them in the example, there should be other cases of list configs). About the default when no configuration is given: both 'all containers' or 'just the one having the default name' are reasonable in my opinion. |
||
|
||
protected String d; | ||
|
||
public String def() { | ||
return d; | ||
} | ||
} | ||
|
||
@Override | ||
public void addMissingResources(KubernetesListBuilder builder) { | ||
|
||
final List<HasMetadata> buildItems = builder.buildItems(); | ||
|
||
builder.accept(new TypedVisitor<ContainerBuilder>() { | ||
@Override | ||
public void visit(ContainerBuilder container) { | ||
if (!container.hasReadinessProbe()) { | ||
Probe probe = getReadinessProbe(container); | ||
if (probe != null) { | ||
log.info("Adding readiness " + describe(probe)); | ||
container.withReadinessProbe(probe); | ||
Container matchedContainer = null; | ||
int idx = 0; | ||
|
||
// by default true - as probeMode will be all containers | ||
boolean matches = true; | ||
|
||
//do probe mode check only for first and last probe modes | ||
if ("first".equalsIgnoreCase(getConfig(Config.probeMode)) || | ||
"last".equalsIgnoreCase(getConfig(Config.probeMode))) { | ||
for (HasMetadata buildItem : buildItems) { | ||
//TODO: SK check with ROL on whether kind to be for Replication Controllers as well?? | ||
if ("Deployment".equals(buildItem.getKind())) { | ||
Deployment deployment = (Deployment) buildItem; | ||
List<Container> containers = deployment.getSpec().getTemplate().getSpec().getContainers(); | ||
if ("first".equalsIgnoreCase(getConfig(Config.probeMode))) { | ||
idx = 0; | ||
} else if ("last".equalsIgnoreCase(getConfig(Config.probeMode))) { | ||
idx = containers.size() - 1; | ||
} | ||
matchedContainer = containers.get(idx); | ||
} | ||
} | ||
matches = matchedContainer != null && | ||
container.build().getImage().equals(matchedContainer.getImage()); | ||
} | ||
|
||
if (!container.hasLivenessProbe()) { | ||
Probe probe = getLivenessProbe(container); | ||
if (probe != null) { | ||
log.info("Adding liveness " + describe(probe)); | ||
container.withLivenessProbe(probe); | ||
if (matches) { | ||
if (!container.hasReadinessProbe()) { | ||
Probe probe = getReadinessProbe(container); | ||
if (probe != null) { | ||
log.info("Adding readiness " + describe(probe)); | ||
container.withReadinessProbe(probe); | ||
} | ||
} | ||
|
||
if (!container.hasLivenessProbe()) { | ||
Probe probe = getLivenessProbe(container); | ||
if (probe != null) { | ||
log.info("Adding liveness " + describe(probe)); | ||
container.withLivenessProbe(probe); | ||
} | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
--- | ||
apiVersion: v1 | ||
kind: List | ||
items: | ||
- apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
annotations: | ||
fabric8.io/git-commit: "@ignore@" | ||
fabric8.io/iconUrl: img/icons/spring-boot.svg | ||
fabric8.io/git-branch: "@ignore@" | ||
prometheus.io/scrape: "@ignore@" | ||
prometheus.io/port: "@ignore@" | ||
labels: | ||
expose: "true" | ||
provider: fabric8 | ||
project: hello-world | ||
version: 0.0.1-SNAPSHOT | ||
group: io.fabric8 | ||
name: hello-world | ||
spec: | ||
ports: | ||
- name: http | ||
port: 8080 | ||
protocol: TCP | ||
targetPort: 8080 | ||
selector: | ||
project: hello-world | ||
provider: fabric8 | ||
group: io.fabric8 | ||
- apiVersion: extensions/v1beta1 | ||
kind: Deployment | ||
metadata: | ||
annotations: | ||
fabric8.io/git-commit: "@ignore@" | ||
fabric8.io/iconUrl: img/icons/spring-boot.svg | ||
fabric8.io/git-branch: "@ignore@" | ||
fabric8.io/metrics-path: dashboard/file/kubernetes-pods.json/?var-project=hello-world&var-version=0.0.1-SNAPSHOT | ||
labels: | ||
provider: fabric8 | ||
project: hello-world | ||
version: 0.0.1-SNAPSHOT | ||
group: io.fabric8 | ||
name: hello-world | ||
spec: | ||
replicas: 1 | ||
selector: | ||
matchLabels: | ||
project: hello-world | ||
provider: fabric8 | ||
group: io.fabric8 | ||
template: | ||
metadata: | ||
annotations: | ||
alpha.istio.io/sidecar: injected | ||
alpha.istio.io/version: [email protected] | ||
fabric8.io/git-commit: "@ignore@" | ||
fabric8.io/iconUrl: img/icons/spring-boot.svg | ||
fabric8.io/git-branch: "@ignore@" | ||
fabric8.io/metrics-path: dashboard/file/kubernetes-pods.json/?var-project=hello-world&var-version=0.0.1-SNAPSHOT | ||
labels: | ||
provider: fabric8 | ||
project: hello-world | ||
version: 0.0.1-SNAPSHOT | ||
group: io.fabric8 | ||
spec: | ||
containers: | ||
- args: | ||
- proxy | ||
- sidecar | ||
- -v | ||
- "2" | ||
- --passthrough | ||
- "8080" | ||
env: | ||
- name: POD_NAME | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: metadata.name | ||
- name: POD_NAMESPACE | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: metadata.namespace | ||
- name: POD_IP | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: status.podIP | ||
image: docker.io/istio/proxy_debug:0.1 | ||
imagePullPolicy: Always | ||
livenessProbe: | ||
httpGet: | ||
path: /health | ||
port: 8080 | ||
scheme: HTTP | ||
initialDelaySeconds: 180 | ||
name: proxy | ||
readinessProbe: | ||
httpGet: | ||
path: /health | ||
port: 8080 | ||
scheme: HTTP | ||
initialDelaySeconds: 10 | ||
resources: {} | ||
securityContext: | ||
runAsUser: 1337 | ||
- env: | ||
- name: KUBERNETES_NAMESPACE | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: metadata.namespace | ||
image: "@matches('fabric8/hello-world:.*$')@" | ||
imagePullPolicy: IfNotPresent | ||
livenessProbe: | ||
httpGet: | ||
path: /health | ||
port: 8080 | ||
scheme: HTTP | ||
initialDelaySeconds: 180 | ||
name: spring-boot | ||
ports: | ||
- containerPort: 8080 | ||
name: http | ||
protocol: TCP | ||
- containerPort: 9779 | ||
name: prometheus | ||
protocol: TCP | ||
- containerPort: 8778 | ||
name: jolokia | ||
protocol: TCP | ||
readinessProbe: | ||
httpGet: | ||
path: /health | ||
port: 8080 | ||
scheme: HTTP | ||
initialDelaySeconds: 10 | ||
securityContext: | ||
privileged: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you're correlating over the image name. This works with sidecars, but it may have problems with pods having multiple containers from the same base image (with different startup options).
I think a better approach would be to correlate over the container name, i.e.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nicolaferraro - do you mean this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like that @kameshsampath, but I see that code adds another container if the fragment does not declare a name (that is the standard case when adding fragments). I'd add another container only if the one declared in the fragments uses a name that is different from the default container name for the project (e.g. it's called
proxy
). Please, also fix the dependencies of the 'it' tests as they refer snapshot artifacts.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nicolaferraro - am not getting what you mean " I see that code adds another container if the fragment does not declare a name" - can you please point to the line# in the code for it ?