728x90

인증서를 다루다보면 가장 많이 사용하는 것이 OpenSSL 입니다. OpenSSL 의 명령들중 자주 사용하는 것들을 기억해두면 생활이 편리해지고 퇴근시간이 빨라지는 장점이 있습니다. 서버나 로컬 터미널 환경에 미리 alias 로 몇 가지 등록해 두면 두고두고 편리하게 사용할 수 있는 명령들을 몇 가지 정리해 보았습니다. 


로컬 환경의 RSA 인증서의 Private Key 확인하기

$ openssl rsa -in private_key_file.key -check
RSA key ok
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
...

 

로컬 환경의 X509 인증서 (보통 SSL 인증서라 부르죠) 내용 확인하기

$ openssl x509 -in certificate_file.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            11:22:33:aa:44:bb:55:66:77:88:99:cc
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=BE, O=GlobalSign nv-sa, CN=GlobalSign RSA OV SSL CA 2018
        Validity
            Not Before: Apr 22 03:16:05 2021 GMT
            Not After : May 23 03:16:05 2022 GMT
        Subject: C=KR, ST=Seoul-si, L=Kangseo-gu, O=NoPD Corp, CN=*.nopd.me
        ...

 

원격지 환경의 인증서 Trust Chain 확인하기

$ openssl s_client -showcerts -connect www.naver.com:443
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
verify return:1
depth=0 C = KR, ST = Gyeonggi-do, L = Seongnam-si, O = NAVER Corp., CN = *.www.naver.com
verify return:1
---
Certificate chain
 0 s:/C=KR/ST=Gyeonggi-do/L=Seongnam-si/O=NAVER Corp./CN=*.www.naver.com
   i:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
-----BEGIN CERTIFICATE-----
...

 

 

원격지 환경의 X509 인증서 상세 내용 확인하기

$ openssl s_client -connect www.naver.com:443 | openssl x509 -noout -text
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
verify return:1
depth=0 C = KR, ST = Gyeonggi-do, L = Seongnam-si, O = NAVER Corp., CN = *.www.naver.com
verify return:1
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            05:75:b5:1c:cb:25:fc:9c:ef:cb:6e:63:fe:1a:45:29
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=DigiCert Inc, CN=DigiCert SHA2 Secure Server CA
        Validity
            Not Before: May 30 00:00:00 2020 GMT
            Not After : Jun  8 12:00:00 2022 GMT
        Subject: C=KR, ST=Gyeonggi-do, L=Seongnam-si, O=NAVER Corp., CN=*.www.naver.com
        ...
        

 

 

 

728x90
728x90

새로운 개발환경은 늘 어색합니다. 플러터(Flutter)를 안드로이드 스튜디오 환경에서 다시 공부하기 시작하면서 매일매일 새로운 느낌으로 시행착오를 겪고 있습니다. Mac 운영체제의 Big Sir의 업데이트 때문에 설치후 재기동을 하고 난 뒤 안드로이드 스튜디오에서 겪은 문제에 대한 이야기입니다.

운영체제 업데이트전까지 아무런 문제 없이 안드로이드 스튜디오에서 플러터로 코드를 만들고 안드로이드 시뮬레이터를 이용해 디버깅을 하고 있었습니다. 그런데 업데이트 설치후에 갑자기 안드로이드 스튜디오가 시뮬레이터에서 앱을 실행하지 못하고 에러를 토하는 현상을 맞딱들였습니다. 

집나간 시뮬레이터들... 아빠가 잘못했다, 어서 돌라오렴!

안드로이드 스튜디오를 여러번 재기동해도 시뮬레이터의 목록이 보이지 않았습니다. 안드로이드 스튜디오에서 코드를 실행하면 시뮬레이터가 기동은 되었지만 (왜지...) 디버거가 연결이 안되고 앱이 배포되지 않았습니다. 안드로이드 시뮬레이터를 관리하는 AVD Manager 를 이용해 만들어 둔 이미지를 개별적으로 실행하면 <Unable to locate adb>라는 에러 메세지가 출력되었습니다. 

 

AVD Manager 의 에러 : Unable to locate adb

 

구글에서 검색을 해보니 이 현상이 일어나는 원인중 대표적인 것이 안드로이드 디버거인 adb 의 경로가 제대로 설정되지 않아 실행되지 않는 경우라는 이야기가 많았습니다. 안타깝게도 제 경우에는 터미널에서 adb 가 아주아주 원활히 잘 실행되고 있었기 때문에 환경변수에서 path 설정이 잘못된 것으로는 생각되지 않았습니다. 

