Infra/Kubernetes

Kubernetes 1

서머스 2022. 7. 14. 19:32

쿠버네티스

- 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식성이 있고, 확장 가능한 오픈소스 플랫폼

- 선언적 구성과 자동화를 모두 용이하게 함

 

 

컨트롤 플레인 컴포넌트

- 클러스터에 대한 전반적인 결정(스케줄링-pod 배치)을 수행하고 클러스터 이벤트(ex. 디플로이먼트의 replicas 필드에 대한 요구 조건이 충족되지 않을 경우 새로운 파드를 구동시키는 것=>자아 치유)를 감지하고 반응한다.

- 일종의 마스터 역할

- 워커 노드를 감시하는 중추 역할

 

kube-apiserver

- 쿠버네티스 API를 노출하는 쿠버네티스 컨트롤 플레인 컴포넌트

- 쿠버네티스 컨트롤 플레인의 프론트 엔드

- 수평으로 확장되도록 디자인됨

 

etcd: DB, Nosql(KVS;Key-value store)이다.

사용자: 3개의 pod 운영한다.

모든 클러스터 데이터를 담는 쿠버네티스 뒷단의 저장소로 사용되는 일관성, 고가용성 키-값 저장소

백업이 필수적

 

sched: kube-scheduler, 상태 정보를 알 수 있다.

노드에 파드(pod)를 배정하는 역할

노드가 배정되지 않은 새로 생성된 파드를 감지하고, 실행할 노드를 선택하는 컨트롤 플레인 컴포넌트

스케줄링 결정을 위해 리소스(주로 메모리)에 대한 개별 및 총체적 요구 사항이 주됨.

 

kubelet : api에 따라 pod, 컨테이너 생성

클러스터의 각 노드에서 실행되는 에이전트

쿠버네티스를 통해 생성되지 않는 컨테이너는 관리하지 않습니다

 

c-c-m : 클라우드를 위함

 

c-m(Control Manager)

 

레플리케이션 컨트롤러 : replica=5 , 즉 desired 개수 유지해준다.

 

노드 컴포넌트

- = 워커 노드

- 동작 중인 파드를 유지시켜 준다.

- 모든 노드 상에서 동작한다. - 마스터 노드 상에서도 실행시킬 수 있다.

 

kube-proxy

로드 밸런서의 기능도 가지고 있음

쿠버네티스 서비스 개념의 구현부

 

container-runtime

컨테이너 실행을 담당하는 소프트웨어

그 중 나는 도커를 사용한다.

 

 

Minikube

쿠버네티스의 경량화 버전

 

# curl -fsSL https://get.docker.com/ | sudo sh
# systemctl enable --now docker
# yum install -y conntrack git
# curl -Lo minikube https://storage.googleapis.com/minikube/releases/v1.23.2/minikube-linux-amd64 && chmod +x minikube
# mkdir -p /usr/local/bin/
# install minikube /usr/local/bin/
# minikube version
# minikube start --driver=none
# minikube status

 

Kubectl 설치

# curl -LO https://dl.k8s.io/release/v1.22.2/bin/linux/amd64/kubectl
# install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# source <(kubectl completion bash)
# echo "source <(kubectl completion bash)" >> ~/.bashrc
# kubectl version

만약 안되면, yum install -y bash-completion 한다.

 

파드(pod):

쿠버네티스에서 배포할 수 있는 가장 작은 단위

파드에 속한 컨테이너는 스토리지와 네트워크를 공유하고 서로 localhost로 접근할 수 있다

 

 

 

 

 

 

 

