
사용하고 있는 Docker Desktop에 내장되어 있는 Kubernetes를 이용해서 미니큐브를 설치해보자.
Docker Desktop을 가동시켜주고, 상단에 톱니바퀴 모양을 누르면 Setting에 들어갈 수 있다.
Setting에서 위에서 네 번재에 Kubernetes 항목을 클릭해주고, Enable Kubernetes 체크박스를 선택해주면 활성화가 된다.
활성화를 시키면 왼쪽 하단에 Docker와 Kubernetes 모두 초록불을 띄게 되며 실행 되었음을 알 수 있다.
이것이 바로 MiniKube방식으로 Kubernetes를 간단하게 사용하는 방법이다.

kubectl get nodes
미니큐브를 이용했기 때문에 control-plane이라는 이름의 단일 노드만 존재한다.
하나밖에 없다는 얘기는 미니큐브를 통해서 마스터 역할과 워크 노드 역할을 같이 한다고 보면 된다.

kubectl get pods
kubectl get deployments
kubectl get services
kubectl get pods : pods가 작동되고 있는지 확인
kubectl get deployments : deployment 오브젝트가 작동 중인지 확인
kubectl get services : 사용하고 있는 service 목록을 확인
여기서는 kubernetes 라는 서비스가 하나 등록된 것을 확인할 수 있다.
** namespace라는 것은 사용하고 있는 이 Kubernetes의 오브젝트들이 모여있는 가상의 공간이라고 생각하면 된다.
** namespace를 특별하게 생성하지 않으면 default namespace로 작업한다고 생각하면 된다.

kubectl run sample-nginx --image=nignx --port=80
kubectl 명령어를 통해서 간단하게 nginx라는 웹서버를 다운로드 받아 컨테이너 방식으로 기동하는 명령어이다.
이름은 sample-nginx이고, 사용할 이미지는 nignx이며 포트는 80번을 쓴다는 뜻이다.

kubectl get pods
Pod가 하나 만들어지며 그 이름은 sample-nignx라고 되어있다.
이전 포스트에서도 말했지만 Kubernetes를 사용할 때는 기본적으로 컨테이너가 이미 작동 중인 상태여야 한다.
그리고 Kubernetes에서 관리하고자 하는 최소한의 단위가 Pod이기에 그 안에는 실행하고자 하는 어떤 서비스, 미들웨어, 운영체제, 어플리케이션들이 컨테이너로 패키징화되어 있어서 사용할 수 있는 상태가 되어야 한다.
다시 말해서 앞에 있는 예제인 Nginx 웹서버는 이미지 형태로 제공이 되고 있는데 그 이미지를 가지고 와서 우리가 샘플 Nginx라는 Pod를 생성하겠다라는 의미로 보면 된다.

kubectl describe pods sample-nginx
작동 중인 Pod에 대한 상세 정보를 확인할 수 있는 명령어다.
현재 싱글 노드 상태이기 때문에 하나밖에 없지만 실제로 Kubernetes 클러스터를 제대로 구축했을 경우에는 노드가 여러 개 있을 것이다.
워커노드 어디에 설치가 됐는지, 워크스페이스는 어디에 설치되어 있는지, 네임스페이스는 어디에 설치되어 있는지 이런 정보를 확인할 수 있다.
또한 내부적인 Pod에 할당되어진 가상 IP도 확인할 수 있다.
하단에 Events라는 항목에선 문제가 생겼을 때는 어떤 이유로 Pod가 혹은 어떤 Service가 실행이 안 됐는지도 확인이 가능하다.

kubectl delete pod/sample-nginx
delete 키워드를 사용하여 원하는 이름의 pod를 삭제할 수 있다.

