반응형

kubectl drain 노드명

- drain 명령어를 사용하게 되면 해당 노드의 pod 를 다른 노드로 옮긴다.
- 실제로는 pod 를 옮기는게 아니라 다른 노드에 재 생성한다.
- 데몬셋을 무시하고 진행할 경우에는 --ignore-daemonsets 옵션을 사용한다.

아래와 같이 myserver-002와 myserver-003 에 pod 가 각각 deploy 되어있다.

root@myserver-001:~# kubectl get po -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP          NODE           NOMINATED NODE   READINESS GATES
rollout-nginx-74695fdcd-5trw5   1/1     Running   0          3m55s   10.32.0.2   myserver-002   <none>           <none>
rollout-nginx-74695fdcd-jkw2d   1/1     Running   0          3m55s   10.47.0.2   myserver-003   <none>           <none>
rollout-nginx-74695fdcd-tp75z   1/1     Running   0          3m55s   10.47.0.1   myserver-003   <none>           <none>

이 상황에서 myserver-003 을 drain 을 시켜보면 다음과 같이 변경된다.

root@myserver-001:~# kubectl get nodes
NAME           STATUS                     ROLES                  AGE     VERSION
myserver-001   Ready                      control-plane,master   2d8h    v1.22.3
myserver-002   Ready                      <none>                 2d8h    v1.22.3
myserver-003   Ready,SchedulingDisabled   <none>                 4h23m   v1.22.3

 

root@myserver-001:~# kubectl get po -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP          NODE           NOMINATED NODE   READINESS GATES
rollout-nginx-74695fdcd-5trw5   1/1     Running   0          4m45s   10.32.0.2   myserver-002   <none>           <none>
rollout-nginx-74695fdcd-8c55f   1/1     Running   0          11s     10.32.0.3   myserver-002   <none>           <none>
rollout-nginx-74695fdcd-h6txz   1/1     Running   0          11s     10.32.0.4   myserver-002   <none>           <none>

기존에 있던 rollout-nginx-74695fdcd-5trw5 파드를 제외하고 나머지 pod 는 이름을 보면 새로 만들어진것이다. Age 도 11s 로 나온다. 따라서 위에서 말한것처럼 drain 을 했을 경우 pod 를 옮기는게 아니라 삭제하고 새로 만들게 된다. 

 

728x90
반응형
반응형

파드 스케줄링

파드를 만들때 어떤 노드에서 실행할지 다양한 옵션으로 선택할 수 있다.

NodeSelector(노드 셀렉터)

  • 설정
    spec:
      containers:
      nodeSelector:
        key: value

Node Affinity

  • 노드 레이블을 기반으로 파드를 스케줄링 한다.
  • 노드 셀렉터를 함께 설정할 경우 둘다 만족하는 노드에 스케줄링된다.
  • requiredDuringSchedulingIgnoredDuringExecution : 스케줄링 하는동안 꼭 필요한 조건
  • preferredDuringSchedulingIgnoredDuringExecution : 만족하면 좋은 조건. (필수아님)
  • 스케줄링 하는 동안 조건이 변경되더라도 무시한다.
  • 설정
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: beta.kubernetes.io/os
                operator: In
                values:
                - linux
                - window
              - key: disktype
                operator: Exists
          preferredDuringSchedulingIgnoredDuringExecution  
          - weight: 10
            preference:
              matchExpressions:
              - key: kubernetes.io/hostname
                operator: In
                values:
                - worker-node01
    • operators : In, NotIn, Exists, DoesNotExist, Gt(Greater than), Lt(Lower than)

Pod affinity, antiAffinity

  • affinity: 서로 연관성이 있는 Pod 를 같은 노드에 배치
  • antiAffinity: 자원을 많이 차지 하는 Pod 를 서로 다른 노드에 배치
  • 설정
    spec:
        affinity:
          podAntiAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - store
              topologyKey: "kubernetes.io/hostname"
    • app 필드 값이 store 인 노드는 피해서 스케줄링 한다.
    • topologyKey : affinity 를 만족하면 topologyKey 기준으로 같은 노드에 pod 를 실행하고 anitiAffinity를 만족하면 topologyKey 기준으로 다른 노드에 pod 를 실행한다.

