pod 컨테이너의 구성정보나 환경정보 등을 한 곳에서 관리.

configmap는 API

 

  • ConfigMap 생성
  • ConfigMap 일부 적용
  • ConfigMap 전체 적용
  • ConfigMap 을 볼륨으로 적용하기

 

ConfigMap 생성

configMap : 컨테이너 구성정보를 key-value 형태로 한곳에 모아서 관리

 

ConfigMap 일부 적용

configMap의 key를 pod의 컨테이너에 적용

configMapKeyRef 사용

ConfigMap 전체 적용

configMapRef 사용

ConfigMap 을 볼륨으로 적용하기

mountpath 로 볼륨을 지정

 

 

레이블과 어노테이션

Labels are for Kubernetes, while annotations are for humans.

Kubernetes의 레이블은 
레이블은 선택기와 함께 사용되어 관련 리소스 그룹을 식별합니다. 선택기는 레이블을 쿼리하는 데 사용되므로 이 작업은 효율적이어야 합니다. 효율적인 쿼리를 위해 레이블은 RFC 1123에 의해 제한됩니다. RFC 1123은 다른 제약 조건 중에서 레이블을 최대 63자 길이로 제한합니다. 따라서 Kubernetes가 관련 리소스 집합을 그룹화하도록 하려면 레이블을 사용해야 합니다.

Kubernetes의 주석이란
주석은 "비식별 정보", 즉 Kubernetes가 신경 쓰지 않는 메타데이터에 사용됩니다. 따라서 주석 키와 값에는 제약 조건이 없습니다. 따라서 주어진 리소스에 대해 다른 사람을 위한 정보를 추가하려는 경우 주석이 더 나은 선택입니다.

 

레이블이란?

- 노드, pod, deployment 등 모든 리소스에 할당

- 리소스의 특성을 분류하고, selector를 이용해서 선택

- key-value 한쌍으로 적용

 

워커 노드에 레이블 설정

 

 

 

 

어노테이션(annotation)

Kubernetes 어노테이션을 사용하여 임의의 비식별 메타데이터를 개체에 연결할 수 있습니다. 도구 및 라이브러리와 같은 클라이언트는 이 메타데이터를 검색할 수 있습니다.

레이블을 사용하여 개체를 선택하고 특정 조건을 충족하는 개체 모음을 찾을 수 있습니다. 반면 어노테이션은 개체를 식별하고 선택하는 데 사용되지 않습니다. 어노테이션의 메타데이터는 작거나 크거나, 구조화되거나 구조화되지 않을 수 있으며 레이블에서 허용하지 않는 문자를 포함할 수 있습니다.

 

label과 동일하게 key-value 를 통해 리소스의 특성을 기록

쿠버네티스에 특정 정보를 전달한 목적으로 사용

예시) deployment 의 rolling update 정보 기록 

annotations:
  kubernetes.io/change-cause: version 1.15

관리를 위해 필요한 정보를 저장할 목적으로 사용

- 릴리즈, 로깅, 모니터링에 필요한 정보들을 기록

annotations:
  builder: "hong kil done(hkd@google.com)"
  buildDate: "20220601"
  imageRegistry: https://hub.docker.com

 

레이블을 이용한 카나리 배포(canary deployment)

 

pod를 배포하는 방법

  • 블루 그린 업데이트 : 블루를 내리고 그린으로 대체(다운타임 발생)
  • 카나리 업데이트 : 
  • 롤링 업데이트 : 하나씩 교체

 

canary 배포

- 기존 버전을 유지한 채 일부 버전만 업데이트하여 이상 여부를 확인하는 방법

레이블을 이용한 canary 배포 방법

단일 진입점으로 묶기 위해서 서비스를 사용함

 

 

'쿠버네티스' 카테고리의 다른 글

쿠버네티스 - configmap  (0) 2022.05.18
쿠버네티스 - configmap  (0) 2022.05.18
쿠버네티스 Cluster 설치하기 - on centos linux  (0) 2022.05.17
쿠버네티스 - CPU, 메모리 할당하기  (0) 2022.05.17
쿠버네티스 - POD  (0) 2022.05.09

 

구성 순서

1. runtime(Docker) 설치

 - docker : /var/run/docker.sock

 - containerd /run/containerd/containerd.sock

 - CRI-O : /var/run/crio/crio.sock

 

yum install docker-ce docker-ce-cli containerd.io

 

 

2. control plane, worker node – kubeadm 설치

 - 설치전 환경설정

 - kubeadm, kubectl, kubelet 설치

 

3. LB 구성

  - nginx로 대체 구성

 

4. kubeadm을 이용한 HA 클러스터 구성

 - master1 : kubeadm init 명령어로 초기화 – LB 등록

 - master2, master3master1join :

 - CNI(Container Network Interface) 설치

 - worker nodeLB를 통해 masterjoin

 - 설치확인

'쿠버네티스' 카테고리의 다른 글

쿠버네티스 - configmap  (0) 2022.05.18
쿠버네티스 - label & annotation  (0) 2022.05.18
쿠버네티스 - CPU, 메모리 할당하기  (0) 2022.05.17
쿠버네티스 - POD  (0) 2022.05.09
쿠버네티스 - namespace  (0) 2022.05.09

POD에 할당되는 CPU, 메모리 자원을 제한하는 방법입니다.

 

resource request

- pod가 실행될 수 있는 최소 리소스 양을 요청

 

resource limit : 

- pod가 사용할 수 있는 최대 리소스 양를 제한

- memory limit을 초과해서 사용하는 pod는 종료(OOM Kill)되며 다시 스케줄링 된다.

- limit만 사용할 겨우 request는 limit와 동일하게 설정된다.

 

 

쿠버네티스 Pod 환경변수 설정과 실행 패턴

환경변수

pod내의 컨테이너가 실행될 때 사용하는 변수

pod 실행 시 미리 정의된 컨테이너 환경 변수를 변경할  수 있다.

 

yaml 파일에 env: 항목으로 정의할 수 있다.

 

POD 구성 패턴의 종류

pod를 구성하고 실행하는 패턴

- multi-container pod 

  • sidecar : APP 컨테이너 + sidecar(로그 저장), 컨테이너 2개가 같이 동작하는 환경
  • adapter : APP 컨테이너 +  adapter()
  • ambasssador : 

 

Controller - ReplicationController란?

- RelicationController

- ReplicaSet

- Deployment

- DaemonSet

- StatefulSet

- Job

- CronJob

controller란

- pod 개수를 보장

 

RelicationController : 요구하는 pod의 개수를 보장하며 파드 실행을 안정적으로 유지

ReplicaSet : 많은 selector 을 쓸수 있음. matchExpressions 연산자

Deployment : replicaset의 상위 컨트롤러. rolling update & rolling back 를 위한 용도

- DaemonSet

- StatefulSet

- Job

- CronJob

 

'쿠버네티스' 카테고리의 다른 글

쿠버네티스 - label & annotation  (0) 2022.05.18
쿠버네티스 Cluster 설치하기 - on centos linux  (0) 2022.05.17
쿠버네티스 - POD  (0) 2022.05.09
쿠버네티스 - namespace  (0) 2022.05.09
쿠버네티스 아키텍처  (0) 2022.05.09

 

multi-container POD 생성하기

multi-container를 정의한 yaml 파일로 pod를 생성한다.

- file명 : multipod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: multipod
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 80
  - name: centos-container
    image: centos:7
    command:
    - sleep
    - "10000"

아래 명령어를 수행하여 multipod를 생성하고 조회합니다.

## multipod 생성
kubeclt create -f multipod.yaml

## pod 조회
kubectl get pods -o wide
NAME                      READY   STATUS    RESTARTS      AGE     IP          NODE     NOMINATED NODE   READINESS GATES
multipod                  2/2     Running   0             19m     10.44.0.4   node-1   <none>           <none>

READY 상태가 2/2 로 표시되는데 이는 2개의 컨테이너가 running 상태임을 나타냅니다.

 

생성된 centos-container 에 접속한 후 웹페이지를 조회합니다.

$ kubectl exec multipod -it -c centos-container -- /bin/bash

## centos-container 에 접속한 상태
[root@multipod /]# curl http://localhost:80

## 실행결과
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
......

## centos-container ps로 프로세스 확인
[root@multipod /]# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 13:17 ?        00:00:00 sleep 10000
root          26       0  0 13:43 pts/0    00:00:00 /bin/bash
root          41      26  0 13:44 pts/0    00:00:00 ps -ef
=> nginx 프로세스는 보이지 않음

[root@multipod /]# curl localhost:80
=> nginx 페이지를 불러옴

## centos-container 에서 빠져나옴
[root@multipod /]# exit

위에서 확인할 수 있듯이 POD의 컨테이너는 동일한 IP를 사용하고 있는 것을 알 수 있습니다.

 

컨테이너의 log를 조회합니다.

kubectl logs multipod -c nginx-container

 

[참고 : deployment 삭제]

deployment 생성했다면 pods를 먼저 삭제하면 다시 실행되기 때문에 deployment 를 삭제해야 한다. 

systanx : kubectl delete deployment <deployment_name>
예시) deployment 이름이 deploy_app 인 경우 deployment 삭제 명령어
kubectl delete deployment deploy_app

 

 

 

POD 동작 flow

pod 생성 과정을 보기 위해 아래와 같이 --watch option으로 모니터링을 합니다.

kubectl create 명령어를 수행하면 pod 생성 과정을 볼 수 있습니다.

$ kubectl get pods -o wide --watch

NAME        READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
nginx-pod   0/1     Pending   0          0s    <none>   <none>   <none>           <none>
nginx-pod   0/1     Pending   0          0s    <none>   node-2   <none>           <none>
nginx-pod   0/1     ContainerCreating   0          0s    <none>   node-2   <none>           <none>
nginx-pod   1/1     Running             0          3s    10.36.0.1   node-2   <none>           <none>

새로운 창에서 pod를 생성하면서 watch 옵션으로 수행중인 명령창을 확인합니다.

$ kubectl create -f nginx.yaml

nginx.yaml 파일 내용

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - image: nginx
    name: nginx
    ports:
    - containerPort: 80

 

Pod 관리하기

- 동작중인 pod 정보 보기

kubectl get pod -o wide

kubectl describe pod <pod_name> -o wide

 

- 동작중인 pod 수정

kubectl edit pod <pod_name>

 

- 동작중인 pod 삭제

kubectl delete pod <pod_name>

kubectl delete pod --all

 

 

LivenessProbe 로 self-healing pod 만들기

- kubelet로 컨테이너 진단하기

pod가 계속 실행할 수 있음을 보장

pod의 spec에 정의

 

pod definition livenessProbe definition
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - image: nginx
    name: nginx-container
    ports:
    - containerPort: 80
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - image: nginx
    name: nginx-container
    ports:
    - containerPort: 80
    livenessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 15 
      periodSeconds: 20
      timeoutSeconds: 1
      successThreshold: 1
      failureThreshold: 3

LivenessProbe  메커니즘

httpGet probe: 지정한 IP주소, port, path에 HTTP GET 요청을 보내 해당 컨테이너가 응답하는지를 확인합니다. 반환코드가 200이 아닌 값이 나오면 오류이고 컨테이너를 다시 시작합니다.

    livenessProbe:
      httpGet:
        path: /
        port: 80

tcpSocket probe:  지정된 포트에 TCP연결을 시도. 연결되지 않으면 컨테이너를 다시 시작합니다.

    livenessProbe:
      tcpSocket:
        port: 22

exec probe : exec 명령을 전달하고 명령의 종료코드가 0이 아니면 컨테이너를 다시 시작합니다.

    livenessProbe:
      exec:
        command:
        - ls
        - /filesystem

livenessProve 매개변수를 설정하지 않을 경우에는 default 값을 사용합니다. 아래 명령어를 수행한 우 describe 를 하면 Liveness 정보를 확인할 수 있습니다.

kubectl describe pod <pod-name>

## 예제
$ kubectl describe pod nginx-pod-liveness | grep -i liveness
Name:         nginx-pod-liveness
    Liveness:       http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
  Normal  Scheduled  44s   default-scheduler  Successfully assigned default/nginx-pod-liveness to node-2

 

 

 

livenessProve 매개변수

      initialDelaySeconds: pod 실행 후 delay 할 시간 
      periodSeconds: health check 반복 수행 시간
      timeoutSeconds: health check 응답을 기다리는 시간
      successThreshold: 1
      failureThreshold: 3

 

 

 

init container(https://kubernetes.io/ko/docs/concepts/workloads/pods/init-containers/)

 

init container : 초기화 컨테이너

앱 컨테이너 실행전에 미리 동작시킬 컨테이너

main 컨테이너가 실행되기 전에 사전 작업이 필요한 경우 사용

초기화 컨테이너가 모두 실행된 후에 앱 컨테이너 실행

 

 

main container : init 컨테이너에 의존

 

예를 들어 pod에 여러개의 컨테이너가 있을 경우, init 컨테이너가 성공해야 main 컨테이너가 실행됨

 

사용 중인 초기화 컨테이너

쿠버네티스 1.5에 대한 다음의 yaml 파일은 두 개의 초기화 컨테이너를 포함한 간단한 파드에 대한 개요를 보여준다. 첫 번째는 myservice 를 기다리고 두 번째는 mydb 를 기다린다. 두 컨테이너들이 완료되면, 파드가 시작될 것이다.

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]