kubectl create deployment sample-nginx --image=nginx
kubectl get deployment
Deployment 개념을 통해서 방금 실행했던 Nginx를 설치해 보도록 하자.
Deployment에서는 레플리카셋(ReplicaSet)라고 해서 파드(Pod) 집합의 실행을 안정적으로 유지하는데 목적을 갖춘 쿠버네티스 워크로드를 만들 수 있다.
Pod 상위 개념으로서 배포 단위를 Deployment로 감싸서 배포하게 되면 스케일링 작업, 스케줄 작업할 때 훨씬 더 편하게 작업할 수 있다.
kubectl get deployment 명령어로 sample-nginx라는 deployment가 하나 만들어진 것을 볼 수 있다.
이 경우 Pod가 어떻게 생성되는지 확인해보자.

kubectl get pods
이전에 없었던 Pod가 생성된 것을 확인할 수 있다.
여기선 smple-nginx 이름 뒤에 랜덤하게 생성되어진 숫자를 볼 수 있다.
즉 smple-nginx라는 Deployment에는 파드가 Pod가 묶여서 하나가 딸려 있어 정상적으로 실행되고 있다고 볼 수 있다.

kubectl delete pod/sample-nginx-68847595c4-8jqxp
kubectl get pods
Pod를 삭제해도 Pod를 다시 한번 확인해봐도 여전히 작동되고 있는 것을 확인할 수 있다.
그런데 작동 중인 Pod의 이름을 보면 조금 전 삭제했던 Pod와 이름이 다르다.
다시 말해 Deployment로 Pod를 실행하게 되면 Pod가 삭제된다 하더라도 Deployment가 새로운 Pod를 자동으로 생성해주며 최소한의 Pod의 개수를 계속 유지한다.
따라서 Pod가 문제가 생겼거나, Pod가 크러쉬가 생겼거나, 문제가 생겼거나, 오류가 생겼거나, 정상 작동 중이지 않거나, 심지어 삭제하여도 Deployment에서 제시했던 그 개수만큼은 무조건 Pod를 유지하려고 하는 속성을 가지고 있다.

kubectl scale deployment smple-nginx --replicas=2
kubectl get pods
위는 스케일링 작업으로 Deployment의 개수를 레플리카셋(ReplicaSet)을 2로 설정하여 개수를 2개로 하겠다는 명령어이다.
sample-nginx에서 유지하려고 하는 Pod의 개수를 두 개라고 늘려놨다.
실행중인 Pod의 목록을 보는 명령어의 결과를 보면 Deployment가 유지해야 될 Pod의 개수를 두 개를 만들어 놨기 때문에 자동적으로 해당하는 Deployment가 Pod를 하나 더 실행을 한 것을 볼 수 있다.
또한 Pod = Container라고 말할 수는 없다.
왜냐하면 Pod에는 컨테이너가 하나가 들어갈 수도 있고 여러 개의 컨테이너가 들어가서 한 개의 Pod를 구성할 수도 있다.
따라서 READY에 나와있는 숫자는 해당하는 Pod 안에 포함되어 있는 컨테이너 개수가 몇 개인지를 나타낸다.
일반적으로 Pod 하나에 컨테이너를 하나를 집어 넣었기 때문에 1/1 이라고 표시가 되는 것뿐이다.

kubectl get deployments
작동 중인 Deployment 오브젝트를 확인해 보면 READY에 2/2라고 표시되어 있다.
즉 2개의 Pod를 유지할 거고,2개의 Pod가 정상 작동되고 있다라고 표시가 되는 것이다.

kubectl scale deployment smple-nginx --replicas=1
kubectl get pods
스케일링 작업은 이렇게 늘리는 것 뿐만 아니라 숫자를 줄이면 자동적으로 줄어드는 작업도 할 수 있다.
옵션 replicas를 1로 변경하면 작동 중인 Pod 하나가 삭제되어 한 개의 Pod만 작동 중인 것을 확인할 수 있다.

kubectl delete deployments.apps/sample-nginx
kubectl get pods
kubectl get deployments
간단한 테스트가 끝났으니 Deployment를 삭제하여 깔끔하게 비워주었다.

