Skip to content
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
77 changes: 45 additions & 32 deletions cns/ipampool/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,80 +6,93 @@ import (
)

const (
subnetLabel = "subnet"
subnetCIDRLabel = "subnet_cidr"
subnetLabel = "subnet"
subnetCIDRLabel = "subnet_cidr"
podnetARMIDLabel = "podnet_arm_id"
customerMetricLabel = "customer_metric"
customerMetricLabelValue = "customer metric"
)

var (
ipamAllocatedIPCount = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ipam_pod_allocated_ips",
Help: "Count of IPs CNS has allocated to Pods.",
Name: "cx_ipam_pod_allocated_ips",
Help: "Count of IPs CNS has allocated to Pods.",
ConstLabels: prometheus.Labels{customerMetricLabel: customerMetricLabelValue},
},
[]string{subnetLabel, subnetCIDRLabel},
[]string{subnetLabel, subnetCIDRLabel, podnetARMIDLabel},
)
ipamAvailableIPCount = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ipam_available_ips",
Help: "Available IP count.",
Name: "cx_ipam_available_ips",
Help: "Available IP count.",
ConstLabels: prometheus.Labels{customerMetricLabel: customerMetricLabelValue},
},
[]string{subnetLabel, subnetCIDRLabel},
[]string{subnetLabel, subnetCIDRLabel, podnetARMIDLabel},
)
ipamBatchSize = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ipam_batch_size",
Help: "IPAM IP pool batch size.",
Name: "cx_ipam_batch_size",
Help: "IPAM IP pool batch size.",
ConstLabels: prometheus.Labels{customerMetricLabel: customerMetricLabelValue},
},
[]string{subnetLabel, subnetCIDRLabel},
[]string{subnetLabel, subnetCIDRLabel, podnetARMIDLabel},
)
ipamCurrentAvailableIPcount = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ipam_current_available_ips",
Help: "Current available IP count.",
Name: "cx_ipam_current_available_ips",
Help: "Current available IP count.",
ConstLabels: prometheus.Labels{customerMetricLabel: customerMetricLabelValue},
},
[]string{subnetLabel, subnetCIDRLabel},
[]string{subnetLabel, subnetCIDRLabel, podnetARMIDLabel},
)
ipamExpectedAvailableIPCount = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ipam_expect_available_ips",
Help: "Expected future available IP count assuming the Requested IP count is honored.",
Name: "cx_ipam_expect_available_ips",
Help: "Expected future available IP count assuming the Requested IP count is honored.",
ConstLabels: prometheus.Labels{customerMetricLabel: customerMetricLabelValue},
},
[]string{subnetLabel, subnetCIDRLabel},
[]string{subnetLabel, subnetCIDRLabel, podnetARMIDLabel},
)
ipamMaxIPCount = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ipam_max_ips",
Help: "Maximum IP count.",
Name: "cx_ipam_max_ips",
Help: "Maximum IP count.",
ConstLabels: prometheus.Labels{customerMetricLabel: customerMetricLabelValue},
},
[]string{subnetLabel, subnetCIDRLabel},
[]string{subnetLabel, subnetCIDRLabel, podnetARMIDLabel},
)
ipamPendingProgramIPCount = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ipam_pending_programming_ips",
Help: "Pending programming IP count.",
Name: "cx_ipam_pending_programming_ips",
Help: "Pending programming IP count.",
ConstLabels: prometheus.Labels{customerMetricLabel: customerMetricLabelValue},
},
[]string{subnetLabel, subnetCIDRLabel},
[]string{subnetLabel, subnetCIDRLabel, podnetARMIDLabel},
)
ipamPendingReleaseIPCount = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ipam_pending_release_ips",
Help: "Pending release IP count.",
Name: "cx_ipam_pending_release_ips",
Help: "Pending release IP count.",
ConstLabels: prometheus.Labels{customerMetricLabel: customerMetricLabelValue},
},
[]string{subnetLabel, subnetCIDRLabel},
[]string{subnetLabel, subnetCIDRLabel, podnetARMIDLabel},
)
ipamRequestedIPConfigCount = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ipam_requested_ips",
Help: "Requested IP count.",
Name: "cx_ipam_requested_ips",
Help: "Requested IP count.",
ConstLabels: prometheus.Labels{customerMetricLabel: customerMetricLabelValue},
},
[]string{subnetLabel, subnetCIDRLabel},
[]string{subnetLabel, subnetCIDRLabel, podnetARMIDLabel},
)
ipamTotalIPCount = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "ipam_total_ips",
Help: "Count of total IP pool size allocated to CNS by DNC.",
Name: "cx_ipam_total_ips",
Help: "Count of total IP pool size allocated to CNS by DNC.",
ConstLabels: prometheus.Labels{customerMetricLabel: customerMetricLabelValue},
},
[]string{subnetLabel, subnetCIDRLabel},
[]string{subnetLabel, subnetCIDRLabel, podnetARMIDLabel},
)
)

