GCP 배포

이동명·2023년 10월 9일
0

오늘은 GCP 무료 요금제를 이용해서 간단하게 배포를 해 보고, 후에 CI/CD 및 container 개념을 배우면서 실습을 진행할 간단한 프로젝트를 준비해보자.

1. 인스턴스 생성

리전은 간단하게 해볼 것 이기 때문에 가장 저렴한 아이오와로 선택하였다. 꽤나 느리지만 그래도 공부용이기 때문에..선택

2. puttygen key 생성 후 키 등록

ssh 접속을 위한 key를 생성.. 아래는 샘플 이미지 이다..

cloud 에 ssh key 등록 하자.

private key로 저장해서.. putty 로그인 할 때 마다 사용하도록 하자.

나는 2개의 클라우드를 이용할거고

A 클라우드 에서는 spring boot server 를 돌리고

B 클라우드 에서는 react 프로젝트와 DB를 올려놓을 것 이다.

3. A클라우드 - server 배포

서버 배포를 위해서 일단 필요한 모듈먼저 다운 받도록 하자.

Git 설치

sudo apt-get install git

nvm + node 설치

참고링크

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash

nvm install 18.18.0

source ~/.bashrc

java 17 설치

sudo apt-get install openjdk-17-jdk

그 후 간단히 post 와 get을 하는 서버 프로젝트를 하나 만들고.. git 프로젝트를 올린 후 서버배포용 클라우드에서 clone을 받고 jar로 패키징을 하였다.

서버를 키는 script 작성


sudo java -jar -Dspring.profiles.active=prod demo-0.0.1-SNAPSHOT.jar > ../logs/app.out 2> ../logs/app.err &

서버 프로세스를 종료하는 script 작성

sudo kill -9 $(ps -ef | grep 'java -jar' | grep -v grep | awk '{print $2}')

이후 이 클라우드에선 서버를 계속 돌리고 있을 것 임..

프로젝트는 /api/v1/demo 의 entry로 get 과 post 만 만들어놓았음.

CrossOrigin 은 test 할 때만 * 로 해놓고 나중에 접근하는쪽만 걸어놓을 것임.

4. B클라우드 - front 배포 및 DB server

MySql 설치

설치는 이 링크를 보고 하였음.

wget https://dev.mysql.com/get/mysql-apt-config_0.8.26-1_all.deb

sudo dpkg -i mysql-apt-config_0.8.26-1_all.deb

sudo apt-get update

첫번째 옵션선택 에서 OK를 눌러주고 비밀번호 설정 후 설치 마침.

-- 유저 생성
CREATE USER 'test'@'%' identified by '1234';

-- 권한 주기
grant all privileges on *.* to 'test'@'%';

-- 권한 적용
flush privileges;

5. front src

axios.defaults.baseURL = process.env.NODE_ENV === 'development' && 'http://localhost:8001'; 를 이용해서..

npm start를 켯을 땐 development 이고 build 를 치면 production 으로 돌아가기 때문에..

build 를 하면 production 으로 되면서 위의 조건에 부합하지 않기 때문에 현재 url이 axios default주소에 꽂히게 된다.

import React, { useState, useEffect } from 'react';
import axios from 'axios';

axios.defaults.baseURL = process.env.NODE_ENV === 'development' && 'http://localhost:8001';

const FormList = (props) => {
  const [demos, setDemos] = useState([]);



  useEffect(() => {
    axios.get('/api/v1/demo')
      .then(response => {
        setDemos(response.data);
      })
      .catch(error => {
        console.error('Error fetching data:', error);
      });
  }, [props.observer]);

  return (
    <div className="form-list">
      <h2>Form List</h2>
      <ul>
        {demos.length != 0 ? demos.map(demo => (
          <li key={demo.id}>
            <strong>{demo.name}</strong>: {demo.description}
          </li>
        )) : <p>데이터 없음</p>}
      </ul>

    </div>
  );
};

export default FormList;

이 프로젝트도 마찬가지로 git 으로 B클라우드 쪽으로 옮겨놓고 build 를 하고.. was로 사용 할 nginx를 먼저 설치하였다.

6. nginx

nginx 에 대한 자세한 내용은 추후에 공부하면서 포스팅 하도록 하고 오늘은 nginx를 이용해서 내 외부 ip주소로 접근했을 때 보여줄 index.html 과 proxy_pass 와 load_balancer 정도만 접근해보자..

nginx 설치

설치 - sudo apt install nginx

nginx 작업상태 확인 - sudo systemctl status nginx

사용중인 포트확인 - netstat -napt

80포트가 이미 사용중이었음 확인해보니 apache2 http가 포트를 먹고 있었음

