14

I am running my CI/CD pipeline in Google cloud build. My app has web and wget containers. I am trying to reach web from wget

Cloud build internally used cloudbuild bridge network while starting containers as steps. So I am expecting these steps to communicate using names. But its failing.

If I create my own docker bridge netwok then they communicating.

I want to know why cloudbuild network is not working as expected.

Please let me know if you know any other ways to establish communication between step containers.

cloudbuild.yaml

steps:

- name: 'gcr.io/cloud-builders/docker'
  id: Web server
  args: ["run", "-d", "--name", "mani", "manikantanr/hostname_ip"]

- name: 'gcr.io/cloud-builders/wget'
  id: wget web mani:8000
  args: ["-qO-", "http://mani:8000"]

To understand the cloudbuild internals I used few docker commands.

debug-cloudbuild.yaml

steps:

- name: 'gcr.io/cloud-builders/docker'
  id: Docker Version
  args: ["version"]

- name: 'gcr.io/cloud-builders/docker'
  id: Docker info
  args: ["info"]

- name: 'gcr.io/cloud-builders/docker'
  id: Docker volume ls
  args: ["volume", "ls"]

- name: 'gcr.io/cloud-builders/docker'
  id: Docker volume inspect homevol
  args: ["volume", "inspect", "homevol"]


- name: 'gcr.io/cloud-builders/docker'
  id: Docker network ls
  args: ["network", "ls"]

- name: 'gcr.io/cloud-builders/docker'
  id: Docker network inspect cloudbuild
  args: ["network", "inspect", "cloudbuild"]

- name: 'gcr.io/cloud-builders/docker'
  id: Docker ps before
  args: ["container", "ls", "--no-trunc"]

- name: 'gcr.io/cloud-builders/docker'
  id: Web server
  args: ["run", "-d", "--name", "mani", "manikantanr/hostname_ip"]
  # waitFor: ['-']

- name: 'gcr.io/cloud-builders/wget'
  id: wget ipinfo
  args: ["-qO-", "https://ipinfo.io"]

- name: 'gcr.io/cloud-builders/docker'
  id: Docker ps after
  args: ["container", "ls", "--no-trunc"]

- name: 'gcr.io/cloud-builders/docker'
  id: Docker inspect mani host network
  args: ["inspect", "mani"]

- name: 'gcr.io/cloud-builders/docker'
  id: Docker alpine ifconfig inside container
  args: ["run", "alpine", "ifconfig"]

- name: 'gcr.io/cloud-builders/wget'
  id: wget mani:8000
  args: ["-qO-", "http://mani:8000"]
manikantanr
  • 506
  • 3
  • 10
  • I think Cloud Builder runners are pretty basics and they are not intended to run web servers inside. Why do you want to do that? Unit test that requires external service? – Yann C. Aug 28 '18 at 07:14
  • 1
    Usually I use unit tests with mocks for external services. But this time I have a usecase where I had to test with real db containers.So I created a `Postgres` and `Oracle Db`s in new docker network in detached mode. Then started `web` container in same network to communicate with them. – manikantanr Aug 28 '18 at 07:22
  • I am looking for a clean way to do this without a sepearate docker network. I tried starting containers with `cloudbuild` and `host` networks. – manikantanr Aug 28 '18 at 07:24
  • 1
    Cloud build is starting containers with names `steps-x` but these are not reachable from other steps. – manikantanr Aug 28 '18 at 07:26
  • What did you end up doing? I'm experiencing the same problem, except that it doesn't even work when I define the network myself, and this is infinitely frustrating! – Ola Vikholt Mar 12 '20 at 21:53
  • @OlaVikholt I used docker-compose. Started one service with `-d` and execute my test in another service. – manikantanr Mar 14 '20 at 17:02
  • what would `-d` stands for? I am having a similar issue: https://stackoverflow.com/questions/63721400/is-it-possible-to-start-pubsub-emulator-from-cloud-build-step – Emixam23 Sep 03 '20 at 14:08

3 Answers3

5

I had a similar issue setting up integration tests on cloud build. I was trying to run integration tests from another builder (go-builder) against my other containers (started through docker-compose community built containers).

Without specifying any networks on docker-compose.yaml, all containers are started on the default network (https://docs.docker.com/compose/networking/). On cloud build, it creates a new network named cloudbuild_default and places all my containers there. By forcing all containers to join cloudbuild network through my docker-compose.yaml file, I was able to establish communications and run my tests against them.

#docker-compose.yaml

networks:
  default:
    external:
      name: cloudbuild

This might be an alternate configuration for you. Hope it helps

  • 1
    Were you still able to access your service as the OP is showing using the container's name? E.g. just at `http://:`? – pappy-o Sep 25 '18 at 14:24
2

From the docs:

Each build step is run with its container attached to a local Docker network named cloudbuild. This allows build steps to communicate with each other and share data.

You can use docker compose and using cloudbuild network, for example:

#docker-compose.yml
app-workspace:
  ...
  network_mode: cloudbuild
db-mysql:
  ...
  network_mode: cloudbuild
...
networks:
  default:
    external:
      name: cloudbuild

Or if you are using docker run, add option --network cloudbuild.

After that, you can communicate to other services you defined in the previous step as you expect. For example:

#steps
- id: 'Ping to other container'
  name: gcr.io/cloud-builders/curl
  args: ["app-workspace:your-service-port"]

Hope this helps.

Andy
  • 16,265
  • 9
  • 48
  • 69
0

I did an experiment and it looks like (without doing any special setup) you can communicate between build step containers by using the name step_x (0-based numbering).

For example if you have a web-server listening on the endpoint /hello (on port 8081) in the container for the first build step (step_0). You can make requests to that endpoint from another build step container by making a request to http://step_0:8081/hello.

Mark Pevec
  • 81
  • 1
  • 9
  • I tried same thing 3 months ago. I too tried the container hostname `step_x` to connect one container from another. But it did not work as you said. I'm not sure I did everything right then. But I tested the same by creating another network and started my steps in that network, then they were able to communicate. By default steps starts in the network called `cloudbuild` I tried starting containers in the same network, even this didn't help. – manikantanr Dec 01 '18 at 19:31
  • 1
    I just did a test where I ran this step first: `- name: gcr.io/cloud-builders/docker` `args: ['network', 'create', 'cloudbuild-net']` then if I run the other step containers in that network via option: `--network cloudbuild-net` I'm able to get all the step containers to talk to each other based on their names – Mark Pevec Dec 04 '18 at 16:14
  • Would you happen to have an example? I'm struggling with this at the moment. – Jeff May 29 '19 at 16:23
  • 1
    Yes, here is a repo that was set up by someone doing a similar thing: https://github.com/Philmod/gcb-docker-compose – Mark Pevec May 30 '19 at 21:05