Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
7d0adbcb
Commit
7d0adbcb
authored
May 28, 2015
by
Abhishek Shah
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SRV record support
parent
03ece333
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
108 additions
and
34 deletions
+108
-34
Makefile
cluster/addons/dns/kube2sky/Makefile
+1
-1
kube2sky.go
cluster/addons/dns/kube2sky/kube2sky.go
+102
-28
kube2sky_test.go
cluster/addons/dns/kube2sky/kube2sky_test.go
+0
-0
skydns-rc.yaml.in
cluster/addons/dns/skydns-rc.yaml.in
+5
-5
dns.go
test/e2e/dns.go
+0
-0
No files found.
cluster/addons/dns/kube2sky/Makefile
View file @
7d0adbcb
...
...
@@ -4,7 +4,7 @@
.PHONY
:
all kube2sky container push clean test
TAG
=
1.
8
TAG
=
1.
9
PREFIX
=
gcr.io/google_containers
all
:
container
...
...
cluster/addons/dns/kube2sky/kube2sky.go
View file @
7d0adbcb
...
...
@@ -23,6 +23,7 @@ import (
"encoding/json"
"flag"
"fmt"
"hash/fnv"
"net/http"
"net/url"
"os"
...
...
@@ -56,7 +57,7 @@ const (
// Maximum number of attempts to connect to etcd server.
maxConnectAttempts
=
12
// Resync period for the kube controller loop.
resyncPeriod
=
5
*
time
.
Second
resyncPeriod
=
30
*
time
.
Minute
// A subdomain added to the user specified domain for all services.
serviceSubdomain
=
"svc"
)
...
...
@@ -90,7 +91,7 @@ type kube2sky struct {
// Removes 'subdomain' from etcd.
func
(
ks
*
kube2sky
)
removeDNS
(
subdomain
string
)
error
{
glog
.
V
(
2
)
.
Infof
(
"Removing %s from DNS"
,
subdomain
)
resp
,
err
:=
ks
.
etcdClient
.
RawGet
(
skymsg
.
Path
(
subdomain
),
false
,
fals
e
)
resp
,
err
:=
ks
.
etcdClient
.
RawGet
(
skymsg
.
Path
(
subdomain
),
false
,
tru
e
)
if
err
!=
nil
{
return
err
}
...
...
@@ -109,7 +110,7 @@ func (ks *kube2sky) writeSkyRecord(subdomain string, data string) error {
}
// Generates skydns records for a headless service.
func
(
ks
*
kube2sky
)
newHeadlessService
(
subdomain
string
,
service
*
kapi
.
Service
)
error
{
func
(
ks
*
kube2sky
)
newHeadlessService
(
subdomain
string
,
service
*
kapi
.
Service
,
isNewStyleFormat
bool
)
error
{
// Create an A record for every pod in the service.
// This record must be periodically updated.
// Format is as follows:
...
...
@@ -131,7 +132,7 @@ func (ks *kube2sky) newHeadlessService(subdomain string, service *kapi.Service)
return
nil
}
if
e
,
ok
:=
e
.
(
*
kapi
.
Endpoints
);
ok
{
return
ks
.
generateRecordsForHeadlessService
(
subdomain
,
e
,
service
)
return
ks
.
generateRecordsForHeadlessService
(
subdomain
,
e
,
service
,
isNewStyleFormat
)
}
return
nil
}
...
...
@@ -146,18 +147,33 @@ func getSkyMsg(ip string, port int) *skymsg.Service {
}
}
func
(
ks
*
kube2sky
)
generateRecordsForHeadlessService
(
subdomain
string
,
e
*
kapi
.
Endpoints
,
svc
*
kapi
.
Service
)
error
{
func
(
ks
*
kube2sky
)
generateRecordsForHeadlessService
(
subdomain
string
,
e
*
kapi
.
Endpoints
,
svc
*
kapi
.
Service
,
isNewStyleFormat
bool
)
error
{
for
idx
:=
range
e
.
Subsets
{
for
subIdx
:=
range
e
.
Subsets
[
idx
]
.
Addresses
{
subdomain
:=
buildDNSNameString
(
subdomain
,
fmt
.
Sprintf
(
"%d%d"
,
idx
,
subIdx
))
b
,
err
:=
json
.
Marshal
(
getSkyMsg
(
e
.
Subsets
[
idx
]
.
Addresses
[
subIdx
]
.
IP
,
svc
.
Spec
.
Ports
[
0
]
.
Port
))
b
,
err
:=
json
.
Marshal
(
getSkyMsg
(
e
.
Subsets
[
idx
]
.
Addresses
[
subIdx
]
.
IP
,
0
))
if
err
!=
nil
{
return
err
}
glog
.
V
(
2
)
.
Infof
(
"Setting DNS record: %v -> %q
\n
"
,
subdomain
,
string
(
b
))
if
err
:=
ks
.
writeSkyRecord
(
subdomain
,
string
(
b
));
err
!=
nil
{
recordValue
:=
string
(
b
)
recordLabel
:=
getHash
(
recordValue
)
recordKey
:=
buildDNSNameString
(
subdomain
,
recordLabel
)
glog
.
V
(
2
)
.
Infof
(
"Setting DNS record: %v -> %q
\n
"
,
recordKey
,
recordValue
)
if
err
:=
ks
.
writeSkyRecord
(
recordKey
,
recordValue
);
err
!=
nil
{
return
err
}
if
isNewStyleFormat
{
for
portIdx
:=
range
e
.
Subsets
[
idx
]
.
Ports
{
endpointPort
:=
&
e
.
Subsets
[
idx
]
.
Ports
[
portIdx
]
portSegment
:=
buildPortSegmentString
(
endpointPort
.
Name
,
endpointPort
.
Protocol
)
if
portSegment
!=
""
{
err
:=
ks
.
generateSRVRecord
(
subdomain
,
portSegment
,
recordLabel
,
recordKey
,
endpointPort
.
Port
)
if
err
!=
nil
{
return
err
}
}
}
}
}
}
...
...
@@ -183,7 +199,7 @@ func (ks *kube2sky) getServiceFromEndpoints(e *kapi.Endpoints) (*kapi.Service, e
return
nil
,
fmt
.
Errorf
(
"got a non service object in services store %v"
,
obj
)
}
func
(
ks
*
kube2sky
)
addDNSUsingEndpoints
(
subdomain
string
,
e
*
kapi
.
Endpoints
)
error
{
func
(
ks
*
kube2sky
)
addDNSUsingEndpoints
(
subdomain
string
,
e
*
kapi
.
Endpoints
,
isNewStyleFormat
bool
)
error
{
ks
.
mlock
.
Lock
()
defer
ks
.
mlock
.
Unlock
()
svc
,
err
:=
ks
.
getServiceFromEndpoints
(
e
)
...
...
@@ -198,41 +214,90 @@ func (ks *kube2sky) addDNSUsingEndpoints(subdomain string, e *kapi.Endpoints) er
if
err
:=
ks
.
removeDNS
(
subdomain
);
err
!=
nil
{
return
err
}
return
ks
.
generateRecordsForHeadlessService
(
subdomain
,
e
,
svc
)
return
ks
.
generateRecordsForHeadlessService
(
subdomain
,
e
,
svc
,
isNewStyleFormat
)
}
func
(
ks
*
kube2sky
)
handleEndpointAdd
(
obj
interface
{})
{
if
e
,
ok
:=
obj
.
(
*
kapi
.
Endpoints
);
ok
{
name
:=
buildDNSNameString
(
ks
.
domain
,
e
.
Namespace
,
e
.
Name
)
ks
.
mutateEtcdOrDie
(
func
()
error
{
return
ks
.
addDNSUsingEndpoints
(
name
,
e
)
})
ks
.
mutateEtcdOrDie
(
func
()
error
{
return
ks
.
addDNSUsingEndpoints
(
name
,
e
,
false
)
})
name
=
buildDNSNameString
(
ks
.
domain
,
serviceSubdomain
,
e
.
Namespace
,
e
.
Name
)
ks
.
mutateEtcdOrDie
(
func
()
error
{
return
ks
.
addDNSUsingEndpoints
(
name
,
e
)
})
ks
.
mutateEtcdOrDie
(
func
()
error
{
return
ks
.
addDNSUsingEndpoints
(
name
,
e
,
true
)
})
}
}
func
(
ks
*
kube2sky
)
generateRecordsForPortalService
(
subdomain
string
,
service
*
kapi
.
Service
)
error
{
for
i
:=
range
service
.
Spec
.
Ports
{
b
,
err
:=
json
.
Marshal
(
getSkyMsg
(
service
.
Spec
.
ClusterIP
,
service
.
Spec
.
Ports
[
i
]
.
Port
))
func
(
ks
*
kube2sky
)
generateRecordsForPortalService
(
subdomain
string
,
service
*
kapi
.
Service
,
isNewStyleFormat
bool
)
error
{
b
,
err
:=
json
.
Marshal
(
getSkyMsg
(
service
.
Spec
.
ClusterIP
,
0
))
if
err
!=
nil
{
return
err
}
recordValue
:=
string
(
b
)
recordKey
:=
subdomain
recordLabel
:=
""
if
isNewStyleFormat
{
recordLabel
=
getHash
(
recordValue
)
if
err
!=
nil
{
return
err
}
glog
.
V
(
2
)
.
Infof
(
"Setting DNS record: %v -> %q
\n
"
,
subdomain
,
string
(
b
))
if
err
:=
ks
.
writeSkyRecord
(
subdomain
,
string
(
b
));
err
!=
nil
{
return
err
recordKey
=
buildDNSNameString
(
subdomain
,
recordLabel
)
}
glog
.
V
(
2
)
.
Infof
(
"Setting DNS record: %v -> %q, with recordKey: %v
\n
"
,
subdomain
,
recordValue
,
recordKey
)
if
err
:=
ks
.
writeSkyRecord
(
recordKey
,
recordValue
);
err
!=
nil
{
return
err
}
if
!
isNewStyleFormat
{
return
nil
}
// Generate SRV Records
for
i
:=
range
service
.
Spec
.
Ports
{
port
:=
&
service
.
Spec
.
Ports
[
i
]
portSegment
:=
buildPortSegmentString
(
port
.
Name
,
port
.
Protocol
)
if
portSegment
!=
""
{
err
=
ks
.
generateSRVRecord
(
subdomain
,
portSegment
,
recordLabel
,
subdomain
,
port
.
Port
)
if
err
!=
nil
{
return
err
}
}
}
return
nil
}
func
(
ks
*
kube2sky
)
addDNS
(
subdomain
string
,
service
*
kapi
.
Service
)
error
{
func
buildPortSegmentString
(
portName
string
,
portProtocol
kapi
.
Protocol
)
string
{
if
portName
==
""
{
// we don't create a random name
return
""
}
if
portProtocol
==
""
{
glog
.
Errorf
(
"Port Protocol not set. port segment string cannot be created."
)
return
""
}
return
fmt
.
Sprintf
(
"_%s._%s"
,
portName
,
strings
.
ToLower
(
string
(
portProtocol
)))
}
func
(
ks
*
kube2sky
)
generateSRVRecord
(
subdomain
,
portSegment
,
recordName
,
cName
string
,
portNumber
int
)
error
{
recordKey
:=
buildDNSNameString
(
subdomain
,
portSegment
,
recordName
)
srv_rec
,
err
:=
json
.
Marshal
(
getSkyMsg
(
cName
,
portNumber
))
if
err
!=
nil
{
return
err
}
if
err
:=
ks
.
writeSkyRecord
(
recordKey
,
string
(
srv_rec
));
err
!=
nil
{
return
err
}
return
nil
}
func
(
ks
*
kube2sky
)
addDNS
(
subdomain
string
,
service
*
kapi
.
Service
,
isNewStyleFormat
bool
)
error
{
if
len
(
service
.
Spec
.
Ports
)
==
0
{
glog
.
Fatalf
(
"unexpected service with no ports: %v"
,
service
)
}
// if ClusterIP is not set, a DNS entry should not be created
if
!
kapi
.
IsServiceIPSet
(
service
)
{
return
ks
.
newHeadlessService
(
subdomain
,
service
)
return
ks
.
newHeadlessService
(
subdomain
,
service
,
isNewStyleFormat
)
}
return
ks
.
generateRecordsForPortalService
(
subdomain
,
service
)
return
ks
.
generateRecordsForPortalService
(
subdomain
,
service
,
isNewStyleFormat
)
}
// Implements retry logic for arbitrary mutator. Crashes after retrying for
...
...
@@ -281,9 +346,9 @@ func (ks *kube2sky) newService(obj interface{}) {
if
s
,
ok
:=
obj
.
(
*
kapi
.
Service
);
ok
{
//TODO(artfulcoder) stop adding and deleting old-format string for service
name
:=
buildDNSNameString
(
ks
.
domain
,
s
.
Namespace
,
s
.
Name
)
ks
.
mutateEtcdOrDie
(
func
()
error
{
return
ks
.
addDNS
(
name
,
s
)
})
ks
.
mutateEtcdOrDie
(
func
()
error
{
return
ks
.
addDNS
(
name
,
s
,
false
)
})
name
=
buildDNSNameString
(
ks
.
domain
,
serviceSubdomain
,
s
.
Namespace
,
s
.
Name
)
ks
.
mutateEtcdOrDie
(
func
()
error
{
return
ks
.
addDNS
(
name
,
s
)
})
ks
.
mutateEtcdOrDie
(
func
()
error
{
return
ks
.
addDNS
(
name
,
s
,
true
)
})
}
}
...
...
@@ -296,6 +361,12 @@ func (ks *kube2sky) removeService(obj interface{}) {
}
}
func
(
ks
*
kube2sky
)
updateService
(
oldObj
,
newObj
interface
{})
{
// TODO: Avoid unwanted updates.
ks
.
removeService
(
oldObj
)
ks
.
newService
(
newObj
)
}
func
newEtcdClient
(
etcdServer
string
)
(
*
etcd
.
Client
,
error
)
{
var
(
client
*
etcd
.
Client
...
...
@@ -390,10 +461,7 @@ func watchForServices(kubeClient *kclient.Client, ks *kube2sky) kcache.Store {
kframework
.
ResourceEventHandlerFuncs
{
AddFunc
:
ks
.
newService
,
DeleteFunc
:
ks
.
removeService
,
UpdateFunc
:
func
(
oldObj
,
newObj
interface
{})
{
// TODO: Avoid unwanted updates.
ks
.
newService
(
newObj
)
},
UpdateFunc
:
ks
.
updateService
,
},
)
go
serviceController
.
Run
(
util
.
NeverStop
)
...
...
@@ -418,6 +486,12 @@ func watchEndpoints(kubeClient *kclient.Client, ks *kube2sky) kcache.Store {
return
eStore
}
func
getHash
(
text
string
)
string
{
h
:=
fnv
.
New32a
()
h
.
Write
([]
byte
(
text
))
return
fmt
.
Sprintf
(
"%x"
,
h
.
Sum32
())
}
func
main
()
{
flag
.
Parse
()
var
err
error
...
...
cluster/addons/dns/kube2sky/kube2sky_test.go
View file @
7d0adbcb
This diff is collapsed.
Click to expand it.
cluster/addons/dns/skydns-rc.yaml.in
View file @
7d0adbcb
apiVersion: v1beta3
kind: ReplicationController
metadata:
name: kube-dns-v
2
name: kube-dns-v
3
namespace: default
labels:
k8s-app: kube-dns-v
2
k8s-app: kube-dns-v
3
kubernetes.io/cluster-service: "true"
spec:
replicas: {{ pillar['dns_replicas'] }}
selector:
k8s-app: kube-dns
version: v
2
version: v
3
template:
metadata:
labels:
k8s-app: kube-dns
version: v
2
version: v
3
kubernetes.io/cluster-service: "true"
spec:
containers:
...
...
@@ -30,7 +30,7 @@ spec:
- -initial-cluster-token
- skydns-etcd
- name: kube2sky
image: gcr.io/google_containers/kube2sky:1.
8
image: gcr.io/google_containers/kube2sky:1.
9
args:
# command = "/kube2sky"
- -domain={{ pillar['dns_domain'] }}
...
...
test/e2e/dns.go
View file @
7d0adbcb
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment