Skip to content

Commit c64d689

Browse files
authored
Merge pull request #1531 from sgaist/podman_in_k8s
Podman in k8s
2 parents 0049297 + 9558c28 commit c64d689

File tree

15 files changed

+336
-115
lines changed

15 files changed

+336
-115
lines changed

.github/workflows/test.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,20 @@ jobs:
161161
helm template --validate binderhub-test helm-chart/binderhub \
162162
--values tools/templates/lint-and-validate-values.yaml
163163
164+
- name: "Helm template --validate for dind (with lint-and-validate-values.yaml)"
165+
if: matrix.test == 'helm'
166+
run: |
167+
helm template --validate binderhub-test helm-chart/binderhub \
168+
--values tools/templates/lint-and-validate-values.yaml \
169+
--set imageBuilderType=dind
170+
171+
- name: "Helm template --validate for pink (with lint-and-validate-values.yaml)"
172+
if: matrix.test == 'helm'
173+
run: |
174+
helm template --validate binderhub-test helm-chart/binderhub \
175+
--values tools/templates/lint-and-validate-values.yaml \
176+
--set imageBuilderType=pink
177+
164178
- name: Validate the chart against the k8s API
165179
if: matrix.test == 'helm'
166180
run: |

.github/workflows/watch-dependencies.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ jobs:
2929
registry: registry.hub.docker.com
3030
repository: library/docker
3131
values_path: dind.daemonset.image.tag
32+
- name: podman
33+
registry: quay.io
34+
repository: podman/stable
35+
values_path: pink.daemonset.image.tag
3236

3337
# FIXME: After docker-image-cleaner 1.0.0 is released, we can enable
3438
# this. So far, there isn't any available stable release, and
@@ -59,7 +63,7 @@ jobs:
5963
run: |
6064
latest_tag=$(
6165
docker run --rm quay.io/skopeo/stable list-tags docker://${{ matrix.registry }}/${{ matrix.repository }} \
62-
| jq -r '[.Tags[] | select(. | match("^\\d+\\.\\d+\\.\\d+$") | .string)] | sort_by(split(".") | map(tonumber)) | last'
66+
| jq -r '[.Tags[] | select(. | match("^v?\\d+\\.\\d+\\.\\d+$") | .string)] | sort_by(split(".") | map(ltrimstr("v") | tonumber)) | last'
6367
)
6468
echo "tag=$latest_tag" >> $GITHUB_OUTPUT
6569

binderhub/build.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,12 @@ def _default_namespace(self):
259259
{}, help="Node selector for the kubernetes build pod.", config=True
260260
)
261261

262+
extra_envs = Dict(
263+
{},
264+
help="Extra environment variables for the kubernetes build pod.",
265+
config=True,
266+
)
267+
262268
log_tail_lines = Integer(
263269
100,
264270
help=(
@@ -380,7 +386,10 @@ def submit(self):
380386
)
381387
)
382388

