Multiarch support for pets images

pull/6/head
Manjunath A Kumatagi 2017-07-06 21:31:35 +05:30
parent 4231308582
commit 33b0702edc
22 changed files with 278 additions and 28 deletions

View File

@ -32,6 +32,7 @@ filegroup(
"//test/images/no-snat-test:all-srcs",
"//test/images/no-snat-test-proxy:all-srcs",
"//test/images/nonewprivs:all-srcs",
"//test/images/pets/peer-finder:all-srcs",
"//test/images/port-forward-tester:all-srcs",
"//test/images/porter:all-srcs",
"//test/images/resource-consumer:all-srcs",

View File

@ -0,0 +1,4 @@
amd64=gcr.io/google-containers/debian-base-amd64:0.2
arm=gcr.io/google-containers/debian-base-arm:0.2
arm64=gcr.io/google-containers/debian-base-arm64:0.2
ppc64le=gcr.io/google-containers/debian-base-ppc64le:0.2

View File

@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "peer-finder",
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["peer-finder.go"],
tags = ["automanaged"],
deps = ["//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -12,16 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
all: push
FROM BASEIMAGE
TAG = e2e
PREFIX = gcr.io/google_containers/redis-install-3.2.0
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
container:
docker build --pull -t $(PREFIX):$(TAG) .
RUN clean-install wget bash dnsutils
push: container
gcloud docker -- push $(PREFIX):$(TAG)
COPY peer-finder /
clean:
docker rmi $(PREFIX):$(TAG)
EXPOSE 9376
ENTRYPOINT ["/peer-finder"]

View File

@ -12,16 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
all: push
SRCS = peer-finder
ARCH ?= amd64
TARGET ?= $(CURDIR)
GOLANG_VERSION ?= latest
SRC_DIR = pets/peer-finder
export
TAG = e2e
PREFIX = gcr.io/google_containers/zookeeper-install-3.5.0-alpha
bin:
../../image-util.sh bin $(SRCS)
container:
docker build --pull -t $(PREFIX):$(TAG) .
push: container
gcloud docker -- push $(PREFIX):$(TAG)
clean:
docker rmi $(PREFIX):$(TAG)
.PHONY: bin

View File

@ -0,0 +1,39 @@
# Peer finder
This is a simple peer finder daemon that is useful with StatefulSet and related use cases.
All it does is watch DNS for changes in the set of endpoints that are part of the governing service
of the PetSet. It periodically looks up the SRV record of the DNS entry that corresponds to a Kubernetes
Service which enumerates the set of peers for this the specified service.
Be sure to use the `service.alpha.kubernetes.io/tolerate-unready-endpoints` on the governing service
of the StatefulSet so that all peers are listed in endpoints before any peers are started.
There are several ways to bundle it with your main application.
1. In an [init container](http://kubernetes.io/docs/user-guide/pods/init-container/),
to help your pod determine its peers when it it first started (determine the desired set of
peers from the governing service of the StatefulSet. For this use case, the `--on-start` option
can be used, but the `--on-change` option should not be used since the init container will no
longer be running after the pod is started. An example of an `--on-start` script would be to
edit a configuration file for the main app to insert the list of peers. This file needs to be
on a Volume shared between the init container and the main container.
2. In a sidecar (e.g. a second container in the same pod as the main app), in which case the `--on-change`
option can be used, but `--on-start` may not be useful without a way to guarantee the ordering
of the sidecar relative to the main app container. An example of an on-change script would be to
send an administrative command to the main container over the localhost network. (Note that signalling
is not practical since pods currently do not share a PID namespace).
3. As pid 1 of the main container, in which case both `--on-change` and `--on-start` may be used.
In this mode, the ordering of the peer-finder relative to the main app is ensured by having the peer
finder start the main app. An example script would be to modify a configuration file and send SIGHUP
to the main process.
4. Both 1 and 2.
Options 1 and 2 and 4 may be preferable since they do not require changes to the main container image.
Option 3 is useful is signalling is necessary.
The peer-finder tool is intended to help legacy applications run in containers on Kubernetes.
If possible, it may be preferable to modify an applications to poll DNS itself to determine its peer set.
Not all StatefulSets are able to be scaled. For unscalable StatefulSets, only the on-start message is needed, and
so option 1 is a good choice.

View File

@ -0,0 +1 @@
1.0

View File

@ -0,0 +1,111 @@
/*
Copyright 2014 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.
*/
// A small utility program to lookup hostnames of endpoints in a service.
package main
import (
"flag"
"fmt"
"log"
"net"
"os"
"os/exec"
"sort"
"strings"
"time"
"k8s.io/apimachinery/pkg/util/sets"
)
const (
pollPeriod = 1 * time.Second
)
var (
onChange = flag.String("on-change", "", "Script to run on change, must accept a new line separated list of peers via stdin.")
onStart = flag.String("on-start", "", "Script to run on start, must accept a new line separated list of peers via stdin.")
svc = flag.String("service", "", "Governing service responsible for the DNS records of the domain this pod is in.")
namespace = flag.String("ns", "", "The namespace this pod is running in. If unspecified, the POD_NAMESPACE env var is used.")
domain = flag.String("domain", "cluster.local", "The Cluster Domain which is used by the Cluster.")
)
func lookup(svcName string) (sets.String, error) {
endpoints := sets.NewString()
_, srvRecords, err := net.LookupSRV("", "", svcName)
if err != nil {
return endpoints, err
}
for _, srvRecord := range srvRecords {
// The SRV records ends in a "." for the root domain
ep := fmt.Sprintf("%v", srvRecord.Target[:len(srvRecord.Target)-1])
endpoints.Insert(ep)
}
return endpoints, nil
}
func shellOut(sendStdin, script string) {
log.Printf("execing: %v with stdin: %v", script, sendStdin)
// TODO: Switch to sending stdin from go
out, err := exec.Command("bash", "-c", fmt.Sprintf("echo -e '%v' | %v", sendStdin, script)).CombinedOutput()
if err != nil {
log.Fatalf("Failed to execute %v: %v, err: %v", script, string(out), err)
}
log.Print(string(out))
}
func main() {
flag.Parse()
ns := *namespace
if ns == "" {
ns = os.Getenv("POD_NAMESPACE")
}
if *svc == "" || ns == "" || (*onChange == "" && *onStart == "") {
log.Fatalf("Incomplete args, require -on-change and/or -on-start, -service and -ns or an env var for POD_NAMESPACE.")
}
hostname, err := os.Hostname()
if err != nil {
log.Fatalf("Failed to get hostname: %s", err)
}
svcLocalSuffix := strings.Join([]string{"svc", *domain}, ".")
myName := strings.Join([]string{hostname, *svc, ns, svcLocalSuffix}, ".")
script := *onStart
if script == "" {
script = *onChange
log.Printf("No on-start supplied, on-change %v will be applied on start.", script)
}
for newPeers, peers := sets.NewString(), sets.NewString(); script != ""; time.Sleep(pollPeriod) {
newPeers, err = lookup(*svc)
if err != nil {
log.Printf("%v", err)
continue
}
if newPeers.Equal(peers) || !newPeers.Has(myName) {
continue
}
peerList := newPeers.List()
sort.Strings(peerList)
log.Printf("Peer list updated\nwas %v\nnow %v", peers.List(), newPeers.List())
shellOut(strings.Join(peerList, "\n"), script)
peers = newPeers
script = *onChange
}
// TODO: Exit if there's no on-change?
log.Printf("Peer finder exiting")
}

View File

@ -0,0 +1,4 @@
amd64=gcr.io/google-containers/debian-base-amd64:0.2
arm=gcr.io/google-containers/debian-base-arm:0.2
arm64=gcr.io/google-containers/debian-base-arm64:0.2
ppc64le=gcr.io/google-containers/debian-base-ppc64le:0.2

View File

@ -14,10 +14,12 @@
# TODO: get rid of bash dependency and switch to plain busybox.
# The tar in busybox also doesn't seem to understand compression.
FROM debian:jessie
FROM BASEIMAGE
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
# TODO: just use standard redis when there is one for 3.2.0.
RUN apt-get update && apt-get install -y wget make gcc
RUN clean-install wget make gcc libc-dev
# See README.md
RUN wget -qO /redis-3.2.0.tar.gz http://download.redis.io/releases/redis-3.2.0.tar.gz && \
@ -31,8 +33,8 @@ RUN cd /tmp/redis-3.2.0 && make distclean && mkdir -p /redis && \
rm -rf /tmp/redis-3.2.0
ADD on-start.sh /
# See contrib/pets/peer-finder for details
RUN wget -qO /peer-finder https://storage.googleapis.com/kubernetes-release/pets/peer-finder
COPY peer-finder /
ADD install.sh /
RUN chmod -c 755 /install.sh /on-start.sh /peer-finder
Entrypoint ["/install.sh"]

View File

@ -0,0 +1,25 @@
# 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.
SRCS = peer-finder
ARCH ?= amd64
TARGET ?= $(CURDIR)
GOLANG_VERSION ?= latest
SRC_DIR = pets/peer-finder
export
bin:
../../image-util.sh bin $(SRCS)
.PHONY: bin

View File

@ -0,0 +1 @@
1.0

View File

@ -0,0 +1,4 @@
amd64=gcr.io/google-containers/debian-base-amd64:0.2
arm=gcr.io/google-containers/debian-base-arm:0.2
arm64=gcr.io/google-containers/debian-base-arm64:0.2
ppc64le=gcr.io/google-containers/debian-base-ppc64le:0.2

View File

@ -14,13 +14,15 @@
# TODO: get rid of bash dependency and switch to plain busybox.
# The tar in busybox also doesn't seem to understand compression.
FROM debian:jessie
FROM BASEIMAGE
RUN apt-get update && apt-get install -y wget netcat
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
RUN clean-install wget netcat
ADD on-start.sh /
# See contrib/pets/peer-finder for details
RUN wget -qO /peer-finder https://storage.googleapis.com/kubernetes-release/pets/peer-finder
COPY peer-finder /
# See README.md
RUN wget -q -O /zookeeper-3.5.0-alpha.tar.gz http://apache.mirrors.pair.com/zookeeper/zookeeper-3.5.0-alpha/zookeeper-3.5.0-alpha.tar.gz && \

View File

@ -0,0 +1,25 @@
# 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.
SRCS = peer-finder
ARCH ?= amd64
TARGET ?= $(CURDIR)
GOLANG_VERSION ?= latest
SRC_DIR = pets/peer-finder
export
bin:
../../image-util.sh bin $(SRCS)
.PHONY: bin

View File

@ -0,0 +1 @@
1.0