SDK 설정을 보려면 File > Project Structure 메뉴를 사용합니다.

 

그러던 중 <Project Structure> 에서 SDK 설정이 제대로 되지 않았거나 삭제된 경우 (아마도 업데이트의 여파?) 비슷한 문제를 겪었다는 글을 발견할 수 있었습니다. 밑져야 본전, 정말로 SDK 설정이 <갑자기> 사라진 것인지 확인해 보기로 했습니다. 설마 안드로이스 스튜디오가 그런 일을 저질렀겠냐는 생각을 하던 바로 그 순간...

헐... No SDK 라니...

 

저는 제 눈을 의심해야 했습니다. Project 의 SDK가 <No SDK>를 가리키고 있었습니다. 누가 이런 짓을 한 걸까요? 그건 아무도 모릅니다. 며느리도 모릅니다. 다만, SDK 설정이 사라졌다는 사실이 중요한 것이고 이것을 바로 잡아 문제가 해소되는지 확인해야 했습니다. 

 

드롭다운 리스트를 열고 로컬 환경에 설치된 안드로이드 SDK중 28버전의 API 를 다시 선택했습니다. 그리고 창을 닫고 기도를 했습니다. 집나간 시뮬레이터가 어서 돌아오게 해주세요. 모든걸 용서하겠다고...

집에 돌아온 시뮬레이터

 

오오오오.. 아무 것도 없던 디바이스 선택 드롭다운 리스트에 만들어둔 시뮬레이터가 똬악하고 보였습니다. 프로젝트를 실행해보니 디버거 연결도 잘 되고 앱도 정상적으로 배포되는 것을 확인할 수 있었습니다. 왜 이런일이 일어난 것인지는 알아낼 수 없었지만 유사한 현상이 발생헀을 때, 이제 당황하지 않고 문제를 처리할 수 있을 것 같은 자신감이 샘솟았습니다. :-)

728x90
728x90

안드로이드 스튜디오의 셋업이 끝났으니 이제 플러터 프로젝트를 만들고 자동 생성되는 기본 구조를 살펴보겠습니다. 프로젝트가 생성되면 조금 복잡해 보이는 디렉토리 구조와 프로젝트에 필요한 기본 파일들이 생성됩니다. 

 

안드로이드와 iOS를 모두 지원하는 앱을 만들어야 하기 때문에 android, ios 이름을 갖고 있는 폴더가 먼저 눈에 띕니다. 우리가 직접 코드를 만들어 지지고 볶는 곳은 main.dart 파일이 포함된 lib 디렉토리라고 합니다. 그럼 main.dart 를 한 번 열어보겠습니다. 보물상자를 여는 기분으로다...

 

복잡해 보이는 main.dart 파일이지만 코드 블럭을 접어서 보면 크게 위의 다섯가지 부분 정도로 나뉩니다. 모듈이나 라이브러리를 불러오기 위해 사용하는 import 가 가장 먼저 눈에 띕니다. 그리고 자바나 C, C# 등에서 익숙하게 봤을 main() 함수가 어플리케이션의 진입점이 된다는 것을 눈치챌 수 있었습니다.

main() 에 자동 생성된 코드가 거의 없을 거라는 것을 예상하셨겠지만, 정말로 들어 있는 내용이 없습니다 ^^;; main() 함수는 7번 행부터 정의하고 있는 실제 플러터 어플리케이션의 시작이라 할 수 있는 <위젯>을 호출하는 역할만 수행하고 있습니다. 샘플 프로젝트에는 MyApp 이라는 클래스가 StatelessWidget 을 상속받아 생성되고 있습니다. 

 

<위젯>은 플러터에서 UI의 컴포넌트나 화면 단위를 만드는 단위입니다. 오래된 사람인 저는 컨트롤이라는 용어가 익숙합니다만 이제 <위젯>이라는 단어에 스스로를 맞춰보도록 하겠습니다 ^^;; 

 

위젯은 크게 상태 값이 보존되는 위젯과 상태 값이 보존되지 않는 위젯으로 나뉜다고 합니다. MyApp 과 MyHomePage 클래스가 상속 받고 있는 StatelessWidget 과 StatefulWidget 이 정의하고 있는 위젯 클래스의 목적을 나타내주고 있습니다. 자세한건 저도 아직 잘 몰라서 천천히 좋은 감정으로 알아가 보도록 하겠습니다. ㅋ

 

샘플 프로젝트를 생성했을 때 이 프로젝트는 완전히 빈 깡통 프로젝트는 아닙니다. 간단하게 StatelessWidget과 StatefulWidget의 차이를 알아볼 수 있는 카운트 앱이 샘플 프로젝트에 담겨 있습니다. MyApp 과 MyHomePage 클래스에 들어 있는 코드를 자세히 볼까요?

 

