컨테이너 한 개로 어플리케이션을 구동한다면 기존 방식도 나쁘지 않습니다.
하지만 요즘 서비스 규모가 커지며 마이크로 서비스 아키텍처가 트랜드입니다.
한 개의 어플리케이션에 수 많은 컨테이너가 필요합니다.
여러 대의 컨테이너를 안정적으로 구동하기 위해 멀티 호스트 도커 플랫폼을 사용하기도 하지만,
여러 대의 호스트, 여러 개의 컨테이너를 관리하기는 쉽지 않습니다.
효율적인 관리 측면에서 쿠버네티스가 등장합니다. - 컨테이너 오케스트레이션
kubernetes.io
운영 수준의 컨테이너 오케스트레이션
컨테이너화된 애플리케이션을 자동으로 배포, 스케일링 및 관리해주는 오픈소스 시스템입니다.
그리스어: 조타수
1) 설치하지 않고 사용하기
카타코다 쿠버네티스 플레이그라운드 - 서비스 종료
Play with the kubernets
2) 가상머신에 설치하기
virtureMachine 8 - 생략
Container간 통신을 지원하는 VxLAN. Pod Network라고도 부릅니다.
다양한 종류의 플러그 인이 존재합니다.
플라넬, 칼리코, 위브넷 등 다양한 종류가 존재합니다.
control plane
워커 노드들의 상태를 관리하고 제어
single master
multi amster(3,5개의 master nodes)
workder node
도커 플랫폼을 통해 컨테이너를 동작하며 실제 서비스 제공
https://www.virtualbox.org/wiki/Downloads
-macOS 지원이 안되어 실제 설치 환경 구축은 생략하겠습니다.
실습 환경을 구축해보겠습니다.
kubectl --help
명령어를 통해 제대로 설치가 되어있는지 확인해봅시다.
control plane이 worker node들에게
" 웹 서버 3개 실행해줘 " 와 같은 명령어를 요청할 때 사용하는 명령어입니다.
kubectl [command] [type] [name] [flags]
ex) kubectl get pod webserver -o wide
command : 자원(Object)에 실행할 명령
type : 자원의 타입
name : 자원의 이름
flags : 부가적으로 설정할 옵션
echo "source <(kubectl completion bash)" >> ~/.bashrc
echo "source <(kubeadm completion bash)" >> ~/.bashrc
저는 컴퓨터에 직접 vm을 설치하는 방법이 아닌
playground에서 실습을 진행해 playground 예시를 보여드리겠습니다.
앞에 설명한 playground 링크를 접속해 docker 나 github계정으로 로그인하면 아래 화면처럼 나오게 됩니다.
좌측에 + ADD NEW INSTENCES를 세번 눌러
3개의 node를 구성해줍니다.
명령어 3개가 보이실텐데
1번 명령어는 마스터 노드를 설정하는 명령어입니다.
2번 명령어는 앞에 설명한 CNI 설치 명령어입니다.
3번 명령어는 nginx 웹서버 설치 명령어입니다.
마스터 노드(node1)에 위 명령어를 모두 실행 후
worker node를 구성해주어야합니다.
instance를 한 개 더 만들고 master node(node1)과 join시켜줍니다.
이제 아래 명령어를 실행해봅니다.
kubectl run webserver --image=nginx:1.14 --port 80
kubectl get pods
#run = 컨테이너 1개
kubectl create deployment mainui --image=httpd --replicas=3
kubectl get deployments.apps
webserver 내부로 들어가서 내용을 바꾸어봅시다.
kubectl exec webserver -it -- /bin/bash
#exec는 pod에서만 이루어져 type을 생략가능합니다.
ls
cd /usr/share/nginx/html/
ls
cat index.html
echo "MoonSH WebPage" > index.html
exit
curl <ip>
edit 예제
kubectl edit deployments.apps mainui
내부의 replicas를 3 -> 5로 바꿔봅시다.
kubectl run webserver --image=nginx --port 80 --dry-run -o yaml
kubectl run webserver --image=nginx --port 80 --dry-run -o yaml > webserver-pod.yaml
vi webserver-pod.yaml
#수정
kubectl create -f webserver-pod.yaml
명령어는 추후 예제를 통해 익숙해지니 간단한 예제만 알아보았습니다.
개발자 혹은 운영자가 컨테이너를 만들어
docker push 를 이용해 hub에 저장합니다.
kubectl을 이용해 kuberneties가 hub에 있는 컨테이너를 실행하도록
master node(control plane)에게 요청합니다.
master에 있는 api가 요청을 받아들여
worker node(작업 노드)에 스케줄러에게 컨테이너를 실행하도록 요청합니다.
스케줄러는 컨테이너를 실행하기 적합한 node를 찾아 해당 kubelet에
컨테이너 실행 요청을 합니다.
요청받은 node의 kubelet이 요청을 docker 명령어로 변환해
dockerd에 전달합니다.
dockerd은 hub에 해당 컨테이너가 있는지 확인 후 컨테이너로 실행하게됩니다.
k8s는 pod라는 단위로 이를 관리하게 됩니다.
-애드온 생략 (cAdvisor, CNI, coreDNS ...)
물리적인 클러스터는 하나이지만 여러개로 동작하도록 네임스페이스를 만들어 각각 관리하는 방식입니다
namespace 보기 kubectl get namespaces
기본은 default namespae가 동작중입니다.
현재 namespace에서 동작중인 pod를 보기위해 아래 명령어들을 사용할 수 있습니다.
kubectl get pod
kubectl get pod --namespace default
kubectl get pod -n default
cat > nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- image: nginx:1.14
name: nginx
ports:
- containerPort: 80
- containerPort: 443
kubectl create -f nginx.yaml
kubectl get pods -n default
모든 namespace에서 실행중인 모든 pod들을 아래 명령어로 불러올 수 있다.
-> k8s 시스템을 위한 pod들도 가져오기 때문에 파드 관리가 힘들어 질 것이다.
kubectl get pods --all-namespaces
kubectl create namespace blue
kubectl create namespace red --dry-run -o yaml > red-ns.yaml
ls
vi red-ns.yaml
creationTimestamp 지우기
spec, status 지우기
kubectl get namespace
kubectl create -f nginx.yaml -n red
vi nginx.yaml
metadata에 namespace:red
로 설정해주면 실행될 때 명령어를 입력하지 않아도 됩니다.
쿠버네티스는 기본적으로 default namespace를 사용합니다.
이 기본 설정값을 변경하는 법을 알아보겠습니다.
kubectl config -- help
kubectl config view
kubectl config set-context blue@kubernetes --cluster=kuberneties --user=kubernetes-admin --namespace=blue
kubectl config current-context
kubectl config use-context blue@kubernetes
네임스페이스 삭제 시 내부 pod, api 들 모두 삭제됩니다.
kubectl delete namespace blue
사람이 쉽게 읽을 수 있는 데이터 직렬화 양식
explain으로 버전 확인
kubectl explain pod
-> pod의 version을 알려줌
kubectl run webserver --image=nginx:1.14
#kubectl run nginx --image=nginx --dry-run -o yaml > pod-nginx.yaml
apiVersion: v1
kind: pod
metadata:
name: webserver
spec:
containers:
- name: nginx-container
image: nginx:1.14
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
#Pod 실행
kubectl create -f pod-nginx.yaml
#동작중인 Pod확인
kubectl get pods
#확인
curl <pod's IP address>
#vi pod-multi.yaml
apiVersion: v1
kind: Pod
metadata:
name: multipod
spec:
containers:
- name: nginx-container
image: nginx:1.14
ports:
- containerPort: 80
- name: centos-container
image: centos:7
command:
- sleep
- "10000"
kubectl create -f pod-multi.yaml
kubectl get pods
kubectl get pods -o wide
kubectl exec multipod -it -c centos-container -- /bin/bash
kubectl logs mutipod -c nginx-container
사용자가 api에게 실행 요청을 합니다
kubectl run webserver --image=nginx:1.14
API가 합당한 명령어인지 체크 후 이를 실행하게 됩니다.
->Pending상태
이 Pod를 실행할 node에게 배치해 실행한다면 -> Running
실패한다면 -> Succeeded Failed
kubectl get pod -o wide -watch
명령어를 활용해 STATUS값이 어떻게 변하는지 확인해봅시다.
self Healing : 컨테이너 실행을 보장해주는 기능
livenessProbe definition은 일반 pod definition과 하단 livenessProbe 부분이 생긴 것을 볼 수 있습니다.
아래 파일에서는 주기적으로 80번 포트로 '/'로 접속해 연결을 확인한다는 뜻입니다.
apiVersion: v1
kind: Pod
metadata:
name: multipod
spec:
conotainers:
- name: nginx-container
image: nginx:1.14
livenessProbe:
httpGet:
path: /
port: 80
livenessProbe:
httpGet
path: /
port: 80
livenessProbe:
tcpSocket:
port: 22
livenessProbe:
exec:
command:
- ls
- /data/file
#vi init-container=exam.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app.kubernetes.io/name: MyApp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
'''
#cat > init-container-exam-svc.yaml
apiVersion: v1
kind : Service
metadata:
name: myservice
spec:
ports:
'''
kubectl create -f init-container-exam-svc.yaml
#cat > init-container-exam-svc.yaml
apiVersion: v1
kind : Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
Pod마다 내부에 'pause'라는 컨테이너가 있습니다.
Pod 컨테이너는 특별히 작업하는 일은 없으며,
Pod의 환경을 만들어주는 컨테이너라고 생각해주시면 됩니다.
Pod생성 시 생성되며, 다른 컨테이너와 같이 Pod delete 시 삭제됩니다.
kubectl delete pod --all
kubectl run web --image=nginx --port=80
vi /var/lib/kubelet/config.yaml
...#아래 위치에 yaml파일 생성으로 pod 시행
staticPodPath: /etc/kubernetes/manifests
#디렉터리 수정시 명령어
systemctl restart kubelet
cd /etc/kubernetes/manifests
vi pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx-container
image: nginx:1.14
livenessProbe:
httpGet:
path: /
port: 80
예시)
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: app
image: images.my-company.example/app:v4
resources:
requests:
#파드를 실행하기 위한 최소 리소스 양을 요청
memory: "64Mi"
cpu: "250m"
limits:
#최대 , 초과 시 kill 후 다시 스케쥴링
memory: "128Mi"
cpu: "500m"
- name: log-aggregator
image: images.my-company.example/log-aggregator:v6
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
메모리 단위
1MB = 1000KB
1MiB = 1024Kib
1Gi
1Mi
10Ki
CPU 단위
1000m = 1core or 1
ENV NGINX_VERSION 1.19.2
ENV NJS_VERSION 0.4.3
#vi pod-nginx-env
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-env
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
protocol: TCP
env:
- name: MYVAR
value: "testvalue"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
kubectl create -f pod-nginx-env
kubectl exec nginx-pod-env -it -- /bin/bash
env
1) Sidecar
2) Adaptor
3) Ambassador
...
spec:
replicas: <배포개수>
selector:
key: value (label에 이 key value가 필수로 있어야 한다.)
template:
<컨테이너 템플릿>
...
#공식 페이지 예제
#vi rc-nginx.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
예제)
kubectl create rc-exam --image=nginx --replicas=3 --selector=app=webui
위 명령어들을 통해 rc-nginx이 3개가 실행되는 중에 아래 명령어를 통해 만든 새로운 yaml파일로 생성한 pod를 실행시키면 -> fail
(replicationController가 pod의 개수를 3개 보장하기 때문입니다.)
(yaml 파일을 빠르게 만들기 위한 --dry-run > ~~.yaml)
kubectl run redis --image=redis --labels=app=nginx --dry-run -o yaml > redis.yaml
해결하기 위해 아래 명령어를 통해 replicas의 개수를 조정하면 됩니다.(scale-out)
kubectl edit rc nginx
kubectl scale rc rc-nginx --replicas=4
->성공
kubectl scale rc rc-nginx --replicas=4
selector:
matchLabels:
component: redis
matchExpressions:
- {key: tier, operator: ln, values: [cache]}
- {key: enciroment, operator: Notln, values: [dev]}
#레플리카셋 삭제 후 파드 삭제 안하기
kubectl delete rs rs-nginx --cascade=false
ReplicaSet을 컨트롤해서 Pod수를 조절합니다.
Rolling Update & Rolling Back
yaml파일은 kind의 value부분만 replicaSet -> deployment로 고치면 됩니다.
set 명령어를 통해 롤링 업데이트를 진행할 수 있습니다.
kubectl set image deployment <deploy_name> <container_name>=<new_version_image>
kubectl rollout status deployment <deploy_name> #상태정보 확인
kubectl rollout pause deployment <deploy_name> #정지
kubectl rollout resume deployment <deploy_name> #재시작
kubectl rollout resume history <deploy_name> #히스토리 보기
# revisionHistoryLimit : defalut = 10 //조절가능
롤백
# history 기준 한단계 전으로 롤백
kubectl rollout undo deployment <deploy_name>
# x번 리비전으로 롤백
kubectl rollout undo deployment <deploy_name> --to-revision=x
vi deployment-exam.yaml
'''
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
'''
kubectl create -f deployment-exam.yaml --record
kubectl describe pod nginx-deployment-cbdccf466-9hlqz
kubectl set image deploy nginx-deployment nginx=ngonx:1.15 --record
kubectl rollout history deployment nginx-deployment
kubectl rollout undo deployment nginx-deployment --to-revision=1
kubectl
kubectl apply -f deployment-exam2.yaml
서비스 개념
서비스 타입
서비스 사용
헤드리스 서비스
kube-proxy
동일한 서비스를 제공하는 Pod 그룹의 단일 진입점을 제공
ClusterIP
NodePort
LoadBalancer
ExternalName
남은 쿠버네티스 기본 개념들
남은 강의