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 김용환 '김용환'



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 김용환 '김용환'

쿠버네티스 + 스파크 예시


https://weidongzhou.wordpress.com/2018/04/29/running-spark-on-kubernetes/



https://medium.com/@timfpark/cloud-native-big-data-jobs-with-spark-2-3-and-kubernetes-938b04d0da57




Posted by 김용환 '김용환'



쿠버네티스의 service discovery 컴포넌트로 istio와 linkered가 있는데.. 


https://linkerd.io/ 는 version 1(https://github.com/linkerd/linkerd)은 스칼라로 개발되었는데..


version2(https://github.com/linkerd/linkerd2)부터는 go언어로 개발되었다.




go로 간 이유는 성능적인 요소와 쿠버네티스 생태계에 가까워지기 위함이라고 한다.




참고




https://www.sdxcentral.com/articles/news/linkerd-2-0-update-moves-closer-to-kubernetes/2018/09/

Posted by 김용환 '김용환'


쿠버네티스(kubernetes)에서 pods를 재시작하고 싶을 때가 있다.  



kubectl create -f x.yaml


전체 컴포넌트를 시작한다.



kubectl replace -f x.yaml

x.yaml에 변경사항 있으면 반영하면서 재시작. 변경사항없으면 유지




kubectl replace --force -f x.yaml <- x.yaml 변경사항과 상관없이 재시작


kubectl edit ds APP => env 에 값 추가

kubectl patch deployment prometheus-deployment -p \

  "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"`date +'%s'`\"}}}}}"

  

replicaSet 구성했다면 kubectl get pods 한 후, kubectl delete pods-id하면 된다.

  

Posted by 김용환 '김용환'





jenkins를 docker로 말아 올릴 때(jenkins Dockerfile 사용) 치명적인 이슈는 모든 environment variable을 사용할 수 없을 수 있다. 


동작할 것이라 생각한 두개의 변수는 비어 있었다.

BUILD_URL

JENKINS_URL_VALUE




Manager Jenkins->Configure System ( $jenkin-url:8080/configure) 에 접속해서 

Global properties의 Envrioment variables를 임의로 추가했더니..



BUILD_URL, JENKINS_URL_VALUE를 jenkins에서 읽어온다. 



Posted by 김용환 '김용환'


ubuntu 장비에서 진행했고,


master만 jenkins-docker를 사용하고, slave는 간단하게 기존처럼 실행(java 설치, 디폴트 디렉토리는 /var/lib/jenkins)가 되도록 했다.


jenkins master 장비에 docker를 실행할 때 최신 docker 18.06.ce 버전을 사용했고,


2.141 버전을 사용했다.


jenkins dockerfile은 https://github.com/jenkinsci/docker/blob/master/Dockerfile 에 있고,





< 주의 사항>


1. 백업은 필수 


docker가 죽어도 파일 시스템은 살아야 하니, 호스트 장비에 파일 시스템을 두었다. credentials이나 ssh, slave 설정, 추가 플러그인은 호스트 장비에 두어야 마음이 편할 것이다. (하지만 항상 백업하는 것이 중요하다. 자칫 잘못하면 도커 볼륨에 연결된 파일들이 모두 초기화될 수 있다) 


docker rm container_id 커맨드가 대표적이다.



2. jenkins-docker의 내부 홈 디렉토리는 /var/jenkins_home 이다.



3. docker volume 설정을 잘 적용한다.

ssh 설정, jenkins 홈 디렉토리를 docker외부에서 접근할 수 있도록 한다.


 -v  /home/www/.ssh/:/var/jenkins_home/.ssh




예를 들어 여러 개의 docker volumne을 설정하고 싶을 수 있다. 

ssh 설정은 docker host의 ssh 설정을 사용하고, docker의 timezone을 docker host의 timzezone 설정을 사용하도록 하고 jenkins 홈 디렉토리를 docker host의 디렉토리를 가르키게 하려면 다음을 실행한다.


sudo docker run --name google-jenkins-master -d  -v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime -v /var/lib/jenkins:/var/jenkins_home -v  /home/www/.ssh/:/var/jenkins_home/.ssh -p 8080:8080 hub/google-jenkins-docker






4. 기본 계정은 Dockerfile에서 정의한다.

dockerfile 생성할 때 ADMIN_USERNAME, ADMIN_PASSWORD가 기본 패스워드이다. 


ENV JAVA_OPTS="-Djenkins.install.runSetupWizard=false" \

    ADMIN_USERNAME="google" \

    ADMIN_PASSWORD="google" \

...




5. 참고할 만한 dockerfile 설정은 다음과 같다. 



ENV JENKINS_FOLDER /usr/share/jenkins

USER ROOT


COPY plugins.txt "${JENKINS_FOLDER}/ref/plugins.txt"

COPY setupSecurity.groovy "${JENKINS_FOLDER}/ref/init.groovy.d/setupSecurity.groovy"

COPY setupProxy.groovy "${JENKINS_FOLDER}/ref/init.groovy.d/setupProxy.groovy"

COPY executors.groovy "${JENKINS_FOLDER}/ref/init.groovy.d/executors.groovy"

RUN /usr/local/bin/install-plugins.sh < "${JENKINS_FOLDER}/ref/plugins.txt"



6. 플러그인 추려내기

아래를 참조해서 잘 알아낸다. 실제 알고 있던 플러그인 이름이 plugins.txt 파일의 이름과 정확히 매칭되지 않으니.. 좀 시도해야 봐야 감이 잡힌다.

https://github.com/fabric8io/jenkins-docker/blob/master/plugins.txt



7.시작할 때 다음 url을 참고한다. 


https://github.com/jenkinsci/docker/blob/master/README.md

Posted by 김용환 '김용환'



쿠버네티스에 배포한후 pods 상태가 이상하다.


$ kubectl apply -f deployment.yaml



$ kubectl get pods

NAME                          READY     STATUS             RESTARTS   AGE

oncall-api-79f79c5bdf-cltxk   0/1       CrashLoopBackOff   7          12m





다시 배포해도 동일한 문제가 발생한다.




문제를 해결할려면 kubectl describe와 kubectl log 커맨드를 사용한다.




$ kubectl describe pods


...

    Port:           5000/TCP

    Host Port:      0/TCP

    State:          Waiting

      Reason:       CrashLoopBackOff

    Last State:     Terminated

      Reason:       Error

      Exit Code:    139

      Started:      Tue, 11 Sep 2018 20:15:41 +0900

      Finished:     Tue, 11 Sep 2018 20:15:41 +0900

    Ready:          False

    Restart Count:  7

    Requests:

      cpu:        500m

      memory:     900Mi

    Environment:  <none>


..

Events:

  Type     Reason                 Age                From                             Message

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

  Normal   Scheduled              15m                default-scheduler                Successfully assigned ...

  Normal   SuccessfulMountVolume  15m                kubelet, ...

  Normal   Pulled                 13m (x5 over 15m)  kubelet, ....

  Normal   Created                13m (x5 over 15m)  kubelet, ...

  Normal   Started                13m (x5 over 15m)  kubelet, Started container

  Warning  BackOff                7s (x70 over 15m)  kubelet, Back-off restarting failed container


...




kubernetes yaml에 인덴트가 정상인지 확인하고,
잘못된 부분이 어딘가 있을지도 모르니 철자 확인한 후,,
imagePullPolicy 정책이 없다면 always로 수정해야 한다.

http://knight76.tistory.com/entry/kubernetes%EC%97%90%EC%84%9C-%EB%B0%B0%ED%8F%AC-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%83%9D%EC%84%B1%EC%8B%9C-%EC%9C%A0%EC%9D%98-%EC%82%AC%ED%95%AD-imagePullPolicy


Posted by 김용환 '김용환'