최초 샘플 프로젝트 생성시에는 엄청난 양의 주석이 같이 있습니다. 주석을 모두 제거하면 두 클래스의 코드는 몇 줄 되지 않습니다. MyApp 클래스는 어플리케이션의 윤곽을 나타내기 위한 위젯을 리턴하는 코드가 전부입니다. 코드 내에서 다시 MyHomePage 클래스를 사용하여 `Flutter Demo Home Page`라는 타이틀을 가진 StatefulWidget 을 만들고 있습니다.

MyHomePage 위젯도 코드가 무척 단순합니다. 클래스의 인스턴스가 만들어 질 때 매개변수로 타이틀을 받아서 멤버 변수에 저장하고 _MyHomePageState 클래스 형식으로 createState() 함수를 호출해 위젯의 상태를 저장할 객체를 생성하게 됩니다. 

 

마지막으로 _MyHomePageState 클래스입니다. 주석이 많이 생기기 때문에 주석을 삭제하면 내용을 한 눈에 알아보기 더 쉽습니다. 물론 주석에 자세한 설명들이 있기 때문에 공부하는 동안에는 한 번 읽어보는 것도 도움이 될 것 같긴합니다. 

멤버 변수로 _counter 를 갖고 있으며 앱이 수행되는 동안 카운터 된 숫자를 기억하기 위해 사용하는 변수입니다. 앱을 실행하면 더하기 floatingActionButton 이 하나 화면에 나오고, 버튼을 누를때마다 _counter 의 값을 1씩 증가시킵니다. 내장 함수인 _incrementCounter() 에 증감연산자를 사용해 _conuter++ 를 실행하는 코드가 보입니다. 

이처럼 플러터는 값의 저장, 보존이 필요한 경우 StatefulWidget 과 State 를 사용하고 그렇지 않은 경우 StatelessWidget 을 사용한다는 점을 기억하고 익숙해져야 할 것 같네요!


 

 

플러터(Flutter), 안드로이드 스튜디오로 개발환경 만들기

플러터 개발환경을 안드로이드 스튜디오에 구성해 보도록 하겠습니다. 기억하실지 모르겠지만 비주얼 스튜디오 코드 Visual Studio Code 에 환경을 구성하는 법을 잠깐 소개드렸었죠? 어쩌다보니 그

ondemand.tistory.com

 

플러터(Flutter), 샘플앱 실행으로 개발환경 문제점을 파악해보자

지난 포스팅에서 안드로이드 스튜디오를 업데이트하고 플러터 플러그인을 설치해보았습니다. 추가된 플러그인을 통해 샘플 프로젝트를 만들고 실행을 해보았지만 예상대로 문제가 발생했고,

ondemand.tistory.com

 

728x90
728x90

지난 포스팅에서 안드로이드 스튜디오를 업데이트하고 플러터 플러그인을 설치해보았습니다. 추가된 플러그인을 통해 샘플 프로젝트를 만들고 실행을 해보았지만 예상대로 문제가 발생했고, 안드로이드 가상 장치에서 시험을 해볼 수 없었습니다. 무슨 문제가 있었던 것일까요?

 

안드로이드 스튜디오에서 플러터 프로젝트를 생성하고 기본 샘플 앱을 가상 안드로이드 기기로 실행했을때 발생한 에러 화면입니다. 뭔가 SDK와 관련된 라이센스가 제대로 적용이 안된 것 같은 에러메세지입니다. 바로 터미널을 실행하여 플러터 닥터 flutter docter 명령을 통해 문제점을 확인해 보았습니다. 명령은 터미널에서 flutter docter 를 입력하여 수행합니다. 

 

초록색 체크표시가 된 것들은 문제가 없는 부분들입니다. 느낌표로 출력된 내용을 보니 비주얼 스튜디오 코드를 위한 플러터 환경 구성 이후 변경된 것들이 좀 있어 보입니다. 가장먼저 Android toolchain 항목에 대한 명령을 통해 첫번째 문제를 해결해 보겠습니다. 

flutter doctor --android-licenses

 

위의 플러터 닥터 명령은 동의해야 하는 약관, 라이센스에 대한 확인을 해주는 명령입니다. 실행후 나오는 내용을 살펴보고 (영어입니다 -_-;) 동의한다는 의미로 y 키를 몇 번 눌러주면 됩니다. 다시 닥터를 실행해서 처리가 잘 되었는지 보겠습니다. 

