안녕하세요 미루고 미루고 미루다 ( 끝 없는 배포의 연장으로 진행이 안된 상태로 이렇게 시간이... ㅜ ) 

 

최근 다시 데드라인이 다가오고 있기 때문에 급하게 관련 작업들을 진행을 하고 있습니다.

 

사실 FE쪽 디자인은 Antd를 사용하였는데 해당 포스팅은 다음 포스팅에 하도록 하고 ( 사용이 어렵지 않기 때문 )

 

Redux를 통한 전역 상태 관리에 대해서 우선 작성하게 되었습니다. Redux와 Hooks를 너무 오랜만에 사용하다보니 

 

기억이 너무 가물가물 했기 때문입니다

 

1차적으로는 모두의 룰인 Counter 입니다. Counter 작성 후 개발중인 페이지의 전역 상태 관리로 바로 넘어가겠습니다.

 

Store

React-Redux와 관련 @types 및 Redux의 내용들은 많은 검색을 통해 알수 있기 때문에 과감하게 생략 하겠습니다. 사용성 및 작성 순서대로만

 

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import App from './App';
import rootReducer from './redux';


const store = createStore(rootReducer);

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
        <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

1차적으로 react-redux의 Provider를 받아와서 App 을 통해 전달 합니다.

* 한 개의 프로젝트는 단 하나의 스토어만 가질수 있으며 스토어 안에는 애플리케이션의 현재 상태 및 리듀서가 있습니다.

Store에 있는 상태값을 가져와서 사용하는 컴포넌트라면 아래의 순서를 거치게 됩니다.

 

컴포넌트 ( 1. 스토어를 통해 상태 값을 받아옴 ) 

컴포넌트 ( 2. 받아온 상태값으로 렌더 ) 

컴포넌트 ( 3. 상태 변경을 위해서 액션 디스패치 -> 스토어가 변경됨 )

컴포넌트 ( 4. 스토어의 상태가 변경되면서 다시 컴포넌트를 재 렌더링 )

 

액션 : 상태 변화시 발생하는 것

액션 생성 : 액션을 만들어서 상태 변화시 사용

리듀서 : 변화를 일으킴 액션을 파라미터로 받아서 새로운 상태를 만든 후 반환 

디스패치 : 액션을 발생 시킴 디스패치가 호출시 스토어가 리듀서 함수를 실행시켜서 새로운 상태를 만듬

 

여러가지의 상태를 사용하기 위해서는 리듀서를 여러개 사용하여야 하기 때문에 Combine 함수를 통해 rootReducer를 만든 후 해당 리듀서를 Store 에 전달합니다.

 

( rootReducer )

import { combineReducers } from 'redux';

const rootReducer = combineReducers({

});

export default rootReducer;

( CounterReducer )

const INCREASE = 'counter/INCREASE';
const DECREASE = 'counter/DECREASAE';


interface counterAction {
  type:string;
}
export const increase = () =>({type:INCREASE});
export const decrease = () =>({type:DECREASE});

const initialState = {
  number : 55
}

function counter(state = initialState,action:counterAction){
  switch(action.type){
    case INCREASE:
      return{
        number:state.number + 1
      };
    case DECREASE:
      return{
        number:state.number -1
      };
    default:
      return state;
  }
}

export default counter;

( App 에서 hooks를 통해 state를 selector ) 

import React from 'react';
import './App.css';
import ReduxComponent from './ReduxComponent'
import { useSelector } from 'react-redux';
import { increase, decrease } from './redux/counter';
function App() {
  const number = useSelector((state:any) => state.counter.number);

  return (
    <div className="App">
          Test App 
          <ReduxComponent number={number}></ReduxComponent>
    </div>
  );
}

export default App;

( ReduxComponent )

import React from 'react';

const ReduxComponent:React.FunctionComponent<any> = ({number,onIncrease,onDecrease}) => {
  
  return (
    <div>
      <h1>{number}</h1>
        <div>
          <button onClick={onIncrease} >+1</button>
          <button onClick={onDecrease} >-1</button>
        </div>
    </div>
    
  );
}

export default ReduxComponent;

 결과

이제 동작하기 위한 Dispatch

import React from 'react';
import './App.css';
import ReduxComponent from './ReduxComponent'
import { useSelector , useDispatch } from 'react-redux';
import { increase, decrease } from './redux/counter';
function App() {
  const number = useSelector((state:any) => state.counter.number);
  const dispatch = useDispatch();
  return (
    <div className="App">
          Test App 
          <ReduxComponent number={number} 
          onIncrease={()=> dispatch(increase)}
          onDecrease={()=> dispatch(decrease)}
          ></ReduxComponent>
    </div>
  );
}

export default App;

실행결과

Error: Actions must be plain objects. Instead, the actual type was: 'function'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions.

 

액션은 plain object 여야 한다 -> increase, decrease 액션 디버깅 

 

딱 봐도 객체가 아니라 함수로 리턴 되는 것 처럼 보이네요

       onIncrease={()=> dispatch(increase())}
       onDecrease={()=> dispatch(decrease())}

 

오타였네요 여기서 실행했어야; 

수정하니 정상적으로 잘되네용 ~ hooks 기억 되살리기 끝 다음 포스팅에 작업중인 자동화 플랫폼에 적용 하도록 하겠습니다.

 

컴퓨터 새로 사서 세팅하는 기념 포스팅 ( 지속 업데이트 )

최근에 Mac OS 를 구매했기 때문에 Mac M1 PRO 와 Windows PC 2개로 나눠서 작성 해놓겠습니다.

 

Mac OS PC

Visual Studio Code

1. Git Lens

2. Material Icon Theme

 

Windows PC

Visual Studio Code

1. Better Comments

개발도중 남길수 있는 코멘트들에 대한 가시성이 증대 됩니다.

2. Bracket Pair Colorizer 2

코드 블럭을 가시적으로 보여주게 합니다.

3. DotENV

Node.js에서 많이 사용되는 .env에 대한 기본 세팅입니다.

4. vscode-icons

기본적인 vscode에서 사용되는 icons 테마로 사용중입니다.

 

 

5. SynthWave '84 (디자인 테마 개인 취향)

개인 취향인 디자인으로 Custom CSS and JS Loader 를 사용해서 neon 효과를 줄수 있습니다. 

***command 'synthwave84.enableNeon' not found

금일 새로 설치 해서 세팅하게 되었는데 해당 오류가 발생해서 이것저것 확인해보니 visual studio code 가 1.60 으로 최신버전으로 되어있는데 1.60에서 오류가 나서 동작하지 않았던 이슈가 있었습니다.

VSCodeUserSetup-x64-1.59.1 로 새로 재 설치 후 enable neon dreams 실행시 정상 동작합니다.

visual studio code 1.59 download link - > https://code.visualstudio.com/updates/v1_59

 

 

 

6. Ctrl 로 소스코드 확대

 

Ctrl + Shift + P - > Settings 입력  JSON Default   

검색창 Ctrl 

Editor : Mouse Wheel Zoom 

Zoom the font of the editor when using mouse wheel and holding Ctrl  체크

7. Map 제거

검색창 : Map

Editor > Minimap :Enable 

Controls whether the minimap is shown. - > 체크 해제 

 

 

XShell ( 무료 버전 ) 

1. Ctrl + W : 탭 종료

브라우저는 Ctrl + W 로 탭을  빠르게 종료 하고 다음 작업을 하는데 Xshell 도 같은 작업을 해야하기에 초기에 세팅을 해놓습니다.

 

키 매핑 (P)...

 

새로 만들기(N)....

키 입력후 - 메뉴 - [탭] 닫기 설정

 

2. 마지막 탭 종료시 Xshell 종료 옵션

체크 해제

 

'개인 setting' 카테고리의 다른 글

유용한 사이트 모음 (깍돌이)  (0) 2019.12.24
vim 셋팅  (0) 2016.06.23

안녕하세요 오늘은 네이버 클라우드 플랫폼 이죠 NCP 에 대해서 적어 보려고 합니다.

최근 1년사이에 www.ncloud.com/ 에서도

네이버 클라우드 플랫폼의 최근 추가된 VPC 

VPC(Virtual Private Cloud) 가 출시 되며 기존에 있던 네이버 클라우드 플랫폼에 Classic 환경에서 사용하던

ACG(AccessControlGroup) 은 VM < - > VM 단위의 네트워크 룰을 적용하였다면 VPC가 출시되면서 Subnet 이라는 개념과 함께 Subnet < - > Subnet 의 네트워크 룰을 적용할수 있는 NACL 이 등장하게 되었습니다.

기본적으로  NACL 은 ACG와는 조금 다른 형태를 띄고 있기 때문에 이에 대해서 간단하게 적어 놓도록 하겠습니다.

 

NACL ( Network  Access Control List ) 

네이버 클라우드 플랫폼 환경에서 기존에 Classic에 경우는 ACG를 통하여서 VM 간의 차단룰을 적용했다면 NACL의 경우에는 Subnet 을 통한 차단룰을 적용합니다.  간단하게 설명된 곳이 있어 첨부합니다.

출처 : 코스콤 금융 클라우드 www.koscom.cloud/product/networking/vpc

서버의 접근 제어 서브넷의 접근 제어
허용 (Allow) 허용 및 거부 (Allow/Deny)
상태 저장
(규칙에 관계없이 반환 트래픽이 자동으로 허용됨)
상태 비저장
(반환 트래픽이 규칙에 의해 명시적으로 허용되어야 함)
ACG를 서버의 NIC에 적용 서브넷에 있는 모든 서버에 자동 적용됨

흔히 ACG는 Stateful NACL 은 Stateless라고 표현을 하기도 합니다.  ACG는 따로 포스 중이기 때문에 거기서 설명하도록 하겠습니다. 

NACL 을 적용해 보기 위해서는 일단 네이버클라우드플랫폼에서 VPC와 Subnet을 하나 만들어야합니다.

VPC 생성

Console 접속 후 VPC - VPC Management 에서 [ + VPC 생성 ] 을 클릭하여 아래와 같이 생성합니다.

기본적으로 특수 목적용 사설 IP대역은 위의 범위내에서 지정하도록 되어있기 때문에 저는 10.2.0.0/16 대역으로 지정하였습니다. 이부분에 대해서도 CIDR에 대한 설명이 필요하지만 해당 포스팅에선 따로 설명하지 않겠습니다.

생성이 완료되면 VPC내부에 VM 을 놓기 위한 Subnet을 생성합니다.

 

Subnet 생성 

VPC Management 바로 밑에 있는 Subnet Management 로 들어가서 [ + Subnet 생성 ] 을 선택합니다.

원하는 서브넷 이름을 정하고 방금 생성한 VPC를 선택하도록 합니다.

 

VM 생성

VM 생성은 이제 일반적인 서버 생성을 하신다고 보면되며 2개의 VM 이 생성되었다고 가정하겠습니다.

Send-Server( 10.2.1.55 )    

Recv-Server ( 10.2.1.77 )

 

NACL

NACL 은 기본적으로 VPC가 생성됨에 따라서 vpc-default-network-acl 이 하나 생성되며 아무런 룰도 존재하지않습니다.

NACL 의 Default 룰은 ALLOW 입니다. 그렇기 때문에 기본적인 서버를 생성시에는 ACG룰에 의하여 적용이 됩니다. (ACG는 Default DENY)

위와같이 NACL 의 경우 Default 가 "ALLOW" 이기 때문에 아무런 룰이 없어도 NACL 규칙에 위반되는 트래픽이 발생하지않습니다. 

 

해당 상황에서 

Send-Server( 10.2.1.55 )  ==== > Recv-Server ( 10.2.1.77 ) 에서 10.2.1.77 의 22번 포트차단시 단순하게는 

Case 1

   InBound 10.2.1.77  22 차단

Case 2

   OutBound 10.2.1.77 22 차단

 

2개의 케이스를 도출해낼수 있다고 생각 할수 있는데요  실제로 케이스 1번은 차단되지않습니다. 

처음에 잘못 생각 했던 부분이 Case 1번과 같이 룰을 지정해 놓게 되면

Send-Server 에서 -> Recv-Server 까지는 트래픽이 나가고 ( 인바운드만 차단이니까 ) 다시 들어올 때 10.2.1.77 의 22번 포트로 들어오겠지? 라는 생각에 당연히 막히겠지 라는 잘못된 생각을 가질수 있습니다.

 

간단하게 정리하면

 

NACL

-- inbound 포트 : 목적지 포트 ( VM 으로 들어오는 port )

-- outbound 포트 : 출발지 포트 ( VM 에서 나가는 port )

 

그럼 1번 케이스가 차단이 되어야 하지 않나? 라고 여기서고 생각한다면 OS에 특징을 봐야합니다. 네이버클라우드플랫폼에 있는 Centos 7.8 OS를 기준으로 하게되면  inbound 룰을 차단하게 되면  10.2.1.77 로는 일단 트래픽이 나가고 

다시 들어오는 IP 와 포트의 22을 차단하게 됩니다. 실제로 들어오는 IP는 10.2.1.77 이 들어옵니다. 하지만 Port는 랜덤하게 지정해줘서 들어오게 됩니다.  해당 포트 는 1024 ~ 65535 에서 랜덤으로 주게 되었으며 실제로 우리가 알고 있는 port의 범위는

 

0 ~ 1023 : well-known port번호 해당 영역의 port번호는 UNIX/LINUX에서 root 권한으로만 port를 열 수 있습니다. 예약영역이라고 보면 됩니다. 

1024 ~ 49151번: 등록된 포트 (registered port) 이 영역은 주로 서버 소켓으로 사용하는 영역입니다. 

49152 ~ 65535번 : 동적 포트(dynamic port) 이 영역은 client가 connect(2)시 또는 bind(2)없이 server socket을 생성했어 listen(2)할 경우에 자동으로 할당되는 영역입니다. server socket에서 자동할당하면, client에게 할당된 port번호를 알릴방법이 있어야하기 때문에 서버 소켓은 prot번호를 정합니다.

위와같은 영역이 정해져있습니다. 하지만 우리가 쓰고있는 VM들은 어느 범위 내에서 포트를 할당할시 알수가 있습니다.

바로 port_range 인데요 

네이버 클라우드 플랫폼의 VM인 Centos 7.8 을 기준으로 

vi /proc/sys/net/ipv4/ip_local_port_range

결과

32768   60999

 

해당 범위내에서 포트를 지정해서 다시 돌려주도록 되어있습니다. 제가 Express.js나 Java 서버든 장고를 사용하든 해당 OS설정으로 인해서 해당 포트의 범위를 돌려줍니다.

 

그래서 위의 상황에서 CASE는 아래와같이 변경되어야 합니다.

 

Send-Server( 10.2.1.55 )  ==== > Recv-Server ( 10.2.1.77 ) 에서 10.2.1.77 의 22번 포트 차단시 단순하게는

Case 1

   InBound 10.2.1.77  32768-60999 차단

Case 2

   OutBound 10.2.1.77 22 차단

 

이렇게 되면 1번 케이스에서 55서버는 77서버로 아웃바운드 트래픽을 정상적으로 나가고 77서버는 55서버에게 다시 돌려주기 위해서 10.2.1.77:(32768-60999) 포트를 돌려주게 되며 해당 룰은 차단되어있기 때문에 10.2.1.55 서버에서 NACL 에 의해 막히게 됩니다. 

 

간단하게 NACL 에 대해 살펴 보았습니다. 사실 위에 부분 말고는 처음 NACL 을 접하였을 때 특이사항은 없었던 것 같습니다.  잠깐 신경 안쓰다 보니 다시 잊혀져 가는거 같아서 포스팅을 해놓았습니다.  ㅎㅎ

 

 

감사합니다.

안녕하세요 깍돌이입니다.

 

이제는 FE 쪽 간단한 개발을 위해서 Table 태그를 이용한 TASK 상태를 그려줄 화면을 만들어야하는데요

 

React 에서 해당 table을 만들게 되면 위와같은 warning이 나타납니다.(노랑색도 아니고 빨간색이라 오류로 보고 처리하는게 나을거 같습니다.)

 

 <div>
    <table>
      <colgroup>
        <col width="100px"/>
        <col width="*"/>
        <col width="90px"/>
        <col width="160px"/>
        <col width="120px"/>
        <col width="50px"/>
        <col width="50px"/>
      </colgroup>
      <thead>
          <th>UUID</th>
          <th>TESTNO</th>
          <th>TASK</th>
          <th>TASKSTATUS</th>
          <th>TESTRESULT</th>
          <th>START</th>
          <th>FINISH</th>
      </thead>
      <tbody>
        <tr>
          <td>test-1234-sddf-4321</td>
          <td>1</td>
          <td>할당 및 접속 테스트</td>
          <td>WAIT</td>
          <td>FAIL</td>
          <td>5분전</td>
          <td>2분전</td>
        </tr>
      </tbody>
    </table>
  </div>

위와같이 하였을때 일반 페이지에서는 오류가 발생하지 않지만 React 에서는 해당 태그의 구조는 오류가 발생합니다.

 

validateDOMNesting(...) <th> cannot appear as a child of <thead>

직역을 하자면 th는 thead의 자식으로 나타날수 없다 라는 뜻이 되는데요 간단하게 처리하자면

 

 <div>
    <table>
      <colgroup>
        <col width="100px"/>
        <col width="*"/>
        <col width="90px"/>
        <col width="160px"/>
        <col width="120px"/>
        <col width="50px"/>
        <col width="50px"/>
      </colgroup>
      <thead>

         <tr>
          <th>UUID</th>
          <th>TESTNO</th>
          <th>TASK</th>
          <th>TASKSTATUS</th>
          <th>TESTRESULT</th>
          <th>START</th>
          <th>FINISH</th>

         </tr>
      </thead>
      <tbody>
        <tr>
          <td>test-1234-sddf-4321</td>
          <td>1</td>
          <td>할당 및 접속 테스트</td>
          <td>WAIT</td>
          <td>FAIL</td>
          <td>5분전</td>
          <td>2분전</td>
        </tr>
      </tbody>
    </table>
  </div>

 

th 부분을 tr로 묵어 주면 됩니다.

안녕하세요 깍돌이 입니다 .아파치를 재시작하거나 시작 할때 해당 오류를 만나는 부분들이 꽤있는데요 

아주 단순한 케이스이지만 기록 해놓으려고 작성하게 되었습니다.

 

NCP(NaverCloudPlatform) & Init Script

NCP 클라우드 에서는 VM 을 생성시 Init Script 를 사용하여서 서버가 "운영중"으로 들어오기전에 하고싶은 작업들을 실행할수가 있습니다.  제가 하려고 했던 작업 중 일부분 입니다.

# 아파치 설치 
sudo -s yum -y install httpd
# 아파치 시작 
sudo -s systemctl start httpd
# 아파치 Root 디렉토리 변경
sudo -s sed -i 's/var\/www\/html/home1\/ncloud\/index.html/g' /etc/httpd/conf/httpd.conf
# 아파치 재시작  
sudo -s systemctl restart httpd

작성해놓았지만 동작이 되지않았기에 직접 VM에 들어가서 확인해보니

 

"Job for httpd.service failed because the control process exited with error code"

에러가 발생 중이였습니다. 뒤에 에러 코드에 보면 systemctl status httpd.service 를 보라는 문구가 있죠

 

Systemctl status httpd.service

원래 가장 친절한 에러 문구부터 파악을 해야겠죠

보시면 딱히 어떤 에러가 있는지는 확인이 쉽게 되지는 않게 나타나고 있습니다. 저희는 재시작 혹은 실행 에서 오류가 났기 때문에 해당 status에서 눈여겨 볼 점은 ExecStart 인데요

 

/usr/sbin/httpd 를 통해서 직접 실행을 해봅시다

 

ExecStart - /usr/sbin/httpd

결과 : '/home1/ncloud/index.html' is not a directory , or is not readable 

-> 제가 위에서 변경 하였던 오류였네요 루트 경로를 /var/www/html -> /home1/ncloud 로 했어야 하는데 index.html 까지 써버려서 폴더가 아니기 때문에 아파치의 welcome-list 필터링에서 오류가 발생하였습니다.

 

sudo -s sed -i 's/var\/www\/html/home1\/ncloud/g' /etc/httpd/conf/httpd.conf

 

/home1/ncloud로 변경 후 다시 시도시 (welcome-list에 의해서 index.html 을 찾을 겁니다)

 

정상적으로 나타났네요

 

* 별첨으로 Ubuntu와 Centos에서의 Apache (아파치) 설치 및 루트 디렉토리 변경이 조금씩 다르기 때문에

해당 관련 shell 을 첨부합니다.

 

Ubuntu 16.04-64 Server

#!/bin/bash

sudo -s apt-get update
sudo -s apt-get -y install apache2
# Create Apache New Index Folder
mkdir /home1/ncloud/www

# Change Apache Root Directory
sudo -s sed -i 's/var\/www\/html/home1\/ncloud\/www/g' /etc/apache2/sites-available/000-default.conf

# Change Apache Root Direceotry Access Authority
sudo -s sed -i 's/denied/granted/g' /etc/apache2/apache2.conf

# authority change 
sudo -s chmod -R 775 /home1
sudo -s chmod -R 775 /home1/ncloud
sudo -s chmod -R 775 /home1/ncloud/www
sudo -s chmod -R 775 /home1/ncloud/www/index.html

# Restart Apache
sudo -s /etc/init.d/apache2 restart

 

Centos 7.3-64

#!/bin/bash

# Apache Install
sudo -s yum -y install httpd
# Apache start
sudo -s systemctl start httpd

# Create Apache New Index Folder
mkdir /home1/ncloud/www

# Change Apache Root Directory
sudo -s sed -i 's/var\/www\/html/home1\/ncloud\/www/g' /etc/httpd/conf/httpd.conf

# authority change 
sudo -s chmod -R 775 /home1
sudo -s chmod -R 775 /home1/ncloud
sudo -s chmod -R 775 /home1/ncloud/www
sudo -s chmod -R 775 /home1/ncloud/www/index.html

# Restart Apache
sudo -s systemctl restart httpd

 

감사합니다.

꾸벅 @.@

+ Recent posts