지금까지 방법 1번과 방법 2번에 대해 정리해보았다.
CD(Continuous Deployment) 작업을 위해 간단한 Kubernetes 기본 명령어들을 살펴보았는데, 사실 가장 많이 쓰이는 건 방법 3번이다.
스크립트 되어 있는 내용을 실행하는 방법을 살펴보고자 한다.
kubectl apply -f sample1.yml
kubectl apply 명령어를 사용하고, -f 옵션을 사용해 파일명을 지정해 줄 건데 예시 파일로 우측 스크립트 내용을 실행하려고 한다.
오른쪽에 작성되어 있는 명령어는 크게 4가지 파트로 나뉜다.
어떤 오브젝트를 사용하더라도 4가지 구조를 가지고 있는 것은 거의 동일할 것이다.
apiVersion
제일 상단에 API 버전을 어떤 것을 사용할 것인지는 어떤 오브젝트를 만들 것인지에 따라 달라지지만 일반적으로 많이 사용하는 Pod, Service, Deployment 같은 경우에는 apps-v1이라는 버전이 고정값처럼 사용되고 있다.
kind
두 번째 kind라는 것은 만들고자 하는 Kubernetes의 오브젝트 이름을 적어주면 된다.
(오브젝트 : Pod, Deployment, Service, ReplicaSet 등)
metadata
metadata는 현재 작성하고 있는 스크립트의 name 또는 labels을 할 수 있는데, labels을 달아놨다는 얘기는 자유롭게 key-value 형태로 작성하면서 다른 리소스에서 지금 만들고 있는 리소스를 선택을 해서 사용을 하거나 어떤 값을 반영할 때 쓸 수 있다.
( key: app / value: nginx )
spec
spec은 어떤 kind를 쓰냐에 따라서 종류가 조금 달라지긴 하는데 Pod를 썼을 때는 Pod에 포함될 컨테이너 이름 쓰고, Deployment를 사용했을 때는 Deployment이 필요한 옵션들을 정리한다 보면 된다.
replicas
앞서 실행했던 것처럼 레플리카셋(ReplicaSet)에다가 2라고 입력하면 지금 만들고 있는 Deployment는 생성하려고 하는 Pod를 두 개 유지해달라는 명령어가 된다.
selector
selector에 지금 작업하려고 하는 대상을 어떤 labels에 명시할 건지 고를 수 있다.
( matchLabels )
위쪽에서 labels를 app: nginx라고 적어놨었다. 따라서 지금 작업하려고 하는 대상을 nginx로 적어주었다.
( key: app / value: nginx )
template
그 밑에 있는 template이라는 것은 실제 이 Deployment를 통해서 설치하고자 하는 Pod의 내용을 기술하면 된다.
spec의 containers에는 설치하고자 하는 컨테이너의 이미지 이름을 써준다.
(name: nginx)
다음 이 컨테이너에서 사용하려고 하는 포트번호도 지정할 수 있다.
(containerPort: 80)

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
먼저 Kubernetes가 호스트 pc에 깔려있기 때문에 실행 위치는 호스트 pc이기에 홈 디렉토리에 sample1.yml을 만들어준다.
내용은 방금 설명했던 스크립트 내용과 동일하므로 그대로 적어주었다.

kubectl apply -f sample1.yml
다시 CMD로 돌아와 스크립트 파일을 실행하는 명령어를 입력해준다.

kubectl get deployments
kubectl get pods
Deployment 안에는 아까 레플리카셋(ReplicaSet)을 2라고 명시를 해놓았기에 "유지하려고 하는 pod의 개수가 2개입니다" 라고 표시가 되었다.
Pod는 nginx-deployment라는 이름으로 되어있는 Pod가 2개 실행 중이다.

kubectl get pods -o wide
위 명령어는 가지고 있는 Pod의 정보가 좀 더 자세하게 표시가 된다.
각각 파드한테 할당되어진 IP 어드레스도 확인할 수 있다.

