지돌이의 블로그 입니다!

Kubernetes에서 사용할 Deployment/Service설정 yaml을 온라인 상에서 GUI로 만들 수 있게ㅜ도와주는걸 만들었습니다.

 

https://jc-lab.github.io/auto-generator/#/

 

kube-yaml-generator

 

jc-lab.github.io

 

github에 소스 공개되어 있으니 기능 추가 및 개선 PR주심 넘나 감사!

 

 

https://github.com/jc-lab/auto-generator/

 

jc-lab/auto-generator

Contribute to jc-lab/auto-generator development by creating an account on GitHub.

github.com

 

Comment +0

openpgp을 사용하는 프로젝트를 webpack으로 번들링하면 아래와 같은 오류가 발생한다.

Error: Cannot find module 'stream'
    at o (/bundle.js:4293:292)
    at /bundle.js:4293:449
    at Object.<anonymous> (/bundle.js:28885:38)
    at Object.76.stream (/bundle.js:28943:4)
    at o (/bundle.js:4293:398)
    at /bundle.js:4293:449
    at Object.<anonymous> (/bundle.js:28422:13)
    at Object.75../node-conversions (/bundle.js:28875:4)
    at o (/bundle.js:4293:398)
    at /bundle.js:4293:449

이런 경우 Webpack에서 openpgp패키지의 dist대신 src를 쓰게 하고 필요한 dependency들을 추가해주면 된다.

package.json의 dependencies에

    "asmcrypto.js": "github:openpgpjs/asmcrypto#6e4e407b9b8ae317925a9e677cc7b4de3e447e83",
    "elliptic": "github:openpgpjs/elliptic#6b7801573b8940a49e7b8253176ece2725841efd",
    "email-addresses": "github:openpgpjs/email-addresses#686743c6452b44bafcd06d47db7f36ddf3f3f118",

추가한다.

(주의할점은 그냥 npm install 으로 설치하면 안되고 openpgpjs의 github 리포지터리에서 가져와야 한다. 기존의 패키지를 openpgp에서 수정해서 쓰는것이기 때문)

그리고

$ npm update

$ npm install --save web-stream-tools tweetnacl text-encoding-utf-8 @mattiasbuelens/web-streams-polyfill

Comment +0

 INFO  Launching Electron...
internal/modules/cjs/loader.js:630
    throw err;
    ^
Error: Cannot find module 'electron'
Require stack:
- ...\electron-output\index.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:627:15)
    at Function.Module._load (internal/modules/cjs/loader.js:531:27)
    at Module.require (internal/modules/cjs/loader.js:685:19)
    at require (internal/modules/cjs/helpers.js:16:16)
    at eval (webpack:///external_%22electron%22?:1:18)
    at Object.electron (...\electron-output\index.js:2146:1)
    at __webpack_require__ (...\electron-output\index.js:20:30)
    at eval (webpack:///./background/background.ts?:3:66)
    at Module../background/background.ts (...\electron-output\index.js:133:1)
    at __webpack_require__ (...\electron-output\index.js:20:30) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    ...\\electron-output\\index.js'
  ]
}
Done in 26.02s.

ELECTRON_RUN_AS_NODE 환경변수를 확인해 보아야 한다.

(Windows 환경임)

> set ELECTRON_RUN_AS_NODE=0

이건 node로 실행하지 않겠다는 뜻이지만...

> set ELECTRON_RUN_AS_NODE=0

이게 있으면 위와 같은 문제가 발생한다...ㅠㅠ 겁나 삽질함....

Comment +0

https://gist.github.com/jc-lab/b80aa4183c0f8c3971260ac2ee49443d

 

AWS NAT Instance configure-pat.sh for Keep source ip

AWS NAT Instance configure-pat.sh for Keep source ip - configure-pat.sh

gist.github.com

기존에는 configure-pat.sh에

 

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