[root@localhost ~]# kubectl version
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2", GitTreeState:"clean", BuildDate:"2021-09-15T21:38:50Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2", GitTreeState:"clean", BuildDate:"2021-09-15T21:32:41Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}
[root@localhost ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   12m
[root@localhost ~]# mkdir workspace && cd $_
[root@localhost workspace]# kubectl run nginx-pod --image nginx
pod/nginx-pod created
[root@localhost workspace]# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          18s
[root@localhost workspace]# kubectl expose pod nginx-pod --name clusterip --type ClusterIP --port 80
service/clusterip exposed
[root@localhost workspace]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
clusterip    ClusterIP   10.103.4.82   <none>        80/TCP    72s
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP   111m
[root@localhost workspace]# curl clusterip
curl: (6) Could not resolve host: clusterip; Unknown error
[root@localhost workspace]# curl 10.103.4.82
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

expose

터미널에서 웹브라우저에 접속할 수 없으니 curl 명령어를 이용해 접속 테스트 해 본다.

 

nodeport에 접속하려면 쿠버네티스의 ip - 31394 포트를 이용해서 접속해야 한다.

노드 포트 = 호스트 포트

 

내부에서 접속가능한 Cluster IP

클러스트 ip로도 접속이 가능한 것.

 

 

외부에서 접속 가능한 호스트 포트 = 노드 포트

 

LoadBalancer

[root@localhost workspace]# kubectl expose pod nginx-pod --name loadbalancer --type=LoadBalancer --external-ip 192.168.0.50 --port 80
service/loadbalancer exposed
[root@localhost workspace]# kubectl get svc
NAME           TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)        AGE
clusterip      ClusterIP      10.103.4.82      <none>         80/TCP         55m
kubernetes     ClusterIP      10.96.0.1        <none>         443/TCP        165m
loadbalancer   LoadBalancer   10.99.118.123    192.168.0.50   80:32281/TCP   36s
nodeport       NodePort       10.111.117.159   <none>         80:31394/TCP   27m

바로 External IP로 접속해 본다

 

로드밸런스로 접속할 시 80포트로, 노드 포트로 접속할 시 31394 포트로 접속하게 된다.

 

[root@localhost workspace]# bkubectl exec -it nginx-pod -- bash
-bash: bkubectl: command not found
[root@localhost workspace]# kubectl exec -it nginx-pod -- bash
root@nginx-pod:/# ls
bin   docker-entrypoint.d   home   media  proc	sbin  tmp
boot  docker-entrypoint.sh  lib    mnt	  root	srv   usr
dev   etc		    lib64  opt	  run	sys   var
root@nginx-pod:/# cd /usr/share/nginx/html
root@nginx-pod:/usr/share/nginx/html# ls
50x.html  index.html
root@nginx-pod:/usr/share/nginx/html# echo "minikube" > index.html

 

자원 정리하기

[root@localhost workspace]# kubectl delete svc clusterip
service "clusterip" deleted

service - 일부만 지우기

 

[root@localhost workspace]# kubectl delete svc --all
service "kubernetes" deleted
service "loadbalancer" deleted
service "nodeport" deleted

전체 지우기

 

kubernetes도 지워졌지만, 시간이 지나면 다시 생긴다.

 

[root@localhost workspace]# kubectl delete pod nginx-pod
pod "nginx-pod" deleted

pod 삭제하기

 

삭제되었다.

 

 

 

서비스 만들기

 

vi nginx-pod.yaml

 

# kubectl apply -f nginx-pod.yaml

apply를 이용해 yml파일을 실행시킨다.

 

[root@localhost workspace]# kubectl get pod -o wide
NAME        READY   STATUS    RESTARTS   AGE     IP           NODE                    NOMINATED NODE   READINESS GATES
nginx-pod   1/1     Running   0          2m40s   172.17.0.3   localhost.localdomain   <none>           <none>

wide를 이용해서 몇번째 노드에 pod가 있는지 확인할 수 있다.

 

[root@localhost workspace]# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          5m29s
[root@localhost workspace]# kubectl describe pod nginx-pod
Name:         nginx-pod
Namespace:    default
Priority:     0
Node:         localhost.localdomain/192.168.0.50
Start Time:   Thu, 14 Jul 2022 16:19:30 +0900
Labels:       app=nginx-pod
Annotations:  <none>
Status:       Running
IP:           172.17.0.3
IPs:
  IP:  172.17.0.3
