Merge pull request #78390 from bclau/test-images/centralize-images-to-agnhost-part-2

Centralizes images into agnhost (part 2)
This commit is contained in:
Kubernetes Prow Robot 2019-06-14 02:51:04 -07:00 committed by GitHub
commit aa125b4dd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 380 additions and 565 deletions

View File

@ -66,7 +66,7 @@ go_library(
"//test/e2e/framework/providers/gce:go_default_library",
"//test/e2e/framework/ssh:go_default_library",
"//test/e2e/network/scale:go_default_library",
"//test/images/net/nat:go_default_library",
"//test/images/agnhost/net/nat:go_default_library",
"//test/utils:go_default_library",
"//test/utils/image:go_default_library",
"//vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud:go_default_library",

View File

@ -30,7 +30,7 @@ import (
"k8s.io/kubernetes/test/e2e/framework"
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
e2essh "k8s.io/kubernetes/test/e2e/framework/ssh"
"k8s.io/kubernetes/test/images/net/nat"
"k8s.io/kubernetes/test/images/agnhost/net/nat"
imageutils "k8s.io/kubernetes/test/utils/image"
"github.com/onsi/ginkgo"

View File

@ -23,9 +23,6 @@ filegroup(
"//test/images/logs-generator:all-srcs",
"//test/images/metadata-concealment:all-srcs",
"//test/images/mounttest:all-srcs",
"//test/images/net:all-srcs",
"//test/images/netexec:all-srcs",
"//test/images/nettest:all-srcs",
"//test/images/no-snat-test:all-srcs",
"//test/images/no-snat-test-proxy:all-srcs",
"//test/images/nonewprivs:all-srcs",
@ -39,7 +36,6 @@ filegroup(
"//test/images/sample-device-plugin:all-srcs",
"//test/images/serve-hostname:all-srcs",
"//test/images/test-webserver:all-srcs",
"//test/images/webhook:all-srcs",
],
tags = ["automanaged"],
)

View File

@ -0,0 +1,5 @@
linux/amd64=alpine:3.6
linux/arm=arm32v6/alpine:3.6
linux/arm64=arm64v8/alpine:3.6
linux/ppc64le=ppc64le/alpine:3.6
linux/s390x=s390x/alpine:3.6

View File

@ -21,7 +21,12 @@ go_library(
],
importpath = "k8s.io/kubernetes/test/images/agnhost",
deps = [
"//test/images/agnhost/net:go_default_library",
"//test/images/agnhost/netexec:go_default_library",
"//test/images/agnhost/nettest:go_default_library",
"//test/images/agnhost/webhook:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
],
)
@ -34,6 +39,12 @@ filegroup(
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
srcs = [
":package-srcs",
"//test/images/agnhost/net:all-srcs",
"//test/images/agnhost/netexec:all-srcs",
"//test/images/agnhost/nettest:all-srcs",
"//test/images/agnhost/webhook:all-srcs",
],
tags = ["automanaged"],
)

View File

@ -12,7 +12,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
FROM scratch
FROM BASEIMAGE
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
# from hostexec image
# install necessary packages:
# - curl, nc: used by a lot of e2e tests
# - iproute2: includes ss used in NodePort tests
RUN apk --update add curl netcat-openbsd iproute2 && rm -rf /var/cache/apk/*
# PORT 8080 needed by: netexec, nettest
# PORT 8081 needed by: netexec
EXPOSE 8080 8081
# from netexec
RUN mkdir /uploads
ADD agnhost agnhost
ENTRYPOINT ["/agnhost"]

View File

@ -41,7 +41,7 @@ For example, let's consider the following `pod.yaml` file:
containers:
- args:
- dns-suffix
image: gcr.io/kubernetes-e2e-test-images/agnhost:1.0
image: gcr.io/kubernetes-e2e-test-images/agnhost:2.1
name: agnhost
dnsConfig:
nameservers:
@ -72,8 +72,125 @@ created with the `pause` argument instead, allowing us execute multiple commands
kubectl exec test-agnhost -- /agnhost dns-server-list
```
The `agnhost` binary is a CLI with the following subcommands:
### net
The goal of this Go project is to consolidate all low-level
network testing "daemons" into one place. In network testing we
frequently have need of simple daemons (common/Runner) that perform
some "trivial" set of actions on a socket.
Usage:
* A package for each general area that is being tested, for example
`nat/` will contain Runners that test various NAT features.
* Every runner should be registered via `main.go:makeRunnerMap()`.
* Runners receive a JSON options structure as to their configuration. `Run()`
should return the disposition of the test.
Runners can be executed into two different ways, either through the
command-line or via an HTTP request:
Command-line:
```console
kubectl exec test-agnhost -- /agnhost net --runner <runner> --options <json>
kubectl exec test-agnhost -- /agnhost net \
--runner nat-closewait-client \
--options '{"RemoteAddr":"127.0.0.1:9999"}'
```
HTTP server:
```console
kubectl exec test-agnhost -- /agnhost net --serve :8889
kubectl exec test-agnhost -- curl -v -X POST localhost:8889/run/nat-closewait-server \
-d '{"LocalAddr":"127.0.0.1:9999"}'
```
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/test/images/net/README.md?pixel)]()
### netexec
Starts a HTTP server on given TCP / UDP ports with the following endpoints:
- `/`: Returns the request's timestamp.
- `/clientip`: Returns the request's IP address.
- `/dial`: Creates a given number of requests to the given host and port using the given protocol,
and returns a JSON with the fields `responses` (successful request responses) and `errors` (
failed request responses). Returns `200 OK` status code if the last request succeeded,
`417 Expectation Failed` if it did not, or `400 Bad Request` if any of the endpoint's parameters
is invalid. The endpoint's parameters are:
- `host`: The host that will be dialed.
- `port`: The port that will be dialed.
- `request`: The HTTP endpoint or data to be sent through UDP. If not specified, it will result
in a `400 Bad Request` status code being returned.
- `protocol`: The protocol which will be used when making the request. Default value: `http`.
Acceptable values: `http`, `udp`.
- `tries`: The number of times the request will be performed. Default value: `1`.
- `/echo`: Returns the given `msg` (`/echo?msg=echoed_msg`)
- `/exit`: Closes the server with the given code (`/exit?code=some-code`). The `code`
is expected to be an integer [0-127] or empty; if it is not, it will return an error message.
- `/healthz`: Returns `200 OK` if the server is ready, `412 Status Precondition Failed`
otherwise. The server is considered not ready if the UDP server did not start yet or
it exited.
- `/hostname`: Returns the server's hostname.
- `/hostName`: Returns the server's hostname.
- `/shell`: Executes the given `shellCommand` or `cmd` (`/shell?cmd=some-command`) and
returns a JSON containing the fields `output` (command's output) and `error` (command's
error message). Returns `200 OK` if the command succeeded, `417 Expectation Failed` if not.
- `/shutdown`: Closes the server with the exit code 0.
- `/upload`: Accepts a file to be uploaded, writing it in the `/uploads` folder on the host.
Returns a JSON with the fields `output` (containing the file's name on the server) and
`error` containing any potential server side errors.
Usage:
```console
kubectl exec test-agnhost -- /agnhost netexec [--http-port <http-port>] [--udp-port <udp-port>]
```
### nettest
A tiny web server for checking networking connectivity.
Will dial out to, and expect to hear from, every pod that is a member of the service
passed in the flag `--service`.
Will serve a webserver on given `--port`, and will create the following endpoints:
- `/read`: to see the current state, or `/quit` to shut down.
- `/status`: to see `pass/running/fail` determination. (literally, it will return
one of those words.)
- `/write`: is used by other network test pods to register connectivity.
Usage:
```console
kubectl exec test-agnhost -- /agnhost nettest [--port <port>] [--peers <peers>] [--service <service>] [--namespace <namespace>] [--delay-shutdown <delay>]
```
### webhook (Kubernetes External Admission Webhook)
The subcommand tests MutatingAdmissionWebhook and ValidatingAdmissionWebhook. After deploying
it to kubernetes cluster, administrator needs to create a ValidatingWebhookConfiguration
in kubernetes cluster to register remote webhook admission controllers.
TODO: add the reference when the document for admission webhook v1beta1 API is done.
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.
Usage:
```console
kubectl exec test-agnhost -- /agnhost webhook [--tls-cert-file <key-file>] [--tls-private-key-file <cert-file>]
```
## Image
The image can be found at `gcr.io/kubernetes-e2e-test-images/agnhost:1.0` for Linux
containers, and `e2eteam/agnhost:1.0` for Windows containers. In the future, the same
The image can be found at `gcr.io/kubernetes-e2e-test-images/agnhost:2.1` for Linux
containers, and `e2eteam/agnhost:2.1` for Windows containers. In the future, the same
repository can be used for both OSes.

View File

@ -1 +1 @@
1.0
2.1

View File

@ -17,7 +17,15 @@ limitations under the License.
package main
import (
"flag"
"github.com/spf13/cobra"
"k8s.io/klog"
"k8s.io/kubernetes/test/images/agnhost/net"
"k8s.io/kubernetes/test/images/agnhost/netexec"
"k8s.io/kubernetes/test/images/agnhost/nettest"
"k8s.io/kubernetes/test/images/agnhost/webhook"
)
func main() {
@ -58,5 +66,16 @@ func main() {
rootCmd.AddCommand(cmdDNSServerList)
rootCmd.AddCommand(cmdEtcHosts)
rootCmd.AddCommand(cmdPause)
rootCmd.AddCommand(net.CmdNet)
rootCmd.AddCommand(netexec.CmdNetexec)
rootCmd.AddCommand(nettest.CmdNettest)
rootCmd.AddCommand(webhook.CmdWebhook)
// 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.
loggingFlags := &flag.FlagSet{}
klog.InitFlags(loggingFlags)
rootCmd.PersistentFlags().AddGoFlagSet(loggingFlags)
rootCmd.Execute()
}

View File

@ -2,22 +2,17 @@ package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "net",
embed = [":go_default_library"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
importpath = "k8s.io/kubernetes/test/images/net",
importpath = "k8s.io/kubernetes/test/images/agnhost/net",
deps = [
"//test/images/net/common:go_default_library",
"//test/images/net/nat:go_default_library",
"//test/images/agnhost/net/common:go_default_library",
"//test/images/agnhost/net/nat:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
],
)
@ -32,8 +27,8 @@ filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//test/images/net/common:all-srcs",
"//test/images/net/nat:all-srcs",
"//test/images/agnhost/net/common:all-srcs",
"//test/images/agnhost/net/nat:all-srcs",
],
tags = ["automanaged"],
)

View File

@ -8,7 +8,7 @@ load(
go_library(
name = "go_default_library",
srcs = ["common.go"],
importpath = "k8s.io/kubernetes/test/images/net/common",
importpath = "k8s.io/kubernetes/test/images/agnhost/net/common",
)
filegroup(

View File

@ -14,12 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package net
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
@ -27,8 +26,10 @@ import (
"os"
"strings"
"k8s.io/kubernetes/test/images/net/common"
"k8s.io/kubernetes/test/images/net/nat"
"github.com/spf13/cobra"
"k8s.io/kubernetes/test/images/agnhost/net/common"
"k8s.io/kubernetes/test/images/agnhost/net/nat"
)
type runnerMap map[string]common.Runner
@ -49,8 +50,42 @@ type logOutput struct {
b bytes.Buffer
}
func main() {
initFlags()
// CmdNet is used by agnhost Cobra.
var CmdNet = &cobra.Command{
Use: "net",
Short: "Creates webserver or runner for various networking tests",
Long: `The subcommand will run the network tester in server mode if the "--serve" flag is given, and the runners are triggered through HTTP requests.
Alternatively, if the "--runner" flag is given, it will execute the given runner directly. Note that "--runner" and "--serve" flags cannot be given at the same time.
Examples:
agnhost net --runner nat-closewait-client --options '{"RemoteAddr":"127.0.0.1:9999"}'
agnhost net --serve :8889 && curl -v -X POST localhost:8889/run/nat-closewait-server -d '{"LocalAddr":"127.0.0.1:9999"}'
`,
Args: cobra.MaximumNArgs(0),
Run: main,
}
func init() {
legalRunners := ""
for k := range runners {
legalRunners += " " + k
}
CmdNet.Flags().StringVar(&flags.Serve, "serve", "",
"Address and port to bind to (e.g. 127.0.0.1:8080). Setting this will "+
"run the network tester in server mode runner are triggered through "+
"HTTP requests.")
CmdNet.Flags().StringVar(&flags.Runner, "runner", "", "Runner to execute (available:"+legalRunners+")")
CmdNet.Flags().StringVar(&flags.Options, "options", "", "JSON options to the Runner")
}
func main(cmd *cobra.Command, args []string) {
if flags.Runner == "" && flags.Serve == "" {
log.Fatalf("Must set either --runner or --serve, see --help")
}
log.SetFlags(log.Flags() | log.Lshortfile)
if flags.Serve == "" {
@ -70,29 +105,6 @@ func main() {
}
}
func initFlags() {
legalRunners := ""
for k := range runners {
legalRunners += " " + k
}
flag.StringVar(
&flags.Serve, "serve", "",
"Address and port to bind to (e.g. 127.0.0.1:8080). Setting this will "+
"run the network tester in server mode runner are triggered through "+
"HTTP requests.")
flag.StringVar(
&flags.Runner, "runner", "",
"Runner to execute (available:"+legalRunners+")")
flag.StringVar(
&flags.Options, "options", "",
"JSON options to the Runner")
flag.Parse()
if flags.Runner == "" && flags.Serve == "" {
log.Fatalf("Must set either -runner or -serve, see --help")
}
}
func makeRunnerMap() runnerMap {
// runner name is <pkg>-<file>-<specific>.
return runnerMap{

View File

@ -8,8 +8,8 @@ load(
go_library(
name = "go_default_library",
srcs = ["closewait.go"],
importpath = "k8s.io/kubernetes/test/images/net/nat",
deps = ["//test/images/net/common:go_default_library"],
importpath = "k8s.io/kubernetes/test/images/agnhost/net/nat",
deps = ["//test/images/agnhost/net/common:go_default_library"],
)
filegroup(

View File

@ -33,7 +33,7 @@ import (
"net"
"time"
"k8s.io/kubernetes/test/images/net/common"
"k8s.io/kubernetes/test/images/agnhost/net/common"
)
// leakedConnection is a global variable that should leak the active

View File

@ -2,20 +2,17 @@ package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "netexec",
embed = [":go_default_library"],
)
go_library(
name = "go_default_library",
srcs = ["netexec.go"],
importpath = "k8s.io/kubernetes/test/images/netexec",
deps = ["//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library"],
importpath = "k8s.io/kubernetes/test/images/agnhost/netexec",
deps = [
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
],
)
filegroup(

View File

@ -14,11 +14,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package netexec
import (
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
@ -33,6 +32,8 @@ import (
"sync/atomic"
"time"
"github.com/spf13/cobra"
utilnet "k8s.io/apimachinery/pkg/util/net"
)
@ -43,6 +44,50 @@ var (
serverReady = &atomicBool{0}
)
// CmdNetexec is used by agnhost Cobra.
var CmdNetexec = &cobra.Command{
Use: "netexec",
Short: "Creates a HTTP / UDP server with various endpoints",
Long: `Starts a HTTP server on given TCP / UDP ports with the following endpoints:
- /: Returns the request's timestamp.
- /clientip: Returns the request's IP address.
- /dial: Creates a given number of requests to the given host and port using the given protocol,
and returns a JSON with the fields "responses" (successful request responses) and "errors" (
failed request responses). Returns "200 OK" status code if the last request succeeded,
"417 Expectation Failed" if it did not, or "400 Bad Request" if any of the endpoint's parameters
is invalid. The endpoint's parameters are:
- "host": The host that will be dialed.
- "port": The port that will be dialed.
- "request": The HTTP endpoint or data to be sent through UDP. If not specified, it will result
in a "400 Bad Request" status code being returned.
- "protocol": The protocol which will be used when making the request. Default value: "http".
Acceptable values: "http", "udp".
- "tries": The number of times the request will be performed. Default value: "1".
- "/echo": Returns the given "msg" ("/echo?msg=echoed_msg")
- "/exit": Closes the server with the given code ("/exit?code=some-code"). The "code"
is expected to be an integer [0-127] or empty; if it is not, it will return an error message.
- "/healthz": Returns "200 OK" if the server is ready, "412 Status Precondition Failed"
otherwise. The server is considered not ready if the UDP server did not start yet or
it exited.
- "/hostname": Returns the server's hostname.
- "/hostName": Returns the server's hostname.
- "/shell": Executes the given "shellCommand" or "cmd" ("/shell?cmd=some-command") and
returns a JSON containing the fields "output" (command's output) and "error" (command's
error message). Returns "200 OK" if the command succeeded, "417 Expectation Failed" if not.
- "/shutdown": Closes the server with the exit code 0.
- "/upload": Accepts a file to be uploaded, writing it in the "/uploads" folder on the host.
Returns a JSON with the fields "output" (containing the file's name on the server) and
"error" containing any potential server side errors.`,
Args: cobra.MaximumNArgs(0),
Run: main,
}
func init() {
CmdNetexec.Flags().IntVar(&httpPort, "http-port", 8080, "HTTP Listen Port")
CmdNetexec.Flags().IntVar(&udpPort, "udp-port", 8081, "UDP Listen Port")
}
// atomicBool uses load/store operations on an int32 to simulate an atomic boolean.
type atomicBool struct {
v int32
@ -62,13 +107,7 @@ func (a *atomicBool) get() bool {
return atomic.LoadInt32(&a.v) == 1
}
func init() {
flag.IntVar(&httpPort, "http-port", 8080, "HTTP Listen Port")
flag.IntVar(&udpPort, "udp-port", 8081, "UDP Listen Port")
}
func main() {
flag.Parse()
func main(cmd *cobra.Command, args []string) {
go startUDPServer(udpPort)
startHTTPServer(httpPort)
}

View File

@ -2,20 +2,20 @@ package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["nettest.go"],
importpath = "k8s.io/kubernetes/test/images/nettest",
importpath = "k8s.io/kubernetes/test/images/agnhost/nettest",
deps = [
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
],
)
@ -31,8 +31,3 @@ filegroup(
srcs = [":package-srcs"],
tags = ["automanaged"],
)
go_binary(
name = "nettest",
embed = [":go_default_library"],
)

View File

@ -27,12 +27,12 @@ limitations under the License.
// return one of those words.)
//
// /write is used by other network test pods to register connectivity.
package main
package nettest
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
@ -44,6 +44,8 @@ import (
"syscall"
"time"
"github.com/spf13/cobra"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/version"
@ -52,13 +54,42 @@ import (
)
var (
port = flag.Int("port", 8080, "Port number to serve at.")
peerCount = flag.Int("peers", 8, "Must find at least this many peers for the test to pass.")
service = flag.String("service", "nettest", "Service to find other network test pods in.")
namespace = flag.String("namespace", "default", "Namespace of this pod. TODO: kubernetes should make this discoverable.")
delayShutdown = flag.Int("delay-shutdown", 0, "Number of seconds to delay shutdown when receiving SIGTERM.")
port int
peerCount int
service string
namespace string
delayShutdown int
)
// CmdNettest is used by agnhost Cobra.
var CmdNettest = &cobra.Command{
Use: "nettest",
Short: "Starts a tiny web server for checking networking connectivity",
Long: `Starts a web server for checking networking connectivity on the given "--port".
Will dial out to, and expect to hear from, every pod that is a member of the service
passed in the flag "--service".
The web server will have the following endpoints:
- "/read": to see the current state, or "/quit" to shut down.
- "/status": to see "pass/running/fail" determination. (literally, it will return
one of those words.)
- "/write": is used by other network test pods to register connectivity.`,
Args: cobra.MaximumNArgs(0),
Run: main,
}
func init() {
CmdNettest.Flags().IntVar(&port, "port", 8080, "Port number to serve at.")
CmdNettest.Flags().IntVar(&peerCount, "peers", 8, "Must find at least this many peers for the test to pass.")
CmdNettest.Flags().StringVar(&service, "service", "nettest", "Service to find other network test pods in.")
CmdNettest.Flags().StringVar(&namespace, "namespace", "default", "Namespace of this pod. TODO: kubernetes should make this discoverable.")
CmdNettest.Flags().IntVar(&delayShutdown, "delay-shutdown", 0, "Number of seconds to delay shutdown when receiving SIGTERM.")
}
// State tracks the internal state of our little http server.
// It's returned verbatim over the /read endpoint.
type State struct {
@ -85,7 +116,7 @@ func (s *State) doneContactingPeers() {
func (s *State) serveStatus(w http.ResponseWriter, r *http.Request) {
s.lock.Lock()
defer s.lock.Unlock()
if len(s.Sent) >= *peerCount && len(s.Received) >= *peerCount {
if len(s.Sent) >= peerCount && len(s.Received) >= peerCount {
fmt.Fprintf(w, "pass")
return
}
@ -94,7 +125,7 @@ func (s *State) serveStatus(w http.ResponseWriter, r *http.Request) {
return
}
// Logf can't be called while holding the lock, so defer using a goroutine
go s.Logf("Declaring failure for %s/%s with %d sent and %d received and %d peers", *namespace, *service, len(s.Sent), len(s.Received), *peerCount)
go s.Logf("Declaring failure for %s/%s with %d sent and %d received and %d peers", namespace, service, len(s.Sent), len(s.Received), peerCount)
fmt.Fprintf(w, "fail")
}
@ -173,10 +204,8 @@ var (
state State
)
func main() {
flag.Parse()
if *service == "" {
func main(cmd *cobra.Command, args []string) {
if service == "" {
log.Fatal("Must provide -service flag.")
}
@ -185,13 +214,13 @@ func main() {
log.Fatalf("Error getting hostname: %v", err)
}
if *delayShutdown > 0 {
if delayShutdown > 0 {
termCh := make(chan os.Signal)
signal.Notify(termCh, syscall.SIGTERM)
go func() {
<-termCh
log.Printf("Sleeping %d seconds before exit ...", *delayShutdown)
time.Sleep(time.Duration(*delayShutdown) * time.Second)
log.Printf("Sleeping %d seconds before exit ...", delayShutdown)
time.Sleep(time.Duration(delayShutdown) * time.Second)
os.Exit(0)
}()
}
@ -211,7 +240,7 @@ func main() {
http.HandleFunc("/write", state.serveWrite)
http.HandleFunc("/status", state.serveStatus)
go log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
go log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
select {}
}
@ -226,14 +255,14 @@ func contactOthers(state *State) {
// In large cluster getting all endpoints is pretty expensive.
// Thus, we will limit ourselves to send on average at most 10 such
// requests per second
if sleepTime < time.Duration(*peerCount/10)*time.Second {
sleepTime = time.Duration(*peerCount/10) * time.Second
if sleepTime < time.Duration(peerCount/10)*time.Second {
sleepTime = time.Duration(peerCount/10) * time.Second
}
timeout := 5 * time.Minute
// Similarly we need to bump timeout so that it is reasonable in large
// clusters.
if timeout < time.Duration(*peerCount)*time.Second {
timeout = time.Duration(*peerCount) * time.Second
if timeout < time.Duration(peerCount)*time.Second {
timeout = time.Duration(peerCount) * time.Second
}
defer state.doneContactingPeers()
@ -266,10 +295,10 @@ func contactOthers(state *State) {
for start := time.Now(); time.Since(start) < timeout; time.Sleep(sleepTime) {
eps := getWebserverEndpoints(client)
if eps.Len() >= *peerCount {
if eps.Len() >= peerCount {
break
}
state.Logf("%v/%v has %v endpoints (%v), which is less than %v as expected. Waiting for all endpoints to come up.", *namespace, *service, len(eps), eps.List(), *peerCount)
state.Logf("%v/%v has %v endpoints (%v), which is less than %v as expected. Waiting for all endpoints to come up.", namespace, service, len(eps), eps.List(), peerCount)
}
// Do this repeatedly, in case there's some propagation delay with getting
@ -286,10 +315,10 @@ func contactOthers(state *State) {
//getWebserverEndpoints returns the webserver endpoints as a set of String, each in the format like "http://{ip}:{port}"
func getWebserverEndpoints(client clientset.Interface) sets.String {
endpoints, err := client.CoreV1().Endpoints(*namespace).Get(*service, v1.GetOptions{})
endpoints, err := client.CoreV1().Endpoints(namespace).Get(service, v1.GetOptions{})
eps := sets.String{}
if err != nil {
state.Logf("Unable to read the endpoints for %v/%v: %v.", *namespace, *service, err)
state.Logf("Unable to read the endpoints for %v/%v: %v.", namespace, service, err)
return eps
}
for _, ss := range endpoints.Subsets {

View File

@ -1,4 +1,4 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
@ -14,8 +14,8 @@ go_library(
"pods.go",
"scheme.go",
],
importpath = "k8s.io/kubernetes/test/images/webhook",
visibility = ["//visibility:private"],
importpath = "k8s.io/kubernetes/test/images/agnhost/webhook",
visibility = ["//visibility:public"],
deps = [
"//staging/src/k8s.io/api/admission/v1beta1:go_default_library",
"//staging/src/k8s.io/api/admissionregistration/v1beta1:go_default_library",
@ -25,16 +25,11 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
],
)
go_binary(
name = "webhook",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package webhook
import (
"encoding/json"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package webhook
import (
"time"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package webhook
import (
"k8s.io/api/admission/v1beta1"

View File

@ -14,11 +14,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package webhook
import (
"crypto/tls"
"flag"
"k8s.io/klog"
)
@ -29,14 +28,6 @@ type Config struct {
KeyFile string
}
func (c *Config) addFlags() {
flag.StringVar(&c.CertFile, "tls-cert-file", c.CertFile, ""+
"File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated "+
"after server cert).")
flag.StringVar(&c.KeyFile, "tls-private-key-file", c.KeyFile, ""+
"File containing the default x509 private key matching --tls-cert-file.")
}
func configTLS(config Config) *tls.Config {
sCert, err := tls.LoadX509KeyPair(config.CertFile, config.KeyFile)
if err != nil {

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package webhook
import (
"k8s.io/api/admission/v1beta1"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package webhook
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package webhook
import (
"encoding/json"

View File

@ -14,15 +14,16 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package webhook
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"net/http"
"github.com/spf13/cobra"
"k8s.io/api/admission/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog"
@ -30,6 +31,29 @@ import (
// https://github.com/mattbaird/jsonpatch
)
var (
certFile string
keyFile string
)
// CmdWebhook is used by agnhost Cobra.
var CmdWebhook = &cobra.Command{
Use: "webhook",
Short: "Starts a HTTP server, useful for testing MutatingAdmissionWebhook and ValidatingAdmissionWebhook",
Long: `Starts a HTTP server, useful for testing MutatingAdmissionWebhook and ValidatingAdmissionWebhook.
After deploying it to Kubernetes cluster, the Administrator needs to create a ValidatingWebhookConfiguration
in the Kubernetes cluster to register remote webhook admission controllers.`,
Args: cobra.MaximumNArgs(0),
Run: main,
}
func init() {
CmdWebhook.Flags().StringVar(&certFile, "tls-cert-file", "",
"File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated after server cert).")
CmdWebhook.Flags().StringVar(&keyFile, "tls-private-key-file", "",
"File containing the default x509 private key matching --tls-cert-file.")
}
// toAdmissionResponse is a helper function to create an AdmissionResponse
// with an embedded error
func toAdmissionResponse(err error) *v1beta1.AdmissionResponse {
@ -135,11 +159,11 @@ func serveCRD(w http.ResponseWriter, r *http.Request) {
serve(w, r, admitCRD)
}
func main() {
klog.InitFlags(nil)
var config Config
config.addFlags()
flag.Parse()
func main(cmd *cobra.Command, args []string) {
config := Config{
CertFile: certFile,
KeyFile: keyFile,
}
http.HandleFunc("/always-allow-delay-5s", serveAlwaysAllowDelayFiveSeconds)
http.HandleFunc("/always-deny", serveAlwaysDeny)

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package webhook
import (
"encoding/json"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package webhook
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package webhook
import (
admissionv1beta1 "k8s.io/api/admission/v1beta1"

View File

@ -1 +0,0 @@
/net

View File

@ -1,5 +0,0 @@
amd64=alpine:3.6
arm=arm32v6/alpine:3.6
arm64=arm64v8/alpine:3.6
ppc64le=ppc64le/alpine:3.6
s390x=s390x/alpine:3.6

View File

@ -1,20 +0,0 @@
# Copyright 2016 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.
FROM BASEIMAGE
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
COPY net /net
RUN apk update && apk add curl

View File

@ -1,25 +0,0 @@
# Copyright 2016 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=net
ARCH ?= amd64
TARGET ?= $(CURDIR)
GOLANG_VERSION ?= latest
SRC_DIR = $(notdir $(shell pwd))
export
bin:
../image-util.sh bin $(SRCS)
.PHONY: bin

View File

@ -1,36 +0,0 @@
# Overview
The goal of this Go project is to consolidate all low-level
network testing "daemons" into one place. In network testing we
frequently have need of simple daemons (common/Runner) that perform
some "trivial" set of actions on a socket.
# Usage
* A package for each general area that is being tested, for example
`nat/` will contain Runners that test various NAT features.
* Every runner should be registered via `main.go:makeRunnerMap()`.
* Runners receive a JSON options structure as to their configuration. `Run()`
should return the disposition of the test.
Runners can be executed into two different ways, either through the
command-line or via an HTTP request:
## Command-line
````
$ ./net -runner <runner> -options <json>
./net \
-runner nat-closewait-client \
-options '{"RemoteAddr":"127.0.0.1:9999"}'
````
## HTTP server
````
$ ./net --serve :8889
$ curl -v -X POST localhost:8889/run/nat-closewait-server \
-d '{"LocalAddr":"127.0.0.1:9999"}'
````
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/test/images/net/README.md?pixel)]()

View File

@ -1 +0,0 @@
1.0

View File

@ -1 +0,0 @@
netexec

View File

@ -1,5 +0,0 @@
amd64=busybox
arm=arm32v6/busybox
arm64=arm64v8/busybox
ppc64le=ppc64le/busybox
s390x=s390x/busybox

View File

@ -1,25 +0,0 @@
# Copyright 2016 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.
FROM BASEIMAGE
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
ADD netexec netexec
EXPOSE 8080
EXPOSE 8081
RUN mkdir /uploads
ENTRYPOINT ["/netexec"]

View File

@ -1,25 +0,0 @@
# Copyright 2016 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=netexec
ARCH ?= amd64
TARGET ?= $(CURDIR)
GOLANG_VERSION ?= latest
SRC_DIR = $(notdir $(shell pwd))
export
bin:
../image-util.sh bin $(SRCS)
.PHONY: bin

View File

@ -1 +0,0 @@
1.1

View File

@ -1,39 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: netexec
labels:
app: netexec
spec:
containers:
- name: netexec
image: gcr.io/kubernetes-e2e-test-images/netexec-amd64:1.1
ports:
- containerPort: 8080
protocol: TCP
- containerPort: 8081
protocol: UDP
# give this pod the same liveness and readiness probe because
# we always want the kubelet to restart it if it becomes
# unready, and at the same time we want to observe readiness
# as a signal to start testing.
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 5
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
readinessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 5
failureThreshold: 3
periodSeconds: 10
successThreshold: 1

View File

@ -1,18 +0,0 @@
# Copyright 2016 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.
FROM gcr.io/distroless/static:latest
COPY nettest /
EXPOSE 8080
ENTRYPOINT ["/nettest"]

View File

@ -1,25 +0,0 @@
# Copyright 2016 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=nettest
ARCH ?= amd64
TARGET ?= $(CURDIR)
GOLANG_VERSION ?= latest
SRC_DIR = $(notdir $(shell pwd))
export
bin:
../image-util.sh bin $(SRCS)
.PHONY: bin

View File

@ -1 +0,0 @@
1.1

View File

@ -1,44 +0,0 @@
{
"kind": "ReplicationController",
"apiVersion": "v1",
"metadata": {
"name": "nettest-controller",
"labels": {
"name": "nettest"
}
},
"spec": {
"replicas": 2,
"selector": {
"name": "nettest"
},
"template": {
"metadata": {
"labels": {
"name": "nettest"
}
},
"spec": {
"containers": [
{
"name": "webserver",
"image": "gcr.io/kubernetes-e2e-test-images/nettest-amd64:1.0",
"imagePullPolicy": "Always",
"args": [
"-service=nettest",
"-port=8080",
"-namespace=default",
"-peers=2"
],
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
]
}
]
}
}
}
}

View File

@ -1,22 +0,0 @@
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "nettest",
"labels": {
"name": "nettest"
}
},
"spec": {
"ports": [
{
"port": 8080,
"protocol": "TCP",
"targetPort": 8080
}
],
"selector": {
"name": "nettest"
}
}
}

View File

@ -1,28 +0,0 @@
{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "slow-pod",
"labels": {
"name": "nettest"
}
},
"spec": {
"containers": [
{
"name": "webserver",
"image": "gcr.io/kubernetes-e2e-test-images/nettest-amd64:1.0",
"args": [
"-service=nettest",
"-delay-shutdown=10"
],
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
]
}
]
}
}

View File

@ -1,42 +0,0 @@
{
"kind": "ReplicationController",
"apiVersion": "v1",
"metadata": {
"name": "slow-rc",
"labels": {
"name": "nettest"
}
},
"spec": {
"replicas": 8,
"selector": {
"name": "nettest"
},
"template": {
"metadata": {
"labels": {
"name": "nettest"
}
},
"spec": {
"terminationGracePeriodSeconds": 5,
"containers": [
{
"name": "webserver",
"image": "gcr.io/kubernetes-e2e-test-images/nettest-amd64:1.0",
"args": [
"-service=nettest",
"-delay-shutdown=10"
],
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
]
}
]
}
}
}
}

View File

@ -1,4 +0,0 @@
amd64=alpine:3.6
arm=arm32v6/alpine:3.6
arm64=arm64v8/alpine:3.6
ppc64le=ppc64le/alpine:3.6

View File

@ -1,18 +0,0 @@
# Copyright 2017 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.
FROM BASEIMAGE
ADD webhook /webhook
ENTRYPOINT ["/webhook"]

View File

@ -1,25 +0,0 @@
# Copyright 2017 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=webhook
ARCH ?= amd64
TARGET ?= $(CURDIR)
GOLANG_VERSION ?= latest
SRC_DIR = $(notdir $(shell pwd))
export
bin:
../image-util.sh bin $(SRCS)
.PHONY: bin

View File

@ -1,13 +0,0 @@
# Kubernetes External Admission Webhook Test Image
The image tests MutatingAdmissionWebhook and ValidatingAdmissionWebhook. After deploying
it to kubernetes cluster, administrator needs to create a ValidatingWebhookConfiguration
in kubernetes cluster to register remote webhook admission controllers.
TODO: add the reference when the document for admission webhook v1beta1 API is done.
## Build the code
```bash
make build
```

View File

@ -1 +0,0 @@
1.15v1