별내자이 사전점검 업체 원케어 점검 후기

사는 일|2023. 11. 6. 01:32

별내자이 사전점검 기간이 되어서,

셀프로 할지, 대행 업체를 이용할 지 고민을 많이 했다.

별내자이 입주 카톡방에서는 특정 업체가 인기가 많아서 예약이 많았는데,

나는 고민하느라 예약을 못하고 있었다...

그리고 점검 1주 전에 톡방에서 어떤 분이 추천해주신 업체가 원케어여서,

뒤늦게 예약을 했는데, 결과적으로 대만족한다.

가격도 다른 업체와 비교해 최저가여서 나는 18만원을 지불했다.

 

특히 나처럼 점검이 처음이신 분들, 잘 모르시는 분들은 업체 대행을 맡기는 게 좋을 것 같다.

나는 홈페이지를 통해서 주말에 예약 상담을 요청했고, 다음날 전화가 와서 어느 시간에 하면 좋은지 등을 상담받고 예약했다.

https://onecarehaja.com

 

원케어 H.I.S

저희 원케어 H.I.S.는 입주 사전점검 전문업체로 저희가 점검하는 아파트 하나하나를 저희 집처럼 정말 꼼꼼하고 세밀하게 일을 진행합니다. 규모면에서 최대는 아닐지라도 최고임은 자부하며,

onecarehaja.com

 

 

나는 사실 자이 앱에서 오후 1시로 예약했는데,

원케어에서 상담할 때 오전이 좋을 것 같고, 일찍 와도 입장 가능할 거라고 하셔서 일찍 갔다.

점검하시는 분들은 더 일찍와서 기다리고 계셔서 9시 30분쯤 만나서

자이에서 선착순으로 대기하다가 10시쯤부터 사전점검을 시작했고

원케어에서는 2시간~2시간30분 정도를 꼼꼼히 봐주시고 가셨다.

원케어는 하루에 세 집만 점검한다고 했는데, 그게 맞는 것 같다.

 

 

두 분이 먼저 와서 전체적인 하자를 찾아주셨고, 나중에 두 분이 추가로 와서,

건물이 틀어졌는지, 단열이 잘 돼있는지,

화장실/세탁실 등에 물이 빠져나갈 수 있는 각도가 잘 만들어져 있는지를 확인해 주셨다.

일단 이것만 해도 몇몇 장비가 필요한 일이라, 대행 업체를 이용하길 잘했다고 생각했다.

 

3번째 방의 각도가 일부 틀어졌지만, 3cm 미만이라 법적으로 하자는 아니고,

이정도는 다시 공사를 하는게 오히려 리스크가 크다고 알려주셔서, 하자 접수를 하지 않기로 했다.

 

먼저 오신 전문가분들께서는 사소한 것부터 전혀 생각지 못한것까지 꼼꼼하게 체크하셨다.

먼저 강마루와 타일 들뜸을 하나하나 다 쳐보면서 확인하셨고, 줄눈이 정상인지,

창틀 주변이 눌리는지, 창문 열때 흔들리는지, 

욕조, 수전, 싱크대 등이 정상인지,

라돈 측정기로 공기질이 정상인지,

각 벽지 이음새 부분이 정상인지, 각 문짝에 이격이 있는지 등등...

 

셀프점검을 했으면 전혀 생각도 못했을 것들을 전문가가 알아서 확인해주니 몸도 마음도 편했다.

아니 이런것도 확인해야돼?

또는 아니 이렇게 사소한것도 하자야?

등등 내 선에서 결정하지 못하는 것들을 정해주니 좋았다.

거실에만 붙은 스티커가 전부 몇개나 될까...

 

원케어에서 찾아주신 하자는 90여 개가 나왔고, 나랑 동생이 남아서 추가로 찾은게 2~3개 정도 되는 것 같다.

사전 점검이 끝난 후에는 나온 하자에 대해 하나하나 설명해주시고, 

당일 발견된 하자는 웹페이지 보고서로 만들어서 보내주신다.

보고서에 보면 알겠지만, 모든 하자에 대한 내용과 단열을 확인 한 사진과 건물 비틀림 밑 배수를 확인한 사진, 그리고 라돈 측정에 대한 자료가 잘 나와 있다.

https://cutt.ly/7wRJx2Hx

 

자이의 경우 하자 내용을 앱에 올려 접수해야하는데, 추가비용을 지불하면, 앱 접수 대행도 해주신다.

 

 

 

앱 접수의 경우 정확한 하자 내용을 입력하기도 해야하고, 사진도 원거리/근거리, 하자 위치를 정확하게 표시해서 올려야하는데 사진만 200장 정도가 필요하니, 대행을 하는게 시간을 아끼는 거라고 생각한다.

'사는 일' 카테고리의 다른 글

연말정산 세액공제 정치인 후원하기  (0) 2020.11.25

댓글()

zeppelin shiro 계정 password 암호화

IT기술/hadoop family|2021. 1. 17. 16:27

2020-07-28 작성

 

https://shiro.apache.org/command-line-hasher.html#CommandLineHasher-%7B%7Bshiro.ini%7D%7DUserPasswords

https://repo1.maven.org/maven2/org/apache/shiro/tools/shiro-tools-hasher/1.3.2/

위 내용대로 shiro-tools-hasher-version-cli.jar로 pw를 생성하고, 그 내용을 shiro에 입력해주고, 설정을 해주면 될 것 같다.

 

zeppelin/conf의 shiro.ini 파일에 아래 부분을 입력해주고, hash화 한 패스워드를 [users]에 입력해주고, restart하면 된다.

[main]
...
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
iniRealm.credentialsMatcher = $passwordMatcher
...

 

참고: https://shiro.apache.org/configuration.html#Configuration-EncryptingPasswords

댓글()

zeppelin cron module

IT기술/hadoop family|2021. 1. 17. 16:26

2020-06-24 작성

 

zeppelin에서 cron job을 수행할 수 있다. 아래 페이지에서 설명하는 바와 같이 설정을 해주면 된다.

https://zeppelin.apache.org/docs/0.8.0/usage/other_features/cron_scheduler.html

댓글()

spring data jpa doc

공부 자료 모음|2021. 1. 17. 16:25

2020-06-04 작성

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation

'공부 자료 모음' 카테고리의 다른 글

windows terminal  (0) 2021.01.15
pyspark tutorial  (0) 2021.01.15
bash shell script 공부  (0) 2021.01.15
javascript 공부 자료 모음  (0) 2021.01.14
python 공부 자료 모음  (0) 2021.01.14

