컨테이너 이미지는 애플리케이션과 모든 소프트웨어 의존성을 캡슐화하는 바이너리 데이터를 나타낸다. 컨테이너 이미지는 독립적으로 실행할 수 있고 런타임 환경에 대해 잘 정의된 가정을 만드는 실행 가능한 소프트웨어 번들이다.

 

일반적으로 파드에서 참조하기 전에 애플리케이션의 컨테이너 이미지를 생성해서 레지스트리로 푸시한다.

 

도커 레지스트리

Docker registry is a storage and distribution system for named Docker images. The same image might have multiple different versions, identified by their tags.

도커 퍼플릿 레지스트리

By default, the Docker engine interacts with DockerHub

 

도커 프라이빗 레지스트리

- 파드에 ImagePullSecrets을 명시하기 위해 시크릿을 생성하자

kubectl create secret docker-registry <name> 
--docker-server=DOCKER_REGISTRY_SERVER 
--docker-username=DOCKER_USER 
--docker-password=DOCKER_PASSWORD 
--docker-email=DOCKER_EMAIL

 

참고: 파드는 이미지 풀 시크릿을 자신의 네임스페이스에서만 참조할 수 있다. 따라서 이 과정은 네임스페이스 당 한 번만 수행될 필요가 있다.

 

- 해당 시크릿을 참조하는 파드 생성 예시

cat <<EOF > pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: awesomeapps
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1
  imagePullSecrets:
    - name: docker-registry
EOF

cat <<EOF >> ./kustomization.yaml
resources:
- pod.yaml
EOF

 

이미지 이름 부분 다음에 tag 를 추가할 수 있다. 태그를 사용하면 동일한 시리즈 이미지의 다른 버전을 식별할 수 있다.

 

이미지 태그는 소문자와 대문자, 숫자, 밑줄(_), 마침표(.) 및 대시(-)로 구성된다. 이미지 태그 안에서 구분 문자(_, - 그리고 .)를 배치할 수 있는 위치에 대한 추가 규칙이 있다. 태그를 지정하지 않으면, 쿠버네티스는 태그 latest 를 의미한다고 가정한다.

 

프로덕션에서 컨테이너를 배포할 때는 latest 태그를 사용하지 않아야 한다. 실행 중인 이미지 버전을 추적하기가 어렵고 이전에 잘 동작하던 버전으로 롤백하기가 더 어렵다.
대신, v1.42.0 과 같은 의미있는 태그를 지정한다.

 

보다 정확하게 파드가 같은 버전의 이미지를 사용하게 하고 싶다면 digest를 사용할 수 있다.

image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2

 

만약 파드가 사용하고 있는 digest를 알고 싶다면 아래 명령어를 사용하길 바란다.

kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{","}{range .status.containerStatuses[*]}{.image}{", "}{.imageID}{", "}{end}{end}' | sort

 

이미지 업데이트

디플로이먼트, 스테이트풀셋, 파드 또는 파드 템플릿은 포함하는 다른 오브젝트를 처음 만들 때 특별히 명시하지 않은 경우 기본적으로 해당 파드에 있는 모든 컨테이너의 풀(pull) 정책은 IfNotPresent로 설정된다.

 

이미지 Pull Policy

pull policy 설명
IfNotPresent the image is pulled only if it is not already present locally.
Always every time the kubelet launches a container, the kubelet queries the container image registry to resolve the name to an image digest. If the kubelet has a container image with that exact digest cached locally, the kubelet uses its cached image; otherwise, the kubelet pulls the image with the resolved digest, and uses that image to launch the container.
Never the kubelet does not try fetching the image. If the image is somehow already present locally, the kubelet attempts to start the container; otherwise, startup fails.

 

만약 항상 이미지 풀을 강제하고 싶다면, 다음 중 하나를 수행하면 된다.

  • 컨테이너의 imagePullPolicy를 Always로 설정.
  • imagePullPolicy를 생략하고 :latest를 사용할 이미지의 태그로 사용, 쿠버네티스는 정책을 Always로 설정한다.
  • imagePullPolicy와 사용할 이미지의 태그를 생략.
  • AlwaysPullImages 어드미션 컨트롤러를 활성화.
