63/120

김건호·2022년 5월 13일
1
post-custom-banner

ECR

Amazon Elastic Container Registry
docker hub처럼 이미지를 저장하고 관리하는 서비스

레지스트리 등록

레지스트리 push는 명령어를 통해서만 가능하기 때문에 프로그래밍 방식의 사용자를 생성하여 등록

사용자 생성 및 인증

  1. IAM에서 프로그래밍 방식 인증 사용자 생성
  2. administrator 권한을 가진 그룹에 등록
  3. Access key ID,Secret access key 정보 확인
  4. aws configure로 인증
sudo apt get install awscli
aws configure

리포지토리 생성

  1. ECR 서비스 메뉴의 Repositories를 선택
  2. 리포지토리 생성 클릭
  3. 표시 여부 설정에서 프라이빗을 선택
  4. 리포지토리 이름은 실제 접속할 주소. 유일한 주소가 되도록 입력
  5. 태그 변경은 불가능 비활성화
    태그 변경 불가능을 하게되면 덮어쓰기가 안 됨
  6. 푸시 명령 보기로 push 하는 법을 확인
  7. 인증 토큰을 검색하고 레지스트리에 대해 Docker 클라이언트를 인증
aws ecr get-login-password --region us-east-1 | 
docker login --username AWS --password-stdin 리포지토리 이름

...

Login Succeeded

aws에서 레지스트리용 패스워드를 랜덤으로 생성 get-login-password로 가져온 후 |파이프라인을 통해 --password-stdin으로 전달
docker login의 username은 AWS로 고정
8. 이미지를 빌드하고 태그를 지정

docker build -t ken2022 .
docker tag ken2022:latest 리포지토리 이름/ken2022:latest
docker push 리포지토리 이름/ken2022:latest
  1. 이미지 push 완료 후 해당 이미지에 관련된 취약성 문제를 확인 할 수 있음

ECS

Amazon Elastic Compute Cloud

클러스터 생성

  1. 클러스터 이름 지정
  2. 네트워킹에서 서브넷 선택

태스크 정의

어떤 이미지로 어떻게 실행할 것인지 미리 셋팅
1. 태스크 정의 패밀리 지정
2. 컨테이너이미지 URL 설정
wordpress:5-apache처럼 도커 허브에서 가져올 수도 있고, ECR 만든 이미지를 가져올 수 있음(ECR에 올린 이미지에 가면 URL이 있음)

배포

  1. 배포 구성 설정 애플리케이션 유형에서 서비스는 -d 옵션과 같은 상태(웹앱), 태스크는 배치 작업(통신사 같은경우 월말에 비용청구 비용청구하기전에 어느 시점까지 언제부터 언제까지 사용량을 계산해야하는데 청구하기 위한 작업을 해줘야함)

쿠버네티스

Linux 컨테이너 작업을 자동화하는 오픈소스 플랫폼
cncf라는 재단에서 코드를 관리

쿠버네티스 장점

  • 자동화된 롤아웃과 롤백
  • 자동화된 복구(도커의 리스타트 정책)
  • 스토리지 오케스트레이션
  • 서비스 디스커버리와 로드 밸런싱

쿠버네티스가 아닌것

Pass가 제공하는 모든 기능을 제공하지는 않음
안되는걸 정확하게 알아야함

  • 앱의 유형을 제약하지 않음. 애플리케이션이 컨테이너에서 구동될 수 있다면, 쿠버네티스에서도 잘 동작할 것이다.
  • 소스코드 배포와 빌드하는 기능은 없음 -> 별도의 CI/CD구성
  • 앱 레벨의 서비스를 제공하지 않음
  • 로깅, 모니터링, 경보 솔루션은 포함되지 않음 -> Promethus를 써서 로깅 모니터링 경보 솔루션을 구축함
  • 특정 언어 같은건 없음, 쿠버네티스도 yaml(언어가 아님) (하나의 데이터 포맷)
  • 머신설정 유지보수 관리 자동복구 시스템 기능은 없음 -> 퍼블릭 클라우드는 관리형 쿠버네티스를 제공 -> 프로바이더가 인프라 관리를 해줌
  • Saas가 아니라 PaaS 임, Log Monitir 없음 소스코드, 배포 depoly 없음 중요한 세가지 개념

쿠버네티스 컴포넌트

클러스터

물리적으로 논리적으로 여러개의 리소스를 하나로 묶어서 사용하는 개념

node

실질적으로 운영하기 위한 컨테이너를 운영해주는 시스템 -> 노드에는 도커가 설치되어야함

kubelet

CRI(Container Runtime Interface)
k8s는 컨테이너 직접관리 안하고 pod라는 객체로 함
kubelet 는 컨테이너 런타임들을 관리해주는 에이전트(누군가가 일을 대신 해주는 사람)

kube-proxy(k-proxy)

네트워크 정책을 세팅을 해서 네트워크 정책을 담당해주는 역할

컨테이너 담당과 네트워크 담당 둘이 나뉘어져 있음

Control plane

