64/120

김건호·2022년 5월 16일
1

kubeadm으로 worker 노드 추가

join을 사용하여 control plane에 새로운 노드를 추가

kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>

kubeadm init을 하면 token과 키가 생성 됨 -> 하지만 24시간만 유효
따라서 token과 키를 새로 생성

token 생성

kubeadm token create # token 생성
kubeadm token list # 생성된 token 확인

키 생성

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

예시

kubeadm join --token 5didvk.d09sbcov8ph2amjw 192.168.100.100:6443 --discovery-token-ca-cert-hash sha256:8cb2de97839780a412b93877f8507ad6c94f73add17d5d7058e91741c9d5ec78

6443 포트는 api server와 통신하기 위한 포트

Woker Node 추가

  1. VM 추가
  2. Docker 설치
  3. kubeadm kubectl kubelet 설치 1.22.8 버전이 같아야함
  4. kubeadm join 명령어를 실행(work에서 실행)
  5. kubeadm get nodes (control plane에서 실행)
NAME           STATUS   ROLES                  AGE     VERSION
docker         Ready    control-plane,master   2d18h   v1.22.8
worker   Ready    <none>                 4m38s   v1.22.8

고가용성을 위한 토폴로지 구성

stacked etcd topology

엣시디 들이 각각의 cp에 붙어있는 형태

워커노드가 api 서버랑 통신할 수 있어야 함 -> load balancer를 구성
join 시 워커노드는 haproxy 주소를 잡아줘야 함
kubeadm init 할때 로드밸런서 미리 구성하고 로드밸런서 주소를 미리 정의

external etcd tpolgy


별도의 vm에 엣시디들이 있음
엣시디 = key vaule 스토리지-> IO가 많기 때문에 성능이 중요 -> 별도의 VM으로 구성하는것을 추천함

쿠버네티스 버전 업그레이드

skew

버전의 차이 개념
쿠버네티스 아키텍쳐의 구성 요소는 각각의 버전을 가지고 있음

버전 업데이트를 할때 모두다 한꺼번에 버전을 올리게 되면 구성요소들은 컨테이너로 되어 있기 때문에 -> 버전 업그레이드를 한다 -> 이미지를 교체한다
하지만 이미지만 교체하는법은 존재 하지 않음 -> 기존 컨테이너 지우고 새로운 컨테이너 이미지 띄어야함 -> 결국에는 downtime 이 발생

쿠버네티스 버전은 x.y.z로 표현되는데, 부분별로 업데이트 api 로 통신 해야하기때문에 버전이 다를경우 어디까지 지원가능한지가 버전 차이라고 함

  1. kube-apiserver
  2. kube-controller-manager, kube-cloud-controller-manage, kube-scheduler
  3. kubelet(Control Plane -> Worker Node)
  4. kube-proxy(Control Plane -> Worker Node)

Control Plane(api -> cm, ccm, sched -> let,proxy) --> Work Node(let, proxy)

kubeadm 업그레이드

  1. Control Plane의 kubeadm 업그레이드
  2. Control Plane의 kubeadm으로 api, cm, sched 업그레이드
  3. Control Plane의 kubelet, kubectl 업그레이드
  4. Work Node의 kubeadm 업그레이드
  5. Work Node의 kubeadm으로 업그레이드
  6. Work Node의 kubelet, kubectl 업그레이드

Control Plane 업그레이드

sudo apt-mark unhold kubeadm
sudo apt update
sudo apt upgrade kubeadm=1.22.9-00 -y
kubeadm version
sudo apt-mark hold kubeadm
sudo kubeadm upgrade plan
sudo kubeadm upgrade apply v1.22.9
sudo apt-mark unhold kubelet kubectl
sudo apt upgrade kubectl=1.22.9-00 kubelet=1.22.9-00 -y
sudo apt-mark hold kubelet kubectl
kubelet --version
kubectl version

drain 작업

sudo systemctl daemon-reload
sudo systemctl restart kubelet

uncordon 작업

systemctl status kubelet

Work Node 업그레이드

sudo apt-mark unhold kubeadm
sudo apt update
sudo apt upgrade kubeadm=1.22.9-00 -y
kubeadm version
sudo apt-mark hold kubeadm

