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
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
106 additions
and
32 deletions
+106
-32
Makefile
cluster/addons/dns/kube2sky/Makefile
+1
-1
kube2sky.go
cluster/addons/dns/kube2sky/kube2sky.go
+100
-26
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 @@
...
@@ -4,7 +4,7 @@
.PHONY
:
all kube2sky container push clean test
.PHONY
:
all kube2sky container push clean test
TAG
=
1.
8
TAG
=
1.
9
PREFIX
=
gcr.io/google_containers
PREFIX
=
gcr.io/google_containers
all
:
container
all
:
container
...
...
cluster/addons/dns/kube2sky/kube2sky.go
View file @
7d0adbcb
...
@@ -23,6 +23,7 @@ import (
...
@@ -23,6 +23,7 @@ import (
"encoding/json"
"encoding/json"
"flag"
"flag"
"fmt"
"fmt"
"hash/fnv"
"net/http"
"net/http"
"net/url"
"net/url"
"os"
"os"
...
@@ -56,7 +57,7 @@ const (
...
@@ -56,7 +57,7 @@ const (
// Maximum number of attempts to connect to etcd server.
// Maximum number of attempts to connect to etcd server.
maxConnectAttempts
=
12
maxConnectAttempts
=
12
// Resync period for the kube controller loop.
// 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.
// A subdomain added to the user specified domain for all services.
serviceSubdomain
=
"svc"
serviceSubdomain
=
"svc"
)
)
...
@@ -90,7 +91,7 @@ type kube2sky struct {
...
@@ -90,7 +91,7 @@ type kube2sky struct {
// Removes 'subdomain' from etcd.
// Removes 'subdomain' from etcd.
func
(
ks
*
kube2sky
)
removeDNS
(
subdomain
string
)
error
{
func
(
ks
*
kube2sky
)
removeDNS
(
subdomain
string
)
error
{
glog
.
V
(
2
)
.
Infof
(
"Removing %s from DNS"
,
subdomain
)
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
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -109,7 +110,7 @@ func (ks *kube2sky) writeSkyRecord(subdomain string, data string) error {
...
@@ -109,7 +110,7 @@ func (ks *kube2sky) writeSkyRecord(subdomain string, data string) error {
}
}
// Generates skydns records for a headless service.
// 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.
// Create an A record for every pod in the service.
// This record must be periodically updated.
// This record must be periodically updated.
// Format is as follows:
// Format is as follows:
...
@@ -131,7 +132,7 @@ func (ks *kube2sky) newHeadlessService(subdomain string, service *kapi.Service)
...
@@ -131,7 +132,7 @@ func (ks *kube2sky) newHeadlessService(subdomain string, service *kapi.Service)
return
nil
return
nil
}
}
if
e
,
ok
:=
e
.
(
*
kapi
.
Endpoints
);
ok
{
if
e
,
ok
:=
e
.
(
*
kapi
.
Endpoints
);
ok
{
return
ks
.
generateRecordsForHeadlessService
(
subdomain
,
e
,
service
)
return
ks
.
generateRecordsForHeadlessService
(
subdomain
,
e
,
service
,
isNewStyleFormat
)
}
}
return
nil
return
nil
}
}
...
@@ -146,20 +147,35 @@ func getSkyMsg(ip string, port int) *skymsg.Service {
...
@@ -146,20 +147,35 @@ 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
idx
:=
range
e
.
Subsets
{
for
subIdx
:=
range
e
.
Subsets
[
idx
]
.
Addresses
{
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
,
0
))
b
,
err
:=
json
.
Marshal
(
getSkyMsg
(
e
.
Subsets
[
idx
]
.
Addresses
[
subIdx
]
.
IP
,
svc
.
Spec
.
Ports
[
0
]
.
Port
))
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
glog
.
V
(
2
)
.
Infof
(
"Setting DNS record: %v -> %q
\n
"
,
subdomain
,
string
(
b
))
recordValue
:=
string
(
b
)
if
err
:=
ks
.
writeSkyRecord
(
subdomain
,
string
(
b
));
err
!=
nil
{
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
return
err
}
}
}
}
}
}
}
}
}
return
nil
return
nil
}
}
...
@@ -183,7 +199,7 @@ func (ks *kube2sky) getServiceFromEndpoints(e *kapi.Endpoints) (*kapi.Service, e
...
@@ -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
)
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
()
ks
.
mlock
.
Lock
()
defer
ks
.
mlock
.
Unlock
()
defer
ks
.
mlock
.
Unlock
()
svc
,
err
:=
ks
.
getServiceFromEndpoints
(
e
)
svc
,
err
:=
ks
.
getServiceFromEndpoints
(
e
)
...
@@ -198,41 +214,90 @@ func (ks *kube2sky) addDNSUsingEndpoints(subdomain string, e *kapi.Endpoints) er
...
@@ -198,41 +214,90 @@ func (ks *kube2sky) addDNSUsingEndpoints(subdomain string, e *kapi.Endpoints) er
if
err
:=
ks
.
removeDNS
(
subdomain
);
err
!=
nil
{
if
err
:=
ks
.
removeDNS
(
subdomain
);
err
!=
nil
{
return
err
return
err
}
}
return
ks
.
generateRecordsForHeadlessService
(
subdomain
,
e
,
svc
)
return
ks
.
generateRecordsForHeadlessService
(
subdomain
,
e
,
svc
,
isNewStyleFormat
)
}
}
func
(
ks
*
kube2sky
)
handleEndpointAdd
(
obj
interface
{})
{
func
(
ks
*
kube2sky
)
handleEndpointAdd
(
obj
interface
{})
{
if
e
,
ok
:=
obj
.
(
*
kapi
.
Endpoints
);
ok
{
if
e
,
ok
:=
obj
.
(
*
kapi
.
Endpoints
);
ok
{
name
:=
buildDNSNameString
(
ks
.
domain
,
e
.
Namespace
,
e
.
Name
)
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
)
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
{
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
}
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
{
for
i
:=
range
service
.
Spec
.
Ports
{
b
,
err
:=
json
.
Marshal
(
getSkyMsg
(
service
.
Spec
.
ClusterIP
,
service
.
Spec
.
Ports
[
i
]
.
Port
))
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
{
if
err
!=
nil
{
return
err
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
nil
}
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
return
err
}
}
if
err
:=
ks
.
writeSkyRecord
(
recordKey
,
string
(
srv_rec
));
err
!=
nil
{
return
err
}
}
return
nil
return
nil
}
}
func
(
ks
*
kube2sky
)
addDNS
(
subdomain
string
,
service
*
kapi
.
Service
)
error
{
func
(
ks
*
kube2sky
)
addDNS
(
subdomain
string
,
service
*
kapi
.
Service
,
isNewStyleFormat
bool
)
error
{
if
len
(
service
.
Spec
.
Ports
)
==
0
{
if
len
(
service
.
Spec
.
Ports
)
==
0
{
glog
.
Fatalf
(
"unexpected service with no ports: %v"
,
service
)
glog
.
Fatalf
(
"unexpected service with no ports: %v"
,
service
)
}
}
// if ClusterIP is not set, a DNS entry should not be created
// if ClusterIP is not set, a DNS entry should not be created
if
!
kapi
.
IsServiceIPSet
(
service
)
{
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
// Implements retry logic for arbitrary mutator. Crashes after retrying for
...
@@ -281,9 +346,9 @@ func (ks *kube2sky) newService(obj interface{}) {
...
@@ -281,9 +346,9 @@ func (ks *kube2sky) newService(obj interface{}) {
if
s
,
ok
:=
obj
.
(
*
kapi
.
Service
);
ok
{
if
s
,
ok
:=
obj
.
(
*
kapi
.
Service
);
ok
{
//TODO(artfulcoder) stop adding and deleting old-format string for service
//TODO(artfulcoder) stop adding and deleting old-format string for service
name
:=
buildDNSNameString
(
ks
.
domain
,
s
.
Namespace
,
s
.
Name
)
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
)
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{}) {
...
@@ -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
)
{
func
newEtcdClient
(
etcdServer
string
)
(
*
etcd
.
Client
,
error
)
{
var
(
var
(
client
*
etcd
.
Client
client
*
etcd
.
Client
...
@@ -390,10 +461,7 @@ func watchForServices(kubeClient *kclient.Client, ks *kube2sky) kcache.Store {
...
@@ -390,10 +461,7 @@ func watchForServices(kubeClient *kclient.Client, ks *kube2sky) kcache.Store {
kframework
.
ResourceEventHandlerFuncs
{
kframework
.
ResourceEventHandlerFuncs
{
AddFunc
:
ks
.
newService
,
AddFunc
:
ks
.
newService
,
DeleteFunc
:
ks
.
removeService
,
DeleteFunc
:
ks
.
removeService
,
UpdateFunc
:
func
(
oldObj
,
newObj
interface
{})
{
UpdateFunc
:
ks
.
updateService
,
// TODO: Avoid unwanted updates.
ks
.
newService
(
newObj
)
},
},
},
)
)
go
serviceController
.
Run
(
util
.
NeverStop
)
go
serviceController
.
Run
(
util
.
NeverStop
)
...
@@ -418,6 +486,12 @@ func watchEndpoints(kubeClient *kclient.Client, ks *kube2sky) kcache.Store {
...
@@ -418,6 +486,12 @@ func watchEndpoints(kubeClient *kclient.Client, ks *kube2sky) kcache.Store {
return
eStore
return
eStore
}
}
func
getHash
(
text
string
)
string
{
h
:=
fnv
.
New32a
()
h
.
Write
([]
byte
(
text
))
return
fmt
.
Sprintf
(
"%x"
,
h
.
Sum32
())
}
func
main
()
{
func
main
()
{
flag
.
Parse
()
flag
.
Parse
()
var
err
error
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
apiVersion: v1beta3
kind: ReplicationController
kind: ReplicationController
metadata:
metadata:
name: kube-dns-v
2
name: kube-dns-v
3
namespace: default
namespace: default
labels:
labels:
k8s-app: kube-dns-v
2
k8s-app: kube-dns-v
3
kubernetes.io/cluster-service: "true"
kubernetes.io/cluster-service: "true"
spec:
spec:
replicas: {{ pillar['dns_replicas'] }}
replicas: {{ pillar['dns_replicas'] }}
selector:
selector:
k8s-app: kube-dns
k8s-app: kube-dns
version: v
2
version: v
3
template:
template:
metadata:
metadata:
labels:
labels:
k8s-app: kube-dns
k8s-app: kube-dns
version: v
2
version: v
3
kubernetes.io/cluster-service: "true"
kubernetes.io/cluster-service: "true"
spec:
spec:
containers:
containers:
...
@@ -30,7 +30,7 @@ spec:
...
@@ -30,7 +30,7 @@ spec:
- -initial-cluster-token
- -initial-cluster-token
- skydns-etcd
- skydns-etcd
- name: kube2sky
- name: kube2sky
image: gcr.io/google_containers/kube2sky:1.
8
image: gcr.io/google_containers/kube2sky:1.
9
args:
args:
# command = "/kube2sky"
# command = "/kube2sky"
- -domain={{ pillar['dns_domain'] }}
- -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