지돌이의 블로그 입니다!

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

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

https://mxtoolbox.com/domain/

 

일단 위 사이트에서 확인해보면 웬만한건 해결방법을 알 수 있다.

 

나는 몇군데 blacklist가 걸려서 그랬었는데...

 

https://rabbitchris.tistory.com/819


참고하여 해결하였다.

Comment +0

JCE Provider를 개발 및 배포하려면 Oracle으로부터 발급받은 JCE Code Signing Certificate를 통해 클래스들을 서명해야 합니다.

그렇지 않으면 디버깅조차 되지 않습니다.

Exception in thread "main" java.lang.SecurityException: JCE cannot authenticate the provider CustomProvider
	at javax.crypto.Cipher.getInstance(Cipher.java:656)
	at MyTestMain.main(MyTestMain.java:16)
Caused by: java.lang.SecurityException: Cannot verify jar:file:/....

위와 같은 오류를 보게 됩니다..

 

JCE Code Signing Certificate를 발급받는 과정은 아래와 같습니다.

 

참고 : https://www.oracle.com/technetwork/java/javase/tech/getcodesigningcertificate-361306.html

 

Get A JCE Code-Signing Certificate

Obtain a JCE Code Signing Certificate JCE Code Signing Certification Authority IMPORTANT NOTE: Oracle does not issue general code-signing certificates for applet or Web Start deployment. The process described here is only for obtaining certificates for use

www.oracle.com

https://docs.oracle.com/javase/10/security/howtoimplaprovider.htm

 

How to Implement a Provider in the Java Cryptography Architecture

An algorithm parameter specification is a transparent representation of the sets of parameters used with an algorithm. A transparent representation of parameters means that you can access each value individually, through one of the get methods defined in t

docs.oracle.com

(아래 내용은 Oracle사의 사정에 따라 변할 수 있으니 위 링크를 보시고, 아래 내용은 방법만 참고해 주시기 바랍니다~)

 

1. jce-cert-request_ww_grp@oracle.com 이 주소로 제목을 정확히 Request a Certificate for Signing a JCE Provider 이라고 써서 메일을 보내야 합니다.

메일에 작성해야 하는 내용은 아래와 같습니다.

 

Include the following contact information in the body of your message:

  • Company Name
  • Street Address (Not a post office box)
  • City
  • State/Province
  • Country
  • Company Telephone Number
  • Company Fax Number
  • Requester Name
  • Requester Telephone Number
  • Requester Email Address
  • Brief description of your company (size, line of business, etc.)
  • Purpose of Requested JCE Code Signing Certificate (for example: "Signing JCE providers containing Ciphers/Mac/KeyAgreement implementations")

그리고 PEM형식으로 인코딩된 CSR을 메일에 첨부파일로 첨부합니다.

CSR(인증서요청파일)을 만드는 방법은 두번째 링크에 있습니다. 아래와 같은 명령으로 생성 가능합니다.

keytool -genkeypair -alias <alias> \
        -keyalg RSA -keysize 2048 \
        -dname "cn=<Company Name>, \
        ou=Java Software Code Signing, \
        o=Oracle Corporation" \
        -keystore <keystore file name> \  
        -storepass <keystore password>

설명에는 10일 정도 걸리는걸 생각하라고 써있는데.. 메일을 보냈더니 저는 5 Business day 가 걸렸습니다.

 

그런데 여기서 끝이 아닙니다...ㅋ

 

몇일 후에 Confirmation of JCE Code Signing Certificate Request 라는 메일이 오는데 거의 물어봤던 내용을 다시 물어봅니다.

이 메일에 CSR request number 라는것이 발급되고 pdf파일 링크하나를 줍니다.