오호라. 첫번째 Android toolchain 항목도 이제 초록색 체크로 바뀌었습니다. 플러터로 개발된 코드를 iOS 에서 실행할 수 있도록 하기 위해서는 Xcode 환경도 준비가 되어 있어야 합니다. 지난번에도 CocoaPods 설치하느라 고생했는데... 그래도 다시 한 번 해보았습니다. 

#  sudo gem install cocoapods
Password:
Fetching i18n-1.8.9.gem
Fetching tzinfo-1.2.9.gem
Fetching activesupport-5.2.4.5.gem
Fetching nap-1.1.0.gem
Fetching fuzzy_match-2.0.4.gem
Fetching concurrent-ruby-1.1.8.gem
...
...
Parsing documentation for gh_inspector-1.1.3
Installing ri documentation for gh_inspector-1.1.3
Parsing documentation for ruby-macho-1.4.0
Installing ri documentation for ruby-macho-1.4.0
Parsing documentation for cocoapods-1.10.1
Installing ri documentation for cocoapods-1.10.1
Done installing documentation for concurrent-ruby, i18n, thread_safe, tzinfo, activesupport, nap, fuzzy_match, httpclient, algoliasearch, ffi, ethon, typhoeus, netrc, public_suffix, addressable, cocoapods-core, claide, cocoapods-deintegrate, cocoapods-downloader, cocoapods-plugins, cocoapods-search, cocoapods-trunk, cocoapods-try, molinillo, atomos, CFPropertyList, colored2, nanaimo, xcodeproj, escape, fourflusher, gh_inspector, ruby-macho, cocoapods after 25 seconds
34 gems installed

 

자, 코코아포드 관련한 패키지들의 추가도 끝났으니 다시 flutter docter 를 실행해 봐야겠죠?

 

에러 메세지가 확~ 사라졌습니다. 이제 마지막으로 남은 것은 안드로이드 스튜디오에서 플러그인을 설치하는 일입니다. 에..? 플러그인? 분명히 설치했다고 생각했는데... 무슨 문제일까요? 일단 에러 메세지를 무시하고 코드를 안드로이드 에뮬레이터에서 실행해 보겠습니다. 희안하게도 문제 없이 실행이 됩니다. 

 

어렵지 않죠? 네, 저는 어렵습니다 ㅎㅎ. 일단 동작이 잘 되는 것을 확인했으니, 본격적으로 뭔가를 만들어 봐야겠습니다!

728x90
728x90

아따 많이도 업데이트한다...

 

어제는 간만에 Flutter로 코드 만들어 보느라 고생했고 오늘은 또 간만에 파이썬으로 코드 만드느라 고생중입니다. 그 사이에 무슨 일이 있었던 것인가... (빅써 없데이트!?) 갑작스레 새 코드 프로젝트를 만들기 위해 virtualenv 를 돌리는데 Library not loaded 에러가 발생합니다. 자연스레 pip 로 virtualenv 를 업데이트 해볼랬더니.. 어라? pip도 동작을 안합니다. 

% virtualenv
dyld: Library not loaded: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
  Referenced from: /Library/Frameworks/Python.framework/Versions/3.6/Resources/Python.app/Contents/MacOS/Python
  Reason: image not found
zsh: abort      virtualenv
% pip
dyld: Library not loaded: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
  Referenced from: /Library/Frameworks/Python.framework/Versions/3.6/Resources/Python.app/Contents/MacOS/Python
  Reason: image not found
zsh: abort      pip

 

뭔가 운영체제 업데이트가 되면서 symlink가 꼬인 느낌이라 과감히 brew 로 파이썬을 재설치 해보기로 했습니다. 의존성이 걸려있는 패키지가 너무 많은 탓인지 업데이트가 한참 걸리네요. 열심히 다운로드 받고 설치하는 동안 저의 맥북프로는 또 다시 이륙을 하고는 고도를 높여 나갑니다...

% brew install python
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 3 taps (homebrew/core, homebrew/cask and homebrew/services).
...
...
==> Installing python@3.9
==> Pouring python@3.9-3.9.2_1.big_sur.bottle.tar.gz
Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink bin/2to3
Target /usr/local/bin/2to3
already exists. You may want to remove it:
  rm '/usr/local/bin/2to3'

To force the link and overwrite all conflicting files:
  brew link --overwrite python@3.9

To list all files that would be deleted:
  brew link --overwrite --dry-run python@3.9

