작업 목적 : 여러 개의 컨테이너를 오케스트레이션할 수 있도록 Docker Image단위로 Kubernetes 서비스를 구축한다.
1. Docker Image pull -> Docker run
2. Docker Image -> Kubernetes pod으로 관리
3. Docker Image들을 Kubernetes를 통해서 오케스트레이션
서비스 임의종료시 복구 확인
4. 일련의 과정을 원클릭(최소) instruction으로 수행
각 서비스별 상세 설정항목 관리
Docker Image pull 받아서 Kubernetes로 실행 (from dockerhub)
Jenkins, Nexus, Tomcat, MariaDB
여러 개의 컨테이너를 오케스트레이션할 수 있도록 Docker Image단위로 Kubernetes 서비스를 구축한다.
사용 할 Docker Images : Jenkins, Nexus, Tomcat, MariaDB
Kubernetes 오케스트레이션
Minikube 클러스터 만들기
minikube start 명령어를 통해서 minikube를 실행시켜준다.
위와 같은 결과가 나온다면 정상적으로 작동되고 있다는 것을 알 수 있다.
참고한 사이트 : minikube 클러스터 만들기
Hello Minikube
이 튜토리얼에서는 Minikube와 Katacoda를 이용하여 쿠버네티스에서 샘플 애플리케이션을 어떻게 실행하는지 살펴본다. Katacode는 무료로 브라우저에서 쿠버네티스 환경을 제공한다. 참고: 로컬에서
kubernetes.io
Kubernetes deployment 만들기
deployment 란
디플로이먼트는 쿠버네티스가 애플리케이션의 인스턴스를 어떻게 생성하고 업데이트해야 하는지를 지시한다.
각 개별 노드가 일을 잘 하고있는지 못하고있는지 감시를 하다가 노드가 다운이 되거나 삭제가 되면
다른 노드의 인스턴스로 교체시켜주는 역할을 한다.
kubectl create deployment nexus --image=sonatype/nexus3:latest
위 명령어는 deployment를 생성하는데 이름은 nexus로, 관리하는 pod의 image는 sonatype:nexus3 으로 그리고 그 이미지의 태그는 latest라는 뜻이다.
kubectl describe pods
를 입력하면 pod에 대한 정보를 얻을 수 있다.
minikube dashboard 를 통해서 대쉬보드를 확인하면
이렇게 정상적으로 나오는 것을 볼 수 있다.
deployment가 정상적으로 작동하는지 확인하기 위해서 일부로 pod를 삭제해본다.
kubectl delete pod <pod name>
을 통해서 삭제를 해준다.
Tip : kubectl delete pod까지 치고 <pod name> 을 전부 치지 말고 몇글자만 친 다음 Tap키를 누르면 자동완성이 된다. (kubectl 자동완성 기능 다운받아야 함)
pod 삭제 이후 kubectl get pods 명령어로 다시 pod를 확인해보면 AGE가 10초밖에 안된 pod가 다시 생성이 되어있다.
이것으로 디플로이먼트가 이 nexus-86b8f8c75c-d4d55 pod를 주시하고있다가 원하는 상태로 계속 바꿔주는 것을 알 수 있다.
참고한 사이트 : 쿠버네티스 느낌가져가기, kubectl 치트 시트, 쿠버네티스 공식 문서 : 앱 배포하기
앱 배포하기
운영 수준의 컨테이너 오케스트레이션
kubernetes.io
kubectl 치트 시트
참고 항목: Kubectl 개요와 JsonPath 가이드. 이 페이지는 kubectl 커맨드의 개요이다. kubectl - 치트 시트 Kubectl 자동 완성 BASH source <(kubectl completion bash) # bash-completion 패키지를 먼저 설치한 후, bash의 자��
kubernetes.io
쿠버네티스 느낌가져가기 1 - minikube
쿠버네티스 느낌가져가기 1 - minikube - 아이단의 블로그
aidanbae.github.io
Kubernetes object
kubernetes object 란
쿠버네티스 오브젝트는 클러스터의 상태를 나타내기 위해 사용하는 것이다.
쿠버네티스 시스템은 오브젝트에 명시되어있는 것을 보장하기 위해 지속적으로 작동한다.
이것이 바로 우리가 클러스터에 대해 "의도한 상태" 가 되는 것이다.
object의 명세(spec)와 상태(status)
spec 을 가진 오브젝트는 오브젝트를 생성할 때 리소스에 원하는 "원하는 상태"에 대한 설명을 제공해서 설정한다.
그럼 쿠버네티스는 실제 상태를 사용자가 의도한 상태와 일치시키기 위해 끊임없이 그리고 능동적으로 관리한다.
기본적인 디플로이먼트 생성 오브젝트입니다.
deployment object 선언 및 생성
deployment.yaml 생성
다음과 같이 deployment.yaml을 생성해주었다.
pod는 3개를 생성하고, deployment의 이름은 test-deployment로 실행
그리고 containers에 image이름을 잘못쓰면
다음과 같이 ImagePullBackOff 오류가 뜬다.
이 오류는 image이름을 잘못쓰거나, 로컬에있는 이미지를 받아오는것에 permission을 받지못해서 생기는 오류라고 한다.
그럴때는 secret을 만들어서 permission을 받거나, image 이름을 잘 확인하자..
잘 받아오게 되면 Running 상태로 잘 실행이 되는 것을 확인할 수 있다.
그 다음에 주소를 받아오기 위해서 Service를 만들어야 한다.
Service를 만들어주는 deployment-service.yaml을 작성해주었다.
service가 잘 생성되었다. 8080뒤에있는 해쉬번호가 jenkins로 들어가기 위한 포트번호가 된다.
주소는 클러스터ip:포트번호 로 접속하면 되기 때문에
클러스터 ip를 알아온다.
그러면 jenkins가 구동되고있는 주소는 http://172.17.0.3:32318이 된다
정상적으로 접속이 된 모습.
참고한 사이트 : How-to-setup jenkins on kubernetes, 쿠버네티스 multiple ports 연결,
쿠버네티스 디플로이먼트 개념
[Kubernetes] 쿠버네티스 디플로이먼트(Deployment) 개념 (생성, 확인, 업데이트, 롤백, 롤아웃 기록 조��
디플로이먼트(Deployment) 란? 디플로이먼트는 레플리카셋의 상위 개념으로 볼 수도 있습니다. 레플리카셋을 생성하는 디플로이먼트를 정의할 수 있고, 배포 작업을 좀 더 세분화(롤링 업데이트 등
nirsa.tistory.com
How to expose multiple port using a load balancer services in kubernetes
I have created a cluster using the google cloud plateform (container engine) and deployed a pod using the following yaml file: apiVersion: extensions/v1beta1 kind: Deployment metadata: name:
stackoverflow.com
kubernetes deployment of scale down
현재는 test-deployment에 관리되는 레플리카에 3개의 pod가 있지만
하나로 줄이고 싶다면
kubectl scale deploy <deploymnet name> --replicas=1
위와 같이 입력해주면 deployment가 scaled 됐다는 문구와 함께 2개의 pod를 terminating한다.
그러고는 하나의 pod만 남겨놓는 것을 알 수 있다.
본래의 kubernetes scaling의 개념
kubernetes에서 제공하는 scaling의 개념은 만약 트래픽이 증가하면
자동적으로 deployment의 replicas의 개수가 바뀌면서 관리를 해준다는 기능이다.
replicas의 개수를 0개로 지정도 되는데 그렇게 되면
deployment의 pod가 모두 terminated될 것이다.
참고한 사이트 : 쿠버네티스 공식문서 : Scale , 스택오버플로우 Scale down
Scale down Kubernetes pods
I am using kubectl scale --replicas=0 -f deployment.yaml to stop all my running pods. Please let me know if there are better ways to bring down all running pods to Zero keeping configuration,
stackoverflow.com
Running Multiple Instances of Your App
Objectives Scale an app using kubectl. Scaling an application In the previous modules we created a Deployment, and then exposed it publicly via a Service. The Deployment created only one Pod for running our application. When traffic increases, we will need
kubernetes.io
Jenkins, Nexus, Mariadb, Tomcat을 하나의 deployment로 관리
Jenkins, Nexus 연결
하나의 deployment에 동시에 두개의 컨테이너를 명시
하나는 jenkins, 하나는 nexus로 각각 다른 port를 지정해준다.
그리고 포트를 노출시키기 위한 service도 아래에 작성
service에서 targetPort는 위에 deployment에서 컨테이너의 ports에 적어준
name을 명시해준다.
그리고
kubectl apply -f <파일명>
deployment와 service가 동시에 생성되는 것을 볼 수 있다.
8080 : 32181로 8081 : 31574
<클러스터ip : port번호> 로 입력하면 각각의 컨테이너에 접속할 수 있다.
172.17.0.2:31574 = Nexus
172.17.0.2:32181 = Jenkins 구동중
그리고 각각의 서비스들은 deployment에 의해서 관리된다.
참고한 사이트 : how to configure a kubernetes multi pod deployment, Kubernetes NodePort vs LoadBalancer vs Ingress?
Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?
Recently, someone asked me what the difference between NodePorts, LoadBalancers, and Ingress were. They are all different ways to get…
medium.com
How to configure a Kubernetes Multi-Pod Deployment
I would like to deploy an application cluster by managing my deployment via k8s Deployment object. The documentation has me extremely confused. My basic layout has the following components that scale
stackoverflow.com
하나의 deployment에 다수 이미지 명시를 했을 때의 문제점
내가 생각했던 것은 하나의 deployment에 여러개의 컨테이너를 명시해주면
각각의 컨테이너가 pod 하나씩 연결이 되는줄 알았다..
만약 각각의 컨테이너들을 하나의 pod로 연결해주고 싶다면
여러개의 deployment를 써야한단다.
하나의 deployment는 오직 하나의 pod를 지원한다!
그렇기 때문에 코드를 조금 수정해주었다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: Jenkins-deployment
labels:
app: MyApp
spec:
replicas: 1
selector:
matchLabels:
app: MyApp
template:
metadata:
labels:
app: MyApp #pod tempate의 레이블 명세
spec:
containers:
- name: jenkins #jenkins 컨테이너 명세
image: jenkins/jenkins:lts #jenkins 이미지 이름 명시
ports:
- containerPort: 8080
name: jenkins
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: Nexus-deployment
labels:
app: MyApp
spec:
replicas: 1
selector:
matchLabels:
app: MyApp
template:
metadata:
labels:
app: MyApp #pod tempate의 레이블 명세
spec:
containers:
- name: nexus #nexus 컨테이너 명세
image: sonatype/nexus3:latest #nexus 이미지 이름 명시
ports:
- containerPort: 8081
name: nexus
---
apiVersion: v1
kind: Service
metadata:
name: service
spec:
type: NodePort
ports:
- name: jenkins
protocol: TCP #기본 프로토콜 : TCP
port: 8080
targetPort: jenkins
- name: nexus
protocol: TCP
port: 8081
targetPort: nexus
selector:
app: MyApp
두 개의 deployment로 나누어주었다.
참고로 deployment의 metadata의 name 필드는 영어 소문자로 시작해야되고
'-' , '/' 같은 특수문자는 허용되지 않는다.
성공적으로 yaml 파일이 작성이 됐다면
잘 작동한다.
Jenkins와 nexus는 하나의 yaml파일에 명시해서 잘 작동하게 했으니,
다음으로는 tomcat과 mariaDB까지 연동해서
우리가 목적했던 쿠버네티스 오케스트레이션을 마무리 하려고 한다.
docker-compose와 kubernetes deployment는 같으면서도 전혀 다른 느낌이다.
deployment 명세할 때 docker-compose 코드를 많이 참고했다.
mariaDB와 tomcat을 연동하기위해 또 두개의 deployment를 추가해주었다.
코드에 대한 설명은 아래 주석과 함께 올리겠다.
그에 맞게 Service도 바꾸어준다. 각각의 targetPort에 명시를 해주어야 한다.
mariadb deployment와 tomcat deployment가 추가가 되면서 created 되는 모습
그리고 컨테이너가 만들어진다.
결과물들
deployment.yaml
apiVersion: apps/v1
kind: Deployment # deployment
metadata:
name: jenkins # deployment의 이름 = jenkins
labels:
app: MyApp # deployment의 레이블 = MyApp
spec:
replicas: 1 # 최대 생성 pod 개수
selector:
matchLabels:
app: MyApp # MyApp이라는 레이블을 가진 container와 연결해준다.
template:
metadata:
labels:
app: MyApp # pod tempate의 레이블 명세
spec:
containers:
- name: jenkins # jenkins 컨테이너 명세
image: jenkins/jenkins:lts # jenkins 이미지 이름 명시
ports:
- containerPort: 8080 # container에서의 port번호
name: jenkins # port의 이름 = Service와 connect
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nexus
labels:
app: MyApp
spec:
replicas: 1
selector:
matchLabels:
app: MyApp
template:
metadata:
labels:
app: MyApp
spec:
containers:
- name: nexus
image: sonatype/nexus3:latest
ports:
- containerPort: 8081
name: nexus
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat
labels:
app: MyApp
spec:
replicas: 1
selector:
matchLabels:
app: MyApp
template:
metadata:
labels:
app: MyApp
spec:
containers:
- name: tomcat
image: tomcat
ports:
- containerPort: 8080
name: tomcat
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mariadb
labels:
app: MyApp
spec:
replicas: 1
selector:
matchLabels:
app: MyApp
template:
metadata:
labels:
app: MyApp
spec:
containers:
- name: mariadb
env: #환경변수 설정
- name: MYSQL_ROOT_PASSWORD #root_password
value: admin # = admin
---
apiVersion: v1
kind: Service
metadata:
name: service
spec:
type: NodePort
ports:
- name: jenkins
protocol: TCP #기본 프로토콜 : TCP
port: 8080 #Service 자신의 포트
targetPort: jenkins #Pod 내 컨테이너 포트 (deployment의 port name과 연결)
nodePort: 30001
- name: nexus
protocol: TCP
port: 8081
targetPort: nexus
nodePort: 30002
- name: tomcat
protocol: TCP
port: 8082
targetPort: tomcat
nodePort: 30003
- name: mariadb
protocol: TCP
port: 3306
targetPort: mariadb
nodePort: 30004
selector:
app: MyApp
지금까지 우리가 목표한 쿠버네티스를 이용한 전체 서비스의 오케스트레이션을 해보았다.
느꼈던 점
처음 접했던 쿠버네티스, 너무 생소하고 내가 할 수 있을까 라는 생각이 먼저들었다.
쿠버네티스도 모르는데 Jenkins, Nexus, MariaDB, Tomcat 총 4개의 서비스를
연결해서 관리를 하라는 말이 무슨 뜻인지도 몰랐다.
docker의 개념을 처음 보았을 땐 이해가 잘가지않았지만 계속 이해하려고
노력하다보니 어느순간 이해를 하게 되었다. 그리고 엄청난 기술이란것도 알았다.
우리가 사용하는 어플리케이션의 뒷단에서 관리하는 관리자같은 느낌
신기하고 재미있었다. 아직 배워야 할 것이 더 많지만 할수없다고 느껴진 것을
해내고나니 자신감도 생기고 더 공부해보고 싶다는 생각이 든다.
'Kubernetes & Docker' 카테고리의 다른 글
Docker-compose로 여러 개의 서비스 구동하기 (0) | 2020.07.10 |
---|---|
Docker를 이용한 Tomcat Image pull & run (0) | 2020.07.10 |
Docker를 이용한 Nexus Image pull & run (0) | 2020.07.10 |
Docker를 이용한 MariaDB Image pull & run (0) | 2020.07.10 |
Docker를 이용한 Jenkins Image pull & run (0) | 2020.07.10 |