Skip to content

Commit f8ac5ef

Browse files
author
Ware, Joseph (DLSLtd,RAL,LSCI)
committed
Add docs for creating Helm resources
1 parent f9b1176 commit f8ac5ef

File tree

6 files changed

+172
-4
lines changed

6 files changed

+172
-4
lines changed

.github/workflows/_container.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,21 @@ jobs:
5858
push: true
5959
tags: ${{ steps.meta.outputs.tags }}
6060
labels: ${{ steps.meta.outputs.labels }}
61+
62+
{% if helm %}
63+
- name: Install Helm
64+
uses: Azure/setup-helm@v4
65+
id: install
66+
67+
- name: Log in to GitHub Container Registry
68+
if: github.ref_type == 'tag'
69+
run: |
70+
echo ${{ secrets.GITHUB_TOKEN }} | helm registry login ghcr.io/${{ github.repository }} --username ${{ github.repository_owner }} --password-stdin
71+
72+
- name: package chart and push it
73+
if: github.ref_type == 'tag'
74+
run: |
75+
helm dependencies update helm/{{ repo_name }}
76+
helm package helm/{{ repo_name }} --version ${{ steps.meta.outputs.version }} --app-version ${{ steps.meta.outputs.version }} -d /tmp/
77+
helm push /tmp/{{ repo_name }}-${{ steps.meta.outputs.version }}.tgz oci://ghcr.io/${{ github.repository_owner }}/charts
78+
{% end if %}

copier.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ docker:
103103
Would you like to publish your project in a Docker container?
104104
You should select this if you are making a service.
105105
106+
helm:
107+
type: bool
108+
when: "{{ github_org == 'DiamondLightSource' && docker}}"
109+
help: |
110+
Would you like to publish a Helm chart?
111+
You should select this if you are making a long-running service.
112+
This requires that releases use Semantic Versioning
113+
106114
docs_type:
107115
type: str
108116
help: |

docs/how-to/coverage.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
# How to check code coverage
32

43
Code coverage is reported to the command line and to a `cov.xml` file by the command `tox -e tests`. The file is uploaded to the Codecov service in CI.

