k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/test/images/agnhost/README.md (about)

     1  # Agnhost
     2  
     3  ## Overview
     4  
     5  There are significant differences between Linux and Windows, especially in the way
     6  something can be obtained or tested. For example, the DNS suffix list can be found in
     7  `/etc/resolv.conf` on Linux, but on Windows, such file does not exist, the same
     8  information could retrieved through other means. To combat those differences,
     9  `agnhost` was created.
    10  
    11  `agnhost` is an extendable CLI that behaves and outputs the same expected content,
    12  no matter the underlying OS. The name itself reflects this idea, being a portmanteau
    13  word of the words agnostic and host.
    14  
    15  The image was created for testing purposes, reducing the need for having different test
    16  cases for the same tested behaviour.
    17  
    18  
    19  ## Usage
    20  
    21  The `agnhost` binary has several subcommands which are can be used to test different
    22  Kubernetes features; their behaviour and output is not affected by the underlying OS.
    23  
    24  For example, let's consider the following `pod.yaml` file:
    25  
    26  ```yaml
    27      apiVersion: v1
    28      kind: Pod
    29      metadata:
    30        name: test-agnhost
    31      spec:
    32        containers:
    33        - args:
    34          - dns-suffix
    35          image: registry.k8s.io/e2e-test-images/agnhost:2.40
    36          name: agnhost
    37        dnsConfig:
    38          nameservers:
    39          - 1.1.1.1
    40          searches:
    41          - resolv.conf.local
    42        dnsPolicy: None
    43  ```
    44  
    45  After we've used it to create a pod:
    46  
    47  ```console
    48      kubectl create -f pod.yaml
    49  ```
    50  
    51  We can then check the container's output to see what is DNS suffix list the Pod was
    52  configured with:
    53  
    54  ```console
    55      kubectl logs pod/test-agnhost
    56  ```
    57  
    58  The output will be `resolv.conf.local`, as expected. Alternatively, the Pod could be
    59  created with the `pause` argument instead, allowing us execute multiple commands:
    60  
    61  ```console
    62      kubectl exec test-agnhost -- /agnhost dns-suffix
    63      kubectl exec test-agnhost -- /agnhost dns-server-list
    64  ```
    65  
    66  The `agnhost` binary is a CLI with the following subcommands:
    67  
    68  
    69  ### audit-proxy
    70  
    71  The audit proxy is used to test dynamic auditing. It listens on port 8080 for incoming audit
    72  events and writes them in a uniform manner to stdout.
    73  
    74  Usage:
    75  
    76  ```console
    77      kubectl exec test-agnhost -- /agnhost audit-proxy
    78  ```
    79  
    80  
    81  ### connect
    82  
    83  Tries to open a TCP or SCTP connection to the given host and port. On error it
    84  prints an error message prefixed with a specific fixed string that
    85  test cases can check for:
    86  
    87  * `UNKNOWN` - Generic/unknown (non-network) error (eg, bad arguments)
    88  * `TIMEOUT` - The connection attempt timed out
    89  * `DNS` - An error in DNS resolution
    90  * `REFUSED` - Connection refused
    91  * `OTHER` - Other networking error (eg, "no route to host")
    92  
    93  (Theoretically it would be nicer for it to distinguish these by exit
    94  code, but it's much easier for test programs to compare strings in the
    95  output than to check the exit code.)
    96  
    97  Usage:
    98  
    99  ```console
   100      kubectl exec test-agnhost -- /agnhost connect [--timeout=<duration>] [--protocol=<protocol>] <host>:<port>
   101  ```
   102  
   103  The optional `--protocol` parameter can be set to `sctp` to test SCTP
   104  connections. The default value is `tcp`.
   105  
   106  ### crd-conversion-webhook
   107  
   108  The subcommand tests `CustomResourceConversionWebhook`. After deploying it to Kubernetes cluster,
   109  the administrator needs to create a `CustomResourceConversion.Webhook` in Kubernetes cluster
   110  to use remote webhook for conversions.
   111  
   112  The subcommand starts a HTTP server, listening on port 443, and creating the `/crdconvert`
   113  endpoint.
   114  
   115  Usage
   116  
   117  ```console
   118      kubectl exec test-agnhost -- /agnhost crd-conversion-webhook \
   119          [--tls-cert-file <tls-cert-file>] [--tls-private-key-file <tls-private-key-file>]
   120  ```
   121  
   122  
   123  ### dns-server-list
   124  
   125  It will output the host's configured DNS servers, separated by commas.
   126  
   127  Usage:
   128  
   129  ```console
   130      kubectl exec test-agnhost -- /agnhost dns-server-list
   131  ```
   132  
   133  
   134  ### dns-suffix
   135  
   136  It will output the host's configured DNS suffix list, separated by commas.
   137  
   138  Usage:
   139  
   140  ```console
   141      kubectl exec test-agnhost -- /agnhost dns-suffix
   142  ```
   143  
   144  
   145  ### entrypoint-tester
   146  
   147  This subcommand will print the arguments it's passed and exists.
   148  
   149  Usage:
   150  
   151  ```console
   152      kubectl exec test-agnhost -- /agnhost entrypoint-tester foo lish args
   153  ```
   154  
   155  
   156  ### etc-hosts
   157  
   158  It will output the contents of host's `hosts` file. This file's location is `/etc/hosts`
   159  on Linux, while on Windows it is `C:/Windows/System32/drivers/etc/hosts`.
   160  
   161  Usage:
   162  
   163  ```console
   164      kubectl exec test-agnhost -- /agnhost etc-hosts
   165  ```
   166  
   167  
   168  ### fake-gitserver
   169  
   170  Fakes a git server. When doing `git clone http://localhost:8000`, you will clone an empty git
   171  repo named `localhost` on local. You can also use `git clone http://localhost:8000 my-repo-name` to
   172  rename that repo. Access to the service with the backing pod will show you below information.
   173  
   174  ```console
   175  curl -w "\n" http://localhost:8000
   176  I am a fake git server
   177  ```
   178  
   179  Usage:
   180  
   181  ```console
   182      kubectl exec test-agnhost -- /agnhost fake-gitserver
   183  ```
   184  
   185  
   186  ### guestbook
   187  
   188  Starts a HTTP server on the given `--http-port` (default: 80), serving various endpoints representing a
   189  guestbook app. The endpoints and their purpose are:
   190  
   191  - `/register`: A guestbook replica will subscribe to a primary, to its given `--replicaof` endpoint. The primary
   192    will then push any updates it receives to its registered replicas through the `--backend-port` (default: 6379).
   193  - `/get`: Returns `{"data": value}`, where the `value` is the stored value for the given `key` if non-empty,
   194    or the entire store.
   195  - `/set`: Will set the given key-value pair in its own store and propagate it to its replicas, if any.
   196    Will return `{"data": "Updated"}` to the caller on success.
   197  - `/guestbook`: Will proxy the request to `agnhost-primary` if the given `cmd` is `set`, or `agnhost-replica`
   198    if the given `cmd` is `get`.
   199  
   200  Usage:
   201  
   202  ```console
   203  guestbook="test/e2e/testing-manifests/guestbook"
   204  sed_expr="s|{{.AgnhostImage}}|registry.k8s.io/e2e-test-images/agnhost:2.40|"
   205  
   206  # create the services.
   207  kubectl create -f ${guestbook}/frontend-service.yaml
   208  kubectl create -f ${guestbook}/agnhost-primary-service.yaml
   209  kubectl create -f ${guestbook}/agnhost-replica-service.yaml
   210  
   211  # create the deployments.
   212  cat ${guestbook}/frontend-deployment.yaml.in | sed ${sed_expr} | kubectl create -f -
   213  cat ${guestbook}/agnhost-primary-deployment.yaml.in | sed ${sed_expr} | kubectl create -f -
   214  cat ${guestbook}/agnhost-replica-deployment.yaml.in | sed ${sed_expr} | kubectl create -f -
   215  ```
   216  
   217  
   218  ### help
   219  
   220  Prints the binary's help menu. Additionally, it can be followed by another subcommand
   221  in order to get more information about that subcommand, including its possible arguments.
   222  
   223  Usage:
   224  
   225  ```console
   226      kubectl exec test-agnhost -- /agnhost help
   227  ```
   228  
   229  
   230  ### inclusterclient
   231  
   232  The subcommand will periodically poll the Kubernetes `/healthz` endpoint using the in-cluster
   233  config. Because of this, the subcommand is meant to be run inside of a Kubernetes pod. It can
   234  also be used to validate token rotation.
   235  
   236  The given `--poll-interval` flag (default is 30 seconds) represents the poll interval in
   237  seconds of the call to `/healhz`.
   238  
   239  Usage:
   240  
   241  ```console
   242      kubectl exec test-agnhost -- /agnhost inclusterclient [--poll-interval <poll-interval>]
   243  ```
   244  
   245  
   246  ### liveness
   247  
   248  Starts a simple server that is alive for 10 seconds, then reports unhealthy for the rest
   249  of its (hopefully) short existence.
   250  
   251  Usage:
   252  
   253  ```console
   254      kubectl exec test-agnhost -- /agnhost liveness
   255  ```
   256  
   257  ### grpc-health-checking
   258  
   259  Started the gRPC health checking server. The health checking response can be
   260  controlled with the time delay or via http control server.
   261  
   262  - `--delay-unhealthy-sec` - the delay to change status to NOT_SERVING.
   263    Endpoint reporting SERVING for `delay-unhealthy-sec` (`-1` by default)
   264    seconds and then NOT_SERVING. Negative value indicates always SERVING. Use `0` to
   265    start endpoint as NOT_SERVING.
   266  - `--port` (default: `5000`) can be used to override the gRPC port number.
   267  - `--http-port` (default: `8080`) can be used to override the http control server port number.
   268  - `--service` (default: ``) can be used used to specify which service this endpoint will respond to.
   269  - `--tls-cert-file` File containing an x509 certificate for gRPC TLS. (CA cert, if any, concatenated after server cert).
   270  - `--tls-private-key-file` File containing an x509 private key matching `--tls-cert-file`.
   271  
   272  Usage:
   273  
   274  ```console
   275      kubectl exec test-agnhost -- /agnhost grpc-health-checking \
   276        [--delay-unhealthy-sec 5] [--service ""] \
   277        [--port 5000] [--http-port 8080]
   278  
   279      kubectl exec test-agnhost -- curl http://localhost:8080/make-not-serving
   280  ```
   281  
   282  ### logs-generator
   283  
   284  The `logs-generator` subcommand is a tool to create predictable load on the logs delivery system.
   285  It generates random lines with predictable format and predictable average length.
   286  Each line can be later uniquely identified to ensure logs delivery.
   287  
   288  Tool is parametrized with the total number of number that should be generated and the duration of
   289  the generation process. For example, if you want to create a throughput of 100 lines per second
   290  for a minute, you set total number of lines to 6000 and duration to 1 minute.
   291  
   292  Parameters are passed through CLI flags. There are no defaults, you should always pass the flags
   293  to the container. Total number of line is parametrized through the flag `--log-lines-total`
   294  and duration in go format is parametrized through the flag `--run-duration`.
   295  
   296  Inside the container all log lines are written to the stdout.
   297  
   298  Each line is on average 100 bytes long and follows this pattern:
   299  
   300  ```
   301  2000-12-31T12:59:59Z <id> <method> /api/v1/namespaces/<namespace>/endpoints/<random_string> <random_number>
   302  ```
   303  
   304  Where `<id>` refers to the number from 0 to `total_lines - 1`, which is unique for each
   305  line in a given run of the container.
   306  
   307  Examples:
   308  
   309  ```console
   310  docker run -i \
   311    registry.k8s.io/e2e-test-images/agnhost:2.40 \
   312    logs-generator --log-lines-total 10 --run-duration 1s
   313  ```
   314  
   315  ```console
   316  kubectl run logs-generator \
   317    --generator=run-pod/v1 \
   318    --image=registry.k8s.io/e2e-test-images/agnhost:2.40 \
   319    --restart=Never \
   320    -- logs-generator -t 10 -d 1s
   321  ```
   322  
   323  ### mounttest
   324  
   325  The `mounttest` subcommand can be used to create files with various permissions, read files,
   326  and output file system type, mode, owner, and permissions for any given file.
   327  
   328  The subcommand can accept the following flags:
   329  
   330  - `fs_type`: Path to print the FS type for.
   331  - `file_mode`: Path to print the mode bits of.
   332  - `file_perm`: Path to print the perms of.
   333  - `file_owner`: Path to print the owning UID and GID of.
   334  - `new_file_0644`: Path to write to and read from with perm 0644.
   335  - `new_file_0666`: Path to write to and read from with perm 0666.
   336  - `new_file_0660`: Path to write to and read from with perm 0660.
   337  - `new_file_0777`: Path to write to and read from with perm 0777.
   338  - `file_content`: Path to read the file content from.
   339  - `file_content_in_loop`: Path to read the file content in loop from.
   340  - `retry_time` (default: 180): Retry time during the loop.
   341  - `break_on_expected_content` (default: true): Break out of loop on expected content (use with `--file_content_in_loop` flag only).
   342  
   343  Usage:
   344  
   345  ```console
   346      kubectl exec test-agnhost -- /agnhost mounttest \
   347          [--fs_type <path>] [--file_mode <path>] [--file_perm <path>] [--file_owner <path>] \
   348          [--new_file_0644 <path>] [--new_file_0666 <path>] [--new_file_0660 <path>] [--new_file_0777 <path>] \
   349          [--file_content <path>] [--file_content_in_loop <path>] \
   350          [--retry_time <seconds>] [--break_on_expected_content <true_or_false>]
   351  ```
   352  
   353  
   354  ### net
   355  
   356  The goal of this Go project is to consolidate all low-level
   357  network testing "daemons" into one place. In network testing we
   358  frequently have need of simple daemons (common/Runner) that perform
   359  some "trivial" set of actions on a socket.
   360  
   361  Usage:
   362  
   363  * A package for each general area that is being tested, for example
   364    `nat/` will contain Runners that test various NAT features.
   365  * Every runner should be registered via `main.go:makeRunnerMap()`.
   366  * Runners receive a JSON options structure as to their configuration. `Run()`
   367    should return the disposition of the test.
   368  
   369  Runners can be executed into two different ways, either through the
   370  command-line or via an HTTP request:
   371  
   372  Command-line:
   373  
   374  ```console
   375      kubectl exec test-agnhost -- /agnhost net --runner <runner> --options <json>
   376      kubectl exec test-agnhost -- /agnhost net \
   377          --runner nat-closewait-client \
   378          --options '{"RemoteAddr":"127.0.0.1:9999"}'
   379  ```
   380  
   381  HTTP server:
   382  
   383  ```console
   384      kubectl exec test-agnhost -- /agnhost net --serve :8889
   385      kubectl exec test-agnhost -- curl -v -X POST localhost:8889/run/nat-closewait-server \
   386          -d '{"LocalAddr":"127.0.0.1:9999"}'
   387  ```
   388  
   389  ### netexec
   390  
   391  Starts a HTTP(S) server on given port with the following endpoints:
   392  
   393  - `/`: Returns the request's timestamp.
   394  - `/clientip`: Returns the request's IP address.
   395  - `/dial`: Creates a given number of requests to the given host and port using the given protocol,
   396    and returns a JSON with the fields `responses` (successful request responses) and `errors` (
   397    failed request responses). Returns `200 OK` status code if the last request succeeded,
   398    `417 Expectation Failed` if it did not, or `400 Bad Request` if any of the endpoint's parameters
   399    is invalid. The endpoint's parameters are:
   400    - `host`: The host that will be dialed.
   401    - `port`: The port that will be dialed.
   402    - `request`: The HTTP endpoint or data to be sent through UDP. If not specified, it will result
   403      in a `400 Bad Request` status code being returned.
   404    - `protocol`: The protocol which will be used when making the request. Default value: `http`.
   405      Acceptable values: `http`, `udp`, `sctp`.
   406    - `tries`: The number of times the request will be performed. Default value: `1`.
   407  - `/echo`: Returns the given `msg` (`/echo?msg=echoed_msg`), with the optional status `code`.
   408  - `/exit`: Closes the server with the given code and graceful shutdown. The endpoint's parameters
   409  	are:
   410  	- `code`: The exit code for the process. Default value: 0. Allows an integer [0-127].
   411  	- `timeout`: The amount of time to wait for connections to close before shutting down.
   412  		Acceptable values are golang durations. If 0 the process will exit immediately without
   413  		shutdown.
   414  	- `wait`: The amount of time to wait before starting shutdown. Acceptable values are
   415  	  golang durations. If 0 the process will start shutdown immediately.
   416  - `/healthz`: Returns `200 OK` if the server is ready, `412 Status Precondition Failed`
   417    otherwise. The server is considered not ready if the UDP server did not start yet or
   418    it exited.
   419  - `/hostname`: Returns the server's hostname.
   420  - `/hostName`: Returns the server's hostname.
   421  - `/redirect`: Returns a redirect response to the given `location`, with the optional status `code`
   422    (`/redirect?location=/echo%3Fmsg=foobar&code=307`).
   423  - `/shell`: Executes the given `shellCommand` or `cmd` (`/shell?cmd=some-command`) and
   424    returns a JSON containing the fields `output` (command's output) and `error` (command's
   425    error message). Returns `200 OK` if the command succeeded, `417 Expectation Failed` if not.
   426  - `/shutdown`: Closes the server with the exit code 0.
   427  - `/upload`: Accepts a file to be uploaded, writing it in the `/uploads` folder on the host.
   428    Returns a JSON with the fields `output` (containing the file's name on the server) and
   429    `error` containing any potential server side errors.
   430  
   431  If `--tls-cert-file` is added (ideally in conjunction with `--tls-private-key-file`, the HTTP server
   432  will be upgraded to HTTPS. The image has default, `localhost`-based cert/privkey files at
   433  `/localhost.crt` and `/localhost.key` (see: [`porter` subcommand](#porter))
   434  
   435  If `--http-override` is set, the HTTP(S) server will always serve the override path & options,
   436  ignoring the request URL.
   437  
   438  It will also start a UDP server on the indicated UDP port that responds to the following commands:
   439  
   440  - `hostname`: Returns the server's hostname
   441  - `echo <msg>`: Returns the given `<msg>`
   442  - `clientip`: Returns the request's IP address
   443  
   444  The UDP server can be disabled by setting `--udp-port -1`.
   445  
   446  Additionally, if (and only if) `--sctp-port` is passed, it will start an SCTP server on that port,
   447  responding to the same commands as the UDP server.
   448  
   449  Usage:
   450  
   451  ```console
   452      kubectl exec test-agnhost -- /agnhost netexec [--http-port <http-port>] [--udp-port <udp-port>] [--sctp-port <sctp-port>] [--tls-cert-file <cert-file>] [--tls-private-key-file <privkey-file>]
   453  ```
   454  
   455  ### nettest
   456  
   457  A tiny web server for checking networking connectivity.
   458  
   459  Will dial out to, and expect to hear from, every pod that is a member of the service
   460  passed in the flag `--service`.
   461  
   462  Will serve a webserver on given `--port`, and will create the following endpoints:
   463  
   464  - `/read`: to see the current state, or `/quit` to shut down.
   465  
   466  - `/status`: to see `pass/running/fail` determination. (literally, it will return
   467  one of those words.)
   468  
   469  - `/write`: is used by other network test pods to register connectivity.
   470  
   471  Usage:
   472  
   473  ```console
   474      kubectl exec test-agnhost -- /agnhost nettest [--port <port>] [--peers <peers>] [--service <service>] [--namespace <namespace>] [--delay-shutdown <delay>]
   475  ```
   476  
   477  
   478  ### no-snat-test
   479  
   480  The subcommand requires the following environment variables to be set, and they should be
   481  valid IP addresses:
   482  
   483  - `POD_IP`
   484  - `NODE_IP`
   485  
   486  Serves the following endpoints on the given port (defaults to `8080`).
   487  
   488  - `/whoami` - returns the request's IP address.
   489  - `/checknosnat` - queries  `ip/whoami` for each provided IP (`/checknosnat?ips=ip1,ip2`),
   490    and if all the response bodies match the `POD_IP`, it will return a 200 response, 500 otherwise.
   491  
   492  Usage:
   493  
   494  ```console
   495      kubectl run test-agnhost \
   496        --generator=run-pod/v1 \
   497        --image=registry.k8s.io/e2e-test-images/agnhost:2.40 \
   498        --restart=Never \
   499        --env "POD_IP=<POD_IP>" \
   500        --env "NODE_IP=<NODE_IP>" \
   501        -- no-snat-test [--port <port>]
   502  ```
   503  
   504  
   505  ### no-snat-test-proxy
   506  
   507  Serves the `/checknosnat` endpoint on the given port (defaults to `31235`). The endpoint
   508  proxies the request to the given `target` (`/checknosnat?target=target_ip&ips=ip1,ip2`
   509  -> `target_ip/checknosnat?ips=ip1,ip2`) and will return the same status as the status
   510  as the proxied request, or 500 on error.
   511  
   512  
   513  Usage:
   514  
   515  ```console
   516      kubectl exec test-agnhost -- /agnhost no-snat-test-proxy [--port <port>]
   517  ```
   518  
   519  
   520  ### pause
   521  
   522  It will pause the execution of the binary. This can be used for containers
   523  which have to be kept in a `Running` state for various purposes, including
   524  executing other `agnhost` commands.
   525  
   526  Usage:
   527  
   528  ```console
   529      kubectl exec test-agnhost -- /agnhost pause
   530  ```
   531  
   532  
   533  ### port-forward-tester
   534  
   535  Listens for TCP connections on a given address and port, optionally checks the data received,
   536  and sends a configurable number of data chunks, with a configurable interval between chunks.
   537  
   538  The subcommand is using the following environment variables:
   539  
   540  - `BIND_ADDRESS` (optional): The address on which it will start listening for TCP connections (default value: `localhost`)
   541  - `BIND_PORT`: The port on which it will start listening for TCP connections.
   542  - `EXPECTED_CLIENT_DATA` (optional): If set, it will check that the request sends the same exact data.
   543  - `CHUNKS`: How many chunks of data to write in the response.
   544  - `CHUNK_SIZE`: The expected size of each written chunk of data. If it does not match the actual size of the written data, it will exit with the exit code `4`.
   545  - `CHUNK_INTERVAL`: The amount of time to wait in between chunks.
   546  
   547  Usage:
   548  
   549  ```console
   550      kubectl run test-agnhost \
   551        --generator=run-pod/v1 \
   552        --image=registry.k8s.io/e2e-test-images/agnhost:2.40 \
   553        --restart=Never \
   554        --env "BIND_ADDRESS=localhost" \
   555        --env "BIND_PORT=8080" \
   556        --env "EXPECTED_CLIENT_DATA='Hello there!'" \
   557        --env "CHUNKS=1" \
   558        --env "CHUNK_SIZE=10" \
   559        --env "CHUNK_INTERVAL=1" \
   560        -- port-forward-tester
   561  ```
   562  
   563  
   564  ### porter
   565  
   566  Serves requested data on ports specified in environment variables of the form `SERVE_{PORT,TLS_PORT,SCTP_PORT}_[NNNN]`. eg:
   567      - `SERVE_PORT_9001` - serve TCP connections on port 9001
   568      - `SERVE_TLS_PORT_9002` - serve TLS-encrypted TCP connections on port 9002
   569      - `SERVE_SCTP_PORT_9003` - serve SCTP connections on port 9003
   570  
   571  The included `localhost.crt` is a PEM-encoded TLS cert with SAN IPs `127.0.0.1` and `[::1]`,
   572  expiring in January 2084, generated from `src/crypto/tls`:
   573  
   574  ```console
   575      go run generate_cert.go  --rsa-bits 2048 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
   576  ```
   577  
   578  To use a different cert/key, mount them into the pod and set the `CERT_FILE` and `KEY_FILE`
   579  environment variables to the desired paths.
   580  
   581  Usage:
   582  
   583  ```console
   584      kubectl exec test-agnhost -- /agnhost porter
   585  ```
   586  
   587  ### resource-consumer-controller
   588  
   589  This subcommand starts an HTTP server that spreads requests around resource consumers. The HTTP server has the same endpoints and usage as the one spawned by the ``resource-consumer`` subcommand.
   590  
   591  The subcommand can accept the following flags:
   592  
   593  - `port` (default: 8080): The port number to listen to.
   594  - `consumer-port` (default: 8080): Port number of consumers.
   595  - `consumer-service-name` (default: `resource-consumer`): Name of service containing resource consumers.
   596  - `consumer-service-namespace` (default: `default`): Namespace of service containing resource consumers.
   597  
   598  Usage:
   599  
   600  ```console
   601      kubectl exec test-agnhost -- /agnhost resource-consumer-controller \
   602          [--port <port>] [--consumer-port <port>] [--consumer-service-name <service-name>] [--consumer-service-namespace <namespace>]
   603  ```
   604  
   605  
   606  ### serve-hostname
   607  
   608  This is a small util app to serve your hostname on TCP and/or UDP. Useful for testing.
   609  
   610  The subcommand can accept the following flags:
   611  
   612  - `tcp` (default: `false`): Serve raw over TCP.
   613  - `udp` (default: `false`): Serve raw over UDP.
   614  - `http` (default: `true`): Serve HTTP.
   615  - `close` (default: `false`): Close connection per each HTTP request.
   616  - `port` (default: `9376`): The port number to listen to.
   617  
   618  Keep in mind that `--http` cannot be given at the same time as `--tcp` or `--udp`.
   619  
   620  Usage:
   621  
   622  ```console
   623      kubectl exec test-agnhost -- /agnhost serve-hostname [--tcp] [--udp] [--http] [--close] [--port <port>]
   624  ```
   625  
   626  ### tcp-reset
   627  
   628  Starts a simple TCP servers that reads only one byte of the connection and then closes it,
   629  having the effect of sending a TCP RST to the client.
   630  
   631  The subcommand can accept the following flags:
   632  
   633  - `port` (default: `8080`): The port number to listen to.
   634  
   635  Usage:
   636  
   637  ```console
   638      kubectl exec test-agnhost -- /agnhost tcp-reset [--port <port>]
   639  ```
   640  
   641  Important: This behavior only works if the client send more than 1 byte and is OS
   642  dependant, it is guaranteed to work on Linux.
   643  
   644  ```console
   645  echo -n 1 | nc 192.168.1.4:8080  # FIN
   646  echo -n 12 | nc 192.168.1.4:8080 # RST
   647  ```
   648  
   649  ### test-webserver
   650  
   651  Starts a simple HTTP fileserver which serves any file specified in the URL path, if it exists.
   652  
   653  The subcommand can accept the following flags:
   654  
   655  - `port` (default: `80`): The port number to listen to.
   656  
   657  Usage:
   658  
   659  ```console
   660      kubectl exec test-agnhost -- /agnhost test-webserver [--port <port>]
   661  ```
   662  
   663  
   664  ### webhook (Kubernetes External Admission Webhook)
   665  
   666  The subcommand tests MutatingAdmissionWebhook and ValidatingAdmissionWebhook. After deploying
   667  it to kubernetes cluster, administrator needs to create a MutatingWebhookConfiguration or
   668  ValidatingWebhookConfiguration in kubernetes cluster to register remote webhook admission controllers.
   669  
   670  More details on the configuration can be found from here [Dynamic Admission Control](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/).
   671  
   672  Check the [MutatingAdmissionWebhook](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/#mutatingwebhookconfiguration-v1beta1-admissionregistration-k8s-io) and [ValidatingAdmissionWebhook](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/#validatingwebhookconfiguration-v1beta1-admissionregistration-k8s-io) documentations for more information about them.
   673  
   674  Usage:
   675  
   676  ```console
   677      kubectl exec test-agnhost -- /agnhost webhook [--tls-cert-file <key-file>] [--tls-private-key-file <cert-file>]
   678  ```
   679  
   680  
   681  ## Other tools
   682  
   683  The image contains `iperf`, `curl`, `dns-tools` (including `dig`), CoreDNS, for both Windows and Linux.
   684  
   685  For Windows, the image is based on `busybox`, meaning that most of the Linux common tools are also
   686  available on it, making it possible to run most Linux commands in the `agnhost` Windows container
   687  as well. Keep in mind that there might still be some differences though (e.g.: `wget` does not
   688  have the `-T` argument on Windows).
   689  
   690  The Windows `agnhost` image includes a `nc` binary that is 100% compliant with its Linux equivalent.
   691  
   692  
   693  ## Image
   694  
   695  The image can be found at `registry.k8s.io/e2e-test-images/agnhost:2.40` for both Linux and
   696  Windows containers (based on `mcr.microsoft.com/windows/nanoserver:1809` and
   697  `mcr.microsoft.com/windows/nanoserver:ltsc2022`).