으로 되어있는데 이러면 내/외부 모든 패킷에 MASQUERADE가 적용되어 DNAT를 이용한 Port Forwarding시 Source IP가 NAT Instance의 IP으로 변하게 됩니다.

따라서 MySQL의 User에 IP Rule이 적용되어있으면 로그인 할 수 없게 되죠..

이를 해결하기 위해서는 외부망으로 다시 나가는 패킷에만 MASQUERADE를 해야 하는데

iptables -t nat -A POSTROUTING -o eth0 ! -d 내부망 MASQUERADE 으로 바꿔야 합니다.

Cloud 환경은 친절하게도 metadata url을 지원해서 내부망 IP를 자동으로 가져올 수 있습니다.

자동으로 위 처리를 해주는 스크립트로 변경하였습니다.

 

AWS에서 이렇게 진즉에 적용해주었음 참 고마웠을텐데요...

 

(그나저나 여담으로.. 뉴스는 안나왔지만 어제 밤 8시쯤 넘어서 언젠가.. 잠깐 AWS Console에 장애가 있었네요..

로그인도 안되고 창도 엄청 늦게 뜨거나 안나오고.. EC2/Lambda등 서비스에서는 문제없고 AWS Console에만 문제가 있었습니다. Console만져야 하는데 긴장좀 탔네요..ㅠㅠ)

Comment +0

요즘 AWS Lambda를 써보는데 기본적인 걸로 삽질을 했다..ㅋㅋ

1. VPC의 Subnet는 기본적으로 서로 통신이 가능하다.

삽질한 내용은 아니지만 기본적인 내용인데 인터넷을 보면 잘못 설명한 글이 몇몇 있었다.

한 VPC내의 모든 Subnet들은 라우터로 연결된 것으로 묘사되는데 서로 통신이 가능하단 뜻이다.

2. API Gateway이랑 연동할 때 Lambda에서 Timeout발생시 502 Bad Gateway가 뜬다.

3. Security Group는 Rule이 없으면 기본적으로 모든 Inbound를 거부한다.

4. Lambda를 VPC로 연결했을 때 기본적으로 AWS Service에 연결할 수 없다.

따라서 VPC에 Endpoint를 만들어서 외부 endpoint가 아닌 VPC 내부의 endpoint를 타도록 해야 한다.

여기서 VPC에 Endpoint만들 때 Security Group선택하는데 443포트에 대한 Inbound를 허용해야 한다.

그리고 DNS가 활성화되기 때문에 lambda 소스에서 따로 endpoint를 지정해줄 필요는 없다. ({service}.{region}.amazonaws.com 이 자동으로 VPC Endpoint IP로 Resolve된다)

5. UnrecognizedClientException: The security token included in the request is invalid. 오류시...

    await new Promise((resolve, reject) => {
        AWS.config.getCredentials(function(err) {
            if (err)
                reject(err);
            else {
                resolve();
            }
        });
    });
    const kms = new AWS.KMS({
        credentials: AWS.config.credentials // 필요!
    }));

6. Private Subnet에서 실행중인 Lambda는 다른 Lambda를 호출할 수 없다.

4번과 같은 문제인데 진짜 문제는 AWS PrivateLink에 Lambda 서비스 (lambda.{region}.amazonaws.com)가 없다는 것이다.

따라서 Private Subnet에서 돌아가는 Lambda에서 다른 Lambda를 Invoke하려면 NAT이 필수적이다.

이참에.. KMS도 써야하고 Lambda도 써야하는데 PrivateLink는 비싸서(시간당 0.01달라인가.. 여러개면...ㅠㅠ) NAT Instance를 구축했다. (NAT Gateway는 비싸다...ㅠㅠ)

AWS때문에 지갑이 얇아진다... 아니 지네 서비스안에서 지네 서비스 연결하는데도 돈이 든다니... 인터넷 통신비용도 또 따로 책정하면서... 이런...

7. NodeJs에서 exports = require(...) 이런 형식의 handler는 안된다.