컨테이너의 imagePullPolicy 값은 오브젝트가 처음 created 일 때 항상 설정되고 나중에 이미지 태그가 변경되더라도 업데이트되지 않는다.
예를 들어, 태그가 :latest가 아닌 이미지로 디플로이먼트를 생성하고, 나중에 해당 디플로이먼트의 이미지를 :latest 태그로 업데이트하면 imagePullPolicy 필드가 Always 로 변경되지 않는다. 오브젝트를 처음 생성 한 후 모든 오브젝트의 풀 정책을 수동으로 변경해야 한다.

 

도커 이미지와 이미지 사이즈

이미지명 이미지 사이즈
scratch 최소
alpine 작다
distroless 작다
ubuntu 크다
centos 크다
Universal Base Image 크다

 


출처

- [Docker Registry] : https://www.aquasec.com/cloud-native-academy/docker-container/docker-registry/

- [책: 쿠버네티스 완벽 가이드 마사야 아오야마 지음, 박상욱 옮김]

- [컨테이너 이미지]

https://kubernetes.io/ko/docs/tasks/access-application-cluster/list-all-running-container-images/

https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images

https://kubernetes.io/ko/docs/concepts/containers/images/

Kubernetes 관리 서비스를 제공하는 대형 클라우드 업체 중 AWS EKS를 통한 k8s 클러스터 생성 과정을 살펴보자.

 

출처 : https://docs.aws.amazon.com/eks/latest/userguide

 

 

첫째, 클러스터 생성

AWS CLI 혹은 eksctl 등으로 EKS 클러스터를 할 수 있는데 eksctl를 이용한 방법을 살펴보자. 그 이유는 eksctl은 클러스터 구성에 필요한 설정을 일반적인 수준에서 알아서 관리해준다. 좀 더 자세한 클러스터 튜닝을 하고 싶다면 AWS CLI를 이용하여 클러스터를 생성하는 것을 추천한다.

 

Prerequisites

- kubectl : A command line tool for working with Kubernetes clusters.

- eksctl : A command line tool for working with EKS clusters that automates many individual tasks.

 

클러스터 생성 옵션

- name : 클러스터 이름

- version : kubernetes 버전

- managed : Node를 Amazon EC2 인스턴스로 생성

- node-type : Amazon EC2 인스턴스 유형

- region : 클러스터 리전

eksctl create cluster \
--name my-cluster \
--version 1.xx \
--node-type t2.xx \
--region us-west-2 \
--with-oidc \
--ssh-access \
--ssh-public-key your-key
--managed

 

클러스터 생성 진행상황을 확인하고 싶다면 CloudFormation을 확인해보길 바란다.

 

클러스터 삭제 역시 아주 간단하다.

eksctl delete cluster --name cluster_name

 

이렇게 eksctl를 이용해서 쿠버네티스 클러스터 생성을 아주 쉽게 완료할 수 있다.

 

둘째, 기본적으로 추가되는 노드그룹 외에 노드그룹 생성

- cluster : 클러스터 이름

- region : 클러스터 리전

- name : 노드그룹 이름

- node-type : 노드그룹 Amazon EC2 인스턴스 유형

- nodes : 노드 요청 개수

- nodes-min : 최소 노드 개수

- nodes-max : 최대 노드 개수

- managed : Node를 Amazon EC2 인스턴스로 생성

eksctl create nodegroup \
  --cluster <my-cluster> \
  --region <region-code> \
  --name <my-mng> \
  --node-type <m5.large> \
  --nodes <3> \
  --nodes-min <2> \
  --nodes-max <4> \
  --ssh-access \
  --ssh-public-key <my-key>
  --managed
  
eksctl scale nodegroup --cluster=clusterName --nodes=desiredCount --name=nodegroupName --region region --nodes-min=3 --nodes-max=6

 

기본적으로 생성된 노드그룹은 아래 내용을 포함하고 있을 것이다.

- coredns : 쿠버네티스 클러스터의 DNS 역할을 수행할 수 있는, 유연하고 확장 가능한 DNS 서버이다. 서비스디스커버리에 활용됨.

- kube-proxy : worker node 사이의 container들의 커뮤니케이션 수단 제공 

- cni : Container Network Interface

- kubelet : master node와 컨테이너 상태 등에 대해서 커뮤니케이션 및 container를 제어하는 역할

 