다음 커맨드들을 이용하여 파드를 시작하거나 디버깅할 수 있다.

kubectl apply -f myapp.yaml

myapp.yaml 파일 내용

apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376

init container를 실행하기 위해 myapp.yaml 파일로 myservice 서비스를 생성합니다.

kubectl create -f myservice.yaml

 

mydb.yaml 파일 내용

apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377

init container를 실행하기 위해 mydb.yaml 파일로 mydb 서비스를 생성합니다.

kubectl create -f mydb.yaml

위 명령어를 실행 후 pod 상태를 조회해 보면, init 컨테이너가 실행되면서 pod가 running 상태로 변경된 것을 확인할 수 있습니다.

kubectl get pods myapp-pod -o wide --watch

infra container(pause)

pod를 생성하면 기본적으로 생성되는 컨테이너입니다.

pause 컨테이너를 확인하기 위해 pod를 하나 생성합니다.

$ kubectl run  webserver --image=nginx

컨테이너 정보를 확인합니다.

 

 

네임스페이스란

네임스페이스는 단일 클러스터 내에서의 리소스 그룹을 격리하는 메커니즘을 제공합니다. 리소스의 이름은 네임스페이스 내에서 유일해야 하며, 네임스페이스 간에서 유일할 필요는 없습니다. 네임스페이스 기반 영역은 네임스페이스 기반 오브젝트 (예: 디플로이먼트, 서비스 등) 에만 적용 가능하며 클러스터 범위의 오브젝트 (예: 스토리지클래스, 노드, 퍼시스턴트볼륨 등) 에는 적용 불가능하다.

 

여러 개의 네임스페이스를 사용하는 경우

네임스페이스는 여러 개의 팀이나, 프로젝트에 걸쳐서 많은 사용자가 있는 환경에서 사용하도록 만들어졌다. 사용자가 거의 없거나, 수 십명 정도가 되는 경우에는 네임스페이스를 전혀 고려할 필요가 없다. 네임스페이스가 제공하는 기능이 필요할 때 사용하도록 하자.

네임스페이스는 이름의 범위를 제공한다. 리소스의 이름은 네임스페이스 내에서 유일해야하지만, 네임스페이스를 통틀어서 유일할 필요는 없다. 네임스페이스는 서로 중첩될 수 없으며, 각 쿠버네티스 리소스는 하나의 네임스페이스에만 있을 수 있다.

네임스페이스는 클러스터 자원을 (리소스 쿼터를 통해) 여러 사용자 사이에서 나누는 방법이다.

동일한 소프트웨어의 다른 버전과 같이 약간 다른 리소스를 분리하기 위해 여러 네임스페이스를 사용할 필요는 없다. 동일한 네임스페이스 내에서 리소스를 구별하기 위해 레이블을 사용한다.

네임스페이스 다루기

참고: kube- 접두사로 시작하는 네임스페이스는 쿠버네티스 시스템용으로 예약되어 있으므로, 사용자는 이러한 네임스페이스를 생성하지 않는다.

 

 

네임스페이스 조회

kubectl get 명령어로 사용 중인 클러스터의 현재 네임스페이스를 나열할 수 있다.

$ kubectl get namespaces
NAME              STATUS   AGE
default           Active   4d
kube-node-lease   Active   4d
kube-public       Active   4d
kube-system       Active   4d

쿠버네티스는 처음에 네 개의 초기 네임스페이스를 갖는다.

  • default 다른 네임스페이스가 없는 오브젝트를 위한 기본 네임스페이스
  • kube-system 쿠버네티스 시스템에서 생성한 오브젝트를 위한 네임스페이스
  • kube-public 이 네임스페이스는 자동으로 생성되며 모든 사용자(인증되지 않은 사용자 포함)가 읽기 권한으로 접근할 수 있다. 이 네임스페이스는 주로 전체 클러스터 중에 공개적으로 드러나서 읽을 수 있는 리소스를 위해 예약되어 있다. 이 네임스페이스의 공개적인 성격은 단지 관례이지 요구 사항은 아니다.
  • kube-node-lease 이 네임스페이스는 각 노드와 연관된 리스 오브젝트를 갖는다. 노드 리스는 kubelet이 하트비트를 보내서 컨트롤 플레인이 노드의 장애를 탐지할 수 있게 한다.

 

네임스페이스 생성하기

kubectl create 명령어나 파일로 새로운 네임스페이스를 생성할 수 있습니다.

 

1) 명령어로 namespace 생성

sysntax : kubectl create namespace <insert-namespace-name-here>

예시) first-ns 라는 이름의 namespace 생성

## namespace 생성
kubectl create namespace first-ns

## namespace 조회
kubeclt get namespaces

2) yaml 파일로 namespace 생성

## namespace 생성
kubectl create namespace second-ns  --dry-run=client -o yaml > second-ns.yaml
vi second-ns.yaml
kubectl create -f second-ns.yaml


## namespace 조회
kubeclt get namespaces

pod 생성 시 특정 namespace를 지정해서 생성할 수 있습니다.

 

네이스페이스 삭제

## namespace 생성
kubectl create namespace second-ns  --dry-run=client -o yaml > second-ns.yaml
vi second-ns.yaml
kubectl create -f second-ns.yaml


## namespace 조회
kubeclt get namespaces

 

request 에 네임스페이스 설정하기

현재 요청에 대한 네임스페이스를 설정하기 위해서 --namespace 플래그를 사용한다.

예를 들면,

kubectl run nginx --image=nginx --namespace=<insert-namespace-name-here>
kubectl get pods --namespace=<insert-namespace-name-here>

선호하는 네임스페이스 설정하기

이후 모든 kubectl 명령에서 사용하는 네임스페이스를 컨텍스트에 영구적으로 저장할 수 있다.

kubectl config set-context --current --namespace=<insert-namespace-name-here>
# 확인하기
kubectl config view --minify | grep namespace:

네임스페이스와 DNS

서비스를 생성하면 해당 DNS 엔트리가 생성된다. 이 엔트리는 <서비스-이름>.<네임스페이스-이름>.svc.cluster.local의 형식을 갖는데, 이는 컨테이너가 <서비스-이름>만 사용하는 경우, 네임스페이스 내에 국한된 서비스로 연결된다. 개발, 스테이징, 운영과 같이 여러 네임스페이스 내에서 동일한 설정을 사용하는 경우에 유용하다. 네임스페이스를 넘어서 접근하기 위해서는, 전체 주소 도메인 이름(FQDN)을 사용해야 한다.

그렇기 때문에, 모든 네임스페이스 이름은 유효한 RFC 1123 DNS 레이블이어야 한다.

 

모든 오브젝트가 네임스페이스에 속하지는 않음

대부분의 쿠버네티스 리소스(예를 들어, 파드, 서비스, 레플리케이션 컨트롤러 외)는 네임스페이스에 속한다. 하지만 네임스페이스 리소스 자체는 네임스페이스에 속하지 않는다. 그리고 노드나 퍼시스턴트 볼륨과 같은 저수준 리소스는 어느 네임스페이스에도 속하지 않는다.

다음은 네임스페이스에 속하지 않는 쿠버네티스 리소스를 조회하는 방법이다.

# 네임스페이스에 속하는 리소스
kubectl api-resources --namespaced=true

# 네임스페이스에 속하지 않는 리소스
kubectl api-resources --namespaced=false

자동 레이블링

FEATURE STATE: Kubernetes 1.21 [beta]

쿠버네티스 컨트롤 플레인은 NamespaceDefaultLabelName 기능 게이트가 활성화된 경우 모든 네임스페이스에 변경할 수 없는(immutable) 레이블 kubernetes.io / metadata.name 을 설정한다. 레이블 값은 네임스페이스 이름이다.

 

'쿠버네티스' 카테고리의 다른 글

쿠버네티스 - CPU, 메모리 할당하기  (0) 2022.05.17
쿠버네티스 - POD  (0) 2022.05.09
쿠버네티스 아키텍처  (0) 2022.05.09
쿠버네티스 Cluster 설치하기 - on ubuntu linux  (0) 2022.05.05
CNI 플러그인 모드  (0) 2022.05.04

 

'쿠버네티스' 카테고리의 다른 글

쿠버네티스 - POD  (0) 2022.05.09
쿠버네티스 - namespace  (0) 2022.05.09
쿠버네티스 Cluster 설치하기 - on ubuntu linux  (0) 2022.05.05
CNI 플러그인 모드  (0) 2022.05.04
쿠버네티스 - 로드 밸런싱  (0) 2022.04.27

Install Kubernetes Cluster on Ubuntu 20.04 with kubeadm

설치환경

- OS : Ubuntu 20.04 LTS(2 CPU, 4GB Memory, 20GB Disk 이상)

- master node : 1대(hostname : master)

- worker node : 2대(hostname : worker-1, worker-2)

 

설치순서

master node

- containerd 만 설치

master node에도 내부적으로 관리하는 pod들이 있으며, 이를 위해서는 containerd 가 필요함

sudo apt-get update

sudo apt-get install ca-certificates curl gnupg lsb-release -y

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  
sudo apt-get update
sudo apt-get install containerd.io

 

kubernetes.io 사이트를 참조하여 설치

1) kubernetes 설치 전 환경설정

br_netfilter 모듈이 로드되었는지 확인한다. 

lsmod | grep br_netfilter 를 실행하면 된다.

명시적으로 로드하려면 sudo modprobe br_netfilter 를 실행한다.

- iptables가 브리지된 트래픽을 보게 하기

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

- swap off

$ sudo swapoff -a

- port 확인

master node에 6443, 8080 port 가 사용중인지 확인합니다. 사용 중인 서비스가 없어야 합니다.

쿠버네티스 API 서버는 2개의 포트에서 HTTP를 서비스합니다.

- 8080 port : 스트 및 부트스트랩을 하기 위한 것이며 마스터 노드의 다른 구성요소 (스케줄러, 컨트롤러 매니저)가 API와 통신

- 6443 port : TLS를 사용한다. --tls-cert-file 플래그로 인증서를 지정하고 --tls-private-key-file 플래그로 키를 지정한다.

telnet 10.10.1.15(예시, master node IP Address) 6443

 

- 방화벽 open(서버 방화벽 disable)

방화벽이 설정을 확인한 다음 방화벽이 enable되어 있으면 방화벽을 disable 합니다. 

## 방화벽 설정 확인
sudo ufw status

## 방화벽 disable
sudo ufw disable

 

 

- kubectl, kubeadm, kubelet 설치

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl

sudo apt-mark hold kubelet kubeadm kubectl

 

- ip_forward 설정

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

 

 

 

- control plane 구성

control plane 구성은 master node에서만 실행합니다.

아래 명령어로 control plane 을 구성합니다. 명령어 수행 제일 하단에 아래와 같이 kubeadm join 으로 시작하는 정보가 표시됩니다. 이 명령어는 나중에 worker node 에서 수행하여 cluster를 구성하는 명령어입니다. 별도로 저장해 놓습니다.

kubeadm init

......
kubeadm join 10.10.1.20:6443 --token x8g6zc.1yb94eh1u1940rrj \
	--discovery-token-ca-cert-hash sha256:996f5ea00339533897cd991fb005349eeb366af000b13c8458f9743d5ada230c

 

root와 일반 user가 쿠버네티스 명령어를 사용할 수 있도록 환경 설정(master node에 설정)

 

root 유저로 수행하려면 아래를 설정합니다. root 유저로 실행합니다.

export KUBECONFIG=/etc/kubernetes/admin.conf

 

일반 유저로 kubectl 명령어를 수행하기 위해 설정합니다. 일반 유저로 실행합니다.

mkdir -p $HOME/.kube

## admin.conf 파일은 kubelet 설치 시 생성
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

 

 

2) CNI 설치(master node에 설정)

Pod network add-on 설치

pod 네트워크 애드온 종류는 많습니다(calico, canal, flannel, romana, weave net 등).

원하는 네트워크 애드온을 설치합니다.

본 문서에서는 weave network add on 을 설치합니다. 

Weave Net을 설치하기 전에 TCP 6783 및 UDP 6783/6784 포트가 방화벽에 의해 차단되지 않았는지 확인해야 합니다.

아래 명령어로 weave network add-on을 설치합니다.

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

## 실행결과
serviceaccount/weave-net created
clusterrole.rbac.authorization.k8s.io/weave-net created
clusterrolebinding.rbac.authorization.k8s.io/weave-net created
role.rbac.authorization.k8s.io/weave-net created
rolebinding.rbac.authorization.k8s.io/weave-net created
daemonset.apps/weave-net created

[참고]

flannel add-on 설치

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

아래 오류가 발생하면

Warning  FailedCreatePodSandBox  22s   kubelet            
Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "...": 
open /run/flannel/subnet.env: no such file or directory

 

 

 

- kubectl auto completion

echo "source <(kubectl completion bash)" >> ~/.bashrc
echo "source <(kubeadm completion bash)" >> ~/.bashrc

 

 

worker node

- worker node join

master node 에서 수행한 kubeadm init 명령어의 실행 결과창에서 보여진 kubeadm join으로 시작되는 부분을 실행해 줍니다.