댓글()

centos6 encoding locale 설정

IT기술/linux, windows|2021. 1. 17. 16:24

2020-06-01 작성

 

locale 명령으로 현재 encoding을 확인한다. 다음과 같이 표시된다.

$ locale
LANG=ko_KR.eucKR
LC_CTYPE="ko_KR.eucKR"
LC_NUMERIC="ko_KR.eucKR"
LC_TIME="ko_KR.eucKR"
LC_COLLATE="ko_KR.eucKR"
LC_MONETARY="ko_KR.eucKR"
LC_MESSAGES="ko_KR.eucKR"
LC_PAPER="ko_KR.eucKR"
LC_NAME="ko_KR.eucKR"
LC_ADDRESS="ko_KR.eucKR"
LC_TELEPHONE="ko_KR.eucKR"
LC_MEASUREMENT="ko_KR.eucKR"
LC_IDENTIFICATION="ko_KR.eucKR"
LC_ALL=

 

1. 서버 전체의 locale 변경

eucKR을 utf8로 변경하고 싶다.

서버 전체의 locale을 변경하기 위해서는 /etc/sysconfig/i18n 파일의 설정 내용을 변경하면 된다.

즉, 다음 내용의 eucKR을 utf8로 변경하고 저장한다.

LANG="ko_KR.eucKR"
SUPPORTED="ko_KR.eucKR"
SYSFONT="latarcyrheb-sun16"

source /etc/sysconfig/i18n로 적용하고 locale을 확인한다.

서버 대수가 많을 때는 다음과 같이 ansible로 변경할수도 있다.

ansible [cluster] -m shell -a 'sudo sed -i "s/ko_KR.eucKR/ko_KR.utf8/g" /etc/sysconfig/i18n'

 

2. 해당 계정의 locale 변경

1과 같이 했는데, locale이 변경되지 않았다면?

그 이유는 현재 접속한 계정 shell profile 설정에 우선순위가 높은 locale 설정이 따로 있는 것이다.

우선순위에 따라 다음 순서로 export LANG, export LC_* 문이 있는지 확인한 후 바꿔주면 된다.
1. [.bash_profile]
2. [.bashrc]
3. [/etc/profile]

export LC_ALL=ko_KR.UTF-8
export LANG=ko_KR.UTF-8

source [.bash_profile] 한 후에 locale을 확인해보자!

 

참고사이트:
https://www.lesstif.com/system-admin/unix-profile-export-lang-c-17105910.html

댓글()

java로 shell 명령어 실행하기, pipeline

IT기술/java, spring|2021. 1. 17. 16:19

2020-05-29 작성

 

java로 shell 명령어를 실행하는 방법은 2가지가 있다.
ProcessBuilder와 runtime.exec()를 사용하면 된다.

 