Possible conflicting files are:
/usr/local/bin/2to3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/2to3
/usr/local/bin/easy_install-3.9 -> /usr/local/Cellar/python@3.9/3.9.0_2/bin/easy_install-3.9
/usr/local/bin/idle3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/idle3
/usr/local/bin/pip3 -> /usr/local/Cellar/python@3.9/3.9.0_2/bin/pip3
/usr/local/bin/pip3.9 -> /usr/local/Cellar/python@3.9/3.9.0_2/bin/pip3.9
/usr/local/bin/pydoc3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/pydoc3
/usr/local/bin/python3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/python3
/usr/local/bin/python3-config -> /Library/Frameworks/Python.framework/Versions/3.6/bin/python3-config
==> /usr/local/Cellar/python@3.9/3.9.2_1/bin/python3 -m ensurepip
==> /usr/local/Cellar/python@3.9/3.9.2_1/bin/pip3 install -v --global-option=--no-user-cfg --install-option=--force --install-option=--single-version-externally-managed --install-option=--record=installed.txt --upgrade --target=/usr/local
==> /usr/local/Cellar/python@3.9/3.9.2_1/bin/pip3 wheel --wheel-dir=/usr/local/Cellar/python@3.9/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ensurepip/_bundled /usr/local/Cellar/python@3.9/3.9.2_1/libexec/setuptools /us
==> Caveats
Python has been installed as
  /usr/local/bin/python3

Unversioned symlinks `python`, `python-config`, `pip` etc. pointing to
`python3`, `python3-config`, `pip3` etc., respectively, have been installed into
  /usr/local/opt/python@3.9/libexec/bin

You can install Python packages with
  pip3 install <package>
They will install into the site-package directory
  /usr/local/lib/python3.9/site-packages

See: https://docs.brew.sh/Homebrew-and-Python
...
...

 

brew 의 로그를 보면서 에러가 난 부분들을 집중적으로 살펴봅니다. 확실히 python 3.9 를 설치하는 과정에 link 연결이 원활하지 않은게 보이는군요. 설치가 끝나는대로 brew link 명령을 --overwrite 으로 돌려보는게 좋을 것 같습니다. 그나저나 설치는 언제 끝나나...하고 있는데 설치가 끝났네요. 자 한번 brew link 를 수행해 보겠습니다

% brew link --overwrite --dry-run python@3.9
Would remove:
/usr/local/bin/2to3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/2to3
/usr/local/bin/idle3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/idle3
/usr/local/bin/pydoc3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/pydoc3
/usr/local/bin/python3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/python3
/usr/local/bin/python3-config -> /Library/Frameworks/Python.framework/Versions/3.6/bin/python3-config
%
% brew link --overwrite python@3.9
Linking /usr/local/Cellar/python@3.9/3.9.2_1... 21 symlinks created.
%
%
% python3
dyld: Library not loaded: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
  Referenced from: /Library/Frameworks/Python.framework/Versions/3.6/Resources/Python.app/Contents/MacOS/Python
  Reason: image not found
zsh: abort      python3

 

하아... 뭔가 잘 해결이 안되었네요. 분명 3.9 를 설치한 것 같은데 에러 내용의 중간을 보니 3.6을 참조하고 있는게 문제인 듯 싶습니다. python3 의 위치를 탐색해서 강제로 symlink 를 변경해 보도록 하겠습니다. 

% which python3
/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
%
%
% cd /Library/Frameworks/Python.framework/Versions/3.6/bin/
% rm python3
%
% which python3
/usr/local/bin/python3

 

하하~! 요렇게 하니 이제 새로 설치된 python3.9 버전이 잘 실행이 됩니다. 그러나 여전히 virtualenv나 pip가 제대로 동작하지 않았습니다.

% python3
Python 3.9.2 (default, Feb 24 2021, 13:26:09)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

 

뭐가 문제일까 하다가... 문득 .bash_profile 에 추가되었던 PATH 정보가 생각나서 이 부분을 모두 제거하고 터미널을 재기동 해보았습니다. 그리고 나니 이제야 제대로 동작하는 virtualenv 와 pip..!! 개발 환경은 처음 설정이 늘 어렵고 번거롭고... 그런것 같습니다 ㅎㅎ. 비슷한 어려움을 겪는 분들이 계시다면, 

1. brew 로 python 패키지 업데이트
2. symlink 가 이상하게 걸려 있는지 확인
3. PATH 로 잡혀 있는 파이썬 디렉토리 확인

의 순서를 따르시면 문제를 해결하실 수 있을 것 같습니다!

 

728x90
728x90

