0
votes

I'm using the docker image (grafana/grafana:7.4.3). I see there is no curl as part of it. The grafana API mentioned is a HTTP API and all the example requests and responses use curl. If the maintainers decided to remove curl, may I know what alternative is there so as to perform the request/response from inside the container ?

I understand that we need to deploy, run the image then expose the port and use the curl commands from the host.

Use case:

All our monitoring systems have a dashboard. Currently we're saving each of the dashboards into a git repo and manually uploading it to the grafana through the import functionality from UI.

Need to automate the k8s deployment script such that it picks the dashboard.json from the git repo and then imports it to grafana UI.

What we are doing now

  1. Pulling grafana image as part of the k8s.
  2. Before the image is successfully pulled, I'm adding a command in the spec (given below). Please ignore the admin:admin combo for username and password I'm using. It'll be changed before the deployment from Dev to QA/Stage.
  3. Once the BEARER_TOKEN is exported to env, I'm fetching dashboards from a volume mounted. These dashboards are in the JSON format in line with the HTTP API import curl command.

Keeping in view my scenario, can anyone suggest ideas which can by pass the need/usage of curl ?

- apiVersion: apps/v1
  kind: Deployment
  metadata:
    labels:
        app: dashboard
    name: dashboard
    namespace: monitoring
    spec:
      template:
        spec:
          containers:
            - name: grafana
              image: 'docker.io/grafana/grafana:7.3.6'
              imagePullPolicy: Always
              env:
                - name: GF_AUTH_BASIC_ENABLED
                  value: "true"
                - name: GF_AUTH_ANONYMOUS_ENABLED
                  value: "true"
                - name: GF_SERVER_ROOT_URL
                  value: "%(protocol)s://%(domain)s:%(http_port)s/grafana/"
              command: ["/bin/sh", "-c", "apk --no-cache add curl jq && curl -X POST -H \"Content-Type: application/json\" -d '{\"name\":\"apikeycurl\", \"role\": \"Admin\"}' http://admin:admin@localhost:3000/api/auth/keys -o /tmp/file.json && export BEARER_TOKEN=$(jq .key /tmp/file.json | grep -o '\".*\"' | sed 's/\"//g')"]
              args:
                - "apk --no-cache add curl jq"
                - "curl -X POST \
                  -H \"Content-Type: application/json\" 
                  -d '{\"name\":\"apikeycurl\", \"role\": \"Admin\"}' http://admin:admin@localhost:3000/api/auth/keys 
                  -o /tmp/file.json"
                - "export BEARER_TOKEN=$(jq .key /tmp/file.json | grep -o '\".*\"' | sed 's/\"//g')"
                - "curl -X POST \
                  --insecure -H \"Authorization: Bearer \"$BEARER_TOKEN\" \" \
                  -H \"Content-Type: application/json\" \
                  --show-error \
                  --data-binary @/Users/coder/Work/grafana/dashboards/service-dashboard.json \
                  -i http://localhost:3000/api/dashboards/db"
              terminationMessagePath: /dev/termination-log-grafana
              terminationMessagePolicy: File
              volumeMounts:
                - mountPath: /etc/grafana/provisioning/datasources/
                  name: datasource-volume
                - mountPath: /etc/grafana/provisioning/dashboards/
                  name: dashboard-volume
                - name: secret-volume
                  mountPath: /etc/secret-volume
              securityContext:
                allowPrivilegeEscalation: false
                runAsUser: 0
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          terminationGracePeriodSeconds: 30
          volumes:
            - name: grafana-persistent-storage
              emptyDir: {}
            - configMap:
                defaultMode: 420
                name: grafana-datasource-cm
              name: datasource-volume
            - configMap:
                defaultMode: 420
                name: grafana-dashboard-cm
              name: dashboard-volume
            - name: secret-volume
              secret:
                secretName: grafana-api-key-secret
    status: {}
2
Why do you want to make http calls from inside the grafana container?Malt
Updated the question to make the question much clear.user1683894

2 Answers

3
votes

If you want to use curl you can simply add curl to the grafana image - just write a new Dockerfile that uses grafana/grafana as the base image and installs curl. Build the image, tag it, and upload it to your own container registry e.g. my-container-repo.com/user1683894/grafana:7.3.6. This can be easily be automated for every new grafana version. Or you could put a pre-compiled version of curl someplace accessible like a volume mount.

However, I don't think that using curl is the right approach here. Grafana has a built-in provisioning mechanism for configuration and dashboards. So a cleaner solution would be to use an init container to get the latest dashboards from the git repo, and save the files to where grafana expects to find them.

0
votes

You can find the node where the container is running:

kubectl get pods -o wide -A

SSH into this node (for example gcloud compute ssh instance-name-here in GCP)

Access this container using root account:

docker exec -it -u root container-id-here /bin/bash

Use apt install curl -y, apk add --update curl, yum install curl -y or whatever your distro is

Using this method, you don't need to build Dockerfile in each scenario where you need curl or other package to check something.


Alternative: you could also use a nice command kubectl cp /tmp/curl namespace-name-here/pod-name-here:/tmp/curl to copy curl fiels. So you can build Dockerfile locally, install curl and copy binaries/libraries to the pod.


So it's maybe not direct answer, but I did an assumption that they didn't include curl as it can work without it. Also this guide could be useful in other cases.