Score:0

How to have a multiple port app in the same GKE pod (using cli)?

in flag

Presentation

Working on an Elixir Umbrella app (a general app managing multiple app), I included two web app within the main one, each one with its own URL and port (admin.example.com:8081 && www.example.com:8080).

I recently deployed the app onto Google Kubernetes Engine, following this tutorial. Though I've had some problems from times to times, I managed to complete it and have one website online accessible (can't access the other).

Configuration

Here is the production Dockerfile

FROM elixir:alpine

ARG app_name=prod
ARG phoenix_subdir=.
ARG build_env=prod

ENV MIX_ENV=${build_env} TERM=xterm
WORKDIR /opt/app
RUN apk update --no-cache \
  && apk upgrade --no-cache \
  && apk add --update --no-cache nodejs npm make build-base openssl ncurses-libs libgcc libstdc++ \
  && mix local.rebar --force \
  && mix local.hex --force
COPY . .

RUN mix do deps.get, compile
RUN cd apps/admin/assets \
  && npm rebuild node-sass \
  && npm install \
  && ./node_modules/webpack/bin/webpack.js \
  && cd .. \
  && mix phx.digest

RUN cd apps/app/assets \
  && npm rebuild node-sass \
  && npm install \
  && ./node_modules/webpack/bin/webpack.js \
  && cd .. \
  && mix phx.digest
RUN mix release ${app_name} \
  && mv _build/${build_env}/rel/${app_name} /opt/release \
  && mv /opt/release/bin/${app_name} /opt/release/bin/start_server


FROM alpine:latest

ARG hello

RUN apk update --no-cache \
  && apk upgrade --no-cache \
  && apk --no-cache --update add ca-certificates openssl-dev bash openssl libc6-compat libgcc libstdc++ ncurses-libs \
  && apk add --no-cache --virtual .erlang-build gcc g++ libc-dev \
  && mkdir -p /usr/local/bin \
  && wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 \
  -O /usr/local/bin/cloud_sql_proxy \
  # && wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub \
  # && wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.33-r0/glibc-2.33-r0.apk \
  # && apk add --no-cache glibc-2.33-r0.apk \
  && chmod +x /usr/local/bin/cloud_sql_proxy \
  && mkdir -p /tmp/cloudsql
ENV GCLOUD_PROJECT_ID=${project_id} \
  REPLACE_OS_VARS=true
EXPOSE ${PORT}
EXPOSE 8081
WORKDIR /opt/app
COPY --from=0 /opt/release .
CMD (/usr/local/bin/cloud_sql_proxy \
  -projects=${GCLOUD_PROJECT_ID} -dir=/tmp/cloudsql &); \
  exec /opt/app/bin/start_server start

as well as the cloudbuild.yaml used by GKE to build the pod.

steps:
  name: "gcr.io/cloud-builders/docker"
  args: ["build", "-t", "gcr.io/next-borders-v1/prod:$_TAG",
       "--build-arg", "project_id=next-borders-v1", ".",
       "--file=./prod.Dockerfile"]
images: ["gcr.io/next-borders-v1/prod:$_TAG"]

With these two files in hand, I follow this set of commands to expose port 8080 (the web app), which worked:

gcloud builds submit --substitutions=_TAG=v0.2 .
kubectl run hello-web --image=gcr.io/${PROJECT_ID}/hello:v1 --port 8080
kubectl expose pod hello-web --type=LoadBalancer --port=80 --target-port=8080

But I couldn't access the admin app. So, I tried to expose multiple target-ports:

# Remove the actual service so it doesn't create an error saying it already exists
kubectl delete svc hello-web
kubectl expose pod hello-web --type=LoadBalancer --port=80,8080,8081 --target-port=8080,8081

And got an error.

Then I went back to try and expose multiple port and changing the target-port to the admin website (8081), which worked, though it still was just one website.

kubectl expose pod hello-web --type=LoadBalancer --port=80,8080,8081 --target-port=8081

I also added the IP in the DNS configuration, so I could try to access the apps through their designated URL (they includes a server which can filter through the URL request).

Questions

So, here are my few questions as a beginner: Can a GKE pod handle multiple port in one app? If yes, can I do it through the cli, and how? Or do I have to use a configuration file? If not, what is the best way? Two pods, one for the app and the other for the admin website?

Observation

There is actually a similar thread, but it doesn't talk about the GKE command line interface, and the tutorial I followed doesn't explain the configuration of file neither their usage. Would the configuration file be the solution, I have so far no clues about how to write it or use it.

Documentation I looked to try to find an answer

Edit

  • 2021/08/15
    • Add multiple target port try in the Configuration section
    • Add the port/website associated to the kubectl expose request in the Configuration section
jp flag
Yes, pods can expose multiple pods. From your description it is hard to tell what port you are missing. It is more common ot work with declarative manifests and not work with imperative cli commands when doing this.
Aridjar avatar
in flag
Thank you for your reply @Jonas . The missing port is a targeted-port (either 8080 (web app) or 8081 (admin website)). I edited the question to include a precision on the targeted-port as well as a command with multiple targeted-port I tried, but which didn't work.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.