383-
env = []
389+
env = [
390+
client.V1EnvVar(name=key, value=value)
391+
for key, value in self.extra_envs.items()
392+
]
384393
if self.git_credentials:
385394
env.append(
386395
client.V1EnvVar(name="GIT_CREDENTIAL_ENV", value=self.git_credentials)

binderhub/tests/test_build.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from tornado.httputil import url_concat
1414
from tornado.queues import Queue
1515

16-
from binderhub.build import Build, ProgressEvent
16+
from binderhub.build import Build, KubernetesBuildExecutor, ProgressEvent
1717
from binderhub.build_local import LocalRepo2dockerBuild, ProcessTerminated, _execute_cmd
1818

1919
from .utils import async_requests
@@ -241,6 +241,47 @@ def test_git_credentials_passed_to_podspec_upon_submit():
241241
assert env["GIT_CREDENTIAL_ENV"] == git_credentials
242242

243243

244+
def test_extra_environment_variables_passed_to_podspec_upon_submit():
245+
extra_environments = {
246+
"CONTAINER_HOST": "unix:///var/run/docker.sock",
247+
"REGISTRY_AUTH_FILE": "/root/.docker/config.json",
248+
}
249+
250+
mock_k8s_api = _list_image_builder_pods_mock()
251+
252+
class EnvBuild(KubernetesBuildExecutor):
253+
q = mock.MagicMock()
254+
api = mock_k8s_api
255+
name = "test_build"
256+
repo_url = "repo"
257+
ref = "ref"
258+
image_name = "name"
259+
extra_envs = extra_environments
260+
namespace = "build_namespace"
261+
push_secret = ""
262+
build_image = "image"
263+
memory_limit = 0
264+
docker_host = "http://mydockerregistry.local"
265+
node_selector = {}
266+
267+
build = EnvBuild()
268+
269+
with mock.patch.object(build.stop_event, "is_set", return_value=True):
270+
build.submit()
271+
272+
call_args_list = mock_k8s_api.create_namespaced_pod.call_args_list
273+
assert len(call_args_list) == 1
274+
275+
args = call_args_list[0][0]
276+
pod = args[1]
277+
278+
assert len(pod.spec.containers) == 1
279+
280+
env = {env_var.name: env_var.value for env_var in pod.spec.containers[0].env}
281+
282+
assert env == extra_environments
283+
284+
244285
async def test_local_repo2docker_build():
245286
q = Queue()
246287
repo_url = "https://github.com/binderhub-ci-repos/cached-minimal-dockerfile"

docs/source/zero-to-binderhub/setup-binderhub.rst

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ You now have a functioning BinderHub at the above IP address.
355355
Customizing your Deployment
356356
---------------------------
357357

358-
The Helm chart used to install your BinderHub deployemnt exposes a number of
358+
The Helm chart used to install your BinderHub deployment exposes a number of
359359
optional features. Below we describe a few of the most common customizations
360360
and how you can configure them.
361361

@@ -431,7 +431,7 @@ time at `the token administration page <https://github.com/settings/tokens>`_.
431431
GitLab
432432
^^^^^^
433433

434-
To access private GitLab repos, create an API token for your binderhub user
434+
To access private GitLab repos, create an API token for your BinderHub user
435435
under "User Settings" > "Access tokens". It at least needs the scopes "api" and
436436
"read_repository".
437437

@@ -452,20 +452,20 @@ clone a repo.
452452
Use Docker-inside-Docker (DinD)
453453
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
454454

455-
By default, BinderHub will build pods with the host Docker installation.
455+
By default, BinderHub will build images with the host Docker installation.
456456
This often means you are stuck with whatever version of Docker provided by your
457457
cloud provider. BinderHub supports an alternative that uses `Docker-in-Docker
458458
(DinD) <https://hub.docker.com/_/docker>`_. To turn `dind` on, you'll need to set
459459
the following configuration in your ``config.yaml`` file::
460460

461+
imageBuilderType: dind
461462
dind:
462-
enabled: true
463463
daemonset:
464464
image:
465465
name: docker
466466
tag: 18.09.2-dind
467467

468-
If you plan to host multiple BinderHub deployments on the same kubernetes
468+
If you plan to host multiple BinderHub deployments on the same Kubernetes
469469
cluster, you'll also need to isolate the host socket and library directory
470470
for each DinD application::
471471

@@ -474,4 +474,32 @@ for each DinD application::
474474
hostSocketDir: /var/run/dind/"<name of deployment, e.g. staging>"
475475

476476

477+
Use Podman-inside-Kubernetes (PinK)
478+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
479+
480+
In case Docker is not an option, Podman can be used as drop in replacement.
481+
Note that the implications about using a host installation of Podman are the same
482+
as with Docker. BinderHub supports an alternative that uses `Podman-in-Kubernetes
483+
(PinK) <https://www.redhat.com/sysadmin/podman-inside-kubernetes>`_. To turn
484+
`pink` on, you'll need to set the following configuration in your ``config.yaml`` file::
485+
486+
imageBuilderType: pink
487+
488+
You can optionally override the default podman image:
489+
490+
pink:
491+
daemonset:
492+
image:
493+
name: quay.io/podman/stable
494+
tag: v4.2.0
495+
496+
If you plan to host multiple BinderHub deployments on the same Kubernetes
497+
cluster, you'll also need to isolate the host socket and library directory
498+
for each DinD application::
499+
500+
pink:
501+
hostStorageDir: /var/lib/pink/"<name of deployment, e.g. staging>"
502+
hostSocketDir: /var/run/pink/"<name of deployment, e.g. staging>"
503+
504+
477505
For next steps, see :doc:`../debug` and :doc:`turn-off`.

helm-chart/binderhub/files/binderhub_config.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,12 @@ def get_value(key, default=None):
4646
for section, sub_cfg in get_value("config", {}).items():
4747
c[section].update(sub_cfg)
4848

49-
if get_value("dind.enabled", False) and get_value("dind.hostSocketDir"):
50-
c.BinderHub.build_docker_host = "unix://{}/docker.sock".format(
51-
get_value("dind.hostSocketDir")
52-
)
53-
49+
imageBuilderType = get_value("imageBuilderType")
50+
if imageBuilderType in ["dind", "pink"]:
51+
hostSocketDir = get_value(f"{imageBuilderType}.hostSocketDir")
52+
if hostSocketDir:
53+
socketname = "docker" if imageBuilderType == "dind" else "podman"
54+
c.BinderHub.build_docker_host = f"unix://{hostSocketDir}/{socketname}.sock"
5455

5556
if c.BinderHub.auth_enabled:
5657
hub_url = urlparse(c.BinderHub.hub_url)

helm-chart/binderhub/schema.yaml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ required:
2828
- jupyterhub
2929
- deployment
3030
- dind
31+
- pink
32+
- imageBuilderType
3133
- imageCleaner
3234
- ingress
3335
- initContainers
@@ -349,14 +351,21 @@ properties:
349351
See the [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)
350352
to learn more about labels.
351353
354+
imageBuilderType:
355+
type: string
356+
enum: ["local", "dind", "pink"]
357+
default: "local"
358+
description: |
359+
Selected image builder type
360+
352361
dind:
353362
type: object
354363
additionalProperties: false
355364
properties:
356365
enabled:
357366
type: boolean
358367
description: |
359-
TODO
368+
DEPRECATED: Use `imageBuilderType: dind`
360369
initContainers: &initContainers-spec
361370
type: array
362371
description: |
@@ -409,6 +418,29 @@ properties:
409418
description: |
410419
TODO
411420
421+
pink:
422+
type: object
423+
additionalProperties: false
424+
properties:
425+
initContainers: *initContainers-spec
426+
daemonset:
427+
type: object
428+
additionalProperties: false
429+
properties:
430+
image: *image-spec
431+
lifecycle: *lifecycle-spec
432+
extraVolumes: *extraVolumes-spec
433+
extraVolumeMounts: *extraVolumeMounts-spec
434+
resources: *resources-spec
435+
hostStorageDir:
436+
type: string
437+
description: |
438+
Host path where the containers storage will be located
439+
hostSocketDir:
440+
type: string
441+
description: |
442+
Host path where the podman socket will be located
443+
412444
imageCleaner:
413445
type: object
414446
additionalProperties: false

helm-chart/binderhub/templates/NOTES.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,14 @@ config:
182182
{{- $breaking = print $breaking "\n\nRENAMED: jupyterhub.custom.cors.allowOrigin has been renamed to jupyterhub.hub.config.BinderSpawner.cors_allow_origin" }}
183183
{{- end }}
184184

185+
{{- if hasKey .Values.dind "enabled" }}
186+
{{- $breaking = print $breaking "\n\nCHANGED:" }}
187+
{{- $breaking = print $breaking "\n\ndind:" }}
188+
{{- $breaking = print $breaking "\n enabled: true" }}
189+
{{- $breaking = print $breaking "\n\nmust as of version 0.3.0 be replace by" }}
190+
{{- $breaking = print $breaking "\n\nimageBuilderType: dind" }}
191+
{{- end }}
192+
185193
{{- if $breaking }}
186194
{{- fail (print $breaking_title $breaking) }}
187195
{{- end }}

0 commit comments

Comments
 (0)