플러터 개발환경을 안드로이드 스튜디오에 구성해 보도록 하겠습니다. 기억하실지 모르겠지만 비주얼 스튜디오 코드 Visual Studio Code 에 환경을 구성하는 법을 잠깐 소개드렸었죠? 어쩌다보니 그 사이 시간도 많이 흘렀고... 다시 플러터 작업을 시작하면서 이번엔 안드로이드 스튜디오에 환경을 만들어 보도록 하겠습니다. 

플러터 플러그인 설치

가장 먼저 필요한 것은 안드로이드 스튜디오입니다. 안드로이드 스튜디오의 설치는 이미 되어 있다는 가정하에 플러터 개발환경을 꾸미도록 하겠습니다. 안드로이드 스튜디오가 제공하는 플러터 플러그인을 설치하면 개발환경 구성이 쉽게 진행됩니다. 

Configure > Plugins

 

안드로이드 스튜디오를 실행하고 우측 하단의 <Configure>를 눌러 <Plugins>를 선택합니다. 플러그인 추가를 통해 플러터를 안드로이드 스튜디오에서 사용할 수 있게 됩니다. 플러그인을 선택하고 검색창에 flutter를 검색했더니...

아무런 플러그인이 검색되지 않았습니다. 설치되어 있는 안드로이드 스튜디오의 버전이 3.1.4로 꽤 낮은 편이라 플러그인에서 검색이 잘 안되는 것 같습니다. 친절하게 안내된 <Search in repositories>를 누르고 다시 flutter를 검색해 봅니다. 높은 버전의 안드로이드 스튜디오라면 플러터를 바로 찾으실 수 있었을겁니다.

네, 이번에는 잘 찾아졌습니다! 여러가지가 있지만 가장 눈에 띄는 것을 설치하려고 보니... 업데이트 날짜가 2018년 10월 2일이군요. 아무래도 느낌이 좋지 않으니 안드로이드 스튜디오를 업데이트하고 오도록 하겠습니다 ;;;

 

안드로이드 스튜디오 업데이트 

매번 느끼는 것이지만 새로운 개발 환경을 만드는 것은 참 스트레스입니다. 본 게임에 들어가기도 전에 환경 설정하고 Hello World 찍어보다가 시간이 다 가기 마련이죠. 이번에는 꼭 제대로 공부하겠다는 일념으로 (스스로를 속이며) 안드로이드 스튜디오를 업데이트 해봅니다. 

다행히 용량이 그리 크지 않네요. 최신버전과는 메이저 버전 넘버가 차이날 정도로 시대에 뒤떨어져 있는 안드로이드 스튜디오를 가지고 있었군요. 과감히 <Update and Restart>를 눌러 업데이트를 진행합니다. 자바도 업데이트하고... 여러가지로 컴퓨터가 고생을 합니다. 

친절히도 오래된 버전 삭제를 건의하길래... 재빨리 마음 변하기 전에 <Delete Directories>를 눌러줍니다. 잘가라 안드로이드 스튜디오 3.1아..!

 

다시 플러터 플러그인 설치 시도하기!

이제 정신차리고 다시 플러그인 업데이트를 시도해 봅니다. <Configure>메뉴에 옵션도 많아지고... 잘은 모르겠지만 버전업을 하니 UI도 막 이뻐지는 것 같고 뭐 그런 기분이가 듭니다. 플러터가 이번에는 잘 검색되겠죠?

다행히 이번에는 Flutter의 검색결과가 바로 똭~하고 나왔습니다. 다운로드 횟수가 8백만회가 넘어가는 가장 첫번째 검색결과가 우리가 찾는 플러그인입니다. 

우측 상단의 Install 버튼을 누르고 플러그인 설치를 진행하겠습니다. 아파트 네트웍이 느린지 아직 아이콘도 제대로 안뜬 플러그인들이 눈에 띄는군요. 일해라 SK브로드밴드!

플러터를 구성하는 필수 요소인 다트 Dart 언어용 플러그인도 따로 존재하나 봅니다. Required 이니 Install 을 눌러서 Dart 플러그인도 설치하도록 하겠습니다. 

하아.. 뭔가 많습니다. 다트를 설치하고나니 이번에는 개발 도구를 재기동 하겠다고 합니다. 배움의 길은 역시 멀고도 험합니다. Restart를 누르고 재기동을 수행합니다. 참 착하죠?

안드로이드 스튜디오가 재기동되고 나니 이전에 없었던 옵션이 하나 생긴 것이 보입니다. 바로 <Create New Flutter Project> 입니다! 감동적인 순간입니다. 드디어 플러터 프로젝트를 만들고 코드를 개발할 수 있는 준비가 되었습니다! 

To be continued...