Expand Down
26 changes: 22 additions & 4 deletions cns/ipampool/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ipampool

import (
"context"
"fmt"
"sync"
"time"

Expand All @@ -18,6 +19,8 @@ const (
DefaultRefreshDelay = 1 * time.Second
// DefaultMaxIPs default maximum allocatable IPs
DefaultMaxIPs = 250
// Subnet ARM ID /subscriptions/$(SUB)/resourceGroups/$(GROUP)/providers/Microsoft.Network/virtualNetworks/$(VNET)/subnets/$(SUBNET)
subnetARMIDTemplate = "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s"
)

type nodeNetworkConfigSpecUpdater interface {
Expand Down Expand Up @@ -49,8 +52,8 @@ type Monitor struct {
once sync.Once
}

// Global Variables for Subnet and SubnetAddressSpace
var subnet, subnetCIDR string
// Global Variables for Subnet, Subnet Address Space and Subnet ARM ID
var subnet, subnetCIDR, subnetARMID string

func NewMonitor(httpService cns.HTTPService, nnccli nodeNetworkConfigSpecUpdater, opts *Options) *Monitor {
if opts.RefreshDelay < 1 {
Expand Down Expand Up @@ -94,9 +97,10 @@ func (pm *Monitor) Start(ctx context.Context) error {
pm.spec = nnc.Spec
scaler := nnc.Status.Scaler

// Set SubnetName and SubnetAddressSpace values to the global subnet and subnetCIDR variables.
// Set SubnetName, SubnetAddressSpace and Pod Network ARM ID values to the global subnet, subnetCIDR and subnetARM variables.
subnet = nnc.Status.NetworkContainers[0].SubnetName
subnetCIDR = nnc.Status.NetworkContainers[0].SubnetAddressSpace
subnetARMID = GenerateARMID(&nnc.Status.NetworkContainers[0])

pm.metastate.batch = scaler.BatchSize
pm.metastate.max = scaler.MaxIPCount
Expand Down Expand Up @@ -157,7 +161,7 @@ func (pm *Monitor) reconcile(ctx context.Context) error {
allocatedIPs := pm.httpService.GetPodIPConfigState()
state := buildIPPoolState(allocatedIPs, pm.spec)
logger.Printf("ipam-pool-monitor state %+v", state)
observeIPPoolState(state, pm.metastate, []string{subnet, subnetCIDR})
observeIPPoolState(state, pm.metastate, []string{subnet, subnetCIDR, subnetARMID})

switch {
// pod count is increasing
Expand Down Expand Up @@ -343,6 +347,20 @@ func (pm *Monitor) GetStateSnapshot() cns.IpamPoolMonitorStateSnapshot {
}
}

// GenerateARMID uses the Subnet ARM ID format to populate the ARM ID with the metadata.
// If either of the metadata attributes are empty, then the ARM ID will be an empty string.
func GenerateARMID(nc *v1alpha.NetworkContainer) string {
subscription := nc.SubscriptionID
resourceGroup := nc.ResourceGroupID
vnetID := nc.VNETID
subnetID := nc.SubnetID

if subscription == "" || resourceGroup == "" || vnetID == "" || subnetID == "" {
return ""
}
return fmt.Sprintf(subnetARMIDTemplate, subscription, resourceGroup, vnetID, subnetID)
}

// Update ingests a NodeNetworkConfig, clamping some values to ensure they are legal and then
// pushing it to the Monitor's source channel.
// If the Monitor has been Started but is blocking until it receives an NNC, this will start
Expand Down
4 changes: 4 additions & 0 deletions crd/nodenetworkconfig/api/v1alpha/nodenetworkconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ type NetworkContainer struct {
SubnetAddressSpace string `json:"subnetAddressSpace,omitempty"`
Version int64 `json:"version,omitempty"`
NodeIP string `json:"nodeIP,omitempty"`
SubscriptionID string `json:"subcriptionID,omitempty"`
ResourceGroupID string `json:"resourceGroupID,omitempty"`
VNETID string `json:"vnetID,omitempty"`
SubnetID string `json:"subnetID,omitempty"`
}

// IPAssignment groups an IP address and Name. Name is a UUID set by the the IP address assigner.
Expand Down