무슨 말이냐면...

index.js

exports = require('./dist/main.js')

dist/main.js

const server = JsExpressServer.createServer();
exports.handler = server.lambdaHandler;

이렇게 했는데 안되었다.

웃긴건 index.js에서 exports.handler를 출력해보면 자알 존재하는데 딱히 실행하면 오류도 안나고 그저 502 Bad Gateway (Timeout)가 떠버린다..

이유는 lambdaHandler가 Promise로 작동하는거 때문인거 같은데 쨋든 웃기다기보단 내가 아직 node.js를 잘 몰라서 그렇다..ㅎㅎ

this 참조때문인가 했는데 그건 아니었다. lambdaHandler안에서 this객체들은 너무도 잘 참조되었다.

지금은 dist/main.js를 직접 실행하고 (WebPack을 쓰고있다. 용량도 확 줄고 alias도 쓸 수 있고 좋다~)

const server = JsExpressServer.createServer();
exports.handler = (event, context) => server.lambdaHandler(event, context);

이렇게 하니 잘 된다!

Comment +0

https://github.com/jc-lab/node-app

 

jc-lab/node-app

Embed node.js application with VFS(Virtual File System) - jc-lab/node-app

github.com

삽질의 결과!ㅠㅠ

결과는 간단한데 과정이 힘들었음..

Comment +0

https://github.com/jc-lab/openssl-fips-cmake

 

jc-lab/openssl-fips-cmake

Contribute to jc-lab/openssl-fips-cmake development by creating an account on GitHub.

github.com

참고~

Comment +0

Kubernetes

Master Node 초기화

  1. sysctl 수정

현재 Runtime에 대한 sysctl 변경

$ sudo sysctl net.bridge.bridge-nf-call-iptables=1

vim 으로 sysctl 에 대한 영구 설정 변경

$ sudo vim /etc/sysctl.d/99-sysctl.conf

net.bridge.bridge-nf-call-iptables=1 # 추가
  1. kubeadm
$ sudo kubeadm init --pod-network-cidr=172.30.0.0/16 --service-cidr=10.244.0.0/16

마지막에 나오는 문장 기억해놓기

kubeadm join 10.0.0.2:6443 --token ssssss.asdasdasdas --discovery-token-ca-cert-hash sha256:asdasdasdasdasdasdsadsad

이런거

  1. 관리자 사용자 설정
# 관리자 사용자 계정에서
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
  1. Network overlay 추가
# 다운로드
$ wget https://raw.githubusercontent.com/coreos/flannel/v0.11.0/Documentation/kube-flannel.yml

# 내용 수정
$ vim kube-flannel.yml
# net-conf.json 부분의 "Network": "10.244.0.0/16" => "Network": "172.30.0.0/16" 으로 변경 후 저장

# 적용
$ kubectl apply -f kube-flannel.yml
  1. Slave Node 설정
# Slave Node 에서
$ sudo kubeadm join 10.0.0.2:6443 --token ssssss.asdasdasdas --discovery-token-ca-cert-hash sha256:asdasdasdasdasdasdsadsad
  1. 1분쯤 지나도 kubectl get nodes 에서 Slave노드가 NotReady 라면
$ sudo mkdir -p /etc/cni/net.d
$ sudo vim /etc/cni/net.d/10-flannel.conflist
# 파일 만들기 (이건 모든 node에서,없는경우)

{
    "name": "cbr0",
    "plugins": [
        {
            "type": "flannel",
            "delegate": {
                "hairpinMode": true,
                "isDefaultGateway": true
            }
        },
        {
            "type": "portmap",
            "capabilities": {
                "portMappings": true
            }
        }
    ]
}

$ sudo systemctl restart kubelet

Comment +0

C++ & libuv & uvw (C++ libuv wrapper library) 으로 http server을 구현했습니다.

 

