Add glide.yaml and vendor deps

This commit is contained in:
Dalton Hubble 2016-12-03 22:43:32 -08:00
parent db918f12ad
commit 5b3d5e81bd
18880 changed files with 5166045 additions and 1 deletions

View file

@ -0,0 +1,24 @@
# Copyright 2016 The Kubernetes 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.
FROM gliderlabs/alpine
MAINTAINER Mehdy Bohlool <mehdy@google.com>
RUN apk-install bash
ADD etcd-empty-dir-cleanup.sh etcd-empty-dir-cleanup.sh
ADD etcdctl etcdctl
ENV ETCDCTL /etcdctl
ENV SLEEP_SECOND 3600
RUN chmod +x etcd-empty-dir-cleanup.sh
CMD bash /etcd-empty-dir-cleanup.sh

View file

@ -0,0 +1,32 @@
# Copyright 2016 The Kubernetes 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.
.PHONY: build push
ETCD_VERSION = 2.2.1
IMAGE = gcr.io/google_containers/etcd-empty-dir-cleanup
TAG = 0.0.1
clean:
rm -rf etcdctl etcd-v$(ETCD_VERSION)-linux-amd64 etcd-v$(ETCD_VERSION)-linux-amd64.tar.gz
build: clean
curl -L -O https://github.com/coreos/etcd/releases/download/v$(ETCD_VERSION)/etcd-v$(ETCD_VERSION)-linux-amd64.tar.gz
tar xzvf etcd-v$(ETCD_VERSION)-linux-amd64.tar.gz
cp etcd-v$(ETCD_VERSION)-linux-amd64/etcdctl .
docker build -t $(IMAGE):$(TAG) .
rm -rf etcdctl etcd-v$(ETCD_VERSION)-linux-amd64 etcd-v$(ETCD_VERSION)-linux-amd64.tar.gz
push: build
gcloud docker -- push $(IMAGE):$(TAG)

View file

@ -0,0 +1,37 @@
#!/bin/bash
# Copyright 2016 The Kubernetes 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.
echo "Removing empty directories from etcd..."
cleanup_empty_dirs () {
if [[ $(${ETCDCTL} ls $1) ]]; then
for SUBDIR in $(${ETCDCTL} ls -p $1 | grep "/$")
do
cleanup_empty_dirs ${SUBDIR}
done
else
echo "Removing empty key $1 ..."
${ETCDCTL} rmdir $1
fi
}
while true
do
echo "Starting cleanup..."
cleanup_empty_dirs "/registry"
echo "Done with cleanup."
sleep ${SLEEP_SECOND}
done

View file

@ -0,0 +1,20 @@
# Copyright 2016 The Kubernetes 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.
FROM BASEIMAGE
MAINTAINER Wojciech Tyczynski <wojtekt@google.com>
EXPOSE 2379 2380 4001 7001
COPY etcd* etcdctl* /usr/local/bin/
COPY migrate-if-needed.sh attachlease rollback /usr/local/bin/

114
vendor/k8s.io/kubernetes/cluster/images/etcd/Makefile generated vendored Normal file
View file

@ -0,0 +1,114 @@
# Copyright 2016 The Kubernetes 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.
# Build the etcd image
#
# Usage:
# [TAGS=2.2.1 2.3.7 3.0.14] [REGISTRY=gcr.io/google_containers] [ARCH=amd64] [BASEIMAGE=busybox] make (build|push)
# The image contains different etcd versions to simplify
# upgrades. Thus be careful when removing any tag from here.
#
# NOTE: The etcd upgrade rules are that you can upgrade only 1 minor
# version at a time, and patch release don't matter.
#
# Except from etcd-$(tag) and etcdctl-$(tag) binaries, we also
# need etcd and etcdctl binaries for backward compatibility reasons.
# That binary will be set to the last tag from $(TAGS).
TAGS?=2.2.1 2.3.7 3.0.14
REGISTRY_TAG?=3.0.14
ARCH?=amd64
REGISTRY?=gcr.io/google_containers
GOLANG_VERSION?=1.6.3
GOARM=6
TEMP_DIR:=$(shell mktemp -d)
ifeq ($(ARCH),amd64)
BASEIMAGE?=busybox
endif
ifeq ($(ARCH),arm)
BASEIMAGE?=armel/busybox
endif
ifeq ($(ARCH),arm64)
BASEIMAGE?=aarch64/busybox
endif
ifeq ($(ARCH),ppc64le)
BASEIMAGE?=ppc64le/busybox
endif
build:
# Copy the content in this dir to the temp dir,
# without copying the subdirectories.
find ./ -maxdepth 1 -type f | xargs cp -t $(TEMP_DIR)
# Compile attachlease
docker run -it -v $(shell pwd)/../../../:/go/src/k8s.io/kubernetes -v $(TEMP_DIR):/build -e GOARCH=$(ARCH) golang:$(GOLANG_VERSION) \
/bin/bash -c "CGO_ENABLED=0 go build -o /build/attachlease k8s.io/kubernetes/cluster/images/etcd/attachlease"
# Compile rollback
docker run -it -v $(shell pwd)/../../../:/go/src/k8s.io/kubernetes -v $(TEMP_DIR):/build -e GOARCH=$(ARCH) golang:$(GOLANG_VERSION) \
/bin/bash -c "CGO_ENABLED=0 go build -o /build/rollback k8s.io/kubernetes/cluster/images/etcd/rollback"
ifeq ($(ARCH),amd64)
# Do not compile if we should make an image for amd64, use the official etcd binaries instead
# For each release create a tmp dir 'etcd_release_tmp_dir' and unpack the release tar there.
for tag in $(TAGS); do \
etcd_release_tmp_dir=$(shell mktemp -d); \
curl -sSL --retry 5 https://github.com/coreos/etcd/releases/download/v$$tag/etcd-v$$tag-linux-amd64.tar.gz | tar -xz -C $$etcd_release_tmp_dir --strip-components=1; \
cp $$etcd_release_tmp_dir/etcd $$etcd_release_tmp_dir/etcdctl $(TEMP_DIR)/; \
cp $(TEMP_DIR)/etcd $(TEMP_DIR)/etcd-$$tag; \
cp $(TEMP_DIR)/etcdctl $(TEMP_DIR)/etcdctl-$$tag; \
done
else
# Download etcd in a golang container and cross-compile it statically
# For each release create a tmp dir 'etcd_release_tmp_dir' and unpack the release tar there.
for tag in $(TAGS); do \
etcd_release_tmp_dir=$(shell mktemp -d); \
docker run -it -v $$etcd_release_tmp_dir:/etcdbin golang:$(GOLANG_VERSION) /bin/bash -c \
"git clone https://github.com/coreos/etcd /go/src/github.com/coreos/etcd \
&& cd /go/src/github.com/coreos/etcd \
&& git checkout v$$tag \
&& GOARM=$(GOARM) GOARCH=$(ARCH) ./build \
&& cp -f bin/$(ARCH)/etcd* bin/etcd* /etcdbin; echo 'done'"; \
cp $$etcd_release_tmp_dir/etcd $$etcd_release_tmp_dir/etcdctl $(TEMP_DIR)/; \
cp $(TEMP_DIR)/etcd $(TEMP_DIR)/etcd-$$tag; \
cp $(TEMP_DIR)/etcdctl $(TEMP_DIR)/etcdctl-$$tag; \
done
# Add this ENV variable in order to workaround an unsupported arch blocker
# The multiarch feature is in an limited and experimental state right now, and etcd should work fine on arm64
# On arm (which is 32-bit), it can't handle >1GB data in-memory, but it is very unlikely someone tinkering with their limited arm devices would reach such a high usage
# ppc64le is still quite untested, but compiles and is probably in the process of being validated by IBM.
cd $(TEMP_DIR) && echo "ENV ETCD_UNSUPPORTED_ARCH=$(ARCH)" >> Dockerfile
endif
# Replace BASEIMAGE with the real base image
cd $(TEMP_DIR) && sed -i.bak 's|BASEIMAGE|$(BASEIMAGE)|g' Dockerfile
# And build the image
docker build -t $(REGISTRY)/etcd-$(ARCH):$(REGISTRY_TAG) $(TEMP_DIR)
push: build
gcloud docker -- push $(REGISTRY)/etcd-$(ARCH):$(REGISTRY_TAG)
ifeq ($(ARCH),amd64)
# Backward compatibility. TODO: deprecate this image tag
docker tag $(REGISTRY)/etcd-$(ARCH):$(REGISTRY_TAG) $(REGISTRY)/etcd:$(REGISTRY_TAG)
gcloud docker -- push $(REGISTRY)/etcd:$(REGISTRY_TAG)
endif
all: build
.PHONY: build push