`

sudo kubeadm upgrade node

drain 작업

sudo apt-mark unhold kubelet kubectl
sudo apt upgrade kubectl=1.22.9-00 kubelet=1.22.9-00 -y
sudo apt-mark hold kubelet kubectl
kubelet --version
kubectl version
sudo systemctl daemon-reload
sudo systemctl restart kubelet

uncordon 작업

Kubespray

kubeadm vs kubespray

https://kubespray.io/#/
https://github.com/kubernetes-sigs/kubespray

kubespray로 클러스터 구성

Control Plane 1개
Work Node 3개(1 Control Plane + 2 Worker Node)

CPU: 2, Memory 3GB

가상머신 생성

node1은 control plane과 work node 기능을 동시에 수행
~/vagrant/k8s

Vagrant.configure("2") do |config|
	# Define VM
	config.vm.define "k8s-node1" do |ubuntu|
		ubuntu.vm.box = "ubuntu/focal64"
		ubuntu.vm.hostname = "k8s-node1"
		ubuntu.vm.network "private_network", ip: "192.168.100.100"
		ubuntu.vm.provider "virtualbox" do |vb|
			vb.name = "k8s-node1"
			vb.cpus = 2
			vb.memory = 3000
		end
	end
	config.vm.define "k8s-node2" do |ubuntu|
		ubuntu.vm.box = "ubuntu/focal64"
		ubuntu.vm.hostname = "k8s-node2"
		ubuntu.vm.network "private_network", ip: "192.168.100.101"
		ubuntu.vm.provider "virtualbox" do |vb|
			vb.name = "k8s-node2"
			vb.cpus = 2
			vb.memory = 3000
		end
	end
	config.vm.define "k8s-node3" do |ubuntu|
		ubuntu.vm.box = "ubuntu/focal64"
		ubuntu.vm.hostname = "k8s-node3"
		ubuntu.vm.network "private_network", ip: "192.168.100.102"
		ubuntu.vm.provider "virtualbox" do |vb|
			vb.name = "k8s-node3"
			vb.cpus = 2
			vb.memory = 3000
		end
	end

	# 패스워드 인증 활성화 ansible에 필요한 ssh 키를 배포하기 위한 ssh-copy-id를 위해
	config.vm.provision "shell", inline: <<-SHELL
	  sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
	  sed -i 's/archive.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list
	  sed -i 's/security.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list
	  systemctl restart ssh
	SHELL
end

1. SSH 키 생성 및 복사

ssh-keygen
ssh-copy-id vagrant@192.168.100.100
ssh-copy-id vagrant@192.168.100.101
ssh-copy-id vagrant@192.168.100.102

2. kubespray 소스 다운로드

cd ~
git clone -b v2.18.1 https://github.com/kubernetes-sigs/kubespray.git
cd kubespray

3. ansible, netaddr, jinja 등 패키지 설치

sudo apt update
sudo apt install python3-pip -y
sudo pip3 install -r requirments.txt # 가상환경 아니라 글로벌이라 sudo

4. 인벤토리 구성

로컬이 있고 샘플이있음
로컬 : 자기 자신 혼자 설치할때
샘플 : 실제 클러스터 설치할 때
그룹명을 바꿔선 안됨

cp -rpf inventory/sample/ inventory/mycluster

inventory/mycluster/inventory.ini

[all]
node1 ansible_host=192.168.100.100 ip=192.168.100.100
node2 ansible_host=192.168.100.101 ip=192.168.100.101
node3 ansible_host=192.168.100.102 ip=192.168.100.102

[kube_control_plane]
node1

[etcd]
node1

[kube_node]
node1
node2
node3

[calico_rr]

[k8s_cluster:children]
kube_control_plane
kube_node
calico_rr

5. 변수 설정

kubespary 변수의 정의 및 정리
inventory/mycluster/group_vars

6. 플레이북 실행

  • inven파일에 작성된 호스트로 ping을 보내 정상적으로 작성됐는지 확인
ansible all -m ping -i inventory/mycluster/inventory.ini
  • kubespray의 cluster.yml로 클러스터 생성 시작
ansible-playbook -i inventory/mycluster/inventory.ini cluster.yml -b 

7. 검증

https://kubespray.io/#/docs/getting-started

localhost:8080 refuse api

서버통신이 안되는것 왜 ? 인증정보가 없어서 그럼

인증정보 생성
mkdir ~/.kube
sudo cp /etc/kubernetes/admin.conf ~/.kube/config
sudo chown vagrant:vagrant ~/.kube/config

노드 확인

kubectl get nodes

노드들은 Ready 상태이어야함

pods 확인

kubectl get pods -A

Ready와 STATUS는 1/1과 Running 이어야 함

kubectl get pods -A -o wide : 상세하게 보기

Kubernetes Objects

kubectl api-resouces
쿠버네티스에서 생성할수잇는 모든 오브젝트 다 나옴
- Label/LabelSelector 중요 어떤 객체와 특정 다른 개체와 연결이 됨-> 연관성을 가짐
- 컨트롤러와 pod의 관계처럼 연관관계 에서 사용하는 개념
- AWS의 태그 
- 오브젝트와 오브젝트의 관계를 정의할때 사용

- Workload # 두개로 나누어짐 pod와 controller 핵심은 pod
	- Pod #  핵심 컨테이너보다 pod가 더 큰 개념
	- Controller # pod를 제어 직접만들어서 쓰는경우는 없고 컨트롤러를 통해 pod만들어서 사용 무엇을? pod를 제어 어떻게 제어할지는 방법이 다 다름
		- ReplicationController # pod 를 복제 더이상 안씀
		- ReplicaSets # 얘가 대체 기능은 같음
		- DaemonSets # 데몬과 관련 된것들
		- Jobs # 
		- CronJobs # 이 두개는 배치 작업 시작과 끝이 있는ㄴ 위에 나머지는 시작만있는
		- Deployments # 핵심은 배포 얘가 레플리카셋 관리 레플리카셋이 pod관리
		- StatefulSets # stateful, stateless 상태가 있는(대표가 얘고) 상태가 없는(대표 위에 배포)
		- HorizontalPodAutoscaler # 컨트롤러의 분류에 바로직접 포함되지는 않지만 일반적으로 pod를 관리하기때문에 분류 HPA pod의 오토스케일링 담당


- Network # 깊이 있게 못함
	- Service # 핵심 -> kubectl expose로 서비스 만든거 L4 로드밸런서
	- Endpoints # 서비스와 연관 로드밸런스의 백엔드 정의하고 관리하는 리소스
	- Ingress # 핵심 쿠버네티스 기본에 없고 애드온으로 추가 L7 로드밸런서 pod의 로드밸런싱

- Storage # 조금 다른 개념 1번2번
	- PersistentVolume # PV 저장소 볼륨을 정의
	- PersistentVolumeClaim # PVC pod가 볼륨을 사용하기위해 claim 요청을 함
	- ConfigMap # 엄밀히말하면 맞는데 두개는 간단한 키벨류 스토리지
	- Secret

- Authentication # 인증 쿠버네시트 클러스터가 있고 kubectl 클라이언트가 접속 접속할때 인증이 필요함 인증파일에서 홈디렉토리에 ~/.kube/config 와 관련된 내용들
	- ServiceAccount # SA 계정(account) 계정과 관련된 개념
	- RBAC # 역할기반의 접근제어 쿠버네티스 기본적으로 역할기반에 접근제어
		- Role # 역할
		- ClusterRole # 역할로 끝나면 역할
		- RoleBinding # 바인딩으로 끝나면 계정과 어카운트를 연결할때 사용하는게 바인드
		- ClusterRoleBinding

- Resource Isolation 
	- Namespaces # 리소스 분류, 위에 모든 내용이 리소스, 도커 네임스페이스와 관련 없음

- Resource Limits # 리소스 제한을 걸때 리소스 주로 pod 
	- Limits
	- Requests
	- ResourceQuota
	- LimitRange

- Scheduling # CP에 보면 스케쥴러 스케쥴링을 조정하는 방법 (제발 다시보기)
	- NodeName 파드를 어디에 배치할지 (한번보기)
	- NodeSelector 파드를 어디에 배치할지
	- Affinity 선호도 파드와 노드와의 관계 파드와 파드와의 관계 정의
		- Node Affinity
		- Pod Affinity
		- Pod Anti Affinity 서로 싫어함
	- Taints/Tolerations kubeadm 할때 명령어는 본적이 있음 
	- Drain/Cordon # 배출/더 이상 스케쥴링을 못하게 함 drain을 하면 cordon이 됨 그래서 uncordon해준것 업그레이드 할때
profile
Ken, 🔽🔽 거노밥 유튜브(house icon) 🔽🔽

0개의 댓글