mirror of
https://github.com/dokku/dokku.git
synced 2025-12-16 12:07:45 +01:00
feat: allow exposing non-web processes as kubernetes services
Closes #7204
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
- `autoscaling` (map of string to object, optional) autoscaling rules. See the autoscaling section for more details
|
||||
- `max_parallel`: (int, optional) number of instances to deploy in parallel at a given time
|
||||
- `quantity`: (int, optional) number of processes to maintain. Default 1 for web processes, 0 for all others.
|
||||
- `service`: (map of string to oject, optional) governs how non-web processes are exposed as services on the network
|
||||
|
||||
### Autoscaling
|
||||
|
||||
@@ -82,6 +83,24 @@ An autoscaling trigger consists of the following properties:
|
||||
- `type`: (string, optional)
|
||||
- `metadata`: (object, optional)
|
||||
|
||||
### Service
|
||||
|
||||
```json
|
||||
{
|
||||
"formation": {
|
||||
"internal-web": {
|
||||
"service": {
|
||||
"exposed": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
(object, optional) A key-value object specifying how to expose non-web processes as services.
|
||||
|
||||
- `service`: (boolean, optional) Whether to expose a process as a network service. The `PORT` variable will be set to 5000.
|
||||
|
||||
## Healthchecks
|
||||
|
||||
```json
|
||||
|
||||
@@ -232,6 +232,27 @@ The global default value may be set by passing an empty value for the option.
|
||||
dokku scheduler-k3s:set --global deploy-timeout
|
||||
```
|
||||
|
||||
### Exposing services on the network
|
||||
|
||||
Dokku will automatically expose the `web` process as a Kubernetes Service, with all others being treated as background processes. In some cases, it may be useful to have other processes exposed as Kubernetes Service objects so as to segregate internal http endpoints from public http endpoints. This can be done by modifying the `app.json` Formation entry for your process type.
|
||||
|
||||
```json
|
||||
{
|
||||
"formation": {
|
||||
"internal-web": {
|
||||
"service": {
|
||||
"exposed": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the above example, the `internal-web` process is exposed as a service. The `PORT` variable for the process will be set to `5000`, and a kubernetes `Service` object will be created pointing at your processes.
|
||||
|
||||
> [!NOTE]
|
||||
> It is not possible to modify the port mapping, nor is it possible to assign domains or SSL to a non-web process.
|
||||
|
||||
### SSL Certificates
|
||||
|
||||
#### Enabling letsencrypt integration
|
||||
|
||||
@@ -76,6 +76,16 @@ type Formation struct {
|
||||
|
||||
// MaxParallel is the maximum number of processes to start in parallel
|
||||
MaxParallel *int `json:"max_parallel"`
|
||||
|
||||
// Service is a struct that represents how to expose the process to the network
|
||||
// This only applies to non-web processes
|
||||
Service *FormationService `json:"service"`
|
||||
}
|
||||
|
||||
// FormationService is a struct that represents how to expose a process to the network
|
||||
type FormationService struct {
|
||||
// Exposed is whether or not the process is exposed as a service
|
||||
Exposed bool `json:"exposed"`
|
||||
}
|
||||
|
||||
// FormationAutoscaling is a struct that represents the autoscaling configuration for a process from an app.json file
|
||||
|
||||
@@ -64,7 +64,11 @@ spec:
|
||||
{{- if hasKey $config "web" }}
|
||||
env:
|
||||
- name: PORT
|
||||
{{- if eq $processName "web" }}
|
||||
value: "{{ $.Values.global.network.primary_port }}"
|
||||
{{- else }}
|
||||
value: "5000"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
envFrom:
|
||||
- secretRef:
|
||||
|
||||
@@ -623,6 +623,22 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e
|
||||
}
|
||||
|
||||
sort.Sort(NameSorter(processValues.Web.PortMaps))
|
||||
} else if appJSON.Formation[processType].Service != nil && appJSON.Formation[processType].Service.Exposed {
|
||||
processValues.Web = ProcessWeb{
|
||||
Domains: []ProcessDomains{},
|
||||
PortMaps: []ProcessPortMap{},
|
||||
TLS: ProcessTls{
|
||||
Enabled: false,
|
||||
},
|
||||
}
|
||||
|
||||
processValues.Web.PortMaps = append(processValues.Web.PortMaps, ProcessPortMap{
|
||||
ContainerPort: 5000,
|
||||
HostPort: 5000,
|
||||
Name: "http-5000-5000",
|
||||
Protocol: PortmapProtocol_TCP,
|
||||
Scheme: "http",
|
||||
})
|
||||
}
|
||||
|
||||
values.Processes[processType] = processValues
|
||||
|
||||
70
tests/unit/scheduler-k3s-4.bats
Normal file
70
tests/unit/scheduler-k3s-4.bats
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
TEST_APP="rdmtestapp"
|
||||
|
||||
setup() {
|
||||
uninstall_k3s || true
|
||||
global_setup
|
||||
dokku nginx:stop
|
||||
export KUBECONFIG="/etc/rancher/k3s/k3s.yaml"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
global_teardown
|
||||
dokku nginx:start
|
||||
uninstall_k3s || true
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s) app.json defined service" {
|
||||
if [[ -z "$DOCKERHUB_USERNAME" ]] || [[ -z "$DOCKERHUB_TOKEN" ]]; then
|
||||
skip "skipping due to missing docker.io credentials DOCKERHUB_USERNAME:DOCKERHUB_TOKEN"
|
||||
fi
|
||||
|
||||
INGRESS_CLASS=nginx install_k3s
|
||||
|
||||
run /bin/bash -c "dokku apps:create $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:scale $TEST_APP web=1 worker=1"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP inject_app_json
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "kubectl get services $TEST_APP-web -o json | jq -r '.spec.ports[0].port'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "80"
|
||||
|
||||
run /bin/bash -c "kubectl get services $TEST_APP-web -o json | jq -r '.spec.ports[0].targetPort'"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output "5000"
|
||||
}
|
||||
|
||||
inject_app_json() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
cat <<EOF >"$APP_REPO_DIR/app.json"
|
||||
{
|
||||
"formation": {
|
||||
"worker": {
|
||||
"service": {
|
||||
"exposed": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
Reference in New Issue
Block a user