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

connect: use heuristic to detect sidecar task driver #17065

Merged
merged 2 commits into from May 5, 2023

Conversation

shoenig
Copy link
Member

@shoenig shoenig commented May 2, 2023

This PR adds a heuristic to detect whether to use the podman task driver
for the connect sidecar proxy. The podman driver will be selected if there
is at least one task in the task group configured to use podman, and there
are zero tasks in the group configured to use docker. In all other cases
the task driver defaults to docker.

After this change, we should be able to run typical Connect jobspecs
(e.g. nomad job init [-short] -connect) on Clusters configured with the
podman task driver, without modification to the job files.

Closes #17042

This PR adds a heuristic to detect whether to use the podman task driver
for the connect sidecar proxy. The podman driver will be selected if there
is at least one task in the task group configured to use podman, and there
are zero tasks in the group configured to use docker. In all other cases
the task driver defaults to docker.

After this change, we should be able to run typical Connect jobspecs
(e.g. nomad job init [-short] -connect) on Clusters configured with the
podman task driver, without modification to the job files.

Closes #17042
@shoenig
Copy link
Member Author

shoenig commented May 2, 2023

Spot check

nomad agent config
server {
  enabled = true
}

client {
  enabled = true

  options = {
    driver.allowlist = "podman"
  }
}

plugin_dir = "/home/shoenig/Go/podman/build"

plugin "nomad-driver-podman" {
}
job file
job "podcon" {

  group "api" {
    network {
      mode = "bridge"
    }

    service {
      name = "count-api"
      port = "9001"

      connect {
        sidecar_service {}
      }
    }

    task "web" {
      driver = "podman"

      config {
        image = "docker.io/hashicorpdev/counter-api:v3"
      }
    }
  }

  group "dashboard" {
    network {
      mode = "bridge"

      port "http" {
        static = 9002
        to     = 9002
      }
    }

    service {
      name = "count-dashboard"
      port = "9002"

      connect {
        sidecar_service {
          proxy {
            upstreams {
              destination_name = "count-api"
              local_bind_port  = 8080
            }
          }
        }
      }
    }

    task "dashboard" {
      driver = "podman"

      env {
        COUNTING_SERVICE_URL = "http://${NOMAD_UPSTREAM_ADDR_count_api}"
      }

      config {
        image = "docker.io/hashicorpdev/counter-dashboard:v3"
      }
    }
  }
}

start nomad and consul

➜ consul agent -dev
➜ sudo nomad agent -dev-connect -config=/home/shoenig/Work/agent.mix.hcl

plan is ok

➜ nomad job plan podcon.hcl
+ Job: "podcon"
+ Task Group: "api" (1 create)
  + Task: "connect-proxy-count-api" (forces create)
  + Task: "web" (forces create)

+ Task Group: "dashboard" (1 create)
  + Task: "connect-proxy-count-dashboard" (forces create)
  + Task: "dashboard" (forces create)

Scheduler dry-run:
- All tasks successfully allocated.

Job Modify Index: 0
To submit the job with version verification run:

nomad job run -check-index 0 podcon.hcl

When running the job with the check-index flag, the job will only be run if the
job modify index given matches the server-side version. If the index has
changed, another user has modified the job and the plan's results are
potentially invalid.

deployment ok

➜ nomad job run podcon.hcl
==> 2023-05-02T21:15:18Z: Monitoring evaluation "859d0de3"
    2023-05-02T21:15:18Z: Evaluation triggered by job "podcon"
    2023-05-02T21:15:19Z: Evaluation within deployment: "35a39ae8"
    2023-05-02T21:15:19Z: Allocation "7ff9e075" created: node "4d26c0cf", group "api"
    2023-05-02T21:15:19Z: Allocation "b3b163c5" created: node "4d26c0cf", group "dashboard"
    2023-05-02T21:15:19Z: Evaluation status changed: "pending" -> "complete"
==> 2023-05-02T21:15:19Z: Evaluation "859d0de3" finished with status "complete"
==> 2023-05-02T21:15:19Z: Monitoring deployment "35a39ae8"
  ✓ Deployment "35a39ae8" successful

    2023-05-02T21:15:30Z
    ID          = 35a39ae8
    Job ID      = podcon
    Job Version = 0
    Status      = successful
    Description = Deployment completed successfully

    Deployed
    Task Group  Desired  Placed  Healthy  Unhealthy  Progress Deadline
    api         1        1       1        0          2023-05-02T21:25:29Z
    dashboard   1        1       1        0          2023-05-02T21:25:29Z

@shoenig shoenig added this to the 1.6.0 milestone May 2, 2023
@shoenig shoenig marked this pull request as ready for review May 2, 2023 21:40
@shoenig shoenig requested review from schmichael and lgfa29 May 2, 2023 21:40
Copy link
Contributor

@lgfa29 lgfa29 left a comment

Choose a reason for hiding this comment

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

After this change, we should be able to run typical Connect jobspecs
(e.g. nomad job init [-short] -connect) on Clusters configured with the
podman task driver, without modification to the job files.

🥳

Comment on lines 240 to 254
func groupConnectGuessTaskDriver(g *structs.TaskGroup) string {
foundPodman := false
for _, task := range g.Tasks {
switch task.Driver {
case "docker":
return "docker"
case "podman":
foundPodman = true
}
}
if foundPodman {
return "podman"
}
return "docker"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

It's a simple function, so I hate to bikeshed on it 😅

But I found this logic a bit confusing to grok at first. I think we could instead have a task driver counter map and then something like this so it more explicitly matches the function docstring:

if numTasks["podman"] > 1 && numTasks["docker"] == 0 {
  return "podman"
}

return "docker"

Copy link
Member Author

Choose a reason for hiding this comment

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

How about

func groupConnectGuessTaskDriver(g *structs.TaskGroup) string {
    drivers := set.FromFunc(g.Tasks, func(t *structs.Task) string {
        return t.Driver
    })
    if drivers.Contains("podman") && !drivers.Contains("docker") {
        return "podman"
    }
    return "docker"
}

return &structs.Task{
// Name is used in container name so must start with '[A-Za-z0-9]'
Name: fmt.Sprintf("%s-%s", structs.ConnectProxyPrefix, service),
Kind: structs.NewTaskKind(structs.ConnectProxyPrefix, service),
Driver: "docker",
Driver: driver,
Config: connectSidecarDriverConfig(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be worth adding a docsting to connectSidecarDriverConfig() to note that it should be compatible with Docker and Podman?

Or maybe even pass the driver choice here. It can be ignored in the current implementation, but may be handy if there are conflicting configs between the drivers or we add support for other plugins.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added a comment; with a note about passing in the parameter one day if needed

@schmichael
Copy link
Member

@shoenig
Copy link
Member Author

shoenig commented May 5, 2023

Is there a doc we could update

yeah, let me cover that in another PR along with an e2e test

@shoenig shoenig merged commit 0c5070a into main May 5, 2023
20 checks passed
@shoenig shoenig deleted the connect-driver-heuristic branch May 5, 2023 15:19
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.

connect: simplify envoy sidecar when using podman
3 participants