[JIRA] (JENKINS-57382) Documentation advises use of legacy container link feature

5 views
Skip to first unread message

craig@2ndquadrant.com (JIRA)

unread,
May 9, 2019, 12:56:03 AM5/9/19
to jenkinsc...@googlegroups.com
Craig Ringer created an issue
 
Jenkins / Bug JENKINS-57382
Documentation advises use of legacy container link feature
Issue Type: Bug Bug
Assignee: Unassigned
Components: docker-workflow-plugin
Created: 2019-05-09 04:55
Priority: Minor Minor
Reporter: Craig Ringer

Docs recommend deprecated / legacy docker features

The docker-workflow-plugin documentation advises users to use the container link ("--link") feature in Docker and links to https://docs.docker.com/network/links/.

But the Docker documentation warns that this is a legacy feature that's not recommended. It recommends user defined networks. Where that's not possible the default "bridge" network, while considered legacy, is preferred to using container links.

The docs should not use the --link argument.

Simplify use of correct Docker inter-container connections in Jenkins

Code enhancements are not necessary to use the default bridge, but a container.getIpAddress() accessor would be very helpful. Without it the user's code must use docker inspect to get the container IP to connect to, as Docker doesn't do container-name resolving for the default bridge network:

docker.image("postgres:11").withRun("-e 5555:5432") {

  def postgres_ip = sh(
    script: "docker inspect -f {{.NetworkSettings.IPAddress}} ${c.id}",
    returnStdout: true)
  
  docker.image("myapp:latest").inside {
    sh("runMyApp --postgres-host ${postgres_ip} --postgres-port 5555")
  }

}

Natively support user defined networks

Even better we could natively support user-defined Docker networks with relatively small changes:

  • a docker.withNetwork(...) DSL call that creates a user defined network with arbitrary name and passes a Network object with getName() accessor to the inner closure, then cleans it up on closure exit. Like withRun etc.
  • All context-nested docker.withRun and docker.inside calls will use this network by default by automatically passing the --network argument to docker run

It'd be further improved by supporting these features:

  • A different network can be selected even within a withNetwork closure by passing a new network keyword argument to docker.withRun or docker.inside. This may be a string network name or a Network wrapper object.
  • docker.createNetwork(...), docker.rmNetwork(...) and docker.getNetwork wrappers for more complex use cases return and destroy Network objects. getNetwork can take a create bool arg to get create-if-not-exists semantics, and can be used to load existing user defined networks.
  • (maybe as sugar): A publish argument to withRun and inside so you don't have to fiddle with the docker argument list to expose port ranges.
Add Comment Add Comment
 
