org.apache.hadoop.ipc.RemoteException: No lease on /google/public_plus/20181127/23_merged (inode 2683729964): File does not exist. [Lease.  Holder: DFSClient_NONMAPREDUCE_-39928930_1, pending creates: 8]





하둡 소스를 보면, 파일이 없거나 디렉토리이면 위의 에러가 발생한다. lease 이슈는 아니다..




https://github.com/facebookarchive/hadoop-20/blob/master/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java#L3105


private void checkLease(String src, String holder, INode file) 

                                                     throws IOException {


    if (file == null || file.isDirectory()) {

      Lease lease = leaseManager.getLease(holder);

      throw new LeaseExpiredException("No lease on " + src +

                                      " File does not exist. " +

                                      (lease != null ? lease.toString() :

                                       "Holder " + holder + 

                                       " does not have any open files"));

    }




참고로 lease는 write lock과 비슷한 개념이다.


Leases

In HDFS these locks are called Leases. Leases are granted to a client which request to open a file for a write operation (e.g. create / append / truncate a file.) 


https://www.raviprak.com/research/hadoop/leaseManagement.html






사실 생각해보면. 실제로 있어야 하는데 존재했다가 삭제된 것이다. 


이는 병렬 이슈인 것이다.


https://stackoverflow.com/questions/7559880/leaseexpiredexception-no-lease-error-on-hdfs




spark이라면. 다음과 같이 설정을 해서 speculative optimization 알고리즘(병렬)을 끄도록 한다.



sparkConf.set("spark.speculation", "false");

sparkConf.set("spark.hadoop.mapreduce.map.speculative", "false");

sparkConf.set("spark.hadoop.mapreduce.reduce.speculative", "false")



hive라면 다음과 같은 설정을 진행한다. 



set mapreduce.map.speculative=false;

set mapreduce.reduce.speculative=false;

set hive.mapred.reduce.tasks.speculative.execution=false;

Posted by '김용환'
,

Database Class Loader started - derby.database.classpath=''

18/11/29 22:05:54 ERROR PoolWatchThread: Error in trying to obtain a connection. Retrying in 7000ms

java.sql.SQLException: A read-only user or a user in a read-only database is not permitted to disable read-only mode on a connection.

at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)

at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)

at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)

at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)

at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)

at org.apache.derby.impl.jdbc.EmbedConnection.setReadOnly(Unknown Source)

at com.jolbox.bonecp.ConnectionHandle.setReadOnly(ConnectionHandle.java:1324)

at com.jolbox.bonecp.ConnectionHandle.<init>(ConnectionHandle.java:262)

at com.jolbox.bonecp.PoolWatchThread.fillConnections(PoolWatchThread.java:115)

at com.jolbox.bonecp.PoolWatchThread.run(PoolWatchThread.java:82)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at java.lang.Thread.run(Thread.java:745)

Caused by: ERROR 25505: A read-only user or a user in a read-only database is not permitted to disable read-only mode on a connection.

at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)

at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)

at org.apache.derby.impl.sql.conn.GenericAuthorizer.setReadOnlyConnection(Unknown Source)

at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.setReadOnly(Unknown Source)




원인은 권한이다. spark-shell의 권한이 root 또는  metastore_db 디렉토리의 권한을 확인한다.

Posted by '김용환'
,



kubernetes에서 cronjob 실행하기 


$ vi cronjob.yaml

apiVersion: batch/v1beta1

kind: CronJob

metadata:

  name: sleepy

spec:

  schedule: "*/1 * * * *"

  jobTemplate:

    spec:

      template:

        spec:

          containers:

          - name: resting

            image: busybox

            command: ["/bin/sleep"]

            args: ["3"]

          restartPolicy: Never





$ kubectl create -f cronjob.yaml

cronjob.batch/sleepy created





시간에 따라 확인한다.



$ kubectl get cronjobs.batch

NAME      SCHEDULE      SUSPEND   ACTIVE    LAST SCHEDULE   AGE

sleepy    */1 * * * *   False     0         <none>          40s



$ kubectl get cronjobs.batch

NAME      SCHEDULE      SUSPEND   ACTIVE    LAST SCHEDULE   AGE

sleepy    */1 * * * *   False     0         1m              2m




Posted by '김용환'
,


kubernetes에서 proxy 사용 예시이다