taint, toleration

  • 테인트를 설정한 노드는 스케줄링 하지 않는다.
  • 테인트를 설정한 노드에 스케줄링 하려면 톨러레이션을 설정해야 한다.
  • kubectl taint nodes 노드명 key01=value01:NoSchedule (key=value:효과)
  • kubectl taint nodes 노드명 key01=value01:NoSchedule- (테인트 제거)
  • 톨러레이션
    spec:
      tolerations:
      - key: "key01"
        operator: "Equal"
        value: "value01"
        effect: "NoSchedule"
    • effect
      • NoSchedule : 톨러레이션 설정 없으면 스케줄링 안함.
      • PreferNoSchedule : 스케줄링 안하지만 자원 부족하면 할수도 있음
      • NoExecute : 스케줄링 안하며 기존 파드도 설정이 없는경우 종료시킴

cordon, drain

  • cordon
    • 지정한 노드에 추가로 파드를 스케줄링 하지 않는다.
    • kubectl cordon 노드명
      master01@master01-VirtualBox:~$ kubectl get nodes
      NAME                  STATUS     ROLES    AGE   VERSION
      master01-virtualbox   Ready      master   79d   v1.19.2
      worker01-virtualbox   Ready      <none>   79d   v1.19.2
      worker02-virtualbox   NotReady   <none>   79d   v1.19.2
      master01@master01-VirtualBox:~$ kubectl cordon worker01-virtualbox
      node/worker01-virtualbox cordoned
      master01@master01-VirtualBox:~$ kubectl get nodes
      NAME                  STATUS                     ROLES    AGE   VERSION
      master01-virtualbox   Ready                      master   79d   v1.19.2
      worker01-virtualbox   Ready,SchedulingDisabled   <none>   79d   v1.19.2
      worker02-virtualbox   NotReady                   <none>   79d   v1.19.2
      master01@master01-VirtualBox:~$ kubectl uncordon worker01-virtualbox
      node/worker01-virtualbox uncordoned
      master01@master01-VirtualBox:~$ kubectl get nodes
      NAME                  STATUS     ROLES    AGE   VERSION
      master01-virtualbox   Ready      master   79d   v1.19.2
      worker01-virtualbox   Ready      <none>   79d   v1.19.2
      worker02-virtualbox   NotReady   <none>   79d   v1.19.2
  • drain
    • 지정된 노드에 있는 파드를 다른 노드로 옮긴다.
    • 노드에 데몬셋이 존재할 경우 적용 불가능
    • 데몬셋 무시하고 적용할 경우 --ignore-daemonsets=true 옵션 추가
    • 컨트롤러를 이용하지 않은 파드들도 drain 불가능

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

Secret

  • 비밀번호 같은 민감한 정보를 저장하는 용도로 사용

생성

  • 명령어
    • kubectl create generic secret명 --from-file~
    • 실제 값은 base64 로 인코딩한 값이 들어간다.
  • 템플릿
    apiVersion: v1
    kind: Secret
    metadata:
      name: user-pass-yaml
    type: Opaque
    data:
      username: 값
      password: 값
    • type
      • Opaque : 기본값
      • kubernetes.io/service-account-token : 쿠버네티스 인증토큰 저장
      • kubernetes.io/dockerconfigjson: 도커 저장소 인증정보 저장
      • kubernetes.io/tls: TLS 인증서 저장
    • data 값은 base64 로 인코딩 한 값을 넣어야 한다.
      • echo -n "username" | base64

