从 consul-connect-service-mesh 访问 consul-api

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

在 consul-connect-service-mesh(使用 k8)中,你如何到达 consul-api 本身? 例如访问consul-kv.

我正在解决这个 tutorial,我想知道如何 您可以将服务中的领事 (http) api 绑定到本地主机。

是否需要进一步配置 Helm Chart? 我本来希望 consul-agent 永远是一个上游服务。

我发现访问 api 的唯一方法是通过 k8-service consul-server。

环境:

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

可以通过Kubernetes向下API在本地代理上访问ConsulAPI,在pod中注入一个环境变量,主机IP地址。这记录在 Installing Consul on Kubernetes: Accessing the Consul HTTP API 下的 Consul.io 中。

您还需要使用 consul.hashicorp.com/transparent-proxy-exclude-outbound-ports 标签从重定向中排除端口 8500(或 8501)。

我目前的最终解决方案是一个基于反向代理(nginx)的(connect)服务,目标是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

下游服务(称为 static-client)现在可以这样声明

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

假设我们在 consul 中有一个名为“test”的 key-value。 我们现在可以从 static-client 的 pod 访问 consul-web-api:

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

此解决方案仍然缺少 fine-tuning(我没有尝试过 https 或 ACL)。