노드들을 관리
시스템이 장애가 나면 아무것도 관리할 수 없음 -> spof 가 될 수 있음 ->
컨트롤 플레인은 3대를 두는것을 원칙으로 함
클러스터링은 절대 짝수개로 하지않음 -> 스플릿 브레인(어느 것을 종료시켜야할지, 어디로 찾아가야할지 모르는 문제) 문제가 발생할 수 있기 때문에

api server

모든 쿠버네티스 통신은 이 서버를 거쳐야함 다이렉트 통신 절대 없음 무조건 api서버 거쳐야함
클러스터 전체가 서버
api server 종료되면 전부 끝남 -> 제일 중요

controller manager

컨트롤 플레인을 정확하게는 쿠버네티스 클러스터 전체를 컨트롤 쿠버네티스의 핵심
4가지 기능

  • 노드 컨트롤러 : 워커노드 죽거나 새로 추가될수 있을 때 관리
  • 레플리케이션 컨트롤러 : k8s의 핵심은 컨테이너의 복제, 레플리카, 쿠버네티스는 컨테이너를 직접 컨트롤 하지않음, 대신 pod라는걸 컨트롤 (pod = container가 아니다) 복제를 제어해줌
  • 엔드포인트 컨트롤러 서비스: pod에 네트워크를 제공
  • 서비스 어카운트 토큰 컨트롤러 : 어카운트에 집중, 토큰 -> 인증

컨테이너 복제본, 노드, 네트워크 관리

Cloud Controller Manager

클라우드 컨트롤러 매니저 -> optional 잇어도 되고 없어도 됨
클라우드에 쿠버네티스가 있으면 즉, 관리형 서비스에 있으면 노드는 vm 노드간의 통신을 해야함. 노드랑 control plane 통신도 해야함

클라우드와 연결을 하는게 CCM. 온프렘에서 이런구성은 필요도 없고 안함
클라우드 서비스 써도 안보임 -> 관리형으로 추상화되기 때문에 이런 구성을 볼 수가 없음

scheduler

노드 세개가 있는데 1번2번 3번노드 어디에 컨테이너를 배치할 것인가? -> 스케쥴려 운영체제, 커널에서 가장 중요 = 스케줄러 => 우리가 실행한 앱이 자원을 얼만큼 쓰게할것인가
pod를 어디다가 배치시킬것인지 스케쥴링을 담당

etcd

etc daemon의 약자
key value 스토리지(저장소)
쿠버네티스에서 강조하는게 있는게 -> 선언적이다 desired state
쿠버네티스는 모든걸 선언함 yaml방식으로 선언
우리가 만드려고하는 pod를 어떻게 만들지 선언

선언적인 데이터를 엣시디에 저장 -> 엣시디 고장나면 다 안됨
docker inspect실행 시 나오는 json정보, 네트워크정보, 컨테이너정보, 모든 정보를 엣시디에 저장
엣시디의 핵심은 클러스터를 구성해야한다
위에 다른 것들은 비상태저장이기때문에 다시 실행하면 됨 장애가 나면 -> statelss기 때문에

엣시디는 데이터를 저장하니까 데이터가 없어지면 데이터에 접근못하면 아무것도 할 수가 없음

control plan도 클러스터 => kubelet k-proxy는 control plan에도 존재

애드온

쿠버네티스가 하지못하는 기능들이 많음
언급이되지 않는 모든것들을 하려면 애드온을 붙임

DNS 애드온

다른말로는 kube-dns 꼭 기억
클러스터 dns를 갖추어야한다 -> 서비스 디스커버리

클러스터 내에서 컨테이너가 여러 개 있는 경우, 1번 컨테이너, 2번 컨테이너를 어떻게 찾을 것인지 -> DNS 사용
클러스터 외부에 사용하는 DNS와는 다른 개념

CoreDNS

쿠버네티스 내에 dns 사용하는 오픈소스

애드온 은 너무많은데 dns 는 필수 필수 필수!! 안쓰면 너무 복잡해서 반드시 사용

클러스터 레벨 로깅

elk ElasticSearch오픈소스로 로깅

쿠버네티스 설치

  • kubeadm 방식 - 일반적 자동화가 안되기 때문에 관리는 힘든 편
  • kubespray (kubeadm + Ansible) 방식
  • minikube 방식 : 멀티플랫폼을 지원 -> 로컬에다가 vm으로 쿠버네티스를 구성

kubeadm 설치

쿠버네티스 설치를 위한 도구

세가지 도구 설치

kubeadm, kubelet kubectl

  • kubeadm: 클러스터를 부트스트랩하는 명령
  • kubelet: 클러스터의 모든 머신에서 실행되는 파드와 컨테이너 시작과 같은 작업을 수행하는 컴포넌트
  • kubectl: 클러스터와 통신하기 위한 커맨드 라인 유틸리티
  1. apt 패키지 업데이트하고, 쿠버네티스 apt 리포지터리를 사용하는 데 필요한 패키지를 설치
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
  1. 구글 클라우드의 공개 사이닝 키를 다운(서명키)
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
  1. 쿠버네티스 apt 리포지터리를 추가(리포지토리 추가)
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
  1. apt 패키지 업데이트(리포지토리를 추가했으므로) kubelet, kubeadm, kubectl을 설치하고 해당 버전을 고정한다.
