Category: Containers

Kubernetes Questions – Please answer them

What is the Difference between a Persistent Volume and a Storage Class?

What happens when pods are killed, is the data persisted - How do you test this?

What is the difference between a Service and an Ingress?

By default, Docker uses host-private networking, so containers can talk to other containers only if they are on the same machine.

If you check the pod ip and there is an open containerPort then you should be able to access it via the node - with curl.

What happens when a node dies? The pods die with it, and the Deployment will create new ones, with different IPs. This is the problem a Service solves.

A Kubernetes Service is an abstraction which defines a logical set of Pods running somewhere in your cluster, that all provide the same functionality

When created, each Service is assigned a unique IP address (also called clusterIP)

This address is tied to the lifespan of the Service, and will not change while the Service is alive

communication to the Service will be automatically load-balanced

  • targetPort: is the port the container accepts traffic on
  • port: is the abstracted Service port, which can be any port other pods use to access the Service

Note that the Service IP is completely virtual, it never hits the wire

Kubernetes supports 2 primary modes of finding a Service - environment variables and DNS - DNS requires a COreDNS addon

Ingress is...

An API object that manages external access to the services in a cluster, typically HTTP

How do you know the size of the PV's to create for the PVC's of a helm chart?

Are helm chart declarative or imperitive?

What is a kubernetes operator?

How do you start a new mysql docker container with an existing data directory?

Usage against an existing databaseIf you start your mysql container instance with a data directory that already contains a database (specifically, a mysql subdirectory), the $MYSQL_ROOT_PASSWORD variable should be omitted from the run command line; it will in any case be ignored, and the pre-existing database will not be changed in any way.

The above did not work for me.

trademate-db_1   | Initializing database
trademate-db_1   | 2020-01-16T05:59:38.689547Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
trademate-db_1   | 2020-01-16T05:59:38.690778Z 0 [ERROR] --initialize specified but the data directory has files in it. Aborting.
trademate-db_1   | 2020-01-16T05:59:38.690818Z 0 [ERROR] Aborting
trademate-db_1   | 
trademate_trademate-db_1 exited with code 1

How do you view the contents of a docker volume?

You can't do this without a container for named volumes (the one's docker manages). So kak...

How do you run python debugger and attach inside a docker container?

Its a mess up...just develop locally

If you were mounting a conf file into an nginx image from docker-compose - how do you do that in production? Do you bake it into the image?

Yes you should.

Do something like this:

FROM nginx:1.17

COPY ./config/nginx/conf.d /etc/nginx/conf.d

# Remove default config
RUN rm /etc/nginx/conf.d/default.conf 

How do you deploy all the k8s spec files in a folder at once? If not is there a specific order to deploy them in?

This Service should exists before the replicas - as it adds environment variables to containers on the pods in the replicaset based on services created.

Should gunicorn and nginx containers be in the same pod?

Alpine Python Docker Base image problem with gcc

An important thing to do with process based containers or any container is to keep them slim and ensure that only what is necessary is packaged into the image.

For that reason I went with the python:3.8-alpine base image. After all was said and done the size of the resulting image was 208MB.

No GCC in that Base Image

Although I needed another python package and this package needed gcc, as shown by this error message in the build process:

    running build_ext
    building 'Cryptodome.Hash._MD2' extension
    creating build/temp.linux-x86_64-3.8
    creating build/temp.linux-x86_64-3.8/src
    gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -DTHREAD_STACK_SIZE=0x100000 -fPIC -DPYCRYPTO_LITTLE_ENDIAN -DSYS_BITS=64 -DLTC_NO_ASM -Isrc/ -I/usr/local/include/python3.8 -c src/MD2.c -o build/temp.linux-x86_64-3.8/src/MD2.o
    unable to execute 'gcc': No such file or directory
    error: command 'gcc' failed with exit status 1

The Wasteful Solution

There is an easy way to fix this problem...use a base image that has gcc prepackaged. I used python:3.8 and it just worked.

However that came at a price, the image was now 1.12GB in size.

So I looked around and it seemed ok to just install gcc with apk.


The Ideal Solution

I reverted back to using python:3.8-alpine and installed gcc and my dependencies in one line:

RUN apk add --no-cache --virtual .build-deps gcc musl-dev \
    && pip install --no-cache-dir -r /code/requirements.txt \
    && apk del .build-deps

Now the image built correctly and the size was 301MB


The ideal solution might not even be this though, as there is the suggestion of multi-stage builds. A Docker image just to build the project and a seperate image just to run.

Batteries Included

I think it comes down to batteries included or not.

I'm also not a fan of having too many commands in your dockerfile, it feels too sysadminy.

But use you descretion - horses for courses.