Spring-boot의 RequestMapping과 같은 기능을 구현해놓아서 URL에 대한 접근이 용이합니다.

 

#include <iostream>

#include <uvw/loop.hpp>
#include <jshttpserver/server.hpp>
#include <jshttpserver/http_request.hpp>

#pragma comment(lib, "libuv.lib")

int main() {
    auto loop = uvw::Loop::getDefault();

    std::shared_ptr<jshttpserver::Server> server(jshttpserver::Server::create(loop));

    server->requestMapping(jshttpserver::METHOD_ALL, "/api/test", [](jshttpserver::HttpRequest &req, jshttpserver::HttpResponse &res) {
      std::cout << "requestMapping FOUND :: /api/test" << std::endl;
      std::cout << "\tsearch[ " << req.url_search << " ]" << std::endl;
    });

    server->requestMapping(jshttpserver::METHOD_ALL, "/api/test2/{v1}/{v2}", [](jshttpserver::HttpRequest &req, jshttpserver::HttpResponse &res) {
      std::cout << "requestMapping FOUND :: /api/test2/{v1}/{v2}" << std::endl;
      std::cout << "\tsearch[ " << req.url_search << " ]" << std::endl;
    });

    server->requestMapping(jshttpserver::METHOD_ALL, "/api/test3/{v3:.+}", [](jshttpserver::HttpRequest &req, jshttpserver::HttpResponse &res) {
      std::cout << "requestMapping FOUND :: /api/test3/{v3:.+}" << std::endl;
      std::cout << "\tsearch[ " << req.url_search << " ]" << std::endl;
    });

    server->documentRootMapping("/docs/", [](jshttpserver::HttpRequest &req, jshttpserver::HttpResponse &res) {
      std::cout << "documentRootMapping FOUND :: /docs/ :: path = " << req.doc_path_name << std::endl;
      std::cout << "\tpath_name[ " << req.doc_path_name << " ], search[ " << req.url_search << " ]" << std::endl;
    });

    server->documentRootMapping("/doxs", [](jshttpserver::HttpRequest &req, jshttpserver::HttpResponse &res) {
      std::cout << "documentRootMapping FOUND :: /doxs :: path = " << req.doc_path_name << std::endl;
      std::cout << "\tpath_name[ " << req.doc_path_name << " ], search[ " << req.url_search << " ]" << std::endl;
    });

    server->addListen(8887);

    loop->run();
    return 0;
}

 

https://github.com/jc-lab/jshttpserver-uvw.git

 

jc-lab/jshttpserver-uvw

Contribute to jc-lab/jshttpserver-uvw development by creating an account on GitHub.

github.com

 

Comment +0

sca6000 드라이버입니다. kernel-3.10 이상에서 동작하도록 수정하였습니다.
https://github.com/jc-lab/sun-sca6000-drv/

 

기존 sca6000 패키지들은 Redhat 5 등의 오래된 OS에서 동작합니다.

centos 5.3 기반 이미지에 OpenSSL/ca-bundle/curl 등을 새로 올린 centos-new-5.3이미지에 sca6000 및 openCryptoki, opensc(pkcs11-tool) 등을 추가한 도커파일입니다.
https://github.com/jc-lab/sun-sca6000-docker/

 

여기에 https://github.com/mtrojnar/osslsigncode 이나 jar signtool 설치 후 openjdk-1.8.0 & Jenkins 를 이용해 빌드 후 자동 sign 기능을 구현하면 좋을듯 합니다.

 

보안을 위해 로그인키는 따로 저장치 않고 빌드시 사용자에게 confirm을 받도록 하면 더욱 안전하겠죠!

 

언젠가 이런거 만들어야 하는데... 언제만드냐...ㅠㅠ 피곤타..

HSM너무 비싸서.. 중고 HSM찾으니 SCA6000이 나와서 구매했는데 생각보다 정보도 없고 너무 오래된거라...ㅠㅠ 꽤나 어려웠네요..

Comment +0