docs/how-to/deploy-cluster.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# How to deploy containers to Kubernetes cluster
2+
3+
If your project is a service with a `Dockerfile`, you may wish to deploy it in a Kubernetes cluster.
4+
5+
## Creating a Helm chart
6+
7+
Helm bundles multiple Kubernetes resources into a single top level resource, `Chart`, and templates resources to inject specified `values`.
8+
9+
```
10+
service/
11+
├── Chart.yaml # Definition of the resource
12+
├── values.yaml # Defaults for templating
13+
├── charts/ # [Optionally] other charts to deploy with
14+
└── templates/ # Templated Kubernetes resources
15+
```
16+
17+
`templates/` may include at least:
18+
- `deployment.yaml`: creates a pod including your container image
19+
- `service.yaml`: manages Kubernetes networking, potentially exposing your service
20+
- `ingress.yaml`: optionally maps a DNS entry to the Kubernetes networking
21+
22+
Using `helm create` ensures your service is using the latest standards, therefore Helm resources are not included in this template.
23+
To avoid collisions and to maintain a neat repository, it is recommended to run `helm create <service name>` inside a directory named `helm/` in the root of your repository.
24+
25+
Assuming your container is published to the GitHub container registry, modify your `values.yaml` to deploy your built container.
26+
27+
```yaml
28+
image:
29+
repository: ghcr.io/<organisation>/<service>
30+
pullPolicy: Always
31+
# Overrides the image tag whose default is the chart appVersion.
32+
tag: ""
33+
```
34+
35+
The container will use the `ENTRYPOINT` and `CMD` defined in your `Dockerfile`.
36+
37+
It is recommended to preserve all of the templates within `templates/`: resources you do not need can be disabled from `values.yaml` while maintaining the ability to deploy or extend the chart.
38+
39+
## Enabling container debugging
40+
41+
The generated `Dockerfile` installs debugpy and with a few modifications can enable remote debugging of a service deployed inside a cluster.
42+
43+
Adding the following to your `values.yaml` gives a standard way of enabling/disabling debugging and documenting the configuration.
44+
45+
```yaml
46+
# Use `kubectl port forward` to access from your machine
47+
debug:
48+
# Whether the container should start in debug mode
49+
enabled: false
50+
# Whether to suspend the process until a debugger connects
51+
suspend: false
52+
# Port to listen for the debugger on
53+
port: 5678
54+
```
55+
56+
The `ENTRYPOINT` and `CMD` concepts in the Dockerfile are analogous to Kubernetes' `command` and `args`.
57+
If `command` is set, it overrides `ENTRYPOINT` and uses `args` if set, ignoring `CMD`.
58+
If `args` is set, `ENTRYPOINT` remains and `CMD` is replaced.
59+
60+
Assuming your `Dockerfile` contains the following, or analogous:
61+
62+
```Dockerfile
63+
ENTRYPOINT ["python"]
64+
CMD ["-m", "service", "--version"]
65+
```
66+
67+
Modifying `deployment.yaml` in the following way allows for your service to enable debugging via the configuration added to `values.yaml`.
68+
69+
```yaml
70+
containers:
71+
- ...
72+
args:
73+
{{- if .Values.debug.enabled}}
74+
- "-Xfrozen_modules=off"
75+
- "-m"
76+
- "debugpy"
77+
{{- if .Values.debug.suspend }}
78+
- "--wait-for-client"
79+
{{- end }}
80+
- "--listen"
81+
- "0.0.0.0:{{ .Values.debug.port }}"
82+
{{- end }}
83+
- "-m"
84+
- "service"
85+
- "--version"
86+
```
87+
88+
## Connecting to debug mode container
89+
90+
`kubectl port forward` forwards your development machine's port 5678 to the container's:
91+
92+
```sh
93+
$ kubectl get pods
94+
NAME READY STATUS RESTARTS AGE
95+
service 1/1 Running 0 (1h ago) 1h
96+
$ kubectl port forward pod/service 5678:5678
97+
Forwarding from 127.0.0.1:5678 -> 5678
98+
```
99+
100+
Check out the version of your service that was built into the container and configure your IDE to attach to a remote debugpy process:
101+
102+
The following is a launch configuration from VSCode `launch.json`.
103+
`"remoteRoot"` should match for the version of Python your `Dockerfile` is built from and use your service's name.
104+
`"justMyCode": False` was found to be required for breakpoints to be active.
105+
`"autoReload"` Configured hot swapping of code from your developer machine to the deployed instance.
106+
107+
> ⚠️ **Changes made by autoReload are not preserved.** Code changes made while debugging or resolving an issue should be committed, pushed and built into a new container as soon as possible.
108+
109+
110+
```json
111+
{
112+
"name": "Python Debugger: Remote Attach",
113+
"type": "debugpy",
114+
"request": "attach",
115+
"connect": {
116+
"host": "localhost",
117+
"port": 5678
118+
},
119+
"pathMappings": [
120+
{
121+
"localRoot": "${workspaceFolder}/src",
122+
"remoteRoot": "/venv/lib/<Python version>/site-packages/<service>"
123+
}
124+
],
125+
"justMyCode": false,
126+
"autoReload": {
127+
"enable": true,
128+
"exclude": [
129+
"**/.git/**",
130+
"**/__pycache__/**",
131+
"**/node_modules/**",
132+
"**/.metadata/**",
133+
"**/site-packages/**"
134+
],
135+
"include": [
136+
"**/*.py",
137+
"**/*.pyw"
138+
]
139+
}
140+
}
141+
```
142+

example-answers.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ component_lifecycle: experimental
66
description: An expanded https://github.com/DiamondLightSource/python-copier-template to illustrate how it looks with all the options enabled.
77
distribution_name: dls-python-copier-template-example
88
docker: true
9+
helm: false
910
docs_type: sphinx
1011
git_platform: github.com
1112
github_org: DiamondLightSource

template/Dockerfile.jinja

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ COPY --from=build /venv/ /venv/
2626
ENV PATH=/venv/bin:$PATH
2727

2828
# change CMD if it is not the same as the repo
29-
ENTRYPOINT ["python" "-m"]
29+
ENTRYPOINT ["python"]
3030
# Allows for modifying the ENTRYPOINT for debugging, e.g.
31-
#ENTRYPOINT ["python", "-m", "debugpy", "-m"]
32-
CMD ["{{ repo_name }}", "--version"]{% endif %}
31+
#ENTRYPOINT ["python", "-m", "debugpy"]
32+
CMD ["-m", "{{ repo_name }}", "--version"]{% endif %}

0 commit comments

Comments
 (0)