diff --git a/sharing-clusters/README.md b/sharing-clusters/README.md new file mode 100644 index 00000000..1957225e --- /dev/null +++ b/sharing-clusters/README.md @@ -0,0 +1,220 @@ + + + + +WARNING +WARNING +WARNING +WARNING +WARNING + +

PLEASE NOTE: This document applies to the HEAD of the source tree

+ +If you are using a released version of Kubernetes, you should +refer to the docs that go with that version. + + +The latest 1.0.x release of this document can be found +[here](http://releases.k8s.io/release-1.0/examples/sharing-clusters/README.md). + +Documentation for other releases can be found at +[releases.k8s.io](http://releases.k8s.io). + +-- + + + + + +# Sharing Clusters + +This example demonstrates how to access one kubernetes cluster from another. It only works if both clusters are running on the same network, on a cloud provider that provides a private ip range per network (eg: GCE, GKE, AWS). + +## Setup + +Create a cluster in US (you don't need to do this if you already have a running kubernetes cluster) + +```shell +$ cluster/kube-up.sh +``` + +Before creating our second cluster, lets have a look at the kubectl config: + +```yaml +apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: REDACTED + server: https://104.197.84.16 + name: +... +current-context: +... +``` + +Now spin up the second cluster in Europe + +```shell +$ ./cluster/kube-up.sh +$ KUBE_GCE_ZONE=europe-west1-b KUBE_GCE_INSTANCE_PREFIX=eu ./cluster/kube-up.sh +``` + +Your kubectl config should contain both clusters: + +```yaml +apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: REDACTED + server: https://146.148.25.221 + name: +- cluster: + certificate-authority-data: REDACTED + server: https://104.197.84.16 + name: +... +current-context: kubernetesdev_eu +... +``` + +And kubectl get nodes should agree: + +``` +$ kubectl get nodes +NAME LABELS STATUS +eu-minion-0n61 kubernetes.io/hostname=eu-minion-0n61 Ready +eu-minion-79ua kubernetes.io/hostname=eu-minion-79ua Ready +eu-minion-7wz7 kubernetes.io/hostname=eu-minion-7wz7 Ready +eu-minion-loh2 kubernetes.io/hostname=eu-minion-loh2 Ready + +$ kubectl config use-context +$ kubectl get nodes +NAME LABELS STATUS +kubernetes-minion-5jtd kubernetes.io/hostname=kubernetes-minion-5jtd Ready +kubernetes-minion-lqfc kubernetes.io/hostname=kubernetes-minion-lqfc Ready +kubernetes-minion-sjra kubernetes.io/hostname=kubernetes-minion-sjra Ready +kubernetes-minion-wul8 kubernetes.io/hostname=kubernetes-minion-wul8 Ready +``` + +## Testing reachability + +For this test to work we'll need to create a service in europe: + +``` +$ kubectl config use-context +$ kubectl create -f /tmp/secret.json +$ kubectl create -f examples/https-nginx/nginx-app.yaml +$ kubectl exec -it my-nginx-luiln -- echo "Europe nginx" >> /usr/share/nginx/html/index.html +$ kubectl get ep +NAME ENDPOINTS +kubernetes 10.240.249.92:443 +nginxsvc 10.244.0.4:80,10.244.0.4:443 +``` + +Just to test reachability, we'll try hitting the Europe nginx from our initial US central cluster. Create a basic curl pod in the US cluster: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: curlpod +spec: + containers: + - image: radial/busyboxplus:curl + command: + - sleep + - "360000000" + imagePullPolicy: IfNotPresent + name: curlcontainer + restartPolicy: Always +``` + +And test that you can actually reach the test nginx service across continents + +``` +$ kubectl config use-context +$ kubectl -it exec curlpod -- /bin/sh +[ root@curlpod:/ ]$ curl http://10.244.0.4:80 +Europe nginx +``` + +## Granting access to the remote cluster + +We will grant the US cluster access to the Europe cluster. Basically we're going to setup a secret that allows kubectl to function in a pod running in the US cluster, just like it did on our local machine in the previous step. First create a secret with the contents of the current .kube/config: + +```shell +$ kubectl config use-context +$ go run ./make_secret.go --kubeconfig=$HOME/.kube/config > /tmp/secret.json +$ kubectl config use-context +$ kubectl create -f /tmp/secret.json +``` + +Create a kubectl pod that uses the secret, in the US cluster. + +```json +{ + "kind": "Pod", + "apiVersion": "v1", + "metadata": { + "name": "kubectl-tester" + }, + "spec": { + "volumes": [ + { + "name": "secret-volume", + "secret": { + "secretName": "kubeconfig" + } + } + ], + "containers": [ + { + "name": "kubectl", + "image": "bprashanth/kubectl:0.0", + "imagePullPolicy": "Always", + "env": [ + { + "name": "KUBECONFIG", + "value": "/.kube/config" + } + ], + "args": [ + "proxy", "-p", "8001" + ], + "volumeMounts": [ + { + "name": "secret-volume", + "mountPath": "/.kube" + } + ] + } + ] + } +} +``` + +And check that you can access the remote cluster + +```shell +$ kubectl config use-context +$ kubectl exec -it kubectl-tester bash + +kubectl-tester $ kubectl get nodes +NAME LABELS STATUS +eu-minion-0n61 kubernetes.io/hostname=eu-minion-0n61 Ready +eu-minion-79ua kubernetes.io/hostname=eu-minion-79ua Ready +eu-minion-7wz7 kubernetes.io/hostname=eu-minion-7wz7 Ready +eu-minion-loh2 kubernetes.io/hostname=eu-minion-loh2 Ready +``` + +For a more advanced example of sharing clusters, see the [service-loadbalancer](../../contrib/service-loadbalancer/README.md) + + + +[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/sharing-clusters/README.md?pixel)]() + diff --git a/sharing-clusters/make_secret.go b/sharing-clusters/make_secret.go new file mode 100644 index 00000000..6cf03c77 --- /dev/null +++ b/sharing-clusters/make_secret.go @@ -0,0 +1,63 @@ +/* +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. +*/ + +// A tiny script to help conver a given kubeconfig into a secret. +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "log" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/runtime" +) + +// TODO: +// Add a -o flag that writes to the specified destination file. +var ( + kubeconfig = flag.String("kubeconfig", "", "path to kubeconfig file.") + name = flag.String("name", "kubeconfig", "name to use in the metadata of the secret.") + ns = flag.String("ns", "default", "namespace of the secret.") +) + +func read(file string) []byte { + b, err := ioutil.ReadFile(file) + if err != nil { + log.Fatalf("Cannot read file %v, %v", file, err) + } + return b +} + +func main() { + flag.Parse() + if *kubeconfig == "" { + log.Fatalf("Need to specify --kubeconfig") + } + cfg := read(*kubeconfig) + secret := &api.Secret{ + ObjectMeta: api.ObjectMeta{ + Name: *name, + Namespace: *ns, + }, + Data: map[string][]byte{ + "config": cfg, + }, + } + fmt.Printf(runtime.EncodeOrDie(latest.Codec, secret)) +}