#1 Kubernetes 기본
1. 정의
- Linux 컨테이너 작업을 자동화하는 오픈소스 플랫폼
- 컨테이너화된 애플리케이션을 배포하고 확장하며 수동 프로세스 필요치 않음
- 클러스터는 퍼블릭, 프라이빗, 하이브리드 클라우드 전체로 호스트 확장 가능
2. 개념
- Observe : 현재 상태
- Diff : 현 상태가 아닌 요구사항
- Act : 현 상태를 요구사항 상태로 만들기 위해 현 상태를 변경
- 상태체크(ovserve) -> 차이점 발견(diff) -> 조치(act) -> 상태체크(observe) -> loop
=> 이러한 loop 프로세스를 Controller라고 부름.
3. Container Orchestration Tools
- Container의 배포, 관리, 확장, 네트워킹을 자동화하는 기술
- 목적
- 여러 컨테이너의 배포 프로세스를 최적화하며, 컨테이너와 호스트 수 증가 시 사용 가치 상승
- 기능
- 컨테이너 자동 배치 및 복제, 그룹에 대한 로드 밸런싱
- 장애 복구, 외부에 서비스 노출, 확장 및 축소
4. 사용 이유
- 애플리케이션은 여러 컨테이너에 걸쳐 있고 이러한 컨테이너는 여러 서버 호스트에 배포
- 지속적 상태 관리, 여러 컨테이너에 걸쳐 애플리케이션 서비스 구축
5. Container 운영 환경
- Scheduling : 컨테이너를 적절한 서버에 배포하는 역할
- 스케쥴링 외에 컨테이너가 정상적으로 작동하는지 점검, 재시작, 모니터링 등 종합정 관리 환경
#2 구성요소
1. Control Plane Component(Master)
- 클러스터에 관한 전반적인 결정( ex 스케쥴링 )을 수행하고 이벤트 감지
- 클러스터 내 어떠한 머신에서도 동작 가능
2. Node Component
- Kubelet
- 클러스터 각 노드에서 실행되는 에이전트
- Pod에서 컨테이너가 확실하게 동작하도록 관리 - 생명주기
- Pod 내부의 컨테이너의 이상유무를 주기적으로 Master에 상태 전달
- Kube-proxy
- 각 노드에서 실행되는 네트워크 프록시로 쿠버네티스의 서비스 개념 구현부
- 노드의 네트워크 규칙 유지 관리
- Userspace
- 클라이언트에서 서비스IP 통해 요청
- iptables거쳐 kube-proxy가 요청 받음
- 그 서비스IP가 연결되어야 하는 적절한 Pod 로 연결
- Round Robin 방식
- Iptables
- 관리하는 역할과 직접 클라이언트로부터 트래픽을 받지 않음
- 모든 요청은 iptables를 거쳐 직접 Pod로 전달
- iptables는 Pod 하나로 가는 요청을 실패 시 재시도 않고 요청 실패
- 이와 반대되게 Userspace 모드는 요청 실패시 자동으로 다른 Pod로 연결 재시도
- 이를 방지하기 위해 Readiness probe 설정 필요
- Container Runtime
- 컨테이너 실행을 담당하는 소프트웨어
#3 Objects
1. Pod
- Kubernetes에서 배포 할 수 있는 가장 작은 단위
- 한 개 이상의 컨테이너와 스토리지, 네트워크 속성을 가짐
- 서로 Localhost로 접근 가능
- 컨테이너 하나만 사용하는 경우도 반드시 Pod로 감싸서 관리
2. NameSpace
- 한 쿠버네티스 클러스터 내 논리적 분리단위
- Pod, Service 등은 namespace 별 생성/관리 가능
- 역할
- 사용자별 namespace별로 접근 권한 다르게 운영
- namespce 별 리소스의 할당량 지정
- 리소스를 나눠서 관리
#4 Controller
1. 종류
- Replication Controller( RC )
- Replication Set : RC이후의 버전
- Pod 여러 개를 복제하여 관리하는 오브젝트
- Pod생성하고 개수 유지하려면 반드시 Replicaset 사용
- DaemonSet
- Pod가 각 노드에서 하나씩만 실행
- 특정 Node들에만 Pod가 하나씩만 배포되도록 설정 가능 - 'node selector'를 이용
- Job, StatefulSet
- Deployment
#5 실습
1. 서버 3개의 EC2 인스턴스 생성( Master, Worker1, Worker2)
2. Security Group : 하나의 그룹에 Master와 Worker 모두 설정
22 : ssh server
80 : http, web port
443 : https
모든 ICMP
6443 : 쿠버네티스 API Server
2379 ~ 2380 : Client API
10250 ~ 10252 : Kubelet API ,...
30000 ~ 32767 : Nodeport Services
3. instance 설정 값
4. 초기 설정 (master, worker1, worker2)
sudo -i
hostnamectl set-hostname master.example.com
bash
apt update
apt install net-tools -y
// ip를 할당 받을 수 있도록 툴을 설치
vim /etc/hosts
> [master의 사설IP] master
> [worker1의 사설IP] worker1
> [worker2의 사설IP] worker2
// 각 서버끼리의 통신을 위함으로 ip와 hostname 사이는 tab키로 이용하여 띄어쓴다.
swapoff -a // swap 비활성화
echo 0 > /proc/sys/vm/swappiness
<<패키치 설치(docker, kubernetes)>>
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add –
chmod -R 777 /etc/apt
vim /etc/apt/sources.list.d/kubernetes.list
> deb http://apt.kubernetes.io/ kubernetes-xenial main
wget -qO- get.docker.com | sh // docker 설치
apt-get update
apt-get install -y kubelet kubeadm kubectl kubernetes-cni
<<docker 환경설정 변경>>
usermod -aG docker $USER
vim /etc/docker/daemon.json
> {"exec-opts": ["native.cgroupdriver=systemd"]}
vim /etc/containerd/config.toml
> #disabled_plugins = ["cri"] // 앞에 # 만 붙여주어 주석처리 한다.
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
systemctl restart containerd
docker version // version이 나오면 제대로 된 것
<<Kernel 파라미터 변경>>
vim /etc/sysctl.d/k8s.conf
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
sysctl --system // 변경사항 활성화
5. Master 노드 설정 ( Master )
kubeadm config images pull
systemctl enable kubelet
kubeadm init --apiserver-advertise-address 0.0.0.0 \
> --pod-network-cidr=192.168.0.0/16
// 결과값 안의 kubeadm 의 명령어를 worker1, worker2에 작성
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
systemctl status kubelet
kubectl get nodes // 생성한 kubectl의 상태를 확인 -> NotReady 상태임
<<CNI Calico 설치>>
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/ \
> v3.25.1/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/ \
> v3.25.1/manifests/custom-resources.yaml
kubectl get pods --all-namespaces
kubectl get nodes // CNI Calico를 설치하며 kubectl의 상태를 Ready로 전환
6. Worker Node 설정 ( Worker1, Worker2 )
systemctl enable kubelet // kubelet을 활성화시킴
kubeadm join ~
// Master Node설정 시 생성된 명령어를 kubelet 활성화 후 작성
kubectl get nodes -o wide
// 각 노드에도 kubelet이 생긴 것을 확인
7. Kubernetes Cluster Test ( Master )
kubectl cluster-info // kubenetes cluster 세부정보 확인
<<Deployment, Service 생성>>
kubectl create deployment nginx-server --image=nginx --port=80
kubectl create service nodeport nginx-server --tcp=80:80
kubectl get pods -o wide
// 생성된 pods의 세부정보로 deploy가 어느 노드에 생성되었는지 확인
kubectl get svc -o wide
// 생성된 service 세부정보로 부여된 NodePort를 확인
curl [생성된 노드 이름]:[NodePort번호]
8. Deploy 복제
kubectl scale deploy nginx-server --replicas=4
kubectl get pods -o wide
// 4개의 복제품을 만들어도 master에는 할당되지 않고 worker에만 할당되는 모습 확인
kubectl scale deploy nginx-server --replicas=2
kubectl get deploy
// 복제는 총 2개가 되는 것으로 마무리
9. Pods Object 삭제
kubectl delete deployment nginx
kubectl delete service nginx
kubectl get pods
// 삭제 된 것 확인
#6 Pods & Namespace 실습
1. Pod 생성 및 정보 확인
kubectl create namespace nginx-app
kubectl get namespaces // 생성된 namespace 확인
wget https://raw.githubusercontent.com/ahmetb/kubectx/master/kubens
chmod +x kubens //kubens에 실행 권환 부여
cp kubens /usr/bin/
kubens nginx-app // 생성한 namespace의 nginx-app 실행
kubectl create deploy nginx --image=nginx
kubectl get deploy
kubectl get pods -o wide
kubectl scale deploy nginx --replicas=3
kubectl get pods -o wide
kubectl create service nodeport nginx --tcp=80:80
kubectl get svc -o wide
kubectl describe deployments nginx
// describe는 docker의 inspect와 같은 의미로 세부정보 확인을 의미
2. Pod 접속 및 오브젝트 삭제
kubectl get pods // pods 이름 확인
kubectl exec -it nginx-6799fc88d8-f98wx -- /bin/bash
// pods의 이름을 포함하여 접속
> echo 'Nginx index page' > /usr/share/nginx/html/index.html
> exit
kubectl exec nginx-6799fc88d8-f98wx -- cat /usr/share/nginx/html/index.html
// cat을 통하여 해당 경로의 파일 내용 확인
kubectl delete svc nginx
kubectl delete deployment nginx
3. 템플릿 이용 Pod 생성
vim nginx-app.yaml
<더보기 참조>
kubectl apply -f nginx-app.yaml // 작성한 파일 적용 및 deploy 생성
kubectl get deploy
kubectl expose deployment nginx-app --type=NodePort
// NodePort를 가지게 deploy 생성
kubectl get svc -o wide // NodePort 번호 확인
kubectl get pods -o wide // 생성된 pods의 노드 확인
curl [노드이름]:[NodePort 번호]
- nginx-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
labels:
app: nginx-app
spec:
replicas: 1
selector:
matchLabels:
app: nginx-app
template:
metadata:
labels:
app: nginx-app
spec:
containers:
- name: nginx-app
image: nginx
ports:
- containerPort: 80
cf. ubuntu의 비밀번호
grep ubuntu /etc/passwd /etc/shadow
<그림1> -> ! : 비밀번호가 없다는 뜻
Passwd ubuntu // 비밀번호 설정
>new password
>reply
grep ubuntu /etc/passwd /etc/shadow
<그림2>
4. Pod 자원 할당 및 환경 변수
kubectl create namespace pod-test
kubens // 생성한 namespace가 활성화 되어 있는거 확인
kubens pod-test
vim pod-resource.yaml
<그림 3 참조>
kubectl apply -f pod-resource.yaml // Pod 생성
kubectl describe pod kubernetes-pod-test
// pod의 이름 작성 (kuber ~ -test)하여 세부 내용을 확인하며 yaml에 작성한 내용 확인
<<환경변수>>
vim pod-resource.yaml
// <그림 4>의 내용을 추가
kubectl apply -f pod-env.yaml
kubectl exec -it kubernetes-pod-test -- sh // 환경 변수 확인으로 해당 pod에 접속
> env // 방금 추가한 내용을 확인
그림 3 | 그림 4 |
#7 Controller
1. Replicaset
- replicaset-nginx.yaml
kind: ReplicaSet
metadata:
name: nginx-replicaset
spec:
template:
metadata:
name: nginx-replicaset
labels:
app: nginx-replicaset
spec:
containers:
- name: nginx-replicaset
image: nginx
ports:
- containerPort: 80
replicas: 3
selector:
matchLabels:
app: nginx-replicaset
vim replicaset-nginx.yaml
<더보기 참조>
kubectl apply -f replicaset-nginx.yaml // 생성한 .yaml 파일로 pods생성
kubectl get pods -o wide // 생성한 pods 세부정보 확인
kubectl delete pod [생성된 pods의 이름]
kubectl get pods -o wide // replicaset으로 인하여 지워도 다시 3개인 것을 확인
kubectl get replicaset
// replicaset을 몇으로 지정하였는지 확인. 이는 .yaml 내에서 지정한다.
kubectl delete replicaset nginx-replicaset --cascade=orphan
// orphan을 통해 replicaset과 pods를 분리
- Replicaset과 Pods를 분리시키지 않는 이상, pods를 아무리 지워도 지정해놓은 숫자만큼 계속해서 생긴다.
- 분리 후 pods가 지워지고 2개인 것을 확인가능하지만, apply릍 통해 사기 연결 시 자동으로 pods가 생긴다.
2. Deamonset
- 클러스터 전체 노드에 특정 Pod를 실행 시 사용하는 컨트롤러
-
더보기
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: k8s.gcr.io/fluentd-elasticsearch:1.20
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
vim daemonset.yaml
<더보기 참조>
kubens kube-system
kubectl apply -f daemonset.yaml
kubectl get pods -o wide | grep fluentd
<그림>
kubectl delete daemonset fluentd-elasticsearch
3. Statefulset
- 상태를 가지고 있는 Pod들을 관리하는 컨트롤러
- 특정데이터를 기록하고 그것을 pod 재시작해도 이를 유지
- statefulset.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
vim statefulset.yaml
<더보기 참조>
kubectl create ns pod-test
kubens pod-test
kubectl apply -f statefulset.yaml
kubectl get pods -o wide // 각 worker에 트래픽을 분산하여 고르게 분포하는 것을 확인
4. Cronjob
- job을 시간 기준으로 관리
- 지정한 시간에 한번만 실행하거나 지정한 시간동안 주기적으로 반복 실행
- cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
vim cronjob.yaml
<더보기 참조>
kubectl apply -f cronjob.yaml
kubectl get cronjob // 활성화 된 것을 확인
// 안의 내용 중 ' */1 * * ~ '의 내용은 시간 당 한번이라는 뜻
'Kubernetes' 카테고리의 다른 글
Kubernetes Scheduling (0) | 2023.08.15 |
---|---|
Kubernetes ConfigMap & volume (0) | 2023.08.09 |
Kubernetes Deploy & Service & Ingress (0) | 2023.08.08 |