Skip to content
This repository has been archived by the owner on Jun 14, 2018. It is now read-only.

Implement Istio sidecar initializer #1041

Merged
merged 20 commits into from
Aug 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bin/push-docker
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,15 @@ bazel build --output_groups=static //cmd/... //test/...
\cp -f "${bin}/test/server/server.static" docker/server
\cp -f "${bin}/cmd/pilot-agent/pilot-agent.static" docker/pilot-agent
\cp -f "${bin}/cmd/pilot-discovery/pilot-discovery.static" docker/pilot-discovery
\cp -f "${bin}/cmd/sidecar-initializer/sidecar-initializer.static" docker/sidecar-initializer

# Build and push images

IFS=',' read -ra tags <<< "${tags}"
IFS=',' read -ra hubs <<< "${hubs}"

pushd docker
for image in app proxy proxy_init proxy_debug pilot; do
for image in app proxy proxy_init proxy_debug pilot sidecar_initializer; do
local_image="${image}:${local_tag}"
docker build -q -f "Dockerfile.${image}" -t "${local_image}" .
for tag in ${tags[@]}; do
Expand Down
24 changes: 24 additions & 0 deletions cmd/sidecar-initializer/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing copyright?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We haven't been adding copyright to the BUILD files.

$ find -name BUILD | xargs grep Copyright | wc -l                                                                                                              
0


go_library(
name = "go_default_library",
srcs = ["main.go"],
visibility = ["//visibility:private"],
deps = [
"//cmd:go_default_library",
"//platform/kube:go_default_library",
"//platform/kube/inject:go_default_library",
"//tools/version:go_default_library",
"@com_github_davecgh_go_spew//spew:go_default_library",
"@com_github_golang_glog//:go_default_library",
"@com_github_hashicorp_go_multierror//:go_default_library",
"@com_github_spf13_cobra//:go_default_library",
"@io_k8s_api//core/v1:go_default_library",
],
)

go_binary(
name = "sidecar-initializer",
library = ":go_default_library",
visibility = ["//visibility:public"],
)
111 changes: 111 additions & 0 deletions cmd/sidecar-initializer/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright 2017 Istio Authors
//
// 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 main

import (
"fmt"
"os"
"time"

"k8s.io/api/core/v1"

"istio.io/pilot/cmd"
"istio.io/pilot/platform/kube"
"istio.io/pilot/platform/kube/inject"
"istio.io/pilot/tools/version"

"github.com/davecgh/go-spew/spew"
"github.com/golang/glog"
multierror "github.com/hashicorp/go-multierror"
"github.com/spf13/cobra"
)

func getRootCmd() *cobra.Command {
flags := struct {
kubeconfig string
meshconfig string
hub string
tag string
namespace string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this enable initializer for a given namespace? If so, won't we need one initializer per namespace? Is there a possibility to watch some config map or something to pick up namespaces enabled for Istio?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initializer is enabled with the InitializerConfiguration resource. InitializerConfiguration is cluster scoped and there is no way through that to restrict which namespace(s) require initialization - its all or nothing. Some proposals to fix this problem are documented here but nothing is designed/implemented.

This namespace flag determines which namespace the initializer deployment manages. This is useful (required?) in our shared per-namespace e2e tests. In this case we would need one initializer deployment per namespace. Once cluster-wide Istio is the standard this can default to v1.NameSpaceAll and the single initializer deployment would be responsible for the entire cluster.

policy string
resyncPeriod time.Duration
}{}

rootCmd := &cobra.Command{
Use: "sidecar-initializer",
Short: "Kubernetes initializer for Istio sidecar",
RunE: func(*cobra.Command, []string) error {
switch inject.InjectionPolicy(flags.policy) {
case inject.InjectionPolicyOff, inject.InjectionPolicyOptIn, inject.InjectionPolicyOptOut:
default:
return fmt.Errorf("unknown injection policy: %v", flags.policy)
}

client, err := kube.CreateInterface(flags.kubeconfig)
if err != nil {
return multierror.Prefix(err, "failed to connect to Kubernetes API.")
}

glog.V(2).Infof("version %s", version.Line())
glog.V(2).Infof("flags %s", spew.Sdump(flags))

// receive mesh configuration
mesh, err := cmd.ReadMeshConfig(flags.meshconfig)
if err != nil {
return multierror.Prefix(err, "failed to read mesh configuration.")
}

options := inject.InitializerOptions{
ResyncPeriod: flags.resyncPeriod,
Hub: flags.hub,
Tag: flags.tag,
Namespace: flags.namespace,

InjectionPolicy: inject.InjectionPolicy(flags.policy),
}
initializer := inject.NewInitializer(client, mesh, options)

stop := make(chan struct{})
go initializer.Run(stop)
cmd.WaitSignal(stop)

return nil
},
}

rootCmd.PersistentFlags().StringVar(&flags.hub, "hub", "docker.io/istio", "Docker hub")
rootCmd.PersistentFlags().StringVar(&flags.tag, "tag", "0.2", "Docker tag")
rootCmd.PersistentFlags().StringVar(&flags.namespace, "namespace",
v1.NamespaceAll, "Namespace managed by initializer")
rootCmd.PersistentFlags().StringVar(&flags.policy, "policy",
string(inject.InjectionPolicyOff), "default injection policy")

rootCmd.PersistentFlags().StringVar(&flags.kubeconfig, "kubeconfig", "",
"Use a Kubernetes configuration file instead of in-cluster configuration")
rootCmd.PersistentFlags().StringVar(&flags.meshconfig, "meshconfig", "/etc/istio/config/mesh",
fmt.Sprintf("File name for Istio mesh configuration"))
rootCmd.PersistentFlags().DurationVar(&flags.resyncPeriod, "resync", 6*time.Minute,
"Initializers resync interval")

cmd.AddFlags(rootCmd)

return rootCmd
}

