mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-17 20:00:07 +00:00
test:add sample-external-metrics-server to agnhost
Signed-off-by: Omer Aplatony <omerap12@gmail.com>
This commit is contained in:
@@ -165,6 +165,35 @@ Usage:
|
||||
```
|
||||
|
||||
|
||||
### external-metrics
|
||||
|
||||
Starts an HTTPS server that implements the external metrics API for testing Horizontal Pod Autoscaler (HPA) with external metrics. The server provides a mock implementation of the `external.metrics.k8s.io` API group.
|
||||
|
||||
The server comes with two pre-configured metrics:
|
||||
- `queue_messages_ready` (value: 100)
|
||||
- `http_requests_total` (value: 500)
|
||||
|
||||
The server exposes the following endpoints:
|
||||
- `/apis/external.metrics.k8s.io/v1beta1/namespaces/{namespace}/{metric-name}`: Get external metric values (supports label selectors via query parameter)
|
||||
- `/healthz` and `/readyz`: Health check endpoints
|
||||
- `/create/{metric-name}?value={value}&labels={key1=value1,key2=value2}&fail={true|false}`: Create a new metric with optional labels
|
||||
- `/set/{metric-name}?value={value}&labels={key1=value1,key2=value2}`: Update an existing metric's value
|
||||
- `/fail/{metric-name}?fail={true|false}&labels={key1=value1,key2=value2}`: Configure a metric to return errors
|
||||
|
||||
The subcommand can accept the following flags:
|
||||
- `port` (default: `6443`): Port number for the HTTPS server.
|
||||
- `service-name` (default: `external-metrics-server`): Name of the external metrics service.
|
||||
- `service-namespace` (default: `default`): Namespace of the external metrics service.
|
||||
|
||||
The server generates self-signed TLS certificates automatically on startup.
|
||||
|
||||
Usage:
|
||||
|
||||
```console
|
||||
kubectl exec test-agnhost -- /agnhost external-metrics [--port <port>] [--service-name <name>] [--service-namespace <namespace>]
|
||||
```
|
||||
|
||||
|
||||
### fake-gitserver
|
||||
|
||||
Fakes a git server. When doing `git clone http://localhost:8000`, you will clone an empty git
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.62.2
|
||||
2.63.0
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
crdconvwebhook "k8s.io/kubernetes/test/images/agnhost/crd-conversion-webhook"
|
||||
"k8s.io/kubernetes/test/images/agnhost/dns"
|
||||
"k8s.io/kubernetes/test/images/agnhost/entrypoint-tester"
|
||||
externalmetrics "k8s.io/kubernetes/test/images/agnhost/external-metrics"
|
||||
"k8s.io/kubernetes/test/images/agnhost/fakegitserver"
|
||||
"k8s.io/kubernetes/test/images/agnhost/fakeregistryserver"
|
||||
grpchealthchecking "k8s.io/kubernetes/test/images/agnhost/grpc-health-checking"
|
||||
@@ -98,6 +99,7 @@ func main() {
|
||||
rootCmd.AddCommand(mtlsclient.CmdMtlsClient)
|
||||
rootCmd.AddCommand(mtlsserver.CmdMtlsServer)
|
||||
rootCmd.AddCommand(nonewprivs.CmdNoNewPrivs)
|
||||
rootCmd.AddCommand(externalmetrics.CmdExternalMetricsServer)
|
||||
// NOTE(claudiub): Some tests are passing logging related flags, so we need to be able to
|
||||
// accept them. This will also include them in the printed help.
|
||||
code := cli.Run(rootCmd)
|
||||
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package externalmetrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package externalmetrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -22,39 +22,50 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/spf13/cobra"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/server/options"
|
||||
"k8s.io/klog/v2"
|
||||
netutils "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
// CmdExternalMetricsServer is used by agnhost Cobra.
|
||||
var CmdExternalMetricsServer = &cobra.Command{
|
||||
Use: "external-metrics",
|
||||
Short: "Starts an external metrics server for testing",
|
||||
Long: "Starts an HTTPS server that implements the external metrics API for testing HPA with external metrics",
|
||||
Args: cobra.MaximumNArgs(0),
|
||||
Run: main,
|
||||
}
|
||||
|
||||
var provider *metricProvider
|
||||
|
||||
func main() {
|
||||
flags := pflag.NewFlagSet("sample-external-metrics", pflag.ExitOnError)
|
||||
klog.InitFlags(nil)
|
||||
var (
|
||||
port int
|
||||
serviceName string
|
||||
serviceNs string
|
||||
)
|
||||
|
||||
func init() {
|
||||
CmdExternalMetricsServer.Flags().IntVar(&port, "port", 6443, "Port number.")
|
||||
CmdExternalMetricsServer.Flags().StringVar(&serviceName, "service-name", "external-metrics-server", "Name of the external metrics service.")
|
||||
CmdExternalMetricsServer.Flags().StringVar(&serviceNs, "service-namespace", "default", "Namespace of the external metrics service.")
|
||||
}
|
||||
|
||||
func main(cmd *cobra.Command, args []string) {
|
||||
|
||||
// Initialize the metric provider
|
||||
provider = NewConfigurableProvider()
|
||||
// Create some default metrics
|
||||
provider.createMetric("queue_messages_ready", nil, 100, false)
|
||||
provider.createMetric("http_requests_total", nil, 500, false)
|
||||
|
||||
secureServing := options.NewSecureServingOptions()
|
||||
secureServing.BindPort = 6443
|
||||
secureServing.BindPort = port
|
||||
secureServing.ServerCert.CertDirectory = "/tmp/cert"
|
||||
secureServing.ServerCert.PairName = "apiserver"
|
||||
secureServing.AddFlags(flags)
|
||||
|
||||
if err := flags.Parse(os.Args[1:]); err != nil {
|
||||
klog.Fatalf("Error parsing flags: %v", err)
|
||||
}
|
||||
|
||||
// Generate self-signed TLS certificates if none exist. This allows the server to run with HTTPS
|
||||
// without requiring manually provisioned certificates. The certs are valid for "localhost" and
|
||||
// the loopback IP 127.0.0.1. The second parameter (nil) means no additional alternate names.
|
||||
@@ -96,6 +107,7 @@ func main() {
|
||||
|
||||
<-listenerStoppedCh
|
||||
<-stoppedCh
|
||||
|
||||
}
|
||||
|
||||
func healthz(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -1,5 +0,0 @@
|
||||
linux/amd64=registry.k8s.io/build-image/debian-base-amd64:bookworm-v1.0.6
|
||||
linux/ppc64le=registry.k8s.io/build-image/debian-base-ppc64le:bookworm-v1.0.6
|
||||
linux/s390x=registry.k8s.io/build-image/debian-base-s390x:bookworm-v1.0.6
|
||||
windows/amd64/1809=mcr.microsoft.com/windows/nanoserver:1809
|
||||
windows/amd64/ltsc2022=mcr.microsoft.com/windows/nanoserver:ltsc2022
|
||||
@@ -1,20 +0,0 @@
|
||||
# Copyright The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ARG BASEIMAGE
|
||||
FROM $BASEIMAGE
|
||||
|
||||
ADD sample-external-metrics-server /sample-external-metrics-server
|
||||
EXPOSE 6443
|
||||
ENTRYPOINT ["/sample-external-metrics-server"]
|
||||
@@ -1,26 +0,0 @@
|
||||
# Copyright The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
SRCS = sample-external-metrics-server
|
||||
OS ?= linux
|
||||
ARCH ?= amd64
|
||||
TARGET ?= $(CURDIR)
|
||||
GOLANG_VERSION ?= latest
|
||||
SRC_DIR = $(notdir $(shell pwd))
|
||||
export
|
||||
|
||||
bin:
|
||||
../image-util.sh bin $(SRCS)
|
||||
|
||||
.PHONY: bin
|
||||
@@ -1,118 +0,0 @@
|
||||
# Test Metrics Server
|
||||
|
||||
A Kubernetes external metrics API server for testing and development purposes. This server implements the `external.metrics.k8s.io` API and provides endpoints to dynamically create, update, and configure metrics for testing HPA (Horizontal Pod Autoscaler) and other metric-based scenarios.
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Health Checks
|
||||
|
||||
#### Check Server Health
|
||||
```bash
|
||||
curl -k https://localhost:6443/healthz
|
||||
curl -k https://localhost:6443/readyz
|
||||
```
|
||||
|
||||
### Kubernetes External Metrics API
|
||||
|
||||
#### List API Groups
|
||||
```bash
|
||||
curl -k https://localhost:6443/apis/external.metrics.k8s.io
|
||||
```
|
||||
|
||||
#### List Available Resources
|
||||
```bash
|
||||
curl -k https://localhost:6443/apis/external.metrics.k8s.io/v1beta1
|
||||
```
|
||||
|
||||
#### Get Metric Value
|
||||
```bash
|
||||
# Query a specific metric
|
||||
curl -k https://localhost:6443/apis/external.metrics.k8s.io/v1beta1/namespaces/default/queue_messages_ready
|
||||
|
||||
# Query a metric with label selector
|
||||
curl -k "https://localhost:6443/apis/external.metrics.k8s.io/v1beta1/namespaces/production/error_rate?labelSelector=env=prod,region=us-west"
|
||||
|
||||
# Or via kubectl
|
||||
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/default/queue_messages_ready"
|
||||
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/default/error_rate?labelSelector=env=prod"
|
||||
```
|
||||
|
||||
**Error Response (Metric Not Found):**
|
||||
```bash
|
||||
curl -k https://localhost:6443/apis/external.metrics.k8s.io/v1beta1/namespaces/default/nonexistent_metric
|
||||
# HTTP 404: no metric name called nonexistent_metric
|
||||
```
|
||||
|
||||
**Error Response (Metric Configured to Fail):**
|
||||
```bash
|
||||
# HTTP 500: metric queue_messages_ready is configured to fail
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Metric Management
|
||||
|
||||
#### Create a New Metric
|
||||
```bash
|
||||
# Create a metric with value 250
|
||||
curl -k "https://localhost:6443/create/my_custom_metric?value=250"
|
||||
|
||||
# Create a metric with labels
|
||||
curl -k "https://localhost:6443/create/error_rate?value=25&labels=env=prod,region=us-west"
|
||||
|
||||
# Create a metric that will fail
|
||||
curl -k "https://localhost:6443/create/failing_metric?value=100&fail=true"
|
||||
|
||||
# Create a metric with labels that will fail
|
||||
curl -k "https://localhost:6443/create/error_rate?value=50&labels=env=staging&fail=true"
|
||||
```
|
||||
|
||||
#### Update Metric Value
|
||||
```bash
|
||||
# Update the value of an existing metric
|
||||
curl -k "https://localhost:6443/set/queue_messages_ready?value=500"
|
||||
```
|
||||
|
||||
```bash
|
||||
# Update the value of an existing labels metric
|
||||
curl -k "https://localhost:6443/set/queue_messages_ready?value=500&labels=env=staging"
|
||||
```
|
||||
|
||||
**Error Response (Metric Not Found):**
|
||||
```bash
|
||||
curl -k "https://localhost:6443/set/nonexistent_metric?value=100"
|
||||
# HTTP 404: metric nonexistent_metric not found
|
||||
```
|
||||
|
||||
#### Configure Metric Failure State
|
||||
```bash
|
||||
# Make a metric fail (return HTTP 500)
|
||||
curl -k "https://localhost:6443/fail/queue_messages_ready?fail=true"
|
||||
|
||||
# Make a metric succeed again
|
||||
curl -k "https://localhost:6443/fail/queue_messages_ready?fail=false"
|
||||
|
||||
# Make a metric with specific labels fail
|
||||
curl -k "https://localhost:6443/fail/error_rate?fail=true&labels=env=prod,region=us-west"
|
||||
|
||||
# Make a labeled metric succeed again
|
||||
curl -k "https://localhost:6443/fail/error_rate?fail=false&labels=env=prod,region=us-west"
|
||||
```
|
||||
### Querying Metrics with Labels
|
||||
```bash
|
||||
# Get all response_time metrics (returns all label variants)
|
||||
curl -k "https://localhost:6443/apis/external.metrics.k8s.io/v1beta1/namespaces/default/response_time"
|
||||
|
||||
# Get only prod environment metrics
|
||||
curl -k "https://localhost:6443/apis/external.metrics.k8s.io/v1beta1/namespaces/default/response_time?labelSelector=env=prod"
|
||||
|
||||
# Get specific metric with exact label match
|
||||
curl -k "https://localhost:6443/apis/external.metrics.k8s.io/v1beta1/namespaces/default/response_time?labelSelector=env=prod,service=api"
|
||||
```
|
||||
|
||||
## Default Metrics
|
||||
|
||||
The server starts with two pre-configured metrics:
|
||||
|
||||
1. **queue_messages_ready** - Initial value: 100
|
||||
2. **http_requests_total** - Initial value: 500
|
||||
@@ -1 +0,0 @@
|
||||
1.0.0
|
||||
Reference in New Issue
Block a user