#플러터 #flutter #androidstudio #ide #개발환경구성 #크로스플랫폼 #모바일앱 #앱개발 

728x90
728x90

근래에 제공되는 대부분의 서비스는 SSL 혹은 TLS 를 이용하여 보안된 채널로 통신이 수행되도록 하는 것이 일반적입니다. 하물며 개인이 만드는 토이 프로젝트부터 대학교에서 과제로 제출하는 웹 사이트도 HTTPS 를 사용하지 않는 경우를 찾아보기 힘듭니다. 네, 물론 이 와중에서 Non-secure 로 버티는 곳들도 <당연히> 있긴 합니다. 

예전에는 HTTPS 를 이용하기 위해 인증서를 구매해야 했고, 보통 년단위의 갱신을 하다보니 비용 부담이 있었습니다. 하지만, 3개월마다 주기적으로 인증서를 업데이트 받는 조건으로 도메인 단위 인증서 (Domain Validation) 를 무료로 발급해주는 렛츠인크립트 Let's Encrypt 의 대중화 이후, 인증서 구매 비용도 단지 핑계가 된지 오래입니다. 


하지만, 이런 인증서 구매와 별개로 서버측에 SSL 설정을 구성하고 적용하는 것은 생각보다 까다롭게 생각하는 경우가 많습니다. 보통 한번 설정해 두면 수정하지 않아서 보안 사고의 원인이 되기도 하고, 설정을 잘못하는 바람에 특정한 단말기들이 서비스에 접근하지 못하는 장애를 겪기도 합니다. 원체 그 파급력이 크다보니 <그리 어려운 일이 아님에도 불구하고> 인증서 교체에 대해서 전문가를 찾는 경우가 종종 생깁니다.

이러한 엔지니어들의 고충을 잘 알고 있는 곳이 모질라 재단이기 때문일까요? 모질라에서 제공하는 SSL 설정 생성기는 이 모든 두려움으로부터...는 아니겠지만, 기본적인 설정 실수로 장애가 발생하는 것을 막아줄 수 있는 여러분의 친구, 좋은 도구가 될 수 있을 것 같습니다. 

다양하다! 

일단 이 도구가 커버해주는 서버측 소프트웨어의 범주가 무척 넓습니다. 널리 사용되는 아파치나 nginx 에서부터 AWS 의 ALB, ELB 도 포함이 되어 있습니다. HAProxy 와 Go 기반으로 서버측 엔드포인트를 만들때 쓸 수 있는 옵션들도 제공하고 있어 왠만한 서버측 도구의 SSL 설정에 활용도가 높아 보입니다. 

가운데 위치한 Mozilla Configuration 은 SSL/TLS 의 어떤 버전을 지원할 것인가에 따라 선택 가능한 항목입니다. 이 항목의 변경은 설정 생성시에 추가되는 Cipher Suite 의 종류에 영향을 주는 부분입니다. SSL/TLS 버전이 상위로 갈 수록 취약한 암호화 알고리즘을 사용할 수 없게 됩니다. 하지만, 오래된 사용자들은 SSL/TLS 의 상위 버전 자체를 사용할 수 없는 경우도 있기 때문에, 사용자 분포에 따라 취약한 알고리즘을 써야 하는 경우도 있을 겁니다.

가장 오른쪽에는 각 서버 어플리케이션의 버전에 따라 달라진 부분을 반영하기 위해 버전 정보를 기입할 수 있는 입력창이 위치해 있습니다. HSTS 와 OCSP Stapling 을 사용할 것인지에 따라 옵션을 선택할 수 있게 되어 있는 것도 눈에 띕니다. 

# generated 2021-02-08, Mozilla Guideline v5.6, nginx 1.17.7, OpenSSL 1.1.1d, modern configuration
# https://ssl-config.mozilla.org/#server=nginx&version=1.17.7&config=modern&openssl=1.1.1d&guideline=5.6
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    ssl_certificate /path/to/signed_cert_plus_intermediates;
    ssl_certificate_key /path/to/private_key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
    ssl_session_tickets off;

    # modern configuration
    ssl_protocols TLSv1.3;
    ssl_prefer_server_ciphers off;

    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header Strict-Transport-Security "max-age=63072000" always;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    # verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

    # replace with the IP address of your resolver
    resolver 127.0.0.1;
}

 

TLS 1.3 을 기준으로 NGINX 를 위한 설정을 생성해 보았습니다. HTTP 로 인입된 경우 HTTPS 로 스킴을 바꾸도록 301 리디렉션 하는 서버 컨텍스트가 앞에 위치해 있고, 443 포트로 HTTP/2.0 을 지원하는 엔드포인트를 열고 있습니다. 센스있게 IPv6 를 위한 포트 바인딩도 함께 추가되어 있네요!