func main() {
if err := getRootCmd().Execute(); err != nil {
os.Exit(-1)
}
}
1 change: 1 addition & 0 deletions docker/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ client
server
pilot-agent
pilot-discovery
sidecar-initializer
3 changes: 3 additions & 0 deletions docker/Dockerfile.sidecar_initializer
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM scratch
ADD sidecar-initializer /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/sidecar-initializer"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably want some TLS certs here (assuming we need to talk to something other than kube API)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current version only ever interacts with the k8s apiserver via patch/list/watch. It uses the in-cluster config similar to pilot discovery service.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, then it's fine. Running out of cluster would not use docker anyways.

26 changes: 24 additions & 2 deletions platform/kube/inject/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,55 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
name = "go_default_library",
srcs = ["inject.go"],
srcs = [
"initializer.go",
"inject.go",
],
visibility = ["//visibility:public"],
deps = [
"//model:go_default_library",
"//proxy:go_default_library",
"//tools/version:go_default_library",
"@com_github_ghodss_yaml//:go_default_library",
"@com_github_golang_glog//:go_default_library",
"@com_github_hashicorp_go_multierror//:go_default_library",
"@io_istio_api//:go_default_library",
"@io_k8s_api//apps/v1beta1:go_default_library",
"@io_k8s_api//batch/v1:go_default_library",
"@io_k8s_api//core/v1:go_default_library",
"@io_k8s_api//extensions/v1beta1:go_default_library",
"@io_k8s_apimachinery//pkg/api/meta:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_apimachinery//pkg/fields:go_default_library",
"@io_k8s_apimachinery//pkg/runtime:go_default_library",
"@io_k8s_apimachinery//pkg/types:go_default_library",
"@io_k8s_apimachinery//pkg/util/strategicpatch:go_default_library",
"@io_k8s_apimachinery//pkg/util/yaml:go_default_library",
"@io_k8s_apimachinery//pkg/watch:go_default_library",
"@io_k8s_client_go//kubernetes:go_default_library",
"@io_k8s_client_go//tools/cache:go_default_library",
],
)

go_test(
name = "go_default_test",
size = "small",
srcs = ["inject_test.go"],
srcs = [
"initializer_test.go",
"inject_test.go",
],
data = glob(["testdata/*.yaml*"]),
library = ":go_default_library",
deps = [
"//platform/kube:go_default_library",
"//proxy:go_default_library",
"//test/util:go_default_library",
"@com_github_ghodss_yaml//:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@io_istio_api//:go_default_library",
"@io_k8s_api//apps/v1beta1:go_default_library",
"@io_k8s_api//core/v1:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_client_go//kubernetes:go_default_library",
],
)
Loading