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

feat: Reverse proxy lifecycle management and connectivity on Docker #1906

Merged
merged 40 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
3e2c856
Reverse proxy and its Traefik implementation.
laurentluce Dec 1, 2023
eb6594c
Bind docker socket and publish http/dashboard ports.
laurentluce Dec 1, 2023
1537d3b
Update docker resources cleanup check to take the reverse proxy conta…
laurentluce Dec 1, 2023
e9982ed
Connect and disconnect the reverse proxy to/from the enclave network.
laurentluce Dec 2, 2023
94d6d9b
Add the reverse proxy enclave network ip address to the list of alrea…
laurentluce Dec 3, 2023
128f2e4
Merge branch 'main' into laurent/traefik-container
laurentluce Dec 3, 2023
e5f396d
Connect reverse proxy to enclave networks at startup.
laurentluce Dec 4, 2023
005f2a9
Update Traefik port numbers.
laurentluce Dec 4, 2023
b93735e
Merge branch 'main' into laurent/traefik-container
laurentluce Dec 5, 2023
1b2d373
Update comments.
laurentluce Dec 5, 2023
ff2a518
Add reverse proxy circle ci test.
laurentluce Dec 5, 2023
f3162d0
Add reverse proxy test to workflow
laurentluce Dec 5, 2023
53686a4
Fix Traefik config template.
laurentluce Dec 6, 2023
1114c75
Debug info for the reverse proxy ci test.
laurentluce Dec 6, 2023
02a62b2
Fix run prepare testing docker include.
laurentluce Dec 6, 2023
f95e9c3
Working on fixing CI tests.
laurentluce Dec 6, 2023
a7b5525
Working on fixing CI tests.
laurentluce Dec 6, 2023
47ad28a
Working on fixing CI tests.
laurentluce Dec 6, 2023
fbf87d6
Working on fixing CI tests.
laurentluce Dec 6, 2023
6e75292
Working on fixing CI tests.
laurentluce Dec 6, 2023
89a598b
Working on fixing CI tests.
laurentluce Dec 6, 2023
4725287
Working on fixing CI tests.
laurentluce Dec 6, 2023
4b9650b
Working on fixing CI tests.
laurentluce Dec 6, 2023
e4d36d9
Give enough time to Traefik to discover the user service - Diable the…
laurentluce Dec 6, 2023
62163f3
Merge branch 'main' into laurent/traefik-container
laurentluce Dec 6, 2023
508bae7
Remove debug msgs.
laurentluce Dec 6, 2023
eaf423e
Linting.
laurentluce Dec 6, 2023
50c1400
Add reminder to re-enable the old enclave continuity ci test once thi…
laurentluce Dec 6, 2023
70b68f3
Clarify the reverse proxy ip addresses.
laurentluce Dec 7, 2023
ca0ad73
Use header instead of host for Traefik routing.
laurentluce Dec 7, 2023
4856979
Add reverse proxy engine restart test.
laurentluce Dec 7, 2023
e3e8a8c
Merge branch 'main' into laurent/traefik-container
laurentluce Dec 7, 2023
c68c167
Split the service port header into three headers: enclave uuid, servi…
laurentluce Dec 8, 2023
045622e
Sync oapi-codegen file headers
laurentluce Dec 8, 2023
df280b1
Update CI tests.
laurentluce Dec 8, 2023
645d187
Update headers to specify that those are short uuids.
laurentluce Dec 8, 2023
9b28968
Update headers to specify that those are short uuids.
laurentluce Dec 8, 2023
f12f1fd
Merge branch 'main' into laurent/traefik-container
laurentluce Dec 8, 2023
122df2f
Address Tedi's comments.
laurentluce Dec 8, 2023
eebbc51
Linting.
laurentluce Dec 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 83 additions & 7 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,19 @@ steps_prepare_testing_k8s_k3s: &steps_prepare_testing_k8s_k3s
command: "${KURTOSIS_BINPATH} gateway"
background: true

