diff --git a/cluster/vagrant/config-default.sh b/cluster/vagrant/config-default.sh index f831bf32c74a7..0d92341951981 100755 --- a/cluster/vagrant/config-default.sh +++ b/cluster/vagrant/config-default.sh @@ -71,5 +71,5 @@ DNS_DOMAIN="kubernetes.local" DNS_REPLICAS=1 # Optional: Enable setting flags for kube-apiserver to turn on behavior in active-dev -RUNTIME_CONFIG="" -#RUNTIME_CONFIG="api/v1beta3" +#RUNTIME_CONFIG="" +RUNTIME_CONFIG="api/v1beta3" diff --git a/examples/openshift-origin/README.md b/examples/openshift-origin/README.md new file mode 100644 index 0000000000000..d13595e531127 --- /dev/null +++ b/examples/openshift-origin/README.md @@ -0,0 +1,110 @@ +## OpenShift Origin example + +This example shows how to run OpenShift Origin as a pod on an existing Kubernetes cluster. + +This example demonstrates usage of a pod with a secret volume mount. + +### Step 0: Prerequisites + +This example assumes that you have a basic understanding of Kubernetes and that you have forked the repository and [turned up a Kubernetes cluster](https://github.com/GoogleCloudPlatform/kubernetes#contents): + +This example has been tested against the **gce** and **vagrant** based KUBERNETES_PROVIDER. + +```shell +$ cd kubernetes +$ export KUBERNETES_PROVIDER=gce +$ hack/dev-build-and-up.sh +``` + +### Step 1: Generate resources + +The demonstration will require the following resources: + +1. A Kubernetes Secret that contains information needed to securely communicate to your Kubernetes master as an administrator +2. A Kubernetes Pod that contains information for how to run OpenShift Origin that consumes this Secret securely +3. A Kubernetes Service that exposes OpenShift Origin API via an external load balancer +4. A Kubernetes Service that exposes OpenShift Origin UI via an external load balancer + +To generate these resources, we will run a script that introspects your configured KUBERNETES_PROVIDER: + +```shell +$ examples/openshift-origin/resource-generator.sh +``` +A Kubernetes Secret was generated that contains the following data: + +1. kubeconfig: a valid kubeconfig file that is used by OpenShift Origin to communicate to the master +2. kube-ca: a certificate authority for the Kubernetes master +3. kube-auth-path: a Kubernetes authorization file +4. kube-cert: a Kubernetes certificate +5. kube-key: a Kubernetes key file + +As required by a Kubernetes secret, each piece of data is base64 encoded - with no line wraps. + +You can view the file by doing: + +```shell +$ cat examples/openshift-origin/secret.json +``` + +Caution: This file contains all of the required information to operate as a Kubernetes admin on your cluster, so only share this file with trusted parties. + +A Kubernetes Pod file was generated that can run OpenShift Origin on your cluster. + +The OpenShift Origin pod file has a volume mount that references the Kubernetes secret we created to know how to work with the underlying Kubernetes provider. + +You can view the file by doing: + +```shell +$ cat examples/openshift-origin/pod.json +``` + +Finally, a Kubernetes service was generated for the UI and the API and available via an external load balancer: + +``shell +$ cat examples/openshift-origin + +### Step 2: Create the secret in Kubernetes + +To provision the secret on Kubernetes: + +```shell +$ cluster/kubectl.sh create -f examples/openshift-origin/secret.json +``` + +You should see your secret resource was created by listing: +```shell +$ cluster/kubectl.sh get secrets +``` + +### Step 3: Provisioning OpenShift Origin + +To create the OpenShift Origin pod: + +```shell +$ cluster/kubectl.sh create -f examples/openshift-origin/pod.json +``` + +### Step 4: Provisioning OpenShift Origin Services + +To create the OpenShift Origin Services that expose the API and UI: + +```shell +$ cluster/kubectl.sh create -f examples/openshift-origin/ui-service.json +$ cluster/kubectl.sh create -f examples/openshift-origin/api-service.json +``` + +### Step 5: Open Firewall Ports + +If you are running on GCE, you need to open the following ports: + +```shell +$ gcloud compute instances list + +FIND THE MINION NAME PREFIX + +$ gcloud compute firewall-rules create openshift-origin-node-8444 --allow tcp:8444 --target-tags kubernetes-minion-prq8 +$ gcloud compute firewall-rules create openshift-origin-node-8443 --allow tcp:8443 --target-tags kubernetes-minion-prq8 +``` +### Step 4: Try out OpenShift Origin + +TODO add more detail here: \ No newline at end of file diff --git a/examples/openshift-origin/create-all.sh b/examples/openshift-origin/create-all.sh new file mode 100755 index 0000000000000..b5a0d3fd522ce --- /dev/null +++ b/examples/openshift-origin/create-all.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Copyright 2014 Google Inc. 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. + +# Generates secret, creates secret on kube, creates pod on kube + +set -o errexit +set -o nounset +set -o pipefail + +ORIGIN=$(dirname "${BASH_SOURCE}") +KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../.. + +## Generate resources +${ORIGIN}/resource-generator.sh + +## Create the secret +${KUBE_ROOT}/cluster/kubectl.sh create -f ${ORIGIN}/secret.json + +## Create the pod +${KUBE_ROOT}/cluster/kubectl.sh create -f ${ORIGIN}/pod.json + +## Create the services +${KUBE_ROOT}/cluster/kubectl.sh create -f ${ORIGIN}/api-service.json +${KUBE_ROOT}/cluster/kubectl.sh create -f ${ORIGIN}/ui-service.json \ No newline at end of file diff --git a/examples/openshift-origin/delete-all.sh b/examples/openshift-origin/delete-all.sh new file mode 100755 index 0000000000000..256b56147b6ce --- /dev/null +++ b/examples/openshift-origin/delete-all.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# Copyright 2014 Google Inc. 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. + +# Deletes pod, deletes secret + +set -o errexit +set -o nounset +set -o pipefail + +ORIGIN=$(dirname "${BASH_SOURCE}") +KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../.. + +## Delete the services +${KUBE_ROOT}/cluster/kubectl.sh delete services origin-api +${KUBE_ROOT}/cluster/kubectl.sh delete services origin-ui + +## Delete the pod +${KUBE_ROOT}/cluster/kubectl.sh delete pods openshift + +## Delete the secret +${KUBE_ROOT}/cluster/kubectl.sh delete secrets kubernetes-secret diff --git a/examples/openshift-origin/origin-kubeconfig.yaml b/examples/openshift-origin/origin-kubeconfig.yaml new file mode 100644 index 0000000000000..7780e0a5aa4dc --- /dev/null +++ b/examples/openshift-origin/origin-kubeconfig.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +clusters: +- cluster: + certificate-authority: /etc/secret-volume/kube-ca + server: https://146.148.35.28 + name: kubernetes +contexts: +- context: + cluster: kubernetes + user: kubernetes-admin + name: kubernetes +current-context: kubernetes +kind: Config +preferences: {} +users: +- name: kubernetes-admin + user: + auth-path: /etc/secret-volume/kube-auth-path diff --git a/examples/openshift-origin/resource-generator.sh b/examples/openshift-origin/resource-generator.sh new file mode 100755 index 0000000000000..e1b2b77338489 --- /dev/null +++ b/examples/openshift-origin/resource-generator.sh @@ -0,0 +1,198 @@ +#!/bin/bash + +# Copyright 2014 Google Inc. 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. + +# Generates pod and secret to deploy origin against configured Kubernetes provider + +set -o errexit +set -o nounset +set -o pipefail + +ORIGIN=$(dirname "${BASH_SOURCE}") +KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../.. +source "${KUBE_ROOT}/cluster/kubectl.sh" > /dev/null 2>&1 + +# Check all prerequisites are on the path +HAVE_JQ=$(which jq) +if [[ -z ${HAVE_JQ} ]]; then + echo "Please install jq" + exit 1 +fi + +HAVE_BASE64=$(which base64) +if [[ -z ${HAVE_BASE64} ]]; then + echo "Please install base64" + exit 1 +fi + +# Capture information about your kubernetes cluster +TEMPLATE="--template=\"{{ index . \"current-context\" }}\"" +CURRENT_CONTEXT=$( "${kubectl}" "${config[@]:+${config[@]}}" config view -o template "${TEMPLATE}" ) + +TEMPLATE="--template=\"{{ index . \"contexts\" ${CURRENT_CONTEXT} \"cluster\" }}\"" +CURRENT_CLUSTER=$( "${kubectl}" "${config[@]:+${config[@]}}" config view -o template "${TEMPLATE}" ) + +TEMPLATE="--template=\"{{ index . \"contexts\" ${CURRENT_CONTEXT} \"user\" }}\"" +CURRENT_USER=$( "${kubectl}" "${config[@]:+${config[@]}}" config view -o template "${TEMPLATE}" ) + +TEMPLATE="--template={{ index . \"clusters\" ${CURRENT_CLUSTER} \"certificate-authority\" }}" +CERTIFICATE_AUTHORITY=$( "${kubectl}" "${config[@]:+${config[@]}}" config view -o template "${TEMPLATE}" ) + +TEMPLATE="--template={{ index . \"clusters\" ${CURRENT_CLUSTER} \"server\" }}" +KUBE_MASTER=$( "${kubectl}" "${config[@]:+${config[@]}}" config view -o template "${TEMPLATE}" ) + +TEMPLATE="--template={{ index . \"users\" ${CURRENT_USER} \"auth-path\" }}" +AUTH_PATH=$( "${kubectl}" "${config[@]:+${config[@]}}" config view -o template "${TEMPLATE}" ) + +# Build an auth_path file to embed as a secret +AUTH_PATH_DATA=$(cat ${AUTH_PATH} ) +KUBE_USER=$( echo ${AUTH_PATH_DATA} | jq '.User' ) +KUBE_PASSWORD=$( echo ${AUTH_PATH_DATA} | jq '.Password' ) +KUBE_CERT_FILE=$( echo ${AUTH_PATH_DATA} | jq '.CertFile' ) +KUBE_KEY_FILE=$( echo ${AUTH_PATH_DATA} | jq '.KeyFile' ) + +cat <"${ORIGIN}/origin-auth-path" +{ + "User": ${KUBE_USER}, + "Password": ${KUBE_PASSWORD}, + "CAFile": "/etc/secret-volume/kube-ca", + "CertFile": "/etc/secret-volume/kube-cert", + "KeyFile": "/etc/secret-volume/kube-key" +} +EOF + +# Collect all the secrets and encode as base64 +ORIGIN_KUBECONFIG_DATA=$( cat ${ORIGIN}/origin-kubeconfig.yaml | base64 --wrap=0) +ORIGIN_CERTIFICATE_AUTHORITY_DATA=$(cat ${CERTIFICATE_AUTHORITY} | base64 --wrap=0) +ORIGIN_AUTH_PATH_DATA=$(cat ${ORIGIN}/origin-auth-path | base64 --wrap=0) +ORIGIN_CERT_FILE=$( cat ${KUBE_CERT_FILE//\"/} | base64 --wrap=0) +ORIGIN_KEY_FILE=$( cat ${KUBE_KEY_FILE//\"/} | base64 --wrap=0) + +cat <"${ORIGIN}/secret.json" +{ + "apiVersion": "v1beta2", + "kind": "Secret", + "id": "kubernetes-secret", + "data": { + "kubeconfig": "${ORIGIN_KUBECONFIG_DATA}", + "kube-ca": "${ORIGIN_CERTIFICATE_AUTHORITY_DATA}", + "kube-auth-path": "${ORIGIN_AUTH_PATH_DATA}", + "kube-cert": "${ORIGIN_CERT_FILE}", + "kube-key": "${ORIGIN_KEY_FILE}" + } +} +EOF + +echo "Generated Kubernetes Secret file: ${ORIGIN}/secret.json" + +# Generate an OpenShift Origin pod +# TODO: In future, move this to a replication controller when we are not running etcd in container + +cat <"${ORIGIN}/pod.json" +{ + "apiVersion": "v1beta1", + "id": "openshift", + "kind": "Pod", + "labels": {"name": "origin"}, + "desiredState": { + "manifest": { + "containers": [ + { + "command": [ + "start", + "master", + "--kubernetes=${KUBE_MASTER}", + "--kubeconfig=/etc/secret-volume/kubeconfig", + "--public-kubernetes=https://10.245.1.3:8443", + "--public-master=https://10.245.1.3:8443", + ], + "image": "openshift/origin:latest", + "imagePullPolicy": "PullIfNotPresent", + "name": "origin", + "ports": [ + { + "name": "https-api", + "containerPort": 8443, + "hostPort": 8443, + }, + { + "name": "https-ui", + "containerPort": 8444, + "hostPort": 8444, + } + ], + "volumeMounts": [ + { + "mountPath": "/etc/secret-volume", + "name": "secret-volume", + "readOnly": true + } + ] + } + ], + "restartPolicy": { + "never": {} + }, + "version": "v1beta2", + "volumes": [ + { + "name": "secret-volume", + "source": { + "secret": { + "target": { + "kind": "Secret", + "name": "kubernetes-secret", + "namespace": "default" + } + } + } + } + ] + } + } +} +EOF + +echo "Generated Kubernetes Pod file: ${ORIGIN}/pod.json" + +cat <"${ORIGIN}/api-service.json" +{ + "apiVersion": "v1beta1", + "kind": "Service", + "id": "origin-api", + "port": 8443, + "containerPort": "https-api", + "selector": { "name": "origin" }, +} +EOF + +echo "Generated Kubernetes Service file: ${ORIGIN}/api-service.json" + +cat <"${ORIGIN}/ui-service.json" +{ + "apiVersion": "v1beta1", + "kind": "Service", + "id": "origin-ui", + "port": 8444, + "containerPort": "https-ui", + "selector": { "name": "origin" }, +} +EOF + +echo "Generated Kubernetes Service file: ${ORIGIN}/ui-service.json" + + + +