<p>I am using <a href="https://github.com/kubernetes-sigs/metrics-server" rel="nofollow noreferrer">metric server</a> to get the usage of my Kubernetes cluster. But in order to use it from outside the host, I need to use "kubectl proxy". But i don't want to do that as it is not intended to run on background. I want it to be run as a service continuously </p>

<p>How can i achieve these</p>

<p><strong>expected output</strong>
 curl clusterip:8001/apis/metrics.k8s.io/v1beta1/nodes</p>

<pre><code>{
  "kind": "NodeMetricsList",
  "apiVersion": "metrics.k8s.io/v1beta1",
  "metadata": {
    "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes"
  },
  "items": [
    {
      "metadata": {
        "name": "manhattan-master",
        "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/manhattan-master",
        "creationTimestamp": "2019-11-15T04:26:47Z"
      },
      "timestamp": "2019-11-15T04:26:33Z",
      "window": "30s",
      "usage": {
        "cpu": "222998424n",
        "memory": "3580660Ki"
      }
    }
  ]
</code></pre>

<p>I tried by using <strong>LoadBalancig service</strong>
<strong>metrics-server-service.yaml</strong></p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    kubernetes.io/name: "Metrics-server"
    kubernetes.io/cluster-service: "true"
spec:
  selector:
    k8s-app: metrics-server
  ports:
  - port: 443
    protocol: TCP
    targetPort: main-port
  externalTrafficPolicy: Local
  type: LoadBalancer
</code></pre>

<p><strong>kubectl describe service metrics-master -n kube-system</strong></p>

<pre><code>[root@manhattan-master 1.8+]# kubectl describe service metrics-server -n kube-system
Name:                     metrics-server
Namespace:                kube-system
Labels:                   kubernetes.io/cluster-service=true
                          kubernetes.io/name=Metrics-server
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"kubernetes.io/cluster-service":"true","kubernetes.io/name":"Me...
Selector:                 k8s-app=metrics-server
Type:                     LoadBalancer
IP:                       10.110.223.216
Port:                     &lt;unset&gt;  443/TCP
TargetPort:               main-port/TCP
NodePort:                 &lt;unset&gt;  31043/TCP
Endpoints:                10.32.0.7:4443
Session Affinity:         None
External Traffic Policy:  Local
HealthCheck NodePort:     32208
Events:                   &lt;none&gt;
</code></pre>

<p>This is possible by creating a new service to expose the Metrics Server. Your Metrics Server Service should look like this: </p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  labels:
    kubernetes.io/name: Metrics-server-ext
  name: metrics-server-ext
  namespace: kube-system
  selfLink: /api/v1/namespaces/kube-system/services/metrics-server
spec:
  ports:
  - port: 443
    protocol: TCP
    targetPort: https
  selector:
    k8s-app: metrics-server
  sessionAffinity: None
  type: LoadBalancer
</code></pre>

<p>If you try to access this service you will face some problems with authorization and you need to do some things to give all necessary authorizations.</p>

<p>After creating the service you will need to create a Cluster Role Binding so our service can have access to the data:</p>

<pre class="lang-sh prettyprint-override"><code>$ kubectl create clusterrolebinding node-admin-default-svc --clusterrole=cluster-admin --serviceaccount=default:default
</code></pre>

<p>Before running <code>curl</code> command we need to get the token so we can pass this on our curl command: </p>

<pre class="lang-sh prettyprint-override"><code>$ TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 --decode)
</code></pre>

<p>Get your service external IP:</p>

<pre class="lang-sh prettyprint-override"><code>kubectl get svc/metrics-server-ext -n kube-system -o jsonpath='{..ip}'
</code></pre>

<p>Your <code>curl</code> command should pass the Token key to get Authorization: </p>

<pre class="lang-sh prettyprint-override"><code>curl -k https://34.89.228.98/apis/metrics.k8s.io/v1beta1/nodes --header "Authorization: Bearer $TOKEN" --insecure
</code></pre>

<p>Sample output: </p>

<pre><code>{
 "kind": "NodeMetricsList",
 "apiVersion": "metrics.k8s.io/v1beta1",
 "metadata": {
   "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes"
 },
 "items": [
   {
     "metadata": {
       "name": "gke-lab-default-pool-993de7d7-ntmc",
       "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/gke-lab-default-pool-993de7d7-ntmc",
       "creationTimestamp": "2019-11-19T10:26:52Z"
     },
     "timestamp": "2019-11-19T10:26:17Z",
     "window": "30s",
     "usage": {
       "cpu": "52046272n",
       "memory": "686768Ki"
     }
   },
   {
     "metadata": {
       "name": "gke-lab-default-pool-993de7d7-tkj9",
       "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/gke-lab-default-pool-993de7d7-tkj9",
       "creationTimestamp": "2019-11-19T10:26:52Z"
     },
     "timestamp": "2019-11-19T10:26:21Z",
     "window": "30s",
     "usage": {
       "cpu": "52320505n",
       "memory": "687252Ki"
     }
   },
   {
     "metadata": {
       "name": "gke-lab-default-pool-993de7d7-v7m3",
       "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/gke-lab-default-pool-993de7d7-v7m3",
       "creationTimestamp": "2019-11-19T10:26:52Z"
     },
     "timestamp": "2019-11-19T10:26:17Z",
     "window": "30s",
     "usage": {
       "cpu": "45602403n",
       "memory": "609968Ki"
     }
   }
 ]
}
</code></pre>

<p>EDIT:</p>

<p>You can also optionally access it from your pods since you created a Cluster Role Binding in your default Service Account with cluster-admin role. </p>

<p>As example, create a pod from a image that includes curl command:</p>

<pre class="lang-sh prettyprint-override"><code>$ kubectl run bb-$RANDOM --rm -i --image=ellerbrock/alpine-bash-curl-ssl --restart=Never --tty -- /bin/bash
</code></pre>

<p>Than you need to exec into you pod and run:</p>

<pre class="lang-sh prettyprint-override"><code>$ curl -k -X GET https://kubernetes.default/apis/metrics.k8s.io/v1beta1/nodes --header "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" --insecure
</code></pre>

<p>Here we are passing the same TOKEN mentioned before in a complete different way. </p>
