mirror of https://github.com/k3s-io/k3s
Add a HollowProxy to the HollowNode.
parent
a10ed3e2b1
commit
5a4e4d4d57
|
@ -62,7 +62,7 @@ type ProxyServerConfig struct {
|
|||
ProxyMode string
|
||||
IptablesSyncPeriod time.Duration
|
||||
ConfigSyncPeriod time.Duration
|
||||
nodeRef *api.ObjectReference // Reference to this node.
|
||||
NodeRef *api.ObjectReference // Reference to this node.
|
||||
MasqueradeAll bool
|
||||
CleanupAndExit bool
|
||||
KubeApiQps float32
|
||||
|
@ -71,9 +71,11 @@ type ProxyServerConfig struct {
|
|||
}
|
||||
|
||||
type ProxyServer struct {
|
||||
Client *kubeclient.Client
|
||||
Config *ProxyServerConfig
|
||||
IptInterface utiliptables.Interface
|
||||
Proxier proxy.ProxyProvider
|
||||
Broadcaster record.EventBroadcaster
|
||||
Recorder record.EventRecorder
|
||||
}
|
||||
|
||||
|
@ -129,15 +131,19 @@ func NewProxyConfig() *ProxyServerConfig {
|
|||
}
|
||||
|
||||
func NewProxyServer(
|
||||
client *kubeclient.Client,
|
||||
config *ProxyServerConfig,
|
||||
iptInterface utiliptables.Interface,
|
||||
proxier proxy.ProxyProvider,
|
||||
broadcaster record.EventBroadcaster,
|
||||
recorder record.EventRecorder,
|
||||
) (*ProxyServer, error) {
|
||||
return &ProxyServer{
|
||||
Client: client,
|
||||
Config: config,
|
||||
IptInterface: iptInterface,
|
||||
Proxier: proxier,
|
||||
Broadcaster: broadcaster,
|
||||
Recorder: recorder,
|
||||
}, nil
|
||||
}
|
||||
|
@ -207,7 +213,6 @@ func NewProxyServerDefault(config *ProxyServerConfig) (*ProxyServer, error) {
|
|||
hostname := nodeutil.GetHostname(config.HostnameOverride)
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "kube-proxy", Host: hostname})
|
||||
eventBroadcaster.StartRecordingToSink(client.Events(""))
|
||||
|
||||
var proxier proxy.ProxyProvider
|
||||
var endpointsHandler proxyconfig.EndpointsConfigHandler
|
||||
|
@ -269,13 +274,13 @@ func NewProxyServerDefault(config *ProxyServerConfig) (*ProxyServer, error) {
|
|||
endpointsConfig.Channel("api"),
|
||||
)
|
||||
|
||||
config.nodeRef = &api.ObjectReference{
|
||||
config.NodeRef = &api.ObjectReference{
|
||||
Kind: "Node",
|
||||
Name: hostname,
|
||||
UID: types.UID(hostname),
|
||||
Namespace: "",
|
||||
}
|
||||
return NewProxyServer(config, iptInterface, proxier, recorder)
|
||||
return NewProxyServer(client, config, iptInterface, proxier, eventBroadcaster, recorder)
|
||||
}
|
||||
|
||||
// Run runs the specified ProxyServer. This should never exit (unless CleanupAndExit is set).
|
||||
|
@ -290,6 +295,8 @@ func (s *ProxyServer) Run(_ []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
s.Broadcaster.StartRecordingToSink(s.Client.Events(""))
|
||||
|
||||
// Birth Cry after the birth is successful
|
||||
s.birthCry()
|
||||
|
||||
|
@ -353,5 +360,5 @@ func mayTryIptablesProxy(proxyMode string, client nodeGetter, hostname string) b
|
|||
}
|
||||
|
||||
func (s *ProxyServer) birthCry() {
|
||||
s.Recorder.Eventf(s.Config.nodeRef, "Starting", "Starting kube-proxy.")
|
||||
s.Recorder.Eventf(s.Config.NodeRef, "Starting", "Starting kube-proxy.")
|
||||
}
|
||||
|
|
|
@ -22,12 +22,18 @@ import (
|
|||
"time"
|
||||
|
||||
docker "github.com/fsouza/go-dockerclient"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||
"k8s.io/kubernetes/pkg/kubelet/cadvisor"
|
||||
"k8s.io/kubernetes/pkg/kubelet/dockertools"
|
||||
"k8s.io/kubernetes/pkg/kubemark"
|
||||
proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
fakeiptables "k8s.io/kubernetes/pkg/util/iptables/testing"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
|
@ -37,16 +43,20 @@ type HollowNodeConfig struct {
|
|||
KubeconfigPath string
|
||||
KubeletPort int
|
||||
KubeletReadOnlyPort int
|
||||
Morph string
|
||||
NodeName string
|
||||
ServerPort int
|
||||
}
|
||||
|
||||
var knownMorphs = sets.NewString("kubelet", "proxy")
|
||||
|
||||
func (c *HollowNodeConfig) addFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&c.KubeconfigPath, "kubeconfig", "/kubeconfig/kubeconfig", "Path to kubeconfig file.")
|
||||
fs.IntVar(&c.KubeletPort, "kubelet-port", 10250, "Port on which HollowKubelet should be listening.")
|
||||
fs.IntVar(&c.KubeletReadOnlyPort, "kubelet-read-only-port", 10255, "Read-only port on which Kubelet is listening.")
|
||||
fs.StringVar(&c.NodeName, "name", "fake-node", "Name of this Hollow Node.")
|
||||
fs.IntVar(&c.ServerPort, "api-server-port", 443, "Port on which API server is listening.")
|
||||
fs.StringVar(&c.Morph, "morph", "", fmt.Sprintf("Specifies into which Hollow component this binary should morph. Allowed values: %v", knownMorphs.List()))
|
||||
}
|
||||
|
||||
func createClientFromFile(path string) (*client.Client, error) {
|
||||
|
@ -75,25 +85,48 @@ func main() {
|
|||
config.addFlags(pflag.CommandLine)
|
||||
util.InitFlags()
|
||||
|
||||
// create a client for Kubelet to communicate with API server.
|
||||
if !knownMorphs.Has(config.Morph) {
|
||||
glog.Fatal("Unknown morph: %v. Allowed values: %v", config.Morph, knownMorphs.List())
|
||||
}
|
||||
|
||||
// create a client to communicate with API server.
|
||||
cl, err := createClientFromFile(config.KubeconfigPath)
|
||||
if err != nil {
|
||||
glog.Fatal("Failed to create a Client. Exiting.")
|
||||
}
|
||||
cadvisorInterface := new(cadvisor.Fake)
|
||||
|
||||
fakeDockerClient := &dockertools.FakeDockerClient{}
|
||||
fakeDockerClient.VersionInfo = docker.Env{"ApiVersion=1.18"}
|
||||
fakeDockerClient.ContainerMap = make(map[string]*docker.Container)
|
||||
fakeDockerClient.EnableSleep = true
|
||||
if config.Morph == "kubelet" {
|
||||
cadvisorInterface := new(cadvisor.Fake)
|
||||
|
||||
hollowKubelet := kubemark.NewHollowKubelet(
|
||||
config.NodeName,
|
||||
cl,
|
||||
cadvisorInterface,
|
||||
fakeDockerClient,
|
||||
config.KubeletPort,
|
||||
config.KubeletReadOnlyPort,
|
||||
)
|
||||
hollowKubelet.Run()
|
||||
fakeDockerClient := &dockertools.FakeDockerClient{}
|
||||
fakeDockerClient.VersionInfo = docker.Env{"ApiVersion=1.18"}
|
||||
fakeDockerClient.ContainerMap = make(map[string]*docker.Container)
|
||||
fakeDockerClient.EnableSleep = true
|
||||
|
||||
hollowKubelet := kubemark.NewHollowKubelet(
|
||||
config.NodeName,
|
||||
cl,
|
||||
cadvisorInterface,
|
||||
fakeDockerClient,
|
||||
config.KubeletPort,
|
||||
config.KubeletReadOnlyPort,
|
||||
)
|
||||
hollowKubelet.Run()
|
||||
}
|
||||
|
||||
if config.Morph == "proxy" {
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "kube-proxy", Host: config.NodeName})
|
||||
|
||||
iptInterface := fakeiptables.NewFake()
|
||||
|
||||
serviceConfig := proxyconfig.NewServiceConfig()
|
||||
serviceConfig.RegisterHandler(&kubemark.FakeProxyHandler{})
|
||||
|
||||
endpointsConfig := proxyconfig.NewEndpointsConfig()
|
||||
endpointsConfig.RegisterHandler(&kubemark.FakeProxyHandler{})
|
||||
|
||||
hollowProxy := kubemark.NewHollowProxyOrDie(config.NodeName, cl, endpointsConfig, serviceConfig, iptInterface, eventBroadcaster, recorder)
|
||||
hollowProxy.Run()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubemark
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
proxyapp "k8s.io/kubernetes/cmd/kube-proxy/app"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
|
||||
"k8s.io/kubernetes/pkg/types"
|
||||
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
type HollowProxy struct {
|
||||
ProxyServer *proxyapp.ProxyServer
|
||||
}
|
||||
|
||||
type FakeProxyHandler struct{}
|
||||
|
||||
func (*FakeProxyHandler) OnServiceUpdate(services []api.Service) {}
|
||||
func (*FakeProxyHandler) OnEndpointsUpdate(endpoints []api.Endpoints) {}
|
||||
|
||||
type FakeProxier struct{}
|
||||
|
||||
func (*FakeProxier) OnServiceUpdate(services []api.Service) {}
|
||||
func (*FakeProxier) Sync() {}
|
||||
func (*FakeProxier) SyncLoop() {
|
||||
select {}
|
||||
}
|
||||
|
||||
func NewHollowProxyOrDie(
|
||||
nodeName string,
|
||||
client *client.Client,
|
||||
endpointsConfig *proxyconfig.EndpointsConfig,
|
||||
serviceConfig *proxyconfig.ServiceConfig,
|
||||
iptInterface utiliptables.Interface,
|
||||
broadcaster record.EventBroadcaster,
|
||||
recorder record.EventRecorder,
|
||||
) *HollowProxy {
|
||||
// Create and start Hollow Proxy
|
||||
config := proxyapp.NewProxyConfig()
|
||||
config.OOMScoreAdj = 0
|
||||
config.ResourceContainer = ""
|
||||
config.NodeRef = &api.ObjectReference{
|
||||
Kind: "Node",
|
||||
Name: nodeName,
|
||||
UID: types.UID(nodeName),
|
||||
Namespace: "",
|
||||
}
|
||||
proxyconfig.NewSourceAPI(
|
||||
client,
|
||||
30*time.Second,
|
||||
serviceConfig.Channel("api"),
|
||||
endpointsConfig.Channel("api"),
|
||||
)
|
||||
|
||||
hollowProxy, err := proxyapp.NewProxyServer(client, config, iptInterface, &FakeProxier{}, broadcaster, recorder)
|
||||
if err != nil {
|
||||
glog.Fatalf("Error while creating ProxyServer: %v\n", err)
|
||||
}
|
||||
return &HollowProxy{
|
||||
ProxyServer: hollowProxy,
|
||||
}
|
||||
}
|
||||
|
||||
func (hp *HollowProxy) Run() {
|
||||
if err := hp.ProxyServer.Run(make([]string, 0)); err != nil {
|
||||
glog.Fatalf("Error while running proxy: %v\n", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package testing
|
||||
|
||||
import "k8s.io/kubernetes/pkg/util/iptables"
|
||||
|
||||
// no-op implemenatation of iptables Interface
|
||||
type fake struct{}
|
||||
|
||||
func NewFake() *fake {
|
||||
return &fake{}
|
||||
}
|
||||
|
||||
func (*fake) EnsureChain(table iptables.Table, chain iptables.Chain) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (*fake) FlushChain(table iptables.Table, chain iptables.Chain) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*fake) DeleteChain(table iptables.Table, chain iptables.Chain) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*fake) EnsureRule(position iptables.RulePosition, table iptables.Table, chain iptables.Chain, args ...string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (*fake) DeleteRule(table iptables.Table, chain iptables.Chain, args ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*fake) IsIpv6() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (*fake) Save(table iptables.Table) ([]byte, error) {
|
||||
return make([]byte, 0), nil
|
||||
}
|
||||
|
||||
func (*fake) SaveAll() ([]byte, error) {
|
||||
return make([]byte, 0), nil
|
||||
}
|
||||
|
||||
func (*fake) Restore(table iptables.Table, data []byte, flush iptables.FlushFlag, counters iptables.RestoreCountersFlag) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*fake) RestoreAll(data []byte, flush iptables.FlushFlag, counters iptables.RestoreCountersFlag) error {
|
||||
return nil
|
||||
}
|
||||
func (*fake) AddReloadFunc(reloadFunc func()) {}
|
||||
|
||||
func (*fake) Destroy() {}
|
||||
|
||||
var _ = iptables.Interface(&fake{})
|
|
@ -14,8 +14,8 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
source "${KUBE_ROOT}/cluster/kubemark/util.sh"
|
||||
source "${KUBE_ROOT}/cluster/kubemark/config-default.sh"
|
||||
source "${KUBE_ROOT}/cluster/kubemark/util.sh"
|
||||
|
||||
detect-project &> /dev/null
|
||||
export PROJECT
|
||||
|
|
|
@ -2,20 +2,20 @@
|
|||
"kind": "ReplicationController",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "hollow-kubelet",
|
||||
"name": "hollow-node",
|
||||
"labels": {
|
||||
"name": "hollow-kubelet"
|
||||
"name": "hollow-node"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"replicas": ##numreplicas##,
|
||||
"selector": {
|
||||
"name": "hollow-kubelet"
|
||||
"name": "hollow-node"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"name": "hollow-kubelet"
|
||||
"name": "hollow-node"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
|
@ -27,7 +27,8 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"containers": [{
|
||||
"containers": [
|
||||
{
|
||||
"name": "hollow-kubelet",
|
||||
"image": "gcr.io/##project##/kubemark:latest",
|
||||
"ports": [
|
||||
|
@ -39,7 +40,8 @@
|
|||
"./kubemark.sh"
|
||||
],
|
||||
"args": [
|
||||
"--v=3"
|
||||
"--v=3",
|
||||
"--morph=kubelet"
|
||||
],
|
||||
"volumeMounts": [
|
||||
{
|
||||
|
@ -53,6 +55,30 @@
|
|||
"memory": "100M"
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"name": "hollow-proxy",
|
||||
"image": "gcr.io/##project##/kubemark:latest",
|
||||
"command": [
|
||||
"./kubemark.sh"
|
||||
],
|
||||
"args": [
|
||||
"--v=3",
|
||||
"--morph=proxy"
|
||||
],
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "kubeconfig-volume",
|
||||
"mountPath": "/kubeconfig"
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"requests": {
|
||||
"cpu": "20m",
|
||||
"memory": "100M"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
|
@ -200,11 +200,11 @@ contexts:
|
|||
current-context: kubemark-context
|
||||
EOF
|
||||
|
||||
sed "s/##numreplicas##/${NUM_MINIONS:-10}/g" ${KUBE_ROOT}/test/kubemark/hollow-kubelet_template.json > ${KUBE_ROOT}/test/kubemark/hollow-kubelet.json
|
||||
sed -i'' -e "s/##project##/${PROJECT}/g" ${KUBE_ROOT}/test/kubemark/hollow-kubelet.json
|
||||
sed "s/##numreplicas##/${NUM_MINIONS:-10}/g" ${KUBE_ROOT}/test/kubemark/hollow-node_template.json > ${KUBE_ROOT}/test/kubemark/hollow-node.json
|
||||
sed -i'' -e "s/##project##/${PROJECT}/g" ${KUBE_ROOT}/test/kubemark/hollow-node.json
|
||||
kubectl create -f ${KUBE_ROOT}/test/kubemark/kubemark-ns.json
|
||||
kubectl create -f ${KUBECONFIG_SECRET} --namespace="kubemark"
|
||||
kubectl create -f ${KUBE_ROOT}/test/kubemark/hollow-kubelet.json --namespace="kubemark"
|
||||
kubectl create -f ${KUBE_ROOT}/test/kubemark/hollow-node.json --namespace="kubemark"
|
||||
|
||||
rm ${KUBECONFIG_SECRET}
|
||||
|
||||
|
|
Loading…
Reference in New Issue