Ax ios в контейнере Node.js в Kubernetes возвращает "ECONNREFUSED 127.0.0.1:30561"? - PullRequest
0 голосов
/ 20 января 2020

Полное сообщение об ошибке: connect ECONNREFUSED 127.0.0.1:30561 at TCPConnectWrap.afterConnect

Запрос axe ios выполняется в среде Node.js (Next. js), где и происходит ошибка, как ни странно, ax ios запрос отлично работает, когда он запускается в браузере.

Мой компонент (работает в Node.js), который вызывает ax ios:

import axios from 'axios'
import Router from 'next/router'
import React, { Component } from 'react'
import { initializeStore } from '~/reducers'
import { authenticate } from '~/actions/auth'
import { getCookieByName } from '~/helpers/cookie'

const isServer = typeof window === 'undefined'
const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__'

function getOrCreateStore(initialState) {
    // Always make a new store if server, otherwise state is shared between requests
    if (isServer) {
        return initializeStore(initialState)
    }
    // Create store if unavailable on the client and set it on the window object
    if (!window[__NEXT_REDUX_STORE__]) {
        window[__NEXT_REDUX_STORE__] = initializeStore(initialState)
    }
    return window[__NEXT_REDUX_STORE__]
}

export default App => {
    return class AppWithRedux extends Component {
        static async getInitialProps(appContext) {

            const reduxStore = getOrCreateStore()
            
            appContext.ctx.reduxStore = reduxStore

            let appProps = {}

            if (typeof App.getInitialProps === 'function') {
                appProps = await App.getInitialProps(appContext)
            }

            const JWT = (isServer ? getCookieByName('JWT', appContext.ctx.req.headers.cookie) : getCookieByName('JWT', document.cookie))

            const pathname = appContext.ctx.pathname

            //set axios baseURL
            axios.defaults.baseURL = (isServer ? `${appContext.ctx.req.headers['x-forwarded-proto']}://${appContext.ctx.req.headers.host}` : window.location.origin)

            //if user has a JWT
            if(JWT){
                axios.defaults.headers.common['Authorization'] = `Bearer ${JWT}`
                //get user from API layer
                reduxStore.dispatch(authenticate())
            } 

            
            return {
                ...appProps,
                initialReduxState: reduxStore.getState()
            }
        }

        constructor(props) {
            super(props)
            this.reduxStore = getOrCreateStore(props.initialReduxState)
        }

        render() {
            return <App {...this.props} reduxStore={this.reduxStore} />
        }
    }
}

В частности reduxStore.dispatch(authenticate())

И мой фактический вызов топора ios (с использованием избыточного толка), глядя на метод authenticate:

import axios from 'axios'
import { setCookieByName } from '~/helpers/cookie'

const BASE_URL = '/api/auth'
export const TYPE_REGISTER = 'TYPE_REGISTER'
export const TYPE_AUTHENTICATE = 'TYPE_AUTHENTICATE'

export const register = values => (dispatch) => {
    return axios.post(`${BASE_URL}/register`, values)
        .then(function({data: {token, user}}){
            setCookieByName('JWT', token, 365)
            dispatch({
                type: TYPE_REGISTER,
                payload: user
            })
        })
}

export const authenticate = () => (dispatch) => {
    return axios.post(`${BASE_URL}/me`)
        .then(function({data: {user}}){
            dispatch({
                type: TYPE_AUTHENTICATE,
                payload: user
            })
        })
        .catch(function(err){
            console.log(err)
            dispatch({
                type: TYPE_AUTHENTICATE,
                payload: {}
            })
        })
}

Я использую свой локальный кластер Kubernetes, используя Docker для Ma c, и доступ к контроллеру Ingress осуществляется по http://kludge.info:30561. Мой домен сопоставлен с 127.0.0.1 kludge.info локально, чтобы контроллер Ingress мог попасть в контейнер. Моя теория заключается в том, что когда я отправляю запрос к http://kludge.info:30561/api/auth/me, например, контейнер docker, на котором запущено приложение Node.js, считает, что это запрос к localhost (внутри контейнера), и приводит к ошибке соединения. Обратите внимание, что приложение Node.js внутри контейнера работает на http://localhost:8080. В основном я использую localhost на своей машине и localhost внутри экземпляра Node. Как я могу отправить запрос снаружи на http://kludge.info:30561/, где работает контроллер Ingress.

Я также настроил baseURL в ax ios, но это не решает проблему. Мой входной контроллер имеет путь /api, который будет указывать на экземпляр PHP, поэтому мне нужен мой вызов Node.js ax ios, чтобы попасть в его контейнер. Любая помощь будет принята с благодарностью.

Когда я запускал свой кластер K8 на Minikube, у меня не было этой проблемы, однако minikube предоставляет вам IP-адрес виртуальной машины, в то время как Docker для настольных компьютеров использует localhost прямо на вашей машине.

1 Ответ

1 голос
/ 21 января 2020

Если я вас правильно понимаю, я вижу, что вы открываете сокет на lcoalhost(127.0.0.1), поэтому он доступен только локально. Если вы хотите, чтобы он был доступен извне, вам нужно привязать его к 0.0.0.0, что означает «все интерфейсы». Прослушивание на 0.0.0.0 означает прослушивание из любого места, имеющего сетевой доступ к этому компьютеру. Например, с этого самого компьютера, из локальной сети или из Inte rnet. И прослушивание 127.0.0.1 означает только с этого компьютера.

Пожалуйста, дайте мне знать, если это помогло. Или, если я вас неправильно понял.

...