kubectl exec -it nginx-deployment-7fb96c846b-5hq75 -- /bin/bash
exec 라는 명령어로 Kubernetes에 의해서 작동되고 있는 Pod 내부에 터널링하여 bash셸에 접속할 수 있다.

apt-get update
몇 가지 명령어를 확인하기 위해 이 상태에서 apt-get update로 패키지 목록을 업데이트를 한다.
/etc/apt/sources.list의 저장소 주소가 잘못되어 에러 메세지가 떠서 echo 명령어를 활용해 구성파일을 살짝 변경해주었다.

echo "deb http://archive.debian.org/debian stretch main" > /etc/apt/sources.list
apt-get update

apt-get install -y curl wget
변경 후에 update, install 하였더니 정상적으로 설치가 되었다.
"curl"은 URL을 통해 데이터를 전송하고 받는 명령 줄 도구이며, "wget"은 인터넷 상의 파일을 다운로드하는 데 사용된다.

hostname -i
curl -X GET http://10.1.0.14
현재 "10.1.0.14"의 호스트 주소를 가지고 있는 것을 확인할 수 있다.
그리고 curl -X GET http://10.1.0.14는 10.1.0.14 IP 주소에 GET 요청을 보내 해당 주소에서 제공하는 데이터나 웹 페이지를 요청한다.
nignx라는 웹서버를 설치했을 때 보이는 기본적인 내용을 확인할 수 있다.
다시 말하지만 이것은 어디까지나 컨테이너, 즉 Pod 형태로 작동되고 있는 상태를 쓰고 있는 것이기 때문에 호스트 pc에서 사용할 거라고 하면 현재 Pod가 사용하고 있는 포트를 외부에서 사용할 수 있는 형태로 즉 서비스 형태로 오픈을 시켜 줘야만 사용 거능하다.

exit
kubectl get pods -o wide
kubectl get services
일단 종료한 후 현재 가지고 있는 Pod의 내용과 Serivce 내용도 확인한다.
현재 서비스는 Kubernetes의 기본 서비스만 실행 중이다.

kubectl expose deployment nginx-deployment --port=80 --type=NodePort
kubectl get services
Kubernetes 클러스터에서 'nginx-deployment'라는 Deployment에 대해 NodePort 타입의 서비스를 생성한다.
--type=NodePort : 서비스 유형을 NodePort로 지정하여 클러스터 외부에서도 접근 가능하게 하였다.
서비스를 기동시켰고, 그 서비스가 80포트로 오픈되어 있는데, 호스트 pc에서 사용할 때는 31851번으로 포워딩할 수 있다.
80은 Pod가 가지고 있는 포트, 31851은 호스트pc가 사용할 수 있는 포트인 것이다.

localhost:31851
이전에 curl -X GET http://10.1.0.14 명령어로 텍스트 형태로 확인한 html을 웹브라우저로 확인 가능하다.

kubectl delete pod/nignx-deployment-7...
kubectl get pods
삭제 시 개별적으로 Deployment로 실행되어 있는 Pod를 삭제하면 의미가 없다.
이전에도 확인했지만 Deployment로 되어 있는 Pod를 삭제하고, 실행 중인 Pod를 확인해보면 새로운 Pod가 생성이 된다.
앞서 말했듯이 deployment의 레플리카셋(ReplicaSet)의 개수의 만큼 계속 Pod의 개수 유지하려는 속성 때문에 Pod를 계속 지운다 하더라도 지정되어 있는 스케일링 개수만큼은 계속 생성을 해준다.

kubectl delete deployment nignx-deployment
kubectl get deployment
kubectl get pods
따라서 Pod를 삭제하고 싶다면 delete 명령어에 deployment를 삭제하는게 필요하다.

kubectl delete service/nignx-deployment
kubectl get services
깔끔하게 비우기 위해 만든 서비스도 지워주었다.
이번엔 조금 심화하여 deployment와 service를 만들어보자.