그 외의 지시자들은 일름에서 유추할 수 있는 것처럼 프로토콜 버전의 지정, 인증서 파일의 위치, 세션 티켓 사용을 위한 옵션들이 지정되어 있습니다. 서버측의 prefer_server_ciphers 가 off 로 생성된 부분은 그 의도가 있을텐데 (아마도 NGINX 에서 TLS 1.3 사용시 기본 Cipher Suite 의 영향?) 자세한 건 문서를 좀 살펴봐야 할 것 같네요.


우리가 코드를 수정하거나 서버의 설정을 변경할 때 늘 하는 말이 있습니다. <지금 니가 무슨짓을 하는지 모른다면, 아무것도 하지 말아라> 라는 말이 바로 그것입니다. 각 설정이나 코드가 존재하는 것은 다 이유가 있어서 입니다. (예, 정말 가끔 이유 없이 존재하는게 없진 않습니다만...) 자동 생성된 설정을 참고하고 사용하는 것은 좋지만, 추가된 설정 항목들이 "왜" 들어갔는지에 대해서는 한번쯤 문서를 찾아보고 고개를 끄덕인 다음 Ctrl-C, V 하는 아름다운 자세를 견지하시기 바랍니다!

 

 

728x90
728x90

공식 문서의 taints 와 tolerations 에 대해서는 아래의 링크를 참고하면 된다. taints 는 노드에 적용되어 <수용 가능한 Pod 의 특성 정의>정도인 것 같고, tolerations 는 Pod 에 적용되어 <내가 동작할 수 있는 Node 를 선택하기 위한 특성 정의>라고 보면 될 것 같다.

 

테인트(Taints)와 톨러레이션(Tolerations)

노드 어피니티는 노드 셋을 (기본 설정 또는 어려운 요구 사항으로) 끌어들이는 파드의 속성이다. 테인트 는 그 반대로, 노드가 파드 셋을 제외할 수 있다. 톨러레이션 은 파드에 적용되며, 파드

kubernetes.io

 


노드에 설정된 taints 를 확인하기 위해서는 kubectl 에서 describe 옵션을 사용하면 된다.

$ kubectl describe node node01
Name:               node01
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
...
Annotations:        flannel.alpha.coreos.com/backend-data: null
                    flannel.alpha.coreos.com/backend-type: host-gw
...
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Mon, 25 Jan 2021 07:43:27 +0000
Taints:             <none>
Unschedulable:      false
Lease:
  HolderIdentity:  node01
  AcquireTime:     <unset>

 

특정 노드에 특정 key-value 와 effect 값을 지정하여 taints 를 설정. 아래는 spray 를 key 로, mortein 을 value 로, effect 는 NoSchedule 로 지정한 예임

$ kubectl taint nodes node01 spray=mortein:NoSchedule
node/node01 tainted

 

Pod 을 생성할 때 배치된 Node 가 없다면 (이 경우에는 Taints 로 특정한 값이 부여된 Node 밖에 없다) Pod 이 생성되지 못하고 Pending 상태로 머무르며, 상세 에러 내용이 taints 와 tolerations 에 대한 내용이 노출된다.

$ kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
mosquito   0/1     Pending   0          88s

$ kubectl describe pod mosquito
Name:         mosquito
Namespace:    default
Priority:     0
Node:         <none>
...
...
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason            Age               From               Message
  ----     ------            ----              ----               -------
  Warning  FailedScheduling  6s (x3 over 92s)  default-scheduler  0/2 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 1 node(s) had taint {spray: mortein}, that the pod didn't tolerate.

 

Pod 을 Taints 가 지정된 Node 로 배포하기 위해서는 Pod 의 스펙에 관련된 값을 지정해 주어야 한다.

$ cat create_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: bee
spec:
  containers:
  - image: nginx
    name: bee
  tolerations:
  - key: spray
    value: mortein
    effect: NoSchedule
    operator: Equal
    
$ kubectl create -f create_pod.yaml
pod/bee created

 

노드에 할당되어 있는 taints 값의 변경은 아래의 명령으로 수행할 수 있다. 예시는 controlplane 노드에 대하여 값을 부여하고 삭제하는 예시임.

$ kubectl taint nodes controlplane node-role.kubernetes.io/master:NoSchedule
node/controlplane tainted
$
$ kubectl taint nodes controlplane node-role.kubernetes.io/master:NoSchedule-
node/controlplane untainted
728x90

+ Recent posts