diff --git a/pkg/kube/client.go b/pkg/kube/client.go
index 9feed468fe2f3af43c77ec1a3479ad62a3ed1ac2..00b61f11f574a726ddc20b8f63b191824735980d 100644
--- a/pkg/kube/client.go
+++ b/pkg/kube/client.go
@@ -23,6 +23,7 @@ import (
 	goerrors "errors"
 	"fmt"
 	"io"
+	"io/ioutil"
 	"log"
 	"sort"
 	"strings"
@@ -42,6 +43,8 @@ import (
 	apiequality "k8s.io/apimachinery/pkg/api/equality"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+	metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
 	"k8s.io/apimachinery/pkg/fields"
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -51,13 +54,14 @@ import (
 	"k8s.io/apimachinery/pkg/util/wait"
 	"k8s.io/apimachinery/pkg/watch"
 	"k8s.io/cli-runtime/pkg/genericclioptions"
+	"k8s.io/cli-runtime/pkg/printers"
 	"k8s.io/cli-runtime/pkg/resource"
 	"k8s.io/client-go/kubernetes/scheme"
+	"k8s.io/client-go/rest"
 	cachetools "k8s.io/client-go/tools/cache"
 	watchtools "k8s.io/client-go/tools/watch"
 	cmdutil "k8s.io/kubectl/pkg/cmd/util"
 	"k8s.io/kubectl/pkg/validation"
-	"k8s.io/kubernetes/pkg/apis/core"
 	"k8s.io/kubernetes/pkg/kubectl/cmd/get"
 )
 
@@ -158,6 +162,40 @@ func (c *Client) BuildUnstructured(namespace string, reader io.Reader) (Result,
 	return result, scrubValidationError(err)
 }
 
+// BuildUnstructuredTable reads Kubernetes objects and returns unstructured infos
+// as a Table. This is meant for viewing resources and displaying them in a table.
+// This is similar to BuildUnstructured but transforms the request for table
+// display.
+func (c *Client) BuildUnstructuredTable(namespace string, reader io.Reader) (Result, error) {
+	var result Result
+
+	result, err := c.NewBuilder().
+		Unstructured().
+		ContinueOnError().
+		NamespaceParam(namespace).
+		DefaultNamespace().
+		Stream(reader, "").
+		Flatten().
+		TransformRequests(transformRequests).
+		Do().Infos()
+	return result, scrubValidationError(err)
+}
+
+// This is used to retrieve a table view of the data. A table view is how kubectl
+// retrieves the information Helm displays as resources in status. Note, table
+// data is returned as a Table type that does not conform to the runtime.Object
+// interface but is that type. So, you can't transform it into Go objects easily.
+func transformRequests(req *rest.Request) {
+
+	// The request headers are for both the v1 and v1beta1 versions of the table
+	// as Kubernetes 1.14 and older used the beta version.
+	req.SetHeader("Accept", strings.Join([]string{
+		fmt.Sprintf("application/json;as=Table;v=%s;g=%s", metav1.SchemeGroupVersion.Version, metav1.GroupName),
+		fmt.Sprintf("application/json;as=Table;v=%s;g=%s", metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName),
+		"application/json",
+	}, ","))
+}
+
 // Validate reads Kubernetes manifests and validates the content.
 //
 // This function does not actually do schema validation of manifests. Adding
@@ -170,6 +208,7 @@ func (c *Client) Validate(namespace string, reader io.Reader) error {
 		DefaultNamespace().
 		// Schema(c.validator()). // No schema validation
 		Stream(reader, "").
+		Latest().
 		Flatten().
 		Do().Infos()
 	return scrubValidationError(err)
@@ -199,7 +238,7 @@ func resourceInfoToObject(info *resource.Info, c *Client) runtime.Object {
 	return internalObj
 }
 
-func sortByKey(objs map[string](map[string]runtime.Object)) []string {
+func sortByKey(objs map[string][]runtime.Object) []string {
 	var keys []string
 	// Create a simple slice, so we can sort it
 	for key := range objs {
@@ -210,24 +249,79 @@ func sortByKey(objs map[string](map[string]runtime.Object)) []string {
 	return keys
 }
 
+// We have slices of tables that need to be sorted by name. In this case the
+// self link is used so the sorting will include namespace and name.
+func sortTableSlice(objs []runtime.Object) []runtime.Object {
+	// If there are 0 or 1 objects to sort there is nothing to sort so
+	// the list can be returned
+	if len(objs) < 2 {
+		return objs
+	}
+
+	ntbl := &metav1.Table{}
+	unstr, ok := objs[0].(*unstructured.Unstructured)
+	if !ok {
+		return objs
+	}
+	if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstr.Object, ntbl); err != nil {
+		return objs
+	}
+
+	// Sort the list of objects
+	var newObjs []runtime.Object
+	namesCache := make(map[string]runtime.Object, len(objs))
+	var names []string
+	for _, obj := range objs {
+		unstr, ok := obj.(*unstructured.Unstructured)
+		if !ok {
+			return objs
+		}
+		if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstr.Object, ntbl); err != nil {
+			return objs
+		}
+		namesCache[ntbl.GetSelfLink()] = obj
+		names = append(names, ntbl.GetSelfLink())
+	}
+
+	sort.Strings(names)
+
+	for _, name := range names {
+		newObjs = append(newObjs, namesCache[name])
+	}
+
+	return newObjs
+}
+
 // Get gets Kubernetes resources as pretty-printed string.
 //
 // Namespace will set the namespace.
 func (c *Client) Get(namespace string, reader io.Reader) (string, error) {
 	// Since we don't know what order the objects come in, let's group them by the types and then sort them, so
 	// that when we print them, they come out looking good (headers apply to subgroups, etc.).
-	objs := make(map[string](map[string]runtime.Object))
+	objs := make(map[string][]runtime.Object)
+	gk := make(map[string]schema.GroupKind)
 	mux := &sync.Mutex{}
 
-	infos, err := c.BuildUnstructured(namespace, reader)
+	// The contents of the reader are used two times. The bytes are coppied out
+	// for use in future readers.
+	b, err := ioutil.ReadAll(reader)
 	if err != nil {
 		return "", err
 	}
 
-	var objPods = make(map[string][]v1.Pod)
+	// Get the table display for the objects associated with the release. This
+	// is done in table format so that it can be displayed in the status in
+	// the same way kubectl displays the resource information.
+	// Note, the response returns unstructured data instead of typed objects.
+	// These cannot be easily (i.e., via the go packages) transformed into
+	// Go types.
+	tinfos, err := c.BuildUnstructuredTable(namespace, bytes.NewBuffer(b))
+	if err != nil {
+		return "", err
+	}
 
 	missing := []string{}
-	err = perform(infos, func(info *resource.Info) error {
+	err = perform(tinfos, func(info *resource.Info) error {
 		mux.Lock()
 		defer mux.Unlock()
 		c.Log("Doing get for %s: %q", info.Mapping.GroupVersionKind.Kind, info.Name)
@@ -241,18 +335,36 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) {
 		// versions per cluster, but this certainly won't hurt anything, so let's be safe.
 		gvk := info.ResourceMapping().GroupVersionKind
 		vk := gvk.Version + "/" + gvk.Kind
+		gk[vk] = gvk.GroupKind()
 
 		// Initialize map. The main map groups resources based on version/kind
 		// The second level is a simple 'Name' to 'Object', that will help sort
 		// the individual resource later
 		if objs[vk] == nil {
-			objs[vk] = make(map[string]runtime.Object)
+			objs[vk] = []runtime.Object{}
 		}
 		// Map between the resource name to the underlying info object
-		objs[vk][info.Name] = resourceInfoToObject(info, c)
+		objs[vk] = append(objs[vk], resourceInfoToObject(info, c))
+
+		return nil
+	})
+	if err != nil {
+		return "", err
+	}
+
+	// This section finds related resources (e.g., pods). Before looking up pods
+	// the resources the pods are made from need to be looked up in a manner
+	// that can be turned into Go types and worked with.
+	infos, err := c.BuildUnstructured(namespace, bytes.NewBuffer(b))
+	if err != nil {
+		return "", err
+	}
+	err = perform(infos, func(info *resource.Info) error {
+		mux.Lock()
+		defer mux.Unlock()
 
 		//Get the relation pods
-		objPods, err = c.getSelectRelationPod(info, objPods)
+		objs, err = c.getSelectRelationPod(info, objs)
 		if err != nil {
 			c.Log("Warning: get the relation pod is failed, err:%s", err.Error())
 		}
@@ -263,25 +375,11 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) {
 		return "", err
 	}
 
-	//here, we will add the objPods to the objs
-	for key, podItems := range objPods {
-		for i := range podItems {
-			pod := &core.Pod{}
-
-			scheme.Scheme.Convert(&podItems[i], pod, nil)
-			if objs[key+"(related)"] == nil {
-				objs[key+"(related)"] = make(map[string]runtime.Object)
-			}
-			objs[key+"(related)"][pod.ObjectMeta.Name] = runtime.Object(pod)
-		}
-	}
-
 	// Ok, now we have all the objects grouped by types (say, by v1/Pod, v1/Service, etc.), so
 	// spin through them and print them. Printer is cool since it prints the header only when
 	// an object type changes, so we can just rely on that. Problem is it doesn't seem to keep
 	// track of tab widths.
 	buf := new(bytes.Buffer)
-	printFlags := get.NewHumanPrintFlags()
 
 	// Sort alphabetically by version/kind keys
 	vkKeys := sortByKey(objs)
@@ -290,20 +388,29 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) {
 		if _, err = fmt.Fprintf(buf, "==> %s\n", t); err != nil {
 			return "", err
 		}
-		typePrinter, _ := printFlags.ToPrinter("")
+		vk := objs[t]
 
-		var sortedResources []string
-		for resource := range objs[t] {
-			sortedResources = append(sortedResources, resource)
+		// The request made for tables returns each Kubernetes object as its
+		// own table. The normal sorting provided by kubectl and cli-runtime
+		// does not handle this case. Here we sort within each of our own
+		// grouping.
+		vk = sortTableSlice(vk)
+
+		// The printer flag setup follows a simalar setup to kubectl
+		printFlags := get.NewHumanPrintFlags()
+		if lgk, ok := gk[t]; ok {
+			printFlags.SetKind(lgk)
 		}
-		sort.Strings(sortedResources)
+		printer, _ := printFlags.ToPrinter("")
+		printer, err = printers.NewTypeSetter(scheme.Scheme).WrapToPrinter(printer, nil)
+		if err != nil {
+			return "", err
+		}
+		printer = &get.TablePrinter{Delegate: printer}
 
-		// Now that each individual resource within the specific version/kind
-		// is sorted, we print each resource using the k8s printer
-		vk := objs[t]
-		for _, resourceName := range sortedResources {
-			if err := typePrinter.PrintObj(vk[resourceName], buf); err != nil {
-				c.Log("failed to print object type %s, object: %q :\n %v", t, resourceName, err)
+		for _, resource := range vk {
+			if err := printer.PrintObj(resource, buf); err != nil {
+				c.Log("failed to print object type %s: %v", t, err)
 				return "", err
 			}
 		}
@@ -985,11 +1092,11 @@ func isPodComplete(event watch.Event) (bool, error) {
 	return false, nil
 }
 
-//get a kubernetes resources' relation pods
+// get a kubernetes resources' relation pods
 // kubernetes resource used select labels to relate pods
-func (c *Client) getSelectRelationPod(info *resource.Info, objPods map[string][]v1.Pod) (map[string][]v1.Pod, error) {
+func (c *Client) getSelectRelationPod(info *resource.Info, objs map[string][]runtime.Object) (map[string][]runtime.Object, error) {
 	if info == nil {
-		return objPods, nil
+		return objs, nil
 	}
 
 	c.Log("get relation pod of object: %s/%s/%s", info.Namespace, info.Mapping.GroupVersionKind.Kind, info.Name)
@@ -997,34 +1104,31 @@ func (c *Client) getSelectRelationPod(info *resource.Info, objPods map[string][]
 	versioned := asVersionedOrUnstructured(info)
 	selector, ok := getSelectorFromObject(versioned)
 	if !ok {
-		return objPods, nil
+		return objs, nil
 	}
 
-	client, _ := c.KubernetesClientSet()
-
-	pods, err := client.CoreV1().Pods(info.Namespace).List(metav1.ListOptions{
-		LabelSelector: labels.Set(selector).AsSelector().String(),
-	})
+	// The related pods are looked up in Table format so that their display can
+	// be printed in a manner similar to kubectl when it get pods. The response
+	// can be used with a table printer.
+	infos, err := c.NewBuilder().
+		Unstructured().
+		ContinueOnError().
+		NamespaceParam(info.Namespace).
+		DefaultNamespace().
+		ResourceTypes("pods").
+		LabelSelector(labels.Set(selector).AsSelector().String()).
+		TransformRequests(transformRequests).
+		Do().Infos()
 	if err != nil {
-		return objPods, err
+		return objs, err
 	}
 
-	for _, pod := range pods.Items {
-		vk := "v1/Pod"
-		if !isFoundPod(objPods[vk], pod) {
-			objPods[vk] = append(objPods[vk], pod)
-		}
+	for _, info := range infos {
+		vk := "v1/Pod(related)"
+		objs[vk] = append(objs[vk], info.Object)
 	}
-	return objPods, nil
-}
 
-func isFoundPod(podItem []v1.Pod, pod v1.Pod) bool {
-	for _, value := range podItem {
-		if (value.Namespace == pod.Namespace) && (value.Name == pod.Name) {
-			return true
-		}
-	}
-	return false
+	return objs, nil
 }
 
 func asVersionedOrUnstructured(info *resource.Info) runtime.Object {