사용

  • 환경변수로 사용

     

    spec:
      containers:
      - name:
        image:
        env:
        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: user-pass-yaml
              key: username
  • volume 에 바인딩 하기
    spec:
      containers:
      - name:
        image:
        volumeMounts:
        - name: volume-secret
          mountPath: /etc/config
          readOnly: true
      volumes:
      - name: config-secret
        secret:
          secretName: user-pass-yaml 
  • 프라이빗 커네이너 이미지 pull
    • kubectl create secret docker-registry dockersecret --docker-username= --docker-password= --docker-email= --docker-service=https://~
    • 설정
      spec:
      containers:
      - name:
        image:
      imagePullSecrets:
      - name: dockersecret      
  • TLS 사용
    • kubectl create secret tls tlssecret --key tls.key --cert tls.crt

제한

  • secret 은 etcd 에 저장된다.
  • secret의 최대 용량은 1MB
  • 작은 용량의 secret 을 여러개 만들어도 문제가 생길수 있다.
  • etcd 는 접근 제한을 해야 한다.

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

Label, Annotation

Label(레이블)

  • 키-값 쌍으로 구성
  • 파드 관리할때 구분하는 역할을 한다.
  • 규칙
    • 63글자 넘으면 안됨
    • 시작과 끝문자는 알파벳 대소문자 및 숫자
    • 중간에는 대시(-), 밑줄(_), 점(.), 숫자등이 올수 있음
  • 레이블 셀렉터
    • 등호기반(=, ==)
    • 집합기반(in, notin..)
    • 레이블을 모두 만족시켜야 하는경우 (And) 는 쉼표로 연결
    • 실제 서비스에서 정상적으로 셀렉트를 했는지 보려면 서비스의 endpoint를 확인해보면 된다.
  • pod 선택시 -l 옵션 사용
    • kubectl get pod -l 레이블~

Annotation

  • 쿠버네티스 시스템이 필요한 정보를 담는다.
  • 키는 쿠버네티스 시스템이 인식할 수 있는 값을 사용한다.

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

ConfigMap

  • 컨테이너에 필요한 환경 설정을 컨테이너와 분리해서 제공하는 기능

사용

  • 설정
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: config-dev
    data:
      DB_URL: localhost
      DB_USER: myuser
      DB_PASS: mypass
      DEBUG_INFO: debug  
  • 컨피그맵 일부만 사용
    spec:
      containers:
      - name:
        image:
        env:
        - name: DEBUG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: config-dev
              key : DEBUG_INFO
    • .env[].valueFrom 사용
    • .env[].valueFrom.configMapKeyRef 를 통해 이미 정의된 configmap 사용
  • 컨피그맵 전체를 불러오기
    spec:
      containers:
      - name:
        image:      
        envFrom:
        - configMapRef:
          name: config-dev      
  • volume 에 바인딩 하기
    spec:
      containers:
      - name:
        image:
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
      volumes:
      - name: config-volume
        configMap:
          name: config-dev    
    • 컨테이너 내부에 파일로 저장한다.
      root@nginx-deployment-67b8444cdf-sp7lx:/# ls /etc/config/
      DB_PASS  DB_URL  DB_USER  DEBUG_INFO

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

Pod

개념

쿠버네티스에서 실제로 컨테이너를 묶어서 관리하는 단위

설정

apiVersion: v1
kind: Pod
metadata:  
  name: simple-pod          (Pod 이름)
  labels: 
    app: simple-pod         (오브젝트를 식별하는 레이블)
spec:
  containers:
  - name: simple-pod        (컨테이너 이름)
    image: ~~~              (컨네이너에서 사용할 이미지)
    ports:
    - containerPort: 8080

Pod 생명주기

Pending -> Running

Successed

Failed

Unknown

컨테이너 진단

  • ivenessProbe

    컨테이너가 실행됐는지 확인

    실패시 컨테이너를 종료시키고 재시작 정책에 따라서 재시작

  • readinessProbe

    컨테이너 실행된 후 실제로 서비스 요청에 응답할 수 있는지 진단

    컨테이너가 실제로 트래픽을 받을 준비가 되었음을 확인할 수 있어 유용함

