Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Docker-based development support #52

Closed

Conversation

ironcladlou
Copy link
Contributor

Why build or run OpenShift in Docker?

Building and running on bare metal and on VMs each have advantages and disadvantages. Using Docker for builds and development is useful when bare metal is too limited and VMs are too cumbersome. Here are some of the reasons to use Docker when developing OpenShift:

  • Many of the scheduling, load balancing, replication, and routing features typically only available to multi-machine VM setups become available but without the need for VMs. (Each component is bound to its own routable IP in a flat subnet topology that more accurately resembles a prod clustered deployment.)
  • It's easy to compose and share portable runnable images to implement arbitrary topologies for testing, demos, and development.
  • With warm caches, the build and launch cycle is very close in turnaround speed compared to bare metal development with hack/build-go.sh.
  • Docker makes it possible to create integrated, shared development toolkits which are more portable than native scripts and provide a more native user experience than VM tooling. (For example, origin-build provides httpie to developers with no host requirements beyond Docker, and in a way which can easily and closely integrate with both the cluster components and the host OS)

@ironcladlou
Copy link
Contributor Author

@smarterclayton
Copy link
Contributor

Articulate why you broke up the all in one into a ton of things? What's the value to real use cases to have ten containers?

@ironcladlou
Copy link
Contributor Author

Articulate why you broke up the all in one into a ton of things? What's the value to real use cases to have ten containers?

First, a question from your question: I want to do some development or integration-like testing of the scheduler and load balancer against 5 minions/kubelets and pods associated with them. What are my options today other than a cluster of VMs?

@ironcladlou
Copy link
Contributor Author

There's nothing preventing an "all-in-one" image as well. The point is having a way to compose clusters locally (multi-master tests, multi-minion, multi-anything) without VMs or host port juggling.

@smarterclayton
Copy link
Contributor

Testing multiple containers in docker on a single vm is useful. I don't see the carry over to testing Openshift as multiple containers adding anything to that.

@smarterclayton
Copy link
Contributor

Host port problem is going away soon in favor of testing real networks. I don't think that requires breaking up the all in one for that test env.

@ironcladlou ironcladlou closed this Sep 6, 2014
@ironcladlou ironcladlou reopened this Sep 6, 2014
@ironcladlou
Copy link
Contributor Author

Host port is going away in favor of testing real networks. I don't think that requires breaking up the all in one for that test env.

How do you do live testing of the scheduler, load balancer, replication controller, multi-anything support today without multiple VMs?

@smarterclayton
Copy link
Contributor