Containers:
  nginx-pod-container:
    Container ID:   docker://f0b3ae7cdbb43a16f9b44d8c27b2639772f27bd4037639b3310b6c2624e45063
    Image:          nginx
    Image ID:       docker-pullable://nginx@sha256:db345982a2f2a4257c6f699a499feb1d79451a1305e8022f16456ddc3ad6b94c
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Thu, 14 Jul 2022 16:19:33 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-ggcgx (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-ggcgx:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  5m48s  default-scheduler  Successfully assigned default/nginx-pod to localhost.localdomain
  Normal  Pulling    5m47s  kubelet            Pulling image "nginx"
  Normal  Pulled     5m45s  kubelet            Successfully pulled image "nginx" in 2.510623243s
  Normal  Created    5m45s  kubelet            Created container nginx-pod-container
  Normal  Started    5m45s  kubelet            Started container nginx-pod-container

describe를 이용해서 container에 대한 상세 정보를 확인할 수 있다.

마지막 Events는 에러가 났을 때 로그를 보기 위해 활용한다.

 

vi clusterip-pod

[root@localhost workspace]# kubectl apply -f clusterip-pod.yaml
service/clusterip-service-pod created
[root@localhost workspace]# kubectl get svc -o wide
NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE   SELECTOR
clusterip-service-pod   ClusterIP   10.98.20.104   <none>        80/TCP    6s    app=nginx-pod
kubernetes              ClusterIP   10.96.0.1      <none>        443/TCP   63m   <none>
[root@localhost workspace]# curl 10.98.20.104
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
apiVersion: v1
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

 

 

 

만약 app에 이름을 잘못 쓰게 된다면 연결된 pod가 없기 때문에 curl 을 했을 때 오류가 난다.

 

 

만약 포트 번호를 바꾸게 된다면, curl을 했을 때 끝에 8080 포트를 붙여야 한다.

 

[root@localhost workspace]# kubectl edit svc clusterip-service-pod

포트번호를 수정할 때, edit 명령어를 이용할 수도 있다.

 

 

 vi nodeport-pod.yaml

port와 targetPort를 8080으로 해 본다.

[root@localhost workspace]# kubectl apply -f nodeport-pod.yaml
service/nodeport-service-pod created
[root@localhost workspace]# kubectl get svc
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
clusterip-service-pod   ClusterIP   10.98.25.220    <none>        80/TCP           35m
kubernetes              ClusterIP   10.96.0.1       <none>        443/TCP
apiVersion: v1
   110m
nodeport-service-pod    NodePort    10.107.76.215   <none>        8080:30080/TCP   8s
[root@localhost workspace]# curl 10.105.60.248:8080
curl: (7) Failed connect to 10.105.60.248:8080; Connection timed out

timeout이 발생한다.

targetport를 컨테이너 포트로 다시 수정한다.

curl을 했을 때 잘 나타난다.

 

 

vi loadbalancer-pod.yaml

 

[root@localhost workspace]# kubectl get svc
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
clusterip-service-pod   ClusterIP   10.98.25.220    <none>        80/TCP           39m
kubernetes              ClusterIP   10.96.0.1       <none>        443/TCP          113m
nodeport-service-pod    NodePort    10.107.76.215   <none>        8080:30080/TCP   3m34s
[root@localhost workspace]# kubectl apply -f loadbalancer-pod.yaml
service/loadbalancer-service-pod created
[root@localhost workspace]# kubectl get svc -o wide
NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE     SELECTOR
clusterip-service-pod      ClusterIP      10.98.25.220    <none>         80/TCP           41m     app=nginx-pod
kubernetes                 ClusterIP      10.96.0.1       <none>         443/TCP          115m    <none>
loadbalancer-service-pod   LoadBalancer   10.96.186.226   192.168.0.50   80:30256/TCP     17s     good=nginx-pod1
nodeport-service-pod       NodePort       10.107.76.215   <none>         8080:30080/TCP   5m51s   app=nginx-pod
[root@localhost workspace]# kubectl describe svc loadbalancer-service-pod
Name:                     loadbalancer-service-pod
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 good=nginx-pod1
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.96.186.226
IPs:                      10.96.186.226
External IPs:             192.168.0.50
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30256/TCP
Endpoints:                <none>
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

 

 

 

 

수동으로 pod 수정하기

[root@localhost ~]# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          71m
[root@localhost ~]# kubectl edit pod nginx-pod
pod/nginx-pod edited

내 repo에 있는 걸로 대체한다.

 

그리고 VM의 IP로 접속한다.

그러면 홈페이지가 떠야 하는데 안뜬다..

 

'Infra > Kubernetes' 카테고리의 다른 글

kubernetes 7  (0) 2022.07.21
kubernetes 5  (0) 2022.07.20
kubernetes 4  (0) 2022.07.19
kubernetes 3  (0) 2022.07.18
kubernetes 2  (0) 2022.07.16