다음은 ProcessBuilder 예제이다. ProcessBuilder에 들어가는 명령어는 String[] 또는 List<String>여야 한다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ProcessBuilderExample {
    public static void main(String[] args) {
        try {
            String[] command = new String[] {"bash","-c", "hdfs dfs -df | tail -n 1"};
            ProcessBuilder processBuilder = new ProcessBuilder(command);
            Process process = processBuilder.start();

            BufferedReader reader =
                    new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            int exitCode = process.waitFor();
            System.out.println("\nExited with error code : " + exitCode);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

다음은 runtime.exec() 예제이다. 위와 코드 내용은 2줄 빼고 같다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class RuntimeExecExample {
    public static void main(String[] args) {
        try {
            String[] command = new String[] {"bash","-c", "hdfs dfs -df | tail -n 1"};
            Process process = Runtime.getRuntime().exec(command);

            BufferedReader reader =
                    new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            int exitCode = process.waitFor();
            System.out.println("\nExited with error code : " + exitCode);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

명령어에 pipeline이 들어있을 때 실행이 안돼서 많이 헤멨는데,

위의 예제 처럼, shell(sh, bash)명령어 뒤에 pipeline이 있는 명령어를 한번에 써주니, 명령이 잘 실행됐다.

String[] cmd = {
"/bin/sh",
"-c",
"ls /etc | grep release"
};

 

참고사이트:
https://d2.naver.com/helloworld/1113548
https://mkyong.com/java/java-processbuilder-examples/
https://mkyong.com/java/how-to-execute-shell-command-from-java/
http://zetcode.com/java/processbuilder/
https://stackoverflow.com/questions/5928225/how-to-make-pipes-work-with-runtime-exec

댓글()

jupyter notebook 환경 정리(from 제주코딩베이스캠프 강의)

IT기술/javascript, python|2021. 1. 17. 12:40

2020-05-24 작성

 

안녕하세요.
제주코딩베이스캠프의 이호준입니다.

 

꼭 영상에서 찍은 환경으로 실습하시지 않으셔도 괜찮습니다. 편하신 에디터를 사용하시기 바랍니다.(Jupyter Notebook이나 google Colab을 추천합니다.)

 

1. 주 환경은 Jupyter notebook을 사용했습니다. 해당 영상에는 활용법만 들어 있어서 google에서 Anaconda를 검색하신 후 다운로드 받으셔서 실행하시면 되십니다.

https://www.anaconda.com/

 

2. google colab에서도 바로 실습이 가능합니다.

https://colab.research.google.com/

 

3. Jupyter Notebook은 공식사이트에서 온라인으로도 사용하실 수 있습니다.

https://jupyter.org/try

 

4. Visual Studio Code에서도 Extension을 활용하여 Jupyter를 사용할 수 있습니다.

youtu.be/Xs5aM9FYuic

vscode 단축기:
ctrl+ “+” 확대, ctrl+”-” 축소
ctrl+n 새파일, ctrl+s 저장
f5 파일실행 선택
ctrl+f5 바로 실행
ctrl+shift+p 메뉴선택(jupyter실행)
ctrl+, 환경설정
ctrl+` 터미널

 

emmet 사용법:
 
!+tab: html 기본 템플릿
h1+tab
table>tr>td+tab
table>(tr>td{hello}*4)*3+tab
h1{hello}+tab
h$*6+p+tab

extention 설치:
python
live server – alt+l, alt+o 하면 실행
beautify – 단축키 설정 후 사용

 

출처: https://www.inflearn.com/course/%EC%A0%9C%EC%A3%BC%EC%BD%94%EB%94%A9-%EC%9B%B9%EA%B0%9C%EB%B0%9C-30%EB%B6%84%EC%9A%94%EC%95%BD-%EC%8B%9C%EC%A6%8C2

댓글()

Hive Authorization Configuration 권한 설정

IT기술/hadoop family|2021. 1. 17. 12:36

2020-05-15 작성

 

Hive 권한 설정이 잘 안돼서 거의 4일을 버렸다..

hadoop설정은 버전별로 안되는 경우가 많고,

인터넷에 레퍼런스가 정확한게 많지 않아 너무 찾기 힘들었다.

열심히 해봐서 안되면 답이 없는 것이다.

하란대로 해서 안되면 답을 알 수 없는 노가다가 돼버린다. 결국 구현을 못하고 끝날수도 있다.

하지만 다행히 방법을 찾아서 포스트를 작성한다.

 

cloudera version: 5.16.1
hive version: 1.1

 

핵심 레퍼런스는 다음 url을 참고하면 된다.

https://cwiki.apache.org/confluence/display/Hive/SQL+Standard+Based+Hive+Authorization#SQLStandardBasedHiveAuthorization-ForHive0.14andNewer

 

목록 중 For Hive 0.14 and Newer에 보면 설정 방법이 나오는데, 다음을 세팅해준다.
(내용을 읽어보면 좋아서 그대로 가져왔다.)

 

Set the following in hive-site.xml: cloudera의 경우 "hive-site.xml에대한 Hive 서비스고급구성스니펫"에 입력해주면 된다.

  • hive.server2.enable.doAs to false. : cloudera에서는 hive config상에서 수정 가능하다.
  • hive.users.in.admin.role to the list of comma-separated users who need to be added to admin role. Note that a user who belongs to the admin role needs to run the "set role" command before getting the privileges of the admin role, as this role is not in current roles by default.
  • Add org.apache.hadoop.hive.ql.security.authorization.MetaStoreAuthzAPIAuthorizerEmbedOnly to hive.security.metastore.authorization.manager. (It takes a comma separated list, so you can add it along with StorageBasedAuthorization parameter, if you want to enable that as well).
    This setting disallows any of the authorization api calls to be invoked in a remote metastore. HiveServer2 can be configured to use embedded metastore, and that will allow it to invoke metastore authorization api. Hive cli and any other remote metastore users would be denied authorization when they try to make authorization api calls. This restricts the authorization api to privileged HiveServer2 process. You should also ensure that the metastore rdbms access is restricted to the metastore server and hiverserver2.
  • hive.security.authorization.manager to org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdConfOnlyAuthorizerFactory. This will ensure that any table or views created by hive-cli have default privileges granted for the owner.

Set the following in hiveserver2-site.xml: 이 파일은 존재하지 않을 수도 있다. cloudera의 경우 "hive-site.xml에대한 HiveServer2 고급구성스니펫"에 입력해주면 된다.

  • hive.security.authorization.manager=org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory
  • hive.security.authorization.enabled=true
  • hive.security.authenticator.manager=org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator
  • hive.metastore.uris=' ' : 이 설정은 설정해보니 불필요한 에러가 발생하여 제외하였다.

xml로는 다음과 같다.

hive-site.xml에대한 Hive 서비스고급구성스니펫: 
<property>
    <name>hive.users.in.admin.role</name>
    <value>admin</value>
</property>
<property>
    <name>hive.security.authorization.manager</name>
    <value>org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdConfOnlyAuthorizerFactory</value>
</property>
<property>
    <name>hive.security.metastore.authorization.manager</name>
    <value>org.apache.hadoop.hive.ql.security.authorization.MetaStoreAuthzAPIAuthorizerEmbedOnly</value>
</property>

hive-site.xml에대한 HiveServer2 고급구성스니펫: 
<property>
    <name>hive.security.authorization.manager</name>
    <value>org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory</value>
</property>
<property>
    <name>hive.security.authorization.enabled</name>
    <value>true</value>
</property>
<property>
    <name>hive.security.authenticator.manager</name>
    <value>org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator</value>
</property>

위 설정을 추가한 후 beeline으로 접속한 후 테스트를 해본다. 위 설정에서 admin role을 admin 계정으로 주었고, hue에도 계정이 있어야 한다. 만약 문서에 나온것만으로 잘되면 다음과 같이 될 것이다. 하지만 나는 잘 안됐다.

 

[irteam@dnaa-opr-t1001 ~]$ beeline -u jdbc:hive2://[host주소]:10000 -n admin
Beeline version 1.1.0-cdh5.16.1 by Apache Hive
0: jdbc:hive2://dnaa-opr-t1001:10000> show current roles;
INFO  : OK
+---------+--+
|  role   |
+---------+--+
| public  |
+---------+--+
1 row selected (2.028 seconds)
0: jdbc:hive2://dnaa-opr-t1001:10000> select * from default.aaa; => 권한이 없어 안되는것 확인
Error: Error while compiling statement: FAILED: HiveAccessControlException Permission denied: Principal [name=admin, type=USER] does not have following privileges for operation QUERY [[SELECT] on Object [type=TABLE_OR_VIEW, name=default.aaa]] (state=42000,code=40000)
0: jdbc:hive2://dnaa-opr-t1001:10000> set role admin;
INFO  : OK
No rows affected (0.022 seconds)
0: jdbc:hive2://dnaa-opr-t1001:10000> show current roles;
INFO  : Compiling command(queryId=hive_20200515160404_c358a275-56b9-4be4-b9df-b8c0e9d0bb13): show current roles
INFO  : OK
+--------+--+
|  role  |
+--------+--+
| admin  |
+--------+--+
0: jdbc:hive2://dnaa-opr-t1001:10000> select * from default.aaa;
INFO  : OK
+---------+--+
| aaa.id  |
+---------+--+
| 222     |
| 111     |
| 333     |
+---------+--+
3 rows selected (0.169 seconds)

 

위에 썼듯이 나의 경우는 잘 안됐다. 그럴경우 다음 config 중 필요한 것을 추가해보자.

아마도 위 설정 중 Factory 관련된 것들은 다음 설정이 필요한 것 같다.
<property>
    <name>hive.security.authorization.task.factory</name>
    <value>org.apache.hadoop.hive.ql.parse.authorization.HiveAuthorizationTaskFactoryImpl</value>
</property>
 
다음 설정은 hue에서 권한 설정이 실행되지 않을 때 필요하다.
<property>
    <name>hive.security.authorization.sqlstd.confwhitelist.append</name>
    <value>hive\.server2\.proxy\.user</value>
</property>
 
다음 설정은 꼭 필요하지 않다. 권한설정이 완료되면 grant 설정이 전혀 없고 수동으로 권한을 넣어줘야 하는데, 이 설정을하면 create table 시 table owner를 기준으로 자동으로 grant 설정을 넣어준다.
<property>
    <name>hive.security.authorization.createtable.owner.grants</name>
    <value>ALL</value>
</property>

 

여기까지 완료되면 설정은 다했다.

beeline과 hue로 접속하면 권한이 없는 계정으로는 테이블에 접근할 수 없다.

누구에게나 공개하고 싶은 테이블은 public 권한을 주면 된다.

다만 hive 명령어로 접속하면 다른계정에서도 접근이 가능하니,

보안을 위해서 admin을 제외하고 hive 명령어에 접근할 수 없도록 해야한다.

 

이제 핵심 레퍼런스를 참고하여 grant로 권한을 넣고 사용하면 된다.

 

그러나 그래도 안된다면, 다음을 확인해보자.

hadoop.proxyuser.hive.groups *[default] 인지 확인
HDFS 상의 권한 설정
– sudo -u hdfs hdfs dfs -chown -R hive:hive /user/hive/warehosue
– sudo -u hdfs hdfs dfs -chmod -R 771 /user/hive/warehouse

 

참고 사이트:

https://cwiki.apache.org/confluence/display/Hive/SQL+Standard+Based+Hive+Authorization#SQLStandardBasedHiveAuthorization-ForHive0.14andNewer

https://qiita.com/bwtakacy/items/2777253ae21fc84b7543

https://www.slideshare.net/julingks/hive-authorization-michael130702

댓글()

hive에서 json포맷 기반으로 데이터 가져오기 위한 설정

IT기술/hadoop family|2021. 1. 16. 00:30

2020-02-26 작성

 

우리 랩에서는 보통 데이터 포맷으로 parquet을 사용한다.

hive에서도 데이터를 가져올 때 parquet 포맷으로 가져오는데, 그 때는 hive 테이블 포맷이 다음과 같다.

ROW FORMAT SERDE
‘org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe’
STORED AS INPUTFORMAT
‘org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat’
OUTPUTFORMAT
‘org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat’

 

그런데 json 파일 포맷을 hive에서 사용하고 싶다는 요청이 왔다. 설정 적용은 생각보다 어렵지 않다. hive hcatalog 라이브러리(hive-hcatalog-core-1.1.0-cdh5.8.0.jar)를 cloudera hive 라이브러리 디렉토리에 넣고 hive-site.xml에 추가해주면 된다.

<property>
  <name>hive.aux.jars.path</name>
  <value>[jar파일이 있는 디렉토리 경로]</value>
</property>

클라우데라 설정은 다음과 같다.

 

나의 경우는 hive hcatalog가 이미 설치가 돼있고, /opt/cloudera/parcels/CDH/jars 디렉토리에 라이브러리가 있었다. 설정 후 hive 관련 서비스를 재시작해주면 된다. 그리고 hive에서 json 포맷이 잘 불러와지는지 확인하면 된다.

ROW FORMAT SERDE
‘org.apache.hive.hcatalog.data.JsonSerDe’
STORED AS INPUTFORMAT
‘org.apache.hadoop.mapred.TextInputFormat’
OUTPUTFORMAT
‘org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat’

댓글()

AWS boto3 시작하기

IT기술/cloud, docker|2021. 1. 16. 00:24

2020-01-10 작성

 

boto3은 AWS를 python 코드로 사용할 수 있게 해주는 라이브러리이다.
처음 시작은 boto3의 QuickStart를 보고 하는게 빠르다.

 

Boto is the Amazon Web Services (AWS) SDK for Python. It enables Python developers to create, configure, and manage AWS services, such as EC2 and S3. Boto provides an easy to use, object-oriented API, as well as low-level access to AWS services.]

https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html

 

1. boto3을 설치한다.

pip install boto3

2. AWS > iam > 사용자 > 보안 자격 증명에서 액세스 키 생성

 

3. credentials 설정파일 입력

touch ~/.aws/credentials
vim ~/.aws/credentials

### 다음 부분을 입력한다.
[default]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY

4. region 설정파일 입력

touch ~/.aws/config
vim ~/.aws/config

### 다음 부분을 입력한다. ap-northeast-2는 서울 리전임
[default]
region=ap-northeast-2

5. s3 bucket 목록 가져오기(여기부터는 python 파일을 만들어서 python으로 실행하면 된다.)

import boto3
 
# Let's use Amazon S3
s3 = boto3.resource('s3')

# Print out bucket names
for bucket in s3.buckets.all():
	print(bucket.name)

6. 파일 업로드 하기

# Upload a new file
data = open('test.parquet', 'rb')
s3.Bucket('my-bucket').put_object(Key='test.parquet', Body=data)

7. parquet 파일을 s3select로 query해보고 출력하기

s3 = boto3.client('s3')
response = s3.select_object_content(
    Bucket=bucket_name,
    Key=file_name,
    ExpressionType='SQL',
    Expression="select * from s3object s limit 10",
    InputSerialization = {'Parquet': {}},
    OutputSerialization = {'JSON': {}},
)
 
 
for event in response['Payload']:
    if 'Records' in event:
        records = event['Records']['Payload'].decode('utf-8')
        print(records)
    elif 'Stats' in event:
        statsDetails = event['Stats']['Details']
        print("Stats details bytesScanned: ")
        print(statsDetails['BytesScanned'])
        print("Stats details bytesProcessed: ")
        print(statsDetails['BytesProcessed'])

8. athena create database

ath = boto3.client('athena')
 
# create database
ath.start_query_execution(
    QueryString='create database mytest',
    ResultConfiguration={'OutputLocation': s3_query_path})

9. athena create table(여기는 ddl file을 생성해서 진행, 경우에 따라서 직접 create query를 만들어줄 수 있음)

# create table
with open('./mydata.ddl') as ddl:
    ath.start_query_execution(
        QueryString=ddl.read(),
        ResultConfiguration={'OutputLocation': s3_query_path})
# mydata.ddl
CREATE EXTERNAL TABLE IF NOT EXISTS
mytest.mytable (
  col1 string,
  col2 integer
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION 's3://mytest/mytest/';

10. athena query 실행

#Function for starting athena query
def run_query(query, database, s3_output):
    client = boto3.client('athena')
    response = client.start_query_execution(
        QueryString=query,
        QueryExecutionContext={
            'Database': database
            },
        ResultConfiguration={
            'OutputLocation': s3_output,
            }
        )
    query_execution_id=response['QueryExecutionId']
 
    # get execution status
    for i in range(1, 1 + RETRY_COUNT):
        # get query execution
        query_status = client.get_query_execution(QueryExecutionId=query_execution_id)
        query_execution_status = query_status['QueryExecution']['Status']['State']
        if query_execution_status == 'SUCCEEDED':
            print("STATUS:" + query_execution_status)
            break
        if query_execution_status == 'FAILED':
            raise Exception("STATUS:" + query_execution_status)
        else:
            print("STATUS:" + query_execution_status)
            time.sleep(i)
    else:
        client.stop_query_execution(QueryExecutionId=query_execution_id)
        raise Exception('TIME OVER')
 
 
    # get query results
    result = client.get_query_results(QueryExecutionId=query_execution_id)
    print(result)
    return response

댓글()

java spring ip가 특정 ip 대역(cidr)에 속하는 지 확인하기 ip restrict

IT기술/java, spring|2021. 1. 16. 00:14

2020-01-07 작성

 

ip가 특정 ip 대역에 속하는 지 확인해보려고 할때,

누가 만들어 놓은 함수들이 없다면 생각보다 계산이 복잡하다. (내가 만들고 싶지 않다)

 

이런 계산을 왜 하냐면, 망 분리 등 보안 이슈에 대응하기 위해서다.

예를들어 다운로드는 분리된 망안에서만 가능하게 한다던지,

특정 IP만 접속 가능한 페이지를 만들던지 하는 식이다.

 

apache httpd를 사용한다면 쉽게 특정 ip를 제한할 수 있다.

하지만 이렇게하면 세세한 설정은 못할 것이다.

<Location>
Order deny,allow
    Deny from all
    Allow from 10.123.115.0/24
</Location>

java에 대해 찾아보면 apache commons의 SubnetUtils를 사용하라는 글들이 많다.

나도 사용하려고 했지만 이상하게도, maven으로부터 가져오지 못했다.

다운로드해서 lib로 넣기엔 귀찮기도 했다. 그래서 maven 문제를 찾다보니 시간을 많이 버렸다.

그러다가 spring security web에 IpAddressMatcher라는 비슷한 함수가 있다는 것을 알게 되었다.

 

사용법은 복붙한다.

import org.springframework.security.web.util.matcher.IpAddressMatcher;
...

private void checkIpMatch() {
    matches("192.168.2.1", "192.168.2.1"); // true
    matches("192.168.2.1", "192.168.2.0/32"); // false
    matches("192.168.2.5", "192.168.2.0/24"); // true
    matches("92.168.2.1", "fe80:0:0:0:0:0:c0a8:1/120"); // false
    matches("fe80:0:0:0:0:0:c0a8:11", "fe80:0:0:0:0:0:c0a8:1/120"); // true
    matches("fe80:0:0:0:0:0:c0a8:11", "fe80:0:0:0:0:0:c0a8:1/128"); // false
    matches("fe80:0:0:0:0:0:c0a8:11", "192.168.2.0/32"); // false
}

private boolean matches(String ip, String subnet) {
    IpAddressMatcher ipAddressMatcher = new IpAddressMatcher(subnet);
    return ipAddressMatcher.matches(ip);
}

다음은 사용하지는 않았지만, 출처에서 퍼온 light weight solution이다.

/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * Matches a request based on IP Address or subnet mask matching against the remote
 * address.
 * <p>
 * Both IPv6 and IPv4 addresses are supported, but a matcher which is configured with an
 * IPv4 address will never match a request which returns an IPv6 address, and vice-versa.
 *
 * @author Luke Taylor
 * @since 3.0.2
 * 
 * Slightly modified by omidzk to have zero dependency to any frameworks other than the JDK.
 */
public final class IpAddressMatcher {
    private final int nMaskBits;
    private final InetAddress requiredAddress;

    /**
     * Takes a specific IP address or a range specified using the IP/Netmask (e.g.
     * 192.168.1.0/24 or 202.24.0.0/14).
     *
     * @param ipAddress the address or range of addresses from which the request must
     * come.
     */
    public IpAddressMatcher(String ipAddress) {

        if (ipAddress.indexOf('/') > 0) {
            String[] addressAndMask = ipAddress.split("/");
            ipAddress = addressAndMask[0];
            nMaskBits = Integer.parseInt(addressAndMask[1]);
        }
        else {
            nMaskBits = -1;
        }
        requiredAddress = parseAddress(ipAddress);
        assert  (requiredAddress.getAddress().length * 8 >= nMaskBits) :
                String.format("IP address %s is too short for bitmask of length %d",
                        ipAddress, nMaskBits);
    }

    public boolean matches(String address) {
        InetAddress remoteAddress = parseAddress(address);

        if (!requiredAddress.getClass().equals(remoteAddress.getClass())) {
            return false;
        }

        if (nMaskBits < 0) {
            return remoteAddress.equals(requiredAddress);
        }

        byte[] remAddr = remoteAddress.getAddress();
        byte[] reqAddr = requiredAddress.getAddress();

        int nMaskFullBytes = nMaskBits / 8;
        byte finalByte = (byte) (0xFF00 >> (nMaskBits & 0x07));

        // System.out.println("Mask is " + new sun.misc.HexDumpEncoder().encode(mask));

        for (int i = 0; i < nMaskFullBytes; i++) {
            if (remAddr[i] != reqAddr[i]) {
                return false;
            }
        }

        if (finalByte != 0) {
            return (remAddr[nMaskFullBytes] & finalByte) == (reqAddr[nMaskFullBytes] & finalByte);
        }

        return true;
    }

    private InetAddress parseAddress(String address) {
        try {
            return InetAddress.getByName(address);
        }
        catch (UnknownHostException e) {
            throw new IllegalArgumentException("Failed to parse address" + address, e);
        }
    }
}

출처: https://stackoverflow.com/questions/577363/how-to-check-if-an-ip-address-is-from-a-particular-network-netmask-in-java

'IT기술 > java, spring' 카테고리의 다른 글

java로 shell 명령어 실행하기, pipeline  (0) 2021.01.17

댓글()

git에서 branch로 clone 하는 방법

IT기술/기타|2021. 1. 15. 23:58

2020-01-07 작성

 

개발을 하다보면 master 브랜치에 merge하기 전에 개발하던 branch만 다시 clone해서 사용할 때가 있다.

git clone -b {branch_name} --single-branch {저장소 URL}
ex) git clone -b javajigi --single-branch https://github.com/javajigi/java-racingcar

출처: https://www.slipp.net/questions/577

'IT기술 > 기타' 카테고리의 다른 글

wordpress 접속 오류 수정  (0) 2021.01.15

댓글()

apache zeppelin 설치하고 hadoop kerberos 연동하기

IT기술/hadoop family|2021. 1. 15. 23:54

2019-12-30 작성

 

http://zeppelin.apache.org/download.html

위 페이지에서 다운 받아서 압축을 풀어준다.

wget http://apache.mirror.cdnetworks.com/zeppelin/zeppelin-0.8.2/zeppelin-0.8.2-bin-all.tgz
tar -xvf zeppelin-0.8.2-bin-all.tgz

 

그러면 일단 설치는 끝이다. 구동방법은 다음 페이지를 참조하면 된다.

http://zeppelin.apache.org/docs/0.8.2/quickstart/install.html

 

${ZEPPELIN_HOME}/conf에 몇가지 설정 파일들이 있는데, 복사해준다.

cp zeppelin-env.sh.template zeppelin-env.sh
cp zeppelin-site.xml.template zeppelin-site.xml
cp shiro.ini.template shiro.ini

 

zeppelin-site.xml를 열어서 IP, PORT 설정을 해준다.

원하는 IP, PORT로 설정해줄 수 있는데, 외부에서 접속하기 위해서 IP는 0.0.0.0으로 했고,

PORT는 기본포트인 8080으로 했다.

<property>
  <name>zeppelin.server.addr</name>
  <value>0.0.0.0</value>
  <description>Server binding address</description>
</property>

<property>
  <name>zeppelin.server.port</name>
  <value>8080</value>
  <description>Server port.</description>
</property>

 

shiro.ini 설정을 해준다. 간단하게 접속 계정을 생성해준다고 생각하면 된다. role은 아래 설정을 참고하면 된다.

[users]
admin = [비밀번호], [role]
[계정] = [비밀번호], [role]

 

그리고 zeppelin-env.sh 설정을 해준다. 하둡을 연결하고 모듈을 연결해주면 되는데, spark를 연결하려고하면 다음과 같은 설정을 변경해준다. 값은 당연히 커스터마이징 해야 한다.
( http://zeppelin.apache.org/docs/0.8.2/interpreter/spark.html 참고)

export SPARK_HOME=/usr/lib/spark

# 아래 설정은 해도 되고 안해도 된다.
# set hadoop conf dir
export HADOOP_CONF_DIR=/etc/hadoop/conf

# set options to pass spark-submit command
export SPARK_SUBMIT_OPTIONS="--packages com.databricks:spark-csv_2.10:1.2.0"

# extra classpath. e.g. set classpath for hive-site.xml
export ZEPPELIN_INTP_CLASSPATH_OVERRIDES=/etc/hive/conf

 

그리고 yarn 모드는 다음과 같이 있는데, 적절한 것으로 선택한다. 보통 yarn-client나 yarn-cluster를 사용한다.

  • local[*] in local mode
  • spark://master:7077 in standalone cluster
  • yarn-client in Yarn client mode
  • yarn-cluster in Yarn cluster mode
  • mesos://host:5050 in Mesos cluster

java 설정이나 pyspark python 버전등을 바꾸려면 다음 설정등을 넣어줄 수 있다.

export MASTER=yarn-cluster

export JAVA_HOME=~/apps/jdk
export PYSPARK_PYTHON=/bin/python3

 

여기까지가 기본설정이며, 보통의 경우 위 설정만 해주면 zeppelin을 잘 사용할 수 있다.

 

다음은 kerberos가 적용된 hadoop Secure Mode일 때 설정이다. 다음 설정을 추가해준다.

# 위에서는 안해도 됐지만, 이번엔 해야한다.
export HADOOP_CONF_DIR=/etc/hadoop/conf

export KRB5_CONFIG=[krb 설정 경로]
export LIBHDFS_OPTS="-Djava.security.krb5.conf=${KRB5_CONFIG} -Djavax.security.auth.useSubjectCredsOnly=false"
export HADOOP_OPTS="-Djava.security.krb5.conf=${KRB5_CONFIG} -Djavax.security.auth.useSubjectCredsOnly=false ${HADOOP_OPTS}"

export ZEPPELIN_INTP_JAVA_OPTS="-Djava.security.krb5.conf=${KRB5_CONFIG} -Djavax.security.auth.useSubjectCredsOnly=false"
export JAVA_INTP_OPTS="-Djava.security.krb5.conf=${KRB5_CONFIG} -Djavax.security.auth.useSubjectCredsOnly=false ${JAVA_INTP_OPTS}"

# 경우에 따라 spark-submit 시에 아래 설정이 필요할 수 있다.
export SPARK_SUBMIT_OPTIONS="--keytab [keytab경로] --principal [principal]"

 

위에 있는 -Djavax.security.auth.useSubjectCredsOnly=false 옵션이 없으면 아래와 같은 에러가 발생할 수 있다.(이것때문에 시간을 많이 버렸다 ㅠ)

ERROR [2019-12-20 17:41:57,275] ({pool-2-thread-2} TSaslTransport.java[open]:315) - SASL negotiation failure
javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
        at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(GssKrb5Client.java:211)
        at org.apache.thrift.transport.TSaslClientTransport.handleSaslStartMessage(TSaslClientTransport.java:94)
        at org.apache.thrift.transport.TSaslTransport.open(TSaslTransport.java:271)
        at org.apache.thrift.transport.TSaslClientTransport.open(TSaslClientTransport.java:37)
        at org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport$1.run(TUGIAssumingTransport.java:52)
        at org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport$1.run(TUGIAssumingTransport.java:49)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:422)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1628)
        at org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport.open(TUGIAssumingTransport.java:49)
        at org.apache.hive.jdbc.HiveConnection.openTransport(HiveConnection.java:190)
        at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:163)
        at org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:105)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:208)
        at org.apache.commons.dbcp2.DriverManagerConnectionFactory.createConnection(DriverManagerConnectionFactory.java:79)
        at org.apache.commons.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:205)
        at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:861)
        at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435)
        at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
        at org.apache.commons.dbcp2.PoolingDriver.connect(PoolingDriver.java:129)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:270)
        at org.apache.zeppelin.jdbc.JDBCInterpreter.getConnectionFromPool(JDBCInterpreter.java:425)
        at org.apache.zeppelin.jdbc.JDBCInterpreter.access$000(JDBCInterpreter.java:91)
        at org.apache.zeppelin.jdbc.JDBCInterpreter$2.run(JDBCInterpreter.java:474)
        at org.apache.zeppelin.jdbc.JDBCInterpreter$2.run(JDBCInterpreter.java:471)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:422)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1628)
        at org.apache.zeppelin.jdbc.JDBCInterpreter.getConnection(JDBCInterpreter.java:471)
        at org.apache.zeppelin.jdbc.JDBCInterpreter.executeSql(JDBCInterpreter.java:692)
        at org.apache.zeppelin.jdbc.JDBCInterpreter.interpret(JDBCInterpreter.java:820)
        at org.apache.zeppelin.interpreter.LazyOpenInterpreter.interpret(LazyOpenInterpreter.java:103)
        at org.apache.zeppelin.interpreter.remote.RemoteInterpreterServer$InterpretJob.jobRun(RemoteInterpreterServer.java:632)
        at org.apache.zeppelin.scheduler.Job.run(Job.java:188)
        at org.apache.zeppelin.scheduler.ParallelScheduler$JobRunner.run(ParallelScheduler.java:162)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
        at sun.security.jgss.krb5.Krb5InitCredential.getInstance(Krb5InitCredential.java:147)
        at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:122)
        at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:187)
        at sun.security.jgss.GSSManagerImpl.getMechanismContext(GSSManagerImpl.java:224)
        at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:212)
        at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
        at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(GssKrb5Client.java:192)
        ... 43 more
 INFO [2019-12-20 17:41:57,278] ({pool-2-thread-2} HiveConnection.java[openTransport]:194) - Could not open client transport with JDBC Uri: jdbc:hive2://[hive주소]/;principal=hive/[principal주소]
ERROR [2019-12-20 17:41:57,278] ({pool-2-thread-2} JDBCInterpreter.java[getConnection]:478) - Error in doAs
java.lang.reflect.UndeclaredThrowableException
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1643)
        at org.apache.zeppelin.jdbc.JDBCInterpreter.getConnection(JDBCInterpreter.java:471)
        at org.apache.zeppelin.jdbc.JDBCInterpreter.executeSql(JDBCInterpreter.java:692)
        at org.apache.zeppelin.jdbc.JDBCInterpreter.interpret(JDBCInterpreter.java:820)
        at org.apache.zeppelin.interpreter.LazyOpenInterpreter.interpret(LazyOpenInterpreter.java:103)
        at org.apache.zeppelin.interpreter.remote.RemoteInterpreterServer$InterpretJob.jobRun(RemoteInterpreterServer.java:632)
        at org.apache.zeppelin.scheduler.Job.run(Job.java:188)
        at org.apache.zeppelin.scheduler.ParallelScheduler$JobRunner.run(ParallelScheduler.java:162)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.sql.SQLException: Could not open client transport with JDBC Uri: jdbc:hive2://[hive주소]/;principal=hive/[principal주소]: GSS initiate failed
        at org.apache.hive.jdbc.HiveConnection.openTransport(HiveConnection.java:215)
        at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:163)
        at org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:105)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:208)
        at org.apache.commons.dbcp2.DriverManagerConnectionFactory.createConnection(DriverManagerConnectionFactory.java:79)
        at org.apache.commons.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:205)
        at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:861)
        at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435)
        at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
        at org.apache.commons.dbcp2.PoolingDriver.connect(PoolingDriver.java:129)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:270)
        at org.apache.zeppelin.jdbc.JDBCInterpreter.getConnectionFromPool(JDBCInterpreter.java:425)
        at org.apache.zeppelin.jdbc.JDBCInterpreter.access$000(JDBCInterpreter.java:91)
        at org.apache.zeppelin.jdbc.JDBCInterpreter$2.run(JDBCInterpreter.java:474)
        at org.apache.zeppelin.jdbc.JDBCInterpreter$2.run(JDBCInterpreter.java:471)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:422)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1628)
        ... 14 more
Caused by: org.apache.thrift.transport.TTransportException: GSS initiate failed
        at org.apache.thrift.transport.TSaslTransport.sendAndThrowMessage(TSaslTransport.java:232)
        at org.apache.thrift.transport.TSaslTransport.open(TSaslTransport.java:316)
        at org.apache.thrift.transport.TSaslClientTransport.open(TSaslClientTransport.java:37)
        at org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport$1.run(TUGIAssumingTransport.java:52)
        at org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport$1.run(TUGIAssumingTransport.java:49)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:422)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1628)
        at org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport.open(TUGIAssumingTransport.java:49)
        at org.apache.hive.jdbc.HiveConnection.openTransport(HiveConnection.java:190)
        ... 33 more
 INFO [2019-12-20 17:41:57,285] ({pool-2-thread-2} SchedulerFactory.java[jobFinished]:120) - Job 20191220-170645_132084413 finished by scheduler org.apache.zeppelin.jdbc.JDBCInterpreter1849124988

 

그리고, ${SPARK_HOME}/conf/spark-defaults.conf 에 kerberos 설정을 넣어준다.

spark.yarn.principal
spark.yarn.keytab

위 설정이 잘 적용되는지 확인해봐야 한다. 만약 안될 시에는 zeppelin interpreter 설정에 추가해준다.

댓글()

javascript 빈 값, null, undefind 구분 함수

IT기술/javascript, python|2021. 1. 15. 23:48

2019-12-24 작성

 

javascript를 사용하다보면, string 빈 값과 null과 undefind 등을 한번에 구분할 수 있는 로직이 필요할 때가 있다. 나도 어디선가 퍼온 로직인데 유용하게 사용할 수 있다. 사용방법은 함수 isEmpty("[확인하고 싶은 값]")를 호출하면 된다.

var isEmpty = function(value){
	if( value == "" || value == null || value == undefined || ( value != null && typeof value == "object" && !Object.keys(value).length ) ){ 
		return true;
	} else {
		return false;
	}
};

댓글()

hadoop security distcp 시 SIMPLE authentication error(distcp hadoop secure insecure)

IT기술/hadoop family|2021. 1. 15. 23:47

2019-12-24 작성

 

Server asks us to fall back to SIMPLE auth, but this client is configured to only allow secure connections
SIMPLE authentication is not enabled. Available:[TOKEN, KERBEROS]

 

hadoop security를 구성한 후에 위와 같이 SIMPLE authentication 오류가 발생할 수 있다. SIMPLE authentication이 허용되어 있지 않아서 발생한 내용인데, 다음 설정을 core-site.xml에 넣어주면 해결된다.

클라우데라에서는 다음과 같이 설정한다.

<property>
  <name>ipc.client.fallback-to-simple-auth-allowed</name>
  <value>true</value>
</property>

https://docs.cloudera.com/documentation/enterprise/5-16-x/topics/cdh_admin_distcp_secure_insecure.html

댓글()

zeppelin에 jdbc interpreter 설정하기(apache hive 기준)

IT기술/hadoop family|2021. 1. 15. 23:45

2019-12-20 작성

 

기본설정

  • cloudera 5.16.2
  • kerberos enabled security hadoop

사실 일반 하둡에서 interpreter는 거의 가이드가 하라는 대로 하면 된다.
http://zeppelin.apache.org/docs/0.8.2/interpreter/jdbc.html

(웬만한 jdbc interpreter는 이걸 보고 하길 바란다)

 

INTERPRETER 추가

1. 먼저 zeppelin에 접속 후 interpreter 메뉴에서 create를 클릭한다.

2. interpreter 이름을 정하고 group는 jdbc로 설정한다.

3. interpreter 관련한 설정을 한다. apache hive를 기준으로 설명하면, 다음과 같이 properties를 입력한다.

Properties

Name Value
default.driver org.apache.hive.jdbc.HiveDriver
default.url jdbc:hive2://localhost:10000
default.user hive_user
default.password hive_password
default.proxy.user.property Example value: hive.server2.proxy.user

Dependencies

Artifact Excludes
org.apache.hive:hive-jdbc:0.14.0  
org.apache.hadoop:hadoop-common:2.6.0  

hive url은 설치 서버에서 접속 가능하도록 수정해주고, dependencies도 version을 수정해준다.

이때 dependencies는 jar 파일을 다음 경로에 넣어야 한다.
$ZEPPELIN_HOME/interpreter/jdbc/

 

가이드에서는 jar 파일을 다운 받을 수 있는 페이지( Maven Repository : org.apache.hive:hive-jdbc)를 안내하고 있다. cloudera 기준으로는 다음 명령으로 파일을 복사할 수 있다.

cp /opt/cloudera/parcels/CDH/jars/hive-jdbc* $ZEPPELIN_HOME/interpreter/jdbc/
cp /opt/cloudera/parcels/CDH/jars/hadoop-common* $ZEPPELIN_HOME/interpreter/jdbc/

그 다음 zeppelin을 재시작하면 기본 적인 것은 끝이다.

계속 추가 예정..

댓글()

docker로 mysql 5.7 설치하기

IT기술/cloud, docker|2021. 1. 15. 23:35

2019-12-18 작성

 

업무용 pc에 개발환경을 구축할 필요가 있어서 mysql을 설치하려고 보니,

docker가 쉬울 것 같아서 docker로 설치해본다. 아래와 같이 실행하면 root 비밀번호 없이 mysql이 설치된다.

docker run -d --name mysql -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7

-p는 대응할 port 옵션이다. [접속 원하는포트]:3306으로 입력하면 된다.
-e는 환경변수
마지막 mysql:5.7은 이미지 이름이다.
mysql db 파일을 로컬에 저장해두고 싶다면 아래와 같이 -v옵션을 사용할 수도 있다.
-v [로컬경로]:/var/lib/mysql

 

-e 옵션을 주지 않으면 다음과 같이 에러 메시지가 표시되는데, 원하는 비밀번호 형식에 따라서 -e 옵션을 바꿔줄 수 있다.

You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD

설치 후 mysql workbench를 통해서 접속할 수 있다.

댓글()

pyspark parquet file 읽어오기

IT기술/hadoop family|2021. 1. 15. 23:26

2019-12-12 작성

 

jupyter notebook에서 pyspark를 사용해 parquet file을 읽어 올 때 가장 기본이 되는 code이다. 실제 pyspark shell에서는 import 등의 내용이 필요 없을 수 있다.

 

import pyspark
from pyspark.sql import SQLContext

sc = pyspark.SparkContext.getOrCreate()
sqlContext = SQLContext(sc)
df = sqlContext.read.parquet('[parquet 경로]')
df.show()

sc.stop()

댓글()

python 임시 테스트 서버 실행하기

IT기술/javascript, python|2021. 1. 15. 23:25

2019-12-12 작성

 

다음과 같이 python(혹은 ruby, nodejs)으로 임시, 테스트 서버를 실행할 수 있다.
실행하면 실행하는 디렉토리를 기준으로 웹서버가 실행된다.

 

python -m SimpleHTTPServer
python3 -m http.server

댓글()

docker nginx로 http static file listing/download server 만들기

IT기술/cloud, docker|2021. 1. 15. 23:21

2019-12-05 작성

 

file download server가 필요할 때가 있다. 일시적으로 사용할 때는

다음과 같이 python(혹은 ruby, nodejs) 서버를 사용한다.

python -m SimpleHTTPServer
python3 -m http.server

하지만 file server를 유지해야할 때는 test서버를 쓰기가 좀 그렇다.(nohup 명령어를 사용해서 계속 사용할 수는 있다..)

 

그래서 여러가지 방안을 고민해봤는데(samba, linux repo 등), 용도가 http download라면 웹서버가 가장 쉬운 것 같다. 그래서 쉽게 docker nginx container를 사용하려고 하니 docker Nginx Official 페이지에 다음과 같이 simple static content를 위한 명령어가 설명돼 있다.

 

서버에서 아래와 같이 실행 하고 [/내경로]에 파일을 저장하면 "http://ip:port/파일명"으로 파일을 다운 받을 수 있게 된다. 그러면 다운로드 서버는 끝.

$ docker run --name nginx -v [/내경로]:/usr/share/nginx/html:ro -d -p [내포트]:80 nginx

 

그 다음, [/내경로]에 있는 파일 목록을 웹상에서 보고 싶다.
우선 docker nginx container에 접속해 vim을 설치한다.

$ docker exec -it [container_name] bash
$ apt-get update
$ apt-get upgrade
$ apt-get install vim

 

그 다음 nginx 설정 파일을 아래과 같이 수정한다.

vim /etc/nginx/nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    ###### 여기가 핵심
    server {
        location / {
            root /usr/share/nginx/html;
            autoindex on;
        }
    }
    ######

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

변경 후 nginx에 설정을 적용해준다.

$ nginx -t # 설정 테스트
$ nginx -s reload # 설정 반영

 

그러면 "http://ip:port/ "에서 file 목록을 확인할 수 있다. 만약 보안 문제로 목록을 보고 싶지 않다면 autoindex off로 변경한다.

 

참고사이트: https://blog.leocat.kr/notes/2018/01/08/nginx-simple-file-listing-server

'IT기술 > cloud, docker' 카테고리의 다른 글

AWS boto3 시작하기  (0) 2021.01.16
docker로 mysql 5.7 설치하기  (0) 2021.01.15

댓글()