k8s.io/kubernetes@v1.29.3/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  
   270  Usage:
   271  
   272  ```console
   273      kubectl exec test-agnhost -- /agnhost grpc-health-checking \
   274        [--delay-unhealthy-sec 5] [--service ""] \
   275        [--port 5000] [--http-port 8080]
   276  
   277      kubectl exec test-agnhost -- curl http://localhost:8080/make-not-serving
   278  ```
   279  
   280  ### logs-generator
   281  
   282  The `logs-generator` subcommand is a tool to create predictable load on the logs delivery system.
   283  It generates random lines with predictable format and predictable average length.
   284  Each line can be later uniquely identified to ensure logs delivery.
   285  
   286  Tool is parametrized with the total number of number that should be generated and the duration of
   287  the generation process. For example, if you want to create a throughput of 100 lines per second
   288  for a minute, you set total number of lines to 6000 and duration to 1 minute.
   289  
   290  Parameters are passed through CLI flags. There are no defaults, you should always pass the flags
   291  to the container. Total number of line is parametrized through the flag `--log-lines-total`
   292  and duration in go format is parametrized through the flag `--run-duration`.
   293  
   294  Inside the container all log lines are written to the stdout.
   295  
   296  Each line is on average 100 bytes long and follows this pattern:
   297  
   298  ```
   299  2000-12-31T12:59:59Z <id> <method> /api/v1/namespaces/<namespace>/endpoints/<random_string> <random_number>
   300  ```
   301  
   302  Where `<id>` refers to the number from 0 to `total_lines - 1`, which is unique for each
   303  line in a given run of the container.
   304  
   305  Examples:
   306  
   307  ```console
   308  docker run -i \
   309    registry.k8s.io/e2e-test-images/agnhost:2.40 \
   310    logs-generator --log-lines-total 10 --run-duration 1s
   311  ```
   312  
   313  ```console
   314  kubectl run logs-generator \
   315    --generator=run-pod/v1 \
   316    --image=registry.k8s.io/e2e-test-images/agnhost:2.40 \
   317    --restart=Never \
   318    -- logs-generator -t 10 -d 1s
   319  ```
   320  
   321  ### mounttest
   322  
   323  The `mounttest` subcommand can be used to create files with various permissions, read files,
   324  and output file system type, mode, owner, and permissions for any given file.
   325  
   326  The subcommand can accept the following flags:
   327  
   328  - `fs_type`: Path to print the FS type for.
   329  - `file_mode`: Path to print the mode bits of.
   330  - `file_perm`: Path to print the perms of.
   331  - `file_owner`: Path to print the owning UID and GID of.
   332  - `new_file_0644`: Path to write to and read from with perm 0644.
   333  - `new_file_0666`: Path to write to and read from with perm 0666.
   334  - `new_file_0660`: Path to write to and read from with perm 0660.
   335  - `new_file_0777`: Path to write to and read from with perm 0777.
   336  - `file_content`: Path to read the file content from.
   337  - `file_content_in_loop`: Path to read the file content in loop from.
   338  - `retry_time` (default: 180): Retry time during the loop.
   339  - `break_on_expected_content` (default: true): Break out of loop on expected content (use with `--file_content_in_loop` flag only).
   340  
   341  Usage:
   342  
   343  ```console
   344      kubectl exec test-agnhost -- /agnhost mounttest \
   345          [--fs_type <path>] [--file_mode <path>] [--file_perm <path>] [--file_owner <path>] \
   346          [--new_file_0644 <path>] [--new_file_0666 <path>] [--new_file_0660 <path>] [--new_file_0777 <path>] \
   347          [--file_content <path>] [--file_content_in_loop <path>] \
   348          [--retry_time <seconds>] [--break_on_expected_content <true_or_false>]
   349  ```
   350  
   351  
   352  ### net
   353  
   354  The goal of this Go project is to consolidate all low-level
   355  network testing "daemons" into one place. In network testing we
   356  frequently have need of simple daemons (common/Runner) that perform
   357  some "trivial" set of actions on a socket.
   358  
   359  Usage:
   360  
   361  * A package for each general area that is being tested, for example
   362    `nat/` will contain Runners that test various NAT features.
   363  * Every runner should be registered via `main.go:makeRunnerMap()`.
   364  * Runners receive a JSON options structure as to their configuration. `Run()`
   365    should return the disposition of the test.
   366  
   367  Runners can be executed into two different ways, either through the
   368  command-line or via an HTTP request:
   369  
   370  Command-line:
   371  
   372  ```console
   373      kubectl exec test-agnhost -- /agnhost net --runner <runner> --options <json>
   374      kubectl exec test-agnhost -- /agnhost net \
   375          --runner nat-closewait-client \
   376          --options '{"RemoteAddr":"127.0.0.1:9999"}'
   377  ```
   378  
   379  HTTP server:
   380  
   381  ```console
   382      kubectl exec test-agnhost -- /agnhost net --serve :8889
   383      kubectl exec test-agnhost -- curl -v -X POST localhost:8889/run/nat-closewait-server \
   384          -d '{"LocalAddr":"127.0.0.1:9999"}'
   385  ```
   386  
   387  ### netexec
   388  
   389  Starts a HTTP(S) server on given port with the following endpoints:
   390  
   391  - `/`: Returns the request's timestamp.
   392  - `/clientip`: Returns the request's IP address.
   393  - `/dial`: Creates a given number of requests to the given host and port using the given protocol,
   394    and returns a JSON with the fields `responses` (successful request responses) and `errors` (
   395    failed request responses). Returns `200 OK` status code if the last request succeeded,
   396    `417 Expectation Failed` if it did not, or `400 Bad Request` if any of the endpoint's parameters
   397    is invalid. The endpoint's parameters are:
   398    - `host`: The host that will be dialed.
   399    - `port`: The port that will be dialed.
   400    - `request`: The HTTP endpoint or data to be sent through UDP. If not specified, it will result
   401      in a `400 Bad Request` status code being returned.
   402    - `protocol`: The protocol which will be used when making the request. Default value: `http`.
   403      Acceptable values: `http`, `udp`, `sctp`.
   404    - `tries`: The number of times the request will be performed. Default value: `1`.
   405  - `/echo`: Returns the given `msg` (`/echo?msg=echoed_msg`), with the optional status `code`.
   406  - `/exit`: Closes the server with the given code and graceful shutdown. The endpoint's parameters
   407  	are:
   408  	- `code`: The exit code for the process. Default value: 0. Allows an integer [0-127].
   409  	- `timeout`: The amount of time to wait for connections to close before shutting down.
   410  		Acceptable values are golang durations. If 0 the process will exit immediately without
   411  		shutdown.
   412  	- `wait`: The amount of time to wait before starting shutdown. Acceptable values are
   413  	  golang durations. If 0 the process will start shutdown immediately.
   414  - `/healthz`: Returns `200 OK` if the server is ready, `412 Status Precondition Failed`
   415    otherwise. The server is considered not ready if the UDP server did not start yet or
   416    it exited.
   417  - `/hostname`: Returns the server's hostname.
   418  - `/hostName`: Returns the server's hostname.
   419  - `/redirect`: Returns a redirect response to the given `location`, with the optional status `code`
   420    (`/redirect?location=/echo%3Fmsg=foobar&code=307`).
   421  - `/shell`: Executes the given `shellCommand` or `cmd` (`/shell?cmd=some-command`) and
   422    returns a JSON containing the fields `output` (command's output) and `error` (command's
   423    error message). Returns `200 OK` if the command succeeded, `417 Expectation Failed` if not.
   424  - `/shutdown`: Closes the server with the exit code 0.
   425  - `/upload`: Accepts a file to be uploaded, writing it in the `/uploads` folder on the host.
   426    Returns a JSON with the fields `output` (containing the file's name on the server) and
   427    `error` containing any potential server side errors.
   428  
   429  If `--tls-cert-file` is added (ideally in conjunction with `--tls-private-key-file`, the HTTP server
   430  will be upgraded to HTTPS. The image has default, `localhost`-based cert/privkey files at
   431  `/localhost.crt` and `/localhost.key` (see: [`porter` subcommand](#porter))
   432  
   433  If `--http-override` is set, the HTTP(S) server will always serve the override path & options,
   434  ignoring the request URL.
   435  
   436  It will also start a UDP server on the indicated UDP port that responds to the following commands:
   437  
   438  - `hostname`: Returns the server's hostname
   439  - `echo <msg>`: Returns the given `<msg>`
   440  - `clientip`: Returns the request's IP address
   441  
   442  The UDP server can be disabled by setting `--udp-port -1`.
   443  
   444  Additionally, if (and only if) `--sctp-port` is passed, it will start an SCTP server on that port,
   445  responding to the same commands as the UDP server.
   446  
   447  Usage:
   448  
   449  ```console
   450      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>]
   451  ```
   452  
   453  ### nettest
   454  
   455  A tiny web server for checking networking connectivity.
   456  
   457  Will dial out to, and expect to hear from, every pod that is a member of the service
   458  passed in the flag `--service`.
   459  
   460  Will serve a webserver on given `--port`, and will create the following endpoints:
   461  
   462  - `/read`: to see the current state, or `/quit` to shut down.
   463  
   464  - `/status`: to see `pass/running/fail` determination. (literally, it will return
   465  one of those words.)
   466  
   467  - `/write`: is used by other network test pods to register connectivity.
   468  
   469  Usage:
   470  
   471  ```console
   472      kubectl exec test-agnhost -- /agnhost nettest [--port <port>] [--peers <peers>] [--service <service>] [--namespace <namespace>] [--delay-shutdown <delay>]
   473  ```
   474  
   475  
   476  ### no-snat-test
   477  
   478  The subcommand requires the following environment variables to be set, and they should be
   479  valid IP addresses:
   480  
   481  - `POD_IP`
   482  - `NODE_IP`
   483  
   484  Serves the following endpoints on the given port (defaults to `8080`).
   485  
   486  - `/whoami` - returns the request's IP address.
   487  - `/checknosnat` - queries  `ip/whoami` for each provided IP (`/checknosnat?ips=ip1,ip2`),
   488    and if all the response bodies match the `POD_IP`, it will return a 200 response, 500 otherwise.
   489  
   490  Usage:
   491  
   492  ```console
   493      kubectl run test-agnhost \
   494        --generator=run-pod/v1 \
   495        --image=registry.k8s.io/e2e-test-images/agnhost:2.40 \
   496        --restart=Never \
   497        --env "POD_IP=<POD_IP>" \
   498        --env "NODE_IP=<NODE_IP>" \
   499        -- no-snat-test [--port <port>]
   500  ```
   501  
   502  
   503  ### no-snat-test-proxy
   504  
   505  Serves the `/checknosnat` endpoint on the given port (defaults to `31235`). The endpoint
   506  proxies the request to the given `target` (`/checknosnat?target=target_ip&ips=ip1,ip2`
   507  -> `target_ip/checknosnat?ips=ip1,ip2`) and will return the same status as the status
   508  as the proxied request, or 500 on error.
   509  
   510  
   511  Usage:
   512  
   513  ```console
   514      kubectl exec test-agnhost -- /agnhost no-snat-test-proxy [--port <port>]
   515  ```
   516  
   517  
   518  ### pause
   519  
   520  It will pause the execution of the binary. This can be used for containers
   521  which have to be kept in a `Running` state for various purposes, including
   522  executing other `agnhost` commands.
   523  
   524  Usage:
   525  
   526  ```console
   527      kubectl exec test-agnhost -- /agnhost pause
   528  ```
   529  
   530  
   531  ### port-forward-tester
   532  
   533  Listens for TCP connections on a given address and port, optionally checks the data received,
   534  and sends a configurable number of data chunks, with a configurable interval between chunks.
   535  
   536  The subcommand is using the following environment variables:
   537  
   538  - `BIND_ADDRESS` (optional): The address on which it will start listening for TCP connections (default value: `localhost`)
   539  - `BIND_PORT`: The port on which it will start listening for TCP connections.
   540  - `EXPECTED_CLIENT_DATA` (optional): If set, it will check that the request sends the same exact data.
   541  - `CHUNKS`: How many chunks of data to write in the response.
   542  - `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`.
   543  - `CHUNK_INTERVAL`: The amount of time to wait in between chunks.
   544  
   545  Usage:
   546  
   547  ```console
   548      kubectl run test-agnhost \
   549        --generator=run-pod/v1 \
   550        --image=registry.k8s.io/e2e-test-images/agnhost:2.40 \
   551        --restart=Never \
   552        --env "BIND_ADDRESS=localhost" \
   553        --env "BIND_PORT=8080" \
   554        --env "EXPECTED_CLIENT_DATA='Hello there!'" \
   555        --env "CHUNKS=1" \
   556        --env "CHUNK_SIZE=10" \
   557        --env "CHUNK_INTERVAL=1" \
   558        -- port-forward-tester
   559  ```
   560  
   561  
   562  ### porter
   563  
   564  Serves requested data on ports specified in environment variables of the form `SERVE_{PORT,TLS_PORT,SCTP_PORT}_[NNNN]`. eg:
   565      - `SERVE_PORT_9001` - serve TCP connections on port 9001
   566      - `SERVE_TLS_PORT_9002` - serve TLS-encrypted TCP connections on port 9002
   567      - `SERVE_SCTP_PORT_9003` - serve SCTP connections on port 9003
   568  
   569  The included `localhost.crt` is a PEM-encoded TLS cert with SAN IPs `127.0.0.1` and `[::1]`,
   570  expiring in January 2084, generated from `src/crypto/tls`:
   571  
   572  ```console
   573      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
   574  ```
   575  
   576  To use a different cert/key, mount them into the pod and set the `CERT_FILE` and `KEY_FILE`
   577  environment variables to the desired paths.
   578  
   579  Usage:
   580  
   581  ```console
   582      kubectl exec test-agnhost -- /agnhost porter
   583  ```
   584  
   585  ### resource-consumer-controller
   586  
   587  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.
   588  
   589  The subcommand can accept the following flags:
   590  
   591  - `port` (default: 8080): The port number to listen to.
   592  - `consumer-port` (default: 8080): Port number of consumers.
   593  - `consumer-service-name` (default: `resource-consumer`): Name of service containing resource consumers.
   594  - `consumer-service-namespace` (default: `default`): Namespace of service containing resource consumers.
   595  
   596  Usage:
   597  
   598  ```console
   599      kubectl exec test-agnhost -- /agnhost resource-consumer-controller \
   600          [--port <port>] [--consumer-port <port>] [--consumer-service-name <service-name>] [--consumer-service-namespace <namespace>]
   601  ```
   602  
   603  
   604  ### serve-hostname
   605  
   606  This is a small util app to serve your hostname on TCP and/or UDP. Useful for testing.
   607  
   608  The subcommand can accept the following flags:
   609  
   610  - `tcp` (default: `false`): Serve raw over TCP.
   611  - `udp` (default: `false`): Serve raw over UDP.
   612  - `http` (default: `true`): Serve HTTP.
   613  - `close` (default: `false`): Close connection per each HTTP request.
   614  - `port` (default: `9376`): The port number to listen to.
   615  
   616  Keep in mind that `--http` cannot be given at the same time as `--tcp` or `--udp`.
   617  
   618  Usage:
   619  
   620  ```console
   621      kubectl exec test-agnhost -- /agnhost serve-hostname [--tcp] [--udp] [--http] [--close] [--port <port>]
   622  ```
   623  
   624  ### tcp-reset
   625  
   626  Starts a simple TCP servers that reads only one byte of the connection and then closes it,
   627  having the effect of sending a TCP RST to the client.
   628  
   629  The subcommand can accept the following flags:
   630  
   631  - `port` (default: `8080`): The port number to listen to.
   632  
   633  Usage:
   634  
   635  ```console
   636      kubectl exec test-agnhost -- /agnhost tcp-reset [--port <port>]
   637  ```
   638  
   639  Important: This behavior only works if the client send more than 1 byte and is OS
   640  dependant, it is guaranteed to work on Linux.
   641  
   642  ```console
   643  echo -n 1 | nc 192.168.1.4:8080  # FIN
   644  echo -n 12 | nc 192.168.1.4:8080 # RST
   645  ```
   646  
   647  ### test-webserver
   648  
   649  Starts a simple HTTP fileserver which serves any file specified in the URL path, if it exists.
   650  
   651  The subcommand can accept the following flags:
   652  
   653  - `port` (default: `80`): The port number to listen to.
   654  
   655  Usage:
   656  
   657  ```console
   658      kubectl exec test-agnhost -- /agnhost test-webserver [--port <port>]
   659  ```
   660  
   661  
   662  ### webhook (Kubernetes External Admission Webhook)
   663  
   664  The subcommand tests MutatingAdmissionWebhook and ValidatingAdmissionWebhook. After deploying
   665  it to kubernetes cluster, administrator needs to create a MutatingWebhookConfiguration or
   666  ValidatingWebhookConfiguration in kubernetes cluster to register remote webhook admission controllers.
   667  
   668  More details on the configuration can be found from here [Dynamic Admission Control](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/).
   669  
   670  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.
   671  
   672  Usage:
   673  
   674  ```console
   675      kubectl exec test-agnhost -- /agnhost webhook [--tls-cert-file <key-file>] [--tls-private-key-file <cert-file>]
   676  ```
   677  
   678  
   679  ## Other tools
   680  
   681  The image contains `iperf`, `curl`, `dns-tools` (including `dig`), CoreDNS, for both Windows and Linux.
   682  
   683  For Windows, the image is based on `busybox`, meaning that most of the Linux common tools are also
   684  available on it, making it possible to run most Linux commands in the `agnhost` Windows container
   685  as well. Keep in mind that there might still be some differences though (e.g.: `wget` does not
   686  have the `-T` argument on Windows).
   687  
   688  The Windows `agnhost` image includes a `nc` binary that is 100% compliant with its Linux equivalent.
   689  
   690  
   691  ## Image
   692  
   693  The image can be found at `registry.k8s.io/e2e-test-images/agnhost:2.40` for both Linux and
   694  Windows containers (based on `mcr.microsoft.com/windows/nanoserver:1809` and
   695  `mcr.microsoft.com/windows/nanoserver:ltsc2022`).