kubernetesconsulservicemeshconsul-kv

Access consul-api from consul-connect-service-mesh


In a consul-connect-service-mesh (using k8) how do you get to the consul-api itself? For example to access the consul-kv.

I'm working through this tutorial, and I'm wondering how you can bind the consul (http) api in a service to localhost.

Do you have to configure the Helm Chart further? I would have expected the consul-agent to always be an upstream service.

The only way i found to access the api is via the k8-service consul-server.

Environment:

global:
  name: consul
  datacenter: dc1
server:
  replicas: 1
  securityContext:
    runAsNonRoot: false
    runAsGroup: 0
    runAsUser: 0
    fsGroup: 0
ui:
  enabled: true
  service:
    type: 'NodePort'
connectInject:
  enabled: true
controller:
  enabled: true

Solution

  • My current final solution is a (connect)service based on reverse proxy (nginx) that targets consul.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: consul-kv-proxy
    data:
     nginx.conf.template: |
        error_log /dev/stdout info;
        server {
          listen 8500;    
          location / {
            access_log off;
            proxy_pass http://${MY_NODE_IP}:8500;
            error_log /dev/stdout;          
          }         
        }    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      # This name will be the service name in Consul.
      name: consul-kv-proxy
    spec:
      selector:
        app: consul-kv-proxy
      ports:
        - protocol: TCP
          port: 8500      
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: consul-kv-proxy
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: consul-kv-proxy
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: consul-kv-proxy
      template:
        metadata:
          name: consul-kv-proxy
          labels:
            app: consul-kv-proxy
          annotations:
            'consul.hashicorp.com/connect-inject': 'true'
        spec:
          containers:
            - name: consul-kv-proxy
              image: nginx:1.14.2            
              volumeMounts:
              - name: config
                mountPath: "/usr/local/nginx/conf"
                readOnly: true           
              command: ['/bin/bash']
              #we have to transform the nginx config to use the node ip address
              args:
                - -c
                - envsubst < /usr/local/nginx/conf/nginx.conf.template > /etc/nginx/conf.d/consul-kv-proxy.conf && nginx -g 'daemon off;'
              ports:
                - containerPort: 8500
                  name: http
              env:
                - name: MY_NODE_IP
                  valueFrom:
                    fieldRef:
                      fieldPath: status.hostIP      
          volumes:
            - name: config
              configMap:
                name: consul-kv-proxy
          
          # If ACLs are enabled, the serviceAccountName must match the Consul service name.
          serviceAccountName: consul-kv-proxy
    

    A downstream service (called static-client) now can be declared like this

    apiVersion: v1
    kind: Service
    metadata:
      name: static-client
    spec:
      selector:
        app: static-client
      ports:
        - port: 80
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: static-client
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: static-client
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: static-client
      template:
        metadata:
          name: static-client
          labels:
            app: static-client
          annotations:
            'consul.hashicorp.com/connect-inject': 'true'         
            'consul.hashicorp.com/connect-service-upstreams': 'consul-kv-proxy:8500'     
        spec:
          containers:
            - name: static-client
              image: curlimages/curl:latest
              # Just spin & wait forever, we'll use `kubectl exec` to demo
              command: ['/bin/sh', '-c', '--']
              args: ['while true; do sleep 30; done;']
          serviceAccountName: static-client
    
    

    Assume we have a key-value in consul called "test". From a pod of the static-client we can now access the consul-web-api with:

    curl http://localhost:8500/v1/kv/test
    

    This solution still lacks fine-tuning (i have not try https, or ACL).