Unable to run apt-get in docker mongo initdb script

10/23/2017

I am trying to run an app on minikube. In order to get mongo up, I am running

kubectl create configmap mongo-initdb --from-file=importdata.sh
kubectl apply -f mongo.yaml

with importdata.sh as:

mongo myapp-dev --eval "db.dropDatabase()"

apt-get update && apt-get install curl && apt-get install bzip2

curl https://cdn.filestackcontent.com/xxxxxxxx -o myapp-db.tar.bz2
bzip2 -dc myapp-db.tar.bz2 | tar xvf -
mongorestore --db myapp-dev myapp-dev

mongo myapp-dev --eval 'db.users.update({}, {$set: {hashedPassword: "fwaPwkoIpS4y4aWA+uljXWIlyjTxUzkU+IgK4+B8m+ZhyBrWwM/N/oGfUj0ERAcwnXCOImkOvbvDMH/BAmN8FA==", salt: "YfnL4jUxfbYY6Y3/w8P8KA=="}}, {multi: true})'
mongo myapp-dev --eval 'db.getCollection("users").dropIndex("bad_index1")'

and mongo.yaml as:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mongo
spec:
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - image: mongo:3.2
        name: mongo
        ports:
        - containerPort: 27017
        volumeMounts:
        - name: mongo-initdb
          mountPath: /docker-entrypoint-initdb.d
      volumes:
      - name: mongo-initdb
        configMap:
          name: mongo-initdb

My goal is to have mongo running with the proper data that I am curling from that url. However, when I check the logs with kubectl logs -f deploy/mongo I see the following:

/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/importdata.sh
MongoDB shell version: 3.2.17
connecting to: myapp-dev
2017-10-20T20:00:49.572+0000 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:47118 #2 (1 connection now open)
{ "ok" : 1 }
2017-10-20T20:00:49.576+0000 I NETWORK  [conn2] end connection 127.0.0.1:47118 (0 connections now open)
E: List directory /var/lib/apt/lists/partial is missing. - Acquire (13: Permission denied)
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
/docker-entrypoint-initdb.d/importdata.sh: line 5: curl: command not found

If I add sudo before the apt-gets, I just get sudo: command not found errors.

How can I properly start mongo with my database? I am open to other solutions besides using curl.

NOTE:

These commands work if I run kubectl exec -it mongo-xxxxx bash and then enter the commands within the pod! Could someone explain the difference between running scripts in the entrypoint and running commands inside the pod?

-- swagrov
docker
kubectl
kubernetes
minikube
mongodb

1 Answer

10/23/2017

Rather than using a ConfigMap for this, I'd recommend you structure the script as something invoked from an initialization container that's run parallel to the container that's hosting MongoDB in the same Pod.

Initialization containers appeared in Kubernetes 1.6, so you'll need at least that version running to take advantage of this - but with a current minikube instance, that shouldn't be an issue. If you're just loading a backup into place, this might be sufficient, but as Janos points out in the comments - these containers all run before the pod is "ready" and in sequence before any general containers defined on the pod. These pods also must exit prior to the main containers getting control.

You might also be able to leverage teh container lifecycle hooks which aren't guaranteed any ordering prior to the container starting up, but which can do some work between the Pod starting and being marked as "ready" (and hence added to services, etc)

There are 4 documentation points for init containers to give you a good sense of what this is and how to do it:

If you use an init container for this, you'll need the mongod server and its load tools, although I haven't tried that specific process to be able to write out how you'd tackle it.

In a general case, I'd recommend building a container specifically that has the tools you want for doing this data loading - a small container with bzip2, curl, and a mongodb client, and make the ENTRYPOINT/CMD for that container be the core of the script that you currently have in ConfigMap setup above. However, since init containers would run before the mongod is running, that wouldn't do you all that much good...

You could take advantage of the fact that all containers within the same Pod are linked to the same loopback network interface and volumes to communicate with MongoDB and load in the relevant data.

-- heckj
Source: StackOverflow