diff --git a/.travis.yml b/.travis.yml index 9a4bed585..bcd0ff760 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,7 @@ before_script: - ./etcd-v2.3.1-linux-amd64/etcd & # If docker is available, pull the kubernetes hyperkube image down and launch kubernetes. - if which docker &>/dev/null ; then docker pull gcr.io/google_containers/hyperkube-amd64:v1.2.4 ; docker ps -a ; fi - - if which docker &>/dev/null ; then ./middleware/kubernetes/test/00_run_k8s.sh && ./middleware/kubernetes/test/10_setup_kubectl.sh && ./middleware/kubernetes/test/20_setup_k8s_services.sh ; docker ps -a ; fi + - if which docker &>/dev/null ; then ./contrib/kubernetes/testscripts/start_k8s_with_services.sh ; docker ps -a ; fi # Get golang dependencies, and build coredns binary - go get -v -d - go get github.com/coreos/go-etcd/etcd @@ -45,4 +45,4 @@ before_script: script: - go test -tags etcd -race -bench=. ./... # Run kubernetes integration tests only if kubectl is available. i.e. If kubernetes was launched - - ./middleware/kubernetes/test/kubectl version && go test -tags k8s -race -bench=. -run 'TestK8sIntegration' ./test + - ./contrib/kubernetes/testscripts/kubectl version && go test -tags k8s -race -bench=. -run 'TestK8sIntegration' ./test diff --git a/middleware/kubernetes/test/00_run_k8s.sh b/contrib/kubernetes/testscripts/00_run_k8s.sh similarity index 96% rename from middleware/kubernetes/test/00_run_k8s.sh rename to contrib/kubernetes/testscripts/00_run_k8s.sh index 1d1eb338c..ef98a8eed 100755 --- a/middleware/kubernetes/test/00_run_k8s.sh +++ b/contrib/kubernetes/testscripts/00_run_k8s.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -e + # Based on instructions at: http://kubernetes.io/docs/getting-started-guides/docker/ #K8S_VERSION=$(curl -sS https://storage.googleapis.com/kubernetes-release/release/latest.txt) @@ -19,6 +21,8 @@ else DNS_ARGUMENTS="" fi +echo "Starting kubernetes..." + docker run -d \ --volume=/:/rootfs:ro \ --volume=/sys:/sys:ro \ diff --git a/middleware/kubernetes/test/10_setup_kubectl.sh b/contrib/kubernetes/testscripts/10_setup_kubectl.sh similarity index 92% rename from middleware/kubernetes/test/10_setup_kubectl.sh rename to contrib/kubernetes/testscripts/10_setup_kubectl.sh index c3658e2bb..17786715f 100755 --- a/middleware/kubernetes/test/10_setup_kubectl.sh +++ b/contrib/kubernetes/testscripts/10_setup_kubectl.sh @@ -1,9 +1,14 @@ #!/bin/bash +set -e + PWD=`pwd` BASEDIR=`readlink -e $(dirname ${0})` cd ${BASEDIR} + +echo "Setting up kubectl..." + if [ ! -e kubectl ]; then curl -O http://storage.googleapis.com/kubernetes-release/release/v1.2.4/bin/linux/amd64/kubectl chmod u+x kubectl diff --git a/middleware/kubernetes/test/15_run_skydns.sh b/contrib/kubernetes/testscripts/15_run_skydns.sh similarity index 100% rename from middleware/kubernetes/test/15_run_skydns.sh rename to contrib/kubernetes/testscripts/15_run_skydns.sh diff --git a/middleware/kubernetes/test/20_setup_k8s_services.sh b/contrib/kubernetes/testscripts/20_setup_k8s_services.sh similarity index 70% rename from middleware/kubernetes/test/20_setup_k8s_services.sh rename to contrib/kubernetes/testscripts/20_setup_k8s_services.sh index 1eb993543..b2f45008d 100755 --- a/middleware/kubernetes/test/20_setup_k8s_services.sh +++ b/contrib/kubernetes/testscripts/20_setup_k8s_services.sh @@ -39,7 +39,6 @@ create_namespaces() { # run_and_expose_service run_and_expose_service() { - if [ "${#}" != "4" ]; then return -1 fi @@ -49,7 +48,7 @@ run_and_expose_service() { image="${3}" port="${4}" - echo " starting service '${service}' in namespace '${namespace}" + echo " starting service '${service}' in namespace '${namespace}'" ${KUBECTL} get deployment --namespace=${namespace} --no-headers 2>/dev/null | grep -q ${service} if [ "${?}" != "0" ]; then @@ -67,6 +66,29 @@ run_and_expose_service() { } +#run_and_expose_rc nginx-controller nginx-rc.yml poddemo 80 +run_and_expose_rc() { + if [ "${#}" != "4" ]; then + return -1 + fi + + rc_name="${1}" + rc_file="${2}" + namespace="${3}" + port="${4}" + + echo " starting replication controller '${rc_name}' from '${rc_file}' in namespace '${namespace}'" + + ${KUBECTL} get rc --namespace=${namespace} --no-headers 2>/dev/null | grep -q ${rc_name} + if [ "${?}" != "0" ]; then + ${KUBECTL} expose -f ${rc_file} --namespace=${namespace} --port=${port} + else + echo "warn: rc '${rc_name}' already running in namespace '${namespace}'" + fi +} + +echo "Starting sample kubernetes services..." + wait_until_k8s_ready NAMESPACES="demo poddemo test" @@ -84,4 +106,14 @@ echo "" echo "Services exposed:" ${KUBECTL} get services --all-namespaces +echo "" +echo "Starting replicationcontrollers:" + +run_and_expose_rc nginx-controller nginx-rc.yml poddemo 80 + +echo "" +echo "ReplicationControllers exposed:" +${KUBECTL} get rc --all-namespaces + + cd ${PWD} diff --git a/middleware/kubernetes/test/README.md b/contrib/kubernetes/testscripts/README.md similarity index 68% rename from middleware/kubernetes/test/README.md rename to contrib/kubernetes/testscripts/README.md index eea1bf7d3..9642b42a8 100644 --- a/middleware/kubernetes/test/README.md +++ b/contrib/kubernetes/testscripts/README.md @@ -6,9 +6,17 @@ Requirements: The scripts in this directory startup kubernetes with docker as the container runtime. After starting kubernetes, a couple of kubernetes services are started to allow automatic -testing of CoreDNS with kubernetes. +testing of CoreDNS with kubernetes. The kubernetes integration tests in `test/kubernetes_test.go` depend on having some sample services running. The scripts in this folder +automate the launch of kubernetes and the creation of the expected sample services. -To use, run the scripts as: +To start up kubernetes and launch some sample services, +run the script `start_k8s_with_services.sh`. + +~~~ +$ ./start_k8s_with_services.sh +~~~ + +Alternatively, the individual scripts may be run independently as needed: ~~~ $ ./00_run_k8s.sh && ./10_setup_kubectl.sh && ./20_setup_k8s_services.sh diff --git a/middleware/kubernetes/test/kill_all_containers.sh b/contrib/kubernetes/testscripts/kill_all_containers.sh similarity index 100% rename from middleware/kubernetes/test/kill_all_containers.sh rename to contrib/kubernetes/testscripts/kill_all_containers.sh diff --git a/contrib/kubernetes/testscripts/nginx-rc.yml b/contrib/kubernetes/testscripts/nginx-rc.yml new file mode 100644 index 000000000..4597de409 --- /dev/null +++ b/contrib/kubernetes/testscripts/nginx-rc.yml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: nginx-controller + namespace: poddemo +spec: + replicas: 2 + selector: + role: load-balancer + template: + metadata: + labels: + role: load-balancer + spec: + containers: + - name: nginx + image: coreos/nginx + ports: + - containerPort: 80 diff --git a/contrib/kubernetes/testscripts/start_k8s_with_services.sh b/contrib/kubernetes/testscripts/start_k8s_with_services.sh new file mode 100755 index 000000000..40db49715 --- /dev/null +++ b/contrib/kubernetes/testscripts/start_k8s_with_services.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +PWD=`pwd` +BASEDIR=`readlink -e $(dirname ${0})` + +cd ${BASEDIR} + +./00_run_k8s.sh && \ +./10_setup_kubectl.sh && \ +./20_setup_k8s_services.sh + +cd ${PWD} diff --git a/middleware/kubernetes/README.md b/middleware/kubernetes/README.md index 024e448db..7301506bf 100644 --- a/middleware/kubernetes/README.md +++ b/middleware/kubernetes/README.md @@ -3,7 +3,8 @@ `kubernetes` enables reading zone data from a kubernetes cluster. Record names are constructed as "myservice.mynamespace.coredns.local" where: -* "myservice" is the name of the k8s service (this may include multiple DNS labels, such as "c1.myservice"), +* "myservice" is the name of the k8s service (this may include multiple DNS labels, + such as "c1.myservice"), * "mynamespace" is the k8s namespace for the service, and * "coredns.local" is the zone configured for `kubernetes`. @@ -50,7 +51,7 @@ This is the default kubernetes setup, with everything specified in full: # API documentation: http://kubernetes.io/docs/user-guide/labels/ # Example selector below only exposes objects tagged as # "application=nginx" in the staging or qa environments. - #labels environment in (staging, qa),application=nginx + labels environment in (staging, qa),application=nginx } # Perform DNS response caching for the coredns.local zone # Cache timeout is provided by the integer in seconds @@ -66,46 +67,20 @@ Defaults: is required. The label selector syntax is described in the kubernetes API documentation at: http://kubernetes.io/docs/user-guide/labels/ +### Template syntax +Record name templates can be constructed using the symbolic elements: +| template symbol | description | +| `{service}` | Kubernetes object/service name. | +| `{namespace}` | The kubernetes namespace. | +| `{type}` | The type of the kubernetes object. Supports values 'svc' and 'pod'. | +| `{zone}` | The zone configured for the kubernetes middleware. | + ### Basic Setup #### Launch Kubernetes -Kubernetes is launched using the commands in the following `run_k8s.sh` script: +Kubernetes is launched using the commands in the `contrib/kubernetes/testscripts/00_run_k8s.sh` script. -~~~ -#!/bin/bash - -# Based on instructions at: http://kubernetes.io/docs/getting-started-guides/docker/ - -#K8S_VERSION=$(curl -sS https://storage.googleapis.com/kubernetes-release/release/latest.txt) -K8S_VERSION="v1.2.4" - -ARCH="amd64" - -export K8S_VERSION -export ARCH - -#DNS_ARGUMENTS="--cluster-dns=10.0.0.10 --cluster-domain=cluster.local" -DNS_ARGUMENTS="" - -docker run -d \ - --volume=/:/rootfs:ro \ - --volume=/sys:/sys:ro \ - --volume=/var/lib/docker/:/var/lib/docker:rw \ - --volume=/var/lib/kubelet/:/var/lib/kubelet:rw \ - --volume=/var/run:/var/run:rw \ - --net=host \ - --pid=host \ - --privileged \ - gcr.io/google_containers/hyperkube-${ARCH}:${K8S_VERSION} \ - /hyperkube kubelet \ - --containerized \ - --hostname-override=127.0.0.1 \ - --api-servers=http://localhost:8080 \ - --config=/etc/kubernetes/manifests \ - ${DNS_ARGUMENTS} \ - --allow-privileged --v=2 -~~~ #### Configure kubectl and test @@ -115,31 +90,8 @@ The kubernetes control client can be downloaded from the generic URL: For example, the kubectl client for Linux can be downloaded using the command: `curl -sSL "http://storage.googleapis.com/kubernetes-release/release/v1.2.4/bin/linux/amd64/kubectl"` -The following `setup_kubectl.sh` script can be stored in the same directory as -kubectl to setup -kubectl to communicate with kubernetes running on the localhost: - -~~~ -#!/bin/bash - -BASEDIR=`readlink -e $(dirname ${0})` - -${BASEDIR}/kubectl config set-cluster test-doc --server=http://localhost:8080 -${BASEDIR}/kubectl config set-context test-doc --cluster=test-doc -${BASEDIR}/kubectl config use-context test-doc - -alias kubctl="${BASEDIR}/kubectl" -~~~ - - -Verify that kubectl is working by querying for the kubernetes namespaces: - -~~~ -$ ./kubectl get namespaces -NAME STATUS AGE -default Active 8d -test Active 7d -~~~ +The `contrib/kubernetes/testscripts/10_setup_kubectl.sh` script can be stored in the same directory as +kubectl to setup kubectl to communicate with kubernetes running on the localhost. #### Launch a kubernetes service and expose the service @@ -158,6 +110,10 @@ $ ./kubectl expose deployment mynginx --namespace=demo --port=80 $ ./kubectl get service --namespace=demo ~~~ +The script `contrib/kubernetes/testscripts/20_setup_k8s_services.sh` creates a couple of sample namespaces +with services running in those namespaces. The automated kubernetes integration tests in +`test/kubernetes_test.go` depend on these services and namespaces to exist in kubernetes. + #### Launch CoreDNS diff --git a/middleware/kubernetes/kubernetes.go b/middleware/kubernetes/kubernetes.go index 4fa1e494b..5e2a1bf53 100644 --- a/middleware/kubernetes/kubernetes.go +++ b/middleware/kubernetes/kubernetes.go @@ -56,7 +56,7 @@ func (g *Kubernetes) StartKubeCache() error { return err } if g.LabelSelector == nil { - log.Printf("[INFO] Kubernetes middleware configured without a label selector. No label-based filtering will be operformed.") + log.Printf("[INFO] Kubernetes middleware configured without a label selector. No label-based filtering will be performed.") } else { var selector labels.Selector selector, err = unversionedapi.LabelSelectorAsSelector(g.LabelSelector)