1. ingress란

클러스터 외부에서 내부로 접근하는 요청들을 어떻게 처리할지 정의해둔 규칙들의 모음.
외부에서 접근가능한 url을 사용할 수 있게 하고,
트래픽 로드밸런싱도 해주고,
ssl 인증서 처리,
도메인 기반 가상 호스팅을 제공.
ingress 자체는 이런 규칙들을 정의해둔 자원.
실제 동작하게 해주는게 ingress controller.
클라우드서비스를 사용하는것이 아니라면
ingress와 ingress controller를 직접 연동해주어야함.

이때 가장 많이 사용되는게 kubernetes에서 제공하는 ingress-nginx.

2. ingress-nginx 설치, 사용.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml

kubectl expose deploy nginx-ingress-controller --type=NodePort -n ingress-nginx

kubectl apply -f test.yaml

# 확인
kubectl describe ingress test

kubctl apply -f deployments-nginx.yaml

kubectl expose deploy nginx-deployment --name s1

 

  • test.yaml 내용

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
    name: test
    annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
    rules:
     - host: xxx.xxx.xx
    paths:
     - path: /foos1
    backend:
    serviceName: s1
    servicePort: 80
     - path: /bars2
    backend:
    serviceName: s2
    servicePort: 80
     - host: xxx.xxx.xx
    http:
    paths:
     - backend:
    serviceName: s2
    servicePort: 80

     

  • deployments-nginx.yaml 내용.
    kind: Deployment
    metadata:
    name: nginx-deployment
    labels:
    app: nginx
    spec:
    replicas: 3
    selector:
    matchLabels:
    app: nginx
    template:
    metadata:
    labels:
    app: nginx
    spec:
    containers:
    - name: nginx
    image: nginx
    ports:
    - containerPort: 80

 

3. 접근

kubectl get services --all-namespaces 에서 나온 port와 s1에 설정한 host, path를 이용하여
xxx.xxx.xxx:31536/foos1 로 접근 가능.

 

저는 소스관리를 위해 github을 사용중입니다.

ssh key 설정을 해두지 않으면 commit, push 할때 마다 로그인 정보를 입력해야하는 번거로움이 있습니다.

그런데 ssh key를 github deploy key에 등록해주면 그런 번거로움을 덜 수 있습니다.

 

1. git clone을 할때 http가 아닌 ssh 주소를 사용하세요

텍스트 추가

대표사진 삭제

사진 설명을 입력하세요.

텍스트 추가

 

2. 작업하는 서버에서 ssh key를 생성합니다.

ssh-keygen -t rsa -C “your_email@example.com”

 

3. 생성된 public key를 github settings > deploy keys에 push권한을 체크해서 등록해줍니다.

cat ~/.ssh/id_rsa.pub

 

텍스트 추가

대표사진 삭제

사진 설명을 입력하세요.

텍스트 추가

 

 

 

이제는 매번 로그인 하지 않아도 되네요 ^^

 

 

mysql8로 버전업이 됨에 따라 기존에 사용중이던 hibernate, mysql-connector-java등 version을 올리고 관련 conf수정하였다

수정 부분 요약.

  1. pom.xml
    hibernate.version=5.3.1.Final
    (hibernate-entitymanager 삭제, hibernate-validator 추가 )

  2. application.properties
    hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

  3. mysql8.0 user 권한부여

구체적인 내용.

  1. pom.xml 1.8 0.0.1
     <properties>
         <java.version>1.8</java.version>
         <twig-service.version>0.0.1</twig-service.version>
-        <hibernate.version>5.0.3.Final</hibernate.version>
+        <hibernate.version>5.3.1.Final</hibernate.version>
         <hibernate-javax-persistence.version>1.0.0.Final</hibernate-javax-persistence.version>
         <commons-configuration.version>1.10</commons-configuration.version>
-        <mariadb-java-client.version>1.3.0</mariadb-java-client.version>
+        <mariadb-java-client.version>2.4.1</mariadb-java-client.version>
         <querydsl.version>4.1.4</querydsl.version>
         <spring-data-mock.version>1.1.4</spring-data-mock.version>
+       <hibernate.validator.version>6.0.10.Final</hibernate.validator.version>
     </properties>

-       <dependency>
-            <groupId>org.hibernate</groupId>
-             <artifactId>hibernate-entitymanager</artifactId>
-             <version>${hibernate.version}</version>
-       </dependency>
+       <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator</artifactId>
+           <version>${hibernate.validator.version}</version>
+       </dependency>
        <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
-            <version>5.1.37</version>
+            <version>8.0.16</version>
        </dependency>

 

  1. application.properties
    hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

  2. mysql설정

    - 아래와 같이 mysql conf수정
     default password plugin 설정 추가

    [mysqld]
    default-authentication-plugin=mysql_native_password

       - mysql 내 계정 생성시 문법 변경 및 인증 타입 명시  
         grant 에는 identified 삭제  
         create 시에 with mysql\_native\_password 추가

 create user 'mydb'@'%' IDENTIFIED WITH mysql_native_password BY 'YOURPASSWORD';
 GRANT ALL PRIVILEGES on mydb.* to 'myuser'@'%' WITH GRANT OPTION;

