Updated to use default Kubernetes client discovery logic (#3432)

* Updated to use default Kubernetes client discovery logic

* Removed kubectl-proxy container

* Remove kubectl-proxy image property

* Syntax cleanup

* Added missing kubernetes dependency
diff --git a/deploy/kubernetes/general/apiserver.yaml b/deploy/kubernetes/general/apiserver.yaml
index 470dff3..6e0cc97 100644
--- a/deploy/kubernetes/general/apiserver.yaml
+++ b/deploy/kubernetes/general/apiserver.yaml
@@ -27,7 +27,6 @@
   namespace: default
 
 ---
-
 apiVersion: rbac.authorization.k8s.io/v1beta1
 kind: ClusterRoleBinding
 metadata:
@@ -44,7 +43,6 @@
   namespace: default
 
 ---
-
 apiVersion: apps/v1
 kind: Deployment
 metadata:
@@ -97,13 +95,8 @@
               -D heron.uploader.dlog.topologies.namespace.uri=distributedlog://zookeeper:2181/heron
               -D heron.statefulstorage.classname=org.apache.heron.statefulstorage.dlog.DlogStorage
               -D heron.statefulstorage.dlog.namespace.uri=distributedlog://zookeeper:2181/heron
-        - name: kubectl-proxy
-          image: heron/kubectl:latest
-          command: ["sh", "-c"]
-          args:
-            - >
-              kubectl proxy -p 8001
----    
+
+---
 apiVersion: v1
 kind: Service
 metadata:
diff --git a/deploy/kubernetes/general/bookkeeper.statefulset.yaml b/deploy/kubernetes/general/bookkeeper.statefulset.yaml
index e5c9fe2..24d1ec2 100644
--- a/deploy/kubernetes/general/bookkeeper.statefulset.yaml
+++ b/deploy/kubernetes/general/bookkeeper.statefulset.yaml
@@ -34,8 +34,8 @@
     #BK_statsProviderClass: org.apache.bookkeeper.stats.prometheus.PrometheusMetricsProvider
     # use hostname as bookie id for StatefulSets deployment
     BK_useHostNameAsBookieID: "true"
----
 
+---
 apiVersion: apps/v1
 kind: StatefulSet
 metadata:
@@ -122,6 +122,7 @@
         resources:
           requests:
             storage: 10Gi
+
 ---
 # A headless service to create DNS records
 apiVersion: v1
diff --git a/deploy/kubernetes/general/bookkeeper.statefulset_empty.yaml b/deploy/kubernetes/general/bookkeeper.statefulset_empty.yaml
index 90a158f..4c3fcb9 100644
--- a/deploy/kubernetes/general/bookkeeper.statefulset_empty.yaml
+++ b/deploy/kubernetes/general/bookkeeper.statefulset_empty.yaml
@@ -34,8 +34,8 @@
     #BK_statsProviderClass: org.apache.bookkeeper.stats.prometheus.PrometheusMetricsProvider
     # use hostname as bookie id for StatefulSets deployment
     BK_useHostNameAsBookieID: "true"
----
 
+---
 apiVersion: apps/v1
 kind: StatefulSet
 metadata:
diff --git a/deploy/kubernetes/general/bookkeeper.yaml b/deploy/kubernetes/general/bookkeeper.yaml
index 2ba4891..f757bf6 100644
--- a/deploy/kubernetes/general/bookkeeper.yaml
+++ b/deploy/kubernetes/general/bookkeeper.yaml
@@ -32,8 +32,8 @@
   BK_zkServers: zookeeper
   # TODO: Issue 458: https://github.com/apache/bookkeeper/issues/458
   #BK_statsProviderClass: org.apache.bookkeeper.stats.PrometheusMetricsProvider
----
 
+---
 ## BookKeeper servers need to access the local disks and the pods
 ## cannot be moved across different nodes.
 ## For this reason, we run BK as a daemon set, one for each node in the
@@ -107,7 +107,6 @@
             path: /mnt/disks/ssd1
 
 ---
-
 ##
 ## Define the Bookie headless service
 ## In practice, in this case, it is only useful to have a view of
diff --git a/deploy/kubernetes/general/tools.yaml b/deploy/kubernetes/general/tools.yaml
index a6497f1..b662557 100644
--- a/deploy/kubernetes/general/tools.yaml
+++ b/deploy/kubernetes/general/tools.yaml
@@ -85,8 +85,8 @@
             limits:
               cpu: "400m"
               memory: "512M"
----
 
+---
 ##
 ## Service to expose the heron-ui
 ##
diff --git a/deploy/kubernetes/general/zookeeper.yaml b/deploy/kubernetes/general/zookeeper.yaml
index 835bee5..b159593 100644
--- a/deploy/kubernetes/general/zookeeper.yaml
+++ b/deploy/kubernetes/general/zookeeper.yaml
@@ -30,8 +30,8 @@
     matchLabels:
       app: zk
   minAvailable: 1
----
 
+---
 ## Define a StatefulSet for ZK servers
 apiVersion: apps/v1
 kind: StatefulSet
@@ -107,7 +107,6 @@
           emptyDir: {}
 
 ---
-
 ##
 ## Define the ZooKeeper headless service
 ##
diff --git a/deploy/kubernetes/gke/gcs-apiserver.yaml b/deploy/kubernetes/gke/gcs-apiserver.yaml
index d268a0f..c37c6ee 100644
--- a/deploy/kubernetes/gke/gcs-apiserver.yaml
+++ b/deploy/kubernetes/gke/gcs-apiserver.yaml
@@ -27,7 +27,6 @@
   namespace: default
 
 ---
-
 apiVersion: rbac.authorization.k8s.io/v1beta1
 kind: ClusterRoleBinding
 metadata:
@@ -44,7 +43,6 @@
   namespace: default
 
 ---
-
 apiVersion: apps/v1
 kind: Deployment
 metadata:
@@ -106,15 +104,8 @@
                 configMapKeyRef:
                   name: heron-apiserver-config
                   key: gcs.bucket
-        - name: kubectl-proxy
-          image: heron/kubectl:latest
-          command: ["sh", "-c"]
-          args:
-            - >
-              kubectl proxy -p 8001
 
 ---
-
 ##
 ## Service to expose the heron API server
 ##
diff --git a/deploy/kubernetes/helm/templates/bookie.yaml b/deploy/kubernetes/helm/templates/bookie.yaml
index ed01baf..c14ecd3 100644
--- a/deploy/kubernetes/helm/templates/bookie.yaml
+++ b/deploy/kubernetes/helm/templates/bookie.yaml
@@ -50,8 +50,8 @@
   BK_enableTaskExecutionStats: "true"
   BK_statsProviderClass: org.apache.bookkeeper.stats.prometheus.PrometheusMetricsProvider
   {{- end }}
----
 
+---
 ## BookKeeper servers need to access the local disks and the pods
 ## cannot be moved across different nodes.
 ## For this reason, we run BK as a daemon set, one for each node in the
@@ -195,8 +195,8 @@
           requests:
             storage: {{ $bookieStorageCapacity }}
 {{- end }}
----
 
+---
 ##
 ## Define the Bookie headless service
 ## In practice, in this case, it is only useful to have a view of
diff --git a/deploy/kubernetes/helm/templates/tools.yaml b/deploy/kubernetes/helm/templates/tools.yaml
index 6068b59..64d57b7 100644
--- a/deploy/kubernetes/helm/templates/tools.yaml
+++ b/deploy/kubernetes/helm/templates/tools.yaml
@@ -26,8 +26,8 @@
 data:
   HERON_APISERVER_MEM_MIN: {{ $apiServerMemory | quote }}
   HERON_APISERVER_MEM_MAX: {{ $apiServerMemory | quote }}
----
 
+---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
@@ -161,12 +161,7 @@
           envFrom:
             - configMapRef:
                 name: {{ .Release.Name }}-tools-config
-        - name: kubectl-proxy
-          image: {{ .Values.kubectlImage }}
-          command: ["sh", "-c"]
-          args:
-            - >
-              kubectl proxy -p 8001
+
 ---
 ##
 ## Service to expose the heron-ui
diff --git a/deploy/kubernetes/helm/values.yaml.template b/deploy/kubernetes/helm/values.yaml.template
index 2652d77..ae310be 100644
--- a/deploy/kubernetes/helm/values.yaml.template
+++ b/deploy/kubernetes/helm/values.yaml.template
@@ -29,7 +29,6 @@
 
 # Heron image to use
 image: heron/heron:VERSION
-kubectlImage: heron/kubectl:latest
 
 # Heron image pull policy
 imagePullPolicy: IfNotPresent
diff --git a/deploy/kubernetes/minikube/apiserver.yaml b/deploy/kubernetes/minikube/apiserver.yaml
index 3c4a9b2..502f746 100644
--- a/deploy/kubernetes/minikube/apiserver.yaml
+++ b/deploy/kubernetes/minikube/apiserver.yaml
@@ -28,7 +28,6 @@
   namespace: default
 
 ---
-
 apiVersion: rbac.authorization.k8s.io/v1beta1
 kind: ClusterRoleBinding
 metadata:
@@ -45,7 +44,6 @@
   namespace: default
 
 ---
-
 apiVersion: apps/v1
 kind: Deployment
 metadata:
@@ -84,13 +82,8 @@
               -D heron.uploader.dlog.topologies.namespace.uri=distributedlog://zookeeper:2181/heron
               -D heron.statefulstorage.classname=org.apache.heron.statefulstorage.dlog.DlogStorage
               -D heron.statefulstorage.dlog.namespace.uri=distributedlog://zookeeper:2181/heron
-        - name: kubectl-proxy
-          image: heron/kubectl:latest
-          command: ["sh", "-c"]
-          args:
-            - >
-              kubectl proxy -p 8001
----    
+
+---
 apiVersion: v1
 kind: Service
 metadata:
diff --git a/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/AppsV1Controller.java b/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/AppsV1Controller.java
index be02c0c..8724034 100644
--- a/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/AppsV1Controller.java
+++ b/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/AppsV1Controller.java
@@ -46,6 +46,7 @@
 import io.kubernetes.client.custom.V1Patch;
 import io.kubernetes.client.openapi.ApiClient;
 import io.kubernetes.client.openapi.ApiException;
+import io.kubernetes.client.openapi.Configuration;
 import io.kubernetes.client.openapi.apis.AppsV1Api;
 import io.kubernetes.client.openapi.models.V1Container;
 import io.kubernetes.client.openapi.models.V1ContainerPort;
@@ -72,12 +73,18 @@
 
   private static final String ENV_SHARD_ID = "SHARD_ID";
 
-  private final AppsV1Api client;
+  private final AppsV1Api appsClient;
 
   AppsV1Controller(Config configuration, Config runtimeConfiguration) {
     super(configuration, runtimeConfiguration);
-    final ApiClient apiClient = new ApiClient().setBasePath(getKubernetesUri());
-    client = new AppsV1Api(apiClient);
+    try {
+      final ApiClient apiClient = io.kubernetes.client.util.Config.defaultClient();
+      Configuration.setDefaultApiClient(apiClient);
+      appsClient = new AppsV1Api(apiClient);
+    } catch (IOException e) {
+      LOG.log(Level.SEVERE, "Failed to setup Kubernetes client" + e);
+      throw new RuntimeException(e);
+    }
   }
 
   @Override
@@ -99,7 +106,7 @@
 
     try {
       final V1StatefulSet response =
-          client.createNamespacedStatefulSet(getNamespace(), statefulSet, null,
+          appsClient.createNamespacedStatefulSet(getNamespace(), statefulSet, null,
               null, null);
     } catch (ApiException e) {
       KubernetesUtils.logExceptionWithDetails(LOG, "Error creating topology", e);
@@ -180,7 +187,7 @@
             String.format(JSON_PATCH_STATEFUL_SET_REPLICAS_FORMAT,
                     patchedSpec.getReplicas().toString());
     final V1Patch patch = new V1Patch(body);
-    client.patchNamespacedStatefulSet(getTopologyName(),
+    appsClient.patchNamespacedStatefulSet(getTopologyName(),
             getNamespace(), patch, null, null, null, null);
   }
 
@@ -188,12 +195,13 @@
       "{\"op\":\"replace\",\"path\":\"/spec/replicas\",\"value\":%s}";
 
   V1StatefulSet getStatefulSet() throws ApiException {
-    return client.readNamespacedStatefulSet(getTopologyName(), getNamespace(), null, null, null);
+    return appsClient.readNamespacedStatefulSet(getTopologyName(), getNamespace(),
+        null, null, null);
   }
 
   boolean deleteStatefulSet() {
     try {
-      final Response response = client.deleteNamespacedStatefulSetCall(getTopologyName(),
+      final Response response = appsClient.deleteNamespacedStatefulSetCall(getTopologyName(),
           getNamespace(), null, null, 0, null,
           KubernetesConstants.DELETE_OPTIONS_PROPAGATION_POLICY, null, null).execute();
 
@@ -219,7 +227,7 @@
   boolean isStatefulSet() {
     try {
       final V1StatefulSet response =
-          client.readNamespacedStatefulSet(getTopologyName(), getNamespace(),
+          appsClient.readNamespacedStatefulSet(getTopologyName(), getNamespace(),
               null, null, null);
       return response.getKind().equals("StatefulSet");
     } catch (ApiException e) {
diff --git a/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/KubernetesCompat.java b/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/KubernetesCompat.java
index 2c10ba9..9ce5fba 100644
--- a/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/KubernetesCompat.java
+++ b/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/KubernetesCompat.java
@@ -27,7 +27,9 @@
 
 import io.kubernetes.client.openapi.ApiClient;
 import io.kubernetes.client.openapi.ApiException;
+import io.kubernetes.client.openapi.Configuration;
 import io.kubernetes.client.openapi.apis.CoreV1Api;
+
 import okhttp3.Response;
 
 public class KubernetesCompat {
@@ -35,13 +37,21 @@
   private static final Logger LOG = Logger.getLogger(KubernetesCompat.class.getName());
 
   boolean killTopology(String kubernetesUri, String topology, String namespace) {
-    final CoreV1Api client = new CoreV1Api(new ApiClient().setBasePath(kubernetesUri));
+    CoreV1Api coreClient;
+    try {
+      final ApiClient apiClient = io.kubernetes.client.util.Config.defaultClient();
+      Configuration.setDefaultApiClient(apiClient);
+      coreClient = new CoreV1Api(apiClient);
+    } catch (IOException e) {
+      LOG.log(Level.SEVERE, "Failed to setup Kubernetes client" + e);
+      throw new RuntimeException(e);
+    }
 
     // old version deployed topologies as naked pods
     try {
       final String labelSelector = KubernetesConstants.LABEL_TOPOLOGY + "=" + topology;
       final Response response =
-          client.deleteCollectionNamespacedPodCall(namespace, null, null, null, null, null,
+          coreClient.deleteCollectionNamespacedPodCall(namespace, null, null, null, null, null,
           null, labelSelector, null, null,
           KubernetesConstants.DELETE_OPTIONS_PROPAGATION_POLICY,
           null, null, null, null, null).execute();
diff --git a/heron/schedulers/tests/java/BUILD b/heron/schedulers/tests/java/BUILD
index 2c0d961..0f67de7 100644
--- a/heron/schedulers/tests/java/BUILD
+++ b/heron/schedulers/tests/java/BUILD
@@ -64,6 +64,7 @@
     "//heron/schedulers/src/java:kubernetes-scheduler-java",
     "//heron/schedulers/src/java:scheduler-utils-java",
     "//third_party/java:kubernetes-java-client",
+    "@org_slf4j_slf4j_api//jar",
 ]
 
 nomad_sdk_deps = [