Search code examples
kubernetescontainersopenshiftkubernetes-podopenshift-3

Init container in openshift


I am new to openshift, I have gone through Openshift website for more details but wanted to know if anyone has deployed init container. I want to use that to take dump from database and restore it to new version of it with the help of init container We are using postgres database

Any help would be appreciated.

Thanks!


Solution

  • I want to use that to take dump from database and restore it to new version of it with the help of init container

    I would say you should rather use the operator instead of initContainer. Take a look at below Init Containers Design Considerations

    There are some considerations that you should take into account when you create initcontainers:

    • They always get executed before other containers in the Pod. So, they shouldn’t contain complex logic that takes a long time to complete. Startup scripts are typically small and concise. If you find that you’re adding too much logic to init containers, you should consider moving part of it to the application container itself.
    • Init containers are started and executed in sequence. An init container is not invoked unless its predecessor is completed successfully. Hence, if the startup task is very long, you may consider breaking it into a number of steps, each handled by an init container so that you know which steps fail.
    • If any of the init containers fail, the whole Pod is restarted (unless you set restartPolicy to Never). Restarting the Pod means re-executing all the containers again including any init containers. So, you may need to ensure that the startup logic tolerates being executed multiple times without causing duplication. For example, if a DB migration is already done, executing the migration command again should just be ignored.
    • An init container is a good candidate for delaying the application initialization until one or more dependencies are available. For example, if your application depends on an API that imposes an API request-rate limit, you may need to wait for a certain time period to be able to receive responses from that API. Implementing this logic in the application container may be complex; as it needs to be combined with health and readiness probes. A much simpler way would be creating an init container that waits until the API is ready before it exits successfully. The application container would start only after the init container has done its job successfully.
    • Init containers cannot use health and readiness probes as application containers do. The reason is that they are meant to start and exit successfully, much like how Jobs and CronJobs behave.
    • All containers on the same Pod share the same Volumes and network. You can make use of this feature to share data between the application and its init containers.

    The only thing I found about using it for dumping data is this example about doing that with mysql, maybe it can guide you how to do it with postgresql.

    In this scenario, we are serving a MySQL database. This database is used for testing an application. It doesn’t have to contain real data, but it must be seeded with enough data so that we can test the application's query speed. We use an init container to handle downloading the SQL dump file and restore it to the database, which is hosted in another container. This scenario can be illustrated as below:

    enter image description here

    The definition file may look like this:

    apiVersion: v1
    kind: Pod
    metadata:
      name: mydb
      labels:
        app: db
    spec:
      initContainers:
        - name: fetch
          image: mwendler/wget
          command: ["wget","--no-check-certificate","https://sample-videos.com/sql/Sample-SQL-File-1000rows.sql","-O","/docker-entrypoint-initdb.d/dump.sql"]
          volumeMounts:
            - mountPath: /docker-entrypoint-initdb.d
              name: dump
      containers:
        - name: mysql
          image: mysql
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "example"
          volumeMounts:
            - mountPath: /docker-entrypoint-initdb.d
              name: dump
      volumes:
        - emptyDir: {}
          name: dump
    

    The above definition creates a Pod that hosts two containers: the init container and the application one. Let’s have a look at the interesting aspects of this definition:

    The init container is responsible for downloading the SQL file that contains the database dump. We use the mwendler/wget image because we only need the wget command. The destination directory for the downloaded SQL is the directory used by the MySQL image to execute SQL files (/docker-entrypoint-initdb.d). This behavior is built into the MySQL image that we use in the application container. The init container mounts /docker-entrypoint-initdb.d to an emptyDir volume. Because both containers are hosted on the same Pod, they share the same volume. So, the database container has access to the SQL file placed on the emptyDir volume.


    Additionally for best practices I would suggest to take a look at kubernetes operators, as far as I know that's the best practice way to menage databases in kubernetes.

    If you're not familiar with operators I would suggest to start with kubernetes documentation and this short video on youtube.

    Operators are methods of packaging Kubernetes that enable you to more easily manage and monitor stateful applications. There are many operators already available, such as the

    which automates and simplifies deploying and managing open source PostgreSQL clusters on Kubernetes by providing the essential features you need to keep your PostgreSQL clusters up and running.