$ kubectl proxy --api-prefix=/ &

[1] 9789

Starting to serve on 127.0.0.1:8001





$ curl http://127.0.0.1:8001/api/

{

  "kind": "APIVersions",

  "versions": [

    "v1"

  ],

  "serverAddressByClientCIDRs": [

    {

      "clientCIDR": "0.0.0.0/0",

      "serverAddress": "10.1.1.1:6443"

    }

  ]






$ curl http://127.0.0.1:8001/api/v1/namespaces
{
"kind": "NamespaceList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/namespaces",
"resourceVersion": "445783"
"items": [
    {
      "metadata": {
        "name": "default",
        "selfLink": "/api/v1/namespaces/default",
        "uid": "8fd4381e-f15f-11e8-8c69-fa163ec1822d",
        "resourceVersion": "5",
        "creationTimestamp": ",.,,,17Z"
      },
      "spec": {
        "finalizers": [
          "kubernetes"
        ]
      },
      "status": {
        "phase": "Active"
      }
    },
    {
      "metadata": {
        "name": "ingres

...

Posted by '김용환'
,



다음은 kubernetes의 discovery 예시이다.




$ kubectl config view

apiVersion: v1

clusters:

- cluster:

certificate-authority-data: REDACTED

server: https://10.1.1.1:6443

name: kubernetes

...




$ kubectl get secrets

NAME                  TYPE                                  DATA      AGE

default-token-686zl   kubernetes.io/service-account-token   3         3d





$ kubectl describe secret default-token-686zl

Name:         default-token-686zl

Namespace:    default

Labels:       <none>

Annotations:  kubernetes.io/service-account.name=default

              kubernetes.io/service-account.uid=a0b98cf2-f15f-11e8-9449-fa163e9f27a5


Type:  kubernetes.io/service-account-token


Data

====

ca.crt:     1090 bytes

namespace:  7 bytes

token:      xxxx



$ export token=$(kubectl describe secret default-token-686zl |grep ^token |cut -f7 -d ' ')



$ echo $token

xxx



$ curl https://10.1.1.1:6443/apis --header "Authorization: Bearer $token" -k

{

"kind": "APIVersions",

"versions": [

"v1"

],

"serverAddressByClientCIDRs": [

{

"clientCIDR": "0.0.0.0/0",

"serverAddress": "10.1.1.1:6443"

}

]

}

...



이전 결과와 동일하다. 



$ curl https://10.128.0.3:6443/api/v1 --header "Authorization: Bearer $token" -k


{

"kind": "APIVersions",

"versions": [

"v1"

],

"serverAddressByClientCIDRs": [

{

"clientCIDR": "0.0.0.0/0",

"serverAddress": "10.1.1.1:6443"

}

]

}

...




Posted by '김용환'
,



열심히 일했던 카카오의 한 동료가 여의치 않게 퇴사하게 되었다. (1년 조금 안되게 함께 일했던 것 같다.)


하지만 능력있던 그 동료가 소설가로 신인상을 받게 되었다. 


너무 축하해 주고 싶다!!!!!


앞으로 계속 잘 되시기를!!!!


앞으로 책 나오면 잘 볼께요~






http://www.changbi.com/archives/76278?cat=3378


– 제21회 창비신인소설상

사진_장류진_c수상작: 장류진(張琉珍) 「일의 기쁨과 슬픔」

수상자 약력: 1986년생. 연세대 사회학과 졸업, 동국대 대학원 국어국문학과 수료

심사위원: 기준영 김성중(이상 소설가) 박인성 한영인 황정아(이상 문학평론가)

 

선정 이유: 「일의 기쁨과 슬픔」은 짧고 기민하게 잽을 날리는 가벼운 스텝의 복서를 연상케 한다. 회장의 심기를 거스르는 바람에 월급을 전액 카드 포인트로 받게 된 ‘거북이알’이 다시 포인트를 돈으로 전환하기 위해 중고거래에 나선다는 설정은 한숨이 나올 만큼 ‘웃픈’ 이야기지만 재벌총수가의 물의가 연일 보도되는 현실의 거울에 비추어보면 허무맹랑한 소리만은 아니다. 인물들이 나란히 판교 엔씨소프트 사옥 너머로 네모난 하늘을 바라보는 장면에서 보이듯 작품에 묘한 청량감이 있다고 할까. 꽉 짜인 로직을 뚫고 한줄기 바람이 통과하는 듯한, 세상은 만만치 않고 어이없는 일투성이지만 그 안에서 ‘소확행’이든 무엇이든 자기만의 방식으로 적응해나가는 청년세대의 기쁨과 슬픔이 생생하다.




소설 내용은 아래 링크..


https://magazine.changbi.com/q_posts/%EC%9D%BC%EC%9D%98-%EA%B8%B0%EC%81%A8%EA%B3%BC-%EC%8A%AC%ED%94%94/?board_id=2659






Posted by '김용환'
,



namespace에 자원 제한(reousrce limit) 예시



 low-usage-limit name space를 생성한다.


$ kubectl create namespace low-usage-limit

namespace/low-usage-limit created



$ kubectl get namespace

NAME              STATUS    AGE

default           Active    1h

ingress-nginx     Active    1h

kube-public       Active    1h

kube-system       Active    1h

low-usage-limit   Active    19s



자원 제한 정보를 설정한다.



$ vi low-resource-range.yaml


apiVersion: v1

kind: LimitRange

metadata:

  name: low-resource-range

spec:

  limits:

  - default:

      cpu: 1

      memory: 500Mi

    defaultRequest:

      cpu: 0.5

      memory: 100Mi

    type: Container





아래와 같이 진행하면 실행되지 않는다.


$ kubectl create -f low-resource-range.yaml --namespace=low-usage-limit



$ kubectl get LimitRange --all-namespaces

NAMESPACE         NAME                 AGE

low-usage-limit   low-resource-range   1m



$ kubectl get LimitRange




namespace이름을 넣어주고 새로운 deployment를 생성한다. 


$ kubectl create deployment limited-hog --image vish/stress -n low-usage-limit




참고로 삭제할 때도 namespace를 줘야 삭제된다. 


$ kubectl delete deployment limited-hog -n low-usage-limit

deployment.extensions "limited-hog" deleted


$ kubectl delete deployment limited-hog

Error from server (NotFound): deployments.extensions "limited-hog" not found




제대로 실행되었다면. low-usage-limit   limited-hog  의 available이 0이 되지 않을 것이다. (마침 1이다.)


$ kubectl get deployments --all-namespaces

NAMESPACE         NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE

default           hog                    1         1         1            1           15m

kube-system       kube-dns               2         2         2            2           1h

kube-system       kubedns-autoscaler     1         1         1            1           1h

kube-system       kubernetes-dashboard   1         1         1            1           1h

kube-system       tiller-deploy          1         1         1            1           1h

low-usage-limit   limited-hog            1         1         1            1           37s



제대로 실행 중이다. 만약 deployment가 잘못 되었다면 STATUS에 잘 표시될 것이다 .


$ kubectl -n low-usage-limit get pods

NAME                           READY     STATUS    RESTARTS   AGE

limited-hog-757fc847ff-mvm7s   1/1       Running   0          1m




pod 설정을 yaml로 보면 제대로 되어 있다. 


$ kubectl -n low-usage-limit get pod limited-hog-757fc847ff-mvm7s -o yaml





 resources:

      limits:

        cpu: "1"

        memory: 500Mi

      requests:

        cpu: 500m

        memory: 100Mi




deployment를 수정해 namespace를 적용한다.


$ kubectl get deployment hog --export -o yaml > new-hog.yaml



namespace: low-usage-limit를 추가하고 deploy한다.


$ vi new-hog.yaml


  labels:

    app: hog

  name: hog

  namespace: low-usage-limit



$ kubectl create -f new-hog.yaml



$ get deployments --all-namespaces

NAMESPACE         NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE

default           hog                    1         1         1            1           23m

kube-system       kube-dns               2         2         2            2           1h

kube-system       kubedns-autoscaler     1         1         1            1           1h

kube-system       kubernetes-dashboard   1         1         1            1           1h

kube-system       tiller-deploy          1         1         1            1           1h

low-usage-limit   hog                    1         1         1            1           40s

low-usage-limit   limited-hog            1         1         1            1           8m




work장비에 들어가서 보면 메모리를 12% 쓰고 있다. 


  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND

30062 root      20   0  960872 954176   3120 S 101.0 11.7  26:52.72 stress

 1126 root      20   0  960104 954108   3180 S 100.3 11.7   3:53.52 stress





정리한다.


$ kubectl -n low-usage-limit delete deployment hog

deployment.extensions "hog" deleted

$ kubectl delete deployment hog

deployment.extensions "hog" deleted







출처 : linux foundation kubernetes 예시







Posted by '김용환'
,


적당한 이미지를 deploy한다.



$ kubectl create deployment hog --image vish/stress

deployment.apps/hog created





$ kubectl get deployments

NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE

hog       1         1         1            1           7m





$ kubectl describe deployment hog

Name:                   hog

Namespace:              default

CreationTimestamp:      Mon, 26 Nov 2018 20:32:09 +0900

Labels:                 app=hog

Annotations:            deployment.kubernetes.io/revision=2

Selector:               app=hog

Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable

StrategyType:           RollingUpdate

MinReadySeconds:        0

RollingUpdateStrategy:  25% max unavailable, 25% max surge

Pod Template:

  Labels:  app=hog

  Containers:

   stress:

    Image:      vish/stress

    Port:       <none>

    Host Port:  <none>

    Environment:  <none>

    Mounts:       <none>

  Volumes:        <none>

Conditions:

  Type           Status  Reason

  ----           ------  ------

  Available      True    MinimumReplicasAvailable

  Progressing    True    NewReplicaSetAvailable

OldReplicaSets:  <none>

NewReplicaSet:   hog-58d797c5d8 (1/1 replicas created)

Events:

  Type    Reason             Age   From                   Message

  ----    ------             ----  ----                   -------

  Normal  ScalingReplicaSet  8m    deployment-controller  Scaled up replica set hog-5cc4fdb68 to 1

  Normal  ScalingReplicaSet  2m    deployment-controller  Scaled up replica set hog-58d797c5d8 to 1

  Normal  ScalingReplicaSet  2m    deployment-controller  Scaled down replica set hog-5cc4fdb68 to 0




이를 yaml로 변경할 수 있다. 배포형태로 변경 가능하다.



$ kubectl get deployment hog -o yaml

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  annotations:

    deployment.kubernetes.io/revision: "2"

  creationTimestamp: 2018-11-26T10:32:09Z

  generation: 2

  labels:

    app: hog

  name: hog

  namespace: default

  resourceVersion: "6576"

  selfLink: /apis/extensions/v3/namespaces/default/deployments/hog

  uid: 873e80d8-f166-11e8-9a46-fa163e964181

spec:

  progressDeadlineSeconds: 600

  replicas: 1

  revisionHistoryLimit: 10

  selector:

    matchLabels:

      app: hog

  strategy:

    rollingUpdate:

      maxSurge: 25%

      maxUnavailable: 25%

    type: RollingUpdate

  template:

    metadata:

      creationTimestamp: null

      labels:

        app: hog

    spec:

      containers:

      - image: vish/stress

        imagePullPolicy: Always

        name: stress

        resources: {}

        terminationMessagePath: /dev/termination-log

        terminationMessagePolicy: File

      dnsPolicy: ClusterFirst

      restartPolicy: Always

      schedulerName: default-scheduler

      securityContext: {}

      terminationGracePeriodSeconds: 30

status:

  availableReplicas: 1

  conditions:

  - lastTransitionTime: 2018-11-26T10:32:15Z

    lastUpdateTime: 2018-11-26T10:32:15Z

    message: Deployment has minimum availability.

    reason: MinimumReplicasAvailable

    status: "True"

    type: Available

  - lastTransitionTime: 2018-11-26T10:32:09Z

    lastUpdateTime: 2018-11-26T10:38:33Z

    message: ReplicaSet "hog-58d797c5d8" has successfully progressed.

    reason: NewReplicaSetAvailable

    status: "True"

    type: Progressing

  observedGeneration: 2

  readyReplicas: 1

  replicas: 1

  updatedReplicas: 1



설정 파일을 다운받고 deployment를 다시 진행한다.



$ kubectl get deployment hog --export -o yaml > hog.yaml


$ vi hog.yaml


resources: {} 부분을 다음과 같이 변경한다


resources: 

  limits:

    memory: "4Gi"

  requests:

    memory: "2500Mi"





이제 변경된 내용으로 배포한다.



$ kubectl replace -f hog.yaml



반영된 부분을 확인할 수 있다. 


$ kubectl get deployment hog -o yaml


  resources:

          limits:

            memory: 4Gi

          requests:

            memory: 2500Mi



pod는 잘 동작하고 있다.



$ kubectl get po

NAME                   READY     STATUS    RESTARTS   AGE

hog-58d797c5d8-r5lvd   1/1       Running   0          9m

$ kubectl logs hog-58d797c5d8-r5lvd

I1126 10:38:33.299667       1 main.go:26] Allocating "0" memory, in "4Ki" chunks, with a 1ms sleep between allocations

I1126 10:38:33.299827       1 main.go:29] Allocated "0" memory




자원 스트레스를 주기 위해 resources 설정을 변경한다.



        resources:

          limits:

            cpu: "1"

            memory: "4Gi"

          requests:

            cpu: "0.5"

            memory: "500Mi"

        args:

        - -cpus

        - "2"

        - -mem-total

        - "950Mi"

        - -mem-alloc-size

        - "100Mi"

        - -mem-alloc-sleep

        - "1s"



그리고 deployment을 삭제하고 생성한다.


$ kubectl delete deployment hog

deployment.extensions "hog" deleted


$ kubectl apply -f hog.yaml

deployment.extensions/hog created


$ kubectl get pod

NAME                  READY     STATUS    RESTARTS   AGE

hog-786d4f7b8-mccsn   1/1       Running   0          44s


$ kubectl logs hog-786d4f7b8-mccsn

I1126 10:51:52.311973       1 main.go:26] Allocating "950Mi" memory, in "100Mi" chunks, with a 1s sleep between allocations

I1126 10:51:52.312143       1 main.go:39] Spawning a thread to consume CPU

I1126 10:51:52.312179       1 main.go:39] Spawning a thread to consume CPU

