cluster/kube/lib/cockroach: move client to deployment

This prevents a bug where kubecfg fails to update the client pod when
running a cluster/kube/cluster.jsonnet update. The pod update is
attempted because of runtime/intent differences at serviceAccounts
specification, which causes kubecfg to see a diff, which causes it to
attempt and update, which causes kube-apiserver to reject the change
(because pods are immutable), which causes kubecfg to fail.

Change-Id: I20b0ecbb264213a2eb483d475c7683b4965c82be
diff --git a/cluster/kube/lib/cockroachdb.libsonnet b/cluster/kube/lib/cockroachdb.libsonnet
index 4ce2af7..4df69b6 100644
--- a/cluster/kube/lib/cockroachdb.libsonnet
+++ b/cluster/kube/lib/cockroachdb.libsonnet
@@ -15,7 +15,7 @@
 #},
 #
 # After the cluster is up, you can get to an administrateive SQL shell:
-#   $ kubectl -n q3k exec -it q3kdb-client /cockroach/cockroach sql
+#   $ NS=q3k kubectl -n $NS exec -it $(kubectl -n $NS get pods -o name | grep client- | cut -d/ -f 2) /cockroach/cockroach sql
 #   root@q3kdb-cockroachdb-0.q3kdb-internal.q3k.svc.cluster.local:26257/defaultdb>
 #
 # Then, you can create some users and databases for applications:
@@ -365,51 +365,56 @@
             },
         },
 
-        clientPod: kube.Pod(cluster.name("client")) {
+        client: kube.Deployment(cluster.name("client")) {
             metadata+: cluster.metadata {
                 labels+: {
                     "app.kubernetes.io/component": "client",
                 },
             },
-            spec: {
-                terminationGracePeriodSeconds: 5,
-                containers: [
-                    kube.Container("cockroachdb-client") {
-                        image: cluster.cfg.image,
-                        env_: {
-                            "COCKROACH_CERTS_DIR": "/cockroach/cockroach-certs",
-                            "COCKROACH_HOST": cluster.publicService.host,
-                            "COCKROACH_PORT": std.toString(cluster.cfg.portServe),
-                        },
-                        command: ["sleep", "2147483648"], //(FIXME) keep the client pod running indefinitely
-                        volumeMounts: [
-                            {
-                                name: "certs",
-                                mountPath: "/cockroach/cockroach-certs/ca.crt",
-                                subPath: "ca.crt",
+            spec+: {
+                template: {
+                    metadata: cluster.client.metadata,
+                    spec+: {
+                        terminationGracePeriodSeconds: 5,
+                        containers: [
+                            kube.Container("cockroachdb-client") {
+                                image: cluster.cfg.image,
+                                env_: {
+                                    "COCKROACH_CERTS_DIR": "/cockroach/cockroach-certs",
+                                    "COCKROACH_HOST": cluster.publicService.host,
+                                    "COCKROACH_PORT": std.toString(cluster.cfg.portServe),
+                                },
+                                command: ["sleep", "2147483648"], //(FIXME) keep the client pod running indefinitely
+                                volumeMounts: [
+                                    {
+                                        name: "certs",
+                                        mountPath: "/cockroach/cockroach-certs/ca.crt",
+                                        subPath: "ca.crt",
+                                    },
+                                    {
+                                        name: "certs",
+                                        mountPath: "/cockroach/cockroach-certs/client.root.crt",
+                                        subPath: "tls.crt",
+                                    },
+                                    {
+                                        name: "certs",
+                                        mountPath: "/cockroach/cockroach-certs/client.root.key",
+                                        subPath: "tls.key",
+                                    },
+                                ],
                             },
+                        ],
+                        volumes: [
                             {
                                 name: "certs",
-                                mountPath: "/cockroach/cockroach-certs/client.root.crt",
-                                subPath: "tls.crt",
-                            },
-                            {
-                                name: "certs",
-                                mountPath: "/cockroach/cockroach-certs/client.root.key",
-                                subPath: "tls.key",
+                                secret: {
+                                    secretName: cluster.pki.clientCertificate.spec.secretName,
+                                    defaultMode: kube.parseOctal("400")
+                                }
                             },
                         ],
                     },
-                ],
-                volumes: [
-                    {
-                        name: "certs",
-                        secret: {
-                            secretName: cluster.pki.clientCertificate.spec.secretName,
-                            defaultMode: kube.parseOctal("400")
-                        }
-                    },
-                ],
+                },
             },
         },
     },