diff --git a/middleware/kubernetes/README.md b/middleware/kubernetes/README.md
index d3faeef7f..7e7cb679e 100644
--- a/middleware/kubernetes/README.md
+++ b/middleware/kubernetes/README.md
@@ -28,6 +28,7 @@ kubernetes [ZONES...] {
     labels EXPRESSION
     pods POD-MODE
     upstream ADDRESS...
+    ttl TTL
     fallthrough
 }
 ```
@@ -62,6 +63,8 @@ kubernetes [ZONES...] {
 * `upstream` **ADDRESS [ADDRESS...]** defines the upstream resolvers used for resolving services
   that point to external hosts (External Services).  **ADDRESS** can be an ip, an ip:port, or a path
   to a file structured like resolv.conf.
+* `ttl` allows you to set a custom TTL for responses. The default (and allowed minimum) is to use
+  5 seconds, the maximum is capped at 3600 seconds.
 * `fallthrough`  If a query for a record in the cluster zone results in NXDOMAIN, normally that is
   what the response will be. However, if you specify this option, the query will instead be passed
   on down the middleware chain, which can include another middleware to handle the query.
diff --git a/middleware/kubernetes/handler_test.go b/middleware/kubernetes/handler_test.go
index e3ddfb071..c65fd516f 100644
--- a/middleware/kubernetes/handler_test.go
+++ b/middleware/kubernetes/handler_test.go
@@ -16,33 +16,33 @@ var dnsTestCases = map[string](test.Case){
 		Qname: "svc1.testns.svc.cluster.local.", Qtype: dns.TypeA,
 		Rcode: dns.RcodeSuccess,
 		Answer: []dns.RR{
-			test.A("svc1.testns.svc.cluster.local.	0	IN	A	10.0.0.1"),
+			test.A("svc1.testns.svc.cluster.local.	5	IN	A	10.0.0.1"),
 		},
 	},
 	"A Service (wildcard)": {
 		Qname: "svc1.*.svc.cluster.local.", Qtype: dns.TypeA,
 		Rcode: dns.RcodeSuccess,
 		Answer: []dns.RR{
-			test.A("svc1.*.svc.cluster.local.  0       IN      A       10.0.0.1"),
+			test.A("svc1.*.svc.cluster.local.  5       IN      A       10.0.0.1"),
 		},
 	},
 	"SRV Service (wildcard)": {
 		Qname: "svc1.*.svc.cluster.local.", Qtype: dns.TypeSRV,
 		Rcode: dns.RcodeSuccess,
-		Answer: []dns.RR{test.SRV("svc1.*.svc.cluster.local.	0	IN	SRV	0 100 80 svc1.testns.svc.cluster.local.")},
-		Extra: []dns.RR{test.A("svc1.testns.svc.cluster.local.  0       IN      A       10.0.0.1")},
+		Answer: []dns.RR{test.SRV("svc1.*.svc.cluster.local.	303	IN	SRV	0 100 80 svc1.testns.svc.cluster.local.")},
+		Extra: []dns.RR{test.A("svc1.testns.svc.cluster.local.  303       IN      A       10.0.0.1")},
 	},
 	"SRV Service (wildcards)": {
 		Qname: "*.any.svc1.*.svc.cluster.local.", Qtype: dns.TypeSRV,
 		Rcode: dns.RcodeSuccess,
-		Answer: []dns.RR{test.SRV("*.any.svc1.*.svc.cluster.local.	0	IN	SRV	0 100 80 svc1.testns.svc.cluster.local.")},
-		Extra: []dns.RR{test.A("svc1.testns.svc.cluster.local.  0       IN      A       10.0.0.1")},
+		Answer: []dns.RR{test.SRV("*.any.svc1.*.svc.cluster.local.	303	IN	SRV	0 100 80 svc1.testns.svc.cluster.local.")},
+		Extra: []dns.RR{test.A("svc1.testns.svc.cluster.local.  303       IN      A       10.0.0.1")},
 	},
 	"A Service (wildcards)": {
 		Qname: "*.any.svc1.*.svc.cluster.local.", Qtype: dns.TypeA,
 		Rcode: dns.RcodeSuccess,
 		Answer: []dns.RR{
-			test.A("*.any.svc1.*.svc.cluster.local.  0       IN      A       10.0.0.1"),
+			test.A("*.any.svc1.*.svc.cluster.local.  303       IN      A       10.0.0.1"),
 		},
 	},
 	"SRV Service Not udp/tcp": {
@@ -56,37 +56,37 @@ var dnsTestCases = map[string](test.Case){
 		Qname: "_http._tcp.svc1.testns.svc.cluster.local.", Qtype: dns.TypeSRV,
 		Rcode: dns.RcodeSuccess,
 		Answer: []dns.RR{
-			test.SRV("_http._tcp.svc1.testns.svc.cluster.local.	0	IN	SRV	0 100 80 svc1.testns.svc.cluster.local."),
+			test.SRV("_http._tcp.svc1.testns.svc.cluster.local.	303	IN	SRV	0 100 80 svc1.testns.svc.cluster.local."),
 		},
 		Extra: []dns.RR{
-			test.A("svc1.testns.svc.cluster.local.	0	IN	A	10.0.0.1"),
+			test.A("svc1.testns.svc.cluster.local.	303	IN	A	10.0.0.1"),
 		},
 	},
 	"A Service (Headless)": {
 		Qname: "hdls1.testns.svc.cluster.local.", Qtype: dns.TypeA,
 		Rcode: dns.RcodeSuccess,
 		Answer: []dns.RR{
-			test.A("hdls1.testns.svc.cluster.local.	0	IN	A	172.0.0.2"),
-			test.A("hdls1.testns.svc.cluster.local.	0	IN	A	172.0.0.3"),
+			test.A("hdls1.testns.svc.cluster.local.	303	IN	A	172.0.0.2"),
+			test.A("hdls1.testns.svc.cluster.local.	303	IN	A	172.0.0.3"),
 		},
 	},
 	"SRV Service (Headless)": {
 		Qname: "_http._tcp.hdls1.testns.svc.cluster.local.", Qtype: dns.TypeSRV,
 		Rcode: dns.RcodeSuccess,
 		Answer: []dns.RR{
-			test.SRV("_http._tcp.hdls1.testns.svc.cluster.local.	0	IN	SRV	0 50 80 172-0-0-2.hdls1.testns.svc.cluster.local."),
-			test.SRV("_http._tcp.hdls1.testns.svc.cluster.local.	0	IN	SRV	0 50 80 172-0-0-3.hdls1.testns.svc.cluster.local."),
+			test.SRV("_http._tcp.hdls1.testns.svc.cluster.local.	303	IN	SRV	0 50 80 172-0-0-2.hdls1.testns.svc.cluster.local."),
+			test.SRV("_http._tcp.hdls1.testns.svc.cluster.local.	303	IN	SRV	0 50 80 172-0-0-3.hdls1.testns.svc.cluster.local."),
 		},
 		Extra: []dns.RR{
-			test.A("172-0-0-2.hdls1.testns.svc.cluster.local.	0	IN	A	172.0.0.2"),
-			test.A("172-0-0-3.hdls1.testns.svc.cluster.local.	0	IN	A	172.0.0.3"),
+			test.A("172-0-0-2.hdls1.testns.svc.cluster.local.	303	IN	A	172.0.0.2"),
+			test.A("172-0-0-3.hdls1.testns.svc.cluster.local.	303	IN	A	172.0.0.3"),
 		},
 	},
 	"CNAME External": {
 		Qname: "external.testns.svc.cluster.local.", Qtype: dns.TypeCNAME,
 		Rcode: dns.RcodeSuccess,
 		Answer: []dns.RR{
-			test.CNAME("external.testns.svc.cluster.local.	0	IN	CNAME	ext.interwebs.test."),
+			test.CNAME("external.testns.svc.cluster.local.	303	IN	CNAME	ext.interwebs.test."),
 		},
 	},
 	"AAAA Service (existing service)": {
diff --git a/middleware/kubernetes/kubernetes.go b/middleware/kubernetes/kubernetes.go
index 4faa818ec..42c68e580 100644
--- a/middleware/kubernetes/kubernetes.go
+++ b/middleware/kubernetes/kubernetes.go
@@ -40,6 +40,7 @@ type Kubernetes struct {
 	Namespaces    map[string]bool
 	podMode       string
 	Fallthrough   bool
+	ttl           uint32
 
 	primaryZoneIndex   int
 	interfaceAddrsFunc func() net.IP
@@ -55,6 +56,7 @@ func New(zones []string) *Kubernetes {
 	k.interfaceAddrsFunc = func() net.IP { return net.ParseIP("127.0.0.1") }
 	k.podMode = podModeDisabled
 	k.Proxy = proxy.Proxy{}
+	k.ttl = defaultTTL
 
 	return k
 }
@@ -382,7 +384,7 @@ func (k *Kubernetes) findServices(r recordRequest, zone string) (services []msg.
 							if !(match(r.port, p.Name) && match(r.protocol, string(p.Protocol))) {
 								continue
 							}
-							s := msg.Service{Host: addr.IP, Port: int(p.Port)}
+							s := msg.Service{Host: addr.IP, Port: int(p.Port), TTL: k.ttl}
 							s.Key = strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name, endpointHostname(addr)}, "/")
 
 							err = nil
@@ -397,7 +399,7 @@ func (k *Kubernetes) findServices(r recordRequest, zone string) (services []msg.
 
 		// External service
 		if svc.Spec.ExternalName != "" {
-			s := msg.Service{Key: strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name}, "/"), Host: svc.Spec.ExternalName}
+			s := msg.Service{Key: strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name}, "/"), Host: svc.Spec.ExternalName, TTL: k.ttl}
 			if t, _ := s.HostType(); t == dns.TypeCNAME {
 				s.Key = strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name}, "/")
 				services = append(services, s)
@@ -416,7 +418,7 @@ func (k *Kubernetes) findServices(r recordRequest, zone string) (services []msg.
 
 			err = nil
 
-			s := msg.Service{Host: svc.Spec.ClusterIP, Port: int(p.Port)}
+			s := msg.Service{Host: svc.Spec.ClusterIP, Port: int(p.Port), TTL: k.ttl}
 			s.Key = strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name}, "/")
 
 			services = append(services, s)
@@ -455,4 +457,6 @@ const (
 	Svc = "svc"
 	// Pod is the DNS schema for kubernetes pods
 	Pod = "pod"
+	// defaultTTL to apply to all answers.
+	defaultTTL = 5
 )
diff --git a/middleware/kubernetes/setup.go b/middleware/kubernetes/setup.go
index 557eca93d..15b87c2cd 100644
--- a/middleware/kubernetes/setup.go
+++ b/middleware/kubernetes/setup.go
@@ -3,6 +3,7 @@ package kubernetes
 import (
 	"errors"
 	"fmt"
+	"strconv"
 	"strings"
 	"time"
 
@@ -174,6 +175,19 @@ func kubernetesParse(c *caddy.Controller) (*Kubernetes, dnsControlOpts, error) {
 					return nil, opts, err
 				}
 				k8s.Proxy = proxy.NewLookup(ups)
+			case "ttl":
+				args := c.RemainingArgs()
+				if len(args) == 0 {
+					return nil, opts, c.ArgErr()
+				}
+				t, err := strconv.Atoi(args[0])
+				if err != nil {
+					return nil, opts, err
+				}
+				if t < 5 || t > 3600 {
+					return nil, opts, c.Errf("ttl must be in range [5, 3600]: %d", t)
+				}
+				k8s.ttl = uint32(t)
 			default:
 				return nil, opts, c.Errf("unknown property '%s'", c.Val())
 			}
diff --git a/middleware/kubernetes/setup_ttl_test.go b/middleware/kubernetes/setup_ttl_test.go
new file mode 100644
index 000000000..d58f91576
--- /dev/null
+++ b/middleware/kubernetes/setup_ttl_test.go
@@ -0,0 +1,45 @@
+package kubernetes
+
+import (
+	"testing"
+
+	"github.com/mholt/caddy"
+)
+
+func TestKubernetesParseTTL(t *testing.T) {
+	tests := []struct {
+		input       string // Corefile data as string
+		expectedTTL uint32 // expected count of defined zones.
+		shouldErr   bool
+	}{
+		{`kubernetes cluster.local {
+			ttl 56
+		}`, 56, false},
+		{`kubernetes cluster.local`, defaultTTL, false},
+		{`kubernetes cluster.local {
+			ttl -1
+		}`, 0, true},
+		{`kubernetes cluster.local {
+			ttl 3601
+		}`, 0, true},
+	}
+
+	for i, tc := range tests {
+		c := caddy.NewTestController("dns", tc.input)
+		k, _, err := kubernetesParse(c)
+		if err != nil && !tc.shouldErr {
+			t.Fatalf("Test %d: Expected no error, got %q", i, err)
+		}
+		if err == nil && tc.shouldErr {
+			t.Fatalf("Test %d: Expected error, got none", i)
+		}
+		if err != nil && tc.shouldErr {
+			// input should error
+			continue
+		}
+
+		if k.ttl != tc.expectedTTL {
+			t.Errorf("Test %d: Expected TTl to be %d, got %d", i, tc.expectedTTL, k.ttl)
+		}
+	}
+}
diff --git a/test/kubernetes_test.go b/test/kubernetes_test.go
index 49d37734c..fa4751166 100644
--- a/test/kubernetes_test.go
+++ b/test/kubernetes_test.go
@@ -30,7 +30,7 @@ var dnsTestCases = []test.Case{
 		Qname: "svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeA,
 		Rcode: dns.RcodeSuccess,
 		Answer: []dns.RR{
-			test.A("svc-1-a.test-1.svc.cluster.local.      303    IN      A       10.0.0.100"),
+			test.A("svc-1-a.test-1.svc.cluster.local.      5    IN      A       10.0.0.100"),
 		},
 	},
 	{
@@ -535,9 +535,7 @@ var dnsTestCasesFallthrough = []test.Case{
 		Rcode: dns.RcodeSuccess,
 		Answer: append(srvResponse("_c-port._UDP.*.test-1.svc.cluster.local.", "TypeSRV", "headless-svc", "test-1"),
 			[]dns.RR{
-				test.SRV("_c-port._UDP.*.test-1.svc.cluster.local.      303    IN    SRV 0 33 1234 svc-c.test-1.svc.cluster.local."),
-			}...),
-
+				test.SRV("_c-port._UDP.*.test-1.svc.cluster.local.      303    IN    SRV 0 33 1234 svc-c.test-1.svc.cluster.local.")}...),
 		Extra: append(srvResponse("_c-port._UDP.*.test-1.svc.cluster.local.", "TypeA", "headless-svc", "test-1"),
 			[]dns.RR{
 				test.A("svc-c.test-1.svc.cluster.local.	303	IN	A	10.0.0.115"),
@@ -626,14 +624,14 @@ var dnsTestCasesFallthrough = []test.Case{
 		Rcode: dns.RcodeSuccess,
 		Answer: []dns.RR{
 			test.A("example.net.		303	IN	A	13.14.15.16"),
-			test.CNAME("ext-svc.test-1.svc.cluster.local. 0 IN	CNAME	example.net."),
+			test.CNAME("ext-svc.test-1.svc.cluster.local. 303 IN	CNAME	example.net."),
 		},
 	},
 	{
 		Qname: "ext-svc.test-1.svc.cluster.local.", Qtype: dns.TypeCNAME,
 		Rcode: dns.RcodeSuccess,
 		Answer: []dns.RR{
-			test.CNAME("ext-svc.test-1.svc.cluster.local. 0 IN	CNAME	example.net."),
+			test.CNAME("ext-svc.test-1.svc.cluster.local. 303 IN	CNAME	example.net."),
 		},
 	},
 	{
@@ -855,7 +853,7 @@ func srvResponse(qname, responsetype, namespace, name string) []dns.RR {
 		ip := strings.Replace(result[i], ".", "-", -1)
 		t := strconv.Itoa(100 / (lr + 1))
 		if responsetype == "TypeA" {
-			rr = append(rr, test.A(ip+"."+namespace+"."+name+".svc.cluster.local.	0	IN	A	"+result[i]))
+			rr = append(rr, test.A(ip+"."+namespace+"."+name+".svc.cluster.local.	303	IN	A	"+result[i]))
 		}
 		if responsetype == "TypeSRV" && namespace == "headless-svc" {
 			rr = append(rr, test.SRV(qname+"   303    IN    SRV 0 "+t+" 1234  "+ip+"."+namespace+"."+name+".svc.cluster.local."))
@@ -864,7 +862,6 @@ func srvResponse(qname, responsetype, namespace, name string) []dns.RR {
 			rr = append(rr, test.SRV(qname+"   303    IN    SRV 0 "+t+" 443  "+ip+"."+namespace+"."+name+".svc.cluster.local."))
 			rr = append(rr, test.SRV(qname+"   303    IN    SRV 0 "+t+" 80  "+ip+"."+namespace+"."+name+".svc.cluster.local."))
 		}
-
 	}
 	return rr
 }