그럼 해당 파일을 인쇄하셔서 CSR request number와 몇가지 정보를 작성하고 (https://www.oracle.com/ocom/groups/public/@otn/documents/digitalasset/402171.txt)  (https://www.oracle.com/ocom/groups/public/@otn/documents/digitalasset/402171.txt) 자필 서명해서 스캔해서 다시 이메일(exporteccn_ww@oracle.com) 혹은 FAX으로 보내면 됩니다.

 

그런데 저는 여기서 엄청 오래걸렸습니다.. 10 Business day 가 넘어도 답장이 없길래...

 

Confirmation of JCE Code Signing Certificate Request 를 보내준 사람에게 질문했는데 해당 메일을 자기한테 CC(참조)걸어서 다시 보내보라고 해서 그렇게 했더니 3일 후에 발급된 인증서를 받아 볼 수 있었습니다.

 

암튼... 거의 3주 좀 안되는 시간만에 발급받았네요...ㅠㅠ

 

JCE 인증서 요청하시는 분은 미리.. 두번째 메일은 exporteccn_ww@oracle.com와 함께 첫번째 답장한 사람을 CC로 걸어서 보내보세요..

 

그리고 여유로움과 인내를...ㅋㅋ

 

Comment +0

단순 예제임.

사용법 없음..ㅋ

Jenkins -> item추가 -> Pipeline 으로 프로젝트 생성하고

Gitlab Integration에서 push event에 대한 WebHook을 jenkins으로 걸어놓고

Jenkins에서는 해당 이벤트를 받으면 gradle build -> Docker 이미지 생성 -> Docker Registry에 배포 -> 결과 전송 (Jandi Webhook)

이런 구조임..

프로젝트 git에는 docker폴더에 Dockerfile이 있어야 함.

import groovy.json.JsonOutput

version = ""
imageName = ""

def sendMessage(title, data) {
    def post = new URL("JANDI Web Hook URL").openConnection();

    data.body = "[[${env.JOB_NAME}]](${env.RUN_DISPLAY_URL}) push by ${env.gitlabUserName}: ${title}"

    post.setRequestMethod("POST")
    post.setDoOutput(true)
    post.setRequestProperty("Accept", "application/vnd.tosslab.jandi-v2+json")
    post.setRequestProperty("Content-Type", "application/json")
    post.getOutputStream().write(JsonOutput.toJson(data).getBytes("UTF-8"));
    def postRC = post.getResponseCode();
    return postRC
}

node('linux-agent-1') {
    try {
        stage('Preparation') {
            sendMessage("start build", [:])

            git(
                    url: env.gitlabSourceRepoURL,
                    credentialsId: 'gitlab-jenkins-1',
                    branch: env.gitlabTargetBranch
            )
        }
        stage('Build') {
            // 아래는 Artifactory 필요한 경우
            withCredentials([usernamePassword(credentialsId: 'artifactory-jenkins-pipeline', usernameVariable: 'ARTIFACTORY_USERNAME', passwordVariable: 'ARTIFACTORY_PASSWORD')]) {
                sh 'chmod +x gradlew'
                sh 'rm -rf build/libs/'
                sh './gradlew bootJar'
            }
        }
        stage('Publish') {
            version = sh(returnStdout: true, script: 'find build/libs/*.jar | sed -r \'s/^.*-([0-9.]+)\\.jar$/\\1/\'').trim()
            imageName = "Docker Registry 주소/네임스페이스/${env.JOB_NAME}:${env.gitlabTargetBranch.substring(7)}-${version}"
            sh 'cp build/libs/*.jar ./docker/app.jar'
            withDockerRegistry([url: "Docker Registry 주소"]) {
                def buildedDockerImage = docker.build(imageName, "./docker/") 
                buildedDockerImage.push()
            }
        }
        stage('Results') {
            def data = [
              "connectColor": "#FAC11B",
              "connectInfo": [
                [
                  "title": "version",
                  "description": version
                ],
                [
                  "title": "published image",
                  "description": imageName
                ]
              ]
            ]
            sendMessage("build success", data)
        }
    }catch(Exception e){
        def data = [
            "connectColor": "#FAC11B",
            "connectInfo": [
                [
                  "title": "version",
                  "description": version
                ],
                [
                  "title": "Exception",
                  "description": e.getMessage()
                ]
              ]
            ]
        sendMessage("build failed. [[Click]](${env.BUILD_URL}/console) to see more information.", data)
        throw e
    }
}

Comment +0

https://doc.primekey.com/ejbca/ejbca-operations/ejbca-operations-guide/ca-operations-guide/end-entities/ssl-certificate-expiration

 

SSL Certificate Expiration

The SSL certificate used for SSL in JBoss is stored in APPSRV_HOME/server/default/conf/keystore.jks. The default validity time for the SSL certificate is two years.

doc.primekey.com

참고.

 

추가로

4. Copy EJBCA_HOME/p12/tomcat.jks to APPSRV_HOME/server/default/conf/keystore.jks, or run 

이 부분있는데 위 대상 경로가 없을 경우

/opt/jboss-as-7.1.1.Final/standalone/configuration/keystore/keystore.jks

으로 하면 된다.

 

추가로 기본CA를 바꾸려면 (https 8443 Client Certificate인증을 위한 DN변경시) truststore.jks을 새로 만들면 된다.

Comment +0