maven에 새 jar를 추가하고 application을 실행해보니 아래와 같은 메세지가 나온다.

오류메세지

:A child container failed during start  
[java.util.concurrent.ExecutionException:](java.util.concurrent.ExecutionException:) [org.apache.catalina.LifecycleException:](org.apache.catalina.LifecycleException:) Failed to start component \[StandardEngine\[Tomcat\].StandardHost\[localhost\].StandardContext\[\]\]  
at [java.util.concurrent.FutureTask.report(FutureTask.java:122)](java.util.concurrent.FutureTask.report(FutureTask.java:122)) ~\[?:1.8.0\_77\]  
at [java.util.concurrent.FutureTask.get(FutureTask.java:192)](java.util.concurrent.FutureTask.get(FutureTask.java:192)) ~\[?:1.8.0\_77\]  
at [org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:911)](org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:911)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:890)](org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:890)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)](org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403)](org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)](org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [java.util.concurrent.FutureTask.run(FutureTask.java:266)](java.util.concurrent.FutureTask.run(FutureTask.java:266)) \[?:1.8.0\_77\]  
at [java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)](java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)) \[?:1.8.0\_77\]  
at [java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)](java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)) \[?:1.8.0\_77\]  
at [java.lang.Thread.run(Thread.java:745)](java.lang.Thread.run(Thread.java:745)) \[?:1.8.0\_77\]  
Caused by: [org.apache.catalina.LifecycleException:](org.apache.catalina.LifecycleException:) Failed to start component \[StandardEngine\[Tomcat\].StandardHost\[localhost\].StandardContext\[\]\]  
at [org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)](org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)) ~\[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
... 6 more  
Caused by: [org.apache.catalina.LifecycleException:](org.apache.catalina.LifecycleException:) Failed to start component \[Pipeline\[StandardEngine\[Tomcat\].StandardHost\[localhost\].StandardContext\[\]\]\]  
at [org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)](org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)) ~\[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5099)](org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5099)) ~\[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  

해결방법

검색해보니 servlet-api.jar를 exclude하라는 말이 많이 나왔는데
나의 경우 아래 설정을 pom에 추가하니 실행 성공하였다.

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

provided 는 무엇을 의미하는지?

This scope is used to mark dependencies that should be provided at runtime by JDK or a container, hence the name.

A good use case for this scope would be a web application deployed in some container, where the container already provides some libraries itself.
컨테이너에서 deploy도는 어플리케이션에서 컨테이너는 이미 자체적인 라이브러리를 제공한다.

For example, a web server that already provides the Servlet API at runtime, thus in our project, those dependencies can be defined with the provided scope:
런타임에 의존성을 가지지 않고 컴파일/테스트단계에서만 제공되는 dependency.

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

The provided dependencies are available only at compile-time and in the test classpath of the project; what's more, they aren't transitive.

라이브러리 의존성을 피하기 위한 방법이리라.

요즘은 java 프로젝트를 gradle로 많이 하지만 나는 maven을 사용 중이다.
맨날 쓰는 maven command line이 있지만, 정확히 어떤 의미인지를 파악해봐야겠다.
인텔리제이 로컬 환경에서 package명령어는 성공하나 deploy가 안되는데 그 이유가 궁금하여 확인해보게되었다.

아파치 공식문서

https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

For the person building a project, this means that it is only necessary to learn a small set of commands to build any Maven project, and the POM will ensure they get the results they desired.

maven이란.

maven은 pom.xml에 description된 정보를 기반으로 프로젝트를 build한다.
goal이란 maven이 행할 수 있는 여러가지 동작을 수행하는 명령어를 의미.

어떤 goal이 있을까?

clean

  • 컴파일 결과물인 target 디렉토리 삭제.

compile

  • compile the source code of the project
  • 모든 소스코드를 컴파일하고 리소스파일은 target/classes 디렉토리에 복사.

package

  • take the compiled code and package it in its distributable format, such as a JAR.
  • compile 수행 후 pom에 있는 정보에 따라 패키징을 수행.
  • description example.
    <executions>
                   <execution>
                       <id>package</id>
                       <phase>package</phase>
                       <goals>
                           <goal>run</goal>
                       </goals>
                       <configuration>
                           <tasks>
                               <copy file="${project.build.directory}/${project.build.finalName}.jar.original"
                                     tofile="./deploy/my-project/${project.build.finalName}.jar"/>
                               <copy todir="./deploy/my-project/bin">
                                   <fileset dir="bin"/>
                               </copy>
                               <copy todir="./deploy/my-project/conf">
                                   <fileset dir="conf"/>
                               </copy>
                               <copy todir="./deploy/my-project/lib">
                                   <fileset dir="${project.build.directory}/dependency/"/>
                               </copy>
                           </tasks>
                       </configuration>
                   </execution>
                   ....
                 <executions>
                   <execution>
                       <phase>package</phase>
                       <goals>
                           <goal>copy-dependencies</goal>
                       </goals>
                       <configuration>
                           <outputDirectory>${project.build.directory}/dependency/</outputDirectory>
                       </configuration>
                   </execution>
               </executions>

install

  • install the package into the local repository, for use as a dependency in other projects locally
  • package 수행 후 local repo에 pakage를 설치. 로컬 다른 프로젝트에서 사용가능함.

validate

  • validate the project is correct and all necessary information is available
  • 프로젝트가 사용 가능한지 확인.

test

  • test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
  • unit test 수행

deploy

  • done in the build environment, copies the final package to the remote repository for sharing with other developers and projects.
  • 환경구성을 마치고 remote repository에 package들을 copy. 실제 릴리즈할때의 배포.

실제로 내가 배포할때 사용하는 명령어.

mvn -U clean --update-snapshots dependency:copy-dependencies package -Dmaven.test.skip=true -Dmaven.test.skip=true

spring boot AOP 구현하기.
Aop를 잘 모르지만

  • Http 요청이 왔을때 끼어들어 요청에 대한 권한이 있는지 체크하기 위한 AOP를 개발하려한다.
    : http요청이 왔을때 실제 응답을 주기전에 권한을 체크하고 권한이 있으면 계속 진행하도록 해주고, 권한이 없으면 진행을 막는다.
  • 더불어 특정 controller에는 권한체크를 하지 않고, http request로 온 header안에 정보를 parameter로 전달하려한다.
  1. pom.xml
    <dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
  1. AopConfig.java
    @Around 이노테이션으로 requestMapping으로 들어오는 요청에 대해서 AOP를 적용할것임을 명시.
    특정 controller 접근시에는 parameter를 넘겨주도록했음.
    주석 참고.
@Configuration
@Aspect
@EnableAspectJAutoProxy() 
public class AopConfig { 
    ...
    @Around("@annotation(requestMapping)") 
    public final Object checkPermission(final ProceedingJoinPoint pjp
                                      , final RequestMapping requestMapping){
        .... 
        //권한을 체크하는 함수에서 true값을 return해주면 계속해서 진행 
        if (permission.check(pjp, requestMapping, httpServletRequest)) { 
            return pjp.proceed();
        } 

        ....
        String email = .... ;
        //특정 controller접근시에는 권한체크는 하지 않고 파라미터만 전달하여 계속 진행
        if (pjp.getSignature().toString().contains("com.xxx.xxx.controller.xxx")) {
            return pjp.proceed(new Object\[\]{email});
        } 
        ... 


        //권한 없는 경우 null을 return하여 계속해서 진행할 수 없음. 
        return null; 
        } 
 }

참고.
proceedjointpoint로 parameter를 넘겨줄때는 넘겨준 parameter와 동일한 명칭, 순서로 받아야한다.

@ResponseBody 
@RequestMapping(method = RequestMethod.GET, value = "/user") 
public LoginUser getLoginEmail(final String email) { 
    LoginUser loginUser = new LoginUser(); 
    loginUser.setEmail(email);
    return loginUser;
}

Apache 2.2.x 버전은 2017년 12월부터 EOL되었기에 업그레이드가 필요하다.
2.4.39에는 mod_proxy, mod_http2 등에서 보안에 취약하다고 나왔기에 2.4.41로 업그레이드 하도록한다.

아파치 2.2 버전이 eol된다는 공식 문서

Apache HTTP Server 2.2 vulnerabilities This page lists all security vulnerabilities fixed in released versions of Apache HTTP Server 2.2. Each vulnerability is given a security impact rating by the Apache security team - please note that this rating may we

아파치 httpd업그레이드 공식 문서

1. 다운로드 및 설치

wget http://apache.tt.co.kr//httpd/httpd-2.4.41.tar.gz
tar -zxvf httpd-2.4.41.tar.gz
cd httpd-2.4.41/
./configure --prefix=/home1/irteam/mocha
make
make install

2. conf 설정

- 필요한 모듈들은 주석을 제거한다.

LoadModule rewrite_module modules/mod_rewrite.so 
LoadModule proxy_module modules/mod_proxy.so 
LoadModule proxy_http_module modules/mod_proxy_http.so

- 모든 요청을 거부 혹은 허용하는것을 기술하는 문법이 바꼈다.
- 그외에 default값이 변경된 것이 있을 수 있으니 upgrade문서를 참고하여 기존 conf설정을 옮겨오도록한다.

1) 모든 요청을 거부

# 2.2 설정
Order deny,allow
Deny from all

# 2.4 설정
Require all denied

2) 모든 요청을 허용

# 2.2 설정
Order allow,deny
Allow from all

# 2.4 설정
Require all granted  

3.  아파치 서버를 시작해준다 :)

sh apachectl start

+ Recent posts