셋째, kubectl을 이용하여 EKS 클러스터를 관리한다.

넷째, 원하는 워크로드를 생성한 EKS 클러스터에 배포한다.

 

자동으로 생성된 VPC 네트워크 구성에 대해서 살펴보도록 하자.

 

https://aws.amazon.com/ko/quickstart/architecture/vpc/

 

VPC(Amazon Virtual Private Cloud)

1. 인터넷게이트웨이(IGW)

- 응답을 받을때 private ip로 주소변환(NAT)

- enables inbound and outbound access to the internet

- 기타

2. 보안그룹

- SSH 접근 보안 설정

- control plane과 워커 노드그룹 사이 보안 설정

- 클러스터 노드 사이 보안 설정

- CNI 보안 설정

- 기타

3. Subnet

출처 : https://medium.com/awesome-cloud/aws-vpc-difference-between-internet-gateway-and-nat-gateway-c9177e710af6

Private subnet

기본적으로 외부와 차단되어 있고, 다른 서브넷과의 연결만 가능

- 라우팅 테이블

- 네트워크 ACL

- Amazon EC2

 

Public subnet

- NAT 게이트웨이 : 인터넷에서 들어오는 트래픽을 차단. private subnet의 인터넷 요청에 대한 결과를 전달.

NAT(Network Address Translation) : IP 패킷 헤더의 IP 주소를 변경하는 기능을 뜻함. DNAT, SNAT

- 라우팅 테이블

- 네트워크 ACL

- Amazon EC2

4. 로드밸런서

5. 기타

 

이렇게 eksctl를 이용하여 AWS EKS 클러스터 생성과정을 살펴보았다. 

 

이외에 Calico를 이용하여 Networkpolicy를 적용하는 등의 설정을 통해 클러스터 보안을 향상시킬 수 있다. 참고로 클러스터 밖에서 접속하는 트래픽에 대해서는 방화벽 설정을 할 수 없다. 그 이유는 외부에서 클러스터 내부로 들어오는 Source 주소가 변경되기 때문이다.

 

https://github.com/projectcalico/calico/issues/2088#issuecomment-411796428

 


출처

- [networkpolicy from outside] : https://github.com/projectcalico/calico/issues/2088

- [AWS EKS CNI plugins] : https://docs.aws.amazon.com/eks/latest/userguide/calico.html

- [Calico on Amazon EKS] : https://docs.aws.amazon.com/eks/latest/userguide/calico.html

- [Internet Gateway and Nat gateway] : https://medium.com/awesome-cloud/aws-vpc-difference-between-internet-gateway-and-nat-gateway-c9177e710af6

- [NAT Gateway]

https://docs.aws.amazon.com/ko_kr/vpc/latest/userguide/vpc-nat-gateway.html

https://www.youtube.com/watch?v=ujXr0i5EoHE

- [Internet Gateway] : https://www.youtube.com/watch?v=u7obme-h3bc

- [kube-proxy] : https://kubernetes.io/docs/reference/command-line-tools-reference/kube-proxy/

- [CoreDNS] : https://kubernetes.io/ko/docs/tasks/administer-cluster/coredns/

- [EKS nodegroup] : https://docs.aws.amazon.com/eks/latest/userguide/create-managed-node-group.html

- [EKS nodegroup scale] : https://aws.amazon.com/ko/premiumsupport/knowledge-center/eks-worker-node-actions/

- [EKS란] : https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html

- [EKS with eksctl] : https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html

문자열 압축

문제 설명

데이터 처리 전문가가 되고 싶은 "어피치"는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문자열에서 같은 값이 연속해서 나타나는 것을 그 문자의 개수와 반복되는 값으로 표현하여 더 짧은 문자열로 줄여서 표현하는 알고리즘을 공부하고 있습니다.
간단한 예로 "aabbaccc"의 경우 "2a2ba3c"(문자가 반복되지 않아 한번만 나타난 경우 1은 생략함)와 같이 표현할 수 있는데, 이러한 방식은 반복되는 문자가 적은 경우 압축률이 낮다는 단점이 있습니다. 예를 들면, "abcabcdede"와 같은 문자열은 전혀 압축되지 않습니다. "어피치"는 이러한 단점을 해결하기 위해 문자열을 1개 이상의 단위로 잘라서 압축하여 더 짧은 문자열로 표현할 수 있는지 방법을 찾아보려고 합니다.