kubeadm join 10.10.1.15:6443 --token 2gcmlw.zfvrc2b42j3q30zk \
	--discovery-token-ca-cert-hash sha256:aeb530a1ee53667a603d53d9d9abe12a32009b9f432b0fbca40fa1116c1fcc46

 

 

런타임 설치

아래는 여러 종류의 container runtime입니다. 본 문서에서는 containerd runtime을 설치합니다.

[ RuntimePath to Unix domain socket ]

runtime 종류  
containerd unix:///var/run/containerd/containerd.sock
CRI-O unix:///var/run/crio/crio.sock
Docker Engine (using cri-dockerd) unix:///var/run/cri-dockerd.sock or
/var/run/docker.sock
Mirantis Container Runtime  

/var/run/docker.sock 파일은
Docker 데몬이 기본적으로 수신 대기하는 Unix 소켓이며 컨테이너 내에서 데몬과 통신하는 데 사용합니다.

 

 

 

# Docker와 Containerd가 모두 감지되면 Docker가 우선합니다.

# 이외에 다른 두 개 이상의 컨테이너 런타임이 감지되면 kubeadm은 오류 메시지를 출력하고 종료됩니다.

 

파드에서 컨테이너를 실행하기 위해, 쿠버네티스는 컨테이너 런타임을 사용합다.

 

containerd : 

다음 명령을 사용하여 시스템에 containerd를 설치한다.

공식 도커 리포지터리에서 containerd.io 패키지를 설치한다. 각 리눅스 배포판에 대한 도커 리포지터리를 설정하고 containerd.io 패키지를 설치하는 방법은 도커 엔진 설치에서 찾을 수 있다.

 

apt 패키지 인덱스를 업데이트하고 apt가 HTTPS를 통해 리포지토리를 사용할 수 있도록 패키지를 설치합니다.

sudo apt-get update

sudo apt-get install ca-certificates curl gnupg lsb-release

도커 공식 GPG 키를 추가합니다.

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

다음 명령어를 사용하여 저장소를 설정합니다. 

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

 

containerd.io 설치

apt 패키지 인덱스를 업데이트하고 최신 버전의 Docker Engine, containerd 및 Docker Compose를 설치합니다.

 

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
  • containerd.io - daemon to interface with the OS API (in this case, LXC - Linux Containers), essentially decouples Docker from the OS, also provides container services for non-Docker container managers
  • docker-ce - Docker daemon, this is the part that does all the management work, requires the other two on Linux
  • docker-ce-cli - CLI tools to control the daemon, you can install them on their own if you want to control a remote Docker daemon

containerd 설정

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

systemd cgroup 드라이버의 사용

/etc/containerd/config.toml 의 systemd cgroup 드라이버를 runc 에서 사용하려면, 다음과 같이 설정한다.

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true

이 변경 사항을 적용하는 경우 containerd를 재시작한다.

sudo systemctl restart containerd

kubeadm을 사용하는 경우, kubelet용 cgroup 드라이버를 수동으로 구성한다.(???)

 

 

 

Step 1: Kubernetes Servers update & upgrade

설치 되어있는 패키지들의 새로운 버젼이 있는지 확인(update)하고 업그레이드 합니다. 업그레이드 후 리부팅을 합니다.

upgrade를 해야 되나?

sudo apt update
sudo apt -y full-upgrade
[ -f /var/run/reboot-required ] && sudo reboot -f

 

참고) pod 생성 시 네트워크 대역을 설정할 수 있습니다.

kubeadm init --pod-network-cidr=10.244.0.0/16;

 

kubeadm init 실행시 에러 : 'curl -sSL http://localhost:10248/healthz' failed with error

발생 시

/etc/docker 디렉토리에 daemon.json 파일을 아래와 같이 만들어줍니다.

{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}

 

daemon.json 파일 생성 후 아래 명령어를 실행해 줍니다.
sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker

 

위 조치 방법은 쿠버네티스 공식 홈페이지에 나와 있는 내용 그대롭니다.

  => https://kubernetes.io/docs/setup/production-environment/container-runtimes/#docker

 

사실은, 원래 쿠버네티스 설치전에 Container runtime 을 먼저 설치해줘야 하는데(여기서는 docker 부분..)

이 부분을 빠뜨리고 진행한 경우 이런 에러상황을 만나게 되는 겁니다.

위와 같이 daemon.json 파일을 만들어주고나서, kubeadm reset 하고 init 해주니 정상적으로 잘 되네요~

kubeadm reset
kubeadm init

 

에러 유형 3) 

init] Using Kubernetes version: v1.24.0
[preflight] Running pre-flight checks
	[WARNING SystemVerification]: missing optional cgroups: blkio
error execution phase preflight: [preflight] Some fatal errors occurred:
	[ERROR CRI]: container runtime is not running: output: time="2022-05-04T10:21:27Z" level=fatal msg="getting status of runtime: rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService"
, error: exit status 1

조치내용 : config.toml 파일 삭제, 컨테이너 엔진 재실행 후 kubeadm init 를 실행합니다.(????)

sudo rm /etc/containerd/config.toml
sudo systemctl restart containerd
sudo kubeadm init

kubeadm init 이 완료되면 제일 아래 줄에 아래와 같이 token 이 나타납니다. master node와 연결 시 필요하므로 별도로 저장해 둡니다.

## kubeadm init 실행 결과
......
kubeadm join 10.10.1.21:6443 --token j0vdns.lqbq17k0rwbuvwqj \
        --discovery-token-ca-cert-hash sha256:acfc34d9d77a3b0b326de55f969f95f34779853ac34720526eef99357982750d

kubectl get nodes 명령어를 수행해 봅니다. 오류가 발생하는데, 

# kubectl get nodes

The connection to the server localhost:8080 was refused - did you specify the right host or port?


오류 발생 시 아래 내용을 참조해서 명령어를 수행합니다.

cluster 를 일반 유저로 실행하려면 일반 유저 계정에서 아래를 실행합니다.

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

일반 유저로 다시 node를 조회해 봅니다.

kubectl get nodes

NAME     STATUS     ROLES           AGE     VERSION
master   NotReady   control-plane   4m11s   v1.24.0

 

 

root 유저로 수행하려면 아래를 설정합니다.

# export KUBECONFIG=/etc/kubernetes/admin.conf
root@instance-2:~# kubectl get nodes
NAME         STATUS     ROLES                  AGE     VERSION
instance-2   NotReady   control-plane,master   9m30s   v1.23.6

위에서 STATUS 를 보변 NotReady 인데 이는 CNI(Container Network Interface)가 설치가 안되어 있어서 그렇습니다. CNI 설치 후 node 정보를 조회하면 STATUS 가 Ready 상태로 변경됩니다.

 

Pod network add-on 설치

pod 네트워크 애드온 종류는 많습니다(calico, canal, flannel, romana, weave net 등).

