DevOps 또한 자동화를 한다거나 코드로 관리할 수 있다면 얼마나 좋을까?
이러한 수요로인해 요즘 각광받고 있는것이 바로 IaC(Infrastructure as Code) 이다.
대표적으로 'ansible' 과 'terraform' 이 있는데, terraform' 의 경우 필요한 라이브러리나 서비스를 설치하는 단계인 프로비저닝에서 많이 사용하고, 자동화를 'ansible' 로 구성하는 두 가지 IoC 툴을 혼용하는 추세이다.
참고 기사
인프라 관리 자동화, ‘IaC’로 구현한다
이번 실습에서는 docker , jenkins , ansible , kubernetes(minikube활용) 을 사용해 어떤식으로 배포를 할 수 있는지 알아보도록 하자.
Docker 를 활용하면 virtualBox 를 활용한 것보다 훨씬 간단하게 로컬에서 CI/CD 환경을 구성해 볼 수 있는 장점이 있다. (필자의 경우 virtualBox 에서 우분투를 설치하는데에만 1시간 넘게 걸렸었다... 그리고 virtualBox 의 GUI 를 활용해 환경을 구성하는 것보다 직접 명령어를 통해 구성하는 것이 더 재밌다!)
먼저 docker 를 활용해 ubuntu 컨테이너를 설치해 서버로 활용할 것이다. 이를 위해 ubuntu 이미지를 다운받아 주자.
- 호스트 PC
docker search ubuntu
docker pull ubuntu
그리고 도커 내부에서 앞으로 설치할 컨테이너간의 통신이 가능하도록 network 그룹을 만들자.
- 호스트 PC
docker network ls
docker network create kube
이제 Ubuntu 컨테이너를 만들어주자.
여기서는 jenkins 서버로 활용할 컨테이너 kube-jenkins ,
ansible 서버로 활용할 컨테이너 kube-ansible ,
kubernetes 서버로 활용할 컨테이너 kube-minikube (minikube 란 가벼운 쿠버네티스 구현체이다.)
이렇게 만들어 줄 것이다.
다음 그림과 같이 Jenkins 를 통해 CI/CD 관리를 할 것이기에 host pc의 localhost 에서 Jenkins 에 접속하기위해 8080 포트를 추가로 포워딩 시켜주었다.
- 호스트 PC
docker run -d -i -t --name kube-jenkins -p 10022:22 -p 8080:8080 --net kube ubuntu
우선 kube-jenkins 컨테이너에 들어가 기본적인 것들을 설치해준 후 이를 도커 이미지화 시켜 놓을 것이다.
- 호스트 PC / kube-jenkins
docker exec -it kube-jenkins bash
apt-get update
apt-get install sudo net-tools vim openssh-server curl
ssh 의 경우 다음과 같이 /etc/ssh/sshd_config 설정에 PermitRootLogin yes 를 추가해 줘야 ssh 를 활용한 접속이 가능하다.
- kube-jenkins
vi /etc/ssh/sshd_config
# -->
# PermitRootLogin without-password
# 아래와 같이 바꾸거나 없으면 추가하자
# PermitRootLogin yes
# --<
root 계정에 password 를 추가하고 password 를 사용해 ssh 접속이 가능하도록 해주자.
- kube-jenkins
passwd root
service ssh start
`exit` 로 컨테이너에서 나와서 `ssh root@localhost -p 10022` 로 ssh 접속이 되는지 확인한 후 다시 `exit` 로 나와 현재까지 셋팅한 컨테이너를 이미지로 만들어 ansible 컨테이너를 만드는데 사용하자.
- 호스트 PC
docker commit kube-jenkins kube-default-ubuntu
docker run -d -i -t --name kube-ansible -p 20022:22 --net kube kube-default-ubuntu
이제 kube-jenkins 에 jenkins 를 설치해보자. 최신 jenkins 를 설치하기 위해서는 java 11 버전 이상이 필요하다.
(참고로 gradle 의 경우 jenkins 에서 `Invoke Gradle script` 를 이용하면 따로 설치할 필요 없다. 하지만 혹시라도 설치를 원한다면 `apt-get install gradle` 을 통해 설치하면 된다. )
또한 추가적으로 `apt-get install git` 으로 git 또한 설치해주자
- 호스트 PC / kube-jenkins
docker exec -it kube-jenkins bash
apt-get install openjdk-11-jdk
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io.key | sudo tee \
/usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
https://pkg.jenkins.io/debian binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
apt-get update
apt-get install jenkins
apt-get install git
이제 jenkins 를 실행해 주면 비밀번호가 나오는데 이를 복사해서 localhost:8080에 접속해 사용해주자
- kube-jenkins
jenkins
# ---
# ...
# "b5a03f6534e447a18818bdf0dfb8a8a3"
# ...
# ---
install sugested plugins 를 눌러 필요한 기본 plugins 들을 받아주도록 하자.
그 후 계정을 생성해 진행해 주면 된다.
이제 ansible 서버를 구성해보자. ansible 은 python 으로 개발되었기에 python 이 설치되어있어야한다.
- 호스트 PC / kube-ansible
docker exec -u root kube-ansible bash
apt-get update
apt-get install python3
apt-get install python3-pip
pip3 install ansible
이제 실습을 위한 간단한 프로젝트가 필요하다. 아래 깃헙에 간단한 프로젝트를 올려놓았다.
GitHub - Hooneats/kube-cicd
Contribute to Hooneats/kube-cicd development by creating an account on GitHub.
github.com
jenkins 에서 생성한 Item 에 다음과 같이 설정해 주면 된다.
Add build step 에 Invoke Gradle script 를 선택 후 Use Gradle Wrapper 를 클릭하면 따로 gradle 설치없이 jenkins 가 gradle wrapper 로 Tasks 를 실행해 준다. Make gradlew executable 를 체크하면 권한문제로 실행이 되지 않는 문제를 방지할 수 있다.
Execute shell 에 다음을 추가해 잘 완료 되었는지 확인해 보자.
이제 저장 후 빌드를 하면 다음과 같은 console 결과를 볼 수 있다.
이제 gradle 통해 생성된 jar 파일을 도커가 설치되어있는 다른 서버에 이동시켜보자 그러기 위해 먼저 jenkins plugin 에 추가적인 Publish Over Ssh 를 설치하자.
이제 jenkins 관리 -> Configure System 에 들어가 kube-master 와 연결해볼 것이다.
Publish over SSH 항목에 `추가` 버튼을 눌러 다음과 같이 알맞은 정보를 입력해주자.
보통은 jenkins 서버에서 `ssh-keygen -t rsa -C "test" -m PEM` 을 활용해 private key 와 public kye 를 만들고,
이 경우 private key(id_rsa) 를 아래 이미지의 Key 항목에 넣어주고, public key(id_rsa_pub) 내용을 kube-ansible 등(접속할 서버) 서버에 /root/.ssh/authorized_keys 안에 넣어줘야한다.(ssh-copy-id root@[접속할 서버] 로 넣어줄 수도 있다.)
하지만 여기서는 간단하게 위에서 설정한 Password 를 활용해 연결해보자.
참고로 SSH Server 에 Hostname 은 `docker network inspect [네트워크 이름]' 명령어로 확인할 수 있다.
- 호스트 PC
docker network inspect kube
그 후 item 구성에 들어와 빌드 후 조치에 `Send build artifacts over SSH` 를 추가 아래의 이미지 처럼 작성해 준다.
여기서 중요한것은 Source files 의 경로는 workspace 상대경로로 적어야한다.
Add Transfer Set 을 눌러 Dockerfile 또한 같이 kube-master 서버로 전송해주자
이제 kube-minikube 서버를 만들어보자. docker 를 통해 minikube 를 설치할 것이다. 이를 위해서
Docker in Docker 가 필요하고 우리는 현재 PC 인 호스트 PC 와는 별개로 작동하는 Docker 인 Real Docker in Docker 로 사용할 것이다.
Docker in Docker 에 대해 : 참고 블로그1 , 참고 블로그2 , 참고 블로그3
minikube 설치 : 참고 블로그1 , 참고 블로그2
- 호스트 PC / kube-minikube
docker run --privileged -d --name kube-minikube --net kube -p 30022:22 -p 9090:8080 docker:dind
apk update
apk add curl
apk add sudo
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \
&& chmod +x minikube
sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/
minikube version
minikube start --force --driver=docker
minikube kubectl -- get pods -A
minikube status
minikube 도 설치가 되었다면 실제 kubernetes 처럼 kubectl 명령어를 사용하기 위해 kubectl 설치도 진행하자
- kube-minikube
curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
kubectl version --output=json
kubectl get pods
kube-minikube 서버에 ssh 또한 설치하자
우선 service 명령어를 사용할 수 있도록 openrc 를 먼저 받고 sshd 를 받자
- kube-minikube
apk add openssh-server
vi /etc/ssh/sshd_config
# --> PermitRootLogin 설정을 yes 로 -> PermitRootLogin yes 추가
passwd root
# --> 비밀번호 설정
apk add openrc --no-cache
apk add openssh
rc-update add sshd
rc-status
/etc/init.d/sshd start
이제 kube-jenkins 서버 SSH publishers 에 kube-ansible 을 추가했듯이 kube-minikube 를 추가해 주자.
그리고 kube-ansible 서버에서 kube-minikube 서버에 ping 을 먼저 보내보자.
이를 위해 kube-minikube 에 python 이 설치되어있어야 하기에 kube-minikube 서버에 python 을 설치하자
- kube-minikube
apk add python3
또한 kube-ansible 이 kube-minikube 서버에 접속이 가능하도록, kube-ansible 서버에서 ssh 키를 생성해 kube-minikube 서버에 복사해 주자.
- kube-ansible
ssh-keygen
ssh-copy-id root@172.24.0.2
# --> 172.24.0.2 는 kube-minikube 서버
vi hosts
# -->
# 172.24.0.2
# ---< 추가
ansible all -i ./hosts -m ping
다음과 같은 결과를 볼 수 있다.
다음으로 Git-hub 에 Dockerfile 을 build 하는 plybook 파일을 만들어보자.
kube-minikube 로 복사되어있는 Dockerfile 을 build 후 image 를 docker-hub 에 push 하는 playbook 파일이다.
- kube-ansible
- hosts: all
tasks:
- name: if exists image then remove
command: docker rmi hooneats/kube-project
ignore_errors: yes
- name: build docker image, name kube-project
command: docker build -t hooneats/kube-project .
args:
chdir: /root
- name: push docker image
command: docker push hooneats/kube-project
추가적으로 docker-hub 에 push 를 위해 kube-minikube 서버에서 `docker login` 으로 login 해놓자
docker-hub 로그인 : 참고 블로그1
- kube-minikube
docker login
또한 kube-minikube 서버 에 kubernetes 를 사용해 서비스를 구동시킬 파일을 두가지 만들자
- kube-minikube
kube-mini-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kube-mini-deployment
spec:
selector:
matchLabels:
app: kube-mini-project
replicas: 2
template:
metadata:
labels:
app: kube-mini-project
spec:
containers:
- name: kube-mini-project
image: hooneats/kube-project
imagePullPolicy: Always
ports:
- containerPort: 8080
- kube-minikube
kube-mini-service.yml
apiVersion: v1
kind: Service
metadata:
name: kube-mini-service
labels:
app: kube-mini-project
spec:
selector:
app: kube-mini-project
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 32000
추가적으로 kube-minikube 서버에 저장해 놓은 두가지 파일을 실행시킬 playbook 파일 또한 Git-hub 에 추가해 주었다.
kube-minikube-deployment-playbook.yml
- name: Create pods from deployment
hosts: all
tasks:
- name: Delete previous deployment
command: kubectl delete deployment.apps/kube-mini-deployment
- name: Create deployment
command: kubectl apply -f kube-mini-deployment.yml
kube-minikube-service-playbook.yml
- name: Create service
hosts: all
tasks:
- name: create service tasks
command: kubectl apply -f kube-mini-service.yml
이제 kube-ansible 에 playbook 파일을 전송하고 playbook 파일을 실행하도록 jenkins 를 구성해보자.
새로운 Item 에서 jenkins-project 로 만들자
jenkins-project
이제 jenkins-project 가 빌드가 완료되면 ansible 이 실행되도록 ansible-project 도 새로운 item 으로 추가해주자.
ansible-project
여기까지 진행 후 jenkins-project 를 build 하면 kube-minikube 서버에 다음과 같이 service 가 생성된 것을 볼 수 있다.
보통 kubernetes 라면 외부와 연결된 포트인 NodePort 를 통해 서비스에 접속이 가능하지만 minikube 는 자체적으로 외부 IP를 막는지 접속이 되지 않았다... minikube 의 ip 를 사용해 접근해야한다고 하는데... 이를 위해 다음과 같이 kube-minikube 서버에서 입력하면 서비스를 볼 수 있다.
-----------------------------------------------------------------------------------
추가적으로
kube-minikube 서버를 docker 에 image push 하는 용도로만 사용하고 호스트 PC 에서 docker-desktop 에 kubernetes 설치를 이용해 kubernetes 설치 후 호스트 PC 를 이용할 수도 있다.
혹시라도 필자처럼 window 사용자라면 ssh 서버를 설치해야하기에 다음 블로그를 참고하길 바란다.
window ssh 설치 : 참고 블로그
'DevOps' 카테고리의 다른 글
kubernetes 개념 (2) | 2022.09.22 |
---|---|
Kubernetes 구조 이해하기 (0) | 2022.08.10 |
최신 (k8s - 2022.07 기준) kubernetes 설치 (0) | 2022.07.31 |
Terraform 을 사용해 AWS EC2 Instance 를 올려보자 (0) | 2022.07.26 |
AWS를 통한 효과적인 데브옵스 구축 2/e 2장 중 AWS CLI 로 EC2 구성하기 (0) | 2022.07.20 |