sudo apt-get update # 저장소 추가했으니까 업데이트
sudo apt-get install kubeadm=1.22.8-00 kubelet=1.22.8-00 kubectl=1.22.8-00
sudo apt-mark hold kubelet kubeadm kubectl

패키지 업데이트시 쿠버네티스까지 업데이트 되어선 안 되기때문에 apt-mark hold로 잠금

k8s 클러스터 생성

kubeadm init

control-plane node를 init

sudo kubeadm init --control-plane-endpoint 192.168.100.100 --pod-network-cidr 172.16.0.0/16 --apiserver-advertise-address=192.168.100.100

control plane의 엔드포인트와
pod의 네트워크 대역 : pod네트워크 연결하기 위한 네트워크가 있어야함
api server가 사용할 ip를 설정하여 init

https://github.com/kelseyhightower/kubernetes-the-hard-way
쿠버네티스 설치를 어렵게 하는 법-> 쿠버네티스의 동작 원리를 알기에 좋음

인증파일 생성

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

쿠버네티스에 인증하기 위한 파일
노출되어서는 안 됨

확인

kubectl get nodes

NAME     STATUS     ROLES                  AGE   VERSION
docker   **NotReady**   control-plane,master   14m   v1.22.8

pod network 구성 마무리

kubeadm init에서는 네트워크 대역만 지정했음 -> addon을 완성하지 않음
네트워크 방식 종류
calico 사용

calico

self-managed on-prem

클러스터에 operator 설치
kubectl create -f https://projectcalico.docs.tigera.io/manifests/tigera-operator.yaml
custom 리소스 다운 및 수정
curl https://projectcalico.docs.tigera.io/manifests/custom-resources.yaml -O

vi custom-resources.yaml
...
cidr: 172.16.0.0/16 # pod netwwork 랑 맞춰줌
...
calico 설치
kubectl create -f custom-resources.yaml

모든 pod의 목록 확인

watch kubectl get pods -A 

전부다 러닝상태여야함

노드는 레디상태가 되어야함

격리 해제

control plane과 node가 한대에 동시에 있는 경우
컨테이너가 실행하지 못하도록 격리가 되어잇는 것을 풀어줘야함

kubectl taint node docker node-role.kubernetes.io/master-

kubelet이 실행이 안 돼요❗❗

cgroup error

https://github.com/kubernetes/kubeadm/issues/2605
cgroupfs 드라이버는 사용이 권장되지 않음
컨테이너 런타임에서는 systemd사용을 권장

현재 cgroup driver는 cgroupfs
docker info | grep 'Cgroup Driver'
 
 Cgroup Driver: cgroupfs
cgroupd driver 마이그레이션

/etc/docker/daemon.json

{
  "exec-opts": ["native.cgroupdriver=systemd"]
}
컨테이너 런타임 재시작
sudo systemctl restart docker
변경 확인
docker info | grep 'Cgroup Driver'

 Cgroup Driver: systemd
데몬 재시작 및 kubelet 재시작
sudo systemctl daemon-reload && sudo systemctl restart kubelet

간단한 예제

서비스 배포

이미지 받아오기
kubectl create deployment myweb --image=ghcr.io/c1t1d0s7/go-myweb
이미지로 배포
kubectl get deployments,replicasets,pods

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/myweb   1/1     1            1           4m40s

NAME                              DESIRED   CURRENT   READY   AGE
replicaset.apps/myweb-97dbf5749   1         1         1       4m40s

NAME                        READY   STATUS    RESTARTS   AGE
pod/myweb-97dbf5749-8tq2l   1/1     **Running**   0          4m40s
expose pod를 외부로 노출 -> 서비스

도커랑 다르게 포트포워딩을 하지 않아도 됨

kubectl expose deployment myweb --port=80 --protocol=TCP --target-port=8080 --name myweb-svc --type=NodePort
배포된 서비스 확인
kubectl get services

NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        40m
myweb-svc    NodePort    10.96.114.201   <none>        80:**31891**/TCP   5s
결과 확인
curl 192.168.100.100:**31891**

Hello World!
myweb-97dbf5749-8tq2l

pod의 개수 늘리기

kubectl scale deployment myweb --replicas=3
kubectl get pods

myweb-97dbf5749-8tq2l   1/1     Running       0          12m
myweb-97dbf5749-9bm8l   1/1     Running       0          3m13s
myweb-97dbf5749-n29m2   1/1     Running       0          3m13s
curl 192.168.100.100:**31891**

생성된 pod에는 오토 스케일링 기능이 자동으로 됨

배포한 서비스 삭제

kubectl delete service myweb-svc
kubectl delete deployment myweb
profile
Ken, 🔽🔽 거노밥 유튜브(house icon) 🔽🔽
post-custom-banner

0개의 댓글