< k8s_script/cicd-devops-deployment.yml >
apiVersion: apps/v1
kind: Deployment
metadata:
name: cicd-deployment
spec:
selector:
matchLabels:
app: cicd-devops-project
replicas: 2
template:
metadata:
labels:
app: cicd-devops-project
spec:
containers:
- name: cicd-devops-project
image: 10000ji/cicd-project-ansible
imagePullPolicy: Always
ports:
- containerPort: 8080
기존에 만들었던 sample1.yml 내용과 다른 점을 찾아보면 sepc의 template 부분이다.
spec
spec은 어떤 kind를 쓰냐에 따라서 종류가 조금 달라지긴 하는데 Pod를 썼을 때는 Pod에 포함될 컨테이너 이름 쓰고, Deployment를 사용했을 때는 Deployment이 필요한 옵션들을 정리한다 보면 된다.
replicas
앞서 실행했던 것처럼 레플리카셋(ReplicaSet)에다가 2라고 입력하면 지금 만들고 있는 Deployment는 생성하려고 하는 Pod를 두 개 유지해달라는 명령어가 된다.
selector
selector에 지금 작업하려고 하는 대상을 어떤 labels에 명시할 건지 고를 수 있다.
( matchLabels )
labels를 app: cicd-devops-project고 적었다. 따라서 지금 작업하려고 하는 대상은 cicd-devops-project이다.
( key: app / value: cicd-devops-project )
template
그 밑에 있는 template이라는 것은 실제 이 Deployment를 통해서 설치하고자 하는 Pod의 내용을 기술하면 된다.
여기서도 metadata의 labels를 app: cicd-devops-project라고 적어주고,
(metadata:
labels:
app:cicd-devops-project)
spec의 containers에는 설치하고자 하는 컨테이너의 이미지 이름을 써준다.
(name: cicd-devops-project)
여기서 중요한 것은 image를 도커 허브 사이트에 올려두었던 걸을 가져올 수 있게 계정명/이미지명을 적어준다.
(image: 10000ji/cicd-project-ansible)
포트는 8080으로 설정해주었다.
(ports:
- containerPort: 8080)
< k8s_script/cicd-devops-service.yml >
apiVersion: v1
kind: Service
metadata:
name: cicd-service
labels:
app: cicd-devops-project
spec:
selector:
app: cicd-devops-project
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 32000
Deployment를 생성한 후 작동시키려면 외부에 공개해 접속할 수 있도록 서비스를 하나 만들어야 한다.
apiVersion
API 버전은 v1
kind
Kubernetes의 오브젝트는 Service
metadata
서비스 이름은 cicd-service, lebels는 cicd-devops-project로 설정
spec
selector
위쪽에서 labels를 app: cicd-devops-project라고 적어놨었다. 따라서 여기도 동일하게 적어주었다.
( key: app / value: cicd-devops-project )
type
서비스는 외부에 특정한 네트워크라던가 포트를 공개하는 목적으로 사용이 된다.
그때 외부에 공개하는 Type을 NodePort로 적어주었다.
ports
컨테이너가 가지고 잇는 포트번호는 8080, 외부에 공개할 때는 32000번으로 하겠다는 뜻이다.

kubectl apply -f cicd-devops-deployment.yml
kubectl get deployment
먼저 만든 cicd-devops-deployment.yml파일을 가지고 kubectl apply로 실행해준다.
실행 중인 Deployment를 확인해 보면 2/2로 정상적으로 생성이 된 것을 확인할 수 있다.

kubectl apply -f cicd-devops-service.yml
kubectl get services
localhost:32000/hello-world/
Deployment를 실행했으니 만든 cicd-devops-service.yml파일을 가지고 kubectl apply로 Service를 생성하였다.
생성된 Service를 확인해보았더니 포트가 32000번으로 포워딩되며 정상적으로 만들어진 것을 확인하였다.
앞서 말했듯 웹브라우저로 32000번 포트를 가지고 실행하고 있는 서비스를 확인해보았다.
이미지로 만들어놓은 index.jsp가 정상적으로 나온다.