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
## 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으로 모니터링을 합니다.
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
네임스페이스는 단일 클러스터 내에서의 리소스 그룹을 격리하는 메커니즘을 제공합니다. 리소스의 이름은 네임스페이스 내에서 유일해야 하며, 네임스페이스 간에서 유일할 필요는 없습니다. 네임스페이스 기반 영역은 네임스페이스 기반 오브젝트 (예: 디플로이먼트, 서비스 등) 에만 적용 가능하며 클러스터 범위의 오브젝트 (예: 스토리지클래스, 노드, 퍼시스턴트볼륨 등) 에는 적용 불가능하다.
여러 개의 네임스페이스를 사용하는 경우
네임스페이스는 여러 개의 팀이나, 프로젝트에 걸쳐서 많은 사용자가 있는 환경에서 사용하도록 만들어졌다. 사용자가 거의 없거나, 수 십명 정도가 되는 경우에는 네임스페이스를 전혀 고려할 필요가 없다. 네임스페이스가 제공하는 기능이 필요할 때 사용하도록 하자.
네임스페이스는 이름의 범위를 제공한다. 리소스의 이름은 네임스페이스 내에서 유일해야하지만, 네임스페이스를 통틀어서 유일할 필요는 없다. 네임스페이스는 서로 중첩될 수 없으며, 각 쿠버네티스 리소스는 하나의 네임스페이스에만 있을 수 있다.
네임스페이스는 클러스터 자원을 (리소스 쿼터를 통해) 여러 사용자 사이에서 나누는 방법이다.
동일한 소프트웨어의 다른 버전과 같이 약간 다른 리소스를 분리하기 위해 여러 네임스페이스를 사용할 필요는 없다. 동일한 네임스페이스 내에서 리소스를 구별하기 위해 레이블을 사용한다.
네임스페이스 다루기
참고: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이 하트비트를 보내서 컨트롤 플레인이 노드의 장애를 탐지할 수 있게 한다.
서비스를 생성하면 해당 DNS 엔트리가 생성된다. 이 엔트리는 <서비스-이름>.<네임스페이스-이름>.svc.cluster.local의 형식을 갖는데, 이는 컨테이너가 <서비스-이름>만 사용하는 경우, 네임스페이스 내에 국한된 서비스로 연결된다. 개발, 스테이징, 운영과 같이 여러 네임스페이스 내에서 동일한 설정을 사용하는 경우에 유용하다. 네임스페이스를 넘어서 접근하기 위해서는, 전체 주소 도메인 이름(FQDN)을 사용해야 한다.
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
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
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
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
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
해결방법 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 명령어 자동완성 기능을 설정합니다. 명령어의 일부 글자만 타입핑한 후 "탭키"를 누르면 명령어가 완성되는 기능입니다.
containerd를 실행하기 전에 containerd의 기본 설정을 정의해줍니다. containerd config default 를 수행하면 기본적으로 제공하는 설정값들을 얻을 수 있습니다. tee 명령어를 통해 화면으로도 출력하고, config.toml 파일로도 저장합니다.
위 단계를 모두 마쳤다면 이제 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]
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;