This message was sent by Atlassian Jira (v7.11.2#711002-sha1:fdc329d)

craig@2ndquadrant.com (JIRA)

unread,
May 9, 2019, 1:04:02 AM5/9/19
to jenkinsc...@googlegroups.com
Craig Ringer updated an issue
Change By: Craig Ringer
h3. Docs recommend deprecated / legacy docker features

The 
[ docker-workflow-plugin documentation for scripted pipeline multiple/sidecar container use|https://jenkins.io/doc/book/pipeline/docker/#running-sidecar-containers] advises users to use the container link ("--link") feature in Docker and links to [https://docs.docker.com/network/links/].


But the Docker documentation warns that this is a legacy feature that's not recommended. It recommends user defined networks. Where that's not possible the default "bridge" network, while considered legacy, is preferred to using container links.

The docs should not use the --link argument.

h3. Simplify use of correct Docker inter-container connections in Jenkins


Code enhancements are not necessary to use the default bridge, but a {{container.getIpAddress()}} accessor would be very helpful. Without it the user's code must use {{docker inspect}} to get the container IP to connect to, as Docker doesn't do container-name resolving for the default {{bridge}} network:

{noformat}

docker.image("postgres:11").withRun("-e 5555:5432") {

  def postgres_ip = sh(
    script: "docker inspect -f {{.NetworkSettings.IPAddress}} ${c.id}",
    returnStdout: true)
  
  docker.image("myapp:latest").inside {
    sh("runMyApp --postgres-host ${postgres_ip} --postgres-port 5555")
  }

}
{noformat}

h3. Natively support user defined networks


Even better we could natively support user-defined Docker networks with relatively small changes:

* a {{docker.withNetwork(...)}} DSL call that creates a user defined network with arbitrary name and passes a {{Network}} object with {{getName()}} accessor to the inner closure, then cleans it up on closure exit. Like {{withRun}} etc.
* All context-nested {{docker.withRun}} and {{docker.inside}} calls will use this network by default by automatically passing the {{--network}} argument to {{docker run}}


It'd be further improved by supporting these features:

* A different network can be selected even within a {{withNetwork}} closure by passing a new {{network}} keyword argument to {{docker.withRun}} or {{docker.inside}}. This may be a string network name or a {{Network}} wrapper object.
* {{docker.createNetwork(...)}}, {{docker.rmNetwork(...)}} and {{docker.getNetwork}} wrappers for more complex use cases return and destroy {{Network}} objects. {{getNetwork}} can take a {{create}} bool arg to get create-if-not-exists semantics, and can be used to load existing user defined networks.
* (maybe as sugar): A {{publish}} argument to {{withRun}} and {{inside}} so you don't have to fiddle with the docker argument list to expose port ranges.

craig@2ndquadrant.com (JIRA)

unread,
May 9, 2019, 1:19:02 AM5/9/19
to jenkinsc...@googlegroups.com
Craig Ringer updated an issue
h3. Docs recommend deprecated / legacy docker features

The [docker-workflow-plugin documentation for scripted pipeline multiple/sidecar container use|https://jenkins.io/doc/book/pipeline/docker/#running-sidecar-containers] advises users to use the container link ("--link") feature in Docker and links to [https://docs.docker.com/network/links/].

But the Docker documentation warns that this is a legacy feature that's not recommended. It recommends user defined networks. Where that's not possible the default "bridge" network, while considered legacy, is preferred to using container links.

The docs should not use the --link argument.

h3. Simplify use of correct Docker inter-container connections in Jenkins

Code enhancements are not necessary to use the default bridge, but a {{container.getIpAddress()}} accessor in {{org/jenkinsci/plugins/docker/workflow/Docker.groovy}}'s {{Container}} inner class would be very helpful. Without it the user's code must use {{docker inspect}} to get the container IP to connect to, as Docker doesn't do container-name resolving for the default {{bridge}} network:

{noformat}
docker.image("postgres:11").withRun("-
e p 5555:5432") { -> pgcontainer

  def postgres_ip = sh(
    script: "docker inspect -f {{.NetworkSettings.IPAddress}} ${
c pgcontainer .id}",

    returnStdout: true)
  
  docker.image("myapp:latest").inside {
    sh("runMyApp --postgres-host ${postgres_ip} --postgres-port 5555")
  }

}
{noformat}

h3. Natively support user defined networks

Even better we could natively support user-defined Docker networks with relatively small changes:

* a {{docker.withNetwork(...)}} DSL call that creates a user defined network with arbitrary name and passes a {{Network}} object with {{getName()}} accessor to the inner closure, then cleans it up on closure exit. Like {{withRun}} etc. Name is generated if not provided.
* All context-nested {{docker.withRun}} and {{docker.inside}} calls will use this network by default by automatically passing the {{--network}} argument to {{docker run}}
* A {{Container.getName(...)}} accessor in {{org/jenkinsci/plugins/docker/workflow/Docker.groovy}}'s {{Container}} inner class, for easy referencing containers by name whether generated or otherwise. (unless the resolver works with container-id, need to check}}

When using user-defined networks Docker creates a custom {{/etc/resolv.conf}} that points to its proxy nameserver, allowing other containers to be resolved by name. So you could then write the following code - which *does not currently work and is not implemented*:

{noformat}
docker.withNetwork {
  docker.image("postgres:11").withRun { -> pgcontainer
  
    docker.image("myapp:latest").inside {
      sh("runMyApp --postgres-host ${pgcontainer.name} --postgres-port 5432")
    }
  }
}
{noformat}

... and the Docker resolver will resolve {{pgcontainer.name}} to the right IP on the bridge network.

It'd be further improved by supporting these features:

* A different network can be selected even within a {{withNetwork}} closure by passing a new {{network}} keyword argument to {{docker.withRun}} or {{docker.inside}}. This may be a string network name or a {{Network}} wrapper object.
* {{docker.createNetwork(...)}}, {{docker.rmNetwork(...)}} and {{docker.getNetwork}} wrappers for more complex use cases return and destroy {{Network}} objects. {{getNetwork}} can take a {{create}} bool arg to get create-if-not-exists semantics, and can be used to load existing user defined networks.
* (maybe as sugar): A {{publish}} argument to {{withRun}} and {{inside}} so you don't have to fiddle with the docker argument list to expose port ranges.
Reply all
Reply to author
Forward
0 new messages