본 문서에서는 weave network add on 을 설치합니다. 

Weave Net을 설치하기 전에 TCP 6783 및 UDP 6783/6784 포트가 방화벽에 의해 차단되지 않았는지 확인해야 합니다.

아래 명령어로 weave network add-on을 설치합니다.

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

## 실행결과
serviceaccount/weave-net created
clusterrole.rbac.authorization.k8s.io/weave-net created
clusterrolebinding.rbac.authorization.k8s.io/weave-net created
role.rbac.authorization.k8s.io/weave-net created
rolebinding.rbac.authorization.k8s.io/weave-net created
daemonset.apps/weave-net created

참고) weave network를 삭제 방법

kubectl delete -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

serviceaccount "weave-net" deleted
clusterrole.rbac.authorization.k8s.io "weave-net" deleted
clusterrolebinding.rbac.authorization.k8s.io "weave-net" deleted
role.rbac.authorization.k8s.io "weave-net" deleted
rolebinding.rbac.authorization.k8s.io "weave-net" deleted
daemonset.apps "weave-net" deleted

 

weave network 가 설치되었는지 확인합니다. 아래 결과를 보면 weave-net-s6g8g 처럼 CNI가 설치된 것을 확인할 수 있습니다.

$ kubectl get pod --all-namespaces

## 명령어 수행결과
NAMESPACE     NAME                               READY   STATUS    RESTARTS   AGE
kube-system   coredns-6d4b75cb6d-h4bnk           1/1     Running   0          129m
kube-system   coredns-6d4b75cb6d-qdzst           1/1     Running   0          129m
kube-system   etcd-master-1                      1/1     Running   0          129m
kube-system   kube-apiserver-master-1            1/1     Running   0          129m
kube-system   kube-controller-manager-master-1   1/1     Running   0          129m
kube-system   kube-proxy-vgvxd                   1/1     Running   0          129m
kube-system   kube-scheduler-master-1            1/1     Running   0          129m
kube-system   weave-net-j92zv                    2/2     Running   1          30s

 

 

kubectl get nodes 명령어를 수행하면 status 가 Ready 상태가 됩니다.

kubectl get nodes
NAME         STATUS   ROLES                  AGE   VERSION
master-1     Ready    control-plane,master   14m   v1.23.6

 

worker node 구성

위에서 설명한 순서대로 환경설정 및 설치를 수행합니다. 제일 마지막 부분의 kubeadm init 명령어는 수행하지 않습니다.

위에서 저장한 token.txt 내용을 복사한 후 worker node에서 수행합니다.

 

 

 

에러 1) 처음 worker node 구성 시 아래와 같은 오류가 발생했는데, 이는 방화벽 때문에 발생한 오류입니다. 마스터 노드와 6443 port로 통신할 수 있는지 확인해 봅니다. 통신이 안될 경우 통신이 되도록 방화벽을 해제합니다.

sudo kubeadm join 10.10.10.210:6443 --token j0vdns.lqbq17k0rwbuvwqj \
>         --discovery-token-ca-cert-hash sha256:acfc34d9d77a3b0b326de55f969f95f34779853ac34720526eef99357982750d
[preflight] Running pre-flight checks
        [WARNING SystemVerification]: missing optional cgroups: hugetlb
error execution phase preflight: couldn't validate the identity of the API Server: Get "https://10.10.1.21:6443/api/v1/namespaces/kube-public/configmaps/cluster-info?timeout=10s": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
To see the stack trace of this error execute with --v=5 or higher

 

에러 2) woker node를 master node에 join 시 아래 오류가 발생하고,

kubeadm token list 명령어 수행 시 아무런 데이터가 조회되지 않을 경우에 대한 해결 방법입니다.

error execution phase preflight: couldn't validate the identity of the API Server: 
could not find a JWS signature in the cluster-info ConfigMap for token ID "j0vdns"

해결방법 1) kubeadm reset 후 kubeadm init을 실행하여 token을 다시 생성한다.

$ kubeadm reset
$ kubeadm init

kubeadm join 10.10.1.21:6443 --token j0vdns.lqbq17k0rwbuvwqj \
        --discovery-token-ca-cert-hash sha256:acfc34d9d77a3b0b326de55f969f95f34779853ac34720526eef99357982750d

## token list 확인
$ kubeadm token list
 TOKEN                     TTL         EXPIRES                USAGES                   DESCRIPTION                                                EXTRA GROUPS
b962zm.9d6jh1g9dq0oroaq   23h         2022-05-03T14:00:04Z   authentication,signing   The default bootstrap token generated by 'kubeadm init'.   system:bootstrappers:kubeadm:default-node-token

재생성된 token으로 다시 worker node에서 실행합니다.

sudo kubeadm join 10.10.1.21:6443 --token j0vdns.lqbq17k0rwbuvwqj \
        --discovery-token-ca-cert-hash sha256:acfc34d9d77a3b0b326de55f969f95f34779853ac34720526eef99357982750d

 

해결방법 2) token 생성 후 hash 값을 확인한 다음 worker node를 join 합니다.

## token 생성
$ kubeadm token create

## hash 확인
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

## node 조인
kubeadm join <Kubernetes API Server:PORT> --token <Token 값> --discovery-token-ca-cert-hash sha256:<Hash 값>

 

worker node를 master에 join 시키기. 

필요한 수 만큼 worker node를 추가합니다. 단, 위에서 설치한 순서대로 설치를 하고 worker node를 추가합니다.

kubeadm join 10.10.1.21:6443 --token b962zm.9d6jh1g9dq0oroaq \
        --discovery-token-ca-cert-hash sha256:fc41fdaa4dfebf0d2c37a67aef3f3d69e88d9f6e3c9c73b510983dc7eb474276
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

 

설치 확인

마스터 노드(control-plane 노드)에서 kubectl get nodes 로 node 정보를 확인합니다. 아래와 같이 조회되면 정상입니다.

$ kubectl get nodes
NAME         STATUS   ROLES                  AGE     VERSION
instance-2   Ready    control-plane,master   10h     v1.23.6
instance-3   Ready    <none>                 9h      v1.23.6
instance-4   Ready    <none>                 2m40s   v1.23.6

 

 

선택사항으로 kubectl 명령어 자동완성 기능을 설정합니다. 명령어의 일부 글자만 타입핑한 후 "탭키"를 누르면 명령어가 완성되는 기능입니다.

echo "source <(kubectl completion bash)" >> ~/.bashrc
echo "source <(kubeadm completion bash)" >> ~/.bashrc

 

 

 

 

 

 

 

 

 

container runtime 설치

아래와 같이 여러 종류의 컨테이너 런타임이 있습니다. 본 문서에서는 containerd 런타임을 설치합니다.

 

 

docker 설치

