这篇文章给大家介绍如何解决DataFlow部署K8s应用的问题,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
基于各种原因,团队的Kubernetes
被加了限制,必须在特定的Node
才可以部署。而之前没有指定,所以Spring Cloud Data Flow
在跑Task
时失败了,无法创建Pod
。按照Spring
官方文档配置也一直没用,后面查看源码、修改源码增加日志后终于解决了。
在自己定义yaml
文件,并通过kubectl apply
部署时,所添加的限制节点的内容是这样的:
spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: beta.kubernetes.io/os operator: In values: - linux containers: - name: php-apache image: 'pkslow/hpa-example:latest' ports: - containerPort: 80 protocol: TCP resources: requests: cpu: 200m imagePullPolicy: IfNotPresent
这样设置是可以成功部署的。
修改Data Flow
的配置如下:
spring: cloud: dataflow: task: platform: kubernetes: accounts: default: limits: memory: 1024Mi affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: beta.kubernetes.io/os operator: In values: - linux datasource: url: jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT}/mysql username: root password: ${mysql-root-password} driverClassName: org.mariadb.jdbc.Driver testOnBorrow: true validationQuery: "SELECT 1"
通过Spring Cloud Data Flow
发布Task
,报错如下:
Pods in namespace pkslow can only map to specific nodes, status=Failure
查看官网,按照官方的格式修改配置:
修改如下:
spring: cloud: dataflow: task: platform: kubernetes: accounts: default: limits: memory: 1024Mi affinity: nodeAffinity: { requiredDuringSchedulingIgnoredDuringExecution: { nodeSelectorTerms: [ { matchExpressions: [ { key: 'beta.kubernetes.io/os', operator: 'In', values: [ 'linux']}]}]}}
依旧报错。改成affinity.nodeAffinity=xxx
,还是报错。加引号,也没用。
查看日志,也没有太多信息。
折腾了许久,也没太大进展。于是就查看源码了。
下载了Spring Cloud Data Flow的源码,看了一下,没有多大用处,最终发布到Kubernetes
是通过Spring Cloud Deployer Kubernetes
来发布的,于是又下载了它的源码。要注意不要下载错了版本,我们用的是2.4.0
版本。或者直接下载所有,然后切换到对应分支:
$ git clone https://github.com/spring-cloud/spring-cloud-deployer-kubernetes.git Cloning into 'spring-cloud-deployer-kubernetes'... remote: Enumerating objects: 65, done. remote: Counting objects: 100% (65/65), done. remote: Compressing objects: 100% (46/46), done. remote: Total 4201 (delta 26), reused 42 (delta 8), pack-reused 4136 Receiving objects: 100% (4201/4201), 738.79 KiB | 936.00 KiB/s, done. Resolving deltas: 100% (1478/1478), done. $ cd spring-cloud-deployer-kubernetes/ $ git branch * master $ git checkout 2.4.0 Branch '2.4.0' set up to track remote branch '2.4.0' from 'origin'. Switched to a new branch '2.4.0' $ git branch * 2.4.0 master
先build
一下,确保成功:
$ mvn clean install -DskipTests
查看源码,也看不出为何配置没有生效,于是在关键点打些日志出来看看。找到发布Task
的入口:
KubernetesTaskLauncher#launch(AppDeploymentRequest)
即类KubernetesTaskLauncher
的launch
方法。开始追踪创建Kubernetes Pod
的过程。
KubernetesTaskLauncher#launch(AppDeploymentRequest) KubernetesTaskLauncher#launch(String, AppDeploymentRequest) AbstractKubernetesDeployer#createPodSpec DeploymentPropertiesResolver#getAffinityRules
然后在整个调用链增加日志打印,注意日志要加上特殊字符串,增加识别性,如:
logger.info("***pkslow log***:" + affinity.toString());
追加了日志后,重新build
包,替换掉Data Flow
引入的jar
包,重新发布即可测试。
通过新加的日志,发现设置的Properties
一直就是没有生效的,但为何没生效尚未得知。
折腾了一圈还是没解决,但项目又要急着使用,于是想了个办法,先修改源码,自己根据属性使其生效:
如果没有读取到Affinity
,就自己生成一个。
重新打包、替换、部署后,不再报错,能正常执行Task
了。
之前的方案只是暂时解决,并不是一个好的办法,还是要搞清楚为何配置没有生效。于是再次查看源码。在查看类KubernetesDeployerProperties
的时候,发现了一点端倪:
这里的字段是没有Affinity
的。
另外,从测试用例入手(这是一个很好的思维,测试用例能告诉你很多信息),看到了DataFlow
配置用例,如下:
所以,应该是不用配置前缀Affinity
的,修改后配置如下:
spring: cloud: dataflow: task: platform: kubernetes: accounts: default: limits: memory: 1024Mi nodeAffinity: { requiredDuringSchedulingIgnoredDuringExecution: { nodeSelectorTerms: [ { matchExpressions: [ { key: 'beta.kubernetes.io/os', operator: 'In', values: [ 'linux']}]}]}}
重新部署后,可以了!!!
这一次确实是被Spring
坑了一把,没有明确给出配置的示例,然后官方文档给的提示也是极其误导。一开始很难想到是不用前缀Affinity
的,因为Kubernetes
的标准配置是有的,而Spring
的官方文档提示也是有的。实在太坑了!
还好,通过查看源码及调试,终于解决了这个问题。
关于如何解决DataFlow部署K8s应用的问题就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。