Axios in einem Node.js-Container auf Kubernetes gibt „ECONNREFUSED 127.0.0.1:30561“ zurück?

Axios in einem Node.js-Container auf Kubernetes gibt „ECONNREFUSED 127.0.0.1:30561“ zurück?

Vollständige Fehlermeldung:connect ECONNREFUSED 127.0.0.1:30561 at TCPConnectWrap.afterConnect

Die Axios-Anfrage wird in einer Node.js-Umgebung (Next.js) ausgeführt, und dort tritt der Fehler auf. Seltsamerweise funktioniert die Axios-Anfrage einwandfrei, wenn sie im Browser ausgeführt wird.

Meine Komponente (läuft in Node.js), die Axios aufruft:

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} />
        }
    }
}

SpeziellreduxStore.dispatch(authenticate())

Und mein tatsächlicher Axios-Aufruf (mit Redux Thunk), mit Blick auf die authenticateMethode:

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: {}
            })
        })
}

Ich betreibe meinen lokalen Kubernetes-Cluster mit Docker für Mac, und auf meinen Ingress-Controller wird über zugegriffen http://kludge.info:30561. Meine Domäne wird 127.0.0.1 kludge.infolokal zugeordnet, damit der Ingress-Controller den Container erreichen kann. Meine Theorie ist, dass, wenn ich http://kludge.info:30561/api/auth/mebeispielsweise eine Anfrage an sende, der Docker-Container, auf dem die Node.js-App läuft, denkt, es handele sich um eine Anfrage an localhost (innerhalb des Containers), und es kommt zu einem Verbindungsfehler. Beachten Sie, dass die Node.js-App im Container auf läuft http://localhost:8080. Im Grunde betreibe ich localhost auf meinem Rechner und localhost innerhalb der Node-Instanz. Wie könnte ich eine Anfrage nach draußen senden, http://kludge.info:30561/wo der Ingress-Controller läuft?

Ich habe das auch baseURLin Axios konfiguriert, aber das löst das Problem nicht. Mein Ingress-Controller hat einen Pfad /api, der auf eine PHP-Instanz verweist, daher muss mein Node.js-Axios-Aufruf diese in seinem Container erreichen. Für jede Hilfe wäre ich sehr dankbar.

Als ich meinen K8-Cluster auf Minikube ausführte, hatte ich dieses Problem nicht. Allerdings stellt Minikube Ihnen die IP der VM zur Verfügung, während Docker für Desktop diese localhostdirekt auf Ihrem Computer verwendet.

verwandte Informationen