예를 들어, "ababcdcdababcdcd"의 경우 문자를 1개 단위로 자르면 전혀 압축되지 않지만, 2개 단위로 잘라서 압축한다면 "2ab2cd2ab2cd"로 표현할 수 있습니다. 다른 방법으로 8개 단위로 잘라서 압축한다면 "2ababcdcd"로 표현할 수 있으며, 이때가 가장 짧게 압축하여 표현할 수 있는 방법입니다.

다른 예로, "abcabcdede"와 같은 경우, 문자를 2개 단위로 잘라서 압축하면 "abcabc2de"가 되지만, 3개 단위로 자른다면 "2abcdede"가 되어 3개 단위가 가장 짧은 압축 방법이 됩니다. 이때 3개 단위로 자르고 마지막에 남는 문자열은 그대로 붙여주면 됩니다.

압축할 문자열 s가 매개변수로 주어질 때, 위에 설명한 방법으로 1개 이상 단위로 문자열을 잘라 압축하여 표현한 문자열 중 가장 짧은 것의 길이를 return 하도록 solution 함수를 완성해주세요.

 

제한사항

  • s의 길이는 1 이상 1,000 이하입니다.
  • s는 알파벳 소문자로만 이루어져 있습니다.

 

입출력 예

s result
"aabbaccc" 7
"ababcdcdababcdcd" 9
"abcabcdede" 8
"abcabcabcabcdededededede" 14
"xababcdcdababcdcd" 17

 

입출력 예에 대한 설명

입출력 예 #1

문자열을 1개 단위로 잘라 압축했을 때 가장 짧습니다.

입출력 예 #2

문자열을 8개 단위로 잘라 압축했을 때 가장 짧습니다.

입출력 예 #3

문자열을 3개 단위로 잘라 압축했을 때 가장 짧습니다.

입출력 예 #4

문자열을 2개 단위로 자르면 "abcabcabcabc6de" 가 됩니다.
문자열을 3개 단위로 자르면 "4abcdededededede" 가 됩니다.
문자열을 4개 단위로 자르면 "abcabcabcabc3dede" 가 됩니다.
문자열을 6개 단위로 자를 경우 "2abcabc2dedede"가 되며, 이때의 길이가 14로 가장 짧습니다.

입출력 예 #5

문자열은 제일 앞부터 정해진 길이만큼 잘라야 합니다.
따라서 주어진 문자열을 x / ababcdcd / ababcdcd 로 자르는 것은 불가능 합니다.
이 경우 어떻게 문자열을 잘라도 압축되지 않으므로 가장 짧은 길이는 17이 됩니다.

 


 

private int solution(String s) {
		int N = s.length() / 2;
		int answer = s.length();
		// 완전탐색 - i개로 자른다.
		for (int i = 1; i <= N; i++) {
			int curIdx = 0;
			int cnt = 1;
			StringBuilder sb = new StringBuilder();
			while(true) {
				String curStr = s.substring(curIdx, curIdx + i);
				//System.out.println(String.format("Step1 --- %s", curStr));
				int nextIdx = curIdx + i;
				if(nextIdx >= s.length() || nextIdx + i - 1 >= s.length()) {
					if(cnt > 1) {
						sb.append(cnt);
					}
					sb.append(s.substring(curIdx, s.length()));
					//System.out.println(String.format("Step3 --- %s %d %d %d", s.substring(curIdx, s.length()), cnt, curIdx, s.length()));
					
					break;
				} else {
					String nextStr = s.substring(nextIdx, nextIdx + i);
					//System.out.println(String.format("Step2 --- %s vs %s = %s", curStr, nextStr, curStr.equals(nextStr)));
					if(curStr.equals(nextStr)) cnt++;
					else {
						if(cnt > 1) {
							sb.append(cnt);
						}
						sb.append(curStr);
						cnt = 1;
						
					};
					
					curIdx = nextIdx;
				} 
			}
			//System.out.println(String.format("Step4 --- %s ", sb.toString()));
			if(sb.toString().length() < answer) answer = sb.toString().length();
			
		}
		return answer;
	}

 

 


출처

- https://programmers.co.kr/learn/courses/30/lessons/60057

OS Upgrades

