현재 진행 중인 프로젝트와 앞으로의 프로젝트들도 모두 Golang 기반으로 갈 것 같아서 공부도 할 생각으로 여러 가지를 찾던 중에 블로그를 Go기반의 Hugo로 개설해 보기로 했다.
Gitlab은 Hexo 기반으로 운영하고 Github는 Hugo 기반으로 운영하려고 한다. 물론 양쪽에 게시물을 따로 올려서 관리하기는 힘들기 때문에 용도를 분리해서 운영을 해 볼까 한다.
어디로 올려야할지 글에 대한 구분을 하는 것도 힘들겠지만, 운영 자체도 힘들 듯해서 앞으로도 이렇게 운영을 하게될지? 아니면 하나로 통합(?)하게 될지는 결정하지 못했지만, 새롭게 시작해서 그런지는 몰라도 은근히 Hugo쪽으로 마음이 기울고 있다.
프로젝트 진행과 입사(프리랜서 -> 정규직)를 하면서 너무 오랜동안 손을 놓고 있었던 Hexo 기반 블로그를 다시 돌려보니 문제점이 몇가지 존재하고 향후의 방향성 때문에 변경이 필요할 듯 하다.
앞으로는 하나의 블로그로 정착해서 글들을 통합하고 운영하던 다른 블로그들은 링크 연결형식으로 정리를 해야할 듯 하다.
]]>진행 중인 프로젝트 (.NET Framework 4.6 기반의 Window Forms Applicaiton Framework 구성)에서 여러 가지 다양한 구성과 기능들과 Core Function 들을 구성해서 제공하지만, 프레임워크 수준의 API 들을 문서화하는 단계를 거치지 못하고 템플릿 (Project / Item) 들과 단위 샘플 코드들과 Visual Studio 의 Intellisense 를 통해 운영하다 보니 개발자들이 API 를 통해 쉽게 처리할 수 있는 것들도 고민이나 질문 또는 찾아보는 수고를 생략하고 기존 방식대로 코드를 자체 생산해서 사용하는 의도하지 않는 문제가 발생하고 있다.
물론 정상적인 기간과 진행이 담보되면 모두 다 구성해서 반복적인 전달 교육을 통한 후에 진행을 해야 하지만, 단기에 구성해서 개발에 적용해야 하는 상황이라 개발 가이드를 통해서 개념적인 부분을 설명하고 샘플 코드 기반으로 전달 교육을 4차례나 진행했지만 개발을 진행하다 보면 이런 저런 경우와 상황이 발생하게 마련이고 이런 경우에 처리를 어떻게 해야할지를 이해하는 것에 한계가 있기 때문에 쉽게 찾아 볼 수 있는 API 문서를 Visual Studio 빌드 작업과 통합할 수 있는 툴을 검색하던 중에 DocFx
라는 오픈 소스를 발견해서 적용해 보기로 했다.
예전에도 한번 적용해 봐야지 했다가 기간과 다른 작업들에 밀려서 하지 못한 것을 이번 기회에 적용해 보도록 한다.
DocFx
는 마이크로소프트에서 제작한 문서화 도구로 GitHub에 공개된 오픈소스다. 문서화 도구뿐만 아니라 Jekyll, Hexo 과 같은 정적 사이트 생성 기능의 복합 제품이라고 봐야할 것 같다.
주요 처리 방식은 다음과 같다.
설치하는 방법은 여러 가지가 존재한다. (DocFx 사이트의 “Getting Started” 부분을 참고) 샘플은 DocFx v2.36.1 버전을 다운로드 해서 사용하는 것으로 한다.
압축 파일로 구성되어 있으므로 다운로드한 후에 압축을 풀고 시스템 환경 변수에 DocFX 경로를 등록해 주면 된다.
DocFx 는 툴이기 때문에 별도의 구성이 필요없지만, 솔루션을 문서화하기 위한 기본 폴더 구조를 구성할 필요가 있다.
기본 구성은 DocFx Seed
가 있으므로 이를 이용해도 된다. 여기서는 개념적인 부분을 검토해 볼 수 있도록 직접 구성해 보도록 한다.
D:\Works\DocFXSample
과 같은 폴더를 하나 생성하고 아래와 같이 기본 폴더 구조를 만들도록 한다.
1 | DocFXSample\ |
문서화의 대상으로 사용할 TestLib.sln 파일과 TestLib 소스 폴더를 Src 폴더 밑에 복사해 놓는다.
DocFX 는 설정을 기반으로 동작하므로 위의 폴더 구성에 맞도록 설정 파일을 구성해 주면 된다.
1 | D:\Works\DocFXSample> docfx init |
대화형으로 옵션들을 물어보는 단계들이 진행되는데 별다른 이유가 없다면 기본 값으로 진행하면 된다.
아래는 생성된 docfx.json
옵션 파일의 내용이다.
1 | { |
위의 파일의 내용을 대략 유추해 보면 “build” 옵션 값들을 통해서 docfx 의 출력 결과물을 처리하는 방법에 대한 옵션들인 것을 볼 수 있다. 아직은 원본 소스들에 대한 설정이 없다.
이 상태로만 실행을 해 보기 위해서는 아래와 같이 서비스 명령을 사용하면 된다.
1 | D:\Works\DocFXSample> docfx serve |
실행된 결과는 localhost:8080
으로 브라우저를 실행하면 볼 수 있다. 현재는 docfx.json 파일만 존재하므로 list of files 만 보인다.
DocFX 가 소스를 인식해서 처리할 수 있도록 metadata
정보와 build > content
정보를 구성해 주면 된다.
1 | { |
위의 내용의 주요 항목들은 다음과 같다.
metadata
: 소스를 연계하기 위한 설정src
: 소스 관련 정보files
: 소스 대상인 솔루션 또는 프로젝트 파일 와일드 카드 설정exclude
: bin/obj 같은 폴더내의 파일 제외용 와일드 카드 설정src
: 소스 폴더 설정dest
: 출력 결과물은 위치시킬 폴더 설정build
: DocFx 빌드를 위한 설정content
: 컨텐츠로 사용할 설정files
: 소스 빌드에서 생성된 파일에 대한 와일드 카드 설정src
: 소스 빌드에서 생성된 출력 결과 폴더 지정dest
: 소스 빌드의 결과를 docfx 빌드해서 결과물을 위치시킬 폴더 지정resource
: 이미지와 같은 Asset 파일들의 폴더 지정dest
: DocFx 결과 사이트 폴더 지정더 많은 설정들과 의미는 DocFx 문서들을 참고하도록 한다.
docfx.json 파일의 build > content 부분에 설정한 것과 같이 소스 연계가 아닌 사이트 구성을 위한 파일들이 필요하다.
1 | "files": [ "articles/**/*.md", "*.md", "toc.yml" ] |
articles 폴더에 게시할 *.md 파일들도 필요하지만, 사이트 루트 폴더를 구성할 파일들도 구성하면 된다.
우선 toc.yml
파일을 루트 폴더에 아래와 같이 구성하도록 한다.
1 | - name: Home |
위의 의미는 Site 의 Root 구성이라고 생각하면 된다. 각 name 에 따라서 분류와 연결할 경로와 파일을 지정하면 된다.
toc.yml 파일에 명시된 각 폴더 (docfx.json 파일에 지정한 내용 중에서 > build > content > 2번째 files) 에는 인덱스 역할을 담당하는 toc.md 파일과 시작을 위한 index.md 파일들을 구성해 줘야 한다.
사이트 홈의 내용을 처리할 index.md 파일은 아래와 같이 간단하게 구성해 보도록 한다.
1 | # DocFx Simple Documents |
그리고 article 폴더도 수동으로 설정하는 것이므로 연계를 위한 toc.md 파일을 아래와 같이 구성해 주도록 한다.
1 | # [Index](index.md) |
위의 toc.md 에서 링크로 설정한 index.md 파일도 articles 폴더에 생성해 주도록 한다.
1 | # Articles Index |
여기까지 구성을 했으면 기본적인 설정과 연계된 파일들에 대한 구성이 된 것이므로 실제 사이트 운영이 가능하다.
1 | D:\Works\DocFXSample> docfx |
위의 세가지 명령 중에 아무거나 사용해도 상관없다.
빌드가 진행되면 site, obj 등의 폴더가 생긴 것을 확인할 수 있다. obj 폴더는 빌드 과정의 산출물을 관리하는 폴더이고, 실제 실행가능한 것은 site 폴더다.
구성을 제대로 했다면 별다른 오류가 없이 생성이 되었을 것이므로 아래와 같이 실행을 해 보도록 한다.
1 | D:\Works\DocFXSample> docfx serve site |
브라우저에서 localhost:8080
에서 결과를 확인할 수 있다.
Notes
Visual Studio XML 주석 문서 처리
src
폴더에 기존에 존재하는 Visual Studio 솔루션 또는 프로젝트를 넣기 전에 반드시 확인해야 하는 부분이 각 소스들에 대한 XML 주석 파일이 존재해야 한다는 것이다.만일 미리 주석을 설정하지 않았다면 각 프로젝트마다 속성 정보에서
빌드 > 출력 > XML 문서파일
의 CheckBox 를 선택해서 주석 파일을 생성하도록 해야 한다. 이 설정이 되면 각 public / protected 메서드와 클래스들은 주석이 없다면 경고로 처리되므로 이를 기준으로 주석을 구성하도록 한다.
아주 간단하게 DocFX 를 이용해서 기존에 생성해 놓은 솔루션을 XML 문서화 정보를 기반으로 마크다운 문서로 전환하고 정적 사이트 구성을 통해서 API 문서를 볼 수 있도록 간단한 사이트를 구성해 보았다.
기존의 SandCastle 과 같이 무겁게 느껴지고 복잡함을 제거하고 단순하게 구성할 수 있다는 의미에서 좋고, 빌드를 통해서 사이트 구성을 제공할 수 있다는 점에서 좋은 것 같다.
MSBuild Task를 통해서 연계가 되므로 MSBuild 스크립트를 잘 활용하면 빌드 자동화에도 연동해서 운영할 수 있다.
]]>일반적으로는 Visual Studio 빌드를 이용해서 처리하지만 파일 배포나 경로 변경 또는 상황적으로 파일 필터링이 필요한 경우등의 추가적인 활용을 위해서는 MSBuild 확장 또는 NAnt 와 같은 빌드 툴을 이용해야 한다.
*.csproj 파일
을 생각해 보자. 대부분은 그냥 프로젝트 파일이라고 생각하고 별다른 생각을 하지 않겠지만, 이 파일 자체가 MSBuild를 정의한 파일이다. 즉, 프로젝트를 빌드하기 위해서 필요한 정보를 담고 있는 XML 파일
인 것이다.
빌드 스크립트는 아래의 샘플과 같이 기본적인 구성이 존재한다. 이 구성을 기준으로 필요한 부분들을 추가하고 조정하면 되는 것이다. 진행하면서 테스트를 위해 아래의 내용을 “build.xml” 이라는 이름으로 생성해 놓도록 하자.
1 | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
위의 샘플에는 3개의 "Target"이 존재하며 각 “Clean”, “Build”, “Rebuild” 로 지정되어 있다.
MSBuild 의 기본 구성 요소는 다음과 같다.
실제로 *.csproj 파일을 열어보면 Import, ItemGrop, PropertyGroup 등의 내용을 볼 수 있지만, Target 에 대한 내용은 없다.
Target은 행동을 나타내기 때문에 Visual Studio 에서 MSBuild 에 미리 지정해 놓은 작업들 “Copy”, “Delete”, “Exec”, “ReadLinesFromFile”, “VCBuild” 등의 대략 30 여개 작업들을 호출하는 것이기 때문에 *.csproj 파일은 Task 처리에 필요한 프로젝트 구성 정보만 가지고 있기 때문이다.
이런 Target들은 확장이 가능하며, 대표적인 사례로 MSBuildCommunityTask 라는 오픈 소스도 이런 확장 기능을 사용한 것이다.
위의 기본 구성을 실행해 보기 위해서는 MSBuild.exe 파일의 경로를 찾아야 한다.
Notes
예전에는 MSBuild 가 프레임워크 특정 버전 아래에 존재했었다.
C:\Windows\Microsoft.NET\Framework(또는 Framework64)\v2.0.50727\msbuild.exe
그러나 VS2015 버전 사용 중이라면 설치 경로에 존재할 것이고
C:\Program Files (x86)\MSBuild\14.0\bin\msbuild.exe
VS2017 버전 사용 중이라면 Visual Studio 설치 경로 아래에 존재할 것이다.
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise(또는 다른 등급)\MSBuild\15.0\bin\msbuild.exe
실행을 위한 스크립트 파일을 아래와 같이 구성하면 된다. (구성하는 방법은 여러 가지가 있으므로 원하는데로 구성하면 된다)
1 | @echo off |
위의 내용 중에 SETLOCAL
과 ENDLOCAL
의 기능은 예를 들어 vcvarsall.bat 과 같은 스크립트를 호출했을 때 PATH 정보를 변경하기 때문에 현재 LOCAL 에서만 적용하겠다는 의미이고 %*
은 지정된 모든 아규먼트를 그대로 전달한다는 의미를 나타낸다.
이제 실행은 아래와 같이 빌드 시크립트와 태스크를 지정하면 된다.
1 | build.bat build.xml /t:build |
위의 같이 실행될 결과를 확인할 수 있다. 각 태스크인 Clean, Rebuild 를 지정해서 결과를 확인해 보도록 한다.
Notes
스크립트를 실행할 때 build.xml 도 /t:xxx 정보도 주지 않으면 어떻게 될까?
- 태스크가 지정되지 않으면 build.xml 에 정의된 첫번째 태스크가 수행된다. (DefaultTargets 가 지정되어 있다면 그 태스크가 실행된다)
- build.xml 이 지정되지 않으면 해당 경로에서 “msbuild.xml” 파일을 찾는다.
이제 기본 스트립트 처리는 완성이 되었으므로 실제 솔루션을 대상으로 동작을 확인해 보도록 하자.
간단하게 “Hello World!” 를 출력하는 콘솔 어플리케이션을 하나 생성하고 프로젝트 파일 (*.csproj)을 열어서 확인해 보도록 하자.
1 | <?xml version="1.0" encoding="utf-8"?> |
위의 내용을 대략적으로 확인해 보면 다음과 같은 항목들로 구성된 것을 확인할 수 있다.
Visual Studio 에서 빌드를 하면 이런 정보가 전달이 되고 이 정보들을 기준으로 MSBuild 가 태스크를 실행하게 되는 것이다.
여기서는 스크립트를 통해서 처리하는 것을 알아보고 있으므로 위에서 작성했던 기본 스크립트 파일을 아래와 같이 변경해서 처리하는 것으로 구성해 본다. 물론 솔루션 파일 (*.sln)을 아규먼트로 전달 받아서 처리할 수도 있지만 여기에서는 직접 지정해서 처리하는 것으로 한다.
1 | <Project DefaultTargets="Build" |
Notes
- @(…) : 빌드 스크립트 내부에 정의된 Property나 ItemGroup 을 참조할 때 사용한다.
- %(…) : 빌드 스크립트 내부에 정의된 Proeprty에 의해서 참조된 내부 Property의 값을 참조할 때 사용한다.
기본 구성에 Configuration 과 Solution 설정이 들어간 것을 확인할 수 있다. Solution 설정은 작성한 샘플 어플리케이션이 존재하는 경로를 지정하면 된다. (여기서는 동일한 경로에 TestApp 라는 이름으로 생성했다)
*.sln 파일 역시 솔루션에 포함될 *.csproj 들을 “ProjectReference” 형식으로 포함하고 있는 MSBuild 스크립트 파일이다.
기본 메시지만 출력하던
이제 옵션을 줘서 실제 빌드를 실행해 보도록 하자.
1 | build.bat build.xml /p:Configuration=Release |
기본 태스크가 “Build” 로 되어 있으므로 /t 옵션은 제외하고, Debug/Realease 값을 옵션으로 전달한 것을 볼 수 있다. 이 옵션 값은 구성한 Build.xml 의 $(Configuration)
속성 값으로 전달되어 처리된다.
실제 솔루션이 연결되었고 빌드도 처리했으므로 정말 Clean 이 제대로 동작하는지도 확인해 보자. Visual Studio 로 프로젝트나 솔루션을 만들면 Clean 작업이 이미 구성되어있기 때문에 동작이 되어야 한다.
build.xml 에 Clean 태스크를 아래와 같이 변경하도록 한다.
1 | ... |
MSBuild 에 이미 구성되어 있는 Clean 태스크가 동작하도록 Targets="Clean"
을 설정한 것을 확인할 수 있다.
이제 실행을 해서 제대로 Clean 이 동작하는지를 확인해 보자.
1 | build.bat build.xml /p:Configuration=Release /t:Clean |
위의 결과와 같이 bin, obj 폴더에 존재하는 파일들을 삭제한 것을 확인할 수 있다. 그러나 실제 대상 폴더에 가 보면 Visual Studio 디버깅 과정에서 자동으로 생성된 .vshost. 등과 같은 파일들이 삭제되지 않고 남아있을 수도 있다. 따라서 완전히 Clean 작업을 수행하기 위해서는 해당 폴더를 삭제하는 것이 필요할 때가 있다.
이를 위해서는 아래와 같이 빌드 스크립트에 폴더와 관련된 설정을 추가해 줘야 한다.
1 | ... |
위에서 보이는 것과 같이 ItemGroup 으로 BinDirs, ObjDirs 를 정의하고 Clean 태스크에서 “RemoveDir” 태스크를 호출해서 삭제하는 것을 확인할 수 있다.
물론 내부에 삭제되지 않은 파일이 있을 경우에는 파일이 존재해서 삭제할 수 없다는 오류가 발생할 수 있고, 중첩된 폴더들이 존재하는 경우도 있을 수 있으므로 이런 경우를 모두 감안하려면
1 | ... |
와 같이 Command line 명령을 수행하도록 할 수도 있으며, MSBuild Extenstions 들을 통해서 처리할 수도 있다.
아직은 스크립트 상태일 뿐이므로 디버깅보다는 디버깅을 위한 옵션이 어떻게 존재하는지를 알아보도록 한다.
1 | build.bat /? |
MSBuild 에서 제공하는 여러가지 옵션들이 보인다. 그 중에서 디버깅 용도로 사용할 수 있는 옵션은 /verbosity:<level>
로 약어로는 /v:<level>
로 지정하면 된다. 사용할 수 있는 Level 은 다음과 같다.
지금까지 아주 기본적인 MSBuild 의 구성과 동작에 대해서 정리해 보았다. 현재는 많은 확장들이 오픈소스로 제공되고 있으므로 이를 활용해서 빌드 스크립트를 구성하는 것이 좋다.
이 글을 정리하는 의미는 향후에 개발하는 모든 프로젝트에 빌드 스크립트를 적용해서 문서화 (DocFx를 사용해서 Markdown 기반의 Static Site 제공까지 고려) 를 하는 기반으로 사용하기 위함이다.
다음에는 DocFx 와의 연계를 하는 부분에 대해서 정리할 생각이다.
]]>Visual Studio 를 사용해서 생성한 WindowForms 화면 디자인을 MacBook 이나 Surface 등과 같은 해상도가 높은 (DPI 가 높은) 머신에서는 열면 디자인 화면이 깨져 보인다.
대 부분은 Label, GroupBox 등의 컨트롤의 크기가 깨지면서 텍스트나 크기 등의 아주 다양한 부분에 디자인의 크기가 자연스럽게 처리되지 못하고 깨지는 상황이 발생한다.
Visual Studio 2015, 2017 은 DPI 인식을 하는 어플리케이션
이기 때문에 이런 문제가 생긴다. 이전 버전은 현재 테스트를 해보지 않았기 때문에 확정할 수는 없지만, 아마도 DPI 인식이 없다면 문제가 없을 것으로 유추된다.
문제는 DPI 인식을 통해서 "디스플레이 배율 조정"
기능이 제대로 동작하면 다행인데 이 기능이 제대로 동작하지 못해서 발생한다.
따라서 어떤 경우는 적용되고, 어떤 경우는 적용되지 못하기 떄문에 Container 는 줄었는데 내부 내용은 처리되지 못하는 등의 문제가 생겨서 화면서 깨진 것처럼 표시되는 것이다.
DPI 인식 어플리케이션에 디스플레이 스케일링을 활성화 또는 비활성화하는 방법은 아래와 같다.
그런데 문제는 Visual Studio 의 경우는 dev.exe 의 속성에 호환성 탭이 없고, devenv.exe.manifest 파일이 실행파일에 포함되어 있기 때문에 이를 재정의할 수 없다
는 점이다.
따라서 이 문제를 해결하기 위해서는 Registry 설정을 통해서 어플리케이션에 대한 DPI 인식을 꺼버리는 수 밖에는 없어 보인다.
1 | [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\devenv.exe] |
실제 Registry 키로 이동해 보면 devenv.exe 는 등록되어 있지 않다. 따라서 왼쪽 레지스트리 트리뷰에서 "devenv.exe" 이름으로 키를 생성
해 줘야 한다.
그리고 오른쪽 속성 창에서 "DWORD(32)" 값으로 "dpiAwareness" 속성을 생성
하면 “00000000” 값으로 생성된다.
이제 Visual Studio 인스턴스들을 모두 종료한 후에 다시 실행해 보면 Registry에 설정된 값에 의해서 DPI 인식 기능이 꺼지고 WindowForms 디자인 화면이 다시 제대로 보이는 것을 확인할 수 있다.
이를 다시 원상 복구 하기 위해서는 Registry에 추가한 “dpiAwareness” 값을 1 로 설정하거나 생성했던 키를 삭제하면 된다.
완벽한 해결책은 아니지만 Font 나 Icon 등이 조금씩 흐려 보이는 증상
을 제외하고는 아직까지는 큰 문제가 없어 보인다.
첨부자료 : DPI 해결 Registry
]]>이번 프로젝트에서는 안정성도 중요하지만 가장 중요한 포인트가 성능
이다. 따라서 가능하면 가볍고, 빠른 라이브러리들을 사용해야 하는 기준이 존재한다.
처음에는 MyBatis.Net 을 사용해서 DAC Layer 를 처리하는 것으로 프로토타입 진행을 했지만, 거의 대부분의 로직은 Stored Procedure 상에 존재하기 때문에 MyBatis.NET 에서 제공하는 SQL Manipulation 등의 장점을 활용하지 못하고 거의 Entity Mapping 정도만 활용할 수 있는 수준이 되었다.
이런 상황에서 활용도 대비 무거운(?) 것이 되어버린 MyBatis.NET 의 대안을 검색하던 중에 Dapper.NET 이라는 Micro-ORM 라이브러리를 찾게 되었다.
Dapper.Net 은 오픈소스로
경량 Object Mapper
라이브러리라고 생각하면 된다.Dapper.Net의 핵심은
성능
으로 순수한 ADO.NET 을 이용한 속도 (SqlDataReader 사용)와 거의 근접한 성능을 보여준다.
현재 국내에는 많은 자료들이 없지만 외국의 수 많은 확장들을 보면 나름대로 어느 정도의 안정성은 확보가 되어 있은 듯 하여 상대적으로 가볍고 빠른 Dapper를 이용해서 프로젝트를 진행해 보도록 한다.
진행하면서 Dapper.NET 에 대한 샘플들과 문제점 해결등에 대한 자료를 게시해 보려고 한다.
References
]]>이 문서에는 프로젝트를 진행하면서 Visual Studio Code (이하 VSCode) 를 사용하면서 유용하게 적용할 수 있는 각종 설정과 팁들 그리고 확장 프로그램들에 대해 지속적으로 갱신하며 정리한다.
주로 VSCode 기본설정 (사용자, 작업영역) 과 개발에 필요한 팁들을 정리한다.
[ VSCode Terminal 에서 PowerShell 을 Cmd 로 변경하기 ]
VSCode 는 터미널이 PowerShell 로 연결되어 있다. 기존에 사용하는 Cmd.exe 를 사용하기 위해서는 기본설정 (사용자) 부분을 다음과 같이 변경해 주면 된다.
1 | ... |
위의 설정은 Windows 64bit 에서 cmd.exe
을 Shell 로 변경하고 폰트와 크기를 변경하는 설정이다.
주로 개발 중에 필요한 확장들을 정리한다.
파일 경로를 자동 완성 처리해 주는 확장
]]>이번에 진행되는 프로젝트는 Angular2
UX Component 변경 처리와 Ionic2
기반의 웹앱 Boilerplate 구성하는 것이다.
사용할 개발 툴은 무료이면서 Front-End 와 같은 개발에 많이 사용되는 VSCode를 선택했기 때문에 Git를 연동해서 사용하는 방법을 정리해 놓도록 한다.
크게 로컬에서 프로젝트를 생성하고 Git 에 연결하는 방법
과 Git 에 있는 프로젝트를 로컬로 Clone 하는 방법
의 두 가지 중에 하나를 사용하게 된다.
클론해서 시작하는 것으로 크게 어려운 것이 없으므로 여기서는 로컬에서 프로젝트를 생성하는 부분에 대해서만 알아보도록 한다.
Importants
VSCode 는 Git 연계만 지원할 뿐 Git 자체를 지원하는 것은 아니기 때문에 반드시 Git 를 사전에 설치하고 관련된 사용자 정보등의 설정을 해 놓았다는 것을 가정하고 진행한다.
Git 설치 및 구성 방법은 검색해 보면 많은 정보들이 존재하므로 이를 참고해서 처리하도록 한다.
VSCode 에서 프로젝트에 사용할 특정 폴더를 선택해서 지정하도록 한다.
좌측에 있는 소스제어
메뉴를 클릭하면 리포지토리 초기화
및 추가 메뉴 (SCM 공급자변경) 를 확인할 수 있다.
VSCode 는 기본적으로 Git 가 기본 소스제어로 설정되어 있으므로 초기화 버튼을 클릭해서 초기화하면 된다.
화면상으로 크게 변화는 없지만 해당 폴더에 가 보면 .git
폴더가 생성된 것을 확인할 수 있다.
지금까지는 단지 프로젝트 폴더에 Local Git 정보만 구성한 것이다. 이제 간단하게 readme.md
파일을 하나 생성해 보도록 한다.
위의 그림에서 보이는 것과 같이 파일을 하나 생성하면 왼쪽의 메뉴에 있는 저장소 아이콘 에 추가/변경된 파일 갯수가 보이는 것을 확인할 수 있다.
아직은 변경된 것만 관리되고 있을 뿐이고 버전관리 대상이 아니기 때문에 이 파일을 Stage 처리를 해 주어야 한다.
위의 그림에서 보이는 것 처럼 해당 파일에 마우스를 위치시키면 +
아이콘이 보이고 클릭하면 Stage 처리된다.
만일 여러 개의 파일들을 모두 한번에 처리할 경우는 CHANGES
에 마우스를 위치시키면 대상 파일들을 모두 Stage 처리할 수 있다. 취소가 필요한 경우는 상단에 ...
클릭하면 추가 명령어들과 Stage 취소를 할 수 있다.
Stage 처리한 후에 해당 파일을 변경헀다면 변경된 파일에 M
상태를 나타내는 아이콘이 표시된다.
당연히 변경된 파일을 선택하면 변경된 내용을 확인할 수 있다. 위에서 생성했던 readme.md
파일을 선택하면 readme.md (Working Tree)
파일에서 stage 처리 후에 변경된 내용을 확인할 수 있다.
이제 로컬 Git 상에서 Stage 처리 (Git 의 버전관리를 위해 Add 된 상태) 를 했으므로 Git 에 Commit 를 해서 버전관리를 해 줘야 한다.
위의 그림과 같이 작업된 내용을 유추할 수 있는 메시지를 입력하고 Commit 아이콘을 클릭하면 된다.
당연한 말이지만 Commit 이 되면 stage 상태에 있던 파일들이 Local Git 저장소로 반영된 것이기 때문에 CHANGED 정보는 초기화 된다.
현재 VSCode 버전에서는 원격 Repository를 UI 에서 연결하는 방법은 없기 때문에 (있는데 못 찾았을 수도 ㅠㅠ) 터미널을 열고 아래의 명령을 통해서 원격 Repository 를 연결해야 한다.
1 | $ git remote add origin "github 등에서 생성한 프로젝트 Repository URL" |
Notes
터미널을 여는 방법은 Git 추가메뉴인
...
에서Git 출력 표시
를 선택한 후에터미널
을 선택해도 되고Ctrl + `
키를 눌러서 열어도 된다. 단, 기본은 PowerShell 로 되어 있으므로 Cmd 창과 같이 사용하려면 ‘VSCode 설정 및 팁들 (계속 갱신)’ 게시글을 참고해서 설정을 변경해 주면 된다.
원격 Repository 정보가 추가되면 왼쪽 하단에 클라우드 업로드
처럼 보이는 아이콘이 생성된다. (아래의 원격 브랜치 설정 이미지 참고)
Remote Git 정보를 추가했지만 아직 로컬에서 원격의 브랜치를 연결한 것은 아니기 때문에 이를 연결해 주는 작업을 아래와 같이 수행하면 된다.
브랜치 연결이 되면 클라우드 업로드 아이콘이 동기화 아이콘으로 변경된다.
이제 로컬에서 관리되고 있는 git repository를 원격 repository에 적용해 줘야 한다.
원격 Repository에 처리하기 위해서는 계정 정보를 입력해야 한다. 만일 다른 프로그램에서 이미 연결해서 사용 중이라면 계정 정보가 남아있기 때문에 그냥 넘어갈 수도 있지만 그렇지 않다면 아래의 그림과 같이 계정정보를 묻게 된다.
위의 오류는 로컬 Repository의 변경을 적용하기 전에 이미 원격 Repository에서 변경이 발생한 것으로 Merge 가 필요한 상태이므로 원격 저장소의 정보를 로컬에 병합해 줘야 한다.
1 | $ git pull origin master |
위의 오류는 로컬과 원격이 동일한 Base 에서 시작하지 않았기 때문에 Merge 중에 연관되지 않은 기록이 존재한다는 것으로 아래의 명령을 통해서 이런 내용들을 모두 수용하는 것으로 처리를 하면 된다.
1 | $ git pull origin master --allow-unrelated-histories |
위의 오류는 로컬 Repository가 원격 Repository와 어떤 브랜치로 연결되어야 하는지에 대한 정보가 부족해서 생기는 것으로 아래의 명령으로 브랜치를 연결해 주면 된다.
1 | git branch --set-upstream-to=origin/<브랜치명> |
일반적으로 로컬 Repository는 기본적으로 master
로 지정되므로 이를 사용하면 된다. 만일 다른 브랜치를 클론 받은 상태라면 해당 브랜치를 지정하면 된다.
지금까지의 결과는 그리 크게 먹지도 잃지도 않은, 그냥 증권사 수수료와 세금(거래세)만 열심히 내고 있는 상황이다. 물론 쌩초보가 아는 것도 없이 무작정 시작을 했는데 이 정도면 괜찮은 상태라고 위안만 열심히 하고 있다.
하지만, 그냥 쉽지 않군! 잘 안되는구나? 라고 생각만하고 말면 영원히 발전은 없을 것이기 때문에 여러가지 자료들을 찾으면서 투자 실패의 원인에 대해 정리해 보고 이를 이겨나가기 위한 재 무장을 해야할 듯 하다.
요즘 가장 증권가에 핫하게 올라오는 단어는 뭘까? 로보어드바이저!!!
라는 단어다. 단순하게 정의하면 "컴퓨터 시스템에 의해서 시장을 분석하고 고객의 자산을 운용해 주는 서비스" 라고 이해하면 된다.
알파고와 사람간의 바둑 게임에서 이미 로보어드바이저의 모습을 봤다.
가장 중요한 것은 어떤 상황에서도 사람과는 달리 환경이나 감정에 휘둘리지 않는 것 하나만으로도 실수를 줄이고 안정된 흐름을 유지할 수 있다는 것이다.
근본적으로 사람은 생각과 감정이라는 것 때문에 투자라는 것과는 맞지 않는다고 한다. 즉, 사람의 투자는 올라가는 흥분에 고가에 투자하고 떨어지는 두려움에 저가에 파는 행동을 하게 된다는 것이다.
성공한 투자자가 아니라 나와 같은 일반적인 개미들을 기준으로 실패의 이유는 구체적인 투자전략이나 계량화가 가능한 것이 없다는 것이다.
쉽게 누구든지 따라할 수 있도록 정리된 교범이 있다면 요리 레시피처럼 누가해도 똑같이 하면 비슷한 요리가 나올 수 있는 것이 필요하다는 것이다.
결국 이런 정량화되거나 구체적인 전략없이 투자를 하게 되면 사람의 주관성이 개입
되는 상황이 발생하고 인간의 주관성에 근거한 투자는 패망의 지름길로 달려가는 것과 같다.
여러 주식투자 관련된 글들을 읽다가 보면 고수들은 한결같이 자신만의 기준을 강조한다. 목표치 설정, 손절치 설정, 기계처럼 동일한 방식의 적용 등등…
행동 경제학으로 경제학 노벨상을 수상한 카네만 교수 (Daniel Kahneman) 는 우리의 뇌는 두 가지 시스템으로 운영된다고 한다.
갑자기 큰 소리가 나는 곳을 쳐다보거나 상대방의 목소리에서 적대감을 느끼거나 뜨거운 물체로 부터 손을 떼는 것과 같이 본능적인 반응이 곧 시스템 1이다.
1 + 1 = 2 와 같이 거의 각인되서 생각이 필요없는 수준은 시스템 1에서 처리가 가능하지만 123 * 321 과 같은 복잡한 계산이라면 시스템 2가 필요하다.
여기서 중요한 것은 시스템 1은 자연스럽게 동작하며 이를 막거나 멈출 수 없다는 것이며, 시스템 2는 우리가 하려고 하지 않으면 절대로 동작하지 않기 때문에 이를 실행하기 위한 노력과 주의가 필요하다는 점이다.
주변에서 보면 아무 생각없이 사는 사람과 여러 가지를 잘 처리하면서 사는 사람을 볼 수 있다. 이는 시스템 1만 사용하는 사람과 시스템 2까지 사용하는 사람의 차이라고 볼 수도 있다.
문제는 시스템 1에는 편향적인 요소가 존재한다는 것이다. 아주 간단하고 생각이 필요없는 단순한 상황에서는 거의 대부분의 사람들이 동일한 결론을 내고 행동하지만 논리적인 검토와 생각이 필요한 상황에서는 시스템 2가 동작하지 않는다면 시스템 1에 근거한 결론이 개개인별로 편향적인 성향을 보인다는 것이다.
예를 들어 길을 가던 중에 아주 귀여운 애완 동물은 봤다면 대부분은 쳐다보며 행복한 미소를 지을 수 있지만, 어떤 위급 환자를 봤을 때는 상황이 다르다. 어떤 사람은 119에 신고하는 사람도 있고, 그냥 멍하게 바라만 보는 사람도 있고, 어떻게 하냐며 말은 하지만 직접적인 행동은 없는 사람과 응급처치를 하는 사람도 있게 된다.
이는 시스템 1 기준으로 직관적인 판단을 해야할 때 나타나는 편향적인 오류라고 볼 수 있다.
카네만 교수는 이를 복잡하기 이를데 없는 주식시장에 연계했을 때 나타나는 실수들을 제시하고 있다.
일관성 (Consistency) : 투자는 일관성이 중요하다. 어떤 전략을 행하던 일관성있게 장기적으로 유지할 수 있어야 한다. 그러나 인간은 기분, 배고픔, 피로함 등의 투자와 전혀 상관없는 요소 때문에 판단에 영향을 받고 실행에 영향을 받게 된다.
과잉 확신 편향 (Overconfidence Bias) : 읿반적인 사람들은 자신을 약간 과대평가하는 성향이 있다. 요즘 말로는 근자감이라고도 한다. 이게 사람이 살아가는 원동력이기도 하다. 그러나 투자 시장에서는 반대의 효과가 발생한다. 자신이 보고 있는 또는 보유하고 있는 종목은 오를 것이라는 과잉확신은 망하는 지름길이다.
투자를 위해서는 여러가지 요소들이 만족되어야 하겠지만, 단지 분석이나 타이밍 같은 기술적인 부분이 부족해서 실패하는 것은 아니다. 99%의 원인은 심리적인 문제가 더 크다.
가격에 대한 편향적 사고 : 흔할 말로 본전 심리
라고 할 수 있다. 더 큰 손실이 날 수 있는데 본전 생각에 팔지를 못한다. 더 좋은 종목이 있다면 본전 보다는 손실과 기회 라는 측면에서 팔 수도 있어야 한다.
손실에 대한 편향적 사고 : 사람에게는 기쁨보다는 슬픔이 더 깊게 각인되는 편향적인 사고가 존재한다. 100만원을 딴 기쁨보다는 100만원을 잃은 슬픔이 깊게 그리고 길게 남는다는 것이다. 거기에 본능적으로 슬픔과 괴로움을 피하려는 습성까지 더해져서 눈에 보여지는 손실이 점점 불어나고 있어도 확정 매도를 하지 못하게 된다.
아픈 기억에 대한 편향적 사고 : 손실에 대한 편향과 같이 손실에 대한 기억이 남아서 현재 이익을 보고 있음에도 앞으로 떨어지면 본전도 못 건질 수 있다는 심리 때문에 약간의 조정에도 너무 쉽게 이익을 확정하게 된다. 하락하고 있는 종목은 본전욕심에 팔지를 못하고, 상승하고 있는 종목은 너무 빨리 팔아버린다
확인에 대한 편향적 사고 : 보통 어떤 상황에서 누군가가 지지를 하면 안정되는 느낌을 받은 적이 있을 것이다. 대부분의 사람들은 애매한 상황에서 누군가 같은 생각을 가지고 있으면 안심하게 되는 편향이 있다. 더욱이 전문가라는 사람의 말을 들으면 무조건 Go 가 되는 경향이 있다. 확인되지 않은 소문이나 누군가의 추천에만 기대지 말고 기본적인 판단을 할 수 있어야 한다
. 나중에 아무도 책임지지 않는다.
최신 및 소수 정보에 대한 편향적 사고 : 지금까지의 기록들을 전제로 한 통계적인 부분을 일반적인 사람들은 너무 무시하는 경향이 있다. 따라서 최신 정보나 기사에만 의존해서 통계적인 문제를 등한시하게 되는 경향이 높다. 또한 통계와 같이 객관적인 사실을 기반으로 하려면 많은 표본 집단이 필요하다. 그러나 일명 찌라시라고 하는 소수만 아는 정보만을 찾아서 대박만을 따르게 된다. 물론 가끔은 정말 대박이 날 수도 있지만 대부분은 무의미한 정보에 추종하는 경향이 많다.
만들어진 스토리에 대한 편향적 사고 : 그럴 듯한 투자 소식이나 신제품 등의 대대적인 기사등을 남발하지만 실제 공시 등에는 이와 관련된 정보들이 너무 제한적인 기업들이 있다. 일반적이라면 의심을 해야하는 상황임에도 불구하고 너무 잘 짜여진 각본을 믿고 거의 의심도 없이 투자를 결정하게 되는 경우가 많다. 물론 장기적으로는 사실일지도 모르지만 거품이 잔뜩 낀 후에는 폭락만이 반길 뿐이다.
후회/분석 회피에 대한 편향적 사고 : 무슨 일이던 한번에 잘 할 수는 없는 것이기 때문에 실패한 것에 대한 후회와 이에 대한 분석을 통해 앞으로 어떻게 대처할 것인지에 대한 검토가 필요하지만 가능하면 이를 회피해서 아픈 기억을 외면하려고 한다. 따라서 그 때마다 그냥 세력, 기관/외국인, 정보, 공매도 등만을 욕하고 넘어가게 되고 다시 똑같은 일을 반복하게 된다.
사이버 머니/도박에 대한 편향적 사고 : 실제 손에 돈을 들고 물건을 살 때는 이것 저것 많은 상황들을 검토한다. 그런데 온라인으로 투자를 하게 되면 마치 게임머니를 다루는 것과 같은 심리 상태가 된다. 그러다보니 도박에서 배팅하는 것과 같이 몰빵하거나 이런 저런 재료에 대한 검토 없이 올라가는 것만 보고 일단 지르고 본다.
아직은 아무것도 모르는 상황이지만, 무작정 투자는 결국 망할 수 밖에는 없다는 것이다. 복권의 경우도 그렇게 많은 돈을 투자하지만 결국 원금도 회수하지 못하는 상황이 대부분이듯 조금씩 망해가는 것일 뿐이다.
도박은 패가망신의 지름길이라는 것은 모두 다 알고 있고 경계하지만 왜? 자신의 도박과 같은 투자는 그런 경계심을 갖지 않을까?
위에서 언급했던 것과 같이 인간의 본성을 기반으로 경제학을 연구한 결과와 같이 사람의 본성은 고차원이 상황에서는 모순 투성가 될 수 밖에는 없는 것 같다.
당장 망하는 모습이 보이지 않는다고 망하는 것이 아니라고 생각할 수 있는 과잉확신 평향이라도 빨리 고치고 로보어드바이저와 같이 규칙을 감정과 별개로 운영할 수 있는 연습을 하지 않으면 언제고 똑같은 결과를 보며 스스로를 원망하는 수준에서 벗어나지 못할 것 같다.
당신은 위에서 나열한 투자에 실패하게 되면 편향적인 사고들 중에서 몇 개나 속하나요?
Notes
위의 글을 읽은 후에 시간이 좀 지났지만 현재는 다음과 같은 규칙을 시스템으로 적용하고 있다.
- 각 매수별로 신규 잔고 감시 (일종의 Stoploss) 를 운영한다.
- 단타 기준으로 대략 3% 이익과 2% 손절의 규칙을 운영한다.
스윙이나 장기는 매뉴얼로 다음과 같은 규칙을 적용하고 있다.
- 셀프펀드와 같이 일정 금액을 기준으로 모아간다.
- 목표치 10% 이상에서 반절을 털고 상황을 봐서 추가 또는 정리를 확정한다
정보 정리는 매일 투자일지와 같이 정리를 해서 가능한 많은 정보들이 겹치거나 언급되는 종목들을 기준으로 매매를 진행한다.
이런 방법이 맞을지는 아직 모른다. 계속적인 투자를 진행하면서 좀더 다양하고 구체적인 규칙을 세우고 가능하면 시스템화 시켜서 운영할 수 있도록 해야한다.
아마도 조금 더 지나면 증권사의 API 을 연계하는 나만의 HTS 자동매매를 만들어야 할지도 모르겠다.
]]>프로젝트를 진행하면서 쿠버네티스 클러스터 구성을 AWS
, AZURE
, GCP
환경에 구축하면서 kubeadm
툴을 사용했다. (각 프로바이더들이 제공하는 컨테이너 서비스를 이용한 것이 아니라 bare-metal 과 같이 인스턴스를 생성해서 클러스터를 구축하는 방식을 적용했다)
이전에는 알파 버전이었지만 현재는 베타 버전인 것으로 알고 있다. 새롭게 클러스터를 구축하는 것이라면 당연히 쿠버네티스를 설치하면 되지만 기존에 설치되어 있는 클러스터를 업그레이드를 하는 것은 딱히 정형화된 방법을 찾지 못했었다.
kubeadm
을 이용해서 설치하는 방법은 이미 많은 자료들이 존재하기 때문에 따로 게시글을 올리지는 않았지만 (혹여 누군가 요청을 한다면 올릴 예정) 이미 설치된 클러스터를 수동으로 설정해서 업그레이드가 가능하기 때문에 이를 정리해 보도록 한다.
가장 먼저 수행할 부분이 현재 버전과 업그레이드할 버전을 검증하는 것이다. 버전 정보 를 참고해서 대상 버전과 실행버전 정보를 확인해 한다.
1 | # 클러스터 구성 버전 확인 |
여기서는 쿠버네티스 1.6.2 에서 1.6.4 로 업그레이드 하는 것을 기준으로 한다.
버전 확인이 되었다면 가장 먼저 클러스터를 구성하고 있는 모든 노드들에 설치되어 있는 시스템 패키지를 업그레이드 해야 한다.
1 | $ sudo apt-get update && sudo apt-get install -y kubelet kubeadm kubectl kubernetes-cni |
그리고 쿠버네티스를 구성하고 있는 컴포넌트들을 갱신해 줘야 한다.
각 컴포넌트는 마스터 서버에 존재하기 때문에 아래의 명령을 통해서 운영에 필요한 설정 파일들의 이미지 버전 정보를 변경해 줘야 한다.
1 | $ sudo sed -i 's/v1.6.2/v1.6.4/g' /etc/kubernetes/manifests/* |
위의 명령은 sed 툴을 이용해서 /etc/kubernetes/manifests/
경로에 있는 모든 파일들을 대상으로 내용 중에서 지정한 정규식에 맞는 부분을 변경하는 작업을 수행하는 것이다.
kube-proxy
는 DaemonSet
이기 때문에 Rolling update 를 지원하지 않는다. 따라서 실행 중인 kube-proxy 컨테이너를 수동으로 삭제하고 아래의 명령으로 DaemonSet 정보를 갱신해 줘야 한다.
1 | $ kubectl edit daemonsets kube-proxy -n=kube-system |
최신 버전을 아래의 명령을 통해서 검증해야 한다.
1 | $ curl -s https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/kubedns-controller.yaml.base | grep image |
dns 에는 3개의 이미지가 존재하므로 버전을 변경해 준다. 배포는 Rolling update 를 지원하기 때문에 아래의 명령을 실행하면 된다.
1 | $ kubectl edit deployments kube-dns -n=kube-system |
위의 처리를 수행하면 다음과 같이 재 구성되어 동작하는 파드 컨테이너들을 확인할 수 있다.
향후에는 기본적인 옵션으로 제공이 될 것으로 예상이 되지만 현재는 위와 같이 단계별로 처리를 해 주면 큰 문제없이 갱신이 가능하다.
이제 변경된 이미지 버전에 따라서 모든 컨테이너들이 원격에서 다운로드되어 변경될 때까지 기다리면 된다.
1 | $ watch -n 2 kubectl get pods -o wide --all-namespaces |
Importants
단, 특정 버전을 대상으로 한 것이기 때문에 다른 버전에서는 인증 방식과 같은 환경 상의 문제 등으로 오류가 발생할 수 있다. 특히 1.5.x 버전 대에서 1.6.x 버전으로 넘어가는 경우는 인증 방법과 데이터 저장 방식등의 변화가 있기 때문에 문제가 발생할 소지가 상당히 많을 수 있다. (이 부분은 직접 테스트해 볼 기회가 없어서 검증을 하지 못한 상태다)
References
하고 싶은 것을 다 하면서 살 수 있으면 좋겠지만, 흙수저 출신인 나에게는 꿈과 같은 이야기일 뿐이고, 그렇다고 남달리 능력이 좋은 것도 아니고, 경력관리를 잘해서 주 분야가 있는 것도 아닌 일반 단순 개발자라서 시장에 부름을 받기는 힘든 상황이니 인생 후반기를 대비해야 할 무엇인가를 늦었지만 빨리 찾아야 할 상황이다.
딱히 기술이 있는 것도 아니고, 금손도 아니고, 대인 관계가 그렇게 활발한 것도 아니기 때문에 여러 가지를 고려해 볼 때 주식 투자가 적합해 보인다. 그러나 시드 머니도 없는 상태고, 관련된 지식도 없는 상태라서 아주 조금씩이라도 부업으로 가능성이 있는지를 확인하는 차원에서 용돈이라도 벌어보자는 도전을 해 보려고 한다. 물론 쉽지 않은 도전이지만 최소한 투자한 시간 대비 최저 임금 수준만 유지하면 용돈으로 쓰기에는 만족할 수준일 것 같다. 향후에는 용돈을 넘어 생활비 벌기에 도전할 수 있도록 열심히 해야할 듯 하다.
"아무 것도 하지 않으면, 아무 일도 일어나지 않는다."
가능성이 있는 것일지, 성공일지, 실패일지를 미리 고민할 필요는 없다. 돈을 잃는다고 해도 그만큼의 경험을 살 수 있다면 나름대로 성공한 것일거다. 물론 계속된 실패를 반복하지만 않는다면 말이다.
주식에 관해서는 아는 것이 별로 없다. 그냥 상식적인 수준에서 단어만 몇개 알고 있을 뿐이다.
시작은 작게 그러나 향후의 꿈은 크게 하는 것이 좋을 듯 하다.
주식시장에 등록된 주식수가 2,000 종목 내외라고 한다. 망할 회사가 아니라면 주가의 흐름 상으로 언젠가는 복구가 될 수 밖에는 없는 것으로 판단이 되고, 업종 / 섹터 등의 구분이 필요하지만 지금은 아무것도 모르는 상태이 그냥 여러 가지 정보 중에서 가능성이 있다고 판단되는 것을 기준으로 선별해 본다.
종목 | 관련 종목 | 정보 |
---|---|---|
필룩스 | 장 시작 30분 이내에 전일 거래량의 100%를 넘겼다. 대형 신규사업 발주 예정 소문 | |
에스디생명과학 | 공모가 이하 진행 중, 중국 한한령 풀리면 화장품/합작드라마 가능성 있음 | |
에이디칩스 | 디에스티로봇, 우리기술,디피시,셀바스AI | 인공지능, 로봇, 사물인터넷 핵심 초경량 CPU 코어 개발 성공, 5월 중 상용화 가능성, 삼성전자와의 연계 |
한신기계 | 적대적 M&A 가능성 |
아직은 뭐가 좋고 나쁜지에 대한 판단을 제대로 하지는 못하지만, 가능성 있는 종목들을 고르다 보면 좋은 결과가 있을지도 모르겠다.
매일은 아닐지 몰라도 관련된 종목과 정보들을 정리하다 보면 연관성과 시장을 바라보는 경험이 쌓일 것이라고 생각한다.
첫날인 오늘은 다행하게도 목표인 +3%에 턱걸이를 했지만 내일은 또 어떨지 벌써 궁금해지고 있다. 내일도 웃을 수 있을까? ^^
Importants
- 매수할 때 목표 수익률과 손절률 정하고 지키기
- 지속 가능성이 적다면 당일로 매도해서 이익 보전 또는 손해 줄이기
- 장기적인 가능성이 있다면 소량씩 분할로 모아가기
- 10원을 벌어도 잃지 않으면 손해가 아니다
- 절대 욕심내지 말고 이익 또는 본절 지키기
- 손절은 생명을 구하는 것과 같다
느리고 답답하더라도 하나씩 자신만의 규칙을 정해가면 좋은 결과가 있을 듯 하다.
]]>Kubernetes 관련 정보들을 검색하던 중에 kubectl
툴을 좀 더 활용할 수 있는 팁 정보가 있어서 정리해 놓는다.
kubectl 은 쿠버네티스를 운영하기 위한 CLI 도구로 상당히 많은 기능들을 제공하기 때문에 기능들을 다 파악하는 것은 어렵지만 강력한 도구로 활용이 가능하다.
기본적인 사용법에 관련된 것은 Cheatsheet 를 참고하면 된다.
kubectl 은 bash 및 zsh가 내장된 쉘 완성 기능을 제공하기 때문에 명령, 플래그 및 객체를 네임스페이스 또는 파드 이름과 같이 자동 완성으로 사용하는 것이 훨씬 쉽다.
아래의 그림은 실제 자동완성 기능을 제공하도록 설정한 후의 사용법을 보여주는 것이다.
원문 에는 kubectl 바이너리 설치부터 설명이 되어 있지만 대부분은 kubernetes 설치환경일 것이므로 자동 완성만 처리하면 된다.
Notes
자동 완성 스크립트는 kubectl에 의해서 생성되므로 프로파일에 설정해서 사용하면 된다. 관련된 정보는
kubectl completion -h
를 확인하면 된다.
리눅스 bash 환경에서 자동완성 스크립트를 Shell 로 로드 처리는 아래의 명령을 사용하면 된다.
1 | $ source <(kubectl completion bash) |
프로파일에 적용하려면 아래의 명령으로 프로파일에 적용해 주면 된다.
1 | $ echo "source <(kubectl completion bash)" >> ~/.bashrc |
맥에서 bash 자동 완성을 수행하려면 아래의 명령으로 자동완성 지원 기능을 먼저 설치해야 한다.
1 | $ brew install bash-completion |
Shell에 자동완성 스크립트 로드 처리는 아래의 명령을 사용하면 된다.
1 | $ source $(brew --prefix)/etc/bash_completion |
프로파일에 적용하려면 아래의 명령으로 프로파일에 적용해 주면 된다.
1 | $ echo "source $(brew --prefix)/etc/bash_completion" >> ~/.bash_profile |
여러 쿠버네티스 클러스들과 상호 작용을 하는 경우라면 쿠버네티스 설정을 병합하는 것이 일반적인 패턴이며 병하해서 사용할 떄 특정 클러스터를 사용하도록 하는 파라미터들을 서술하기 위해 context 개념을 사용한다.
제대로 운영하기에는 복잡하기 때문에 KUBECONFIG
환경 변수를 사용해서 구성 파일을 지정하도록 병합할 수 있다.
만일 병합할 2개의 쿠버네티스 클러스터 (cluster1, cluster2) 가 있다면 각 클러스터별로 정보를 가지는 설정 파일이 다음과 같을 것이므로 이를 개별 파일로 구성하도록 한다.
클러스터 #1 설정
1 | $ kubectl config view --minify > cluster1-config |
클러스터 #2 설정 (#1 에서와 같이 처리해서 사용할 장소에 복사하면 된다)
1 | $ cat cluster2-config |
위의 2개 설정을 KUBECONFIG
환경 변수를 통해서 접근할 수 있도록 병합하고 context 지정을 통해서 2개의 클러스터를 동적으로 사용할 수 있다. context 는 클러스터를 인증 및 상호작용하도록 구성을 참조할 수 있는 클러스터, 사용자 및 이름을 설명하는 맴 정보라고 생각하면 된다.
이제 --kubeconfig
플래그를 이용해서 각 파일의 context 정보를 확인할 수 있다.
1 | $ kubectl --kubeconfig=cluster1-config config get-contexts |
각각의 설정 파일은 하나의 context를 가지기 때문에 서로 충돌하지 않으며, 두 파일을 실제 병합하면 두 개의 Context 가 모두 표시된다.
병합을 위해서 cluster-merge
라는 새로운 파일을 만들고 아래와 같이 처리를 하면 된다.
1 | $ export KUBECONFIG=cluster-merge:cluster-config:cluster2-config |
병합되는 순서는 지정된 순서대로 처리되고 current-context 는 첫번째 구성 파일에서 지정한 context 가 되기 떄문에 액티브 표시 (*
) 가 cluster1 context 를 가르키고 있는 것을 확인할 수 있다.
context 를 2번쨰로 변경하면 정보를 아래와 같이 보여지게 된다.
1 | $ kubectl config get-contexts |
병합에 사용했던 파일을 확인해 보면 아래와 같이 변경된 것을 확인할 수 있다.
1 | $ cat cluster-merge |
실제 사용되는 클러스터는 항상 current-context
정보로 확인할 수 있다.
Context는 강력하고 다양한 방법으로 활용 및 병합이 가능하다. 예를 들어 모든 kubectl 명령에 적용될 수 있도록 네임 스페이스를 지정하는 Context 를 만들 수도 있다. (사실 매번 네임스페이스 지정하는 것도 귀찮은 일이다)
1 | $ kubectl config set-context cluster1_kube-system --cluster=cluster1 --namespace=kube-system --user=cluster1 |
위의 예는 cluster1 에 kube-system
이라는 네임스페이스를 모든 명령에 사용할 수 있도록 context를 구성한 것으로 아래와 같이 context를 지정해서 사용할 수 있다.
1 | $ kubectl config use-context cluster_kube-system |
context 에 네임스페이스가 지정되어 있기 때문에 각 명령 단위로 추가로 지정할 필요가 없다.
Kubernetes는 API 정보 제공을 위해서 swagger UI
가 통합되어 있다. 따라서 아래의 명령으로 json 문서를 얻을 수도 있다.
1 | $ kubectl proxy |
아니면 직접 http://localhost:8001/api/ 페이지를 통해 정보를 확인할 수도 있다.
만일 json 문서를 활용한다면 jq
툴을 이용해서 활용할 수도 있다.
1 | $ cat swagger.json | jq '.paths | keys[]' |
api-versions
명령은 관리자로 실행되며, RBAC가 활성화된 경우라면 다른 API 세트 정보가 표시될 수 있다.
1 | $ kubectl api-versions |
explain
명령은 각 파트에 대한 이해를 위한 기능적인 도움을 제공한다.
1 | $ kubectl explain |
예를 들어 explain deploy
명령을 실행해 보고, deploy 의 좀더 세분화된 객체를 지정해서 정보를 확인할 수도 있다.
1 | $ kubectl explain deploy.spec.template.spec.containers.livenessProbe.exec |
다양한 기능들을 제공하기 때문에 모든 것을 알지도 못하고 정리하는 것도 쉽지는 않지만 다양한 자료들을 확인하면서 유용하다고 생각되는 기능들은 비록 발 번역 수준에 오타, 다른 이해가 있더라도 정리를 해 나갈 예정이다.
현재는 프로젝트를 쉬고 있는 중이지만, 향후 실제 기업에서 운영되는 어플리케이션들을 Containerize 처리와 Kubernetes Cluster에 배포 운영하는 프로젝트를 진행할 예정이기 때문에 좀 더 현실적이고 구체적인 사례들을 정리할 수 있을 것 같다.
References
취미지만 이왕이면 제대로 확인을 해 보고 싶어서 여러 가지를 검색해 보던 중에 큐스코 시스템을 사용하는 구장들이 있다는 것을 알았다.
집에서 가장 가까운 곳을 검색해 보니 신대방 SBS 당구장이 나왔다. 유튜브에서 하이런등의 경기 영상을 많이 보던 곳인데 의외로 가까운 곳에 위치해 있어 용기(?) 내서 다녀왔다.
정액제 동호회가 아니기 때문에 전투적으로 임해야 하는 살벌한 구장이다. 대대 (10분 2,000원) 경기도 많이 해보지 않아서 많이 힘들었지만 중대에서 치는 것과는 다른 기분이다. 일단 무지하게 넓고 힘을 많이 써야할 듯 하다.
2일 동안 4게임을 진행하면서 하이런 4점과 6점을 기록했고, 20, 21, 22 점과의 대결에서 모두 승리했다. 물론 재수(뽀록)가 많이 도움이 되었지만 그래도 상대방과 비교해서 터무니없이 못치는 수준은 아니라는 것을 확인했다. 당연히 기본적인 실력은 내가 모자라다는 것을 느끼지만…
역시나 동영상으로 촬영된 내 플레이 영상을 보니 상당히 많은 문제점들이 존재했다. ㅠㅠ
기타 등등의 문제가 너무나 많다는 사실과 이런데 어떻게 이겼지?? 라는 의문이 든다. 쩝~
큐스코 구장을 사용했을 때의 좋은 점은 여러 가지가 있다.
2017년 5월 11일에 기록한 하이런 6점 영상
음, 영상을 보면서 또 하나 느낀 것은 관리되지 않은 얼굴과 몸매가 그대로 드러나는 단점이다. 취미로 운동(헬쓰와 스쿼시)을 다시 시작해야할 것 같다 ㅠㅠ
]]>“MSVCR (Microsoft Visual C++ Runtime)” 관련 오류는 어플리케이션을 직접 개발해서 배포하거나 아니면 다른 어플리케이션을 설치해서 사용할 때 흔히 발생하는 오류 중에 하나기 때문에 큰 문제는 없다. 그러나 조치를 취했음에도 불구하고 동일한 오류가 계속 반복되는 경우라면 상황을 잘 파악해 봐야 한다.
거의 대부분은 MSVCR 라이브러리가 설치되지 않았기 떄문에 발생한다. 주로 볼 수 있는 오류 상황은 다음과 같다.
설치가 되지 않은 상황이거나 아니면 버전 또는 아키텍처와 관련되어 라이브러리를 로드할 수 없는 경우도 존재한다.
오늘 이 게시글을 작성하는 이유는 설치도 로드도 모두 잘 되었지만 사용 중에 오류가 발생하면서 어플리케이션이 종료가 되는 경우도 있기 때문이다. 이 경우는 아마도 C++ 코드 작성에서 메모리 처리를 하면서 OS 특성을 타는 부분일 것으로 예상된다.
발생한 오류는 예외 코드 0xc0000417
이며 발생한 모듈은 MSVCR90.DLL
이다. 좀 더 구체적인 상항은 덤프된 정보를 분석해 봐야하지만 일반적인 해결 방법을 적용해 보도록 한다.
해결 방법은 구체적인 오류 발생 정보가 없는 경우라면 아래와 같이 단순하게 적용해 볼 수 있다.
설치가 안된 상태이거나 설치에 문제가 있거나 아니면 다른 버전과의 문제가 있다면 프로그램 및 기능
을 통해서 기존에 설치되어 있는 것을 제거한 후에 재 부팅해서 다시 설치하는 방식을 사용하면 된다.
설치를 해서 필요로 하는 버전과 아키텍처가 맞는지를 확인해 봐야 한다. 필요하다면 다른 버전의 배포판도 검토해야 한다.
설치도 모두 되어 있고, 정상적으로 어플리케이션이 실행도 되지만 특정한 상황에서 오류로 종료되는 경우라면 작성한 개발 코드가 OS 아키텍처나 특성 상의 문제가 내포하고 있는 경우가 대 부분이다.
따라서 이런 경우는 어플리케이션에서 문제를 해결한 새 버전을 배포하지 않는 한은 어플리케이션 호환성을 설정해 주고 실행해서 문제가 없는 상황으로 어플리케이션을 실행시키는 방법을 사용해야 한다.
문제가 되는 어플리케이션의 "속성 창"을 열고 "호환성 탭"을 선택한다.
그림에서 빨간 박스로 처리한 “호환성 문제 해결사 실행” 을 누르면 "호환성 마법사"가 동작을 하는 것이고, 익히 겪어본 상황(?) 이라면 파란 박스로 처리한 부분을 직접 설정해서 사용하면 된다.
호환성 문제 해결사는 관련된 문제 요소를 검증해서 자체적인 규칙으로 호환성을 설정한 후에 선택할 수 있도록 제공한다.
권장 설정을 선택하면 해당 프로그램을 테스트 할 수 있도록 제공하므로 반드시 “프로그램 테스트…” 를 눌러서 호환성 환경에서 어플리케이션의 문제가 발생하지 않는지를 확인해야 한다.
위의 호환성 테스트 실행에 문제가 없는 것을 확인하면 다음
버튼을 눌러서 호환성 설정을 어플리케이션에 반영해야 한다. 반영된 설정으로 다음 실행부터 계속 적용이 된다.
Importants
설정이 저장되어 잘 실행된다고 해도
Windows Update
등과 같은 처리가 진행되면서 기존의 호환성 설정 정보가 적용되지 않는 경우도 심심치 않게 발생하므로 문제가 발생할 경우는 다시 호환성 설정을 처리해 줘야 한다.
개발자들이 흔히 간과하는 것이 개발 환경과 실행 환경이 판이하게 다를 수 있다는 점이다. 개발 환경에서 모든 설정을 해 놓고 어플리케이션이 잘 돌아간다고 하는 것은 전혀 다른 사용자의 환경을 고려하지 않았다는 반증이다. 따라서 개발이 완료된 상태라면 블라인드 테스트와 배포 테스트를 통해서 어플리케이션의 실행에 필요한 라이브러리나 설정이 빠진 것이 없는지를 모두 검토해 봐야 한다.
Notice
간혹 msvcr90.dll 파일을 직접 복사해야할 경우가 생길 수 있는데 다음의 경로를 검토해 보면 된다.
- 32 bit인 경우 : C:\Windows\System32
- 64 bit인 경우 : C:\Windows\SysWOW64
References
작년 1월부터 다시 시작을 했고, 3구 기준으로 이제 20점이다. 물론 아직은 제대로 원리를 이해하지는 못하는 수준이지만 개발도 맨땅에 헤딩하면서 배웠듯이 당구도 지금 열심히 헤딩 중이다.
이런 저런 이론적인 것을 동호회나 카페, 유튜브 등에서 읽어보고 휴일에 당구장에서 살 듯이 연습을 해 보지만 역시나 이론과 실제는 너무나 차이가 많다는 것을 체감할 뿐이다. ㅠㅠ
예전에는 거의 4구 경기만 했었기 때문에 오늘 소개하는 것도 역시 4구에 대한 이론 (주로 세리)을 개인적으로 정립하신 정필규님의 자료다.
겨냥점이라는 것은 어려운 것이 아니다. 수구로 제 1 목적구를 맞춘 후에 제 2 목적구를 맞추기 위해서 어떤 곳을 향해서 쳐야 하는지를 정리한 것이라고 생각하면 된다.
여기서 당구의 이론과 각종 시스템을 논의하는 것도 아니고, 내가 좋아하는 취미고, 4구 이론을 3구에도 적용할 수 있을 것 같아서 소개하는 것이다.
아직은 형편없는 수준이지만 몇 가지만 기억하면서 연습하면 될 듯 하다.
당구라는 것이 워낙 다양한 변수들이 조합되는 것이라서, 딱히 정답이라는 것은 없을 수 밖에 없다. 단지 고점자들이 다양한 경험을 기준으로 대략적인 방법을 만들어 놓은 것 (시스템)을 제시하는 것일 뿐이다.
몇 번 시스템을 검토해 보고 따라해 봤지만, 나는 역시 감으로 하는 당구 (무식한 감이 아니라 어느 정도 확률이 높은 나만의 라인을 찾아가고 있다)가 맞는 듯 해서 지금도 열심히 감을 키우고 있다.
목표는 2년 안에 30점을 만드는 것이다. 듣기로는 40점 이상부터 프로 선수 수준이라고 하고 대 부분 1년에 1점씩 그것도 많이 연습해서 올릴 수 있다고 하니 너무 높은 목표인 듯 하지만 그래야 열심히 할 듯 하다. 물론 항상 좌절을 느끼겠지만…
혹시 저와 같이 당구가 취미이신 분은 댓글 달아 주세요. 지역/시간 맞으면 같이 즐겨요~ ^^
References
Importants
Kubernetes Cluster를 테스트하고 운영하는 것과 관련해서 프로젝트를 진행하면서 겪었던 내용과 유사한 고민과 해결방법을 제시하는 글을 보고 고민했던 내용과 게시글을 혼합해서 일단 정리해 놓도록 한다. 어떤 부분은 실제 적용한 부분도 있고, 다른 부분은 실제 테스트를 못해 봤기 때문에 관련된 참고 게시글의 내용을 나름대로 유추해서 정리한 부분도 존재한다.
따라서 아래의 정리된 내용은 개인적인 판단과 이해를 기준으로 정리한 것이기 때문에 Kubernetes 에서 제시된 정보와 다를 수 있으며 혼선을 일으킬 수 있다. 따라서 Kubernetes에서 제시하는 모든 관련 문서들을 읽으신 후에 수 많은 케이스 중에 하나일 뿐이라는 생각으로 접근하는 것이 좋다.
프로젝트가 진행되는 동안 AWS 상에 Kubeadm 를 이용해서 Kubernetes를 설치하고 각종 테스트 및 데모를 진행 했었다.
그 과정에서 운영을 위한 몇 가지 문제점들에 직면 했었고 문제점들은 서로 연관성을 가지고 발생하는 것으로 보이기에 여러 가지 상황들을 검토 하고 적용해 보았다.
Notes
리소스라는 것은
CPU
,Memory
,Disk
,Network
, … 등이 될 수 있지만 현재 버전에서는 대 부분 CPU, MEMORY를 기준으로 한다.
진행하면서 정말 다양하고 이해하기 애매한 상황들이 발생했지만, 결국 모든 것은 클러스터 내에서 어떻게 리소스를 배정하고, 서비스를 운영하기 위한 정책적인 결정과 제한 처리들을 구성하는냐?
의 문제를 정리하면 될 듯 하다.
고민하고 검토했던 내용들은 간략하게 정리하기에는 어렵고 광범위한 내용이지만 적용했던 결론(?)을 기준으로 하나씩 알아보도록 한다.
Kubernetes 기본 옵션으로 클러스터가 구성되면 각 노드들은 Pod 배정을 BestEffort
방식으로 처리한다. 즉, 배정되면 노드의 모든 리소스를 무제한으로 사용하려고 한다. 추가 배정이 이뤄지면 각각 분할해서 최대한 사용하려고 한다. 이런 상황에서 데이터베이스와 같이 리소스를 과다하게 사용하는 Pod 들이 리소스 사용에 대한 규칙없이 배정이 되기 시작하면 어느 순간부터 Pod 들이 종료와 재 배정의 상태에 빠지고 로그를 확인하면 OOM Killed
와 관련된 오류들을 자주 접하게 된다.
리소스에 관련된 것은 대부분의 문제를 야기했던 가장 중요한 부분이고 모든 것의 근원이 되는 것으로 서비스에 대한 요청 (requests) 량과 제한 량 (limits) 를 기준으로 리소스의 배정을 결정해야 한다.
이 부분은 쉽게 결정할 수 있는 부분이 아니기 떄문에 문서를 읽어보고 신중하게 접근하기를 바란다. 간략하게 의미를 정리하면 다음과 같다.
Importants
만일 어플리케이션의
CPU 사용량이 설정된 limit 값을 넘어서는 경우는 CPU 할당에 따른 지연
이 발생한다. 그러나Memory의 경우는 limit 값을 넘어서는 순간 Pod 가 강제로 종료
되는 문제가 있다. 종료가 되면Replica 설정 때문에 다시 배정되는 상황이 발생
하는데 노드들이 과부하가 걸려서 배정할 수 있는 노드가 없다면 배정될 수 있을 때까지 계속 배정 시도를 하는 문제가 발생하게 된다. (물론 재생성 금지 등의 옵션을 설정할 수도 있기는 하다)
대략적인 구성은 아래와 같으며 namespace
단위로 적용된다.
1 | apiVersion: extensions/v1beta1 |
위의 예는 nginx 어플리케이션의 CPU 와 Memory에 대한 request, limit 값을 설정해서 실행하는 것이다. CPU 는 최소 100m 에서 최대 500m (Milicores 단위) 까지 사용하고 Memory는 200Mi 에서 600Mi (MegaByte 단위) 까지 사용 하도록 설정한 것이며, Pod 가 배정이 되면 Dashboard 의 namespace
에서 Resource Quota 정보를 확인할 수 있다.
Importants
위의 정보는 Pod 의 Resource 설정에 대한 부분이므로 실제 배정될 노드의 가용 량과는 상관이 없다. 따라서 클러스터를 구성하고 있는 모든 노드들이 request 를 충족하지 못할 정도로 과부하가 걸린 상태라면 배정되지 못하고 계속 생성 대기 상태가 될 수도 있다.
문제는 리소스 사용량을 지정하는 것이 중요한 것이 아니라 정말 이 값이 적절한 것인가?
를 검토해야 한다.
딱히 정답이 없는 것이기 때문에 실제 구성할 떄는 다음과 같이 결정을 진행했었다.
물론 아주 단순 무식한 방법이기는 하지만 대략적인 적용은 할 수 있다. 중요한 것은 지속적으로 모니터링을 통해서 변경되는 리소스량을 최대한 근접하게 조정해가는 것이다.
Kubernetes 에서 서비스를 생성할 떄 service.beta.kubernetes.io/aws-load-balancer-internal
annotation을 지정하면 AWS Elastic Loadbalancer에 연결할 수 있다. 그러나 Kubernetes Cluster에서 운영하는 모든 서비스를 연결해서 운영하는 것은 비용적인 소비가 너무 많이 발생하게 된다.
Kubernetes에는 Ingress
가 존재하기 때문에 nginx 기반의 Ingress Controller를 구성
하고 서비스들을 여기에 연결하면 모든 서비스 요청은 Controller가 대상이 되는 Pod로 연결되도록 하기 때문에 AWS Loadbalancer를 Controller 당 하나씩만 유지하면 된다.
Ingress 작동 방식
을 잘 참고해서 처리하면 된다. Ingress와 Ingress Controller는 혼란스럽게 느껴지기는 하지만 Ingress는 정보의 집합이고 실제 분배는 Controller가 처리하는 것으로 개념을 잡으면 된다.
일반적으로 개발이 진행되는 동안에 검증을 위해서 서비스를 배포하고 테스트를 수행하고, 별 다른 문제가 없다면 다음 단계로 진행하게 된다. 그러나 배포된 서비스는 실제 사용되는 것과 상관없이 수행 중인 상태로 유지된다. 따라서 실제 사용이나 테스트 등과 상관없이 유휴상태가 되는 Pod 들을 종료시켜서 효율적으로 클러스터가 운영될 수 있도록 하는 것도 중요하다.
필요없는 서비스를 삭제한 후에 필요할 떄 다시 생성하는 것 보다는 Scale up/down 방식이 더 효율적인 것으로 판단해서 주기적으로 최근에 Ingress 설정을 통해서 접근되지 않았고 특정 시간 미만으로 동작하고 있는 서비스들을 제외한 서비스를 찾아서 Pod 를 제거 (Scale down to 0)해서 다른 작업에 클러스터의 리소스를 활용하는 운영을 하고, 향후에 필요할 때 Scale up 해서 사용하면 되는 방식을 적용하는 것도 좋다.
아래의 예제는 위의 처리 조건을 검증하는 것으로 1시간 동안에 Ingress를 통해서 접근이 발생했고, 30분 넘게 유지되고 있는 서비스를 골라서 제거하는 스크립트로 10분 단위로 수행될 수 있도록 crontab 에 등록해서 사용하면 된다.
1 |
|
위의 예제는 실제 적용할 조건에 맞춰서 시간이나 namespace 이름 규칙등을 수정해서 사용하면 된다.
Kubenetes 1.4 버전부터 Autoscaler
기능이 지원되고 있으며, AWS에서 실행하기
가이드도 확인할 수 있다. 물론 다른 클라우드 공급자 부분도 있지만 확인해 보지는 못했다.
주된 기능은 다음과 같은 상황에서 Cluster Size를 조정하는 것이다.
전체적인 부분을 모두 검토한 것은 아니지만 대략 Damons set 이 없거나, Mirror 상태가 아니거나 kube-system pod 들이 여러 노드에 분산되어 있는 경우등을 제외하면 아주 훌륭하게 적용할 수 있는 것으로 보인다.
Cluster-Autoscaler 는 계절적 또는 주기적으로 활용과 비 활용이 반복되는 경우에 적용할 수 있을 것으로 보인다. 즉, 평상시에는 잘 활용하다가 비 활용 시점이 되면 Cluster를 축소할 수 있도록 AutoScale Group에 예약된 작업 (특정한 시간이 되면 노드의 수를 줄이거나 늘리는 작업)을 등록해서 동적으로 운영될 수 있도록 조정하면 더욱 효율적으로 운영이 가능하다.
물론 이 작업이 진행되는 동안에 축소의 경우는 Pods 가 종료되고 재 배치되는 과정이 존재하기 떄문에 일부 서비스가 중지되는 상황이 발생할 수는 있지만 시간대를 잘 선택하면 외부의 접근이 발생하기 이전에 처리할 수 있으므로 큰 문제가 되지는 않을 것으로 보인다.
실제 데모를 위해서 사용한 마이크로 서비스 예제에서 Java로 구성된 어플리케이션이 많아서 CPU 는 별로 사용하지 않지만 메모리를 많이 사용 (대략 700M 언저리)하는 문제가 존재 헀었다.
이 문제 때문에 m2.small 등의 인스턴스를 사용했을 떄 메모리 병목현상과 limit 초과 문제로 인해서 Pods 가 종료되고 재 배치되는 등의 부작용을 많이 겪었다.
Importants
실제 운영과 테스트를 해 보면 CPU 가 부족한 경우보다는 Memory가 부족해서 문제가 생기게 된다. Master 서버가 아닌 경우라면 CPU에 큰 제한이 없기 때문에 차라리 Memory를 충족하게 사용할 수 있는 인스턴스를 선택하는 것이 좋다. 물론 CPU를 과도하게 사용해야 하는 어플리케이션의 경우라면 모두 잘 검토해야 한다.
디스크의 경우도 기본 값인 8G 를 사용해서 테스트를 진행했지만 너무 부족한 상태에서 문제가 발생했었고, 30G (IOPS 100)로 설정했을 때는 디스크 부족 문제의 발생보다는 성능의 문제가 존재하기 때문에 IOPS 가 높게 선택하면 실제 사용량대비 비용이 과다하게 나오는 문제가 발생한다. 따라서 어느 정도의 타협으로 100G (IOPS 300) 정도로 타협하면 충분할 것으로 예상해서 적용했다.
물론 이 부분도 어떤 어플리케이션을 실행할 것인지가 중요하기 때문에 상황에 따라서 선택하면 된다.
또한 AWS 에서 Spot Instance가 아닌 Reserved Instance를 사용하면 좀 더 비용을 줄일 수 있는 것으로 알고 있으므로 이를 잘 활용하면 된다.
지금까지 알아본 것은 실제 대외 서비스를 위한 환경이 아닌 내부 개발 및 데모를 위한 과정에서 검토한 내용들이다. 그러나 언젠가는 대외 서비스를 위한 프로덕션 환경으로 이전해야 할 것이기 때문에 다음과 같은 상황들을 검토해 봐야 한다.
Horizontal Auto Scaler
를 활용하는 것으로 검토해야 한다. 기준은 CPU 사용량에 따라서 확장 또는 축소를 처리하게 된다. (단, CPU 사용량 기준이라는 것이 애매해서 좀 꺼려지기는 하다)데모를 위해서 AWS, Azure, GCE 등을 이용했지만 실제 데모 횟수보다는 운영되는 기간대비 비용이 과다하게 발생했다. 물론 서비스의 안정성은 더욱 중요하지만 좀 더 다양한 측면에서 기준을 세운다면 Kubernetes Cluster를 위에서 검토한 것 이상으로 서비스와 운영비용 절감 등의 방법을 찾게 될 것이라고 생각한다.
이 시리즈는 Hexo
블로그를 Gitlab
페이지로 운영하면서 다양한 플러그인들을 테스트해 보고, 나름대로 설정하는 방법을 정리하는 것이다.
태그를 기반으로 관련 포스트들에 대한 링크 목록을 만들고, Google Analytics
의 페이지 뷰를 기준으로 인기 있는 (많은 페이지 뷰를 기록하는) 포스트들을 정렬된 링크 목록을 만드는 기능을 제공하는 플러그인이다.
또한 포스트의 내용에 따라서 관련된 포스트들에 대한 링크 목록을 생성할 수 있고, 다양한 Styles, Thumbnails 등을 지원하고, 다양한 부분에 사용자 정의가 가능하며, 성능과 관련해서 캐싱 기능도 포함하고 있다.
Notes
이 글에서는 _config.yml 파일에 설정을 다양하게 지정한다. 따라서 설정을 추가/변경하는 경우는 기존에 실행 중이던 Hexo Server를 재 실행해 줘야 하며 다음과 같이 처리하는 것을 권장한다.
[서버 재 실행 명령]
1
2
3 > hexo clean # 기존 캐시 및 Static content 삭제 (db.json)
> hexo g # 신규 Static content 생성 (/public)
> hexo server --draft # Draft 버전도 동일하게 서비스
이 플러그인은 다음과 같은 기능을 제공한다.
Notes
이 플러그인의 인기있는 게시글 및 페이지 뷰 처리는
Google Analytics
연계를 통해서 처리되며, 설정이 쉽지않고(?) 관련된 구글 계정이 구성되어 있어야 하므로 아래의 설정 부분을 검토하고 이 플러그인을 사용할지 여부를 결정하는 것이 좋다.
설치는 아래의 명령을 통해서 Hexo 블러그에 추가하면 된다.
1 | $ npm install hexo-related-popular-posts --save |
기본적인 적용 방법은 블로그에서 사용하는 테마 폴더에서 article.ejs
파일에 아래와 같은 내용을 추가하면 된다.
1 | <%- popular_posts () %> |
이제 Hexo 를 재 처리해서 결과를 확인해 보면 된다.
1 | $ hexo clean |
위의 처리는 해당 포스트 뷰에 태그 기준으로 연관된 다른 포스트에 대한 링크를 보여주는 것으로 실행되면 아래와 같이 생성된 결과를 볼 수 있다.
참고로 샘플에서는 article-footer
바로 위 부분에 삽입한 것이다.
여기까지는 외부의 정보 및 기타 설정 (_config.yml)이 없이 플러그인의 기본 기능을 사용하는 것이다. 따라서 어느 위치에 연관 목록을 만들지만 고민해서 적용하면 된다.
확장 기능은 다음과 같다.
확장 적용을 위해서는 아래와 같이 블로그 설정 파일 (블로그 루트에 있는 _config.yml) 에 설정을 추가해 줘야 한다.
1 | # More detailed settings |
Important
설정 항목이 모두 (optional) 처리가 되어 있다. 그러나 googleAnalyticsAPI 설정은 설정할꺼면 전부 올바른 값을 설정해야 한다. 그렇지 않으면 오류가 발생한다.
우선 각 기능에 대해서 확인을 먼저하고 나머지 설정에 대한 부분을 확인해 보도록 한다.
위에서 사용한 popular_posts()
에 추가 옵션을 설정하는 것으로 다음과 같은 옵션들을 지정할 수 있다.
option | description | default |
---|---|---|
maxCount | 목록으로 구성할 최대 포스트 수 | 5 |
ulClass | 목록에 사용할 CSS 클래스 명 | ‘popular-posts’ |
PPMixingRate | 목록에 인기 포스트와 연관 포스트의 구성 비율 | 0.0 (= 연관 포스트만 처리) |
isDate | 날짜 표시 여부 | false |
isImage | 이미지 표시 여부 | false |
isExcerpt | 발췌 표시 여부 | false |
PPCategoryFilter | 인기 포스트 목록에 카테고리 설정 옵션 | 미 정의 |
옵션 설정의 예제는 다음과 같다.
연관 포스트 목록에 5개를 표시하고 이미지를 구성하는 경우
1 | <%- popular_posts_json({ maxCount: 5 , ulClass: 'popular-posts' , PPMixingRate: 0.0 , isImage: true}) %> |
인기 포스트 목록에 10개를 생성하는 경우 (단, Google Analytics API 설정 필요)
1 | <%- popular_posts_json({ maxCount: 10 , ulClass: 'popular-posts' , PPMixingRate: 1.0 }) %> |
기타 옵션들은 직접 테스트를 해보는 것으로 하고, 화면에 표시되는 HTML 을 설정하고 싶은 경우는 아래의 Customize HTML 을 참고하면 된다.
여기는 Google Analytics 설정
의 페이지 뷰 데이터를 기준으로 동작하는 것이기 때문에 Google Analytics API 호출 설정이 필요하다.
Google Analytics 설정이 되었다는 전제하에 아래와 같은 정보를 블로그 루트 폴더에 있는 _config.yml
파일에 설정해 줘야 한다.
1 | popularPosts: |
Google Analytics 설정 페이지를 잘 확인해서 구성한 후에 필요한 정보를 위의 설정에서 바꿔주면 된다.
우선 아래와 같은 사항에 대해서 구성할 때 검토가 필요하다.
OAuth 2.0 클라이언트 ID
값을 의미한다.Service Account
를 구성하면 생성되는 서비스 계정 ID
를 의미한다. 작성자가 데이터가 이메일 포맷이라서 용어를 그렇게 사용한 것 같다. 이 것 때문에 엄청 헤맸다. -_-Service Account 관리
페이지에서 프로젝트를 선택하고 키를 생성해 줘야 한다. 이 부분에서도 json 과 p12 포맷이 존재하는데 json 을 이용하는 방식을 플러그인에서 제공하지 않으므로 반드시 p12
방식으로 선택해서 키를 생성하고 다운로드하도록 한다. 키 변환 명령은 아래에서 다시 설명한다.Account Expolorer
를 실행해서 표시되는 사이트 정보 밑에 Account 와 같이 표시되는 View
항목에 설정된 값을 사용하면 된다.원문에 Google Analytics 설정 관련 참고자료 가 있기는 하지만 나중에 별도의 포스트를 작성해야 할지도 모르겠다.
위의 _config.yml 파일에 설정한 정보 중에서 몇가지는 환경변수로 처리가 가능하기 때문에 아래와 같이 환경변수와 _config.yml 혼용으로 사용해도 된다.
1 | $ export GOOGLEAPI_CLIENTID="******.apps.googleusercontent.com" |
1 | popularPosts: |
기본적인 연관 포스트 목록은 태그 값을 기준으로 하지만, 내부의 링크나 포스트의 키워드들을 기준으로 형태소 분석(Morphological Analysis)
을 기준으로 설정할 수도 있다.
현재 지원되는 언어는 일어와 영어 딱 2개만 지원되고 있다. 개발자가 일본 사람인 듯하니 어쩔 수 없을 듯하며, 엄청 활성화되기 전에는 한글 지원은 요원해 보인다.
이를 사용하기 위해서는 _config.yml 에 관련 옵션을 설정해 줘야 한다.
1 | popularPosts: |
제외 키워드 설정 파일은 한 라인에 하나씩 정규식으로 설정할 수 있다.
1 | ^.$ |
한국어가 지원되지 않으므로 굳이 이 옵션을 사용할 이유가 없다. 그냥 태그만으로 구성해도 충분하다.
Note
예전에 Solr 검색엔진 관련해서 프로젝트를 수행할 때 한글 형태소 분석 엔진을 설정해서 사용한 적이 있다. 나중에 시간이 좀 되면 형태소 엔진을 Hexo 에 연결해서 활용할 수 있는지 검토해 볼 필요가 있을 듯 하다.
Hexo 에서 블로그 제너레이션을 할 때 성능 향상을 위해서 캐시 설정을 할 수 있다.
1 | popularPosts: |
캐시로 사용할 파일을 지정해 주면 된다.
로그 정보 표시 여부를 설정할 수 있다.
1 | popularPosts: |
직접 설정해 보면 기본으로 지정되는 HTML 이 단순 링크기 때문에 목록 리스트에 대한 HTML 변경을 할 수 밖에는 없으며 popular_posts_json()
헬퍼와 htmlGenerator
레지스터를 사용해야 한다.
<%- popular_posts() %>
문장을 아래 문장으로 대체하면 된다.1 | <%- |
1 | // Examples of helper |
위의 스크립트는 기본 제공되는 HTML 에 날짜, 이미지, 타이틀, 발췌 정보 등을 살짝 추가하는 정도기 떄문에 이 스크립트를 자신이 원하는 HTML 구성으로 모두 변경해 주면 된다.
Important
스크립트가 반영될 수 있도록 실행 중인 Hexo Server를 중지하고 Clean & Generate 를 해줘야 반영된다.
위의 샘플을 응용해서 관련 포스트는 포스트 본문의 위/아래에 배치하고, 인기 포스트는 사이드바의 가장 위에 위치하도록 적용하였다.
pvMeasurementsStartDate
옵션을 추가로 설정하면 포스트에 페이지 뷰 카운트를 설정할 수 있다. 이 부분도 역시 Google Analytics 설정
를 사용한다. 따라서 아래와 같이 기존에 설정해 놓은 부분에 추가해 주면 된다.
1 | popularPosts: |
1 | This post's Visitor Counts is <%- popular_posts_pv() %> views. |
위의 샘플을 응용해서 아래와 같이 포스트 타이틀과 작성일자 및 태그 정보 바로 아래에 위치하도록 조정했다.
rangkingSheet
옵션을 추가로 설정하면 페이지 뷰의 랭킹 정보를 생성할 수 있다.이 부분도 역시 Google Analytics 설정
를 사용한다. 따라서 아래와 같이 기존에 설정해 놓은 부분에 추가해 주면 된다.
1 | popularPosts: |
플러그인 원본 소스에 UTC 시간 처리 문제 소스를 아래와 같이 변경해야 한다.
1 | // 원본 코드 |
위의 원본에서는 moment에 ._i
값을 기준으로 처리했는데, 이 처리는 moment가 최초 생성되는 시점의 정보를 반영하는 문제가 있는 것으로 보인다. 결과적으로 모든 일자가 동일하게 호출 일자로 반환되는 문제가 생긴다.
따라서 시간을 제외한 일자 정보만 처리하는 경우는 수정된 코드를 사용해야 게시된 일자을 정확하게 표시할 수 있다.
정리해서 노출시킨 글들이 어떻게 읽혀지고, 누가 읽고 있었는지 등이 궁금해서 시작을 했지만, 상업적인 솔루션이나 회사 또는 물건을 광고하는 것이 아니기 때문에 솔직히 Google Analytics
의 모든 기능을 사용하는 것은 아니다.
단지, 글들에 대한 액세스등이 궁금해서 플러그인을 설정하기는 했지만, 아직도 필요성 대비 설정이 너무 많고 모르는 것이 넘치기 때문에 이렇게까지 설정해서 사용해야 하는지에 대한 의문점이 든다.
아마도 아직은 단순 무식해서 정말 그 효과를 몰라서 그럴지도… ㅠㅠ
References
]]>node-gyp
빌드 오류가 발생하는 경우Node 기반의 프로그램을 작성하면서 필요한 패키지들을 설정하고 npm install
명령으로 설치를 하다보면 패키지 설정에 의해서 설치 후 빌드 작업이 진행되는 경우가 있다. 이런 경우에 빌드 환경이 제대로 구성되지 않아서 오류가 발생하는 경우가 있어서 정리해 본다.
Warning 이 문서에서 모든 환경을 다루는 것이 아니고
msbuild 처리 환경에 대해서만 검토
한 내용이므로 다른 환경인 경우는 적용되지 않는다.
Node 기반에서 돌아가는 어플리케이션을 Github에서 다운로드 받아서 테스트를 위해서 npm install
명령을 했을 때 뜬금없이 msbuild
관련한 환경설정이 부족해서 오류가 발생했다.
Python 2.5 이상 3.0 이하 설치
해야 한다는 오류.NET Framework 2.0 이상을 설치
해야 한다는 오류VCBuil.exe 가 존재하지 않으니 .NET Framework 2.0 SDK 나 Visual Studio 2005를 설치
해야 한다는 오류상기의 상태에서 더 이상 진행 불가!!! 물론 전부를 설치하면 되겠지만 그렇다고 쓰지도 않는 툴들을 설치하는 것은 문제가 있어 보인다.
오류의 원인은 간단하다. 해당 어플리케이션 패키지에 정의된 의존성 패키지들 중에 설치과정에서 빌드를 거쳐야 하는 것이 존재하며 Python 으로 구현된 것들과 VC 로 구현된 것을 MSBuild를 이용해서 처리하기 때문이다.
일반적으로 Node 기반의 개발에서는 VSCode 나 Atom 등의 도구와 NodeJS, Git 등의 툴들만 사용하기 때문에 관련된 다른 언어나 IDE 환경이 존재하지 않기 때문이다.
가장 쉬운 방법은 모든 언어와 IDE 개발 환경을 맞춰주면 전혀 문제가 없겠지만, 쓰지도 않는 환경을 단지 설치 상의 빌드 때문에 설치하고 지우는 것도 웃기다.
역시 구글링을 하다보니 이런 문제로 시달리는(?) 사람들이 많은 것 같다. 대부분은 아래와 같이 권장하고 있다.
Case 1: Python 설치 및 Visual Studio 2010 이하 환경
위에서 언급한 오류는 발생하지 않는다. 다만 다른 오류가 있다면 해결하면 되는 상황이다.
Case 2: Python 설치 및 Visual Studio 2012 이상 환경
Visual Studio 2010 부터 환경부분이 변경된 것이 있어서 Visual Studio 버전 관련 오류가 발생하므로 다음과 같이 버전을 변경해서 처리해 주어야 한다.
1 | $ npm install <target_module> --msvs_version=2012 |
msvs_version
은 현재 설치되어 있는 버전을 지정하면 된다.
만일 전체적인 npm 에 설정을 적용해 놓고 싶은 경우는 아래의 명령을 이용하면 된다.
1 | $ npm config set msvs_version 2013 --g |
Case 3: Python 및 기타 VS 환경이 없는 경우
이런 상황을 위해서 필요한 툴들과 환경을 처리해 주는 패키지가 제공되고 있으므로 아래와 같이 처리하면 된다.
1 | $ npm install -g windows-build-tools |
Notes 단, 이 방법은
Powhershell 또는 cmd 를 관리자 모드로 실행
해 주어야 한다.
위에 정리된 내용은 경험을 기준으로 작성한 것이므로 다른 상황이라면 관련된 정보를 더 찾아서 해결해야 한다.
]]>‘이전 게시글’ 에서 diskpart
를 이용한 작업 스케줄러 처리로 부트 시점에 자동 마운트 처리를 정리 했었다.
막상 실제 사용하는데 몇 가지 불만 사항이 생겨서 스크립트를 사용하는 방식으로 변경해 본다.
위의 같은 이유로 아래와 같이 스크립트 처리를 추가했다. 기본은 diskpart를 이용하는 방식이다.
윈도우에서 스크립트를 처리할 때는 항상 관리자 권한 여부가 상당히 껄끄럽다. 이런 저런 방법들도 많다. 대략적으로는 아마 아래와 같은 형식들이 될 듯 하다.
그런데 이런 저런 시스템 설정을 하기는 싫고 순수하게 스크립트에서만 이를 해결할 수는 없을까?
이런 저런 자료를 검토하고 나름대로 관리자 모드로 실행 부분을 생각해 보니 의외로 쉽게 할 수 있는 방법이 있다. 그것도 시스템을 건들이지 않고 스크립트 만으로 조정해서 가능하다.
1 | @echo 관리자 권한 검증 >%windir%\admin.confirm |
위의 명령은 %windir%
(보통 C:\Windows) 경로에 “관리자 권한 검증” 이란 문자열을 출력해서 admin.confirm 이라는 파일을 생성하는 것이다. 당연히 관리자 권한이 없으면 액세스가 거부되었습니다.
라는 오류 메시지를 보게 된다.
이를 이용해서 아래와 같이 관리자 권한을 탈취(?)하는 코드를 생성하면 된다.
1 | @echo 관리자 권한 검증 >%windir%\admin.confirm || @( |
위의 명령은 관리자 권한이 없는 경우에 %temp%
(보통 C:\Users<user>\appdata\local\temp) 에 admin.vbs 라는 파일을 만들고 아래와 같이 UAC 객체를 얻어서 실행하는 명령을 구성해서 wscript.exe
로 관리자 권한으로 실행하도록 하는 것이다.
1 | Set UAC = CreateObject("Shell.Application") |
따라서 관리자 권한을 탈취(?)하고 다시 실행되는 경우에 테스트를 위해서 만들었던 파일들을 삭제하고 나머지를 계속 수행하면 된다.
아래는 실제 작업을 진행한 코드를 보여주는 것이다. (multi_vhd_mount.bat)
1 | @echo off |
당연한 말이지만 위의 call mount_vhd %%b %%a
를 call unmount_vhd %%b
로 하면 해제 처리 가능하다.
이제 관리자 권한을 탈취해서 실행되는 스크립트를 만들었으니 내부에서 호출되는 스크립트들을 확인해 보도록 하자.
아래 스크립트는 VHD 를 diskpart 명령을 사용해서 처리하는 스크립트다. 중간 중간에 테스트를 위해 사용한 echo 명령은 제거해도 된다. 물론 diskpart 스크립트 파일 생성을 위한 부분은 남겨둬야 한다.
1 | @echo off |
아래 스크립트는 마운트해서 사용한 VHD 를 연결 해제하는 스크립트다.
1 | @echo off |
수동으로 실행을 해도 되지만, 작업 스케줄러를 이용해도 되고, 아래에서 확인해 볼 것처럼 시작 프로그램으로 등록해 놓고 사용해도 된다.
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup
위의 폴더 중에서 원하는 위치에 작성한 스크립트를 복사해 놓으면 된다. (단, 내부에서 사용한 다른 호출 스크립트 경로를 조정해 줘야 한다)
레지스트리 편집기 (regedit)
를 열고 아래의 키 들 중에 원하는 위치로 이동한다.
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
해당 키 하위로 새로운 문자열 키
를 생성하고 이름은 원하는데로 설정하고, 데이터는 실행할 배치 파일을 전체 경로를 설정하면 된다.
Notes
배치는 잠시지만 명령 창이 나타났다 사라진다. 차라리 길게 보이면 그럭저럭 넘길텐데, 후다닥 지나가면 뭔가 오류가 발생한 느낌이 나기 때문에 심하게 싫다.
이런 경우라면 아래와 같이 VBS 처리를 해주면 보이지 않게 된다. 아래 코드에서
<실행할 Command 파일>
를 위에서 만든 스크립트 파일 전체 경로로 바꿔야 한다.
1
2
3 Set WinScriptHost = CreateObject( "WScript.shell" )
WinScriptHost.Run Chr(34) & <실행할 Command 파일> & Chr(34), 0
Set WinScriptHost = Nothing
위와 같이 처리를 해서 이 VBS 파일을 위에 자동 실행 등록으로 처리하면 정신적으로 위로(?)가 된다.
역시 뭔가 자꾸 바꾸고 테스트하는 것은 스크립트를 활용하는 것이 좋다. 물론 한번 설정하고 안 바꿀 거라면 작업 스케줄러도 나쁘지는 않다. 단, 적응이 안되니 그냥 뭔가 귀찮고 싫을 뿐이다.
::: warning 배치 파일, VHD 관련 정보는 고수님들이 친절하게 설명한 글이 무수하게 많으니 꼭 찾아서 읽어보는 것이 좋다. :::
]]>데이터 백업과 관리는 항상 중요하다. 프로젝트의 경우는 더욱 더 중요하다. 소스관리는 Git 등을 이용해서 관리를 하면 되지만, Open source 검토나 개인적인 문서 등의 자료는 딱히 편한 방법을 찾지 못해서 Sync 툴들을 사용하던 방법을 VHD 파일 단위로 구별해서 관리하고 주기적으로 VHD 파일을 백업하는 방법을 적용해 보려하니 매 부팅마다 마운트해 주는 것이 또 답답하다.
이런 저런 관런 자료를 찾다보니 괜찮은 (쉬운?) 방법이 있어서 정리해 놓도록 한다.
Diskpart 스크립트 파일
을 생성한다.부트 타임 스케줄
을 구성한다.로그인과 상관없이
실행 선택프로그램 시작
으로 설정작업 지연 시간 1분
으로 설정diskaprt
설정/s 스크립트 파일
지정AC 전원이 켜져있는 경우만 작업 시작 옵션
해제diskpart에 옵션으로 지정할 스크립트 파일이므로 확장자는 상관없이 지정해도 된다.
1 | select vdisk file="C:\test.vhd" |
위의 스크립트를 저장한다. 이 샘플에서는 S:\VMs\Scripts\AutoMount.txt
이름으로 저장했다.
윈도우키 + R
을 눌러서 작업 스케줄러
를 실행한다. (윈도우 10 이라면 Windows 검색 창에서 작업
으로 검색 가능)
작업 스케줄러에서 아래와 같이 작업 만들기
를 실행해서 기본 정보를 설정한다.
트리거 탭으로 이동해서 작업 시간 설정을 한다.
작업 탭으로 이동해서 실제 구동될 프로그램 (diskpart) 과 위에서 저장했던 스크립트 파일을 지정한다.
조건 탭으로 이동해서 기본 설정되어 있는 AC 전원 관련 옵션을 해제한다.
마지막으로 “확인” 버튼을 누르면 사용자 계정 확인을 하게 되므로 정보를 입력한다.
이제 부팅 시점에 VHD 를 마운트하는 작업이 등록되었으므로 실제 부팅을 통해서 작업이 잘 처리되는지를 확인하면 된다.
Notes
단, 만일 보안 상의 이유로
Bitlocker
가 걸려 있거나 또는 디스크가 ___압축 설정
___이 되어 있는 경우는 VHD 를 마운트할 수 없으므로 관련된 상황을 확인해야 한다.
References
Notes
이 문서는 Ubuntu 에 Kubernetes 를 설치할 때 특정 버전의 바이너리를 지정해서 처리하는 방법을 설명하는 것이기 때문에 전체 설치 과정을 다루고 있지 않습니다.
설치에 관련된 문서는 iamartin
님 블로그에 kubeadm을 이용해서 아주 쉽게 Kubernetes 설치하기 에 상세하게 기술되어 있으므로 이 부분을 참고하시면 됩니다. (향후 변경된 사항이나 요청이 있다면 정리된 버전을 추가로 올릴 수도 있습니다)
참고로 Kubernetes 를 설치하는 도구들은 상당히 많이 존재하며 향후 kubeadm
으로 통합될 것으로 개인적인 예상을 하고 있기 때문에 다른 설치 도구에 대한 부분은 따로 정리하지 않고 있습니다.
이 문서를 정리한 이유는 Kubernetes가 버전 향상 작업을 수시로 진행하고 있고, 각 종 설치 도구는 latest 버전
을 대상으로 운영되고 있기 때문에 솔루션 개발 중이거나 또는 다른 이유로 버전을 고정해야 할 경우가 있을 수 있기 때문입니다.
ubuntu 에서 설치는 초기에 아래와 같이 4 단계의 작업을 거치게 됩니다. 물론 kubeadm
을 사용하는 경우는 다른 환경에서도 거의 유사하게 사용됩니다.
STEP 1. Apt Key 생성
1 | $ curl http://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - |
STEP 2. Kubernetes Source Repository 생성 (데비안 패키지)
1 | cat <<EOF > /etc/apt/sources.list.d/kubernetes.list |
STEP 3. Apt Repository 갱신
1 | apt-get update |
STEP 4. 필수 프로그램 설치
1 | apt-get install -y docker.io |
위의 단계를 거치고 나면 Kubernetes 설치에 필요한 기본 패키지들이 준비된 것입니다.
Notes
다운로드한 바이너리들에 대한 특정 버전을 지정하는 방법은 아래의 예와 같이 각 Component 별로 버전 식별 정보를 지정하면 됩니다.
1 $ sudo apt-get -y install kubectl=1.5.3-00 kubelet=1.5.3-00 kubernetes-cni=0.3.0.1-07a8a2-00
재미있는 부분은 위의 설치 2번째 작업에서 처리한 데비안 패키지의 내용을 아래의 경로에서 확인을 해 보면 최근에 릴리즈된 정보가 다 구성되어 있다는 것으로 위의 소스 리파지토리 설정 정보를 이용해서 아래와 같은 URL 로 패키지 정보 검증이 가능합니다.
Notes 지금까지 발표된 모든 Release가 아니고 최근에 발표된 버전이 기준입니다. 따라서 1.5 이전 버전을 사용해야 하는 상황이라면 이 문서에 정리된 내용은 맞지 않습니다.
1 | $ https://packages.cloud.google.com/apt/dists/kubernetes-xenial/main/binary-amd64/Packages |
아래의 그림은 위의 경로에서 확인한 패키지 정보를 일부 발췌한 내용입니다.
위의 그림에서 박스로 표시한 것처럼 kubelet
이 1.5.1 ~ 1.6.1 까지 구성 (위의 빨간 박스) 되어 있는 것을 볼 수 있으며, 각 구성 요소에 의존적인 다른 패키지의 버전과 관련된 Depends (위의 파란 박스) 정보가 구성된 것을 볼 수 있습니다.
따라서 처음에는 특정 릴리즈 버전의 정보만을 가져오는 것에 대해 검토를 했지만, 위의 정보를 확인하고 나서는 다운로드된 바이너리들을 어떻게 버전을 지정해서 처리하는지에 대한 것만 결정하고 설정하면 됩니다.
Kubernetes Master Node 의 초기화는 아래와 같은 명령을 기본으로 사용합니다.
1 | kubeadm init |
위의 초기화 명령에 사용할 수 있는 다양한 옵션들 중에 Kuberenetes 의 바이너리 구성 버전을 지정할 수 있습니다.
--kubernetes-version
: 기본 값은 lastest
로 설정되어 있으며 원하는 Kubernetes 버전을 지정하면 됩니다. 단, 이때 지정할 버전은 릴리즈 페이지 를 참고하면 됩니다.위의 Kubernetes 패키지 (xenial main) 에는 kubeadm 1.6.1 만 존재
하기 때문에 Kubernetes 1.6 버전만 처리가 가능합니다. 정확하게는 Depends 로 kubelet >= 1.6.0, kubectl >= 1.6.0 제한이 걸려 있기 때문에 1.6.0 또는 1.6.1 로만 구성이 가능합니다.
따라서 현재 상황에서 1.5.1 ~ 1.5.6 까지의 Kubernetes 버전을 구성할 수 없는 상태입니다.
위에서 Kubernetes의 버전 문제라기 보다는 Kubeadm 버전 문제 떄문에 Kubernetes 1.6.0 이전 설정이 안되는 문제를 확인했기 때문에 이번에는 Kubeadm 의 버전을 처리하는 방법으로 설정해야 합니다.
Notes
Kubernetest 1.6.0 을 설정하는 경우는 이 부분을 처리하지 않아도 처리가 가능합니다. Kubernetes 버전 지정으로 진행하시면 됩니다.
아래의 스크립트는 현재 버전 1.6.1 기준으로 특정한 버전 (ex. 1.5.3) 을 설정하기 위해서 kubeadm 을 재 설정하는 것입니다.
1 | $ apt-get update && apt-get install -y apt-transport-https |
위의 같이 기본적인 설정 및 바이너리 다운로드는 동일하지만 kubeadm 을 이전 버전으로 다운로드하여 설정하고 버전을 고정하는 방식으로 처리하면 됩니다.
Important
현재 프로젝트를 마무리하고 나온 상태라서 위의 정리된 내용을 실제 검증한 것은 아니기 때문에 다소 내용과 실제가 맞지 않을 수 있습니다. 따라서 환경이 구성된 후에 위의 정리된 내용과 다른 부분은 갱신을 할 예정입니다.
References
그 동안 여러 가지 블로그를 구성했었지만 맘에는 안들고, 지나 오면서 이런 저런 것들을 할 때마다 기록을 남기면 누군가에게는 도움이 될 것이라는 생각으로 정리를 하기는 하지만 블로그에 올려 놓으면 보이는 것이 맘에 들지도 않고, 그렇다고 맘대로 바꿀 수도 없고…
결국은 다음과 같은 기준으로 정리를 하게 되었다.
위의 같은 기준으로 Gitlab Pages 에 SSG (Static Site Generator) 인 Hexo 를 사용하는 것으로 최종 결정을 했다. 이젠 좀 그만 바꾸고 정착을 했으면 싶다.
SSG 프로그램은 정말 다양하게 많다. 그 중에서도 Hexo 를 선택한 이유는 node.js 기반이고, 다양한 Plugin 들이 존재하고, 속도가 빠르다는 주관적인 판단에 의해서다.
블로그를 구성하면서 자료들을 찾아보니 GitHub Pages + Hexo 에 대한 것들만 있고 GitLab 을 사용한 경우는 많이 없어서 이것도 경험이니 혹시 나와 같은 경험을 하게 될 사람이 있다면 도움이 될 수 있도록 하나씩 정리를 하도록 할 예정이다.
전혀 궁금해 할 사람은 없겠지만 난 단순 무식한 개발자이며, 이미 시장에서 퇴출의 시간을 한참 넘어버린 노땅 개발자다.
단지 개발이 좋고, 궁금한 것이 너무 많다
는 이유 때문에 아직도 버티고는 있지만, 이제는 새로운 것에 도전하기에도 체력과 지식이 너무 많이 딸린다. 아니 어쩌면 젊었을 시절에 있었던 무대포 정신이 사라진 것일지도 모르겠다.
하지만, 개발과 관련된 일을 계속 하고 있고, 앞으로 할 예정이며, 이와 관련된 정보들을 기록으로 남길 것이다.
일단 시작은 아래와 같은 내용을 정리해 볼 예정이다.
블로그의 정체성은 개발하면서 필요한 것들과 경험한 것들을 다양하게 정리하는 개발 정보 사이트가 되는 것이다.
수 많은 개발의 시간을 보냈지만 딱히 내가 이 부분에서는 제일이다
를 내세울 수 없는 삶을 살았다는 것이 바보같이 느껴지지만 지난 것들에 매달려 있는 것은 더 싫기 때문에 블로그를 통해서라도 재미난 것들을 해 보고 싶다. 그리고 그 과정을 누군가에게는 도움이 될 수 있도록 하고 싶은 희망을 가지고 오늘도 열심히 보내고 있다.