Java-приложение не может подключиться к локальному модулю Mysql, запущенному на Minikube - PullRequest
0 голосов
/ 09 марта 2019

У меня загрузочное приложение Java Spring, развернутое на локальном кластере Minikube, работающем на моем компьютере.

Приложение Java подключается к базе данных mysql и принимает конфигурацию во время выполнения, используя конфигурацию источника данных.Это класс конфигурации БД:

public class DatasourceConfig {
  @Bean
  @Primary
  public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setUrl(System.getProperty("mysql_user"));
    dataSource.setUsername(System.getProperty("mysql_user"));
    dataSource.setPassword(System.getProperty("mysql_pass"));

    return dataSource;
  }
}

Я передаю значения для mysql_url, mysql_pass, mysql_user во время выполнения, как это (из Dockerfile):

ENTRYPOINT java -Dmysql_url=$mysql_url \
    -Dmysql_user=$mysql_user \
    -Dmysql_pass=$mysql_pass \
    -jar myapp.jar

Я создал другой модуль pod / развертывание для локального образа контейнера MySQL и открыл его через службу локально.

Это файл mysql.yml для kubernetes:

apiVersion: v1
kind: Service
metadata:
  name: mysql-svc
  labels:
    app: mysql
spec:
  ports:
  - port: 3306
    nodePort: 30306
    targetPort: mysql-port
    protocol: TCP
  selector:
    app: mysql
  type: NodePort 
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    app: mysql
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
  labels:
    app: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
        tier: mysql
    spec:
      containers:
      - name: mysql
        image: mysql
        imagePullPolicy: Never
        ports:
          - name: mysql-port
            containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: pass
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim

Итак, теперьУ меня есть две из них: pods + deploy + services, работающие на Minikube, одна для моего приложения и другая для контейнера mysql: (ниже вывод kubectl get all

NAME                                    READY   STATUS    RESTARTS   AGE
pod/mysql-deployment-8464d4875d-jlszz   1/1     Running   0          168m
pod/myapp-deployment-6469d8554b-4sbhz   1/1     Running   0          38m

NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/kubernetes  ClusterIP   10.96.0.1        <none>        443/TCP          7d
service/mysql-svc   NodePort    10.105.186.178   <none>        3306:30306/TCP   168m
service/myapp-svc   NodePort    10.96.243.6      <none>        8080:31001/TCP   41m

NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mysql-deployment       1/1     1            1           168m
deployment.apps/myapp-deployment   1/1     1            1           41m

NAME                                          DESIRED   CURRENT   READY   AGE
replicaset.apps/mysql-deployment-8464d4875d   1         1         1       168m
replicaset.apps/myapp-deployment-6469d8554b   1         1         1       41m

Я могу правильно запустить приложение java с хостамашина, выполнив это:

minikube service myapp-svc

, и я также могу подключиться к Mysql с хост-машины, выполнив это:

run minikube service mysql-svc --url, что дает мне: http://<mysql-ip>:30306

и затем я могу подключиться к нему следующим образом (с хост-компьютера):

mysql -h <mysql-ip> -P 30306 -u root -p.

Это правильно соединяет меня с MySQL, работающим налокальный кластер kubernetes через Minikube.

Я даже могу подключиться к службе MySQL изнутри JAVконтейнер, работающий на миникубе:

сначала я подключаюсь к java-модулю следующим образом:

kubectl exec -it myapp-deployment-6469d8554b-4sbhz /bin/bash

, а затем запускаю mysql -h <mysql-ip> -P 30306 -u root -p внутри модуля.Это также правильно связывает меня с mysql, работающим внутри другого модуля.

Единственная проблема заключается в следующем:

Изнутри модуля Java при проверке журналов приложений, Я вижу это:

ОШИБКА 1 --- [main] com.zaxxer.hikari.pool.HikariPool: HikariPool-1 - исключение при инициализации пула.

com.mysql.cj.jdbc.exceptions.CommunicationsException: сбой линии связи

Последний пакет, успешно отправленный на сервер, был 0 миллисекунд назад.Драйвер не получил никаких пакетов от сервера.

, а также, когда я пытаюсь вызвать любой из API, в котором есть операции с базой данных, я получаю следующую ошибку: Unable to acquire JDBC Connection; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection

Это означает, что мой код Java фактически не может подключиться к MySql, развернутому на другом модуле.

Я проверил, что модуль Java успешно может подключиться к модулю Mysql, тогда почемумой Java-код не может подключиться ??

Я даже подтвердил, что могу запускать Java-образ Docker локально, передавая URL-адрес mysql модуля, развернутого в minikube, следующим образом:

docker run -e mysql_url=jdbc:mysql://<mysql-ip>:<mysql-port>/my_db \
    -e mysql_user=root \
    -e mysql_pass=pass \
    --rm -p 8081:8080 --name myApp -it me/myapp

Это подтверждает, что мой Java-код правильно настроен для подключения к MySQL (даже тот, который развернут на модуле), когда я запускаю его локально.

Итак, мне кажется, что в основном все настроено правильно..

  • Сам модуль mysql работает правильно, что я проверил, сначала подключившись к нему с помощью локального клиента mysql.
  • Java code iможет подключиться к MySQL, запущенному на Minikube, когда я запускаю образ Docker локально.
  • Модуль Java на Minikube может подключаться к модулю mysql, что я проверил, подключившись к модулю mysql из модуля java с помощью клиента mysql из bash.
  • Код Java такжевыполняется (без подключения к базе данных).

Единственное, что не работает, - это то, что приложение Java, развернутое внутри Minikube, не может подключиться к mysql, развернутому в другом модуле.

Для этого единственная точка отказа, о которой я могу думать, - это способ, которым Kubernetes передает переменные ENV в образ докера во время его запуска. Но я даже подтвердил это, запустив env внутриBash работает на моем модуле Java.который показал, что все необходимые переменные среды установлены там правильно.

Это мой файл развертывания для Java:

myapp.deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: me/myapp
        imagePullPolicy: Never
        env:
        - name: mysql_url
          value: jdbc:mysql://<mysql-ip>:30306/my_db
        - name: mysql_user
          value: root
        - name: mysql_pass
          value: pass
        ports:
          - name: java-port
            containerPort: 8080

Должен ли я также определить определение модуля и предоставить там переменные ENV?

Есть ли здесь что-то еще, что мне нужно сделать?

Как я могу это исправить?

PS : я уже запустил eval $(minikube docker-env) в моем текущем окне терминала, чтобы локальные образы док-станции были доступны для Minikube.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...