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
2c944439
Commit
2c944439
authored
May 29, 2019
by
Erik Wilson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor certs
parent
c745be58
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
347 additions
and
178 deletions
+347
-178
rolebindings.yaml
manifests/rolebindings.yaml
+12
-0
config.go
pkg/agent/config/config.go
+94
-41
setup.go
pkg/agent/flannel/setup.go
+2
-2
proxy.go
pkg/agent/proxy/proxy.go
+5
-22
tunnel.go
pkg/agent/tunnel/tunnel.go
+1
-1
server.go
pkg/cli/cmds/server.go
+15
-2
server.go
pkg/cli/server/server.go
+25
-1
agent.go
pkg/daemons/agent/agent.go
+7
-7
types.go
pkg/daemons/config/types.go
+63
-38
server.go
pkg/daemons/control/server.go
+0
-0
router.go
pkg/server/router.go
+110
-63
server.go
pkg/server/server.go
+13
-1
No files found.
manifests/rolebindings.yaml
0 → 100644
View file @
2c944439
apiVersion
:
rbac.authorization.k8s.io/v1
kind
:
ClusterRoleBinding
metadata
:
name
:
kube-apiserver-kubelet-admin
roleRef
:
apiGroup
:
rbac.authorization.k8s.io
kind
:
ClusterRole
name
:
system:kubelet-api-admin
subjects
:
-
apiGroup
:
rbac.authorization.k8s.io
kind
:
User
name
:
kube-apiserver
pkg/agent/config/config.go
View file @
2c944439
...
@@ -23,6 +23,7 @@ import (
...
@@ -23,6 +23,7 @@ import (
"github.com/rancher/k3s/pkg/cli/cmds"
"github.com/rancher/k3s/pkg/cli/cmds"
"github.com/rancher/k3s/pkg/clientaccess"
"github.com/rancher/k3s/pkg/clientaccess"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/daemons/control"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/net"
...
@@ -82,6 +83,10 @@ func getNodeNamedCrt(nodeName, nodePasswordFile string) HTTPRequester {
...
@@ -82,6 +83,10 @@ func getNodeNamedCrt(nodeName, nodePasswordFile string) HTTPRequester {
}
}
defer
resp
.
Body
.
Close
()
defer
resp
.
Body
.
Close
()
if
resp
.
StatusCode
==
http
.
StatusForbidden
{
return
nil
,
fmt
.
Errorf
(
"Node password rejected, contents of '%s' may not match server passwd entry"
,
nodePasswordFile
)
}
if
resp
.
StatusCode
!=
http
.
StatusOK
{
if
resp
.
StatusCode
!=
http
.
StatusOK
{
return
nil
,
fmt
.
Errorf
(
"%s: %s"
,
u
,
resp
.
Status
)
return
nil
,
fmt
.
Errorf
(
"%s: %s"
,
u
,
resp
.
Status
)
}
}
...
@@ -101,45 +106,55 @@ func ensureNodePassword(nodePasswordFile string) (string, error) {
...
@@ -101,45 +106,55 @@ func ensureNodePassword(nodePasswordFile string) (string, error) {
return
""
,
err
return
""
,
err
}
}
nodePassword
:=
hex
.
EncodeToString
(
password
)
nodePassword
:=
hex
.
EncodeToString
(
password
)
return
nodePassword
,
ioutil
.
WriteFile
(
nodePasswordFile
,
[]
byte
(
nodePassword
),
0600
)
return
nodePassword
,
ioutil
.
WriteFile
(
nodePasswordFile
,
[]
byte
(
nodePassword
+
"
\n
"
),
0600
)
}
}
func
get
NodeCert
(
nodeName
,
nodeCertFile
,
node
KeyFile
,
nodePasswordFile
string
,
info
*
clientaccess
.
Info
)
(
*
tls
.
Certificate
,
error
)
{
func
get
ServingCert
(
nodeName
,
servingCertFile
,
serving
KeyFile
,
nodePasswordFile
string
,
info
*
clientaccess
.
Info
)
(
*
tls
.
Certificate
,
error
)
{
nodeCert
,
err
:=
Request
(
"/v1-k3s/node
.crt"
,
info
,
getNodeNamedCrt
(
nodeName
,
nodePasswordFile
))
servingCert
,
err
:=
Request
(
"/v1-k3s/serving-kubelet
.crt"
,
info
,
getNodeNamedCrt
(
nodeName
,
nodePasswordFile
))
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
if
err
:=
ioutil
.
WriteFile
(
nodeCertFile
,
node
Cert
,
0600
);
err
!=
nil
{
if
err
:=
ioutil
.
WriteFile
(
servingCertFile
,
serving
Cert
,
0600
);
err
!=
nil
{
return
nil
,
errors
.
Wrapf
(
err
,
"failed to write node cert"
)
return
nil
,
errors
.
Wrapf
(
err
,
"failed to write node cert"
)
}
}
nodeKey
,
err
:=
clientaccess
.
Get
(
"/v1-k3s/node
.key"
,
info
)
servingKey
,
err
:=
clientaccess
.
Get
(
"/v1-k3s/serving-kubelet
.key"
,
info
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
if
err
:=
ioutil
.
WriteFile
(
nodeKeyFile
,
node
Key
,
0600
);
err
!=
nil
{
if
err
:=
ioutil
.
WriteFile
(
servingKeyFile
,
serving
Key
,
0600
);
err
!=
nil
{
return
nil
,
errors
.
Wrapf
(
err
,
"failed to write node key"
)
return
nil
,
errors
.
Wrapf
(
err
,
"failed to write node key"
)
}
}
cert
,
err
:=
tls
.
X509KeyPair
(
nodeCert
,
node
Key
)
cert
,
err
:=
tls
.
X509KeyPair
(
servingCert
,
serving
Key
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
&
cert
,
nil
return
&
cert
,
nil
}
}
func
writeNodeCA
(
dataDir
string
,
nodeCert
*
tls
.
Certificate
)
(
string
,
error
)
{
func
getHostFile
(
filename
string
,
info
*
clientaccess
.
Info
)
error
{
clientCABytes
:=
pem
.
EncodeToMemory
(
&
pem
.
Block
{
basename
:=
filepath
.
Base
(
filename
)
Type
:
"CERTIFICATE"
,
fileBytes
,
err
:=
clientaccess
.
Get
(
"/v1-k3s/"
+
basename
,
info
)
Bytes
:
nodeCert
.
Certificate
[
1
],
if
err
!=
nil
{
})
return
err
}
clientCA
:=
filepath
.
Join
(
dataDir
,
"client-ca.pem"
)
if
err
:=
ioutil
.
WriteFile
(
filename
,
fileBytes
,
0600
);
err
!=
nil
{
if
err
:=
ioutil
.
WriteFile
(
clientCA
,
clientCABytes
,
0600
);
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"failed to write cert %s"
,
filename
)
return
""
,
errors
.
Wrapf
(
err
,
"failed to write client CA"
)
}
}
return
nil
}
return
clientCA
,
nil
func
getNodeNamedHostFile
(
filename
,
nodeName
,
nodePasswordFile
string
,
info
*
clientaccess
.
Info
)
error
{
basename
:=
filepath
.
Base
(
filename
)
fileBytes
,
err
:=
Request
(
"/v1-k3s/"
+
basename
,
info
,
getNodeNamedCrt
(
nodeName
,
nodePasswordFile
))
if
err
!=
nil
{
return
err
}
if
err
:=
ioutil
.
WriteFile
(
filename
,
fileBytes
,
0600
);
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"failed to write cert %s"
,
filename
)
}
return
nil
}
}
func
getHostnameAndIP
(
info
cmds
.
Agent
)
(
string
,
string
,
error
)
{
func
getHostnameAndIP
(
info
cmds
.
Agent
)
(
string
,
string
,
error
)
{
...
@@ -169,17 +184,17 @@ func getHostnameAndIP(info cmds.Agent) (string, string, error) {
...
@@ -169,17 +184,17 @@ func getHostnameAndIP(info cmds.Agent) (string, string, error) {
}
}
func
localAddress
(
controlConfig
*
config
.
Control
)
string
{
func
localAddress
(
controlConfig
*
config
.
Control
)
string
{
return
fmt
.
Sprintf
(
"127.0.0.1:%d"
,
controlConfig
.
Advertise
Port
)
return
fmt
.
Sprintf
(
"127.0.0.1:%d"
,
controlConfig
.
Proxy
Port
)
}
}
func
writeKubeConfig
(
envInfo
*
cmds
.
Agent
,
info
clientaccess
.
Info
,
controlConfig
*
config
.
Control
,
node
Cert
*
tls
.
Certificate
)
(
string
,
error
)
{
func
writeKubeConfig
(
envInfo
*
cmds
.
Agent
,
info
clientaccess
.
Info
,
controlConfig
*
config
.
Control
,
tls
Cert
*
tls
.
Certificate
)
(
string
,
error
)
{
os
.
MkdirAll
(
envInfo
.
DataDir
,
0700
)
os
.
MkdirAll
(
envInfo
.
DataDir
,
0700
)
kubeConfigPath
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"kubeconfig.yaml"
)
kubeConfigPath
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"kubeconfig.yaml"
)
info
.
URL
=
"https://"
+
localAddress
(
controlConfig
)
info
.
URL
=
"https://"
+
localAddress
(
controlConfig
)
info
.
CACerts
=
pem
.
EncodeToMemory
(
&
pem
.
Block
{
info
.
CACerts
=
pem
.
EncodeToMemory
(
&
pem
.
Block
{
Type
:
cert
.
CertificateBlockType
,
Type
:
cert
.
CertificateBlockType
,
Bytes
:
node
Cert
.
Certificate
[
1
],
Bytes
:
tls
Cert
.
Certificate
[
1
],
})
})
return
kubeConfigPath
,
info
.
WriteKubeConfig
(
kubeConfigPath
)
return
kubeConfigPath
,
info
.
WriteKubeConfig
(
kubeConfigPath
)
...
@@ -253,36 +268,72 @@ func get(envInfo *cmds.Agent) (*config.Node, error) {
...
@@ -253,36 +268,72 @@ func get(envInfo *cmds.Agent) (*config.Node, error) {
return
nil
,
err
return
nil
,
err
}
}
nodeCertFile
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"token-node.crt"
)
hostLocal
,
err
:=
exec
.
LookPath
(
"host-local"
)
nodeKeyFile
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"token-node.key"
)
nodePasswordFile
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"node-password.txt"
)
nodeCert
,
err
:=
getNodeCert
(
nodeName
,
nodeCertFile
,
nodeKeyFile
,
nodePasswordFile
,
info
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
errors
.
Wrapf
(
err
,
"failed to find host-local"
)
}
var
flannelIface
*
sysnet
.
Interface
if
!
envInfo
.
NoFlannel
&&
len
(
envInfo
.
FlannelIface
)
>
0
{
flannelIface
,
err
=
sysnet
.
InterfaceByName
(
envInfo
.
FlannelIface
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrapf
(
err
,
"unable to find interface"
)
}
}
proxyURL
:=
"https://"
+
localAddress
(
controlConfig
)
clientCAFile
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"client-ca.crt"
)
if
err
:=
getHostFile
(
clientCAFile
,
info
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
clientCA
,
err
:=
writeNodeCA
(
envInfo
.
DataDir
,
nodeCert
)
serverCAFile
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"server-ca.crt"
)
if
err
!=
nil
{
if
err
:=
getHostFile
(
serverCAFile
,
info
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
kubeConfig
,
err
:=
writeKubeConfig
(
envInfo
,
*
info
,
controlConfig
,
nodeCert
)
servingKubeletCert
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"serving-kubelet.crt"
)
servingKubeletKey
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"serving-kubelet.key"
)
nodePasswordFile
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"node-password.txt"
)
servingCert
,
err
:=
getServingCert
(
nodeName
,
servingKubeletCert
,
servingKubeletKey
,
nodePasswordFile
,
info
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
hostLocal
,
err
:=
exec
.
LookPath
(
"host-local"
)
kubeconfigNode
,
err
:=
writeKubeConfig
(
envInfo
,
*
info
,
controlConfig
,
servingCert
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
ors
.
Wrapf
(
err
,
"failed to find host-local"
)
return
nil
,
err
}
}
var
flannelIface
*
sysnet
.
Interface
clientKubeletCert
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"client-kubelet.crt"
)
if
!
envInfo
.
NoFlannel
&&
len
(
envInfo
.
FlannelIface
)
>
0
{
if
err
:=
getNodeNamedHostFile
(
clientKubeletCert
,
nodeName
,
nodePasswordFile
,
info
);
err
!=
nil
{
flannelIface
,
err
=
sysnet
.
InterfaceByName
(
envInfo
.
FlannelIface
)
return
nil
,
err
if
err
!=
nil
{
}
return
nil
,
errors
.
Wrapf
(
err
,
"unable to find interface"
)
}
clientKubeletKey
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"client-kubelet.key"
)
if
err
:=
getHostFile
(
clientKubeletKey
,
info
);
err
!=
nil
{
return
nil
,
err
}
kubeconfigKubelet
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"kubelet.kubeconfig"
)
if
err
:=
control
.
KubeConfig
(
kubeconfigKubelet
,
proxyURL
,
serverCAFile
,
clientKubeletCert
,
clientKubeletKey
);
err
!=
nil
{
return
nil
,
err
}
clientKubeProxyCert
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"client-kube-proxy.crt"
)
if
err
:=
getHostFile
(
clientKubeProxyCert
,
info
);
err
!=
nil
{
return
nil
,
err
}
clientKubeProxyKey
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"client-kube-proxy.key"
)
if
err
:=
getHostFile
(
clientKubeProxyKey
,
info
);
err
!=
nil
{
return
nil
,
err
}
kubeconfigKubeproxy
:=
filepath
.
Join
(
envInfo
.
DataDir
,
"kubeproxy.kubeconfig"
)
if
err
:=
control
.
KubeConfig
(
kubeconfigKubeproxy
,
proxyURL
,
serverCAFile
,
clientKubeProxyCert
,
clientKubeProxyKey
);
err
!=
nil
{
return
nil
,
err
}
}
nodeConfig
:=
&
config
.
Node
{
nodeConfig
:=
&
config
.
Node
{
...
@@ -295,14 +346,16 @@ func get(envInfo *cmds.Agent) (*config.Node, error) {
...
@@ -295,14 +346,16 @@ func get(envInfo *cmds.Agent) (*config.Node, error) {
nodeConfig
.
Images
=
filepath
.
Join
(
envInfo
.
DataDir
,
"images"
)
nodeConfig
.
Images
=
filepath
.
Join
(
envInfo
.
DataDir
,
"images"
)
nodeConfig
.
AgentConfig
.
NodeIP
=
nodeIP
nodeConfig
.
AgentConfig
.
NodeIP
=
nodeIP
nodeConfig
.
AgentConfig
.
NodeName
=
nodeName
nodeConfig
.
AgentConfig
.
NodeName
=
nodeName
nodeConfig
.
AgentConfig
.
NodeCertFile
=
nodeCertFile
nodeConfig
.
AgentConfig
.
ServingKubeletCert
=
servingKubeletCert
nodeConfig
.
AgentConfig
.
NodeKeyFile
=
nodeKeyFile
nodeConfig
.
AgentConfig
.
ServingKubeletKey
=
servingKubeletKey
nodeConfig
.
AgentConfig
.
ClusterDNS
=
controlConfig
.
ClusterDNS
nodeConfig
.
AgentConfig
.
ClusterDNS
=
controlConfig
.
ClusterDNS
nodeConfig
.
AgentConfig
.
ClusterDomain
=
controlConfig
.
ClusterDomain
nodeConfig
.
AgentConfig
.
ClusterDomain
=
controlConfig
.
ClusterDomain
nodeConfig
.
AgentConfig
.
ResolvConf
=
locateOrGenerateResolvConf
(
envInfo
)
nodeConfig
.
AgentConfig
.
ResolvConf
=
locateOrGenerateResolvConf
(
envInfo
)
nodeConfig
.
AgentConfig
.
C
ACertPath
=
clientCA
nodeConfig
.
AgentConfig
.
C
lientCA
=
clientCAFile
nodeConfig
.
AgentConfig
.
ListenAddress
=
"0.0.0.0"
nodeConfig
.
AgentConfig
.
ListenAddress
=
"0.0.0.0"
nodeConfig
.
AgentConfig
.
KubeConfig
=
kubeConfig
nodeConfig
.
AgentConfig
.
KubeConfigNode
=
kubeconfigNode
nodeConfig
.
AgentConfig
.
KubeConfigKubelet
=
kubeconfigKubelet
nodeConfig
.
AgentConfig
.
KubeConfigKubeProxy
=
kubeconfigKubeproxy
nodeConfig
.
AgentConfig
.
RootDir
=
filepath
.
Join
(
envInfo
.
DataDir
,
"kubelet"
)
nodeConfig
.
AgentConfig
.
RootDir
=
filepath
.
Join
(
envInfo
.
DataDir
,
"kubelet"
)
nodeConfig
.
AgentConfig
.
PauseImage
=
envInfo
.
PauseImage
nodeConfig
.
AgentConfig
.
PauseImage
=
envInfo
.
PauseImage
nodeConfig
.
CACerts
=
info
.
CACerts
nodeConfig
.
CACerts
=
info
.
CACerts
...
@@ -316,7 +369,7 @@ func get(envInfo *cmds.Agent) (*config.Node, error) {
...
@@ -316,7 +369,7 @@ func get(envInfo *cmds.Agent) (*config.Node, error) {
nodeConfig
.
Containerd
.
Address
=
filepath
.
Join
(
nodeConfig
.
Containerd
.
State
,
"containerd.sock"
)
nodeConfig
.
Containerd
.
Address
=
filepath
.
Join
(
nodeConfig
.
Containerd
.
State
,
"containerd.sock"
)
nodeConfig
.
Containerd
.
Template
=
filepath
.
Join
(
envInfo
.
DataDir
,
"etc/containerd/config.toml.tmpl"
)
nodeConfig
.
Containerd
.
Template
=
filepath
.
Join
(
envInfo
.
DataDir
,
"etc/containerd/config.toml.tmpl"
)
nodeConfig
.
ServerAddress
=
serverURLParsed
.
Host
nodeConfig
.
ServerAddress
=
serverURLParsed
.
Host
nodeConfig
.
Certificate
=
node
Cert
nodeConfig
.
Certificate
=
serving
Cert
if
!
nodeConfig
.
NoFlannel
{
if
!
nodeConfig
.
NoFlannel
{
nodeConfig
.
FlannelConf
=
filepath
.
Join
(
envInfo
.
DataDir
,
"etc/flannel/net-conf.json"
)
nodeConfig
.
FlannelConf
=
filepath
.
Join
(
envInfo
.
DataDir
,
"etc/flannel/net-conf.json"
)
nodeConfig
.
AgentConfig
.
CNIBinDir
=
filepath
.
Dir
(
hostLocal
)
nodeConfig
.
AgentConfig
.
CNIBinDir
=
filepath
.
Dir
(
hostLocal
)
...
...
pkg/agent/flannel/setup.go
View file @
2c944439
...
@@ -55,7 +55,7 @@ func Prepare(ctx context.Context, config *config.Node) error {
...
@@ -55,7 +55,7 @@ func Prepare(ctx context.Context, config *config.Node) error {
func
Run
(
ctx
context
.
Context
,
config
*
config
.
Node
)
error
{
func
Run
(
ctx
context
.
Context
,
config
*
config
.
Node
)
error
{
nodeName
:=
config
.
AgentConfig
.
NodeName
nodeName
:=
config
.
AgentConfig
.
NodeName
restConfig
,
err
:=
clientcmd
.
BuildConfigFromFlags
(
""
,
config
.
AgentConfig
.
KubeConfig
)
restConfig
,
err
:=
clientcmd
.
BuildConfigFromFlags
(
""
,
config
.
AgentConfig
.
KubeConfig
Node
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -79,7 +79,7 @@ func Run(ctx context.Context, config *config.Node) error {
...
@@ -79,7 +79,7 @@ func Run(ctx context.Context, config *config.Node) error {
}
}
go
func
()
{
go
func
()
{
err
:=
flannel
(
ctx
,
config
.
FlannelIface
,
config
.
FlannelConf
,
config
.
AgentConfig
.
KubeConfig
)
err
:=
flannel
(
ctx
,
config
.
FlannelIface
,
config
.
FlannelConf
,
config
.
AgentConfig
.
KubeConfig
Node
)
logrus
.
Fatalf
(
"flannel exited: %v"
,
err
)
logrus
.
Fatalf
(
"flannel exited: %v"
,
err
)
}()
}()
...
...
pkg/agent/proxy/proxy.go
View file @
2c944439
package
proxy
package
proxy
import
(
import
(
"crypto/tls"
"github.com/google/tcpproxy"
"net/http"
"github.com/pkg/errors"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/proxy"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
)
)
func
Run
(
config
*
config
.
Node
)
error
{
func
Run
(
config
*
config
.
Node
)
error
{
proxy
,
err
:=
proxy
.
NewSimpleProxy
(
config
.
ServerAddress
,
config
.
CACerts
,
true
)
logrus
.
Infof
(
"Starting proxy %s -> %s"
,
config
.
LocalAddress
,
config
.
ServerAddress
)
if
err
!=
nil
{
var
proxy
tcpproxy
.
Proxy
return
err
proxy
.
AddRoute
(
config
.
LocalAddress
,
tcpproxy
.
To
(
config
.
ServerAddress
))
}
listener
,
err
:=
tls
.
Listen
(
"tcp"
,
config
.
LocalAddress
,
&
tls
.
Config
{
Certificates
:
[]
tls
.
Certificate
{
*
config
.
Certificate
,
},
})
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"Failed to start tls listener"
)
}
go
func
()
{
go
func
()
{
err
:=
http
.
Serve
(
listener
,
proxy
)
err
:=
proxy
.
Run
(
)
logrus
.
Fatalf
(
"TLS proxy stopped: %v"
,
err
)
logrus
.
Fatalf
(
"TLS proxy stopped: %v"
,
err
)
}()
}()
return
nil
return
nil
}
}
pkg/agent/tunnel/tunnel.go
View file @
2c944439
...
@@ -26,7 +26,7 @@ var (
...
@@ -26,7 +26,7 @@ var (
)
)
func
Setup
(
config
*
config
.
Node
)
error
{
func
Setup
(
config
*
config
.
Node
)
error
{
restConfig
,
err
:=
clientcmd
.
BuildConfigFromFlags
(
""
,
config
.
AgentConfig
.
KubeConfig
)
restConfig
,
err
:=
clientcmd
.
BuildConfigFromFlags
(
""
,
config
.
AgentConfig
.
KubeConfig
Node
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
...
pkg/cli/cmds/server.go
View file @
2c944439
...
@@ -17,7 +17,7 @@ type Server struct {
...
@@ -17,7 +17,7 @@ type Server struct {
DisableAgent
bool
DisableAgent
bool
KubeConfigOutput
string
KubeConfigOutput
string
KubeConfigMode
string
KubeConfigMode
string
KnownIPs
cli
.
StringSlice
TLSSan
cli
.
StringSlice
BindAddress
string
BindAddress
string
ExtraAPIArgs
cli
.
StringSlice
ExtraAPIArgs
cli
.
StringSlice
ExtraSchedulerArgs
cli
.
StringSlice
ExtraSchedulerArgs
cli
.
StringSlice
...
@@ -28,6 +28,8 @@ type Server struct {
...
@@ -28,6 +28,8 @@ type Server struct {
StorageCAFile
string
StorageCAFile
string
StorageCertFile
string
StorageCertFile
string
StorageKeyFile
string
StorageKeyFile
string
AdvertiseIP
string
AdvertisePort
int
}
}
var
ServerConfig
Server
var
ServerConfig
Server
...
@@ -120,7 +122,7 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
...
@@ -120,7 +122,7 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
cli
.
StringSliceFlag
{
cli
.
StringSliceFlag
{
Name
:
"tls-san"
,
Name
:
"tls-san"
,
Usage
:
"Add additional hostname or IP as a Subject Alternative Name in the TLS cert"
,
Usage
:
"Add additional hostname or IP as a Subject Alternative Name in the TLS cert"
,
Value
:
&
ServerConfig
.
KnownIPs
,
Value
:
&
ServerConfig
.
TLSSan
,
},
},
cli
.
StringSliceFlag
{
cli
.
StringSliceFlag
{
Name
:
"kube-apiserver-arg"
,
Name
:
"kube-apiserver-arg"
,
...
@@ -172,6 +174,17 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
...
@@ -172,6 +174,17 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
Destination
:
&
ServerConfig
.
StorageKeyFile
,
Destination
:
&
ServerConfig
.
StorageKeyFile
,
EnvVar
:
"K3S_STORAGE_KEYFILE"
,
EnvVar
:
"K3S_STORAGE_KEYFILE"
,
},
},
cli
.
StringFlag
{
Name
:
"advertise-address"
,
Usage
:
"IP address that apiserver uses to advertise to members of the cluster"
,
Destination
:
&
ServerConfig
.
AdvertiseIP
,
},
cli
.
IntFlag
{
Name
:
"advertise-port"
,
Usage
:
"Port that apiserver uses to advertise to members of the cluster"
,
Value
:
0
,
Destination
:
&
ServerConfig
.
AdvertisePort
,
},
NodeIPFlag
,
NodeIPFlag
,
NodeNameFlag
,
NodeNameFlag
,
DockerFlag
,
DockerFlag
,
...
...
pkg/cli/server/server.go
View file @
2c944439
...
@@ -23,6 +23,7 @@ import (
...
@@ -23,6 +23,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/urfave/cli"
"k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/net"
"k8s.io/kubernetes/pkg/master"
"k8s.io/kubernetes/pkg/volume/csi"
"k8s.io/kubernetes/pkg/volume/csi"
_
"github.com/go-sql-driver/mysql"
// ensure we have mysql
_
"github.com/go-sql-driver/mysql"
// ensure we have mysql
...
@@ -102,8 +103,16 @@ func run(app *cli.Context, cfg *cmds.Server) error {
...
@@ -102,8 +103,16 @@ func run(app *cli.Context, cfg *cmds.Server) error {
serverConfig
.
Rootless
=
cfg
.
Rootless
serverConfig
.
Rootless
=
cfg
.
Rootless
serverConfig
.
TLSConfig
.
HTTPSPort
=
cfg
.
HTTPSPort
serverConfig
.
TLSConfig
.
HTTPSPort
=
cfg
.
HTTPSPort
serverConfig
.
TLSConfig
.
HTTPPort
=
cfg
.
HTTPPort
serverConfig
.
TLSConfig
.
HTTPPort
=
cfg
.
HTTPPort
serverConfig
.
TLSConfig
.
KnownIPs
=
knownIPs
(
cfg
.
KnownIPs
)
for
_
,
san
:=
range
knownIPs
(
cfg
.
TLSSan
)
{
addr
:=
net2
.
ParseIP
(
san
)
if
addr
!=
nil
{
serverConfig
.
TLSConfig
.
KnownIPs
=
append
(
serverConfig
.
TLSConfig
.
KnownIPs
,
san
)
}
else
{
serverConfig
.
TLSConfig
.
Domains
=
append
(
serverConfig
.
TLSConfig
.
Domains
,
san
)
}
}
serverConfig
.
TLSConfig
.
BindAddress
=
cfg
.
BindAddress
serverConfig
.
TLSConfig
.
BindAddress
=
cfg
.
BindAddress
serverConfig
.
ControlConfig
.
HTTPSPort
=
cfg
.
HTTPSPort
serverConfig
.
ControlConfig
.
ExtraAPIArgs
=
cfg
.
ExtraAPIArgs
serverConfig
.
ControlConfig
.
ExtraAPIArgs
=
cfg
.
ExtraAPIArgs
serverConfig
.
ControlConfig
.
ExtraControllerArgs
=
cfg
.
ExtraControllerArgs
serverConfig
.
ControlConfig
.
ExtraControllerArgs
=
cfg
.
ExtraControllerArgs
serverConfig
.
ControlConfig
.
ExtraSchedulerAPIArgs
=
cfg
.
ExtraSchedulerArgs
serverConfig
.
ControlConfig
.
ExtraSchedulerAPIArgs
=
cfg
.
ExtraSchedulerArgs
...
@@ -113,6 +122,15 @@ func run(app *cli.Context, cfg *cmds.Server) error {
...
@@ -113,6 +122,15 @@ func run(app *cli.Context, cfg *cmds.Server) error {
serverConfig
.
ControlConfig
.
StorageCAFile
=
cfg
.
StorageCAFile
serverConfig
.
ControlConfig
.
StorageCAFile
=
cfg
.
StorageCAFile
serverConfig
.
ControlConfig
.
StorageCertFile
=
cfg
.
StorageCertFile
serverConfig
.
ControlConfig
.
StorageCertFile
=
cfg
.
StorageCertFile
serverConfig
.
ControlConfig
.
StorageKeyFile
=
cfg
.
StorageKeyFile
serverConfig
.
ControlConfig
.
StorageKeyFile
=
cfg
.
StorageKeyFile
serverConfig
.
ControlConfig
.
AdvertiseIP
=
cfg
.
AdvertiseIP
serverConfig
.
ControlConfig
.
AdvertisePort
=
cfg
.
AdvertisePort
if
serverConfig
.
ControlConfig
.
AdvertiseIP
==
""
&&
cmds
.
AgentConfig
.
NodeIP
!=
""
{
serverConfig
.
ControlConfig
.
AdvertiseIP
=
cmds
.
AgentConfig
.
NodeIP
}
if
serverConfig
.
ControlConfig
.
AdvertiseIP
!=
""
{
serverConfig
.
TLSConfig
.
KnownIPs
=
append
(
serverConfig
.
TLSConfig
.
KnownIPs
,
serverConfig
.
ControlConfig
.
AdvertiseIP
)
}
_
,
serverConfig
.
ControlConfig
.
ClusterIPRange
,
err
=
net2
.
ParseCIDR
(
cfg
.
ClusterCIDR
)
_
,
serverConfig
.
ControlConfig
.
ClusterIPRange
,
err
=
net2
.
ParseCIDR
(
cfg
.
ClusterCIDR
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -123,6 +141,12 @@ func run(app *cli.Context, cfg *cmds.Server) error {
...
@@ -123,6 +141,12 @@ func run(app *cli.Context, cfg *cmds.Server) error {
return
errors
.
Wrapf
(
err
,
"Invalid CIDR %s: %v"
,
cfg
.
ServiceCIDR
,
err
)
return
errors
.
Wrapf
(
err
,
"Invalid CIDR %s: %v"
,
cfg
.
ServiceCIDR
,
err
)
}
}
_
,
apiServerServiceIP
,
err
:=
master
.
DefaultServiceIPRange
(
*
serverConfig
.
ControlConfig
.
ServiceIPRange
)
if
err
!=
nil
{
return
err
}
serverConfig
.
TLSConfig
.
KnownIPs
=
append
(
serverConfig
.
TLSConfig
.
KnownIPs
,
apiServerServiceIP
.
String
())
// If cluster-dns CLI arg is not set, we set ClusterDNS address to be ServiceCIDR network + 10,
// If cluster-dns CLI arg is not set, we set ClusterDNS address to be ServiceCIDR network + 10,
// i.e. when you set service-cidr to 192.168.0.0/16 and don't provide cluster-dns, it will be set to 192.168.0.10
// i.e. when you set service-cidr to 192.168.0.0/16 and don't provide cluster-dns, it will be set to 192.168.0.10
if
cfg
.
ClusterDNS
==
""
{
if
cfg
.
ClusterDNS
==
""
{
...
...
pkg/daemons/agent/agent.go
View file @
2c944439
...
@@ -35,7 +35,7 @@ func kubeProxy(cfg *config.Agent) {
...
@@ -35,7 +35,7 @@ func kubeProxy(cfg *config.Agent) {
argsMap
:=
map
[
string
]
string
{
argsMap
:=
map
[
string
]
string
{
"proxy-mode"
:
"iptables"
,
"proxy-mode"
:
"iptables"
,
"healthz-bind-address"
:
"127.0.0.1"
,
"healthz-bind-address"
:
"127.0.0.1"
,
"kubeconfig"
:
cfg
.
KubeConfig
,
"kubeconfig"
:
cfg
.
KubeConfig
KubeProxy
,
"cluster-cidr"
:
cfg
.
ClusterCIDR
.
String
(),
"cluster-cidr"
:
cfg
.
ClusterCIDR
.
String
(),
}
}
args
:=
config
.
GetArgsList
(
argsMap
,
cfg
.
ExtraKubeProxyArgs
)
args
:=
config
.
GetArgsList
(
argsMap
,
cfg
.
ExtraKubeProxyArgs
)
...
@@ -58,7 +58,7 @@ func kubelet(cfg *config.Agent) {
...
@@ -58,7 +58,7 @@ func kubelet(cfg *config.Agent) {
"read-only-port"
:
"0"
,
"read-only-port"
:
"0"
,
"allow-privileged"
:
"true"
,
"allow-privileged"
:
"true"
,
"cluster-domain"
:
cfg
.
ClusterDomain
,
"cluster-domain"
:
cfg
.
ClusterDomain
,
"kubeconfig"
:
cfg
.
KubeConfig
,
"kubeconfig"
:
cfg
.
KubeConfig
Kubelet
,
"eviction-hard"
:
"imagefs.available<5%,nodefs.available<5%"
,
"eviction-hard"
:
"imagefs.available<5%,nodefs.available<5%"
,
"eviction-minimum-reclaim"
:
"imagefs.available=10%,nodefs.available=10%"
,
"eviction-minimum-reclaim"
:
"imagefs.available=10%,nodefs.available=10%"
,
"fail-swap-on"
:
"false"
,
"fail-swap-on"
:
"false"
,
...
@@ -95,13 +95,13 @@ func kubelet(cfg *config.Agent) {
...
@@ -95,13 +95,13 @@ func kubelet(cfg *config.Agent) {
if
cfg
.
ListenAddress
!=
""
{
if
cfg
.
ListenAddress
!=
""
{
argsMap
[
"address"
]
=
cfg
.
ListenAddress
argsMap
[
"address"
]
=
cfg
.
ListenAddress
}
}
if
cfg
.
C
ACertPath
!=
""
{
if
cfg
.
C
lientCA
!=
""
{
argsMap
[
"anonymous-auth"
]
=
"false"
argsMap
[
"anonymous-auth"
]
=
"false"
argsMap
[
"client-ca-file"
]
=
cfg
.
C
ACertPath
argsMap
[
"client-ca-file"
]
=
cfg
.
C
lientCA
}
}
if
cfg
.
NodeCertFile
!=
""
&&
cfg
.
NodeKeyFile
!=
""
{
if
cfg
.
ServingKubeletCert
!=
""
&&
cfg
.
ServingKubeletKey
!=
""
{
argsMap
[
"tls-cert-file"
]
=
cfg
.
NodeCertFile
argsMap
[
"tls-cert-file"
]
=
cfg
.
ServingKubeletCert
argsMap
[
"tls-private-key-file"
]
=
cfg
.
NodeKeyFile
argsMap
[
"tls-private-key-file"
]
=
cfg
.
ServingKubeletKey
}
}
if
cfg
.
NodeName
!=
""
{
if
cfg
.
NodeName
!=
""
{
argsMap
[
"hostname-override"
]
=
cfg
.
NodeName
argsMap
[
"hostname-override"
]
=
cfg
.
NodeName
...
...
pkg/daemons/config/types.go
View file @
2c944439
...
@@ -36,32 +36,41 @@ type Containerd struct {
...
@@ -36,32 +36,41 @@ type Containerd struct {
}
}
type
Agent
struct
{
type
Agent
struct
{
NodeName
string
NodeName
string
NodeCertFile
string
ClientKubeletCert
string
NodeKeyFile
string
ClientKubeletKey
string
ClusterCIDR
net
.
IPNet
ClientKubeProxyCert
string
ClusterDNS
net
.
IP
ClientKubeProxyKey
string
ClusterDomain
string
ServingKubeletCert
string
ResolvConf
string
ServingKubeletKey
string
RootDir
string
ClusterCIDR
net
.
IPNet
KubeConfig
string
ClusterDNS
net
.
IP
NodeIP
string
ClusterDomain
string
RuntimeSocket
string
ResolvConf
string
ListenAddress
string
RootDir
string
CACertPath
string
KubeConfigNode
string
CNIBinDir
string
KubeConfigKubelet
string
CNIConfDir
string
KubeConfigKubeProxy
string
ExtraKubeletArgs
[]
string
NodeIP
string
ExtraKubeProxyArgs
[]
string
RuntimeSocket
string
PauseImage
string
ListenAddress
string
CNIPlugin
bool
ClientCA
string
NodeTaints
[]
string
CNIBinDir
string
NodeLabels
[]
string
CNIConfDir
string
ExtraKubeletArgs
[]
string
ExtraKubeProxyArgs
[]
string
PauseImage
string
CNIPlugin
bool
NodeTaints
[]
string
NodeLabels
[]
string
}
}
type
Control
struct
{
type
Control
struct
{
AdvertisePort
int
AdvertisePort
int
AdvertiseIP
string
ListenPort
int
ListenPort
int
HTTPSPort
int
ProxyPort
int
ClusterSecret
string
ClusterSecret
string
ClusterIPRange
*
net
.
IPNet
ClusterIPRange
*
net
.
IPNet
ServiceIPRange
*
net
.
IPNet
ServiceIPRange
*
net
.
IPNet
...
@@ -87,28 +96,44 @@ type Control struct {
...
@@ -87,28 +96,44 @@ type Control struct {
}
}
type
ControlRuntime
struct
{
type
ControlRuntime
struct
{
TLSCert
string
ClientKubeAPICert
string
TLSKey
string
ClientKubeAPIKey
string
TLSCA
string
ClientCA
string
TLSCAKey
string
ClientCAKey
string
TokenCA
string
ServerCA
string
TokenCAKey
string
ServerCAKey
string
ServiceKey
string
ServiceKey
string
PasswdFile
string
PasswdFile
string
KubeConfigSystem
string
KubeConfigAdmin
string
NodeCert
string
KubeConfigController
string
NodeKey
string
KubeConfigScheduler
string
ClientToken
string
KubeConfigAPIServer
string
NodeToken
string
Handler
http
.
Handler
ServingKubeAPICert
string
Tunnel
http
.
Handler
ServingKubeAPIKey
string
Authenticator
authenticator
.
Request
ClientToken
string
NodeToken
string
Handler
http
.
Handler
Tunnel
http
.
Handler
Authenticator
authenticator
.
Request
RequestHeaderCA
string
RequestHeaderCA
string
RequestHeaderCAKey
string
RequestHeaderCAKey
string
ClientAuthProxyCert
string
ClientAuthProxyCert
string
ClientAuthProxyKey
string
ClientAuthProxyKey
string
ClientAdminCert
string
ClientAdminKey
string
ClientControllerCert
string
ClientControllerKey
string
ClientSchedulerCert
string
ClientSchedulerKey
string
ClientKubeProxyCert
string
ClientKubeProxyKey
string
ServingKubeletKey
string
ClientKubeletKey
string
}
}
type
ArgString
[]
string
type
ArgString
[]
string
...
...
pkg/daemons/control/server.go
View file @
2c944439
This diff is collapsed.
Click to expand it.
pkg/server/router.go
View file @
2c944439
package
server
package
server
import
(
import
(
"bufio"
"crypto"
"crypto/rsa"
"crypto/x509"
"crypto/x509"
"encoding/csv"
"errors"
"errors"
"fmt"
"fmt"
"io"
"io/ioutil"
"io/ioutil"
"net"
"net"
"net/http"
"net/http"
...
@@ -17,10 +18,10 @@ import (
...
@@ -17,10 +18,10 @@ import (
"github.com/gorilla/mux"
"github.com/gorilla/mux"
certutil
"github.com/rancher/dynamiclistener/cert"
certutil
"github.com/rancher/dynamiclistener/cert"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/daemons/control"
"github.com/rancher/k3s/pkg/openapi"
"github.com/rancher/k3s/pkg/openapi"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/kubernetes/pkg/master"
)
)
const
(
const
(
...
@@ -38,8 +39,14 @@ func router(serverConfig *config.Control, tunnel http.Handler, cacertsGetter CAC
...
@@ -38,8 +39,14 @@ func router(serverConfig *config.Control, tunnel http.Handler, cacertsGetter CAC
authed
.
Use
(
authMiddleware
(
serverConfig
))
authed
.
Use
(
authMiddleware
(
serverConfig
))
authed
.
NotFoundHandler
=
serverConfig
.
Runtime
.
Handler
authed
.
NotFoundHandler
=
serverConfig
.
Runtime
.
Handler
authed
.
Path
(
"/v1-k3s/connect"
)
.
Handler
(
tunnel
)
authed
.
Path
(
"/v1-k3s/connect"
)
.
Handler
(
tunnel
)
authed
.
Path
(
"/v1-k3s/node.crt"
)
.
Handler
(
nodeCrt
(
serverConfig
))
authed
.
Path
(
"/v1-k3s/serving-kubelet.crt"
)
.
Handler
(
servingKubeletCert
(
serverConfig
))
authed
.
Path
(
"/v1-k3s/node.key"
)
.
Handler
(
nodeKey
(
serverConfig
))
authed
.
Path
(
"/v1-k3s/serving-kubelet.key"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ServingKubeletKey
))
authed
.
Path
(
"/v1-k3s/client-kubelet.crt"
)
.
Handler
(
clientKubeletCert
(
serverConfig
))
authed
.
Path
(
"/v1-k3s/client-kubelet.key"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ClientKubeletKey
))
authed
.
Path
(
"/v1-k3s/client-kube-proxy.crt"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ClientKubeProxyCert
))
authed
.
Path
(
"/v1-k3s/client-kube-proxy.key"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ClientKubeProxyKey
))
authed
.
Path
(
"/v1-k3s/client-ca.crt"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ClientCA
))
authed
.
Path
(
"/v1-k3s/server-ca.crt"
)
.
Handler
(
fileHandler
(
serverConfig
.
Runtime
.
ServerCA
))
authed
.
Path
(
"/v1-k3s/config"
)
.
Handler
(
configHandler
(
serverConfig
))
authed
.
Path
(
"/v1-k3s/config"
)
.
Handler
(
configHandler
(
serverConfig
))
staticDir
:=
filepath
.
Join
(
serverConfig
.
DataDir
,
"static"
)
staticDir
:=
filepath
.
Join
(
serverConfig
.
DataDir
,
"static"
)
...
@@ -65,82 +72,122 @@ func cacerts(getter CACertsGetter) http.Handler {
...
@@ -65,82 +72,122 @@ func cacerts(getter CACertsGetter) http.Handler {
})
})
}
}
func
nodeCrt
(
server
*
config
.
Control
)
http
.
Handler
{
func
getNodeInfo
(
req
*
http
.
Request
)
(
string
,
string
,
error
)
{
nodeNames
:=
req
.
Header
[
"K3s-Node-Name"
]
if
len
(
nodeNames
)
!=
1
||
nodeNames
[
0
]
==
""
{
return
""
,
""
,
errors
.
New
(
"node name not set"
)
}
nodePasswords
:=
req
.
Header
[
"K3s-Node-Password"
]
if
len
(
nodePasswords
)
!=
1
||
nodePasswords
[
0
]
==
""
{
return
""
,
""
,
errors
.
New
(
"node password not set"
)
}
return
nodeNames
[
0
],
nodePasswords
[
0
],
nil
}
func
getCACertAndKeys
(
caCertFile
,
caKeyFile
,
signingKeyFile
string
)
([]
*
x509
.
Certificate
,
crypto
.
Signer
,
crypto
.
Signer
,
error
)
{
keyBytes
,
err
:=
ioutil
.
ReadFile
(
signingKeyFile
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
err
}
key
,
err
:=
certutil
.
ParsePrivateKeyPEM
(
keyBytes
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
err
}
caKeyBytes
,
err
:=
ioutil
.
ReadFile
(
caKeyFile
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
err
}
caKey
,
err
:=
certutil
.
ParsePrivateKeyPEM
(
caKeyBytes
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
err
}
caBytes
,
err
:=
ioutil
.
ReadFile
(
caCertFile
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
err
}
caCert
,
err
:=
certutil
.
ParseCertsPEM
(
caBytes
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
err
}
return
caCert
,
caKey
.
(
crypto
.
Signer
),
key
.
(
crypto
.
Signer
),
nil
}
func
servingKubeletCert
(
server
*
config
.
Control
)
http
.
Handler
{
return
http
.
HandlerFunc
(
func
(
resp
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
return
http
.
HandlerFunc
(
func
(
resp
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
if
req
.
TLS
==
nil
{
if
req
.
TLS
==
nil
{
resp
.
WriteHeader
(
http
.
StatusNotFound
)
resp
.
WriteHeader
(
http
.
StatusNotFound
)
return
return
}
}
nodeNames
:=
req
.
Header
[
"K3s-Node-Name"
]
nodeName
,
nodePassword
,
err
:=
getNodeInfo
(
req
)
if
len
(
nodeNames
)
!=
1
||
nodeNames
[
0
]
==
""
{
if
err
!=
nil
{
sendError
(
errors
.
New
(
"node name not set"
),
resp
)
sendError
(
err
,
resp
)
return
}
nodePasswords
:=
req
.
Header
[
"K3s-Node-Password"
]
if
len
(
nodePasswords
)
!=
1
||
nodePasswords
[
0
]
==
""
{
sendError
(
errors
.
New
(
"node password not set"
),
resp
)
return
}
}
if
err
:=
ensureNodePassword
(
server
.
Runtime
.
PasswdFile
,
nodeName
s
[
0
],
nodePasswords
[
0
]
);
err
!=
nil
{
if
err
:=
ensureNodePassword
(
server
.
Runtime
.
PasswdFile
,
nodeName
,
nodePassword
);
err
!=
nil
{
sendError
(
err
,
resp
,
http
.
StatusForbidden
)
sendError
(
err
,
resp
,
http
.
StatusForbidden
)
return
return
}
}
nodeKey
,
err
:=
ioutil
.
ReadFile
(
server
.
Runtime
.
Node
Key
)
caCert
,
caKey
,
key
,
err
:=
getCACertAndKeys
(
server
.
Runtime
.
ServerCA
,
server
.
Runtime
.
ServerCAKey
,
server
.
Runtime
.
ServingKubelet
Key
)
if
err
!=
nil
{
if
err
!=
nil
{
sendError
(
err
,
resp
)
sendError
(
err
,
resp
)
return
return
}
}
key
,
err
:=
certutil
.
ParsePrivateKeyPEM
(
nodeKey
)
cert
,
err
:=
certutil
.
NewSignedCert
(
certutil
.
Config
{
CommonName
:
nodeName
,
Usages
:
[]
x509
.
ExtKeyUsage
{
x509
.
ExtKeyUsageServerAuth
},
AltNames
:
certutil
.
AltNames
{
DNSNames
:
[]
string
{
nodeName
,
"localhost"
},
IPs
:
[]
net
.
IP
{
net
.
ParseIP
(
"127.0.0.1"
)},
},
},
key
,
caCert
[
0
],
caKey
)
if
err
!=
nil
{
if
err
!=
nil
{
sendError
(
err
,
resp
)
sendError
(
err
,
resp
)
return
return
}
}
caKeyBytes
,
err
:=
ioutil
.
ReadFile
(
server
.
Runtime
.
TokenCAKey
)
resp
.
Write
(
append
(
certutil
.
EncodeCertPEM
(
cert
),
certutil
.
EncodeCertPEM
(
caCert
[
0
])
...
))
if
err
!=
nil
{
})
sendError
(
err
,
resp
)
}
return
}
caBytes
,
err
:=
ioutil
.
ReadFile
(
server
.
Runtime
.
TokenCA
)
func
clientKubeletCert
(
server
*
config
.
Control
)
http
.
Handler
{
if
err
!=
nil
{
return
http
.
HandlerFunc
(
func
(
resp
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
sendError
(
err
,
resp
)
if
req
.
TLS
==
nil
{
resp
.
WriteHeader
(
http
.
StatusNotFound
)
return
return
}
}
caKey
,
err
:=
certutil
.
ParsePrivateKeyPEM
(
caKeyBytes
)
nodeName
,
nodePassword
,
err
:=
getNodeInfo
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
sendError
(
err
,
resp
)
sendError
(
err
,
resp
)
return
}
}
caCert
,
err
:=
certutil
.
ParseCertsPEM
(
caBytes
)
if
err
:=
ensureNodePassword
(
server
.
Runtime
.
PasswdFile
,
nodeName
,
nodePassword
);
err
!=
nil
{
if
err
!=
nil
{
sendError
(
err
,
resp
,
http
.
StatusForbidden
)
sendError
(
err
,
resp
)
return
return
}
}
_
,
apiServerServiceIP
,
err
:=
master
.
DefaultServiceIPRange
(
*
server
.
ServiceIPRange
)
caCert
,
caKey
,
key
,
err
:=
getCACertAndKeys
(
server
.
Runtime
.
ClientCA
,
server
.
Runtime
.
ClientCAKey
,
server
.
Runtime
.
ClientKubeletKey
)
if
err
!=
nil
{
if
err
!=
nil
{
sendError
(
err
,
resp
)
sendError
(
err
,
resp
)
return
return
}
}
cfg
:=
certutil
.
Config
{
cert
,
err
:=
certutil
.
NewSignedCert
(
certutil
.
Config
{
CommonName
:
"kubernetes"
,
CommonName
:
"system:node:"
+
nodeName
,
Usages
:
[]
x509
.
ExtKeyUsage
{
x509
.
ExtKeyUsageServerAuth
,
x509
.
ExtKeyUsageClientAuth
},
Organization
:
[]
string
{
"system:nodes"
},
AltNames
:
certutil
.
AltNames
{
Usages
:
[]
x509
.
ExtKeyUsage
{
x509
.
ExtKeyUsageClientAuth
},
DNSNames
:
[]
string
{
"kubernetes.default.svc"
,
"kubernetes.default"
,
"kubernetes"
,
"localhost"
,
nodeNames
[
0
]},
},
key
,
caCert
[
0
],
caKey
)
IPs
:
[]
net
.
IP
{
apiServerServiceIP
,
net
.
ParseIP
(
"127.0.0.1"
)},
},
}
cert
,
err
:=
certutil
.
NewSignedCert
(
cfg
,
key
.
(
*
rsa
.
PrivateKey
),
caCert
[
0
],
caKey
.
(
*
rsa
.
PrivateKey
))
if
err
!=
nil
{
if
err
!=
nil
{
sendError
(
err
,
resp
)
sendError
(
err
,
resp
)
return
return
...
@@ -150,13 +197,13 @@ func nodeCrt(server *config.Control) http.Handler {
...
@@ -150,13 +197,13 @@ func nodeCrt(server *config.Control) http.Handler {
})
})
}
}
func
nodeKey
(
server
*
config
.
Control
)
http
.
Handler
{
func
fileHandler
(
fileName
string
)
http
.
Handler
{
return
http
.
HandlerFunc
(
func
(
resp
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
return
http
.
HandlerFunc
(
func
(
resp
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
if
req
.
TLS
==
nil
{
if
req
.
TLS
==
nil
{
resp
.
WriteHeader
(
http
.
StatusNotFound
)
resp
.
WriteHeader
(
http
.
StatusNotFound
)
return
return
}
}
http
.
ServeFile
(
resp
,
req
,
server
.
Runtime
.
NodeKey
)
http
.
ServeFile
(
resp
,
req
,
fileName
)
})
})
}
}
...
@@ -225,29 +272,29 @@ func ensureNodePassword(passwdFile, nodeName, passwd string) error {
...
@@ -225,29 +272,29 @@ func ensureNodePassword(passwdFile, nodeName, passwd string) error {
defer
f
.
Close
()
defer
f
.
Close
()
user
:=
strings
.
ToLower
(
"node:"
+
nodeName
)
user
:=
strings
.
ToLower
(
"node:"
+
nodeName
)
buf
:=
&
strings
.
Builder
{}
records
:=
[][]
string
{}
scan
:=
bufio
.
NewScanner
(
f
)
reader
:=
csv
.
NewReader
(
f
)
for
scan
.
Scan
()
{
for
{
line
:=
scan
.
Text
()
record
,
err
:=
reader
.
Read
()
parts
:=
strings
.
Split
(
line
,
","
)
if
err
==
io
.
EOF
{
if
len
(
parts
)
<
4
{
break
continue
}
if
err
!=
nil
{
return
err
}
}
if
parts
[
1
]
==
user
{
if
len
(
record
)
<
3
{
if
parts
[
0
]
==
passwd
{
return
fmt
.
Errorf
(
"password file '%s' must have at least 3 columns (password, user name, user uid), found %d"
,
passwdFile
,
len
(
record
))
}
if
record
[
1
]
==
user
{
if
record
[
0
]
==
passwd
{
return
nil
return
nil
}
}
return
fmt
.
Errorf
(
"Node password validation failed for
[%s]"
,
nodeNam
e
)
return
fmt
.
Errorf
(
"Node password validation failed for
'%s', using passwd file '%s'"
,
nodeName
,
passwdFil
e
)
}
}
buf
.
WriteString
(
line
)
records
=
append
(
records
,
record
)
buf
.
WriteString
(
"
\n
"
)
}
buf
.
WriteString
(
fmt
.
Sprintf
(
"%s,%s,%s,system:masters
\n
"
,
passwd
,
user
,
user
))
if
scan
.
Err
()
!=
nil
{
return
scan
.
Err
()
}
}
records
=
append
(
records
,
[]
string
{
passwd
,
user
,
user
,
"system:node:"
+
nodeName
})
f
.
Close
()
f
.
Close
()
return
ioutil
.
WriteFile
(
passwdFile
,
[]
byte
(
buf
.
String
()),
0600
)
return
control
.
WritePasswords
(
passwdFile
,
records
)
}
}
pkg/server/server.go
View file @
2c944439
...
@@ -77,6 +77,18 @@ func startWrangler(ctx context.Context, config *Config) (string, error) {
...
@@ -77,6 +77,18 @@ func startWrangler(ctx context.Context, config *Config) (string, error) {
controlConfig
=
&
config
.
ControlConfig
controlConfig
=
&
config
.
ControlConfig
)
)
caBytes
,
err
:=
ioutil
.
ReadFile
(
controlConfig
.
Runtime
.
ServerCA
)
if
err
!=
nil
{
return
""
,
err
}
caKeyBytes
,
err
:=
ioutil
.
ReadFile
(
controlConfig
.
Runtime
.
ServerCAKey
)
if
err
!=
nil
{
return
""
,
err
}
tlsConfig
.
CACerts
=
string
(
caBytes
)
tlsConfig
.
CAKey
=
string
(
caKeyBytes
)
tlsConfig
.
Handler
=
router
(
controlConfig
,
controlConfig
.
Runtime
.
Tunnel
,
func
()
(
string
,
error
)
{
tlsConfig
.
Handler
=
router
(
controlConfig
,
controlConfig
.
Runtime
.
Tunnel
,
func
()
(
string
,
error
)
{
if
tlsServer
==
nil
{
if
tlsServer
==
nil
{
return
""
,
nil
return
""
,
nil
...
@@ -84,7 +96,7 @@ func startWrangler(ctx context.Context, config *Config) (string, error) {
...
@@ -84,7 +96,7 @@ func startWrangler(ctx context.Context, config *Config) (string, error) {
return
tlsServer
.
CACert
()
return
tlsServer
.
CACert
()
})
})
sc
,
err
:=
newContext
(
ctx
,
controlConfig
.
Runtime
.
KubeConfig
System
)
sc
,
err
:=
newContext
(
ctx
,
controlConfig
.
Runtime
.
KubeConfig
Admin
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
...
...
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