# Steps to prepare a job for Docker testing
laurentluce marked this conversation as resolved.
Show resolved Hide resolved
steps_prepare_testing_docker: &steps_prepare_testing_docker
steps:
- run: |
run_prepare_testing_docker: &run_prepare_testing_docker
- run:
name: Load the engine, apic and file artifacts images and start the engine
command: |
docker load -i "<< pipeline.parameters.workspace-with-cli-binary-and-images-mountpoint >>/<< pipeline.parameters.core-server-image-filename >>"
docker load -i "<< pipeline.parameters.workspace-with-cli-binary-and-images-mountpoint >>/<< pipeline.parameters.engine-server-image-filename >>"
docker load -i "<< pipeline.parameters.workspace-with-cli-binary-and-images-mountpoint >>/<< pipeline.parameters.file-artifacts-expander-image-filename >>"
- run: "${KURTOSIS_BINPATH} engine start --cli-log-level trace"
${KURTOSIS_BINPATH} engine start --cli-log-level trace

# Steps to prepare a job for Docker testing
steps_prepare_testing_docker: &steps_prepare_testing_docker
steps:
- <<: *run_prepare_testing_docker

# Run steps to dump kurtosis enclaves from docker
run_dump_kurtosis_enclaves: &run_dump_kurtosis_enclaves
Expand Down Expand Up @@ -116,6 +121,17 @@ abort_job_if_only_docs_changes: &abort_job_if_only_docs_changes
circleci-agent step halt
fi

abort_job_if_kubernetes_backend: &abort_job_if_kubernetes_backend
when:
condition:
and:
- equal: [ "kubernetes", << parameters.cli-cluster-backend >> ]
steps:
- run: circleci-agent step halt

abort_job: &abort_job
run: circleci-agent step halt

##############
# CircleCI
##############
Expand Down Expand Up @@ -216,6 +232,9 @@ parameters:
kurtosis-cluster-setting-abs-filepath:
type: string
default: "/home/circleci/.local/share/kurtosis/cluster-setting"
reverse-proxy-entrypoint-web-port:
type: string
default: "9730"



Expand Down Expand Up @@ -639,6 +658,9 @@ jobs:
test_old_enclave_continuity:
executor: ubuntu_vm
steps:
# TODO: Re-enable once Traefik has been released.
- <<: *abort_job
laurentluce marked this conversation as resolved.
Show resolved Hide resolved

- checkout

- <<: *abort_job_if_only_docs_changes
Expand Down Expand Up @@ -878,9 +900,9 @@ jobs:
equal: [ "docker", << parameters.cli-cluster-backend >> ]
steps:
- run:
name: "Verify only the engine container and logs aggregator remains after the clean"
name: "Verify only the engine, logs aggregator and reverse proxy remain after the clean"
command: |
if ! [ "$(docker container ls -a | tail -n+2 | wc -l)" -eq 2 ]; then
if ! [ "$(docker container ls -a | tail -n+2 | wc -l)" -eq 3 ]; then
docker container ls -a
false
fi
Expand All @@ -904,6 +926,48 @@ jobs:
false
fi

test_reverse_proxy:
executor: ubuntu_vm
parameters:
<<: *param_cli_cluster_backend
steps:
- <<: *abort_job_if_kubernetes_backend

- checkout

- <<: *abort_job_if_only_docs_changes

# Set up Kurtosis
- attach_workspace:
at: "<< pipeline.parameters.workspace-with-cli-binary-and-images-mountpoint >>"

- <<: *steps_install_go

- run: |
echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list
sudo apt update
sudo apt install kurtosis-cli curl
# We don't send metrics to avoid polluting our logs
- run: |
echo 'export KURTOSIS_BINPATH="<< pipeline.parameters.workspace-with-cli-binary-and-images-mountpoint >>/<< pipeline.parameters.cli-dist-home-relative-dirpath >>/<< pipeline.parameters.cli-linux-amd-64-binary-relative-filepath >>"' >> "${BASH_ENV}"
- run: "${KURTOSIS_BINPATH} analytics disable"

- <<: *run_prepare_testing_docker