노드의 OS Upgrade를 위해서는 노드를 정지해야한다. 이때 도커 컨테이너의 라이브 마이그레이션에 해당하는 기능이 존재하지 않아 메인터넌스 등으로 노드를 정지하는 경우 파드를 정지해야 한다. 따라서 SIGTERM, SIGKILL 신호에 동작하는 애플리케이션을 만들고 terminationGracePeriodSeconds를 적절하게 설정해야한다.

 

즉, 각 파드에 정지 처리가 실행될 때 안전하게 정지하도록 preStop 설정 / gracefulPeriod 설정 / 애플리케이션 측에서 SIGTERM 신호 핸들링 등과 같은 적절한 준비를 해두어야 한다.

 

쿠버네티스 노드는 SchedulingEnabled(Default)와 SchedulingDisabled 중 하나의 상태를 가진다. 노드가 SchedulingDisabled 상태로 변경되도 이미 노드에서 실행되는 파드에는 영향을 주지 않는다.

 

노드의 OS Upgrade 절차는 아래와 같다.

참고) 테스트를 위해 kube-controller-manager의 --pod-eviction-timeout을 사용할 수 있다.

 

첫째, 파드축출(관련 포드들을 gracefully stop 시키고, 다른 노드에 띄운다.)

배출 처리에는 이후의 스케줄링 대상에서 제외하는 처리가 포함되어 있다.

kubectl drain node_name (--force --ignore-daemonsets --delete-local-data)

--force 옵션 : 단일 파드가 있으면 삭제 후에 재성성되지 않아도 되는 경우.

--delete-local-data 옵션 : 로컬 스토리지를 사용하고 있는 경우 데이터가 삭제해도 되는 경우.

--ignore-daemonsets 옵션 : 데몬셋이 관리하는 파드도 축출하고자 하는 경우.

 

둘째, 해당 노드를 스케줄링 대상에서 제외한다. 이미 노드에서 실행되는 파드에는 영향을 주지 않는다.

kubectl cordon node_name

셋째, OS Upgrade를 진행한다.

넷째, 해당 노드를 스케줄링 대상으로 복귀시킨다.

kubectl uncordon node_name

 


Cluster Upgrade

v1.11.3 : major.minor(features, funtionalites).patch(bug fix)

v1.11.0-alpha > v1.11.0-beta > v1.11.0

kube-apiserver, controller-manager, kube-scheduler, kubelet, kube-proxy, kubectl는 같은 버전의 패키지에 포함된다.

 

kubeadm으로 쿠버네티스 클러스터를 구성했다는 가정하에 master/controlplane components의 버전을 업그레이드 하는 과정을 살펴보겠다.

 

Automatic upgrade by providers(AWS EKS, ...)

# 어떤 버전으로 업그레이드 가능한지 볼수 있음
kubectl upgrade plan
# Upgrade
kubectl upgrade apply

 

Upgrade in a hard way(kubeadm)

Master 노드

첫째, master 노드의 파드를 축출한다.

kubectl drain master --ignore-daemonsets

둘째, kubeadm tool을 업그레이드 한다.

# Kubeadm installation
apt install kubeadm=1.xx.0-00 -y

# Check kubeadm version
kubeadm version

셋째, master components를 업그레이드 한다.

# Upgrade
kubeadm upgrade apply v1.xx.0

# Check if it is Upgraded
# not yet upgraded because kubelet is not upgraded
kubectl version --short
kubectl get nodes

넷째, kubelet을 업그레이드 한다.

# upgrade the kubelet on the master node
apt install kubelet=1.xx.0-00

# Recheck if it is Upgraded
kubectl get nodes

다섯째, master node를 스케줄링 대상으로 복귀시킨다.

# Mark the master/controlplane node as "Schedulable"
kubectl uncordon controlplane

 

Work 노드

첫째, work 노드의 파드를 축출한다.

# Drain the worker node of the workloads and mark it UnSchedulable
kubectl drain node-1 --ignore-daemonsets

둘째, kubeadm tool을 업그레이드 한다.

# Kubeadm installation
apt install kubeadm=1.xx.0-00 -y

# Check kubeadm version
kubeadm version

 

셋째, worker 노드를 업그레이드 한다.

kubeadm upgrade node

넷째, local kubelet configuration을 업그레이드 한다.

