1

I have a SPA and a microservices architecture. I am running the program locally on my machine using skaffold dev and kubernetes with Google Cloud Provider (GCP). I am connecting my frontend to my backend using Ingress-NGINX. When I go to the host name on my browser mavata.dev (configured on my local machine), I can no longer load the site. I get a "Cannot GET localhost:9000/main.js" net:::ERR_CONNECTION_REFUSED. See below for my config:

Kubernetes Config:

(ingress-srv.yaml)

# RUN: kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.3.1/deploy/static/provider/cloud/deploy.yaml
# for GCP run: kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user $(gcloud config get-value account)
# then run:   kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.4.0/deploy/static/provider/cloud/deploy.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-srv
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/use-regex: 'true'
    # certmanager.k8s.io/cluster-issuer: core-prod
    # nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
    # nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
    # nginx.ingress.kubernetes.io/rewrite-target: /
    # nginx.ingress.kubernetes.io/secure-backends: "true"
    # nginx.ingress.kubernetes.io/ssl-redirect: "true"
    # nginx.ingress.kubernetes.io/websocket-services: core-service
    # nginx.org/websocket-services: core-service
    #---
    # nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    # nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    # nginx.ingress.kubernetes.io/server-snippets: |
    #   location / {
    #     proxy_set_header Upgrade $http_upgrade;
    #     proxy_http_version 1.1;
    #     proxy_set_header X-Forwarded-Host $http_host;
    #     proxy_set_header X-Forwarded-Proto $scheme;
    #     proxy_set_header X-Forwarded-For $remote_addr;
    #     proxy_set_header Host $host;
    #     proxy_set_header Connection "upgrade";
    #     proxy_cache_bypass $http_upgrade;
    #     }
spec:
  rules:
    - host: mavata.dev # need to update 'hosts' file on local machine (in VS Code) C:\Windows\System32\drivers\etc
      http:
        paths:
          # - backend:
          #   pathType: Prefix
          #   serviceName: tornado-socket
          #   servicePort: 8000
          # - path: /api/company/create
          #   pathType: Prefix
          #   backend:
          #     service:
          #       name: company-clusterip-srv
          #       port:
          #         number: 4000
          # - path: /api/company/?(.*)
          #   pathType: Prefix
          #   backend:
          #     service:
          #       name: company-srv
          #       port:
          #         number: 4000
          # - path: /api/companies
          #   pathType: Prefix
          #   backend:
          #     service:
          #       name: companies-srv
          #       port:
          #         number: 4000
          - path: /api/users/?(.*)
            pathType: Prefix
            backend:
              service:
                name: auth-server-srv
                port:
                  number: 4000
          # - path: /api/permissions/?(.*)
          #   pathType: Prefix
          #   backend:
          #     service:
          #       name: permissions-srv
          #       port:
          #         number: 4000
          - path: /?(.*)
            pathType: Prefix
            backend:
              service:
                name: client-srv
                port:
                  number: 9000

(client-depl.yaml)

apiVersion: apps/v1
kind: Deployment  # tpye of k8s object we want to create
metadata:
  name: client-depl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: client
  template:
    metadata:
      labels:
        app: client
    spec:
      containers:
        - name: client-container
          image: us.gcr.io/mavata/frontend
          ports:
            - containerPort: 9000
---
apiVersion: v1
kind: Service
metadata:
  name: client-srv
spec:
  selector:
    app: client
  ports:
    - name: client-container
      protocol: TCP
      port: 9000
      targetPort: 9000

SPA Webpack Dev Config:

(webpack.dev.config)

const { merge } = require('webpack-merge');
// const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
const commonConfig = require('./webpack.common');
// const packageJson = require('../package.json');
const globals = require('../src/data-variables/global');
const port = globals.port;

