Search code examples
bashkuberneteskubectl

kubectl jsonpath expression for named path


I have kube service running with 2 named ports like this:

$ kubectl get service elasticsearch --output json
{
    "apiVersion": "v1",
    "kind": "Service",
    "metadata": {
        ... stuff that really has nothing to do with my question ...
    },
    "spec": {
        "clusterIP": "10.0.0.174",
        "ports": [
             {
                "name": "http",
                "nodePort": 31041,
                "port": 9200,
                "protocol": "TCP",
                "targetPort": 9200
            },
            {
                "name": "transport",
                "nodePort": 31987,
                "port": 9300,
                "protocol": "TCP",
                "targetPort": 9300
            }
        ],
        "selector": {
            "component": "elasticsearch"
        },
        "sessionAffinity": "None",
        "type": "NodePort"
    },
    "status": {
        "loadBalancer": {}
    }
}

I'm trying to get output containing just the 'http' port:

$ kubectl get service elasticsearch --output jsonpath={.spec.ports[*].nodePort}
31041 31987

Except when I add the test expression as hinted in the cheatsheet here http://kubernetes.io/docs/user-guide/kubectl-cheatsheet/ for the name I get an error

$ kubectl get service elasticsearch --output jsonpath={.spec.ports[?(@.name=="http")].nodePort}
-bash: syntax error near unexpected token `('

Solution

  • ( and ) mean something in bash (see subshell), so your shell interpreter is doing that first and getting confused. Wrap the argument to jsonpath in single quotes, that will fix it:

    $ kubectl get service elasticsearch --output jsonpath='{.spec.ports[?(@.name=="http")].nodePort}'
    

    For example:

    # This won't work:
    $ kubectl get service kubernetes --output jsonpath={.spec.ports[?(@.name=="https")].targetPort}
    -bash: syntax error near unexpected token `('
    
    # ... but this will:
    $ kubectl get service kubernetes --output jsonpath='{.spec.ports[?(@.name=="https")].targetPort}'
    443