{"action":"created","comment":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/69979370","id":69979370,"diff_hunk":"@@ -0,0 +1,477 @@\n+# Kubernetes for multiple platforms\n+\n+**Author**: Lucas Käldström ([@luxas](https://github.com/luxas))\n+\n+**Status** (17th of June 2016): Most parts are already implemented; still there's room for improvement\n+\n+## Abstract\n+\n+Kubernetes is written in Go, and Go code is portable across platforms.\n+Docker and rkt are also written in Go, and it's already possible to use docker on various platforms.\n+When it's possible to run docker containers on a specific architecture, people also want to use Kubernetes to manage the containers.\n+\n+We obviously want Kubernetes to run on as many platforms as possible.\n+This is a proposal that explains what already has been done and why, and what's proposed to yet be done.\n+\n+With this work, we want to achieve a true cross-platform container management system.\n+\n+### TL; DR;\n+\n+This is a pretty long proposal with a lot of information and details, but here are the main tasks that are yet to be done:\n+\n+ - Standardize all Makefiles to build for all platforms\n+   - Document in the devel documentation how to do this, and make people actually care about doing it\n+ - Help Docker to fully implement the Manifest List, and implement it for all Kubernetes infrastructure images.\n+   - To help Docker directly might be a bit out of topic for a Kubernetes proposal, so the first step is to use/build a small utility that is able to build and push Manifest list images.\n+ - Make it possible to run a CI (for distributed testing) on other platforms\n+ - Port even more addons\n+ - Choose a deployment setup that is as \"official\" as possible, and make it working on multiple platforms\n+ - Last but not least, advertise that it is possible to run Kubernetes on non-amd64 platforms already today!\n+\n+## Implementation\n+\n+## Proposed platforms and history\n+\n+The default, and the currently only supported platform is `linux/amd64`.\n+The proposed architectures are `linux/arm`, `linux/arm64` and `linux/ppc64le`.\n+In this proposal, `platform` is defined as `operating system/architecture`\n+\n+32-bit ARM (`linux/arm`) was the first platform Kubernetes was ported to, and luxas' project [`Kubernetes on ARM`](https://github.com/luxas/kubernetes-on-arm) (released on Github the 31st of September 2015)\n+served as a way of running Kubernetes on ARM devices easily.\n+The 30th of November 2015, a tracking issue about making Kubernetes run on ARM was opened: [#17981](https://github.com/kubernetes/kubernetes/issues/17981). It later shifted focus to how to make Kubernetes a more platform-independent system.\n+\n+The 27th of April 2016, Kubernetes `v1.3.0-alpha.3` was released, and it became the first release that was able to run the [docker getting started guide](http://kubernetes.io/docs/getting-started-guides/docker/) on `linux/amd64`, `linux/arm`, `linux/arm64` and `linux/ppc64le` without any modification.\n+\n+If there's interest in running Kubernetes on `linux/s390x` too, it won't require many changes to the source now when we've laid the ground for a multi-platform Kubernetes already.\n+\n+There is also work going on with porting Kubernetes to Windows (`windows/amd64`). See [this issue](https://github.com/kubernetes/kubernetes/issues/22623) for more details.\n+\n+Note that when porting to a new OS, a lot of os-specific changes have to be implemented before cross-compiling, releasing and other concerns this document is describing may apply\n+\n+## Background factors\n+\n+### Go language details\n+\n+Go 1.5 introduced many changes. To name a few that are relevant to Kubernetes:\n+ - C was eliminated from the tree (it was earlier used for the bootstrap runtime).\n+ - All processors are used by default, which means we should be able to remove [lines like this one](https://github.com/kubernetes/kubernetes/blob/v1.2.0/cmd/kubelet/kubelet.go#L37)\n+ - The garbage collector became more efficent (but also [confused our latency test](https://github.com/golang/go/issues/14396)).\n+ - `linux/arm64` and `linux/ppc64le` were added as new ports.\n+ - The `GO15VENDOREXPERIMENT` was started. We switched from `Godeps/_workspace` to the native `vendor/` in [this PR](https://github.com/kubernetes/kubernetes/pull/24242).\n+ - It's not required to pre-build the whole standard library `std` when cross-compliling. [Details](#prebuilding-the-standard-library-std)\n+ - Builds are approximately twice as slow as earlier. That affects the CI. [Details](#releasing)\n+ - The native Go DNS resolver will suffice in the most situations. This makes static linking much easier.\n+\n+All release notes for Go 1.5 [are here](https://golang.org/doc/go1.5)\n+\n+Go 1.6 didn't introduce as many changes as Go 1.5 did, but here are some of note:\n+ - It should perform a little bit better than Go 1.5.\n+ - `linux/mips64` and `linux/mips64le` were added as new ports.\n+ - Go < 1.6.2 for `ppc64le` had [bugs in it](https://github.com/kubernetes/kubernetes/issues/24922).\n+\n+All release notes for Go 1.6 [are here](https://golang.org/doc/go1.6)\n+\n+In Kubernetes 1.2, the only supported Go version was `1.4.2`, so `linux/arm` was the only possible extra architecture: [#19769](https://github.com/kubernetes/kubernetes/pull/19769).\n+In Kubernetes 1.3, [we upgraded to Go 1.6](https://github.com/kubernetes/kubernetes/pull/22149), which made it possible to build Kubernetes for even more architectures [#23931](https://github.com/kubernetes/kubernetes/pull/23931).\n+\n+#### The `sync/atomic` bug on 32-bit platforms\n+\n+From https://golang.org/pkg/sync/atomic/#pkg-note-BUG:\n+> On both ARM and x86-32, it is the caller's responsibility to arrange for 64-bit alignment of 64-bit words accessed atomically. The first word in a global variable or in an allocated struct or slice can be relied upon to be 64-bit aligned.\n+\n+`etcd` have had [issues](https://github.com/coreos/etcd/issues/2308) with this. See [how to fix it here](https://github.com/coreos/etcd/pull/3249)\n+\n+```go\n+// 32-bit-atomic-bug.go\n+package main\n+import \"sync/atomic\"\n+\n+type a struct {\n+    b chan struct{}\n+    c int64\n+}\n+\n+func main(){\n+    d := a{}\n+    atomic.StoreInt64(&d.c, 10 * 1000 * 1000 * 1000)\n+}\n+```\n+```console\n+$ GOARCH=386 go build 32-bit-atomic-bug.go\n+$ file 32-bit-atomic-bug\n+32-bit-atomic-bug: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped\n+$ ./32-bit-atomic-bug\n+panic: runtime error: invalid memory address or nil pointer dereference\n+[signal 0xb code=0x1 addr=0x0 pc=0x808cd9b]\n+\n+goroutine 1 [running]:\n+panic(0x8098de0, 0x1830a038)\n+\t/usr/local/go/src/runtime/panic.go:481 +0x326\n+sync/atomic.StoreUint64(0x1830e0f4, 0x540be400, 0x2)\n+\t/usr/local/go/src/sync/atomic/asm_386.s:190 +0xb\n+main.main()\n+\t/tmp/32-bit-atomic-bug.go:11 +0x4b\n+```\n+\n+This means that all structs should keep all `int64` and `uint64` fields at the top of the struct to be safe. If we would move `a.c` to the top of the `a` struct above, the operation would succeed.\n+\n+The bug affects `32-bit` platforms when a `(u)int64` field is accessed by an `atomic` method.\n+It would be great to write a tool that checks so all `atomic` accessed fields are aligned at the top of the struct, but it's hard: [coreos/etcd#5027](https://github.com/coreos/etcd/issues/5027).\n+\n+### Multi-platform work by docker\n+\n+#### Compiling Docker\n+\n+Since `docker-1.11.0`, there are `Dockerfiles` for building docker for `armhf` (`ARMv7`), `aarch64` (`arm64`), `ppc64le` and `s390x`.\n+This makes it possible to build `docker` for the architectures above **when running on that platform** (cross-build isn't working in this case)\n+\n+In some cases, guys like [`Hypriot`](http://blog.hypriot.org) provide prebuilt versions of docker for other architectures. \n+Otherwise, you have to build docker from source, and distribute the binaries yourself.\n+\n+We should work with the Docker team towards automatically releasing Docker binaries and `.deb` packages for all platforms on each release.\n+\n+#### Multi-platform Docker images\n+\n+Here's a good article about how the \"manifest list\" in the Docker image [manifest spec v2](https://github.com/docker/distribution/pull/1068) works: [A step towards multi-platform Docker images](https://integratedcode.us/2016/04/22/a-step-towards-multi-platform-docker-images/)\n+\n+A short summary: A manifest list is a list of Docker images with a single name (e.g. `busybox`), that holds layers for multiple platforms _when it's stored in a registry_.\n+When the image is pulled by a client (`docker pull busybox`), only layers for the target platforms are downloaded.\n+Right now we have to write `${ARCH}/busybox` instead, but that leads to extra scripting and unnecessary logic.\n+\n+When this is working, it's a perfect fit for the our infrastructure images that live in `gcr.io`, but we're quite far away from that right now.\n+See [image naming](#image-naming) for details how we work around this for the time being.\n+\n+## Cross-compilation\n+\n+## Prebuilding the Go standard library (`std`)\n+\n+A great blog post [that is describing this](https://medium.com/@rakyll/go-1-5-cross-compilation-488092ba44ec#.5jcd0owem) \n+\n+Before Go 1.5, the whole Go project had to be cross-compiled from source for **all** platforms that _might_ be used, and that was quite a slow process:\n+\n+```console\n+# From build/build-image/cross/Dockerfile when we used Go 1.4\n+$ cd /usr/src/go/src\n+$ for platform in ${PLATFORMS}; do GOOS=${platform%/*} GOARCH=${platform##*/} ./make.bash --no-clean; done\n+```\n+\n+With Go 1.5+, cross-compiling the Go repository isn't required anymore. Go will automatically cross-compile the `std` packages that are being used by the code that is being compiled, _and throw it away after the compilation_.\n+If you cross-compile multiple times, Go will build parts of `std`, throw it away, compile parts of it again, throw that away and so on.\n+\n+However, there is an easy way of cross-compiling all `std` packages in advance with Go 1.5+:\n+\n+```console\n+# From build/build-image/cross/Dockerfile when we're using Go 1.5+\n+$ for platform in ${PLATFORMS}; do GOOS=${platform%/*} GOARCH=${platform##*/} go install std; done\n+```\n+\n+### Static cross-compilation\n+\n+Static compilation with Go 1.5+ is dead easy:\n+\n+```go\n+// main.go\n+package main\n+import \"fmt\"\n+func main() {\n+    fmt.Println(\"Hello Kubernetes!\")\n+}\n+```\n+```console\n+$ go build main.go\n+$ file main\n+main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped\n+$ GOOS=linux GOARCH=arm go build main.go\n+$ file main\n+main: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped\n+```\n+\n+The only thing you have to do is change the `GOARCH` and `GOOS` variables. Here's a list of valid values for [GOOS/GOARCH](https://golang.org/doc/install/source#environment)\n+\n+#### Static compilation with `net`\n+\n+Consider this:\n+\n+```go\n+// main-with-net.go\n+package main\n+import \"net\"\n+import \"fmt\"\n+func main() {             \n+\tfmt.Println(net.ParseIP(\"10.0.0.10\").String())\n+}\n+```\n+```console\n+$ go build main-with-net.go\n+$ file main-with-net\n+main-with-net: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, \n+    interpreter /lib64/ld-linux-x86-64.so.2, not stripped\n+$ GOOS=linux GOARCH=arm go build main-with-net.go\n+$ file main-with-net\n+main-with-net: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped\n+```\n+\n+Wait, what? Just because we included `net` from the `std` package, the binary defaults to being dynamically linked when the target platform equals to the host platform?\n+Let's take a look at `go env` to get a clue why this happens:\n+\n+```console\n+$ go env\n+GOARCH=\"amd64\"\n+GOHOSTARCH=\"amd64\"\n+GOHOSTOS=\"linux\"\n+GOOS=\"linux\"\n+GOPATH=\"/go\"\n+GOROOT=\"/usr/local/go\"\n+GO15VENDOREXPERIMENT=\"1\"\n+CC=\"gcc\"\n+CXX=\"g++\"\n+CGO_ENABLED=\"1\"\n+```\n+\n+See the `CGO_ENABLED=1` at the end? That's where compilation for the host and cross-compilation differs. By default, Go will link statically if no `cgo` code is involved. `net` is one of the packages that prefers `cgo`, but doesn't depend on it. \n+\n+When cross-compiling on the other hand, `CGO_ENABLED` is set to `0` by default.\n+\n+To always be safe, run this when compiling statically:\n+\n+```console\n+$ CGO_ENABLED=0 go build -a -installsuffix cgo main-with-net.go\n+$ file main-with-net\n+main-with-net: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped\n+```\n+See [golang/go#9344](https://github.com/golang/go/issues/9344) for more details.\n+\n+### Dynamic cross-compilation\n+\n+In order to dynamically compile a go binary with `cgo`, we need `gcc` installed at build time.\n+\n+The only Kubernetes binary that is using C code is the `kubelet`, or in fact `cAdvisor` on which `kubelet` depends. `hyperkube` is also dynamically linked as long as `kubelet` is. We should aim to make `kubelet` statically linked.\n+\n+The normal `x86_64-linux-gnu` can't cross-compile binaries, so we have to install gcc cross-compilers for every platform. We do this in the [`kube-cross`](https://github.com/kubernetes/kubernetes/blob/master/build/build-image/cross/Dockerfile) image,\n+and depend on the [`emdebian.org` repository](https://wiki.debian.org/CrossToolchains). Depending on `emdebian` isn't ideal, so we should consider using the latest `gcc` cross-compiler packages from the `ubuntu` main repositories in the future.\n+\n+Here's an example when cross-compiling plain C code:\n+```c\n+// main.c\n+#include <stdio.h>\n+main()\n+{\n+  printf(\"Hello Kubernetes!\\n\");\n+}\n+```\n+```console\n+$ arm-linux-gnueabi-gcc -o main-c main.c\n+$ file main-c\n+main-c: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, \n+    interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.32, not stripped\n+```\n+\n+And here's an example when cross-compiling `go` and `c`:\n+```go\n+// main-cgo.go\n+package main\n+/*\n+char* sayhello(void) { return \"Hello Kubernetes!\"; }\n+*/\n+import \"C\"\n+import \"fmt\"\n+func main() {\n+\tfmt.Println(C.GoString(C.sayhello()))\n+}\n+```\n+```console\n+$ CGO_ENABLED=1 CC=arm-linux-gnueabi-gcc GOOS=linux GOARCH=arm go build main-cgo.go\n+$ file main-cgo\n+./main-cgo: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, \n+    interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.32, not stripped\n+```\n+\n+The bad thing with dynamic compilation is that it adds an unnecessary dependency on `glibc` _at runtime_.\n+\n+### Static compilation with CGO code\n+\n+Lastly, it's even possible to cross-compile `cgo` code _statically_:\n+\n+```console\n+$ CGO_ENABLED=1 CC=arm-linux-gnueabi-gcc GOARCH=arm go build -ldflags '-extldflags \"-static\"' main-cgo.go\n+$ file main-cgo\n+./main-cgo: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked,\n+    for GNU/Linux 2.6.32, not stripped\n+```\n+\n+This is especially useful if we want to include the binary in a container. \n+If the binary is statically compiled, we may use `busybox` or even `scratch` as the base image.\n+This should be the preferred way of compiling binaries that strictly require C code to be a part of it.","path":"docs/proposals/multi-platform.md","position":304,"original_position":304,"commit_id":"79639efb4ebae4ad1d1ce5254432016eb59cba1d","original_commit_id":"79639efb4ebae4ad1d1ce5254432016eb59cba1d","user":{"login":"luxas","id":5442475,"avatar_url":"https://avatars.githubusercontent.com/u/5442475?v=3","gravatar_id":"","url":"https://api.github.com/users/luxas","html_url":"https://github.com/luxas","followers_url":"https://api.github.com/users/luxas/followers","following_url":"https://api.github.com/users/luxas/following{/other_user}","gists_url":"https://api.github.com/users/luxas/gists{/gist_id}","starred_url":"https://api.github.com/users/luxas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/luxas/subscriptions","organizations_url":"https://api.github.com/users/luxas/orgs","repos_url":"https://api.github.com/users/luxas/repos","events_url":"https://api.github.com/users/luxas/events{/privacy}","received_events_url":"https://api.github.com/users/luxas/received_events","type":"User","site_admin":false},"body":"Thanks for pointing at a doc flaw.\r\nThat's exactly what my the intention is with this section, to describe how to cross-compile statically with CGO code for another architecture.\r\n\r\nHowever, I see that here it says `compilation` in the header, when it should be `cross-compilation`, and likewise in other places. Will fix.","created_at":"2016-07-07T20:22:25Z","updated_at":"2016-07-07T20:22:25Z","html_url":"https://github.com/kubernetes/kubernetes/pull/26863#discussion_r69979370","pull_request_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/26863","_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/69979370"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/26863#discussion_r69979370"},"pull_request":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/26863"}}},"pull_request":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/26863","id":72639088,"html_url":"https://github.com/kubernetes/kubernetes/pull/26863","diff_url":"https://github.com/kubernetes/kubernetes/pull/26863.diff","patch_url":"https://github.com/kubernetes/kubernetes/pull/26863.patch","issue_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/26863","number":26863,"state":"open","locked":false,"title":"Add a multi-platform proposal","user":{"login":"luxas","id":5442475,"avatar_url":"https://avatars.githubusercontent.com/u/5442475?v=3","gravatar_id":"","url":"https://api.github.com/users/luxas","html_url":"https://github.com/luxas","followers_url":"https://api.github.com/users/luxas/followers","following_url":"https://api.github.com/users/luxas/following{/other_user}","gists_url":"https://api.github.com/users/luxas/gists{/gist_id}","starred_url":"https://api.github.com/users/luxas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/luxas/subscriptions","organizations_url":"https://api.github.com/users/luxas/orgs","repos_url":"https://api.github.com/users/luxas/repos","events_url":"https://api.github.com/users/luxas/events{/privacy}","received_events_url":"https://api.github.com/users/luxas/received_events","type":"User","site_admin":false},"body":"This is a proposal for the work I've done with multiarch Kubernetes. I've worked quite a lot on it and now I've written it down so others may easily use and learn from it, while at the same time pointing out issues that we should fix in the future.\r\n\r\nI would like to get this in before `v1.3`.\r\n\r\nFeel free to comment on it if it's something that's unclear.\r\n\r\n@david-mcmahon @ixdy @mikedanese @Pensu @davidopp @bgrant0607 @dlorenc @eparis @vishh @thockin @dchen1107 @lavalamp ","created_at":"2016-06-05T20:11:42Z","updated_at":"2016-07-07T20:22:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e7f3d3d5e2046dfa7eb27ec6aaaf296c5418081f","assignee":{"login":"vishh","id":7063592,"avatar_url":"https://avatars.githubusercontent.com/u/7063592?v=3","gravatar_id":"","url":"https://api.github.com/users/vishh","html_url":"https://github.com/vishh","followers_url":"https://api.github.com/users/vishh/followers","following_url":"https://api.github.com/users/vishh/following{/other_user}","gists_url":"https://api.github.com/users/vishh/gists{/gist_id}","starred_url":"https://api.github.com/users/vishh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vishh/subscriptions","organizations_url":"https://api.github.com/users/vishh/orgs","repos_url":"https://api.github.com/users/vishh/repos","events_url":"https://api.github.com/users/vishh/events{/privacy}","received_events_url":"https://api.github.com/users/vishh/received_events","type":"User","site_admin":false},"assignees":[{"login":"vishh","id":7063592,"avatar_url":"https://avatars.githubusercontent.com/u/7063592?v=3","gravatar_id":"","url":"https://api.github.com/users/vishh","html_url":"https://github.com/vishh","followers_url":"https://api.github.com/users/vishh/followers","following_url":"https://api.github.com/users/vishh/following{/other_user}","gists_url":"https://api.github.com/users/vishh/gists{/gist_id}","starred_url":"https://api.github.com/users/vishh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vishh/subscriptions","organizations_url":"https://api.github.com/users/vishh/orgs","repos_url":"https://api.github.com/users/vishh/repos","events_url":"https://api.github.com/users/vishh/events{/privacy}","received_events_url":"https://api.github.com/users/vishh/received_events","type":"User","site_admin":false},{"login":"david-mcmahon","id":15622407,"avatar_url":"https://avatars.githubusercontent.com/u/15622407?v=3","gravatar_id":"","url":"https://api.github.com/users/david-mcmahon","html_url":"https://github.com/david-mcmahon","followers_url":"https://api.github.com/users/david-mcmahon/followers","following_url":"https://api.github.com/users/david-mcmahon/following{/other_user}","gists_url":"https://api.github.com/users/david-mcmahon/gists{/gist_id}","starred_url":"https://api.github.com/users/david-mcmahon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/david-mcmahon/subscriptions","organizations_url":"https://api.github.com/users/david-mcmahon/orgs","repos_url":"https://api.github.com/users/david-mcmahon/repos","events_url":"https://api.github.com/users/david-mcmahon/events{/privacy}","received_events_url":"https://api.github.com/users/david-mcmahon/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/26863/commits","review_comments_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/26863/comments","review_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/26863/comments","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/79639efb4ebae4ad1d1ce5254432016eb59cba1d","head":{"label":"luxas:multi_platform","ref":"multi_platform","sha":"79639efb4ebae4ad1d1ce5254432016eb59cba1d","user":{"login":"luxas","id":5442475,"avatar_url":"https://avatars.githubusercontent.com/u/5442475?v=3","gravatar_id":"","url":"https://api.github.com/users/luxas","html_url":"https://github.com/luxas","followers_url":"https://api.github.com/users/luxas/followers","following_url":"https://api.github.com/users/luxas/following{/other_user}","gists_url":"https://api.github.com/users/luxas/gists{/gist_id}","starred_url":"https://api.github.com/users/luxas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/luxas/subscriptions","organizations_url":"https://api.github.com/users/luxas/orgs","repos_url":"https://api.github.com/users/luxas/repos","events_url":"https://api.github.com/users/luxas/events{/privacy}","received_events_url":"https://api.github.com/users/luxas/received_events","type":"User","site_admin":false},"repo":{"id":37801743,"name":"kubernetes","full_name":"luxas/kubernetes","owner":{"login":"luxas","id":5442475,"avatar_url":"https://avatars.githubusercontent.com/u/5442475?v=3","gravatar_id":"","url":"https://api.github.com/users/luxas","html_url":"https://github.com/luxas","followers_url":"https://api.github.com/users/luxas/followers","following_url":"https://api.github.com/users/luxas/following{/other_user}","gists_url":"https://api.github.com/users/luxas/gists{/gist_id}","starred_url":"https://api.github.com/users/luxas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/luxas/subscriptions","organizations_url":"https://api.github.com/users/luxas/orgs","repos_url":"https://api.github.com/users/luxas/repos","events_url":"https://api.github.com/users/luxas/events{/privacy}","received_events_url":"https://api.github.com/users/luxas/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/luxas/kubernetes","description":"Container Cluster Manager from Google","fork":true,"url":"https://api.github.com/repos/luxas/kubernetes","forks_url":"https://api.github.com/repos/luxas/kubernetes/forks","keys_url":"https://api.github.com/repos/luxas/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/luxas/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/luxas/kubernetes/teams","hooks_url":"https://api.github.com/repos/luxas/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/luxas/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/luxas/kubernetes/events","assignees_url":"https://api.github.com/repos/luxas/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/luxas/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/luxas/kubernetes/tags","blobs_url":"https://api.github.com/repos/luxas/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/luxas/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/luxas/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/luxas/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/luxas/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/luxas/kubernetes/languages","stargazers_url":"https://api.github.com/repos/luxas/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/luxas/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/luxas/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/luxas/kubernetes/subscription","commits_url":"https://api.github.com/repos/luxas/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/luxas/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/luxas/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/luxas/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/luxas/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/luxas/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/luxas/kubernetes/merges","archive_url":"https://api.github.com/repos/luxas/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/luxas/kubernetes/downloads","issues_url":"https://api.github.com/repos/luxas/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/luxas/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/luxas/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/luxas/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/luxas/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/luxas/kubernetes/releases{/id}","deployments_url":"https://api.github.com/repos/luxas/kubernetes/deployments","created_at":"2015-06-21T08:14:15Z","updated_at":"2016-01-11T14:11:00Z","pushed_at":"2016-07-07T15:02:17Z","git_url":"git://github.com/luxas/kubernetes.git","ssh_url":"git@github.com:luxas/kubernetes.git","clone_url":"https://github.com/luxas/kubernetes.git","svn_url":"https://github.com/luxas/kubernetes","homepage":"http://kubernetes.io","size":275885,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"kubernetes:master","ref":"master","sha":"58dc3ba31db102fc383881083d9b7c8e3bb3e4a3","user":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"repo":{"id":20580498,"name":"kubernetes","full_name":"kubernetes/kubernetes","owner":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kubernetes/kubernetes","description":"Production-Grade Container Scheduling and Management","fork":false,"url":"https://api.github.com/repos/kubernetes/kubernetes","forks_url":"https://api.github.com/repos/kubernetes/kubernetes/forks","keys_url":"https://api.github.com/repos/kubernetes/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kubernetes/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kubernetes/kubernetes/teams","hooks_url":"https://api.github.com/repos/kubernetes/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/kubernetes/kubernetes/events","assignees_url":"https://api.github.com/repos/kubernetes/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/kubernetes/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/kubernetes/kubernetes/tags","blobs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kubernetes/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/kubernetes/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/kubernetes/kubernetes/languages","stargazers_url":"https://api.github.com/repos/kubernetes/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/kubernetes/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/kubernetes/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/kubernetes/kubernetes/subscription","commits_url":"https://api.github.com/repos/kubernetes/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/kubernetes/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/kubernetes/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/kubernetes/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kubernetes/kubernetes/merges","archive_url":"https://api.github.com/repos/kubernetes/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kubernetes/kubernetes/downloads","issues_url":"https://api.github.com/repos/kubernetes/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/kubernetes/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/kubernetes/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kubernetes/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/kubernetes/kubernetes/releases{/id}","deployments_url":"https://api.github.com/repos/kubernetes/kubernetes/deployments","created_at":"2014-06-06T22:56:04Z","updated_at":"2016-07-07T19:53:18Z","pushed_at":"2016-07-07T20:22:05Z","git_url":"git://github.com/kubernetes/kubernetes.git","ssh_url":"git@github.com:kubernetes/kubernetes.git","clone_url":"https://github.com/kubernetes/kubernetes.git","svn_url":"https://github.com/kubernetes/kubernetes","homepage":"http://kubernetes.io","size":489426,"stargazers_count":15371,"watchers_count":15371,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":4807,"mirror_url":null,"open_issues_count":3857,"forks":4807,"open_issues":3857,"watchers":15371,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/26863"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/26863"},"issue":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/26863"},"comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/26863/comments"},"review_comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/26863/comments"},"review_comment":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/26863/commits"},"statuses":{"href":"https://api.github.com/repos/kubernetes/kubernetes/statuses/79639efb4ebae4ad1d1ce5254432016eb59cba1d"}}}}
{"actor":{"display_login":"luxas"}}