# upgrade the kubelet on the worker node
apt install kubelet=1.xx.0-00

# Recheck if it is Upgraded
kubectl get nodes

다섯째, worker 노드를 스케줄링 대상으로 복귀시킨다.

# Mark the worker node as "Schedulable"
kubectl uncordon worker_node

 


ETCD

ETCD is a distributed reliable key-value store that is Simple, Secure & Fast.

HA topology

- stacked etcd architecture : each control plane node creates a local etcd member

출처 : https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/

- external etcd architecture : etcd members run on separate hosts

출처 :&nbsp;https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/

# cat /etc/systemd/system/kube-apiserver.service
[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
  --advertise-address=${INTERNAL_IP}
  --allow-privileged=true \\
  --apiserver-count=3 \\
  --etcd-cafile=/var/lib/kubernetes/ca.pem \\
  --etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\
  --etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\
  --etcd-servers=https://10.240.0.10:2379,https://10.240.0.11:2379

ETCD options

--listen-client-urls(2379 포트)

--listen-peer-urls : 다른 노드에서 접근시 사용(2380 포트)

--cert-file=/etc/kubernetes/pki/etc/server.crt(ETCD server certificate)

--peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt(ETCD CA certificate)

ETCD read & write

  • READ : you can easily read data from any node
  • Write : only one of the instances is responsible for processing the writes. the two nodes elect a leader among them. Of the total instances one node becomes the leader and the other node becomes the followers. If the writes came into the leader node, then the leader processes the write. The leader makes sure that the other nodes are sent a copy of the data. A write in only considered complete, if the leader gets consent from other members in the cluster.

ETCD Leader Election(RAFT protocol)

  • Quorum = N/2 + 1 : If it can be written on the majority of the nodes in the cluster, a write will be successful.
  • Fault Tolerance : HA 구성을 위해서는 1 노드가 죽더라도 Quorum 2를 유지할 수 있게 적어도 3개 노드는 필요함(recommended).
  • Even or Odd : with even number of nodes there is possibility of the cluster faliling during a network segmentation. So need to choose the odd number.
[etcd.service]
ExecStart=/usr/local/bin/etcd \\
  --name ${ETCD_NAME}
  --cert-file=/etc/etcd/kubernetes.pem \\
  --key-file=/etc/etcd/kubernetes-key.pem \\
  --peer-cert-file=/etc/etcd/kubernetes.pem \\
  --peer-key-file=/etc/etcd/kubernetes-key.pem \\
  --trusted-ca-file=/etc/etcd/ca.pem \\
  --peer-trusted-ca-file=/etc/etcd/ca.pem \\
  --peer-client-cert-auth \\
  --client-cert-auth \\
  --initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \\
  --listen-peer-urls https://${INTERNAL_IP}:2380 \\
  --listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \\
  --advertise-client-urls https://${INTERNAL_IP}:2379 \\
  --initial-cluster-token etcd-cluster-0 \\
  --initial-cluster peer-1=https://${PEER1_IP}:2380,peer-2=https://${PEER2_IP}:2380 \\
  --initial-cluster-state new \\
  --data-dir=/var/lib/etcd

<initial-cluster>

ETCDCTL

  • GET/PUT
export ETCDCTL_API=3
etcdctl put name john
etcdctl get name
etcdctl get / --prefix --keys-only

 

ETCD Backup and Restore configuration

  • Git에 Resource configuration(yaml ...)을 저장
  • ETCD : 스냅샷 변경시 --data-dir 설정을 확인하자.
#etcd.service
ExecStart=/usr/local/bin/etcd \\
  --name ${ETCD_NAME} \\
  --cert-file=/etc/etcd/kubernetes.pem \\
  --key-file=/etc/etcd/kubernetes-key.pem \\
  --peer-cert-file=/etc/etcd/kubernetes.pem \\
  --peer-key-file=/etc/etcd/kubernetes-key.pem \\
  --trusted-ca-file=/etc/etcd/ca.pem \\
  --peer-trusted-ca-file=/etc/etcd/ca.pem \\
  --peer-client-cert-auth \\
  --client-cert-auth \\
  --initial-advertise-peer-urls https://${INTERNAL_IP}:
  --listen-peer-urls https:${INTERNAL_IP}:2380 \\
  --listen-client-urls https:${INTERNAL_IP}:2379,
  --adverties-client-urls https:${INTERNAL_IP}:2379 \\
  --initial-cluster-token etcd-cluster-0 \\
  --initial-cluster controller-0=https://${CONTROLLER0_ \\
  --initial-cluster-state new \\
  --data-dir=/var/lib/etcd

 

ETCD - SAVE

ETCDCTL_API=3 etcdctl snapshot save snapshot.db

# With TLS-Enabled
ETCDCTL_API=3 etcdctl \
		snapshot save snapshot.db \
        --endpoints=https://127.0.0.1:2379 \
        --cacert=/etc/etcd/ca.crt \
        --cert=/etc/etcd/etcd-server.crt \
        --key=/etc/etcd/etcd-server.key

ETCD - STATUS

ETCDCTL_API=3 etcdctl snapshot status snapshot.db

ETCD - RESTORE

# Stop kube-apiserver related to ETCD
service kube-apiserver stop

# Restore
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db --data-dir /var/lib/etcd-from-backup

# Option1. change --data-dir (etcd.service)
ExecStart=/usr/local/bin/etcd \\
  --name ${ETCD_NAME} \\
  --cert-file=/etc/etcd/kubernetes.pem \\
  --key-file=/etc/etcd/kubernetes-key.pem \\
  --peer-cert-file=/etc/etcd/kubernetes.pem \\
  --peer-key-file=/etc/etcd/kubernetes-key.pem \\
  --trusted-ca-file=/etc/etcd/ca.pem \\
  --peer-trusted-ca-file=/etc/etcd/ca.pem \\
  --peer-client-cert-auth \\
  --client-cert-auth \\
  --initial-advertise-peer-urls https://${INTERNAL_IP}:
  --listen-peer-urls https:${INTERNAL_IP}:2380 \\
  --listen-client-urls https:${INTERNAL_IP}:2379,
  --adverties-client-urls https:${INTERNAL_IP}:2379 \\
  --initial-cluster-token etcd-cluster-0 \\
  --initial-cluster controller-0=https://${CONTROLLER0_ \\
  --initial-cluster-state new \\
  --data-dir=/var/lib/etcd-from-backup

# Option2. etcd volume 수정
# /etc/kubernetes/manifests/etcd.yaml(etcd pod - static pod)
volumes:
  - hostPath:
      path: /var/lib/etcd-from-backup
      type: DirectoryOrCreate
    name: etcd-data


# Reload daemon
systemctl daemon-reload

# Restart ETCD
service etcd restart

# Start the kube-apiserver
service kube-apiserver start

 

Note:

If any API servers are running in your cluster, you should not attempt to restore instances of etcd. Instead, follow these steps to restore etcd:

  • stop all API server instances
  • restore state in all etcd instances
  • restart all API server instances

We also recommend restarting any components (e.g. kube-scheduler, kube-controller-manager, kubelet) to ensure that they don't rely on some stale data. Note that in practice, the restore takes a bit of time. During the restoration, critical components will lose leader lock and restart themselves.

 

 

ETCD 디버깅

  • docker ps -a | grep etcd
  • docker logs xxx(위 명령어로 docker container id를 얻는다)
  • If the etcd pod is not getting Ready 1/1, then restart it by kubectl delete pod -n kube-system etcd-controlplane and wait 1 minute.

퀴즈

1. How many nodes can host workloads in this cluster?

>> Inspect the applications and taints set on the nodes.

>> taint 걸려있지 않는 노드의 수

 

2. How many applications are hosted on the cluster?

>> Count the number of deployments

 

3. You are tasked to upgrade the cluster. you can't provision new VMs and User's accessing the applications must not be impacted. What strategy would you use to upgrade the cluster?

>> Upgrade one node at a time while moving the workloads to the other

 


출처

- [강의] udemy - Certified Kubernetes Administrator 

- [책] 쿠버네티스 완벽 가이드(마사야 아오야마 지음, 박상욱 옮김)

- https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/#backing-up-an-etcd-cluster

- https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/recovery.md

- https://www.youtube.com/watch?v=qRPNuT080Hk

- https://v1-19.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/

- https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md

- https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md

- https://kubernetes.io/docs/concepts/overview/kubernetes-api/

 

 

 

+ Recent posts