const devConfig = {
  mode: 'development',
  output: {
    publicPath: `http://localhost:${port}/`   // don't forget the slash at the end
  },
  devServer: {
    host: '0.0.0.0',
    port: port,
    allowedHosts: ['mavata.dev'],
    historyApiFallback: {
      index: 'index.html',
    },
  },
  // plugins: [
  //   new ModuleFederationPlugin({
  //     name: 'container',
  //     filename: 'remoteEntry.js',
  //     remotes: {
  //       marketingMfe: 'marketingMod@http://localhost:8081/remoteEntry.js',
  //       authMfe: 'authMod@http://localhost:8082/remoteEntry.js',
  //       companyMfe: 'companyMod@http://localhost:8083/remoteEntry.js',
  //       dataMfe: 'dataMod@http://localhost:8084/remoteEntry.js'
  //     },
  //     exposes: {
  //       './Functions': './src/functions/Functions',
  //       './Variables': './src/data-variables/Variables'
  //     },
  //     shared: {...packageJson.dependencies, ...packageJson.peerDependencies},
  //   }),
  // ],
};

module.exports = merge(commonConfig, devConfig);

(webpack.common.config)

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-react', '@babel/preset-env'],
            plugins: ['@babel/plugin-transform-runtime'],
          },
        },
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.(scss)$/,
        use: [
          {
            // Adds CSS to the DOM by injecting a `<style>` tag
            loader: 'style-loader'
          },
          {
            // Interprets `@import` and `url()` like `import/require()` and will resolve them
            loader: 'css-loader'
          },
          {
            // Loads a SASS/SCSS file and compiles it to CSS
            loader: 'sass-loader'
          },
        ]
      },
      // {
      //   test: /\.s[ac]ss$/i,
      //   use: [
      //     // Creates `style` nodes from JS strings
      //     "style-loader",
      //     // Translates CSS into CommonJS
      //     "css-loader",
      //     // Compiles Sass to CSS
      //     "sass-loader",
      //   ],
      // },
      {
        test: /\.svg$/,
        use: ['@svgr/webpack'],
      },
      {
        test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[path][name].[ext]',
              outputPath: 'fonts/'
            }
          }
        ]
      },
      {
        // Load all images as base64 encoding if they are smaller than 8192 bytes
        test: /\.(png|jpg|jpeg|gif|ico|svg|webp)$/,
        use: [
          {
            // loader: 'url-loader',
            loader: 'file-loader',
            options: {
              // On development we want to see where the file is coming from, hence we preserve the [path]
              name: '[path][name].[ext]?hash=[hash:20]',
              //name: '[path][name].[ext]',
              limit: 8192
            },
          },
        ],
      },
      {
        // Load all icons
        test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/,
        use: [
          {
            loader: 'file-loader',
          }
        ],
      },

      {
        test: /\.(ttf|eot|woff|woff2)$/,
        loader: 'file-loader',
        options: {
            name: 'fonts/[name].[ext]',
        },
      },
    ],
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
    }),
  ],

  resolve: {
    extensions: ['', '.js', '.jsx', '.scss', '.eot', '.ttf', '.svg', '.woff'],
    modules: ['node_modules', 'src', 'scripts', 'images', 'fonts'],
    alias: {
      Navbar: path.resolve(__dirname, '../src/components/navbar/'),
      containerMfe: path.resolve(__dirname, '../src/'),
      Variables: path.resolve(__dirname, '../src/data-variables/Variables.js'),
      Functions: path.resolve(__dirname, '../src/functions/Functions.js')
    }
  },
};

melv3223
  • 67
  • 5
  • Please clarify: where are you running kubernetes -- in GCP or locally? If you're running it in GCP, what do you mean when you say you are, "running the program locally on my machine"? What service do you running on your machine that exposes port 9000? – Software Engineer Oct 17 '22 at 10:25
  • i am running on GCP sorry for the ambiguity. The EXPOSE 9000 is outdated – melv3223 Oct 18 '22 at 15:06
  • 1
    So, you're running on a remote machine, with its own IP address. Why do you think you can access that via localhost? Are you port-forwarding to your local machine? – Software Engineer Oct 18 '22 at 17:59

0 Answers0