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