초기화 컨테이너(Init Container)

  • 앱 컨테이너가 실행 되기 전 Pod 를 초기화 한다.

  • 여러개 구성 가능하며 실행 순서는 템플릿에 명시한 순서를 따른다.

  • 실패시 성공할때 까지 재시작한다.

  • readinessProbe 를 지원하지 않는다 - Pod 가 준비되기 전에 실행후 종료되기 때문

  • 설정

    .spec.initContainers[] 의 하위 필드

      apiVersion: v1
      kind: Pod
      metadata:  
          name: simple-pod
          labels: 
              app: simple-pod
      spec:
          initContainers:
          - name: 
            image:
            command        

파드 인프라 컨테이너

pause 컨테이너

  • Pod Infrastructure Container (파드 인프라 컨테이너)
  • 모든 Pod 에서 항상 실행된다
  • 다른 컨테이너의 부모 역할을 한다
  • Pod 안 다른 컨테이너들은 pause 컨테이너가 제공하는 네트워크를 사용
  • pause 컨테이너 재시작시 Pod 안 모든 컨테이너 재시작됨
    c34dff11289b        arisu1000/simple-container-app   "./simple-container-…"   41 minutes ago      Up 41 minutes                           k8s_simple-pod_simple-pod_default_112e5cb1-101b-4cb6-a591-c83c6171cce5_0
    67c790777792        k8s.gcr.io/pause:3.2             "/pause"                 41 minutes ago      Up 41 minutes                           k8s_POD_simple-pod_default_112e5cb1-101b-4cb6-a591-c83c6171cce5_0

스태틱 Pod

  • kube-apiserver 를 통하지 않고 kubelet 이 직접 실행하는 Pod
  • 조회는 가능하지만 명령 실행은 불가능(직접 edit 등 불가능)
  • 시스템 파드 실행용도로 많이 사용
  • 스태틱 Pod 경로 : /etc/kubernetes/manifests

자원 할당

  • requests 최소자원, limits 최대자원

    .spec.containers[].resources.limits.cpu

    .spec.containers[].resources.limits.memory

    .spec.containers[].resources.requests.cpu

    .spec.containers[].resources.requests.memory

  • requests 만 설정했을 경우 해당 값보다 더 많이 사용할 수 있기 때문에 limits 설정을 해야 Out of Memory 를 피할수 있다.

  • Memory : Exa, Peta, Tera, Giga, Mega, Kilo (맨 첫글자 사용)

  • CPU : 소수점일 경우 1개 코어에 해당하는 연산능력을 의미( 0.1 일경우 1코어의 10%만 활용)

Pod 의 환경 변수

.spec.conainers[].env[] 하위 필드

  • name
  • value
  • valueFrom
  • fieldRef
  • fieldPath
  • resourceFieldRef
  • containerName
  • resource

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

 


이 책은 Kubernetes 에 대한 이론적인 내용을 담고 있으면서 각각의 Best Practice 에 대한 내용들을 담고 있다. 

실습을 하면서 읽어볼 수도 있고 그런 여건이 되지 않는다면 참고 서적처럼 읽는 방법도 괜찮아 보인다. 나같은 경우는 내용을 따라 해보면서 완독을 했다.

 

책을 읽으면서 몇가지 좋았던 점과 아쉬웠던 점을 말하고자 한다.

우선 좋았던 점은 책 제목에서 처럼 여러가지 사례들이 많이 담겨 있다는 것이다. Kubernetes 에 대한 이론을 설명해주면서 어떻게 활용하는 것이 좋은 방법인지 알려준다. Kubernetes 를 공부하다 보면 노드에 파드를 생성하고 서비스가 잘 동작하는걸 확인해 보는건 그나마 쉽다. 하지만 그걸 운영에 가져갔을때 어떻게 사용을 해야 올바른 방법인지는 찾기가 좀처럼 쉽지 않다. 그런 것에 대한 시작점을 제시해주는 주는게 이 책의 핵심이라고 할수 있다.

 

반면에 몇가지 아쉬웠던 부분이 있었다.

우선 실습을 병행해 봤지만 실습 하기가 쉽지 않았다. github 에 있는 소스를 가지고 실제 반영을 해보면 버전상으로 맞지 않는것이 있어서 수정이 필요 했다.  결국 책에 나온 내용들만 가지고는 실습에 옮기기에는 무리가 있었다. 

