namespace를 쿠버네티스 deployment 설정에 넣는 것이 좋은 줄 알았는데,

막상 운영해보니, ingress에 namespace에 영향을 미치고

공통 파일 관리가 어렵다.

apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: phantom-server
namespace: phantom


namespace를 커맨드 라인에서 전달한다면 편하다. 

apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: phantom-server


$ kubectl apply -f kubernetes.yml --namespace=phantom


Posted by '김용환'
,



deployment -> pods 생성했다면.

pods 먼저 삭제하면 다시 실행되기 때문에..

deployment -> pods 순서대로 삭제해야 한다. 




[~] kubectl get deployments

NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE

phantom-server   1         1         1            1           51m


[~] kubectl get pods

NAME                              READY   STATUS    RESTARTS   AGE

phantom-server-649c56b6b7-nkmjd   1/1     Running   0          18m


[~] kubectl get pods

NAME                              READY   STATUS    RESTARTS   AGE

phantom-server-649c56b6b7-wgtdl   1/1     Running   0          1m

[~]

[~]

[~]

[~] kubectl get pods

NAME                              READY   STATUS    RESTARTS   AGE

phantom-server-649c56b6b7-mtxn8   1/1     Running   0          28m

[~] kubectl delete pods phantom-server-649c56b6b7-mtxn8

pod "phantom-server-649c56b6b7-mtxn8" deleted

[~] kubectl get pods

NAME                              READY   STATUS        RESTARTS   AGE

phantom-server-649c56b6b7-mtxn8   1/1     Terminating   0          28m

phantom-server-649c56b6b7-wgtdl   1/1     Running       0          21s




->




[~] kubectl delete deployment phantom-server

deployment.extensions "phantom-server" deleted

[~] kubectl delete pods phantom-server-649c56b6b7-nkmjd

pod "phantom-server-649c56b6b7-nkmjd" deleted



마찬가지로


cronjob -> job -> pods 로 생성된다면


먼저 cronjob을 생성하고 차례대로 job, pods를 삭제해야 제대로 삭제된다.




하지만, namespace를 삭제하면 namespace 밑의 모든 service, ingress, nodeport, pods가 삭제되니 참고..

Posted by '김용환'
,

MacOS에서 

특정 도메인에 내가 보고 싶은 ip를 보고 싶으면, 다음과 같이 진행한다.

리눅스에서는 /etc/hosts만 진행하면 되나, MacOS에서는 dns cacheflush를 따로 호출해야 한다. 



<ip 설정 (1대 반영 장비) >


$sudo vi /private/etc/hosts

192.168.38.93   shopping.google.com

$dscacheutil -flushcache



Posted by '김용환'
,



도커 파일을 빌드할 때 패키지 관리자와 interative하게 제어할 수 없다..



yum을 사용할 때는 어떠한 interative 입력을 받지 않도록 -y를 사용하는 반면,


apt-get은 interactive 입력을 받지 않도록 다음과 같이 사용해야 한다. 

DEBIAN_FRONTEND=noninteractive




예)

FROM ubuntu:18.04

RUN apt-get update -q \

&& DEBIAN_FRONTEND=noninteractive apt-get install -qy mysql-client


Posted by '김용환'
,



css style에 background-image를 추가하는 것이 있다. 


background-image:url(https://barcode.google.com/123123);background-repeat:no-repeat;background-position: center




도움 되는 아티클

https://www.w3schools.com/cssref/pr_background-position.asp


https://www.codingfactory.net/10571


https://www.w3schools.com/cssref/pr_background-repeat.asp

Posted by '김용환'
,


예)


ENV WIDTH 360 ...

CMD ["sh", "-c", "phantomjs --ssl-protocol=any rasterize.js 
      3001 $WIDTH"]


docker run -e WIDTH=360 -p 3001:3001 phantomjs


CMD 안에서는 제약사항이 많으니 sh를 잘 사용하는 것이 좋다. 








Posted by '김용환'
,


카카오 무료 폰트


https://brand.kakaocorp.com/assets/index/font


네이버 나눔 폰트


https://hangeul.naver.com/2017/nanum


나눔 폰트 재배포/판매시 라이선 전문을 포함하거나 출처 표기를 권장한다고 한다. 

 https://help.naver.com/support/contents/contents.help?serviceNo=1074&categoryNo=3497


네이버 나눔글꼴은 본 저작권 안내와 라이선스 전문을 포함해서 

다른 소프트웨어와 번들하거나 재배포 또는 판매가 가능합니다. 

 

네이버 나눔글꼴 라이선스 전문을 포함하기 어려울 경우, 

나눔글꼴의 출처 표기를 권장합니다. 



우아한 폰트

https://www.woowahan.com/#/fonts



Posted by '김용환'
,


phantomjs을 dockernize할 때 아래와 같이 fontconfig, freetype을 설치한다해도

RUN yum install -y fontconfig fontconfig-devel freetype freetype-devel libstdc++ ; yum clean all



영문이 깨지는 경우가 있다. 이 때는 다음 패키지를 설치해야 영문이 제대로 출력된다. 

urw-fonts

Posted by '김용환'
,



https://github.com/knight76/springboot2-restdocs  참고


Spring Rest Docs 및 Junit Test를 진행할 때 아래와 같이 부모 테스트 클래스를 둔 후, 자식 테스트에서 로직만 테스트하게 했더니 좀 편했다.


부모 테스트 클래스 

package com.example.controller;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;

import org.junit.Before;
import org.junit.Rule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.restdocs.JUnitRestDocumentation;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

public class ParentTest {

@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();

@Autowired
WebApplicationContext context;

RestDocumentationResultHandler document;

MockMvc mockMvc;

@Before
public void setUp() {
this.document = document(
"{class-name}/{method-name}",
preprocessResponse(prettyPrint())
);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration( this.restDocumentation))
.alwaysDo(document)
.build();
}
}





자식 테스트 클래스 

package com.example.controller;

import static org.hamcrest.CoreMatchers.*;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*;
import static org.springframework.restdocs.payload.PayloadDocumentation.*;
import static org.springframework.restdocs.request.RequestDocumentation.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.ResultActions;

@RunWith(SpringRunner.class)
@AutoConfigureRestDocs
@SpringBootTest
public class HelloWorldTest extends ParentTest {

@Test
public void helloWorldJson() throws Exception {
// given
String response = "{\"result\":\"Welcome, Hello World, Samuel\"}";

// when
ResultActions result =
mockMvc.perform(get("/helloworld/json")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.param("name", "Samuel"))
.andDo(print());

// then
result.andExpect(status().isOk())
.andDo(document.document(
requestParameters(
parameterWithName("name").description("이름입니다.")),
responseFields(
fieldWithPath("result").description("결과입니다."))))
.andExpect(jsonPath("result", is(notNullValue())))
.andExpect(content().string(response));
}
}


Posted by '김용환'
,


Spring Test를 수행하다 엄청 삽질한 것 중의 하나가...


Spring Boot에서 Controller(URL) 테스트를 진행할 때, 

Boot를 실행하고 curl json의 형태로 호출하면 제대로 호출되면 동작하는데, 

MockMvc를 사용하면 동작이 안되는 경우가 있었다.



Boot서비스가 실행되는 것과 달리 Spring Test와 MockMvc를 이용할 때는 굉장히 세밀하게 확인한다. 

그래서 JSON을 사용할 때는 반드시 MediaType을 적용하는 게 삽질을 덜하게 한다. 


@RestController
@RequestMapping(path="/api/1",
consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class CitiesController {


Posted by '김용환'
,