다음은 쿠버네티스 스터디 자료를 참고해 정리한 내용입니다.
어플리케이션 최소 실행 단위인 Pod를 알아보자.
<1> 아키텍처 - 컴포넌트
<2> Pod 소개
<3> 컨테이너 공유 확인하기
<4> myweb2-netshoot 컨테이너 내부 들어가서 확인
<5> myweb2-nginx 컨테이너 내부 들어가서 확인
<6> Pod 삭제
<7> 정리
<8> 다음 과정
<1> 아키텍처 - 컴포넌트
https://kubernetes.io/docs/concepts/overview/components/
1
쿠버네티스는 Control Plane(마스터)와 노드로 구성되어 있다.
마스터 = 컨트롤 플레인 = 제어하는 곳이다.
노드 = 워커 노드 = 일하는 곳이다. Pod와 컨테이너가 동작하는 곳이다.
2
Control Plane(마스터 노드) ?
핵심 컴포넌트: 마스터는 고가용성을 위한 클러스터 마스터로 구축
apiserve *: 마스터로 전달되는 모든 요청을 받는 API 서버
etcd : 클러스터내 모든 메타 정보를 저장하는 서비스
kube-scheduler : 사용자의 요청에 따라 적절하게 컨테이너를 워커 노드에 배치하는 스케줄러
kube-controller-manager : 현재 상태와 바라는 상태를 지속적으로 확인하며 특정 이벤트에 따라 특정 동작을 수행하는 컨트롤러 - https://kubernetes.io/docs/concepts/architecture/controller/
cloud-controller-manager : 클라우드 플랫폼(AWS, GCP, Azure 등)에 특화된 리소스를 제어하는
클라우드 컨트롤러 - https://kubernetes.io/docs/concepts/architecture/cloud-controller/
3
워커 노드 ?
kubelet : 마스터의 명령에 따라 컨테이너의 라이프 사이클을 관리하는 노드 관리자
kube-proxy : 컨테이너의 네트워킹을 책임지는 프록시, 네트워크 규칙을 유지 관리
Container Runtime : 실제 컨테이너를 실행하는 컨테이너 실행 환경, (Docker containerD CRI-O)
https://kubernetes.io/docs/concepts/architecture/nodes/
4
CNI?
Container Network Interface 는 k8s 네트워크 환경을 구성해준다
컨테이너 네트워크이다.
https://kubernetes.io/ko/docs/concepts/cluster-administration/networking/
네트워크 조건?
Pod-Pod 간에는 NAT없이 통신
노드의 에이전트(시스템 데몬과 Kubelete)은 모든 Pod와 통신
노드의 호스트 네트워크에 있는 Pod는 NAT없이 모든 노드에 있는 모든 Pod와 통신 가능
서비스 클러스터 IP대역은 각 노드의 Pod IP와 겹치지 않아야 한다.
5
DNS?
쿠버네티스 서비스를 위해 DNS레코드를 제공해 주며, Service Deiscovry 기능을 제공하는 CoreDNS가 있다.
쿠버네티스는 클러스터내에서 통신하기 위해 노드 위치와는 상관없이 어디서든 접근할 수 있는 서비스 끝점(Service Endpoint)이 필요합니다.
사용자(또는 Pod)는 서비스 끝점을 통해 다른 컨테이너(Pod)와 통신할 수 있습니다.
이를 위해 사용자는 서비스에 접근하기 위한 끝점의 접속 정보(예를 들면 IP)를 알아야 합니다.
이를 서비스 탐색(Service Discovery)이라 합니다.
쿠버네티스에서는 DNS 기반의 서비스 탐색을 지원하기에 사용자가 매번 새로운 서비스의 IP를 찾을 필요 없이 도메인 주소를 기반으로 서비스에 접근할 수 있습니다.
쿠버네티스에서는 서비스 탐색 기능을 Service 라는 리소스를 이용하여 제공합니다.경, (Docker containerD)
6
쿠버네티스 리소스 ?
오브젝트라고 표현한다.
컨테이너 = 서비스가 올라가는 프로세스
Pod = 컨테이너가 운영되는 초소 실행단위
Replica Set = 컨터이너 집합을 관리하는 컨트롤러
Service Account = 사용자 계정
Node
7
네임스페이스?
클러스터를 논리적으로 구분해주는것
예를 들어 Front 서비스를 별도의 네임스페이스를 만들어 해당 네임스페이스에서만 서비스한다.
Kubectl 명령어로 실행할때도 기본으로 디폴트 네임스페이스에 질의하여 답한다.
네임스페이스를 변경하여 Pod를 조회한다.
네임서비스 리소스는 특정 네임 스페이스 안에만 존재한다.
Pod, Deployment, Service 는 네임스페이스 안에 포함 된다.
예) 프론트엔드 네임스페이스, 백엔드 네임스페이스, 모니터링 네임스페이스
8
Node PersistentVolume , Storage Class는 네임서비스 밖에 클러스터 레벨에서 존재한다.
kubectl get namespace
kubectl get pods
// -n kube-system 네임스페이스에 존재하는 pod 확인
kubectl get pods -n kube-system
// 모든 네임스페이스에 존재하는 Pod 확인
kubectl get pods --all-namespaces
1
Pod안에는 1개 이상의 컨테이너가 구성되어 있다.
따라서, Pod가 지워지면 컨테이너도 지워진다.
Pod는 계란 판이고, 컨테이너는 계란이다.
계란 판위에 계란(컨테이너가 있는것이다.)
Pod는 IP를 가진다.
컨테이너는 이 IP를 공유한다.
쿠버네티스 Pod는 node ip와는 다른 별도의 IP를 받는다.
2
ec2에 로그인
쿠버네티스 master API 서버 로그인
도메인이 있는경우
ssh -i ~/.ssh/id_rsa ubuntu@api.k8s.serverchk.com
or
로컬 도메인으로 한 경우
ssh 키를 api 서버로 복사
api 서버로 ssh로 접속
3
템플릿 만들기 ?
// 이미지로 myweb.yaml 파일 만들기~
실제로 Pod를 생성하지 않고 파일만 만든다. --dry-run=client -o yaml
kubectl run myweb --image nginx --dry-run=client -o yaml > myweb.yaml
cat myweb.yaml
[root@ip-172-20-41-255:~ (k8.serverchk.com:default)]# kubectl run myweb --image nginx --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: myweb
name: myweb
spec:
containers:
- image: nginx
name: myweb
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
4
다른 터미널에서
ssh -i ~/.ssh/id_rsa ubuntu@api.k8s.serverchk.com
watch -d 'kubectl get pod'
pod 삭제
kubectl delete pod --all
6
YAML 파일 생성
YAML 파일에 컨테이너가 사용할 포트 TCP 80 설정
apply -f(file) 여러번 실행하더라도 항상 YAML 정의서에 선언된 내용과 동일한 결과 얻는다.
cat << EOF > myweb.yaml
apiVersion: v1
kind: Pod
metadata:
name: myweb
spec:
containers:
- image: nginx:latest
name: myweb-container
ports:
- containerPort: 80
protocol: TCP
EOF
7
// Pod 배포
kubectl apply -f myweb.yaml && kubectl get pod -w
pod/myweb unchanged
NAME READY STATUS RESTARTS AGE
myweb 1/1 Running 0 56s
// myweb 현재 상태 1/1
// 요청사항 1
topasvga@cloudshell:~ (ap-seoul-1)$ kubectl get pods
NAME READY STATUS RESTARTS AGE
myweb 1/1 Running 0 33s
8
다시 실행해 보고 Pod 배포 갯수 확인?
멱등성을 가지므로 숫자는 동일하게 유지된다. 새로 생성 되지는 않는다!
kubectl apply -f myweb.yaml
pod/myweb unchanged
9
Pod IP 정보를 확인
kubectl get pod -o wide
10
Pod 자세히 보기 describe
Pod 이름, Containe 이름 확인, Port 80 확인
kubectl describe pod myweb
// pull image ...... ngix 이미지를 가져옴
11
kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myweb 1/1 Running 0 5m48s 100.98.158.130 ip-172-20-38-144.ap-northeast-1.compute.internal <none> <none>
13
Pod(Nginx) 확인
ping 100.98.158.130
14
curl 100.98.158.129
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
15
# Pod 삭제
kubectl delete pod myweb
pod "myweb" deleted
<3> 컨테이너 공유 확인하기
Pod안에 2개의 컨테이너를 사용할수 있다.
Pod단위로 IP가 할당 되므로 컨터이너 2개는 같은 IP를 사용한다.
1
Pod 생성
myweb2 Pod에 2개 컨테이너 만들기
containers:
정보 확인하기
// kubectl apply -f - 바로 실행하는 옵션이다.
// containers: 복수이다. 1개 이상 들어간다는 뜻 ~
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: myweb2
spec:
containers:
- name: myweb2-nginx
image: nginx
ports:
- containerPort: 80
protocol: TCP
- name: myweb2-netshoot
image: nicolaka/netshoot
command: ["/bin/bash"]
args: ["-c", "while true; do sleep 5; curl localhost; done"]
EOF
pod/myweb2 created
while true; do sleep 5; curl localhost; done
// 5초마다 curl localhost 하는 명령어.
2
2개의 컨테이너가 만들어 진다~
- name: myweb2-nginx
- name: myweb2-netshoot
topasvga@cloudshell:~ (ap-seoul-1)$ kubectl get pods
NAME READY STATUS RESTARTS AGE
myweb2 2/2 Running 0 66s
topasvga@cloudshell:~ (ap-seoul-1)$
3
2/2 ?
Pod 내 모든 컨테이너 정상이여야지 Running 됨
k get pod -owide
4
배포된 워커노드로 로그인
docker ps 로 확인
docker ps --format "table {{.Image}}\t{{.Status}}\t{{.Names}}" | grep myweb2
컨테이너 2개가 보인다.
5
Pod 상세 정보 확인 ?
컨테이너 2개 보인다
kubectl describe pod myweb2
Normal Scheduled 2m33s default-scheduler Successfully assigned default/myweb2 to ip-172-20-46-12.ap-northeast-1.compute.internal
Normal Pulling 2m32s kubelet Pulling image "nginx"
Normal Pulled 2m31s kubelet Successfully pulled image "nginx" in 1.394764066s
Normal Created 2m30s kubelet Created container myweb2-nginx
Normal Started 2m30s kubelet Started container myweb2-nginx
Normal Pulling 2m30s kubelet Pulling image "nicolaka/netshoot"
Normal Pulled 2m11s kubelet Successfully pulled image "nicolaka/netshoot" in
Normal Created 2m10s kubelet Created container myweb2-netshoot
Normal Started 2m10s kubelet Started container myweb2-netshoot
<4> myweb2-netshoot 컨테이너 내부 들어가서 확인
1
pod를 확인한다.
kubectl get pod -owide
2
pod내 컨테이너를 확인한다.
kubectl describe pod myweb2
myweb2-nginx
myweb2-netshoot
3
nginx 컨테이너 웹 접속 로그 출력
kubectl logs -f myweb2 -c myweb2-nginx
// pod내 myweb2-nginx 컨테이너의 로그를 보는것이다.
// 반드시 컨테이너 이름을 적어야 한다. -c myweb2-nginx
4
myweb2-netshoot 컨테이너 내부로 들어가 확인
-c 옵션으로 어떤 컨테이너에 대해 명령어를 수행할지 명시한다.
kubectl exec -it myweb2 -c myweb2-netshoot -- zsh
5
웹 접속 확인?
curl -s localhost |grep nginx
myweb2 # curl -s localhost |grep nginx
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
<a href="http://nginx.org/">nginx.org</a>.<br/>
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
4
호스트 이름 확인 ?
cat /etc/hosts
myweb2 # cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
100.98.158.185 myweb2
5
IP 확인 ?
ip a
ip route show
100.98.158.185 로 IP 확인함.
6
라우팅 확인 ?
ip route show
myweb2 # ip route show
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link
7
TCP Listen 확인 ? TCP 80 Listen
ss -tln
8
컨테이너에서 나가기
exit
<5> myweb2-nginx 컨테이너 내부 들어가서 확인
clear
1
kubectl exec -it myweb2 -c myweb2-nginx -- /bin/bash
2
업데이트와 IP 확인가능한 툴 설치
apt update
apt install -y procps net-tools
3
웹 접속 확인
curl -s localhost |grep nginx
4
호스트 이름 확인
cat /etc/hosts
root@myweb2:/# cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
100.98.158.185 myweb2
5
ip 확인?
ifconfig
root@myweb2:/# ifconfig
// IP가 같다.
nginx와 netshoot ip 가 같다.
같은 Pod 라서 IP 가 같은 것이다.
6
기존 온프라미스는 IP단위로 관리했었다.
Pod안의 컨테이너는 IP가 같다.
root@myweb2:/# exit
7
Pod 생성과정?
1) kubectl 로 Pod 생성 요청하면
2) API 서버가 받아 etcd 에 요청 정보와 상태 정보를 저장한다.
3) 컨트롤러 매니저가 API 서버를 모니터링 한다.
4) 컨트롤러 매니저는 생성 요청이 왔는지 확인.
5) 스케쥴러가 Pod 할당 모니터링
6) 스케쥴러가 노드 1에 할당 요청
7) kubelet 이 API 서버에 미배포 Pod 확인
8) C Rruntime에 Pod 생성요청
9) C Runtime 이 Pod (컨테이너)생성한다.
10) node는 Etcd에 노드1에 pod가 정상 동작중이라고 알려준다.
<6> Pod 삭제
kubectl delete pod myweb2
<7> 정리
어플리케이션 최소 실행 단위는 Pod
Pod안에는 1개 이상의 컨테이너가 구성되어 있다.
따라서, Pod가 지워지면 안에 있는 모든 컨테이너도 지워진다.
Pod는 IP를 가진다. 컨테이너들은 이 IP를 공유한다.
모두 API서버를 거쳐서 통신 한다 !!!
<8> 다음 과정
https://brunch.co.kr/@topasvga/1670
감사합니다.