问题描述
我正在使用带有Kubernetes 1.16的Helm v3.3.0。
集群已安装Kubernetes Service Catalog,因此可以将实现Open Service Broker API规范的外部服务实例化为K8S资源-ServiceInstance
和ServiceBinding
。
ServiceBinding
反映为K8S Secret
并包含创建的外部服务的绑定信息。这些秘密通常作为环境变量或卷在K8S Deployment
中映射到Docker容器中。
现在我正在使用Helm部署我的Kubernetes资源,我读到here了...
Kubernetes类型的[Helm]安装顺序由kind_sorter.go中的枚举InstallOrder给出
在该文件中,该订单既未提及ServiceInstance
也未提及ServiceBinding
作为资源,这意味着Helm在安装了其任何之后安装了这些资源类型InstallOrder列表-特别是Deployment
。这似乎与我的图表上运行的helm install --dry-run --debug
的输出相匹配,该顺序指示K8S服务目录资源最后被应用。
问题:我不明白的是,为什么我的Deployment
不能不能无法通过Helm安装。
毕竟我的Deployment
资源似乎早于ServiceBinding
就已经部署了。我的Secret
引用的是ServiceBinding
生成的Deployment
。我希望它会失败,因为在安装Secret
时Deployment
还不存在。但是事实并非如此。
是只是时间故障/幸运的巧合,还是我可以依靠的东西?为什么?
谢谢!
解决方法
所以要回答我自己的问题(并感谢@ dawid-kruk和Slack上Service Catalog Sig的工作人员):
- 实际上,我的
<div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>
(从Pod
中创建的引用Secret
的那些)的初始启动失败了!之所以失败,是因为K8S尝试启动Pod时实际上ServiceBinding
不在。 - Kubernetes具有自我修复机制,即它可以尝试(并重试)达到集群的目标状态(如各种已部署资源所描述的那样)。
- 通过Kubernetes尝试使Pod运行,最终(当
Secret
终于出现时)将满足所有条件,以使Pod正常启动。因此,最终,evth。正在正常运行。
如何精简呢?对于Helm,一种可能性是将自定义资源Secret
和ServiceBinding
包括在其可安装资源的有序列表中,并在安装阶段的早期进行安装。
但是即使没有这个,Kubernetes实际上也能很好地处理它。安装的顺序(在这种情况下)确实无关紧要。那是一件好事!
,正如我在评论中所说:
实际上,您的
Deployment
从Status: CreateContainerConfigError
开始就失败了。您的Deployment
是在Secret
的{{1}}之前创建的。只有ServiceBinding
中的Secret
可用时,它才能重新创建。
我想通过ServiceBinding
为什么没有失败的示例来提供更多见识。
正在发生的事情(按顺序简化):
-
Deployment
->创建并产生一个Deployment
-
Pod
->由于缺少Pod
而导致状态为CreateContainerConfigError
的pod失败 -
Secret
->在后台创建ServiceBinding
-
Secret
获得必需的Pod
并启动
先前提到的Secret
将对line 147发表评论,最后保留InstallOrder
和ServiceInstace
。
示例
假设:
- 有一个有效的Kubernetes集群
- Helm3已安装并可以使用
以下指南:
ServiceBinding
目录中有一个Helm图表,其中包含以下文件:
-
templates/
-
ServiceInstance
-
ServiceBinding
文件:
Deployment
:
ServiceInstance.yaml
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
name: example-instance
spec:
clusterServiceClassExternalName: redis
clusterServicePlanExternalName: 5-0-4
:
ServiceBinding.yaml
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
name: example-binding
spec:
instanceRef:
name: example-instance
:
Deployment.yaml
使用上述资源来检查正在发生的事情可以通过两种方式完成:
- 第一种方法是使用
apiVersion: apps/v1 kind: Deployment metadata: name: ubuntu spec: selector: matchLabels: app: ubuntu replicas: 1 template: metadata: labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu command: - sleep - "infinity" # part below responsible for getting secret as env variable env: - name: DATA valueFrom: secretKeyRef: name: example-binding key: host
中的timestamp
- 第二种方法是使用
$ kubectl get RESOURCE -o yaml
第一种方法
如前所述,$ kubectl get RESOURCE --watch-only=true
中的Pod
无法启动,因为Deployment
尝试生成时Secret
不可用。 Pod
可用后,Secret
开始。
此Pod
的状态如下:
-
Pod
-
Pending
-
ContainerCreating
-
CreateContainerConfigError
这是一个时间戳为Running
和Pod
的表:
Secret
您可以通过调用以下命令获取此时间戳:
-
| Pod | Secret | |-------------------------------------------|-------------------------------------------| | creationTimestamp: "2020-08-23T19:54:47Z" | - | | - | creationTimestamp: "2020-08-23T19:54:55Z" | | startedAt: "2020-08-23T19:55:08Z" | - |
-
$ kubectl get pod pod_name -n namespace -o yaml
您还可以通过以下方式获取其他信息:
-
$ kubectl get secret secret_name -n namespace -o yaml
-
$ kubectl get event -n namespace
第二种方法
此方法需要运行Helm图表之前进行准备。打开另一个终端窗口(对于这种特殊情况2)并运行:
-
$ kubectl describe pod pod_name -n namespace
-
$ kubectl get pod -n namespace --watch-only | while read line ; do echo -e "$(gdate +"%H:%M:%S:%N")\t $line" ; done
之后,应用您的Helm图表。
免责声明!
以上命令将监视资源的更改,并通过操作系统显示时间戳。请记住,此命令仅用于示例目的。
$ kubectl get secret -n namespace --watch-only | while read line ; do echo -e "$(gdate +"%H:%M:%S:%N")\t $line" ; done
的输出:
Pod
21:54:47:534823000 NAME READY STATUS RESTARTS AGE
21:54:47:542107000 ubuntu-65976bb789-l48wz 0/1 Pending 0 0s
21:54:47:553799000 ubuntu-65976bb789-l48wz 0/1 Pending 0 0s
21:54:47:655593000 ubuntu-65976bb789-l48wz 0/1 ContainerCreating 0 0s
-> 21:54:52:001347000 ubuntu-65976bb789-l48wz 0/1 CreateContainerConfigError 0 4s
21:55:09:205265000 ubuntu-65976bb789-l48wz 1/1 Running 0 22s
的输出:
Secret
其他资源: