在Kubernetes中,从.json或.yaml规范实例化资源时接收错误通知的最佳方法是什么?

在Kubernetes中,从.json或.yaml规范实例化资源时接收错误通知的最佳方法是什么?,kubernetes,fabric8,Kubernetes,Fabric8,我正在使用fabric8在Kubernetes之上开发一个集群管理层,我不知道 “官方”API用于在出现问题时获取错误通知 实例化POD/rep控制器和服务等 在“吊舱部署代码”一节中,我有一个我们为吊舱所做的精简版本。万一 只要一切正常,我们的代码就可以了。我们依靠设置“手表”为您服务 可以在方法deployPodWithWatch中查看。我在给定的eventReceived回调中所做的一切 是打印事件,但我们真正的代码将分解如下通知: got action: MODIFIED /

我正在使用fabric8在Kubernetes之上开发一个集群管理层,我不知道 “官方”API用于在出现问题时获取错误通知 实例化POD/rep控制器和服务等

在“吊舱部署代码”一节中,我有一个我们为吊舱所做的精简版本。万一 只要一切正常,我们的代码就可以了。我们依靠设置“手表”为您服务 可以在方法
deployPodWithWatch
中查看。我在给定的
eventReceived
回调中所做的一切 是打印事件,但我们真正的代码将分解如下通知:

got action: 
    MODIFIED / 
      Pod(apiVersion=v1, kind=Pod, metadata=...etc etc
        status=PodStatus(
            conditions=[
 state=ContainerState(running=null, terminated=null, 
        waiting=ContainerStateWaiting(
            reason=API error (500): 
                Error parsing reference: 
                    "nginBoo" is not a valid repository/tag
然后选择Pod的“status”元素,当我们得到PodCondition(status=True,type=Ready)时,我们就知道了 我们的吊舱已经成功部署

在“快乐之路”案例中,这非常有效。实际上,您可以运行随变量提供的代码 k8sUrl为您的站点设置正确的url(希望是您的k8s) 安装不需要特定于站点的auth,因此我没有提供相关代码)

但是,假设您将变量
imageName
更改为“nginBoo”。没有公共码头工人 该名称的图像,因此在运行代码后,将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
我想实现一个watch回调,以便它捕获这些类型的错误。然而, 我唯一看到的是“修改”事件,其中Pod具有如下字段:

got action: 
    MODIFIED / 
      Pod(apiVersion=v1, kind=Pod, metadata=...etc etc
        status=PodStatus(
            conditions=[
 state=ContainerState(running=null, terminated=null, 
        waiting=ContainerStateWaiting(
            reason=API error (500): 
                Error parsing reference: 
                    "nginBoo" is not a valid repository/tag
我想我可以寻找一个包含字符串“API error”的原因码,但这似乎 在很大程度上是一种依赖于实现的黑客——它可能不会涵盖所有情况,也许会 用未来的版本在我脚下改变。我想要一些更“正式”的方式 弄清楚是否有错误,但我的搜索结果已经干涸了——所以我谦虚地说 请所有k8s专家提供指导。谢谢

吊舱部署代码

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()
}
import com.fasterxml.jackson.databind.ObjectMapper
导入scala.collection.JavaConverters_
导入com.ning.http.client.ws.WebSocket
导入com.typesafe.scalalogging.StrictLogging
导入io.fabric8.kubernetes.api.model.{DoneableNamespace,Namespace,Pod,ReplicationController}
导入io.fabric8.kubernetes.client.DefaultKubernetesClient.ConfigBuilder
导入io.fabric8.kubernetes.client.Watcher.Action
导入io.fabric8.kubernetes.client.dsl.Resource
导入io.fabric8.kubernetes.client.{DefaultKubernetesClient,Watcher}
对象错误测试使用StrictLogging扩展应用程序{
//根据io.fabric8.kubernetes.api.model.Cluster,对应于--unsecure skip tls verify=true
val trustCerts=true
val k8sUrl=”http://localhost:8080"
val namespaceName=“junk”//将其替换为已知存在的命名空间的名称
val imageName:String=“nginx”
def go():单位={
val kube=getConnection
dumpnamespace(kube)
deployPodWithWatch(kube,getPod(image=imageName))
}
def deployPodWithWatch(kube:DefaultKubernetesClient,pod:pod):单位={
kube.pods().inNamespace(namespaceName).create(pod)/*创建pod*/
val podWatchWebSocket:WebSocket=/*在pod上创建监视*/
kube.pods().inNamespace(namespaceName).withName(pod.getMetadata.getName).watch(getPodWatch)
}
def getPod(图像:字符串):Pod={
val jsonTemplate=
"""
|{
|“种类”:“豆荚”,
|“apiVersion”:“v1”,
|“元数据”:{
|“名字”:“播客”,
|“标签”:{
|“应用程序”:“nginx”
|   }
| },
|“规格”:{
|“容器”:[
|     {
|“名字”:“播客”,
|“图像”:“,
|“港口”:[
|       {
|“集装箱港口”:80,
|“协议”:“TCP”
|       }
|     ]
|     }
|   ]
| }
|}
""".
条纹边缘
val替换:String=“image\”:\“”+image
val json=jsonTemplate.replaceAll(“图像\:\”,替换)
System.out.println(“json:+json”);
新的ObjectMapper().readValue(json,classOf[Pod])
}
def转储名称空间(kube:DefaultKubernetesClient):单位={
val namespaceNames=kube.namespaces().list().getItems.asScala.map{
(ns:名称空间)=>{
ns.getMetadata.getName
}
}
System.out.println(“名称空间是:“+名称空间名称”);
}
def getConnection={
val configBuilder=新的configBuilder()
val配置=
configBuilder。
信任证书(trustCerts)。
主URL(k8sUrl)。
构建()
新的DefaultKubernetesClient(配置)
}
def getPodWatch:Watcher[Pod]={
新观察者[Pod](){
收到def事件(操作:操作,监视Pod:Pod){
System.out.println(“获得操作:“+action+”/“+watchedPod”)
}
}
}
go()
}

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

是。这是有道理的。一位同事@work提出了同样的建议。谢谢