Permit Consul Connect Gateways to be used with podman (#20611)

* Permit Consul Connect Gateways to be used with podman

Enable use of Consul Connect Gateways (ingresss/terminating/mesh)
with podman task driver.

task driver for Connect-enabled tasks for sidecar services which
used podman if any other task in the same task group was using podman
or fell back to docker otherwise.

That PR did not consider consul connect gateways, which remained
hardcoded to using docker task driver always.

This change applies the same heuristic also to gateway tasks,
enabling use of podman.

Limitations: The heuristic only works where the task group containing
the gateway also contains a podman task. Therefore it does not work
for the ingress example in the docs
(https://developer.hashicorp.com/nomad/docs/job-specification/gateway#ingress-gateway)
which uses connect native and requires the gateway be in a separate task.

* cl: add cl for connect gateway podman autodetect

* connect: add test ensuring we guess podman for gateway when possible

---------

Co-authored-by: Seth Hoenig <shoenig@duck.com>
This commit is contained in:
Ben Roberts
2024-05-17 15:26:09 +01:00
committed by GitHub
parent e9d6c39dba
commit a6f6384b71
3 changed files with 44 additions and 11 deletions

3
.changelog/20611.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:improvement
consul/connect: Attempt autodetection of podman task driver for Connect gateways
```

View File

@@ -375,7 +375,7 @@ func groupConnectHook(job *structs.Job, g *structs.TaskGroup) error {
customizedTLS := service.Connect.IsCustomizedTLS()
task := newConnectGatewayTask(prefix, service.Name,
service.GetConsulClusterName(g), netHost, customizedTLS)
service.GetConsulClusterName(g), groupConnectGuessTaskDriver(g), netHost, customizedTLS)
g.Tasks = append(g.Tasks, task)
// the connect.sidecar_task block can also be used to configure
@@ -494,7 +494,7 @@ func gatewayBindAddressesIngressForBridge(ingress *structs.ConsulIngressConfigEn
return addresses
}
func newConnectGatewayTask(prefix, service, cluster string, netHost, customizedTls bool) *structs.Task {
func newConnectGatewayTask(prefix, service, cluster string, driver string, netHost, customizedTls bool) *structs.Task {
constraints := structs.Constraints{
connectGatewayVersionConstraint(cluster),
connectListenerConstraint(cluster),
@@ -506,7 +506,7 @@ func newConnectGatewayTask(prefix, service, cluster string, netHost, customizedT
// Name is used in container name so must start with '[A-Za-z0-9]'
Name: fmt.Sprintf("%s-%s", prefix, service),
Kind: structs.NewTaskKind(prefix, service),
Driver: "docker",
Driver: driver,
Config: connectGatewayDriverConfig(netHost),
ShutdownDelay: 5 * time.Second,
LogConfig: &structs.LogConfig{

View File

@@ -201,7 +201,7 @@ func TestJobEndpointConnect_groupConnectHook_IngressGateway_BridgeNetwork(t *tes
expTG.Tasks = []*structs.Task{
// inject the gateway task
newConnectGatewayTask(structs.ConnectIngressPrefix, "my-gateway",
structs.ConsulDefaultCluster, false, true),
structs.ConsulDefaultCluster, "docker", false, true),
}
expTG.Services[0].Name = "my-gateway"
expTG.Tasks[0].Canonicalize(job, expTG)
@@ -241,7 +241,7 @@ func TestJobEndpointConnect_groupConnectHook_IngressGateway_HostNetwork(t *testi
expTG.Tasks = []*structs.Task{
// inject the gateway task
newConnectGatewayTask(structs.ConnectIngressPrefix, "my-gateway",
structs.ConsulDefaultCluster, true, false),
structs.ConsulDefaultCluster, "docker", true, false),
}
expTG.Services[0].Name = "my-gateway"
expTG.Tasks[0].Canonicalize(job, expTG)
@@ -258,6 +258,36 @@ func TestJobEndpointConnect_groupConnectHook_IngressGateway_HostNetwork(t *testi
require.Exactly(t, expTG, job.TaskGroups[0])
}
func TestJobEndpointConnect_groupConnectHook_IngressGateway_GuessPodman(t *testing.T) {
ci.Parallel(t)
// Test that the injected gateway task makes use of the podman driver if there
// is another task in the group that uses podman.
job := mock.ConnectIngressGatewayJob("Host", false)
job.Meta = map[string]string{"gateway_name": "my-gateway"}
job.TaskGroups[0].Services[0].Name = "${NOMAD_META_gateway_name}"
// setup a task using podman
job.TaskGroups[0].Tasks = []*structs.Task{{
Name: "mytask",
Driver: "podman",
Config: make(map[string]interface{}),
}}
expTG := job.TaskGroups[0].Copy()
expTG.Tasks = append(expTG.Tasks,
newConnectGatewayTask(structs.ConnectIngressPrefix, "my-gateway",
structs.ConsulDefaultCluster, "podman", false, false),
)
expTG.Services[0].Name = "my-gateway"
expTG.Tasks[1].Canonicalize(job, expTG)
expTG.Networks[0].Canonicalize()
expTG.Services[0].Connect.Gateway.Proxy = gatewayProxy(expTG.Services[0].Connect.Gateway, "host")
must.NoError(t, groupConnectHook(job, job.TaskGroups[0]))
must.Eq(t, expTG, job.TaskGroups[0])
}
func TestJobEndpointConnect_groupConnectHook_IngressGateway_CustomTask(t *testing.T) {
ci.Parallel(t)
@@ -344,7 +374,7 @@ func TestJobEndpointConnect_groupConnectHook_TerminatingGateway(t *testing.T) {
expTG.Tasks = []*structs.Task{
// inject the gateway task
newConnectGatewayTask(structs.ConnectTerminatingPrefix, "my-gateway",
structs.ConsulDefaultCluster, false, false),
structs.ConsulDefaultCluster, "docker", false, false),
}
expTG.Services[0].Name = "my-gateway"
expTG.Tasks[0].Canonicalize(job, expTG)
@@ -379,7 +409,7 @@ func TestJobEndpointConnect_groupConnectHook_MeshGateway(t *testing.T) {
expTG.Tasks = []*structs.Task{
// inject the gateway task
newConnectGatewayTask(structs.ConnectMeshPrefix, "my-gateway",
structs.ConsulDefaultCluster, false, false),
structs.ConsulDefaultCluster, "docker", false, false),
}
expTG.Services[0].Name = "my-gateway"
expTG.Services[0].PortLabel = "public_port"
@@ -770,7 +800,7 @@ func TestJobEndpointConnect_newConnectGatewayTask_host(t *testing.T) {
t.Run("ingress", func(t *testing.T) {
task := newConnectGatewayTask(structs.ConnectIngressPrefix, "foo",
structs.ConsulDefaultCluster, true, false)
structs.ConsulDefaultCluster, "docker", true, false)
must.Eq(t, "connect-ingress-foo", task.Name)
must.Eq(t, "connect-ingress:foo", string(task.Kind))
must.Eq(t, "${attr.consul.version}", task.Constraints[0].LTarget)
@@ -781,7 +811,7 @@ func TestJobEndpointConnect_newConnectGatewayTask_host(t *testing.T) {
t.Run("terminating", func(t *testing.T) {
task := newConnectGatewayTask(structs.ConnectTerminatingPrefix, "bar",
structs.ConsulDefaultCluster, true, false)
structs.ConsulDefaultCluster, "docker", true, false)
must.Eq(t, "connect-terminating-bar", task.Name)
must.Eq(t, "connect-terminating:bar", string(task.Kind))
must.Eq(t, "${attr.consul.version}", task.Constraints[0].LTarget)
@@ -793,7 +823,7 @@ func TestJobEndpointConnect_newConnectGatewayTask_host(t *testing.T) {
// this case can only happen on ENT but gets run in CE code
t.Run("terminating nondefault (ENT)", func(t *testing.T) {
task := newConnectGatewayTask(structs.ConnectTerminatingPrefix, "bar",
"nondefault", true, false)
"nondefault", "docker", true, false)
must.Eq(t, "connect-terminating-bar", task.Name)
must.Eq(t, "connect-terminating:bar", string(task.Kind))
must.Eq(t, "${attr.consul.nondefault.version}", task.Constraints[0].LTarget)
@@ -807,7 +837,7 @@ func TestJobEndpointConnect_newConnectGatewayTask_bridge(t *testing.T) {
ci.Parallel(t)
task := newConnectGatewayTask(structs.ConnectIngressPrefix, "service1",
structs.ConsulDefaultCluster, false, false)
structs.ConsulDefaultCluster, "docker", false, false)
require.NotContains(t, task.Config, "network_mode")
}