Discussed via phone, three concrete use cases:

  • from a system with docker, easily build the source of OpenShift and launch containers that act as individual minions on a single system (q: won't e kubelets fight over the docker namespace?)
  • get a build / compile env in a docker container that works on a linux system allowing you to not have to install Go or other dependencies on your system
  • eventually allow anyone with boot2docker (windows, mac users) to have a runtime environment they can deploy and test kubernetes with

The docker image is best for system level integration testing, spin up a container you can throw away to get back to a clean env.

@ironcladlou
Copy link
Contributor Author

For comparison purposes, here's a branch which collapses all the builder images into a single all-in-one builder image which is reused to launch the discrete components in their own containers: https://github.com/ironcladlou/origin/compare/docker-build-support-collapsed?expand=1

Functionally equivalent, less stuff overall. All linking setup very explicitly expressed in one place now rather than being spread across build-docker.sh and a Dockerfile per component.

EDIT: note that the linked branch is a rough POC to demonstrate the concept.

@pmorie
Copy link
Contributor

pmorie commented Sep 7, 2014

I really like this approach because it allows you to have a clean,
[relatively] self-contained deployment of origin without dependencies on:

  1. A VM infra and orchestration tool for creating said VM
  2. A particular linux distribution for your development host

I think this will be much easier to get into than a Vagrant-created
development VM (not to mention just being 'cooler') and will be much easier
for random folks to get started with.

On Sat, Sep 6, 2014 at 8:35 PM, Dan Mace [email protected] wrote:

For comparison purposes, here's a branch which collapses all the builder
images into a single all-in-one builder image which is reused to launch the
discrete components in their own containers:
https://github.com/ironcladlou/origin/compare/docker-build-support-collapsed?expand=1

Functionally equivalent, less stuff overall. All linking setup very
explicitly expressed in one place now rather than being spread across
build-docker.sh and a Dockerfile per component.


Reply to this email directly or view it on GitHub
#52 (comment).

@derekwaynecarr
Copy link
Member

I like this too. Guessing the major thing we would be missing is per pod IP addresses?

I can take a stab Monday at getting that working in upstream kubernetes by reusing the provision networking pieces after I get a chance to play with this some more.

On Sep 6, 2014, at 8:39 PM, Paul Morie [email protected] wrote:

I really like this approach because it allows you to have a clean,
[relatively] self-contained deployment of origin without dependencies on:

  1. A VM infra and orchestration tool for creating said VM
  2. A particular linux distribution for your development host

I think this will be much easier to get into than a Vagrant-created
development VM (not to mention just being 'cooler') and will be much easier
for random folks to get started with.

On Sat, Sep 6, 2014 at 8:35 PM, Dan Mace [email protected] wrote:

For comparison purposes, here's a branch which collapses all the builder
images into a single all-in-one builder image which is reused to launch the
discrete components in their own containers:
https://github.com/ironcladlou/origin/compare/docker-build-support-collapsed?expand=1

Functionally equivalent, less stuff overall. All linking setup very
explicitly expressed in one place now rather than being spread across
build-docker.sh and a Dockerfile per component.


Reply to this email directly or view it on GitHub
#52 (comment).


Reply to this email directly or view it on GitHub.

@ironcladlou
Copy link
Contributor Author

Per-pod IP addresses are implemented; containers in a pod still share their networking stack with a networking container as usual. All component and pod containers have IPs on the same subnet by virtue of living on the same docker bridge, which combined with links makes everything flatly routable. From an etcd perspective, there's a multi-machine cluster in action, and the kubelet doesn't care that its containers are colocated on the same physical host; docker abstracts the details of where the kubelet's containers actually live.

@smarterclayton
Copy link
Contributor

On Sep 6, 2014, at 10:39 PM, Dan Mace [email protected] wrote:

Per-pod IP addresses are implemented; containers in a pod still share their networking stack with a networking container as usual. All component and pod containers have IPs on the same subnet by virtue of living on the same docker bridge (assuming a default Docker configuration). From an etcd perspective, there's a multi-machine cluster in action, and the kubelet doesn't care that its containers are colocated on the same physical host; docker abstracts the details of where the kubelet's containers actually live.

The kubelet will nuke containers from other machines unless you did something to the kubelet to support that


Reply to this email directly or view it on GitHub.

@ironcladlou
Copy link
Contributor Author

The kubelet will nuke containers from other machines unless you did something to the kubelet to support that

Hm, I think you're right. Looks like the kubelet assumes that any container with a name prefixed with k8s is managed by the kubelet. That explains the guestbook weirdness I saw but didn't yet investigate (with some containers being created and then killed rapidly; the kubelets must have been deleting each others' pods).

Need to think about that some more. Random musings: Is the core assumption flawed? (e.g. Should container labels express a host affinity, like the kubelet does already? That would allow logical partitioning of containers by kubelet within Docker but I have no use case beyond setting up test clusters.) Is there any other way to accommodate the existing behavior without using docker-in-docker?

@smarterclayton
Copy link
Contributor

On Sep 7, 2014, at 7:59 AM, Dan Mace [email protected] wrote:

The kubelet will nuke containers from other machines unless you did something to the kubelet to support that

Hm, I think you're right. Looks like the kubelet assumes that any container with a name prefixed with k8s is managed by the kubelet. That explains the guestbook weirdness I saw but didn't yet investigate (with some containers being created and then killed rapidly; the kubelets must have been deleting each others' pods).

Need to think about that some more. Random musings: Is the core assumption flawed? (e.g. Should container labels express a host affinity, like the kubelet does already? That would allow logical partitioning of containers by kubelet within Docker but I have no use case beyond setting up test clusters.) Is there any other way to accommodate the existing behavior without using docker-in-docker?

Testing might be enough of a use case to make it desirable.

Reply to this email directly or view it on GitHub.

@pmorie
Copy link
Contributor

pmorie commented Sep 7, 2014

Testing is another big value add. We should prototype e2e tests against
this setup.

On Sunday, September 7, 2014, Clayton Coleman [email protected]
wrote:

On Sep 7, 2014, at 7:59 AM, Dan Mace <[email protected]
javascript:_e(%7B%7D,'cvml','[email protected]');> wrote:

The kubelet will nuke containers from other machines unless you did
something to the kubelet to support that

Hm, I think you're right. Looks like the kubelet assumes that any
container with a name prefixed with k8s is managed by the kubelet. That
explains the guestbook weirdness I saw but didn't yet investigate (with
some containers being created and then killed rapidly; the kubelets must
have been deleting each others' pods).

Need to think about that some more. Random musings: Is the core
assumption flawed? (e.g. Should container labels express a host affinity,
like the kubelet does already? That would allow logical partitioning of
containers by kubelet within Docker but I have no use case beyond setting
up test clusters.) Is there any other way to accommodate the existing
behavior without using docker-in-docker?

Testing might be enough of a use case to make it desirable.

Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub
#52 (comment).

@ironcladlou
Copy link
Contributor Author

The latest branch ditches the multiple images in favor of a single build image which also serves as a runner. It also has some really, really rough code to:

  1. Stop using Docker links (to allow routing without knowing in advance what ports will be allocated later, i.e. in pod containers)
  2. Facilitate developing both k8s and origin in tandem by allowing local k8s (or other) source to override the Godeps dependencies during the build (for my own sanity)

Something's still wrong with proxying.

To even try this branch, you need to apply this patch to a local clone of the openshfit/kubernetes repo using the stable branch:

ironcladlou/kubernetes@552c68a

@ironcladlou
Copy link
Contributor Author

Talking and thinking about all this more, docker-in-docker sidesteps all the kubelet and proxy issues entirely, at the expense of some UX complexity: to get at the pod containers, we'd have to try and transparently expose the inner dockers (random idea: docker run ... docker ps using bind mounts to inner docker sockets to see a minion's containers). This complexity compounds the deeper you go, as with docker-in-docker in container pods executing builds.

Docker-in-docker also means a loss of image caching on the host, so spinning up tests is going to be drastically slower unless host level caching is in place.

@ironcladlou
Copy link
Contributor Author

The latest commit demonstrates how this could work using docker-in-docker. It requires no patching to kubernetes. Here's how I inspect the docker daemon within the minions:

DOCKER_HOST=tcp://$(dr-ip origin-minion-1):2375 docker ps

I use a little helper script called dr-ip to get the IPs of docker containers:

docker inspect -f "{{ .NetworkSettings.IPAddress }}" $1 | tr -d '\n'

The guestbook example (with all hostPort refs stripped out) works out of the box with this setup. It does require --privileged containers for the kubelets.

@ironcladlou ironcladlou force-pushed the docker-build-support branch 2 times, most recently from fbfa449 to 4e14071 Compare September 10, 2014 19:04
usage: $0 [OPTIONS]

OPTIONS:
-l lanch a local cluster following a successful build
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

launch

@ironcladlou ironcladlou force-pushed the docker-build-support branch 5 times, most recently from fd65748 to 7e58be1 Compare September 11, 2014 19:53
@@ -11,3 +11,37 @@ If you are not updating packages you should not need godep installed.
To update to a new version of a dependency that's not already included in Kubernetes, checkout the correct version in your GOPATH and then run `godep save <pkgname>`. This should create a new version of `Godeps/Godeps.json`, and update `Godeps/workspace/src`. Create a commit that includes both of these changes.

To update the Kubernetes version, checkout the new "master" branch from openshift/kubernetes (within your regular GOPATH directory for Kubernetes), and run `godep restore ./...` from the Kubernetes dir. Then switch to the OpenShift directory and run `godep save ./...`

## Running OpenShift in Docker
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any benefit for an end user to try this path? If so, have a section for it in CONTRIBUTING.adoc

@openshift-bot
Copy link
Contributor

Origin Action Required: Pull request cannot be automatically merged, please rebase your branch from latest HEAD and push again

pweil- pushed a commit to pweil-/origin that referenced this pull request Oct 6, 2014
@ironcladlou ironcladlou closed this Nov 3, 2014
@ironcladlou ironcladlou deleted the docker-build-support branch January 8, 2015 15:45
gashcrumb pushed a commit to gashcrumb/origin that referenced this pull request Apr 15, 2016
…obile-dropdown

Update nav-mobile-dropdown to use new extensions
deads2k referenced this pull request in deads2k/origin May 17, 2016
ncdc pushed a commit to ncdc/origin that referenced this pull request Mar 27, 2017
REVIEW: UPSTREAM: 00000: k8s.io/apiserver: accept unversioned core gr…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants