ubuntu 18.04 시작 프로그램 등록

작업 가이드

실행 할 shell 만들기

  • 위치(예시) : /home/ubuntu/start.sh
  • 내용
    #!/bin/bash 
    touch /home/ubuntu/test 

shell 실행권한 주기

  • chmod +x /home/ubuntu/start.sh

service 파일만들기

  • sudo vi /lib/systemd/system/service_name.service

    ----------------------------------------내용 시작 
    [Unit] 
    Description=Star shell 
    
    [Service] 
    ExecStart=/home/ubuntu/start.sh 
    
    [Install] 
    WantedBy=multi-user.target 
    Alias=service_name.service 
    ----------------------------------------내용 끝 
    상세 설명 
    [Unit] 
        Description : 설명 
    [Service] 
        ExecStart : 실행 할 shell 
    [Install] 
        WantedBy : multi-user.target은 runlevel3 이 셋팅 되었을 때를 의미 
        Alias : 별칭을 지정해 사용할 수 있다. ex) httpd.service 의 Alias=apache.service  

service 파일에 실행권한 주기

  • sudo chmod 755 /lib/systemd/system/service_name.service

service 파일 시작 프로그램 등록하기

  • sudo systemctl enable service_name.service

[참고] service 직접 실행하기

  • sudo systemctl start service_name.service

패커(Packer)

개요

  • 하나의 설정 소스로부터 여러 플랫폼을 지원하는 머신/컨테이너 이미지를 만드는 도구이다.

구성

  • 이미지 : 머신의 특정한 상태를 그대로 저장하고, 나중에 재사용 가능하도록 준비해둔것

    • 한계
      • 사용중인 가상머신을 그대로 저장하기 때문에 구성하는 과정을 알 수 없다.
      • 현재상태를 구현 하기 힘들다.
      • 최신상태를 저장한 이미지를 만들어 관리해야하기 때문에 비용이 비효율 적이다.
    • 대안
      • 비이스 이미지를 기반으로 프로비저너(Provisioner)를 통해 가성머신에 패키지 설치와 환경설정 작업 진행
      • 프로비저닝(Provisioning) 이 끝난 상태를 빌더(Builder)를 통해서 특정 플랫폼에서 사용 가능한 이미지로 저장
      • 최종 결과물을 저장하는 방식이 아닌, 이미지 생성과정에 대한 모든 정보를 코드로 관리한다.
      • 다양한 플랫폼에서 유사한 이미지를 만들어 사용하는것도 가능하다.
  • 빌더(Builder) : 이미지를 생성하는 작업

    • 지원 서비스 : AWS IAM, Google Compute Engine, Open Stack, Docker ..
  • 프로비저너 (Provisioner) : 이미지를 생성 할때 사용하는 빌드 도구

    • 역할
      • 이미지를 원하는 상태로 만들 수 있다.
    • 지원 서비스 : 원격 셀(Remote Shell), 로컬 셀(Local Shell), 파일 업로드(File Upload), 파워 셀(Power Shell), 윈도우 셀(Window Shell), 엔서블(Ansibie), 셰프(Chef), 퍼핏(Puppet)

파일 기본 포멧

{
    "builders": [{
        // ...
    }],
    "provisioners": [{
        // ...
    }]
}

특징

  • 기본 포멧 에서 볼 수 있듯이 빌더(Builder), 프로비저너(Provisioner) 값을 다수로 설정 할 수 있습니다.

설치

WINDOWS 10

  • 다운로드
    https://releases.hashicorp.com/packer/
  • 압축을 풀어 아래 폴더를 만들고 packer.exe를 위치시킨다.
    C:\packer
  • 환경변수에서 [시스템 변수]-[Path] 에 C:\packer 추가시킨다.

jupyterlab 설치

OS : ubuntu 18

설치

  • apt update
    sudo apt update

 

  • jupyterlab pip 설치
    sudo apt install -y python3-pip jupyter-core

 

  • jupyterlab 설치
    pip3 install jupyterlab

 

  • user profile 재 적용
    source ~/.profile

 

  • config 파일 생성
    jupyter notebook --generate-config
    출력 : Writing default config to: /home/ubuntu/.jupyter/jupyter_notebook_config.py

 

  • jupyter_notebook_config.py 파일 최하단에 아래 내용 추가
    vi /home/ubuntu/.jupyter/jupyter_notebook_config.py

      c = get_config()
      c.NotebookApp.ip = '[내부 IP]'
      예시:
          c = get_config()
          c.NotebookApp.ip = '172.31.24.168'

    ip 확인 방법

      ubuntu@ip-172-31-24-168:~$ ifconfig
      eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
              inet 172.31.24.168  netmask 255.255.240.0  broadcast 172.31.31.255
              inet6 fe80::8e2:ff:fe7e:171c  prefixlen 64  scopeid 0x20<link>
              ether 0a:e2:00:7e:17:1c  txqueuelen 1000  (Ethernet)
              RX packets 99783  bytes 141887383 (141.8 MB)
              RX errors 0  dropped 0  overruns 0  frame 0
              TX packets 13314  bytes 1613233 (1.6 MB)
              TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
      lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
              inet 127.0.0.1  netmask 255.0.0.0
              inet6 ::1  prefixlen 128  scopeid 0x10<host>
              loop  txqueuelen 1000  (Local Loopback)
              RX packets 378  bytes 36028 (36.0 KB)
              RX errors 0  dropped 0  overruns 0  frame 0
              TX packets 378  bytes 36028 (36.0 KB)
              TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

실행

  • jupyter lab 실행
    jupyter lab --allow-root

      ubuntu@ip-172-31-24-168:~$ jupyter lab --allow-root
      [I 11:32:14.547 LabApp] Writing notebook server cookie secret to /home/ubuntu/.local/share/jupyter/runtime/notebook_cookie_secret
      [W 11:32:14.843 LabApp] JupyterLab server extension not enabled, manually loading...
      [I 11:32:14.847 LabApp] JupyterLab extension loaded from /home/ubuntu/.local/lib/python3.6/site-packages/jupyterlab
      [I 11:32:14.847 LabApp] JupyterLab application directory is /home/ubuntu/.local/share/jupyter/lab
      [I 11:32:14.849 LabApp] Serving notebooks from local directory: /home/ubuntu
      [I 11:32:14.849 LabApp] The Jupyter Notebook is running at:
      [I 11:32:14.850 LabApp] http://localhost:8888/?token=7b8f33048569544c7aa237ee485698eb21d7c7e7182b9c12
      [I 11:32:14.850 LabApp]  or http://127.0.0.1:8888/?token=7b8f33048569544c7aa237ee485698eb21d7c7e7182b9c12
      [I 11:32:14.850 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
      [W 11:32:14.854 LabApp] No web browser found: could not locate runnable browser.
      [C 11:32:14.854 LabApp]
          To access the notebook, open this file in a browser:
              file:///home/ubuntu/.local/share/jupyter/runtime/nbserver-7550-open.html
          Or copy and paste one of these URLs:
              http://localhost:8888/?token=7b8f33048569544c7aa237ee485698eb21d7c7e7182b9c12
           or http://127.0.0.1:8888/?token=7b8f33048569544c7aa237ee485698eb21d7c7e7182b9c12
  • 위 출력 내용에 IP를 외부 IP를 입력한다.
    http://[외부 IP]:8888/?token=7b8f33048569544c7aa237ee485698eb21d7c7e7182b9c12

 

  • 빙화벽 AWS 라면 보안그룹에 8888 포트를 연다.

 

  • 백그라운드 실행 및 소유권 포기 (ssh 접속을 끊어도 서비스를 유지하는 방법)
    단축 키 입력 : Ctrl +Z
    cmd 입력 : bg
    cmd 입력 : disown -h

1. 테라폼이란?

terraform 은 Hashicorp에서 오픈소스로 제공하는 ICA(Infrastructure as Code)이다.
서비스가 되는 환경을 구성하는 프로비저닝 도구로 분류되며, Cloud 환경에 제약없이 사용이 가능하다.
terraform은 GUI(Graphical user interface)나 웹 콘솔을 이용해 관리하던 것을 Code로 관리할 수 있게해준다.
이로써 구성을 버젼 관리가 쉬워지고 수작업으로 인한 실수가 적어진다.

특징

  • Infrastructure ad Code : 코드 베이스
  • Execution Plans : 사전 테스트
  • Resource Graph : 리소스 의존관계 처리
  • Change Automation : 변경사항 자동화 가능하다.

2. Cloud 별 ICA

종류

  • AWS : AWS Cloud Formation
  • GCP : Google Cloud Deployment Manager

장점

  • Cloud 별 ICA
    Cloud의 신규 서비스 대응이 빠르다.
  • terraform
    Cloud에 종속되지 않는다.

단점

  • Cloud 별 ICA
    Cloud에 종속 된다.
  • terraform
    Cloud의 신규 서비스 대응이 상대적으로 느리다.

3. 기본 용어 정리

프로비저닝 (Provisioning)

  • 서비스를 실행 하기위한 준비단계
  • 네트워크, 컴퓨팅 자원을 준비 작업 & 준비된 컴퓨팅 자원에 사이트 패키지나 어플리케이션 의존성을 준비하는 단계
  • terraform은 전자에 치우쳐 있다.

프로바이더 (Provider)

  • 외부 서비스를 연결해주는 기능을 하는 모듈
  • AWS, GCP 등등이 프로바이더(Provider)로 있다.

리소스 (Resource)

  • 프로바이더가 제공하는 제품의 최소 단위.
    ex> EC2 Instance, Public IP 등등

HCL (Hashicorp Configration Language)

  • Terraform 에서 사용하는 언어
  • 확장자는 .tf를 사용

계획 (Plan)

  • .tf 파일의 내용이 실제 적용이 가능한지 확인 작업
  • 리소스에 어떤 영향(create, update, delete 등)을 미칠지 보여준다.

적용 (Apply)

  • 계획 (Plan)을 실제 서비스에서 수행하는 단계

4. 설치

Ubuntu

WINDOWS 10

  • 다운로드
    https://www.terraform.io/downloads.html
  • 압축을 풀어 아래 폴더를 만들고 terraform.exe를 위치시킨다.
    C:\terraform
  • 환경변수에서 [시스템 변수]-[Path] 에 C:\terraform을 추가시킨다.

사전 조건

- 각각의 노드로 연결되어 있는 트리구조
- 깊이를 우선으로 탐색한다.
- Stack를 사용

동작 방식

- 시작 노드를 탐색하고 방문처리.
- 시작 노드의 연결을 Stack에 담아준다.
- Stack에 마지막에 넣은 값 중에서 방문하지 않은 노드를 찾아 이동한다.
- 이동한 노드를 시작노드로 잡고 위 작업을 반복해준다,
- 탐색이 완료된 순서대로 출력한다.

예시 소스 결과

[1, 2, 4, 6, 5, 3, 9, 7, 8]

시간 복잡도

O(V + E)
    - 인접 리스트 인경우
    - 모든 정점에 대해 존재하는 간선만 탐색
    - 정점의 수(Vertex) + 간선의 수(Edge)

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 29
    @ Update : 2020. 01. 29
    @ Description : DFS, Depth-First Search (깊이우선탐색)
    '''

    def fn_depthfirst_search(dict_input, int_start, list_end):
        '''
            @Description: DFS, Depth-First Search (깊이우선 탐색)

            @Arguments Example
                # 0~10 사이의 정수라 가정
                dict_input = {
                    1:[2, 3],
                    2:[1, 4, 5, 7],
                    3:[1, 5, 9],
                    4:[2, 6],
                    5:[2, 3, 7, 8],
                    6:[4],
                    7:[5, 2],
                    8:[5],
                    9:[3]
                }
        '''
        list_end.append(int_start)
        for int_index in range(len(dict_input[int_start])):
            if dict_input[int_start][int_index] not in list_end:
                fn_depthfirst_search(dict_input, dict_input[int_start][int_index], list_end)
        return list_end


    if __name__ == "__main__":
        list_fn_depthfirst_search_param={
            1:[2, 3],
            2:[1, 4, 5, 7],
            3:[1, 5, 9],
            4:[2, 6],
            5:[2, 3, 7, 8],
            6:[4],
            7:[5, 2],
            8:[5],
            9:[3]
        }
        print(fn_depthfirst_search(list_fn_depthfirst_search_param, 1, []))

'알고리즘 > 탐색' 카테고리의 다른 글

1. 너비우선 탐색 (Breadth-First Search)  (0) 2020.01.29

사전 조건

- 각각의 노드로 연결되어 있는 트리구조
- 시작점과 가까운것 위주의 탐색 기법
- 최단 경로 찾기, 미로 찾기에서 사용
 -Queue를 사용

동작 방식

- 시작 노드를 탐색하고 방문처리.
- 시작 노드의 연결을 Queue에 담아준다.
- Queue에서 하나씩 꺼낸 값을 시작노드로 설정하고 위 작업을 반복해준다.
- 작업을 반복할 때 이미 탐색한 노드는 탐색하지 않는다.
- 탐색이 완료된 순서대로 출력한다.

동작 순서 예시

[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 7]
[1, 2, 3, 4, 5, 7, 9]
[1, 2, 3, 4, 5, 7, 9, 6]
[1, 2, 3, 4, 5, 7, 9, 6, 8]

시간 복잡도

O(V + E)
    - 인접 리스트 인경우
    - 모든 정점에 대해 존재하는 간선만 탐색
    - 정점의 수(Vertex) + 간선의 수(Edge)

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 29
    @ Update : 2020. 01. 29
    @ Description : BFS, Breadth-First Search (너비우선탐색)
    '''
    import queue


    def fn_breadthfirst_search(dict_input):
        '''
            @Description: BFS, Breadth-First Search (너비우선 탐색)

            @Arguments Example
                # 0~10 사이의 정수라 가정
                dict_input = {
                    1:[2, 3],
                    2:[1, 4, 5, 7],
                    3:[1, 5, 9],
                    4:[2, 6],
                    5:[2, 3, 7, 8],
                    6:[4],
                    7:[5, 2],
                    8:[5],
                    9:[3]
                }
        '''
        responce = []
        list_end = [1]
        queue_list = queue.Queue()
        queue_list.put(1)

        while queue_list.qsize() >= 1:
            int_value = queue_list.get()
            for int_resource_index in range(len(dict_input[int_value])):
                if dict_input[int_value][int_resource_index] not in list_end:
                    queue_list.put(dict_input[int_value][int_resource_index])
                    list_end.append(dict_input[int_value][int_resource_index])
            responce.append(int_value)
            print(responce)

    if __name__ == "__main__":
        list_fn_breadthfirst_search_param={
            1:[2, 3],
            2:[1, 4, 5, 7],
            3:[1, 5, 9],
            4:[2, 6],
            5:[2, 3, 7, 8],
            6:[4],
            7:[5, 2],
            8:[5],
            9:[3]
        }
        print(fn_breadthfirst_search(list_fn_breadthfirst_search_param))

'알고리즘 > 탐색' 카테고리의 다른 글

2. 깊이우선탐색(Depth-First Search)  (0) 2020.01.30

사전 조건

- 배열의 인자 값의 범위가 작을 때 적합하다.

동작 방식

- 배열의 인자를 하나씩 꺼낸 인자값과 새로운 배열의 인덱스 값이 같은 새로운 배열의 인자값을 1식 증가시켜준다.

장점

- 배열의 인자 값의 범위가 적을 경우 매우 빠른 속도를 낼 수 있다.
- 그러나 배열의 크기가 작고 인자값의 크기가 큰 경우 부적합 할 수 있다.

시간 복잡도

O(n) - 최대 값이 주어졌다면
    - 배열의 인자 값의 갯수 만큼 업데이트 하기 때문에 O(n)
    - 새로운 배열의 인자값들의 개수(k)를 합해야 하기 때문에 O(k)
    - 원소들을 새로운 배열에 넣어야 하기 때문에 O(n)
    - 따라서 O(2n + k) 간단하게 O(2n + k)
    - 그러나 k값 즉 인자의 최대 값이 작다면 O(n)으로 표현 할 수 있다.

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 28
    @ Update : 2020. 01. 28
    @ Description : Counting sort (계수 정렬)
    '''


    def fn_counting_sort(list_input, int_max_value):
        '''
            @Description: Counting sort (계수 정렬)

            @Arguments Example
                # 0~10 사이의 정수라 가정
                list_input = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
        '''
        list_result = [0] * (int_max_value + 1)
        responce = []
        for int_value in list_input:
            list_result[int_value] += 1

        for int_index in range(int_max_value + 1):
            for _ in range(list_result[int_index]):
                responce.append(int_index)
        return responce


    if __name__ == "__main__":
        list_fn_counting_sort_param = [1, 9, 1, 2, 7, 3, 2, 8, 6, 1, 10, 10, 5, 6, 5, 9]
        print(fn_counting_sort(list_fn_counting_sort_param, 10))


'알고리즘 > 정렬' 카테고리의 다른 글

6. 힙 정렬 (Heap sort)  (0) 2020.01.27
5. 병합 정렬(Merge sort)  (0) 2020.01.26
4. 퀵 정렬 (Quick sort)  (0) 2020.01.26
3. 삽입 정렬 (Insertion sort)  (0) 2020.01.24
2. 버블정렬 (Bubble sort)  (0) 2020.01.24

사전 조건

- 배열이 완전 이진 트리 구조여야 한다.
    (완전 이진 트리 - Complete binary tree : 
     각각의 노드가 최대 2개 씩의 자식 노드를 가진 이진 트리 구조에서 
     root 노드의 왼쪽부터 자식 노드를 차례로 삽입하는 트리 구조를 말한다.)

종류

- 최대 힙 (부모 노드가 자식 노드보다 큰 힙)
- 최소 힙 (부모 노드가 자식 노드보자 작은 힙)

용어

- leaf 노드 : 자식 노드가 없는 노드들
- 힙 생성 알고리즘 (heapify) : 부모 노드와 자식 노드들 중에서 값이 가장 큰 값을 부모 노드로 변경 해주는 작업
- 상향식 : 아래 노드에서 위로 올라가는 작업
- 하향식 : 위에 노드부터 아래로 내려가는 작업
  (상향식과 하양식은 편한대로 구성한다. 저자는 상향식으로 구성했다.)

동작 방식

- 10개의 값이 있다고 가정하면 heapify작업을 하는 list의 index 값의 순서는 아래와 같다.
    index :  [자식노드 : 왼쪽 값] [부모노드] [자식노드 오른쪽 값]
    index :  9 4 
    index :  7 3 8
    index :  5 2 6
    index :  3 1 4
    index :  1 0 2
- 상단에 index 값 중에서 가장 큰 값을 가운데 부모 노드에 저장한다.
- 해당 작업을 전체 노드 수의 1/2 만큼만 진행한다.(leaf 노드를 제외하고 진행하기 때문)
- 작업이 끝나면 첫번째 값이 가장 큰 값이 되므로 가장 마지막 값과 자리를 바꾼다.
- 위 작업을 list의 작업 범위를 줄여가며 진행한다.
    0 ~9 작업 후 0 의 값을 9에 넣기
    0 ~8 작업 후 0 의 값을 8에 넣기
    ex) 배열 값 예시
        [7, 4, 5, 8, 9, 3, 2, 1, 6, 10]
        [6, 7, 5, 8, 4, 3, 2, 1, 9, 10]
        [1, 6, 5, 7, 4, 3, 2, 8, 9, 10]
        [2, 1, 5, 6, 4, 3, 7, 8, 9, 10]
        [3, 2, 5, 1, 4, 6, 7, 8, 9, 10]
        [2, 4, 3, 1, 5, 6, 7, 8, 9, 10]
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

장점

- 퀵 정렬보다 안정적으로O(NlogN)을 보장한다.
- 메모리 상으로는 병합정렬 보다 효율적이다.

시간 복잡도

O(NlogN)
    - 힙 생성 알고리즘(heapify)작업에 걸리는 시간 복잡도는 완전 이진 트리 구조이기 때문에 로그2에 N 이다.
    - (1/2)n개의 정점에 대해서 진행하기 때문에 (1/2)n* 로그2에 N이다. 따라서 사실상 O(n)가까운 속도가 된다.
    - 그러나 공식적인 알고리즙의 시간 복잡도는 [힙 생성 알고리즘을 만드는데 걸리는 시간 logN] * [전체 데이터의 갯수 N]
    - 따라서 O(NlogN)이 된다.

python 구현

    '''
    @ Author : bsh0817
    @ Created : 2020. 01. 27
    @ Update : 2020. 01. 27
    @ Description : Heap sort (힙 정렬)
    '''


    def fn_swapping(list_target, int_index_a, int_index_b):
        '''
            @Description: List index swapping

            @Arguments Example
                list_target = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
                int_index_a = 0
                int_index_b = 2
        '''
        value_tmp = list_target[int_index_a]
        list_target[int_index_a] = list_target[int_index_b]
        list_target[int_index_b] = value_tmp
        return list_target


    def fn_heap_sort(list_input):
        '''
            @Description: Heap sort (힙 정렬)

            @Arguments Example
                list_input = [10, 5, 1, 8, 4, 3, 2, 9, 6, 7]
        '''

        int_len_list_input = len(list_input)
        for int_main_index in reversed(range(2, int_len_list_input + 1)):
            int_range = int_main_index//2
            if int_main_index%2 == 0:
                if list_input[int_range*2 - 1] > list_input[int_range - 1]:
                    list_input = fn_swapping(list_input, int_range*2 - 1, int_range - 1)
                int_range -= 1
            for int_index in reversed(range(1, int_range + 1)):
                if list_input[int_index*2 - 1] > list_input[(int_index*2)]:
                    if list_input[int_index*2 - 1] > list_input[int_index - 1]:
                        list_input = fn_swapping(list_input, int_index*2 - 1, int_index - 1)
                else:
                    if list_input[int_index*2] > list_input[int_index - 1]:
                        list_input = fn_swapping(list_input, int_index*2, int_index - 1)
                print("   index : ", int_index*2 - 1, int_index - 1, int_index*2)
            list_input = fn_swapping(list_input, 0, int_main_index - 1)
        return list_input


    if __name__ == "__main__":
        list_fn_heap_sort_param = [1, 9, 5, 4, 7, 3, 2, 8, 6, 10]
        print(fn_heap_sort(list_fn_heap_sort_param))

'알고리즘 > 정렬' 카테고리의 다른 글

7.계수 정렬 (Counting sort)  (0) 2020.01.28
5. 병합 정렬(Merge sort)  (0) 2020.01.26
4. 퀵 정렬 (Quick sort)  (0) 2020.01.26
3. 삽입 정렬 (Insertion sort)  (0) 2020.01.24
2. 버블정렬 (Bubble sort)  (0) 2020.01.24

+ Recent posts