docs.docker.com 참조하여 설치합니다. 참고로, 현재 도커 엔진 패키지는 docker-ce라고 부릅니다.

구버전 도커 Uninstall

이전 버전의 Docker는 docker, docker.io 또는 docker-engine이라고 했습니다. 이러한 항목이 설치된 경우 제거합니다.

sudo apt-get remove docker docker-engine docker.io containerd runc

저장소를 사용하여 설치

Docker 저장소를 설정해야 합니다. 그런 다음 저장소에서 Docker를 설치하고 업데이트할 수 있습니다.

저장소 설정

apt 패키지 인덱스를 업데이트하고 apt가 HTTPS를 통해 리포지토리를 사용할 수 있도록 패키지를 설치합니다.

$ sudo apt-get update

$ sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

도커 공식 GPG 키를 추가합니다.

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

다음 명령어를 사용하여 저장소를 설정합니다. 

echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

 

Docker Engine 설치

apt 패키지 인덱스를 업데이트하고 최신 버전의 Docker Engine, containerd 및 Docker Compose를 설치합니다.

$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
or
$ sudo apt-get install docker-ce docker-ce-cli containerd docker-compose-plugin

 

containerd 설정 작업

containerd를 실행하기 전에 containerd의 기본 설정을 정의해줍니다. containerd config default 를 수행하면 기본적으로 제공하는 설정값들을 얻을 수 있습니다. tee 명령어를 통해 화면으로도 출력하고, config.toml 파일로도 저장합니다.

$ sudo mkdir -p /etc/containerd
$ containerd config default | sudo tee /etc/containerd/config.toml

systemd를 cgroup driver로 사용하기

systemd를 cgroup driver로 사용하려면 /etc/containerd/config.toml에 다음 설정을 추가합니다. 참고로, 아래 설정은 config.toml 파일에 사전 정의되어 있지 않으니 직접 추가하셔야 합니다.

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true

위 과정을 잘못 수행하는 경우 정상적으로 containerd가 실행되지 않습니다.

containerd 재시작

위 단계를 모두 마쳤다면 이제 containerd를 재시작할 차례입니다. 아래 명령어로 containerd를 재시작합니다.

$ sudo systemctl restart containerd

 

 

쿠버네티스 설정

kubernetes.io 사이트에 접속하여 각자의 OS에 맞는 설치 방법에 따라 설치한다.

document에서 "Set up cluster"를 클릭한다. install the kubeadm setup tool 를 클락한 후 설명대로 진행한다.

  • 설치전 환경 설정 : 위에서 설명
  • kubeadm, kubectl, kubelet
  • control plane 구성
  • worker node 구성
  • 설치 확인

kubeadm, kubelet 및 kubectl 설치

모든 머신에 다음 패키지들을 설치한다.

  • kubeadm: 클러스터를 부트스트랩하는 명령이다.
  • kubelet: 클러스터의 모든 머신에서 실행되는 파드와 컨테이너 시작과 같은 작업을 수행하는 컴포넌트이다.
  • kubectl: 클러스터와 통신하기 위한 커맨드 라인 유틸리티이다.

 

kubectl 예제

kubectl get 명령어로 클러스터를 구성하고 있는 node 정보를 볼 수 있습니다.

## node 정보조회
$ kubectl get nodes

## node 정보 상세조회
$ kubectl get nodes -o wide

컨테이너를 실행하면서 kubectl 명령어 사용하기

아래 명령어는 nginx 최신 버전의 이미지로 webserver 라는 이름의 pod를 생성하고 실행하라는 내용입니다.

$ kubectl run webserver --image=nginx:latest --port 80
pod/webserver created

생성된 pod를 확인합니다. 아래 내용을 보면 현재 상태가 container creating 인 것을 확인할 수 있습니다. pod가 정상적으로 생성완료되면 running으로  상태가 변경됩니다. 현재 진행되는 상태를 보려면 kubectl describe pods 명령어를 수행합니다.

$ kubectl get pods
NAME        READY   STATUS              RESTARTS   AGE
webserver   0/1     ContainerCreating   0          23s

## pods 정보 확인
$ kubectl get pods webserver -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP          NODE     NOMINATED NODE   READINESS GATES
webserver   1/1     Running   0          49m   10.44.0.1   node-1   <none>           <none>

## pods 상태 상세확인
$ kubectl describe pods webserver
## 실행결과
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  57s   default-scheduler  Successfully assigned default/webserver to node-1
  Normal  Pulling    56s   kubelet            Pulling image "nginx:latest"
  Normal  Pulled     48s   kubelet            Successfully pulled image "nginx:latest" in 8.496066344s
  Normal  Created    48s   kubelet            Created container webserver
  Normal  Started    48s   kubelet            Started container webserver

node-1에서 10.44.0.1 IP로 nginx 웹서버가 작동하고 있는 것을 확인할 수 있습니다.

 

오류) 아래와 같은 오류가 발생할 경우에 containerd 를 재설치 후 서버를 reboot하니 오류가 발생하지 않았습니다.

sudo apt-get install containerd

 

  Warning  FailedCreatePodSandBox  18m                 kubelet            Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "...": failed to find network info for sandbox "..."
  Warning  FailedCreatePodSandBox  30s (x83 over 18m)  kubelet            (combined from similar events): Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "..": failed to find network info for sandbox "..."

 

 

컨테이너 확인하기

curl 명령어로 위에서 생성한 nginx pod 가 정상 동작하는지 확인해 봅니다.(참고. elinks(이링크스)라는 유닉스 기반 운영 체제를 위한 텍스트 기반 콘솔 웹 브라우저로 웹 페이지를 확인할 수 있습니다.)

curl 10.44.0.1

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
....

 

kubectl create 명령어

파일 또는 표준 입력에서 리소스를 생성합니다. JSON and YAML 형식의 파일을 사용할 수 있습니다.

 

usage:
  kubectl create deployment NAME --image=image -- [COMMAND] [args...] [options]

 

kubectl create deployment mainui --image=httpd:latest --replicas=3

생성된 pod를 확인합니다.

1) kubectl get deployment.apps 명령어로 확인

kubectl get deployments.apps 
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
mainui   3/3     3            3           46s

2) kubectl get pods 명령어로 확인

$ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
mainui-7bdb5f79fb-4qvhc   1/1     Running   0          3m29s
mainui-7bdb5f79fb-btblc   1/1     Running   0          3m29s
mainui-7bdb5f79fb-nrdv5   1/1     Running   0          3m29s
webserver                 1/1     Running   0          128m

 

배포한 웹서버의 웹페이지 변경하기

kubectl exec  명령어로 위에서 생성한 webserver pod의 웹페이지를 변경해 봅니다.

kubectl exec  명령어는 동작중인 컨테이너의 셸에 접근할 수 있도록 해주는 명령어입니다.

