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
08928cfe
Commit
08928cfe
authored
Aug 11, 2018
by
Manjunath A Kumatagi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Sync peer-finder code from contrib repo
parent
1f55bbbe
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
60 additions
and
7 deletions
+60
-7
README.md
test/images/pets/peer-finder/README.md
+10
-3
VERSION
test/images/pets/peer-finder/VERSION
+1
-1
peer-finder.go
test/images/pets/peer-finder/peer-finder.go
+49
-3
No files found.
test/images/pets/peer-finder/README.md
View file @
08928cfe
...
@@ -6,13 +6,13 @@ All it does is watch DNS for changes in the set of endpoints that are part of th
...
@@ -6,13 +6,13 @@ All it does is watch DNS for changes in the set of endpoints that are part of th
of the PetSet. It periodically looks up the SRV record of the DNS entry that corresponds to a Kubernetes
of the PetSet. It periodically looks up the SRV record of the DNS entry that corresponds to a Kubernetes
Service which enumerates the set of peers for this the specified service.
Service which enumerates the set of peers for this the specified service.
Be sure to use the
`
publishNotReadyAddresses`
field
on the governing service
Be sure to use the
`
service.alpha.kubernetes.io/tolerate-unready-endpoints`
on the governing service
of the StatefulSet so that all peers are listed in endpoints before any peers are started.
of the StatefulSet so that all peers are listed in endpoints before any peers are started.
There are several ways to bundle it with your main application.
There are several ways to bundle it with your main application.
1.
In an
[
init container
](
http://kubernetes.io/docs/user-guide/pods/init-container/
)
,
1.
In an
[
init container
](
http://kubernetes.io/docs/user-guide/pods/init-container/
)
,
to help your pod determine its peers when it
it first started (determine the desired set of
to help your pod determine its peers when it
first started (determine the desired set of
peers from the governing service of the StatefulSet. For this use case, the
`--on-start`
option
peers from the governing service of the StatefulSet. For this use case, the
`--on-start`
option
can be used, but the
`--on-change`
option should not be used since the init container will no
can be used, but the
`--on-change`
option should not be used since the init container will no
longer be running after the pod is started. An example of an
`--on-start`
script would be to
longer be running after the pod is started. An example of an
`--on-start`
script would be to
...
@@ -33,7 +33,14 @@ Options 1 and 2 and 4 may be preferable since they do not require changes to the
...
@@ -33,7 +33,14 @@ Options 1 and 2 and 4 may be preferable since they do not require changes to the
Option 3 is useful is signalling is necessary.
Option 3 is useful is signalling is necessary.
The peer-finder tool is intended to help legacy applications run in containers on Kubernetes.
The peer-finder tool is intended to help legacy applications run in containers on Kubernetes.
If possible, it may be preferable to modify an application
s to poll DNS itself
to determine its peer set.
If possible, it may be preferable to modify an application
to poll its own DNS
to determine its peer set.
Not all StatefulSets are able to be scaled. For unscalable StatefulSets, only the on-start message is needed, and
Not all StatefulSets are able to be scaled. For unscalable StatefulSets, only the on-start message is needed, and
so option 1 is a good choice.
so option 1 is a good choice.
## DNS Considerations
Unless specified by the
`-domain`
argument,
`peer-finder`
will determine the FQDN of the pod by examining the
`/etc/resolv.conf`
file, looking for a
`search`
line and looking for the best match.
If your pod is not using the default
`dnsPolicy`
value which is
`ClusterFirst`
as the DNS policy, you may need
to provide the
`-domain`
argument. In most common configurations,
`-domain=cluster.local`
will be the correct setting.
test/images/pets/peer-finder/VERSION
View file @
08928cfe
1.
1
1.
2
test/images/pets/peer-finder/peer-finder.go
View file @
08928cfe
...
@@ -25,6 +25,7 @@ import (
...
@@ -25,6 +25,7 @@ import (
"net"
"net"
"os"
"os"
"os/exec"
"os/exec"
"regexp"
"sort"
"sort"
"strings"
"strings"
"time"
"time"
...
@@ -41,7 +42,7 @@ var (
...
@@ -41,7 +42,7 @@ var (
onStart
=
flag
.
String
(
"on-start"
,
""
,
"Script to run on start, must accept a new line separated list of peers via stdin."
)
onStart
=
flag
.
String
(
"on-start"
,
""
,
"Script to run on start, must accept a new line separated list of peers via stdin."
)
svc
=
flag
.
String
(
"service"
,
""
,
"Governing service responsible for the DNS records of the domain this pod is in."
)
svc
=
flag
.
String
(
"service"
,
""
,
"Governing service responsible for the DNS records of the domain this pod is in."
)
namespace
=
flag
.
String
(
"ns"
,
""
,
"The namespace this pod is running in. If unspecified, the POD_NAMESPACE env var is used."
)
namespace
=
flag
.
String
(
"ns"
,
""
,
"The namespace this pod is running in. If unspecified, the POD_NAMESPACE env var is used."
)
domain
=
flag
.
String
(
"domain"
,
"
cluster.local"
,
"The Cluster Domain which is used by the Cluster
."
)
domain
=
flag
.
String
(
"domain"
,
"
"
,
"The Cluster Domain which is used by the Cluster, if not set tries to determine it from /etc/resolv.conf file
."
)
)
)
func
lookup
(
svcName
string
)
(
sets
.
String
,
error
)
{
func
lookup
(
svcName
string
)
(
sets
.
String
,
error
)
{
...
@@ -99,9 +100,53 @@ func main() {
...
@@ -99,9 +100,53 @@ func main() {
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Fatalf
(
"Failed to get hostname: %s"
,
err
)
log
.
Fatalf
(
"Failed to get hostname: %s"
,
err
)
}
}
var
domainName
string
svcLocalSuffix
:=
strings
.
Join
([]
string
{
"svc"
,
*
domain
},
"."
)
// If domain is not provided, try to get it from resolv.conf
myName
:=
strings
.
Join
([]
string
{
hostname
,
*
svc
,
ns
,
svcLocalSuffix
},
"."
)
if
*
domain
==
""
{
resolvConfBytes
,
err
:=
ioutil
.
ReadFile
(
"/etc/resolv.conf"
)
resolvConf
:=
string
(
resolvConfBytes
)
if
err
!=
nil
{
log
.
Fatal
(
"Unable to read /etc/resolv.conf"
)
}
var
re
*
regexp
.
Regexp
if
ns
==
""
{
// Looking for a domain that looks like with *.svc.**
re
,
err
=
regexp
.
Compile
(
`\A(.*\n)*search\s{1,}(.*\s{1,})*(?P<goal>[a-zA-Z0-9-]{1,63}.svc.([a-zA-Z0-9-]{1,63}\.)*[a-zA-Z0-9]{2,63})`
)
}
else
{
// Looking for a domain that looks like svc.**
re
,
err
=
regexp
.
Compile
(
`\A(.*\n)*search\s{1,}(.*\s{1,})*(?P<goal>svc.([a-zA-Z0-9-]{1,63}\.)*[a-zA-Z0-9]{2,63})`
)
}
if
err
!=
nil
{
log
.
Fatalf
(
"Failed to create regular expression: %v"
,
err
)
}
groupNames
:=
re
.
SubexpNames
()
result
:=
re
.
FindStringSubmatch
(
resolvConf
)
for
k
,
v
:=
range
result
{
if
groupNames
[
k
]
==
"goal"
{
if
ns
==
""
{
// Domain is complete if ns is empty
domainName
=
v
}
else
{
// Need to convert svc.** into ns.svc.**
domainName
=
ns
+
"."
+
v
}
break
}
}
log
.
Printf
(
"Determined Domain to be %s"
,
domainName
)
}
else
{
domainName
=
strings
.
Join
([]
string
{
ns
,
"svc"
,
*
domain
},
"."
)
}
if
*
svc
==
""
||
domainName
==
""
||
(
*
onChange
==
""
&&
*
onStart
==
""
)
{
log
.
Fatalf
(
"Incomplete args, require -on-change and/or -on-start, -service and -ns or an env var for POD_NAMESPACE."
)
}
myName
:=
strings
.
Join
([]
string
{
hostname
,
*
svc
,
domainName
},
"."
)
script
:=
*
onStart
script
:=
*
onStart
if
script
==
""
{
if
script
==
""
{
script
=
*
onChange
script
=
*
onChange
...
@@ -114,6 +159,7 @@ func main() {
...
@@ -114,6 +159,7 @@ func main() {
continue
continue
}
}
if
newPeers
.
Equal
(
peers
)
||
!
newPeers
.
Has
(
myName
)
{
if
newPeers
.
Equal
(
peers
)
||
!
newPeers
.
Has
(
myName
)
{
log
.
Printf
(
"Have not found myself in list yet.
\n
My Hostname: %s
\n
Hosts in list: %s"
,
myName
,
strings
.
Join
(
newPeers
.
List
(),
", "
))
continue
continue
}
}
peerList
:=
newPeers
.
List
()
peerList
:=
newPeers
.
List
()
...
...
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