I1126 10:52:05.368902       1 main.go:29] Allocated "950Mi" memory






출처 : linux foundation 공부 자료에서 

Posted by '김용환'
,



LB를 잘 모르는 개발자가 있어서 링크를 모았다.


개발자가 LB 장비를 이해하면 개발 아키텍처에 도움이 될 뿐 아니라

시스템 엔지니어/네트워크 엔지니어가 무엇을 하는지 많은 도움이 된다.




L4 스위치의 inline, DSR 비교


http://travelc.tistory.com/82





DSR과 헬쓰체크

(카카오 그림이지만 네이버와 거의 비슷하다고 볼 수 있다)

http://tech.kakao.com/2014/05/28/l3dsr/






GSLB

https://www.netmanias.com/ko/post/blog/5620/dns-data-center-gslb-network-protocol/global-server-load-balancing-for-enterprise-part-1-concept-workflow


트래픽이 많은 큰회사가 많이 사용한다.


(예, 네이버)



$ nslookup www.naver.com

Server: 10.20.30.60

Address: 10.20.30.60#53


Non-authoritative answer:

www.naver.com canonical name = www.naver.com.nheos.com.

Name: www.naver.com.nheos.com

Address: 210.89.164.90

Name: www.naver.com.nheos.com

Address: 125.209.222.141



Posted by '김용환'
,


쿠버네티스 네트워킹(kubernetes networking)에 대한 쉬운 이해와 문서를 모아둠



이 문서를 가장 먼저 보길 바란다.


https://www.level-up.one/kubernetes-networking-pods-levelup/


https://www.level-up.one/kubernetes-networking-series-two/


https://www.level-up.one/kubernetes-networking-3-level-up/





그 다음에는 아래 문서를 보고.


https://speakerdeck.com/thockin/illustrated-guide-to-kubernetes-networking



이 문서를 보면 더욱 도움 될 것이다.



https://medium.com/@ApsOps/an-illustrated-guide-to-kubernetes-networking-part-1-d1ede3322727


https://medium.com/@ApsOps/an-illustrated-guide-to-kubernetes-networking-part-2-13fdc6c4e24c










쿠버네티스 정식 문서


https://kubernetes.io/docs/concepts/cluster-administration/networking/






참고로 오픈 스택 네트워킹(provider network, vlan, tunneling, north/south&east/west)애 대한 개념이 생길 것이다.


https://keithtenzer.com/2016/07/18/openstack-networking-101-for-non-network-engineers/

Posted by '김용환'
,