2

我正在使用fabric8在Kubernetes之上开发一个集群管理层,我对在实例化pod/rep控制器和服务等时出现问题时获取错误通知的“官方”API感到困惑。

在“Pod 部署代码”部分中,我有一个精简版的我们为 pod 所做的工作。如果一切正常,我们的代码就可以了。正如您在方法中看到的那样,我们依赖于设置“手表” deployPodWithWatch。我在给定的eventReceived回调中所做的只是打印事件,但我们的真实代码将分解这样的通知:

got action: 
    MODIFIED / 
      Pod(apiVersion=v1, kind=Pod, metadata=...etc etc
        status=PodStatus(
            conditions=[

并选择 Pod 的 'status' 元素,当我们得到 PodCondition(status=True, type=Ready) 时,我们知道我们的 Pod 已经成功部署。

在快乐路径的情况下,这很有效。您实际上可以运行将变量 k8sUrl 设置为您站点的正确 url 的代码(希望您的 k8s 安装不需要特定于站点的身份验证,因此我没有为此提供代码)。

但是,假设您将变量更改imageName为“nginBoo”。没有该名称的公共 docker 映像,因此在运行代码后,将 kubernetes 上下文设置为命名空间“junk”,然后执行

  describe pod podboy

您将在最后看到两条状态消息,其中包含以下原因/消息值

Reason      message
failedSync  Error syncing pod, skipping...
failed      Failed to pull image "nginBoo": API error (500): 
            Error parsing reference: "nginBoo" 
            is not a valid repository/tag

我想实现一个监视回调,以便它捕获这些类型的错误。但是,我唯一看到的是“修改”事件,其中 Pod 具有如下字段:

 state=ContainerState(running=null, terminated=null, 
        waiting=ContainerStateWaiting(
            reason=API error (500): 
                Error parsing reference: 
                    "nginBoo" is not a valid repository/tag

我想我可以寻找一个包含字符串“API 错误”的原因代码,但这似乎是一个非常依赖于实现的 hack——它可能无法涵盖所有​​情况,也许它会随着未来的版本而改变。我想要一些更“官方”的方法来确定是否存在错误,但我的搜索结果已经枯竭——所以我谦虚地请求你们所有的 k8s 专家提供指导。谢谢 !

Pod 部署代码

import com.fasterxml.jackson.databind.ObjectMapper
import scala.collection.JavaConverters._
import com.ning.http.client.ws.WebSocket
import com.typesafe.scalalogging.StrictLogging
import io.fabric8.kubernetes.api.model.{DoneableNamespace, Namespace, Pod, ReplicationController}
import io.fabric8.kubernetes.client.DefaultKubernetesClient.ConfigBuilder
import io.fabric8.kubernetes.client.Watcher.Action
import io.fabric8.kubernetes.client.dsl.Resource
import io.fabric8.kubernetes.client.{DefaultKubernetesClient, Watcher}

object ErrorTest extends App with StrictLogging {
  // corresponds to --insecure-skip-tls-verify=true, according to io.fabric8.kubernetes.api.model.Cluster
  val trustCerts = true
  val k8sUrl = "http://localhost:8080"
  val namespaceName = "junk" // replace this with name of a namespace that you know exists
  val imageName: String = "nginx"

  def go(): Unit = {
    val kube = getConnection
    dumpNamespaces(kube)
    deployPodWithWatch(kube, getPod(image = imageName))
  }

  def deployPodWithWatch(kube: DefaultKubernetesClient, pod: Pod): Unit = {
    kube.pods().inNamespace(namespaceName).create(pod) /*  create the pod ! */
    val podWatchWebSocket: WebSocket =                /* create watch on the pod */
      kube.pods().inNamespace(namespaceName).withName(pod.getMetadata.getName).watch(getPodWatch)
  }

  def getPod(image: String): Pod = {
    val jsonTemplate =
      """
    |{
    | "kind": "Pod",
    | "apiVersion": "v1",
    | "metadata": {
    |   "name": "podboy",
    |   "labels": {
    |     "app": "nginx"
    |   }
    | },
    | "spec": {
    |   "containers": [
    |     {
    |     "name": "podboy",
    |     "image": "<image>",
    |     "ports": [
    |       {
    |         "containerPort": 80,
    |         "protocol": "TCP"
    |       }
    |     ]
    |     }
    |   ]
    | }
    |}
      """.
    stripMargin
    val replacement: String = "image\": \"" + image
    val json = jsonTemplate.replaceAll("image\": \"<image>", replacement)
    System.out.println("json:" + json);
    new ObjectMapper().readValue(json, classOf[Pod])
  }

  def dumpNamespaces(kube: DefaultKubernetesClient): Unit = {
    val namespaceNames = kube.namespaces().list().getItems.asScala.map {
      (ns: Namespace) => {
    ns.getMetadata.getName
      }
    }
    System.out.println("namespaces are:" + namespaceNames);
  }

  def getConnection = {
    val configBuilder = new ConfigBuilder()
    val config =
      configBuilder.
    trustCerts(trustCerts).
    masterUrl(k8sUrl).
    build()
    new DefaultKubernetesClient(config)
  }

  def getPodWatch: Watcher[Pod] = {
    new Watcher[Pod]() {
      def eventReceived(action: Action, watchedPod: Pod) {
       System.out.println("got action: " + action + " / "  + watchedPod)
      }
    }
  }

  go()
}
4

1 回答 1

1

我建议您查看事件,请参阅此主题以获得一些指导。通常,每个对象都应该生成您可以观看的事件并收到此类错误的通知。

于 2016-05-05T08:35:39.163 回答