apache2 종료 - sudo systemctl stop apache2

nginx 다시 실행 - sudo systemctl start nginx

여기까지 완료되면 원래 예전에는 nginx 기본 페이지가 떳는데

나는 Apache2 Debian Default Page가 나옴

sites-available/default

/etc/nginx/sites-available/default 에 default 설정들이 되어있고 안에 무슨 내용이 있는지 둘러보자

node-java-mysql-git-1@node-java-mysql-git-1:/etc/nginx/sites-available$
node-java-mysql-git-1@node-java-mysql-git-1:/etc/nginx/sites-available$ cat default

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;
		
        - 내 외부 ip 접속 시 보여주는 index.html 이 들어있음.
       	root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        # pass PHP scripts to FastCGI server
        #
        #location ~ \.php$ {
        #       include snippets/fastcgi-php.conf;
        #
        #       # With php-fpm (or other unix sockets):
        #       fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass 127.0.0.1:9000;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}
}


# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
#       listen 80;
#       listen [::]:80;
#
#       server_name example.com;
#
#       root /var/www/example.com;
#       index index.html;
#
#       location / {
#               try_files $uri $uri/ =404;
#       }
#}

크게 엄청난 설정은 없는 것 같다..

따라서 내 nginx.conf 를 조금 custom 해주자..

nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

		// 이 부분이 default 설정을 쓴다는 import 인데 주석하고
        밑에 server 블록을 추가해 overide 하자..
        
        #include /etc/nginx/conf.d/*.conf;
        #include /etc/nginx/sites-enabled/*;

        server {
                listen 80 default_server;
                listen [::]:80 default_server;

                server_name _;
                location / {
                		// front 패키지 build 추출물을 이 경로로 보낼거임.
                        root /etc/shere/html;
                        index index.html index.htm index.nginx-debian.html;
                }

                location /api/v1/demo {
                		// 밑의 그림에서 설명
                        proxy_pass http://10.128.0.4:8001;
                }
        }
}

7. proxy_pass 사용이유

원래는 밑의 그림처럼 data 가 받고 싶다면 A cloud 에 직접적으로 데이터를 요청하면 되지만..

아래처럼 데이터를 주고 받는다면 A cloud 쪽에서 돌리고 있는 쪽의 방화벽규칙을 허용해줘야 한다..

하지만 방화벽규칙을 수정하지 않고 proxy_pass를 이용한다면 ..?

1. axois default config

axios.defaults.baseURL = process.env.NODE_ENV === 'development' && 'http://localhost:8001'

front 에서 build 를 하면 production 으로 들어간다. 따라서 클라우드에서 axios default 는 cloud B 의 url로 들어가게 된다.

useEffect(() => {
    axios.get('/api/v1/demo')
      .then(response => {
        setDemos(response.data);
      })
      .catch(error => {
        console.error('Error fetching data:', error);
      });
  }, []);

고로 컴포넌트가 시작 될 때 'cloud_B_url/api/v1/demo' 로 요청을 하게 될 것이다.

2. proxy_pass

nginx.conf 에서 server block을 아래처럼 추가 했었다.

server {
                listen 80 default_server;
                listen [::]:80 default_server;

                server_name _;
                
                location / {
                        root /etc/shere/html;
                        index index.html index.htm index.nginx-debian.html;
                }

                location /api/v1/demo {
                        proxy_pass http://10.128.0.4:8001;
                }
        }

location /api/v1/demo 랴고 적어놓은 블록에서 proxy_pass가 cloud A의 내부주소를 가리키고 있다.

즉 'cloud_B_url/api/v1/demo' 로 트래픽이 들어올 시 cloud A의 내부주소로 proxy 를 쏴주겠다는 것 이다.

그렇게 되면 axois default config 로 인해 'cloud_A_url/api/v1/demo' 로 요청을 해서 data를 받아올 것 이다.

그렇다면 방화벽규칙을 설정하지 않아도 proxy_pass를 사용해서 통신이 가능하다.

8. load_balancer

내 server block 설정에서 보도록 하겠다.

server {
     listen 80 default_server;
     listen [::]:80 default_server;

     server_name _;
                
     location / {
          root /etc/shere/html;
          index index.html index.htm index.nginx-debian.html;
     }

     location /api/v1/demo {
          proxy_pass http://10.128.0.4:8001;
          
          // 로드 밸런싱할 url..
          proxy_pass http://backend;
     }
     
}

// 로드 밸런싱할 url..
upstream backend{
      server 10.128.0.20:8090;
      server 34.31.28.179:8080;
      server 34.170.217.245:8080;
}

위 처럼 설정해주면 nginx가 로드밸런싱을 해준다.


profile
Web Developer

0개의 댓글