29
vendor/k8s.io/kubernetes/cluster/images/etcd/README.md generated vendored Normal file
View file

@ -0,0 +1,29 @@
### etcd
This is a small etcd image used in Kubernetes setups where `etcd` is deployed as a docker image.
For `amd64`, official `etcd` and `etcdctl` binaries are downloaded from Github to maintain official support.
For other architectures, `etcd` is cross-compiled from source. Arch-specific `busybox` images serve as base images.
#### How to release
```console
# Build for linux/amd64 (default)
$ make push ARCH=amd64
# ---> gcr.io/google_containers/etcd-amd64:TAG
# ---> gcr.io/google_containers/etcd:TAG
$ make push ARCH=arm
# ---> gcr.io/google_containers/etcd-arm:TAG
$ make push ARCH=arm64
# ---> gcr.io/google_containers/etcd-arm64:TAG
$ make push ARCH=ppc64le
# ---> gcr.io/google_containers/etcd-ppc64le:TAG
```
If you don't want to push the images, run `make` or `make build` instead
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/cluster/images/etcd/README.md?pixel)]()

View file

@ -0,0 +1,70 @@
/*
Copyright 2016 The Kubernetes 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 (
"flag"
"strings"
"time"
"github.com/coreos/etcd/clientv3"
"github.com/golang/glog"
"golang.org/x/net/context"
)
var (
etcdAddress = flag.String("etcd-address", "", "Etcd address")
ttlKeysPrefix = flag.String("ttl-keys-prefix", "", "Prefix for TTL keys")
leaseDuration = flag.Duration("lease-duration", time.Hour, "Lease duration (seconds granularity)")
)
func main() {
flag.Parse()
if *etcdAddress == "" {
glog.Fatalf("--etcd-address flag is required")
}
client, err := clientv3.New(clientv3.Config{Endpoints: []string{*etcdAddress}})
if err != nil {
glog.Fatalf("Error while creating etcd client: %v", err)
}
// Make sure that ttlKeysPrefix is ended with "/" so that we only get children "directories".
if !strings.HasSuffix(*ttlKeysPrefix, "/") {
*ttlKeysPrefix += "/"
}
ctx := context.Background()
objectsResp, err := client.KV.Get(ctx, *ttlKeysPrefix, clientv3.WithPrefix())
if err != nil {
glog.Fatalf("Error while getting objects to attach to the lease")
}
lease, err := client.Lease.Grant(ctx, int64(*leaseDuration/time.Second))
if err != nil {
glog.Fatalf("Error while creating lease: %v", err)
}
glog.Infof("Lease with TTL: %v created", lease.TTL)
glog.Infof("Attaching lease to %d entries", len(objectsResp.Kvs))
for _, kv := range objectsResp.Kvs {
_, err := client.KV.Put(ctx, string(kv.Key), string(kv.Value), clientv3.WithLease(lease.ID))
if err != nil {
glog.Errorf("Error while attaching lease to: %s", string(kv.Key))
}
}
}

View file

@ -0,0 +1,242 @@
#!/bin/sh
# Copyright 2016 The Kubernetes 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.
# NOTES
# This script performs etcd upgrade based on the following environmental
# variables:
# TARGET_STORAGE - API of etcd to be used (supported: 'etcd2', 'etcd3')
# TARGET_VERSION - etcd release to be used (supported: '2.2.1', '2.3.7', '3.0.14')
# DATA_DIRECTORY - directory with etcd data
#
# The current etcd version and storage format is detected based on the
# contents of "${DATA_DIRECTORY}/version.txt" file (if the file doesn't
# exist, we default it to "2.2.1/etcd2".
#
# The update workflow support the following upgrade steps:
# - 2.2.1/etcd2 -> 2.3.7/etcd2
# - 2.3.7/etcd2 -> 3.0.14/etcd2
# - 3.0.14/etcd2 -> 3.0.14/etcd3
#
# NOTE: The releases supported in this script has to match release binaries
# present in the etcd image (to make this script work correctly).
#
# Based on the current etcd version and storage format we detect what
# upgrade step from this should be done to get reach target configuration
set -o errexit
set -o nounset
if [ -z "${TARGET_STORAGE:-}" ]; then
echo "TARGET_STORAGE variable unset - skipping migration"
exit 0
fi
if [ -z "${TARGET_VERSION:-}" ]; then
echo "TARGET_VERSION variable unset - skipping migration"
exit 0
fi
if [ -z "${DATA_DIRECTORY:-}" ]; then
echo "DATA_DIRECTORY variable unset - skipping migration"
exit 0
fi
if [ "${TARGET_STORAGE}" != "etcd2" -a "${TARGET_STORAGE}" != "etcd3" ]; then
echo "Not supported version of storage: ${TARGET_STORAGE}"
exit 1
fi
# Correctly support upgrade and rollback to non-default version.
if [ "${DO_NOT_MOVE_BINARIES:-}" != "true" ]; then
cp "/usr/local/bin/etcd-${TARGET_VERSION}" "/usr/local/bin/etcd"
cp "/usr/local/bin/etcdctl-${TARGET_VERSION}" "/usr/local/bin/etcdctl"
fi
# NOTE: SUPPORTED_VERSION has to match release binaries present in the
# etcd image (to make this script work correctly).
# We cannot use array since sh doesn't support it.
SUPPORTED_VERSIONS_STRING="2.2.1 2.3.7 3.0.14"
SUPPORTED_VERSIONS=$(echo "${SUPPORTED_VERSIONS_STRING}" | tr " " "\n")
VERSION_FILE="version.txt"
CURRENT_STORAGE="etcd2"
CURRENT_VERSION="2.2.1"
if [ -e "${DATA_DIRECTORY}/${VERSION_FILE}" ]; then
VERSION_CONTENTS="$(cat ${DATA_DIRECTORY}/${VERSION_FILE})"
# Example usage: if contents of VERSION_FILE is 2.3.7/etcd2, then
# - CURRENT_VERSION would be '2.3.7'
# - CURRENT_STORAGE would be 'etcd2'
CURRENT_VERSION="$(echo $VERSION_CONTENTS | cut -d '/' -f 1)"
CURRENT_STORAGE="$(echo $VERSION_CONTENTS | cut -d '/' -f 2)"
fi
# If there is no data in DATA_DIRECTORY, this means that we are
# starting etcd from scratch. In that case, we don't need to do
# any migration.
if [ ! -d "${DATA_DIRECTORY}" ]; then
mkdir -p "${DATA_DIRECTORY}"
fi
if [ -z "$(ls -A ${DATA_DIRECTORY})" ]; then
echo "${DATA_DIRECTORY} is empty - skipping migration"
echo "${TARGET_VERSION}/${TARGET_STORAGE}" > "${DATA_DIRECTORY}/${VERSION_FILE}"
exit 0
fi
# Starts 'etcd' version ${START_VERSION} and writes to it:
# 'etcd_version' -> "${START_VERSION}"
# Successful write confirms that etcd is up and running.
# Sets ETCD_PID at the end.
# Returns 0 if etcd was successfully started, non-0 otherwise.
start_etcd() {
# Use random ports, so that apiserver cannot connect to etcd.
ETCD_PORT=18629
ETCD_PEER_PORT=2380
# Avoid collisions between etcd and event-etcd.
case "${DATA_DIRECTORY}" in
*event*)
ETCD_PORT=18631
ETCD_PEER_PORT=2381
;;
esac
local ETCD_CMD="${ETCD:-/usr/local/bin/etcd-${START_VERSION}}"
local ETCDCTL_CMD="${ETCDCTL:-/usr/local/bin/etcdctl-${START_VERSION}}"
local API_VERSION="$(echo ${START_STORAGE} | cut -c5-5)"
if [ "${API_VERSION}" = "2" ]; then
ETCDCTL_CMD="${ETCDCTL_CMD} --debug --endpoint=http://127.0.0.1:${ETCD_PORT} set"
else
ETCDCTL_CMD="${ETCDCTL_CMD} --endpoints=http://127.0.0.1:${ETCD_PORT} put"
fi
${ETCD_CMD} \
--name="etcd-$(hostname)" \
--debug \
--data-dir=${DATA_DIRECTORY} \
--listen-client-urls http://127.0.0.1:${ETCD_PORT} \
--advertise-client-urls http://127.0.0.1:${ETCD_PORT} \
--listen-peer-urls http://127.0.0.1:${ETCD_PEER_PORT} \
--initial-advertise-peer-urls http://127.0.0.1:${ETCD_PEER_PORT} &
ETCD_PID=$!
# Wait until we can write to etcd.
for i in $(seq 240); do
sleep 0.5
ETCDCTL_API="${API_VERSION}" ${ETCDCTL_CMD} 'etcd_version' ${START_VERSION}
if [ "$?" -eq "0" ]; then
echo "Etcd on port ${ETCD_PORT} is up."
return 0
fi
done
echo "Timeout while waiting for etcd on port ${ETCD_PORT}"
return 1
}
# Stops etcd with ${ETCD_PID} pid.
stop_etcd() {
kill "${ETCD_PID-}" >/dev/null 2>&1 || :
wait "${ETCD_PID-}" >/dev/null 2>&1 || :
}
ATTACHLEASE="${ATTACHLEASE:-/usr/local/bin/attachlease}"
ROLLBACK="${ROLLBACK:-/usr/local/bin/rollback}"
# If we are upgrading from 2.2.1 and this is the first try for upgrade,
# do the backup to allow restoring from it in case of failed upgrade.
BACKUP_DIR="${DATA_DIRECTORY}/migration-backup"
if [ "${CURRENT_VERSION}" = "2.2.1" -a ! -d "${BACKUP_DIR}" ]; then
echo "Backup etcd before starting migration"
mkdir ${BACKUP_DIR}
ETCDCTL_CMD="/usr/local/bin/etcdctl-2.2.1"
ETCDCTL_API=2 ${ETCDCTL_CMD} --debug backup --data-dir=${DATA_DIRECTORY} \
--backup-dir=${BACKUP_DIR}
echo "Backup done in ${BACKUP_DIR}"
fi
# Do the roll-forward migration if needed.
# The migration goes as following:
# 1. for all versions starting one after the current version of etcd
# we do "start, wait until healthy and stop etcd". This is the
# procedure that etcd documentation suggests for upgrading binaries.
# 2. For the first 3.0.x version that we encounter, if we are still in
# v2 API, we do upgrade to v3 API using the "etcdct migrate" and
# attachlease commands.
SKIP_STEP=true
for step in ${SUPPORTED_VERSIONS}; do
if [ "${step}" = "${CURRENT_VERSION}" ]; then
SKIP_STEP=false
elif [ "${SKIP_STEP}" != "true" ]; then
# Do the migration step, by just starting etcd in this version.
START_VERSION="${step}"
START_STORAGE="${CURRENT_STORAGE}"
if ! start_etcd; then
# Migration failed.
echo "Starting etcd ${step} failed"
exit 1
fi
# Kill etcd and wait until this is down.
stop_etcd
CURRENT_VERSION=${step}
echo "${CURRENT_VERSION}/${CURRENT_STORAGE}" > "${DATA_DIRECTORY}/${VERSION_FILE}"
fi
if [ "$(echo ${CURRENT_VERSION} | cut -c1-2)" = "3." -a "${CURRENT_STORAGE}" = "etcd2" -a "${TARGET_STORAGE}" = "etcd3" ]; then
# If it is the first 3.x release in the list and we are migrating
# also from 'etcd2' to 'etcd3', do the migration now.
echo "Performing etcd2 -> etcd3 migration"
START_VERSION="${step}"
START_STORAGE="etcd3"
ETCDCTL_CMD="${ETCDCTL:-/usr/local/bin/etcdctl-${START_VERSION}}"
ETCDCTL_API=3 ${ETCDCTL_CMD} migrate --data-dir=${DATA_DIRECTORY}
echo "Attaching leases to TTL entries"
# Now attach lease to all keys.
# To do it, we temporarily start etcd on a random port (so that
# apiserver actually cannot access it).
if ! start_etcd; then
echo "Starting etcd ${step} in v3 mode failed"
exit 1
fi
# Create a lease and attach all keys to it.
${ATTACHLEASE} \
--etcd-address http://127.0.0.1:${ETCD_PORT} \
--ttl-keys-prefix "${TTL_KEYS_DIRECTORY:-/registry/events}" \
--lease-duration 1h
# Kill etcd and wait until this is down.
stop_etcd
CURRENT_STORAGE="etcd3"
echo "${CURRENT_VERSION}/${CURRENT_STORAGE}" > "${DATA_DIRECTORY}/${VERSION_FILE}"
fi
if [ "${CURRENT_VERSION}" = "${TARGET_VERSION}" -a "${CURRENT_STORAGE}" = "${TARGET_STORAGE}" ]; then
break
fi
done
# Do the rollback of needed.
# NOTE: Rollback is only supported from "3.0.x" version in 'etcd3' mode to
# "2.3.7" version in 'etcd2' mode.
if [ "${CURRENT_STORAGE}" = "etcd3" -a "${TARGET_STORAGE}" = "etcd2" ]; then
if [ "$(echo ${CURRENT_VERSION} | cut -c1-4)" != "3.0." -o "${TARGET_VERSION}" != "2.3.7" ]; then
echo "etcd3 -> etcd2 downgrade is supported only between 3.0.x and 2.3.7"
return 0
fi
echo "Backup and remove all existing v2 data"
ROLLBACK_BACKUP_DIR="${DATA_DIRECTORY}.bak"
rm -rf "${ROLLBACK_BACKUP_DIR}"
mkdir -p "${ROLLBACK_BACKUP_DIR}"
cp -r "${DATA_DIRECTORY}" "${ROLLBACK_BACKUP_DIR}"
echo "Performing etcd3 -> etcd2 rollback"
${ROLLBACK} --data-dir "${DATA_DIRECTORY}"
if [ "$?" -ne "0" ]; then
echo "Rollback to etcd2 failed"
exit 1
fi
CURRENT_STORAGE="etcd2"
CURRENT_VERSION="2.3.7"
echo "${CURRENT_VERSION}/${CURRENT_STORAGE}" > "${DATA_DIRECTORY}/${VERSION_FILE}"
fi

View file

@ -0,0 +1,45 @@
# Rollback workflow
Build it in this directory.
Make sure you have etcd dependency ready. Last time we use etcd v3.0.7.
```
$ go build .
```
Run it:
```
$ ./rollback2 --data-dir $ETCD_DATA_DIR --ttl 1h
```
This will rollback KV pairs from v3 into v2.
If a key was attached to a lease before, it will be created with given TTL (default to 1h).
On success, it will print at the end:
```
Finished successfully
```
Repeat this on all etcd members.
You can do simple check on keys (if any exists):
```
etcdctl ls /
```
Important Note
------
This tool isn't recommended to use if any problem comes up in etcd3 backend.
Please report bugs and we will fix it soon.
If it's still preferred to run this tool, please backup all your data beforehand.
This tool will also back up datadir to same path with ".rollback.backup" suffix.
Caveats:
- The tool doesn't preserve versions of keys.
- If any v2 data exists before rollback, they will be wiped out.
- v3 data only exists in the backup after successful rollback.
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/cluster/images/etcd/rollback/README.md?pixel)]()

View file

@ -0,0 +1,331 @@
/*
Copyright 2016 The Kubernetes 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 (
"encoding/json"
"flag"
"fmt"
"os"
"path"
"strconv"
"strings"
"time"
"github.com/coreos/etcd/etcdserver"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/etcdserver/membership"
"github.com/coreos/etcd/mvcc/backend"
"github.com/coreos/etcd/mvcc/mvccpb"
"github.com/coreos/etcd/pkg/pbutil"
"github.com/coreos/etcd/pkg/types"
"github.com/coreos/etcd/raft/raftpb"
"github.com/coreos/etcd/snap"
"github.com/coreos/etcd/store"
"github.com/coreos/etcd/wal"
"github.com/coreos/etcd/wal/walpb"
"github.com/coreos/go-semver/semver"
"github.com/golang/glog"
)
const rollbackVersion = "2.3.7"
var (
migrateDatadir = flag.String("data-dir", "", "Path to the data directory")
ttl = flag.Duration("ttl", time.Hour, "TTL of event keys (default 1 hour)")
)
func main() {
flag.Parse()
if len(*migrateDatadir) == 0 {
glog.Fatal("need to set '--data-dir'")
}
dbpath := path.Join(*migrateDatadir, "member", "snap", "db")
// etcd3 store backend. We will use it to parse v3 data files and extract information.
be := backend.NewDefaultBackend(dbpath)
tx := be.BatchTx()
// etcd2 store backend. We will use v3 data to update this and then save snapshot to disk.
st := store.New(etcdserver.StoreClusterPrefix, etcdserver.StoreKeysPrefix)
expireTime := time.Now().Add(*ttl)
tx.Lock()
err := tx.UnsafeForEach([]byte("key"), func(k, v []byte) error {
kv := &mvccpb.KeyValue{}
kv.Unmarshal(v)
// This is compact key.
if !strings.HasPrefix(string(kv.Key), "/") {
return nil
}
ttlOpt := store.TTLOptionSet{}
if kv.Lease != 0 {
ttlOpt = store.TTLOptionSet{ExpireTime: expireTime}
}
if !isTombstone(k) {
sk := path.Join(strings.Trim(etcdserver.StoreKeysPrefix, "/"), string(kv.Key))
_, err := st.Set(sk, false, string(kv.Value), ttlOpt)
if err != nil {
return err
}
} else {
st.Delete(string(kv.Key), false, false)
}
return nil
})
if err != nil {
glog.Fatal(err)
}
tx.Unlock()
if err := traverseAndDeleteEmptyDir(st, "/"); err != nil {
glog.Fatal(err)
}
// rebuild cluster state.
metadata, hardstate, oldSt, err := rebuild(*migrateDatadir)
if err != nil {
glog.Fatal(err)
}
// In the following, it's low level logic that saves metadata and data into v2 snapshot.
backupPath := *migrateDatadir + ".rollback.backup"
if err := os.Rename(*migrateDatadir, backupPath); err != nil {
glog.Fatal(err)
}
if err := os.MkdirAll(path.Join(*migrateDatadir, "member", "snap"), 0700); err != nil {
glog.Fatal(err)
}
walDir := path.Join(*migrateDatadir, "member", "wal")
w, err := wal.Create(walDir, metadata)
if err != nil {
glog.Fatal(err)
}
err = w.SaveSnapshot(walpb.Snapshot{Index: hardstate.Commit, Term: hardstate.Term})
if err != nil {
glog.Fatal(err)
}
w.Close()
event, err := oldSt.Get(etcdserver.StoreClusterPrefix, true, false)
if err != nil {
glog.Fatal(err)
}
// nodes (members info) for ConfState
nodes := []uint64{}
traverseMetadata(event.Node, func(n *store.NodeExtern) {
if n.Key != etcdserver.StoreClusterPrefix {
// update store metadata
v := ""
if !n.Dir {
v = *n.Value
}
if n.Key == path.Join(etcdserver.StoreClusterPrefix, "version") {
v = rollbackVersion
}
if _, err := st.Set(n.Key, n.Dir, v, store.TTLOptionSet{}); err != nil {
glog.Fatal(err)
}
// update nodes
fields := strings.Split(n.Key, "/")
if len(fields) == 4 && fields[2] == "members" {
nodeID, err := strconv.ParseUint(fields[3], 16, 64)
if err != nil {
glog.Fatalf("failed to parse member ID (%s): %v", fields[3], err)
}
nodes = append(nodes, nodeID)
}
}
})
data, err := st.Save()
if err != nil {
glog.Fatal(err)
}
raftSnap := raftpb.Snapshot{
Data: data,
Metadata: raftpb.SnapshotMetadata{
Index: hardstate.Commit,
Term: hardstate.Term,
ConfState: raftpb.ConfState{
Nodes: nodes,
},
},
}
snapshotter := snap.New(path.Join(*migrateDatadir, "member", "snap"))
if err := snapshotter.SaveSnap(raftSnap); err != nil {
glog.Fatal(err)
}
fmt.Println("Finished successfully")
}
func traverseMetadata(head *store.NodeExtern, handleFunc func(*store.NodeExtern)) {
q := []*store.NodeExtern{head}
for len(q) > 0 {
n := q[0]
q = q[1:]
handleFunc(n)
for _, next := range n.Nodes {
q = append(q, next)
}
}
}
const (
revBytesLen = 8 + 1 + 8
markedRevBytesLen = revBytesLen + 1
markBytePosition = markedRevBytesLen - 1
markTombstone byte = 't'
)
func isTombstone(b []byte) bool {
return len(b) == markedRevBytesLen && b[markBytePosition] == markTombstone
}
func traverseAndDeleteEmptyDir(st store.Store, dir string) error {
e, err := st.Get(dir, true, false)
if err != nil {
return err
}
if len(e.Node.Nodes) == 0 {
st.Delete(dir, true, true)
return nil
}
for _, node := range e.Node.Nodes {
if !node.Dir {
glog.V(2).Infof("key: %s", node.Key[len(etcdserver.StoreKeysPrefix):])
} else {
err := traverseAndDeleteEmptyDir(st, node.Key)
if err != nil {
return err
}
}
}
return nil
}
func rebuild(datadir string) ([]byte, *raftpb.HardState, store.Store, error) {
waldir := path.Join(datadir, "member", "wal")
snapdir := path.Join(datadir, "member", "snap")
ss := snap.New(snapdir)
snapshot, err := ss.Load()
if err != nil && err != snap.ErrNoSnapshot {
return nil, nil, nil, err
}
var walsnap walpb.Snapshot
if snapshot != nil {
walsnap.Index, walsnap.Term = snapshot.Metadata.Index, snapshot.Metadata.Term
}
w, err := wal.OpenForRead(waldir, walsnap)
if err != nil {
return nil, nil, nil, err
}
defer w.Close()
meta, hardstate, ents, err := w.ReadAll()
if err != nil {
return nil, nil, nil, err
}
st := store.New(etcdserver.StoreClusterPrefix, etcdserver.StoreKeysPrefix)
if snapshot != nil {
err := st.Recovery(snapshot.Data)
if err != nil {
return nil, nil, nil, err
}
}
cluster := membership.NewCluster("")
cluster.SetStore(st)
cluster.Recover(func(*semver.Version) {})
applier := etcdserver.NewApplierV2(st, cluster)
for _, ent := range ents {
if ent.Type == raftpb.EntryConfChange {
var cc raftpb.ConfChange
pbutil.MustUnmarshal(&cc, ent.Data)
switch cc.Type {
case raftpb.ConfChangeAddNode:
m := new(membership.Member)
if err := json.Unmarshal(cc.Context, m); err != nil {
return nil, nil, nil, err
}
cluster.AddMember(m)
case raftpb.ConfChangeRemoveNode:
id := types.ID(cc.NodeID)
cluster.RemoveMember(id)
case raftpb.ConfChangeUpdateNode:
m := new(membership.Member)
if err := json.Unmarshal(cc.Context, m); err != nil {
return nil, nil, nil, err
}
cluster.UpdateRaftAttributes(m.ID, m.RaftAttributes)
}
continue
}
var raftReq pb.InternalRaftRequest
if !pbutil.MaybeUnmarshal(&raftReq, ent.Data) { // backward compatible
var r pb.Request
pbutil.MustUnmarshal(&r, ent.Data)
applyRequest(&r, applier)
} else {
if raftReq.V2 != nil {
req := raftReq.V2
applyRequest(req, applier)
}
}
}
return meta, &hardstate, st, nil
}
func toTTLOptions(r *pb.Request) store.TTLOptionSet {
refresh, _ := pbutil.GetBool(r.Refresh)
ttlOptions := store.TTLOptionSet{Refresh: refresh}
if r.Expiration != 0 {
ttlOptions.ExpireTime = time.Unix(0, r.Expiration)
}
return ttlOptions
}
func applyRequest(r *pb.Request, applyV2 etcdserver.ApplierV2) {
toTTLOptions(r)
switch r.Method {
case "PUT":
applyV2.Put(r)
case "DELETE":
applyV2.Delete(r)
case "POST", "QGET", "SYNC":
return
default:
glog.Fatal("unknown command")
}
}

View file

@ -0,0 +1,82 @@
# Copyright 2016 The Kubernetes 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.
FROM BASEIMAGE
# If we're building for another architecture than amd64, the CROSS_BUILD_ placeholder is removed so e.g. CROSS_BUILD_COPY turns into COPY
# If we're building normally, for amd64, CROSS_BUILD lines are removed
CROSS_BUILD_COPY qemu-ARCH-static /usr/bin/
RUN DEBIAN_FRONTEND=noninteractive apt-get update -y \
&& DEBIAN_FRONTEND=noninteractive apt-get -yy -q install \
iptables \
ebtables \
ethtool \
ca-certificates \
conntrack \
util-linux \
socat \
git \
nfs-common \
glusterfs-client \
cifs-utils \
&& DEBIAN_FRONTEND=noninteractive apt-get upgrade -y \
&& DEBIAN_FRONTEND=noninteractive apt-get autoremove -y \
&& DEBIAN_FRONTEND=noninteractive apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # CACHEBUST
RUN cp /usr/bin/nsenter /nsenter
# Manifests for the docker guide
COPY static-pods/master.json \
static-pods/etcd.json \
static-pods/addon-manager-singlenode.json \
static-pods/kube-proxy.json \
/etc/kubernetes/manifests/
# Manifests for the docker-multinode guide
COPY static-pods/master-multi.json \
static-pods/addon-manager-multinode.json \
/etc/kubernetes/manifests-multi/
# Copy over all addons
COPY addons /etc/kubernetes/addons
# Copy other required scripts for the setup
COPY setup-files.sh make-ca-cert.sh copy-addons.sh /
# easy-rsa package required by make-ca-cert
ADD https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz /root/kube/
# Copy the the cni-bin folder into /opt/cni/bin
COPY cni-bin/bin /opt/cni/bin
# Copy overlay configuration to default directory
COPY cni-conf /etc/cni/net.d
# Create symlinks for each hyperkube server
# TODO: replace manual symlink creation with --make-symlink command once
# cross-building with qemu supports go binaries. See #28702
# RUN /hyperkube --make-symlinks
RUN ln -s /hyperkube /apiserver \
&& ln -s /hyperkube /controller-manager \
&& ln -s /hyperkube /federation-apiserver \
&& ln -s /hyperkube /federation-controller-manager \
&& ln -s /hyperkube /kubectl \
&& ln -s /hyperkube /kubelet \
&& ln -s /hyperkube /proxy \
&& ln -s /hyperkube /scheduler
# Copy the hyperkube binary
COPY hyperkube /hyperkube

View file

@ -0,0 +1,116 @@
# Copyright 2016 The Kubernetes 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.
# Build the hyperkube image.
#
# Usage:
# [ARCH=amd64] [REGISTRY="gcr.io/google_containers"] make (build|push) VERSION={some_released_version_of_kubernetes}
REGISTRY?=gcr.io/google_containers
ARCH?=amd64
TEMP_DIR:=$(shell mktemp -d)
CNI_RELEASE=07a8a28637e97b22eb8dfe710eeae1344f69d16e
UNAME_S:=$(shell uname -s)
ifeq ($(UNAME_S),Darwin)
SED_CMD?=sed -i ""
endif
ifeq ($(UNAME_S),Linux)
SED_CMD?=sed -i
endif
ifeq ($(ARCH),amd64)
BASEIMAGE?=debian:jessie
endif
ifeq ($(ARCH),arm)
BASEIMAGE?=armel/debian:jessie
QEMUARCH=arm
endif
ifeq ($(ARCH),arm64)
BASEIMAGE?=aarch64/debian:jessie
QEMUARCH=aarch64
endif
ifeq ($(ARCH),ppc64le)
BASEIMAGE?=ppc64le/debian:jessie
QEMUARCH=ppc64le
endif
all: build
build:
ifndef VERSION
$(error VERSION is undefined)
endif
cp -r ./* ${TEMP_DIR}
mkdir -p ${TEMP_DIR}/cni-bin ${TEMP_DIR}/addons ${TEMP_DIR}/addons/singlenode ${TEMP_DIR}/addons/multinode
cp ../../saltbase/salt/generate-cert/make-ca-cert.sh ${TEMP_DIR}
# Singlenode addons
cp ../../addons/dns/skydns-rc.yaml.base ${TEMP_DIR}/addons/singlenode/skydns-rc.yaml
cp ../../addons/dns/skydns-svc.yaml.base ${TEMP_DIR}/addons/singlenode/skydns-svc.yaml
cp ../../addons/dashboard/dashboard-controller.yaml ${TEMP_DIR}/addons/singlenode/
cp ../../addons/dashboard/dashboard-service.yaml ${TEMP_DIR}/addons/singlenode/
# Multinode addons; all singlenode addons plus kube-proxy (and soon flannel)
cp ${TEMP_DIR}/addons/singlenode/*.yaml ${TEMP_DIR}/addons/multinode/
cp kube-proxy-ds.yaml ${TEMP_DIR}/addons/multinode/kube-proxy.yaml
cp ../../../_output/dockerized/bin/linux/${ARCH}/hyperkube ${TEMP_DIR}
cd ${TEMP_DIR} && sed -i.back "s|VERSION|${VERSION}|g" addons/singlenode/*.yaml addons/multinode/*.yaml static-pods/*.json
cd ${TEMP_DIR} && sed -i.back "s|REGISTRY|${REGISTRY}|g" addons/singlenode/*.yaml addons/multinode/*.yaml static-pods/*.json
cd ${TEMP_DIR} && sed -i.back "s|ARCH|${ARCH}|g" addons/singlenode/*.yaml addons/multinode/*.yaml static-pods/*.json
cd ${TEMP_DIR} && sed -i.back "s|ARCH|${QEMUARCH}|g" Dockerfile
cd ${TEMP_DIR} && sed -i.back "s|BASEIMAGE|${BASEIMAGE}|g" Dockerfile
cd ${TEMP_DIR} && sed -i.back "s|CACHEBUST|$(shell uuidgen)|g" Dockerfile
cd ${TEMP_DIR} && sed -i.back "s|-amd64|-${ARCH}|g" addons/singlenode/*.yaml addons/multinode/*.yaml
cd ${TEMP_DIR} && sed -i.back "s|__PILLAR__DNS__SERVER__|10.0.0.10|g" addons/singlenode/skydns*.yaml addons/multinode/skydns*.yaml
cd ${TEMP_DIR} && sed -i.back "s|__PILLAR__DNS__DOMAIN__|cluster.local|g;s|__PILLAR__FEDERATIONS__DOMAIN__MAP__||g;" addons/singlenode/skydns*.yaml addons/multinode/skydns*.yaml
cd ${TEMP_DIR} && rm -f addons/singlenode/*.back addons/multinode/*.back static-pods/*.back
# Make scripts executable before they are copied into the Docker image. If we make them executable later, in another layer
# they'll take up twice the space because the new executable binary differs from the old one, but everything is cached in layers.
cd ${TEMP_DIR} && chmod a+rx \
hyperkube \
setup-files.sh \
make-ca-cert.sh \
copy-addons.sh
ifeq ($(ARCH),amd64)
# When building "normally" for amd64, remove the whole line, it has no part in the amd64 image
cd ${TEMP_DIR} && ${SED_CMD} "/CROSS_BUILD_/d" Dockerfile
else
cd ${TEMP_DIR} && ${SED_CMD} "s/CROSS_BUILD_//g" Dockerfile
# When cross-building, only the placeholder "CROSS_BUILD_" should be removed
# Register /usr/bin/qemu-ARCH-static as the handler for ARM binaries in the kernel
docker run --rm --privileged multiarch/qemu-user-static:register --reset
curl -sSL --retry 5 https://github.com/multiarch/qemu-user-static/releases/download/v2.5.0/x86_64_qemu-${QEMUARCH}-static.tar.xz | tar -xJ -C ${TEMP_DIR}
endif
# Download CNI
curl -sSL --retry 5 https://storage.googleapis.com/kubernetes-release/network-plugins/cni-${ARCH}-${CNI_RELEASE}.tar.gz | tar -xz -C ${TEMP_DIR}/cni-bin
docker build -t ${REGISTRY}/hyperkube-${ARCH}:${VERSION} ${TEMP_DIR}
rm -rf "${TEMP_DIR}"
push: build
gcloud docker -- push ${REGISTRY}/hyperkube-${ARCH}:${VERSION}
ifeq ($(ARCH),amd64)
docker rmi ${REGISTRY}/hyperkube:${VERSION} || true
docker tag ${REGISTRY}/hyperkube-${ARCH}:${VERSION} ${REGISTRY}/hyperkube:${VERSION}
gcloud docker -- push ${REGISTRY}/hyperkube:${VERSION}
endif
.PHONY: all

View file

@ -0,0 +1,33 @@
### hyperkube
`hyperkube` is an all-in-one binary for the Kubernetes server components
Also, it's very easy to run this `hyperkube` setup dockerized.
See https://github.com/kubernetes/kubernetes/blob/master/docs/devel/local-cluster/docker.md for up-to-date commands.
`hyperkube` is built for multiple architectures and _pushed automatically on every release._
#### How to release by hand
```console
# First, build the binaries
$ build-tools/run.sh make cross
# Build for linux/amd64 (default)
$ make push VERSION={target_version} ARCH=amd64
# ---> gcr.io/google_containers/hyperkube-amd64:VERSION
# ---> gcr.io/google_containers/hyperkube:VERSION (image with backwards-compatible naming)
$ make push VERSION={target_version} ARCH=arm
# ---> gcr.io/google_containers/hyperkube-arm:VERSION
$ make push VERSION={target_version} ARCH=arm64
# ---> gcr.io/google_containers/hyperkube-arm64:VERSION
$ make push VERSION={target_version} ARCH=ppc64le
# ---> gcr.io/google_containers/hyperkube-ppc64le:VERSION
```
If you don't want to push the images, run `make` or `make build` instead
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/cluster/images/hyperkube/README.md?pixel)]()

View file

@ -0,0 +1,10 @@
{
"name": "containernet",
"type": "flannel",
"delegate": {
"bridge": "cni0",
"mtu": 1450,
"isDefaultGateway": true,
"forceAddress": true
}
}

View file

@ -0,0 +1,3 @@
{
"type": "loopback"
}

View file

@ -0,0 +1,34 @@
#!/bin/bash
# Copyright 2016 The Kubernetes 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.
# Now we're running in the sidecar container
# /etc/kubernetes/addons holds the data in the hyperkube container
# /srv/kubernetes is an emptyDir that maps to /etc/kubernetes in the addon-manager container
# This way we're using the latest manifests from hyperkube without updating
# kube-addon-manager which is used for other deployments too
# Inside /etc/kubernetes/addons, there are two directories: singlenode and multinode
# If "singlenode" is passed to this script; those manifests are copied to the addon-manager and vice versa with "multinode"
SUBDIRECTORY=$1
# While there is no data copied over to the emptyDir, try to copy it.
while [[ -z $(ls /srv/kubernetes/addons) ]]; do
cp -r /etc/kubernetes/addons/${SUBDIRECTORY}/* /srv/kubernetes/addons/
done
# Then sleep forever
while true; do
sleep 3600;
done

View file

@ -0,0 +1,51 @@
# Copyright 2016 The Kubernetes 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.
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: k8s-proxy-v1
namespace: kube-system
labels:
k8s-app: k8s-proxy
version: v1
kubernetes.io/cluster-service: "true"
spec:
template:
metadata:
labels:
k8s-app: k8s-proxy
version: v1
kubernetes.io/cluster-service: "true"
spec:
hostNetwork: true
containers:
- name: kube-proxy
image: REGISTRY/hyperkube-ARCH:VERSION
command:
- /hyperkube
- proxy
- --kubeconfig=/var/lib/kubelet/kubeconfig/kubeconfig.yaml
- --v=2
- --resource-container=""
securityContext:
privileged: true
volumeMounts:
- name: kubeconfig
mountPath: /var/lib/kubelet/kubeconfig
readOnly: true
volumes:
- name: kubeconfig
hostPath:
path: /var/lib/kubelet/kubeconfig

View file

@ -0,0 +1,75 @@
#!/bin/bash
# Copyright 2015 The Kubernetes 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.
# This script is intended to set up the files necessary to run a master.
# It currently creates:
# * The basic auth file for access to the kubernetes api server
# * Service tokens for accessing the kubernetes api server
# * The CA cert and keys for HTTPS access to the kubernetes api server
set -o errexit
set -o nounset
set -o pipefail
create_token() {
echo $(cat /dev/urandom | base64 | tr -d "=+/" | dd bs=32 count=1 2> /dev/null)
}
# Additional address of the API server to be added to the
# list of Subject Alternative Names of the server TLS certificate
# Should contain internal IP, i.e. IP:10.0.0.1 for 10.0.0.0/24 cluster IP range
EXTRA_SANS=$1
DATA_DIR=/srv/kubernetes
# Files in /data are persistent across reboots, so we don't want to re-create the files if they already
# exist, because the state is persistent in etcd too, and we don't want a conflict between "old" data in
# etcd and "new" data that this script would create for apiserver. Therefore, if the file exist, skip it.
if [[ ! -f ${DATA_DIR}/ca.crt ]]; then
# Create HTTPS certificates
groupadd -f -r kube-cert
# hostname -I gets the ip of the node
/make-ca-cert.sh $(hostname -I | awk '{print $1}') ${EXTRA_SANS}
echo "Certificates created $(date)"
else
echo "Certificates already found, not recreating."
fi
if [[ ! -f ${DATA_DIR}/basic_auth.csv ]]; then
# Create basic token authorization
echo "admin,admin,admin" > ${DATA_DIR}/basic_auth.csv
echo "basic_auth.csv created $(date)"
else
echo "basic_auth.csv already found, not recreating."
fi
if [[ ! -f ${DATA_DIR}/known_tokens.csv ]]; then
# Create known tokens for service accounts
echo "$(create_token),admin,admin" >> ${DATA_DIR}/known_tokens.csv
echo "$(create_token),kubelet,kubelet" >> ${DATA_DIR}/known_tokens.csv
echo "$(create_token),kube_proxy,kube_proxy" >> ${DATA_DIR}/known_tokens.csv
echo "known_tokens.csv created $(date)"
else
echo "known_tokens.csv already found, not recreating."
fi
while true; do
sleep 3600
done

View file

@ -0,0 +1,52 @@
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "kube-addon-manager",
"namespace": "kube-system",
"version": "v1"
},
"spec": {
"hostNetwork": true,
"containers": [
{
"name": "kube-addon-manager",
"image": "REGISTRY/kube-addon-manager-ARCH:v6.1",
"resources": {
"requests": {
"cpu": "5m",
"memory": "50Mi"
}
},
"volumeMounts": [
{
"name": "addons",
"mountPath": "/etc/kubernetes/addons",
"readOnly": true
}
]
},
{
"name": "kube-addon-manager-data",
"image": "REGISTRY/hyperkube-ARCH:VERSION",
"command": [
"/copy-addons.sh",
"multinode"
],
"volumeMounts": [
{
"name": "addons",
"mountPath": "/srv/kubernetes/addons",
"readOnly": false
}
]
}
],
"volumes":[
{
"name": "addons",
"emptyDir": {}
}
]
}
}

View file

@ -0,0 +1,52 @@
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "kube-addon-manager",
"namespace": "kube-system",
"version": "v1"
},
"spec": {
"hostNetwork": true,
"containers": [
{
"name": "kube-addon-manager",
"image": "REGISTRY/kube-addon-manager-ARCH:v6.1",
"resources": {
"requests": {
"cpu": "5m",
"memory": "50Mi"
}
},
"volumeMounts": [
{
"name": "addons",
"mountPath": "/etc/kubernetes/addons",
"readOnly": true
}
]
},
{
"name": "kube-addon-manager-data",
"image": "REGISTRY/hyperkube-ARCH:VERSION",
"command": [
"/copy-addons.sh",
"singlenode"
],
"volumeMounts": [
{
"name": "addons",
"mountPath": "/srv/kubernetes/addons",
"readOnly": false
}
]
}
],
"volumes":[
{
"name": "addons",
"emptyDir": {}
}
]
}
}

View file

@ -0,0 +1,36 @@
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "k8s-etcd",
"namespace": "kube-system"
},
"spec": {
"hostNetwork": true,
"containers": [
{
"name": "etcd",
"image": "gcr.io/google_containers/etcd-ARCH:2.2.5",
"command": [
"/usr/local/bin/etcd",
"--listen-client-urls=http://127.0.0.1:2379,http://127.0.0.1:4001",
"--advertise-client-urls=http://127.0.0.1:2379,http://127.0.0.1:4001",
"--data-dir=/var/etcd/data"
],
"volumeMounts": [
{
"name": "varetcd",
"mountPath": "/var/etcd",
"readOnly": false
}
]
}
],
"volumes":[
{
"name": "varetcd",
"emptyDir": {}
}
]
}
}

View file

@ -0,0 +1,27 @@
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "k8s-proxy",
"namespace": "kube-system"
},
"spec": {
"hostNetwork": true,
"containers": [
{
"name": "kube-proxy",
"image": "REGISTRY/hyperkube-ARCH:VERSION",
"command": [
"/hyperkube",
"proxy",
"--master=http://127.0.0.1:8080",
"--v=2",
"--resource-container=\"\""
],
"securityContext": {
"privileged": true
}
}
]
}
}

View file

@ -0,0 +1,91 @@
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "k8s-master",
"namespace": "kube-system"
},
"spec":{
"hostNetwork": true,
"containers":[
{
"name": "controller-manager",
"image": "REGISTRY/hyperkube-ARCH:VERSION",
"command": [
"/hyperkube",
"controller-manager",
"--master=127.0.0.1:8080",
"--service-account-private-key-file=/srv/kubernetes/server.key",
"--root-ca-file=/srv/kubernetes/ca.crt",
"--min-resync-period=3m",
"--leader-elect=true",
"--cluster-cidr=10.1.0.0/16",
"--v=2"
],
"volumeMounts": [
{
"name": "data",
"mountPath": "/srv/kubernetes"
}
]
},
{
"name": "apiserver",
"image": "REGISTRY/hyperkube-ARCH:VERSION",
"command": [
"/hyperkube",
"apiserver",
"--service-cluster-ip-range=10.0.0.1/24",
"--insecure-bind-address=0.0.0.0",
"--etcd-servers=http://127.0.0.1:2379",
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota",
"--client-ca-file=/srv/kubernetes/ca.crt",
"--basic-auth-file=/srv/kubernetes/basic_auth.csv",
"--min-request-timeout=300",
"--tls-cert-file=/srv/kubernetes/server.cert",
"--tls-private-key-file=/srv/kubernetes/server.key",
"--token-auth-file=/srv/kubernetes/known_tokens.csv",
"--allow-privileged=true",
"--v=2"
],
"volumeMounts": [
{
"name": "data",
"mountPath": "/srv/kubernetes"
}
]
},
{
"name": "scheduler",
"image": "REGISTRY/hyperkube-ARCH:VERSION",
"command": [
"/hyperkube",
"scheduler",
"--master=127.0.0.1:8080",
"--leader-elect=true",
"--v=2"
]
},
{
"name": "setup",
"image": "REGISTRY/hyperkube-ARCH:VERSION",
"command": [
"/setup-files.sh",
"IP:10.0.0.1,DNS:kubernetes,DNS:kubernetes.default,DNS:kubernetes.default.svc,DNS:kubernetes.default.svc.cluster.local"
],
"volumeMounts": [
{
"name": "data",
"mountPath": "/srv/kubernetes"
}
]
}
],
"volumes": [
{
"name": "data",
"emptyDir": {}
}
]
}
}

View file

@ -0,0 +1,90 @@
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "k8s-master",
"namespace": "kube-system"
},
"spec":{
"hostNetwork": true,
"containers":[
{
"name": "controller-manager",
"image": "REGISTRY/hyperkube-ARCH:VERSION",
"command": [
"/hyperkube",
"controller-manager",
"--master=127.0.0.1:8080",
"--service-account-private-key-file=/srv/kubernetes/server.key",
"--root-ca-file=/srv/kubernetes/ca.crt",
"--min-resync-period=3m",
"--leader-elect=true",
"--v=2"
],
"volumeMounts": [
{
"name": "data",
"mountPath": "/srv/kubernetes"
}
]
},
{
"name": "apiserver",
"image": "REGISTRY/hyperkube-ARCH:VERSION",
"command": [
"/hyperkube",
"apiserver",
"--service-cluster-ip-range=10.0.0.1/24",
"--insecure-bind-address=127.0.0.1",
"--etcd-servers=http://127.0.0.1:2379",
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota",
"--client-ca-file=/srv/kubernetes/ca.crt",
"--basic-auth-file=/srv/kubernetes/basic_auth.csv",
"--min-request-timeout=300",
"--tls-cert-file=/srv/kubernetes/server.cert",
"--tls-private-key-file=/srv/kubernetes/server.key",
"--token-auth-file=/srv/kubernetes/known_tokens.csv",
"--allow-privileged=true",
"--v=2"
],
"volumeMounts": [
{
"name": "data",
"mountPath": "/srv/kubernetes"
}
]
},
{
"name": "scheduler",
"image": "REGISTRY/hyperkube-ARCH:VERSION",
"command": [
"/hyperkube",
"scheduler",
"--master=127.0.0.1:8080",
"--leader-elect=true",
"--v=2"
]
},
{
"name": "setup",
"image": "REGISTRY/hyperkube-ARCH:VERSION",
"command": [
"/setup-files.sh",
"IP:10.0.0.1,DNS:kubernetes,DNS:kubernetes.default,DNS:kubernetes.default.svc,DNS:kubernetes.default.svc.cluster.local"
],
"volumeMounts": [
{
"name": "data",
"mountPath": "/srv/kubernetes"
}
]
}
],
"volumes": [
{
"name": "data",
"emptyDir": {}
}
]
}
}

View file

@ -0,0 +1,18 @@
# Copyright 2016 The Kubernetes 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.
FROM BASEIMAGE
COPY kube-discovery /usr/local/bin
ENTRYPOINT "/usr/local/bin/kube-discovery"

View file

@ -0,0 +1,53 @@
# Copyright 2016 The Kubernetes 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.
# Build the kube-discovery image.
#
# Requires a pre-built kube-discovery binary:
# build-tools/run.sh /bin/bash -c "KUBE_BUILD_PLATFORMS=linux/ARCH make WHAT=cmd/kube-discovery"
#
# Usage:
# [ARCH=amd64] [REGISTRY="gcr.io/google_containers"] make (build|push) VERSION={some_released_version_of_kubernetes}
REGISTRY?=gcr.io/google_containers
ARCH?=amd64
TEMP_DIR:=$(shell mktemp -d)
VERSION?=1.0
ifeq ($(ARCH),amd64)
BASEIMAGE?=debian:jessie
endif
ifeq ($(ARCH),arm)
BASEIMAGE?=armel/debian:jessie
endif
ifeq ($(ARCH),arm64)
BASEIMAGE?=aarch64/debian:jessie
endif
ifeq ($(ARCH),ppc64le)
BASEIMAGE?=ppc64le/debian:jessie
endif
all: build
build:
cp -r ./* ${TEMP_DIR}
cp ../../../_output/dockerized/bin/linux/${ARCH}/kube-discovery ${TEMP_DIR}
cd ${TEMP_DIR} && sed -i.back "s|BASEIMAGE|${BASEIMAGE}|g" Dockerfile
docker build -t ${REGISTRY}/kube-discovery-${ARCH}:${VERSION} ${TEMP_DIR}
rm -rf "${TEMP_DIR}"
push: build
gcloud docker -- push ${REGISTRY}/kube-discovery-${ARCH}:${VERSION}
.PHONY: all

View file

@ -0,0 +1,45 @@
### kube-discovery
An initial implementation of a Kubernetes discovery service using JSON Web Signatures.
This prototype is configured by kubeadm and run within Kubernetes itself.
## Requirements
This pod expects the cluster CA, endpoints list, and token map to exist in /tmp/secret. This allows us to pass them in as kubernetes secrets when deployed as a pod.
```
$ cd /tmp/secret
$ ls
ca.pem endpoint-list.json token-map.json
$ cat endpoint-list.json
["http://192.168.1.5:8080", "http://192.168.1.6:8080"]
$ cat token-map.json
{
"TOKENID": "ABCDEF1234123456"
}
```
## Build And Run From Source
```
$ build-tools/run.sh /bin/bash -c "KUBE_BUILD_PLATFORMS=linux/amd64 make WHAT=cmd/kube-discovery"
$ _output/dockerized/bin/linux/amd64/kube-discovery
2016/08/23 19:17:28 Listening for requests on port 9898.
```
## Running in Docker
This image is published at: gcr.io/google_containers/kube-discovery
`docker run -d -p 9898:9898 -v /tmp/secret/ca.pem:/tmp/secret/ca.pem -v /tmp/secret/endpoint-list.json:/tmp/secret/endpoint-list.json -v /tmp/secret/token-map.json:/tmp/secret/token-map.json --name kubediscovery gcr.io/google_containers/kube-discovery`
## Testing the API
`curl "http://localhost:9898/cluster-info/v1/?token-id=TOKENID"`
You should see JSON containing a signed payload. For code to verify and decode that payload see handler_test.go.
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/cluster/images/kube-discovery/README.md?pixel)]()

View file

@ -0,0 +1,20 @@
# Copyright 2016 The Kubernetes 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.
FROM debian:jessie
COPY kubemark.sh /kubemark.sh
RUN chmod a+x /kubemark.sh
COPY kubemark /kubemark

View file

@ -0,0 +1,22 @@
# Copyright 2016 The Kubernetes 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.
# build Kubemark image from currently built binaries containing both 'real' master and Hollow Node.
# This makefile assumes that the kubemark binary is present in this directory.
all:
docker build -t gcr.io/$(PROJECT)/kubemark .
gcloud docker -- push gcr.io/$(PROJECT)/kubemark
.PHONY: all

View file

@ -0,0 +1,30 @@
#!/bin/bash
# Copyright 2015 The Kubernetes 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.
# We don't need all intermediate steps in the image, especially because
# we clean after ourselves. Thus instead of doing all of this in the Dockerfile
# we use this script.
apt-get update
apt-get install -y wget vim rsync ca-certificates
update-ca-certificates
chmod a+x /kubemark.sh
cp kubemark /
rm -rf /tmp/*
apt-get clean -y
apt-get autoremove -y

View file

@ -0,0 +1,20 @@
#!/bin/bash
# Copyright 2015 The Kubernetes 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.
# Currently populating the Pod IP thought the downward API is broken (#13690)
# this is a temporary workaround.
# TODO: get rid of this script when downward API is fixed.
./kubemark --name=`hostname -i` $@