그리고 번역이 매끄럽지 않다는 느낌을 많이 받았다. 문장이라든지 아니면 단어의 선택들이 고개를 갸웃거리게 만든적이 많았다. 

 

기본 적인 내용이 포함되어 있긴 하지만 사례에 대한 것이 주가 되는 책이기 때문에 처음 Kubernetes 를 접하는 분들은 다른 책을 먼저 공부하고 보길 권한다. 

 "한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평입니다."

728x90
반응형
반응형

[K8S] ## K8S 설치시 Trouble Shooting

- kubeadm init 했는데 다음과 같이 나오는 경우

[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[kubelet-check] Initial timeout of 40s passed.

Unfortunately, an error has occurred:
timed out waiting for the condition
This error is likely caused by:
- The kubelet is not running
- The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)
If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands:
- 'systemctl status kubelet'
- 'journalctl -xeu kubelet'

Additionally, a control plane component may have crashed or exited when started by the container runtime.
To troubleshoot, list all containers using your preferred container runtimes CLI, e.g. docker.
Here is one example how you may list all Kubernetes containers running in docker:
- 'docker ps -a | grep kube | grep -v pause'
Once you have found the failing container, you can inspect its logs with:
- 'docker logs CONTAINERID'
error execution phase wait-control-plane: couldn't initialize a Kubernetes cluster

 

1. docker Cgroup 이 systemd 로 설정되어있을 경우

/etc/docker/daemon.json 파일에 아래 문구 추가한다.

{
	"exec-opts": ["native.cgroupdriver=systemd"]
}

그리고
systemctl daemon-reload
systemctl restart docker

2. 로그 확인

- 'journalctl -xeu kubelet' 

이 명령어를 실행 하면 아래와 같이 로그가 남았다. 

Apr 30 22:19:38 master kubelet: W0430 22:19:38.226441    2372 cni.go:157] Unable to update cni config: No networks found in /etc/cni/net.d
Apr 30 22:19:38 master kubelet: E0430 22:19:38.226587    2372 kubelet.go:2067] Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

 

내 경우에는 위에 2.  /env/environment 설정 에 보면 **no_proxy** 항목에 현재 K8S 가 설치된 Machine 의 IP 를 추가했더니 해결이 되었다.

- kubeadm join 했는데 다음과 같이 나올 경우

[preflight] Running pre-flight checks
error execution phase preflight: [preflight] Some fatal errors occurred:
    [ERROR FileAvailable--etc-kubernetes-kubelet.conf]: /etc/kubernetes/kubelet.conf already exists
    [ERROR Port-10250]: Port 10250 is in use
    [ERROR FileAvailable--etc-kubernetes-pki-ca.crt]: /etc/kubernetes/pki/ca.crt already exists
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher

    VM 에서 다음과 같이 kubeadm join 을 했는데 에러가 났을경우 (node가 2개인데 2번째 노드 구성시)

    kubeadm reset 을 한번 실행하고 다시 join 명령어를 실행해준다.

728x90
반응형
반응형

ingress 에 tls 에서 사용되는 인증서가 만료되어서 secret 을 생성 해야 할 경우 다음과 같이 생성하면된다.

 

인증서와 key 파일은 있다고 가정한다. 

없다면 다음 글을 참고하면 된다.

 

2018/08/22 - [Development/Tech&Seminar] - Openssl로 SSL 을 위한 인증서 발급하기 (HTTPS)

 

secret 이름은 my-secret 이라고 가정하고 dev 네임스페이스에 생성되어있다고 가정한다.

 

1. 기존 secret 삭제

 

kubectl delete secret my-secret -n dev

 

2. secret 생성

 

kubectl create secret tls my-secret --key my.key --cert my.crt -n dev

 

이렇게 하면 끝난다.

 

이미 ingress 에 my-secret 이름으로 설정이 되어있다면 재기동도 안해도 된다.

 

728x90
반응형

+ Recent posts