kubectl exec --stdin --tty webserver -- /bin/bash
또는
kubectl exec -it webserver -- /bin/bash

## 실행결과(컨테이너에 접속됨)
root@webserver:/#

 

nginx 웹페이지는 /usr/share/nginx/html 디렉토리에 있습니다. index.html 파일이 웹서버의 첫 웹페이지입니다.이 웹페이지를 원하는 내용으로 변경하고 curl이나 elinks 로 변경된 내용을 확인합니다.

# cat > index.html
NGINX 웹서버입니다.
ctrl + D 를 클릭하여 저장합니다.
# exit

$ curl 10.44.0.1
NGINX 웹서버입니다.

 

nginx log도 확인해 봅니다. nginx log는 컨테이너의 /var/log/nginx 밑에 access.log, error.log 파일입니다.

$ kubectl logs webserver

...
10.32.0.1 - - [05/May/2022:16:27:14 +0000] "GET / HTTP/1.1" 200 615 "-" "ELinks/0.13.1 (textmode; Linux 5.13.0-1024-gcp x86_64; 153x16-2)" "-"
10.44.0.0 - - [05/May/2022:18:15:45 +0000] "GET / HTTP/1.1" 200 29 "-" "curl/7.68.0" "-"
10.44.0.1 - - [05/May/2022:18:16:20 +0000] "GET / HTTP/1.1" 200 29 "-" "curl/7.74.0" "-"

이제 외부에서 pod에 접속할 수 있도록 port-forward 명령어를 사용합니다.

아래 명령어는 외부에서 8080으로 접속하면 pod의 80 port로 forwarding 하는 예시입니다.

$ kubectl port-forward --address=0.0.0.0 webserver 8080:80

다른 서버에서 curl 명령어를 사용하여 웹서버 페이지를 호출해 봅니다.

$ curl http://10.10.1.35:8080

NGINX 웹서버입니다

위에서 생성한 mainui pod의 개수를 3개에서 kubectl edit 명령어로 변경해 봅니다.

아래 명령어를 수행하면 mainui pod에 대한 설정값을 vi 에디터로 불러옵니다. 여기서 변경하고자 하는 값을 변경하면 됩니다. 본 문서에서는 replicas를 3개에서 5개로 변경해 보겠습니다. 변경 후 :wq 로 저장하고 vi 에디터를 빠져나옵니다.

kubectl edit deployments.app mainui

....
spec:
  progressDeadlineSeconds: 600
  replicas: 5
...

pod 갯수가 변경되었는지 확인합니다. 아래와 같이 mainui pod가 5개로 변경된 것을 볼 수 있습니다.

kubectl get pods

## 실행결과
$ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
mainui-7bdb5f79fb-4qvhc   1/1     Running   0          76m
mainui-7bdb5f79fb-8t9r9   1/1     Running   0          2m23s
mainui-7bdb5f79fb-btblc   1/1     Running   0          76m
mainui-7bdb5f79fb-nrdv5   1/1     Running   0          76m
mainui-7bdb5f79fb-q6nlg   1/1     Running   0          61s
webserver                 1/1     Running   0          3h20m

 

pod 생성할 내용을 파일로 생성해 봅니다.

--dry-run 플래그를 사용하여 실제로 제출하지 않고 클러스터로 보낼 오브젝트를 미리 볼 수 있습니다.

리다이텍션으로 파일로 저장할 수도 있습니다.

kubectl run webserver --image=nginx --port 80 --dry-run=client -o yaml > webser.yaml

yaml 파일로 pod를 생성합니다. 기존에 생성한 이름과 동일한 pod를 생성하므로 기존 pod를 삭제한 후 실행합니다.

## 기존 webserver pod 삭제
$ kubectl delete pod webserver

## yaml 파일로 pod 생성
$ kubectl create -f webserver.yaml

## 생성된 pod 확인
$ kubectl get pods

 

[참고] kubectl create vs apply 

 

kubectl create
kubectl create는 명령형 관리를 위한 것입니다. 이 접근 방식에서는 생성, 교체 또는 삭제하려는 항목을 Kubernetes API에 알립니다. 간단히 말해서 create는 새 객체를 생성합니다. 리소스가 이미 있는 경우 오류가 발생합니다.

 

kubectl apply

kubectl apply는 다른 변경 사항을 개체에 적용하더라도 라이브 개체에 적용했을 수 있는 변경 사항(즉, 규모를 통해)이 "유지 관리"되는 선언적 관리 접근 방식의 일부입니다.
apply는 우리가 필요로 하는 것을 정의함으로써 기존 객체를 점진적으로 변경합니다. 리소스가 이미 있는 경우 오류가 발생하지 않습니다.

 

pod 삭제

예제) kubectl delete pods <pod> : <pod> 부분에 삭제할 pod 이름을 입력합니다.

kubectl delete pods webserver

 

 

 

Initializing control-plane node

control-plane 노드는 etcd(클러스터 데이터베이스) 및 API 서버(kubectl 명령줄 도구가 통신함)를 포함하여 control-plane 구성 요소가 실행되는 시스템입니다.

 

1. (권장) 이 단일 control-plane kubeadm 클러스터를 고가용성으로 업그레이드할 계획이 있는 경우 --control-plane-endpoint를 지정하여 모든 control-plane 노드에 대한 endpoint 설정해야 합니다. 이러한 endpoint 는 DNS 이름 또는 로드 밸런서의 IP 주소일 수 있습니다.

2. Pod 네트워크 추가 기능을 선택하고 kubeadm init에 전달되는 인수가 필요한지 확인합니다. 선택한 타사 공급자에 따라 --pod-network-cidr을 공급자별 값으로 설정해야 할 수도 있습니다.

3. 

 


# initialize kubernetes with a Flannel compatible pod network CIDR
kubeadm init --pod-network-cidr=10.244.0.0/16;

# setup kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config;

# install Flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml;

# install Dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc2/aio/deploy/recommended.yaml;
cat > dashboard-admin.yaml <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard
EOF
kubectl delete clusterrolebinding/kubernetes-dashboard;
kubectl apply -f dashboard-admin.yaml;

# get the dashboard secret and display it
kubectl get secret -n kubernetes-dashboard \
| grep kubernetes-dashboard-token- \
| awk '{print $1}' \
| xargs kubectl describe secret -n kubernetes-dashboard;

 

 

 

 

'쿠버네티스' 카테고리의 다른 글

쿠버네티스 - namespace  (0) 2022.05.09
쿠버네티스 아키텍처  (0) 2022.05.09
CNI 플러그인 모드  (0) 2022.05.04
쿠버네티스 - 로드 밸런싱  (0) 2022.04.27
쿠버네티스 - katacoda  (0) 2022.04.26

+ Recent posts