# Start a service and send an http request to it via the reverse proxy
- run: |
${KURTOSIS_BINPATH} enclave add --name test-enclave
${KURTOSIS_BINPATH} service add test-enclave test1 httpd --ports http=http:80/tcp
enclave_uuid=$(${KURTOSIS_BINPATH} enclave inspect test-enclave | grep "^UUID:" | awk '{print $2}')
service_uuid=$(${KURTOSIS_BINPATH} enclave inspect test-enclave | tail -2 | awk '{print $1}')
# Give the reverse proxy enough time to discover the httpd user service
sleep 10
status_code=$(curl -I http://localhost:<< pipeline.parameters.reverse-proxy-entrypoint-web-port >> -H "Host: 80-$(echo $service_uuid)-$(echo $enclave_uuid)" | head -1 | awk '{print $2}')
if ! [ "${status_code}" -eq "200" ]; then
echo 'HTTP request status code returned is '${status_code}' instead of 200'
false
fi

test_ci_for_failure:
executor: ubuntu_vm
parameters:
Expand Down Expand Up @@ -1352,6 +1416,18 @@ workflows:
- build_files_artifacts_expander
<<: *filters_ignore_main

- test_reverse_proxy:
name: "Test reverse proxy against Docker"
cli-cluster-backend: "docker"
context:
- docker-user
requires:
- build_cli
- build_api_container_server
- build_engine_server
- build_files_artifacts_expander
<<: *filters_ignore_main

# -- Artifact-publishing jobs --------------------------------
- publish_kurtosis_sdk_rust:
context:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ package backend_creator
import (
"context"
"fmt"
"net"
"os"
"path"

"github.com/docker/docker/client"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/logs_collector_functions"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/reverse_proxy_functions"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_manager"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/docker_label_key"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/label_value_consts"
Expand All @@ -18,9 +23,6 @@ import (
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db/service_registration"
"github.com/kurtosis-tech/stacktrace"
"github.com/sirupsen/logrus"
"net"
"os"
"path"
)

const (
Expand Down Expand Up @@ -238,11 +240,21 @@ func getDockerKurtosisBackend(
return nil, stacktrace.Propagate(err, "An error occurred while getting the logs collector object for enclave '%v'; This is a bug in Kurtosis", enclaveUuid)
}

reverseProxy, err := reverse_proxy_functions.GetReverseProxy(ctx, dockerManager)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred while getting the reverse proxy, This is a bug in Kurtosis")
}
reverseProxyEnclaveNetworkIpAddress, found := reverseProxy.GetEnclaveNetworksIpAddress()[network.GetId()]
if !found {
return nil, stacktrace.NewError("An error occured while getting the reverse proxy enclave network IP address for enclave '%v', This is a bug in Kurtosis", enclaveUuid)
}

alreadyTakenIps := map[string]bool{
networkIp.String(): true,
network.GetGatewayIp(): true,
apiContainerIp.String(): true,
logsCollectorObj.GetEnclaveNetworkIpAddress().String(): true,
reverseProxyEnclaveNetworkIpAddress.String(): true,
}

freeIpAddrProvider, err := free_ip_addr_tracker.GetOrCreateNewFreeIpAddrTracker(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/logs_aggregator_functions/implementations/vector"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/logs_collector_functions"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/logs_collector_functions/implementations/fluentbit"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/reverse_proxy_functions"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/reverse_proxy_functions/implementations/traefik"
user_service_functions "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/user_services_functions"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_manager"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_manager/types"
Expand All @@ -27,6 +29,7 @@ import (
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_download_mode"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/logs_aggregator"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/logs_collector"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/reverse_proxy"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db/free_ip_addr_tracker"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db/service_registration"
Expand Down Expand Up @@ -471,6 +474,57 @@ func (backend *DockerKurtosisBackend) DestroyLogsCollectorForEnclave(ctx context
return nil
}

func (backend *DockerKurtosisBackend) CreateReverseProxy(ctx context.Context) (*reverse_proxy.ReverseProxy, error) {
reverseProxyContainer := traefik.NewTraefikReverseProxyContainer()

reverseProxy, _, err := reverse_proxy_functions.CreateReverseProxy(
ctx,
reverseProxyContainer,
backend.dockerManager,
backend.objAttrsProvider,
)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating the reverse proxy using the reverse proxy container '%+v'.", reverseProxyContainer)
}
return reverseProxy, nil
}

func (backend *DockerKurtosisBackend) GetReverseProxy(ctx context.Context) (*reverse_proxy.ReverseProxy, error) {
maybeReverseProxy, err := reverse_proxy_functions.GetReverseProxy(
laurentluce marked this conversation as resolved.
Show resolved Hide resolved
ctx,
backend.dockerManager,
)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred getting the reverse proxy")
}

return maybeReverseProxy, nil
}

func (backend *DockerKurtosisBackend) DestroyReverseProxy(ctx context.Context) error {
if err := reverse_proxy_functions.DestroyReverseProxy(ctx, backend.dockerManager); err != nil {
return stacktrace.Propagate(err, "An error occurred destroying the reverse proxy")
}

return nil
}

func (backend *DockerKurtosisBackend) ConnectReverseProxyToNetwork(ctx context.Context, networkId string) error {
if err := reverse_proxy_functions.ConnectReverseProxyToNetwork(ctx, backend.dockerManager, networkId); err != nil {
return stacktrace.Propagate(err, "An error occurred connecting the reverse proxy to the network with ID '%v'", networkId)
}

return nil
}

func (backend *DockerKurtosisBackend) DisconnectReverseProxyFromNetwork(ctx context.Context, networkId string) error {
if err := reverse_proxy_functions.DisconnectReverseProxyFromNetwork(ctx, backend.dockerManager, networkId); err != nil {
return stacktrace.Propagate(err, "An error occurred disconnecting the reverse proxy from the network with ID '%v'", networkId)
}

return nil
}

func (backend *DockerKurtosisBackend) GetAvailableCPUAndMemory(ctx context.Context) (compute_resources.MemoryInMegaBytes, compute_resources.CpuMilliCores, bool, error) {
availableMemory, availableCpu, err := backend.dockerManager.GetAvailableCPUAndMemory(ctx)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package docker_kurtosis_backend

import (
"context"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/docker_label_key"
"net"
"time"

"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/docker_label_key"

"github.com/docker/go-connections/nat"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/consts"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/shared_helpers"
Expand Down Expand Up @@ -73,14 +74,24 @@ func (backend *DockerKurtosisBackend) CreateAPIContainer(

enclaveLogsCollector, err := backend.GetLogsCollectorForEnclave(ctx, enclaveUuid)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred while getting the logs collector for enclave '%v; This is a bug in Kurtosis'", enclaveUuid)
return nil, stacktrace.Propagate(err, "An error occurred while getting the logs collector for enclave '%v'; This is a bug in Kurtosis", enclaveUuid)
}

reverseProxy, err := backend.GetReverseProxy(ctx)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred while getting the reverse proxy, This is a bug in Kurtosis")
}
reverseProxyEnclaveNetworkIpAddress, found := reverseProxy.GetEnclaveNetworksIpAddress()[enclaveNetwork.GetId()]
laurentluce marked this conversation as resolved.
Show resolved Hide resolved
if !found {
return nil, stacktrace.NewError("An error occured while getting the reverse proxy enclave network IP address for enclave '%v', This is a bug in Kurtosis", enclaveUuid)
}

networkCidr := enclaveNetwork.GetIpAndMask()
alreadyTakenIps := map[string]bool{
networkCidr.IP.String(): true,
enclaveNetwork.GetGatewayIp(): true,
enclaveLogsCollector.GetEnclaveNetworkIpAddress().String(): true,
reverseProxyEnclaveNetworkIpAddress.String(): true,
}

ipAddr, err := network_helpers.GetFreeIpAddrFromSubnet(alreadyTakenIps, networkCidr)
Expand Down
Loading