Java 作为 Pod 工作的容器在 Job 中不工作
Java container that works as a Pod not working in a Job
我正在尝试使用包含 Java 工具的容器在 Kubernetes 作业中的 MySQL 数据库上执行一些数据库迁移。
当我在 Docker 中本地 运行 容器时(使用同一网络中的 MySQL 容器),工具 运行s 如预期。
如果我使用容器创建一个 Pod,并将命令参数设置为指向同一命名空间中的 mysql
服务 运行ning,它也会这样做。
但是如果我将该 Pod 规范转换为作业,创建的容器由于某种原因无法再连接到 MySQL 服务。
容器基于amazoncorretto:8-al2-jdk
,只是将JAR复制到/opt/
。
MySQL 数据库可通过集群中的 mysql
服务获得:
$ kubectl describe service mysql -n <namespace>
Name: mysql
Namespace: <namespace>
Labels: app=mysql
Annotations: <none>
Selector: app=mysql
Type: ClusterIP
IP Families: <none>
IP: <ip>
IPs: <ip>
Port: mysql 3306/TCP
TargetPort: 3306/TCP
Endpoints: <ip>:3306
Session Affinity: None
Events: <none>
Pod 的规格如下:
apiVersion: v1
kind: Pod
metadata:
name: java-tool-pod
spec:
containers:
- name: javatool
image: <registry>/<image-name>:<version>
command: [ "/bin/sh" ]
args: [ "-x", "-c", "/usr/bin/java -jar /opt/<tool>.jar \"jdbc:mysql://mysql:3306/<db>\" -u <user> -p<password>" ]
imagePullSecrets:
- name: <secret>
运行 容器作为 Pod:
$ kubectl apply -f /tmp/as-pod.yaml -n <namespace>
pod/java-tool-pod created
$ kubectl logs pod/java-tool-pod -n <namespace>
+ /usr/bin/java -jar /opt/<tool>.jar jdbc:mysql://mysql:3306/<db> -u <user> -p<password>
DB Migration Tool
Database Schema, 3.30.0.3300024390, built Wed Jul 14 12:13:52 UTC 2021
Driver class: com.mysql.jdbc.Driver
INFO Flyway 3.2.1 by Boxfuse
INFO Database: jdbc:mysql://mysql:3306/<db> (MySQL 5.7)
INFO Validated 721 migrations (execution time 00:00.253s)
INFO Current version of schema `<db>`: 3.29.0.10859.10
WARN outOfOrder mode is active. Migration of schema `<db>` may not be reproducible.
INFO Schema `<db>` is up to date. No migration necessary.
这些是作业的规格:
$ cat /tmp/as-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: javatool-job
spec:
template:
spec:
containers:
- name: javatool
image: <registry>/<image-name>:<version>
command: [ "/bin/sh" ]
args: [ "-x", "-c", "/usr/bin/java -jar /opt/<tool>.jar \"jdbc:mysql://mysql:3306/<db>\" -u <user -p<password>" ]
imagePullSecrets:
- name: <secret>
restartPolicy: Never
运行 作为作业的容器:
$ kubectl apply -f /tmp/as-job.yaml -n <namespace>
job.batch/javatool-job created
$ kubectl logs job.batch/javatool-job -n <namespace>
+ /usr/bin/java -jar /opt/<tool>.jar jdbc:mysql://mysql:3306/<db> -u <user> -p<password>
DB Migration Tool
Database Schema, 3.30.0.3300024390, built Wed Jul 14 12:13:52 UTC 2021
Driver class: com.mysql.jdbc.Driver
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:983)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:339)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2252)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2285)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2084)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:795)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:44)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:400)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:327)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:208)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:173)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:164)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:153)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:119)
at com.nordija.itv.db.FlywayMigrationSchemaData.isNotFlywaySchemaVersion(FlywayMigrationSchemaData.java:58)
[...]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:607)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:214)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:298)
... 22 more
INFO Flyway 3.2.1 by Boxfuse
Unable to obtain Jdbc connection from DataSource
[...]
我没有发现创建的容器有任何显着差异。
我唯一能想到的是某种字符编码问题,但我不明白为什么这只应该发生在为作业创建的 Pod 中,而不是直接创建的 Pod 中。
提前感谢您对此问题的任何帮助!
编辑: 我忘了提到 Istio 在命名空间上处于活动状态,结果导致了问题。
错误消息是“通信 link 失败”。所以我认为你应该看看你的网络策略。
问题是 Istio 不能很好地与 Kubernetes Jobs 配合使用(抱歉,我忘了说 Istio 在命名空间上是活跃的)。
一旦我添加了一个短暂的延迟(sleep 5
在启动 Java 工具之前),就可以建立连接。
但后来我遇到了另一个问题:容器成功终止后,Job 不会被标记为已完成。
原因又是 Istio。
一旦 all Pods 终止并且 Istio Sidecar 是一个不会终止的服务 Pod,作业就被认为是完成的。
在容器中找到 this article, I ended up integrating their scuttle
工具后,现在作业可以成功完成。
我正在尝试使用包含 Java 工具的容器在 Kubernetes 作业中的 MySQL 数据库上执行一些数据库迁移。
当我在 Docker 中本地 运行 容器时(使用同一网络中的 MySQL 容器),工具 运行s 如预期。
如果我使用容器创建一个 Pod,并将命令参数设置为指向同一命名空间中的 mysql
服务 运行ning,它也会这样做。
但是如果我将该 Pod 规范转换为作业,创建的容器由于某种原因无法再连接到 MySQL 服务。
容器基于amazoncorretto:8-al2-jdk
,只是将JAR复制到/opt/
。
MySQL 数据库可通过集群中的 mysql
服务获得:
$ kubectl describe service mysql -n <namespace>
Name: mysql
Namespace: <namespace>
Labels: app=mysql
Annotations: <none>
Selector: app=mysql
Type: ClusterIP
IP Families: <none>
IP: <ip>
IPs: <ip>
Port: mysql 3306/TCP
TargetPort: 3306/TCP
Endpoints: <ip>:3306
Session Affinity: None
Events: <none>
Pod 的规格如下:
apiVersion: v1
kind: Pod
metadata:
name: java-tool-pod
spec:
containers:
- name: javatool
image: <registry>/<image-name>:<version>
command: [ "/bin/sh" ]
args: [ "-x", "-c", "/usr/bin/java -jar /opt/<tool>.jar \"jdbc:mysql://mysql:3306/<db>\" -u <user> -p<password>" ]
imagePullSecrets:
- name: <secret>
运行 容器作为 Pod:
$ kubectl apply -f /tmp/as-pod.yaml -n <namespace>
pod/java-tool-pod created
$ kubectl logs pod/java-tool-pod -n <namespace>
+ /usr/bin/java -jar /opt/<tool>.jar jdbc:mysql://mysql:3306/<db> -u <user> -p<password>
DB Migration Tool
Database Schema, 3.30.0.3300024390, built Wed Jul 14 12:13:52 UTC 2021
Driver class: com.mysql.jdbc.Driver
INFO Flyway 3.2.1 by Boxfuse
INFO Database: jdbc:mysql://mysql:3306/<db> (MySQL 5.7)
INFO Validated 721 migrations (execution time 00:00.253s)
INFO Current version of schema `<db>`: 3.29.0.10859.10
WARN outOfOrder mode is active. Migration of schema `<db>` may not be reproducible.
INFO Schema `<db>` is up to date. No migration necessary.
这些是作业的规格:
$ cat /tmp/as-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: javatool-job
spec:
template:
spec:
containers:
- name: javatool
image: <registry>/<image-name>:<version>
command: [ "/bin/sh" ]
args: [ "-x", "-c", "/usr/bin/java -jar /opt/<tool>.jar \"jdbc:mysql://mysql:3306/<db>\" -u <user -p<password>" ]
imagePullSecrets:
- name: <secret>
restartPolicy: Never
运行 作为作业的容器:
$ kubectl apply -f /tmp/as-job.yaml -n <namespace>
job.batch/javatool-job created
$ kubectl logs job.batch/javatool-job -n <namespace>
+ /usr/bin/java -jar /opt/<tool>.jar jdbc:mysql://mysql:3306/<db> -u <user> -p<password>
DB Migration Tool
Database Schema, 3.30.0.3300024390, built Wed Jul 14 12:13:52 UTC 2021
Driver class: com.mysql.jdbc.Driver
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:983)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:339)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2252)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2285)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2084)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:795)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:44)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:400)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:327)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:208)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:173)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:164)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:153)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:119)
at com.nordija.itv.db.FlywayMigrationSchemaData.isNotFlywaySchemaVersion(FlywayMigrationSchemaData.java:58)
[...]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:607)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:214)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:298)
... 22 more
INFO Flyway 3.2.1 by Boxfuse
Unable to obtain Jdbc connection from DataSource
[...]
我没有发现创建的容器有任何显着差异。 我唯一能想到的是某种字符编码问题,但我不明白为什么这只应该发生在为作业创建的 Pod 中,而不是直接创建的 Pod 中。
提前感谢您对此问题的任何帮助!
编辑: 我忘了提到 Istio 在命名空间上处于活动状态,结果导致了问题。
错误消息是“通信 link 失败”。所以我认为你应该看看你的网络策略。
问题是 Istio 不能很好地与 Kubernetes Jobs 配合使用(抱歉,我忘了说 Istio 在命名空间上是活跃的)。
一旦我添加了一个短暂的延迟(sleep 5
在启动 Java 工具之前),就可以建立连接。
但后来我遇到了另一个问题:容器成功终止后,Job 不会被标记为已完成。
原因又是 Istio。
一旦 all Pods 终止并且 Istio Sidecar 是一个不会终止的服务 Pod,作业就被认为是完成的。
在容器中找到 this article, I ended up integrating their scuttle
工具后,现在作业可以成功完成。