mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-28 01:31:17 +00:00
Remove replica sets
Use a special kind of selector renderer to elide replica sets from pod nodes and directly reference deployment parents instead. Do the inverse (replace replica sets with pods) during the mapping from pod to deployment. Note we can no longer use renderParents since we're using a non-standard Selector
This commit is contained in:
@@ -28,7 +28,6 @@ const (
|
||||
containersByHostnameID = "containers-by-hostname"
|
||||
containersByImageID = "containers-by-image"
|
||||
podsID = "pods"
|
||||
replicaSetsID = "replica-sets"
|
||||
kubeControllersID = "kube-controllers"
|
||||
servicesID = "services"
|
||||
hostsID = "hosts"
|
||||
@@ -97,7 +96,7 @@ func updateSwarmFilters(rpt report.Report, topologies []APITopologyDesc) []APITo
|
||||
|
||||
func updateKubeFilters(rpt report.Report, topologies []APITopologyDesc) []APITopologyDesc {
|
||||
namespaces := map[string]struct{}{}
|
||||
for _, t := range []report.Topology{rpt.Pod, rpt.Service, rpt.Deployment, rpt.ReplicaSet} {
|
||||
for _, t := range []report.Topology{rpt.Pod, rpt.Service, rpt.Deployment} {
|
||||
for _, n := range t.Nodes {
|
||||
if state, ok := n.Latest.Lookup(kubernetes.State); ok && state == kubernetes.StateDeleted {
|
||||
continue
|
||||
@@ -119,7 +118,7 @@ func updateKubeFilters(rpt report.Report, topologies []APITopologyDesc) []APITop
|
||||
sort.Strings(ns)
|
||||
topologies = append([]APITopologyDesc{}, topologies...) // Make a copy so we can make changes safely
|
||||
for i, t := range topologies {
|
||||
if t.id == containersID || t.id == podsID || t.id == servicesID || t.id == replicaSetsID || t.id == kubeControllersID {
|
||||
if t.id == containersID || t.id == podsID || t.id == servicesID || t.id == kubeControllersID {
|
||||
topologies[i] = mergeTopologyFilters(t, []APITopologyOptionGroup{
|
||||
namespaceFilters(ns, "All Namespaces"),
|
||||
})
|
||||
@@ -254,14 +253,6 @@ func MakeRegistry() *Registry {
|
||||
Options: []APITopologyOptionGroup{unmanagedFilter},
|
||||
HideIfEmpty: true,
|
||||
},
|
||||
APITopologyDesc{
|
||||
id: replicaSetsID,
|
||||
parent: podsID,
|
||||
renderer: render.FilterUnconnectedPseudo(render.ReplicaSetRenderer),
|
||||
Name: "replica sets",
|
||||
Options: []APITopologyOptionGroup{unmanagedFilter},
|
||||
HideIfEmpty: true,
|
||||
},
|
||||
APITopologyDesc{
|
||||
id: kubeControllersID,
|
||||
parent: podsID,
|
||||
|
||||
@@ -131,16 +131,6 @@ var nodeSummaryGroupSpecs = []struct {
|
||||
topologyID string
|
||||
NodeSummaryGroup
|
||||
}{
|
||||
{
|
||||
topologyID: report.ReplicaSet,
|
||||
NodeSummaryGroup: NodeSummaryGroup{
|
||||
Label: "Replica Sets",
|
||||
Columns: []Column{
|
||||
{ID: report.Pod, Label: "# Pods", Datatype: "number"},
|
||||
{ID: kubernetes.ObservedGeneration, Label: "Observed Gen.", Datatype: "number"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
topologyID: report.Pod,
|
||||
NodeSummaryGroup: NodeSummaryGroup{
|
||||
|
||||
@@ -23,7 +23,6 @@ var (
|
||||
getLabelForTopology = map[string]func(report.Node) string{
|
||||
report.Container: getRenderableContainerName,
|
||||
report.Pod: kubernetesParentLabel,
|
||||
report.ReplicaSet: kubernetesParentLabel,
|
||||
report.Deployment: kubernetesParentLabel,
|
||||
report.DaemonSet: kubernetesParentLabel,
|
||||
report.Service: kubernetesParentLabel,
|
||||
|
||||
@@ -68,7 +68,6 @@ var renderers = map[string]func(NodeSummary, report.Node) (NodeSummary, bool){
|
||||
report.Service: podGroupNodeSummary,
|
||||
report.Deployment: podGroupNodeSummary,
|
||||
report.DaemonSet: podGroupNodeSummary,
|
||||
report.ReplicaSet: podGroupNodeSummary,
|
||||
report.ECSTask: ecsTaskNodeSummary,
|
||||
report.ECSService: ecsServiceNodeSummary,
|
||||
report.SwarmService: swarmServiceNodeSummary,
|
||||
@@ -89,7 +88,6 @@ var primaryAPITopology = map[string]string{
|
||||
report.Container: "containers",
|
||||
report.ContainerImage: "containers-by-image",
|
||||
report.Pod: "pods",
|
||||
report.ReplicaSet: "replica-sets",
|
||||
report.Deployment: "kube-controllers",
|
||||
report.DaemonSet: "kube-controllers",
|
||||
report.Service: "services",
|
||||
|
||||
@@ -18,7 +18,7 @@ const (
|
||||
var UnmanagedIDPrefix = MakePseudoNodeID(UnmanagedID)
|
||||
|
||||
func renderKubernetesTopologies(rpt report.Report) bool {
|
||||
return len(rpt.Pod.Nodes)+len(rpt.Service.Nodes)+len(rpt.Deployment.Nodes)+len(rpt.ReplicaSet.Nodes)+len(rpt.DaemonSet.Nodes) >= 1
|
||||
return len(rpt.Pod.Nodes)+len(rpt.Service.Nodes)+len(rpt.Deployment.Nodes)+len(rpt.DaemonSet.Nodes) >= 1
|
||||
}
|
||||
|
||||
func isPauseContainer(n report.Node) bool {
|
||||
@@ -44,16 +44,20 @@ var PodRenderer = ConditionalRenderer(renderKubernetesTopologies,
|
||||
return (!ok || state != kubernetes.StateDeleted)
|
||||
},
|
||||
MakeReduce(
|
||||
renderParents(
|
||||
report.Container, []string{report.Pod}, NoParentsPseudo, UnmanagedID, nil,
|
||||
MakeFilter(
|
||||
ComposeFilterFuncs(
|
||||
IsRunning,
|
||||
Complement(isPauseContainer),
|
||||
MakeMap(
|
||||
PropagateSingleMetrics(report.Container),
|
||||
MakeMap(
|
||||
Map2Parent([]string{report.Pod}, NoParentsPseudo, UnmanagedID, nil),
|
||||
MakeFilter(
|
||||
ComposeFilterFuncs(
|
||||
IsRunning,
|
||||
Complement(isPauseContainer),
|
||||
),
|
||||
ContainerWithImageNameRenderer,
|
||||
),
|
||||
ContainerWithImageNameRenderer,
|
||||
),
|
||||
),
|
||||
selectPodsWithDeployments{},
|
||||
ConnectionJoin(SelectPod, MapPod2IP),
|
||||
),
|
||||
),
|
||||
@@ -68,33 +72,15 @@ var PodServiceRenderer = ConditionalRenderer(renderKubernetesTopologies,
|
||||
),
|
||||
)
|
||||
|
||||
// ReplicaSetRenderer is a Renderer which produces a renderable kubernetes replica sets
|
||||
// graph by merging the pods graph and the replica sets topology.
|
||||
var ReplicaSetRenderer = ConditionalRenderer(renderKubernetesTopologies,
|
||||
renderParents(
|
||||
report.Pod, []string{report.ReplicaSet}, NoParentsDrop, "", nil,
|
||||
PodRenderer,
|
||||
),
|
||||
)
|
||||
|
||||
// KubeControllerRenderer is a Renderer which combines all the 'controller' topologies.
|
||||
// We first map pods to daemonsets and replica sets, then to deployments since replica sets
|
||||
// can map to those (the rest are passed through unchanged).
|
||||
// Pods with no controller are mapped to 'Unmanaged'
|
||||
// We can't simply combine the rendered graphs of the high level objects as they would never
|
||||
// have connections to each other.
|
||||
var KubeControllerRenderer = ConditionalRenderer(renderKubernetesTopologies,
|
||||
MakeFilter(
|
||||
// Filter out any remaining unmatched replica sets
|
||||
Complement(IsTopology(report.ReplicaSet)),
|
||||
renderParents(
|
||||
report.ReplicaSet, []string{report.Deployment}, NoParentsKeep, "", mapPodCounts,
|
||||
renderParents(
|
||||
report.Pod, []string{report.ReplicaSet, report.DaemonSet},
|
||||
NoParentsPseudo, UnmanagedID, nil,
|
||||
PodRenderer,
|
||||
),
|
||||
),
|
||||
renderParents(
|
||||
report.Pod, []string{report.Deployment, report.DaemonSet},
|
||||
NoParentsPseudo, UnmanagedID, makePodsChildren,
|
||||
PodRenderer,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -120,12 +106,53 @@ func renderParents(childTopology string, parentTopologies []string, noParentsAct
|
||||
)...)
|
||||
}
|
||||
|
||||
func mapPodCounts(parent, original report.Node) report.Node {
|
||||
// When mapping ReplicaSets to Deployments, we want to propagate the Pods counter
|
||||
if count, ok := original.Counters.Lookup(report.Pod); ok {
|
||||
parent.Counters = parent.Counters.Add(report.Pod, count)
|
||||
// Renderer to return modified Pod nodes to elide replica sets and point directly
|
||||
// to deployments where applicable.
|
||||
type selectPodsWithDeployments struct{}
|
||||
|
||||
func (s selectPodsWithDeployments) Render(rpt report.Report, dct Decorator) report.Nodes {
|
||||
result := report.Nodes{}
|
||||
// For each pod, we check for any replica sets, and merge any deployments they point to
|
||||
// into a replacement Parents value.
|
||||
for podID, pod := range rpt.Pod.Nodes {
|
||||
if replicaSetIDs, ok := pod.Parents.Lookup(report.ReplicaSet); ok {
|
||||
newParents := pod.Parents.Delete(report.ReplicaSet)
|
||||
for _, replicaSetID := range replicaSetIDs {
|
||||
if replicaSet, ok := rpt.ReplicaSet.Nodes[replicaSetID]; ok {
|
||||
if deploymentIDs, ok := replicaSet.Parents.Lookup(report.Deployment); ok {
|
||||
newParents = newParents.Add(report.Deployment, deploymentIDs)
|
||||
}
|
||||
}
|
||||
}
|
||||
pod = pod.WithParents(newParents)
|
||||
}
|
||||
result[podID] = pod
|
||||
}
|
||||
return parent
|
||||
return result
|
||||
}
|
||||
|
||||
func (s selectPodsWithDeployments) Stats(rpt report.Report, _ Decorator) Stats {
|
||||
return Stats{}
|
||||
}
|
||||
|
||||
// When mapping from pods to deployments, complete the two-way relation by making the
|
||||
// mapped-from pod a child of the mapped-to deployment, and remove any replica set children.
|
||||
// This is needed because pods were originally mapped to deployments via an intermediate replica set
|
||||
// which we need to remove.
|
||||
func makePodsChildren(parent, original report.Node) report.Node {
|
||||
children := parent.Children
|
||||
// Gather all the replica sets...
|
||||
replicaSetIDs := []string{}
|
||||
children.ForEach(func(n report.Node) {
|
||||
if n.Topology == report.ReplicaSet {
|
||||
replicaSetIDs = append(replicaSetIDs, n.ID)
|
||||
}
|
||||
})
|
||||
// ...and delete them.
|
||||
children = children.Delete(replicaSetIDs...)
|
||||
// Then add in the mapped-from pod.
|
||||
children = children.Add(original)
|
||||
return parent.WithChildren(children)
|
||||
}
|
||||
|
||||
// MapPod2IP maps pod nodes to their IP address. This allows pods to
|
||||
|
||||
@@ -31,7 +31,6 @@ var (
|
||||
SelectService = TopologySelector(report.Service)
|
||||
SelectDeployment = TopologySelector(report.Deployment)
|
||||
SelectDaemonSet = TopologySelector(report.DaemonSet)
|
||||
SelectReplicaSet = TopologySelector(report.ReplicaSet)
|
||||
SelectECSTask = TopologySelector(report.ECSTask)
|
||||
SelectECSService = TopologySelector(report.ECSService)
|
||||
SelectSwarmService = TopologySelector(report.SwarmService)
|
||||
|
||||
Reference in New Issue
Block a user