내가 쓰는 aws 사양이 t2.micro 라서 실습하기 위해서는 3개의 인스턴스가 필요
각 인스턴스는 젠킨스 서버, k8s-control, k8s-worker(tomcat) 의 역할을 부여
jenkins 인스턴스
역할 : git 소스코드 관리, maven을 사용하여 코드 빌드,
k8s-control 인스턴스
k8s-worker 인스턴스
wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/redhat-stable/jenkins.reporpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
yum install -y java-17-amazon-corretto-devel
dnf -y install jenkins
systemctl daemon-reload
systemctl --now enable jenkins
웹 젠킨스 접속
cat /var/lib/jenkins/secrets/initialAdminPassword
젠킨스 암호 1234로 변경
Jenkins > Nodes > Built-In Node > Configure > Node Properties
크기를 다 400M 으로 설정 후 Built In Node 온라인으로 변경
플러그인 설치 (플러그인은 기본적으로 git, maven 등이 설치된 후에 해야 정상적으로 설치가 완료됨)
CloudBees Docker Build and Publish
Kubernetes Ephemeral Container
GitHub
Maven Integration
publish over ssh
자바 위치 : /usr/lib/jvm/java-17-amazon-corretto.x86_64/bin/
빌드 위치 : /var/lib/jenkins/workspace/아이템명/target/아이템명.war
cd /opt
wget https://dlcdn.apache.org/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.tar.gz
tar xfz apache-maven-3.9.11-bin.tar.gz
mv apache-maven-3.9.11 maven
cd /opt/maven/bin
./mvn -v
cd
vi .bash_profileM2_HOME=/opt/maven M2=/opt/maven/bin JAVA_HOME=/usr/lib/jvm/java-17-amazon-corretto.x86_64 PATH=$PATH:$M2source .bash_profile
echo $PATH
mvn -v
메이븐 기본 위치 : /opt/maven
dnf -y install git
git --version
cd
ssh-keygen -t ed25519
cat /root/.ssh/id_ed25519.pub
git repository 에서 setting > ssh 키 등록
mvn archetype:generate -DgroupId=com.test2 -DartifactId=test2 -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
cd test2
git init
git remote add origin git@github.com:nohsohyun0128/test2.git
git add .
git commit -m "0724-1"
git pull origin master
git repository 연결 및 소스코드 다운로드 완료
tomcat docker 이미지 빌드위한 기본 설정
사실 톰캣을 사용하려고 하는건데 톰캣에 기본적인 설정이 필요함
기본적인 설정을 위해 임시로 톰캣을 설치하고 작업이 완료되면 지우겠음
cd /opt
wget https://dlcdn.apache.org/tomcat/tomcat-11/v11.0.9/bin/apache-tomcat-11.0.9.tar.gz
tar xfz apache-tomcat-11.0.9.tar.gz
mv apache-tomcat-11.0.9 tomcat
포트 변경이 필요할 때는 server.xml 파일 수정
vi /opt/tomcat/conf/server.xml
find / -name "context.xml"
vi /opt/tomcat/webapps/host-manager/META-INF/context.xml
해당 부분 주석 처리<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" /> -->
vi /opt/tomcat/webapps/manager/META-INF/context.xml
해당 부분 주석 처리<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" /> -->
vi /opt/tomcat/conf/tomcat-users.xml<role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> <user username="admin" password="1234" roles="manager-gui,manager-script,manager-jmx,manager-status"/> <user username="gui" password="1234" roles="manager-gui"/> <user username="jenkins" password="1234" roles="manager-script"/>
dnf -y install docker
systemctl --now enable docker
systemctl status docker
docker -vdocker login
dnf -y install ansible
vi /etc/ansible/hosts[k8s] 10.0.11.156 [jenkins] 10.0.11.170vi docker_build.yaml
--- - hosts: jenkins tasks: - name: create docker images shell: docker build -t sohyun2223/setting_tomcat:v2 . args: chdir: /opt/devops - name: push docker images shell: docker push sohyun2223/setting_tomcat:v2vi k8s.yaml
--- - hosts: k8s tasks: - name: delete k8s shell: kubectl delete -f /opt/devops/deployment.yaml || true - name: apply k8s shell: kubectl apply -f /opt/devops/deployment.yaml - name: service k8s shell: kubectl apply -f /opt/devops/service.yaml
사실 이 상태로 ansible --check 하면 오류가난다. 이유? ssh-key-copy 해야하는데 안했기 때문.
ansible all -m ping
본인, k8s-control 모두 오류
이유 : 둘다 ssh-key-copy 안해서
따라서 ssh key를 두개 모두 복사하겠다.
근데 사실 이건 그저 인스턴스에서 자체 테스트를 하기 위해서이고 이걸로 jenkins를 쓰려면 수정해야함
passwd root
1234
vi /etc/ssh/sshd_configPermitRootLogin yes PasswordAuthentication yessystemctl restart sshd
passwd root
1234
vi /etc/ssh/sshd_configPermitRootLogin yes PasswordAuthentication yessystemctl restart sshd
ssh-copy-id root@10.0.4.14 (k8s)
ssh-copy-id root@10.0.10.13 (jenkins - 본인에게도 복사해야함)
ansible all -m ping
성공 그 후에 ansible-playbook --check 실행

cd /opt/devops
ansible-playbook docker_build.yaml --check
ansible-playbook k8s.yaml --check

java-17
/usr/lib/jvm/java-17-amazon-corretto.x86_64/

maven-3.9.11
/opt/maven

최 하단에 SSH Servers에 추가
jenkins_account
10.0.10.13
jenkins
Name 4gl-ansible (알아보기 편한 이름)
Hostname 프라이빗 IP
Username 인스턴스 내 지정한 계정id (ansibleadmin, jenkins 등)

jenkins 계정이 확인되고 해당 계정은 /bin/false 이기 때문에 /bin/bash로 변경해준 후 jenkins 계정으로 ssh키를 만들어서 k8s-control 인스턴스에 jenkins 계정에 ssh키를 copy해놓는다 (필요하다면 k8s-control jenkins 계정도 /bin/bash로 설정)
cat /etc/passwd
useradd jenkins
passwd jenkins
1234
cat /etc/passwd
usermod -s /bin/bash jenkins
passwd jenkins
1234
sudo su - jenkins
ssh-keygen -t ed25519
ssh-copy-id jenkins@10.0.4.14
ssh-copy-id jenkins@10.0.10.13
dnf -y install containerd
systemctl --now enable containerd
vi /etc/hosts3.35.136.101 k8s-control 3.35.141.134 tomcat-workermodprobe overlay
modprobe br_netfiltercat << EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOFcat << EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptalbes = 1
net.bridge.bridge-nf-call-ip6talbes = 1
net.ipv4.ip_forward = 1
EOFcat /etc/modules-load.d/k8s.conf
cat /etc/sysctl.d/k8s.conf
sysctl --systemlsmod | grep overlay
lsmod | grep br_netfiltersysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
containerd config default | tee /etc/containerd/config.toml
cat /etc/containerd/config.toml
vi /etc/containerd/config.toml
139행의 SystemdCgroup = false → true 없으면 추가하면 됨
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = truesystemctl restart containerd
# This overwrites any existing configuration in /etc/yum.repos.d/kubernetes.repo cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/ enabled=1 gpgcheck=1 gpgkey=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/repodata/repomd.xml.key exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni EOFcd /etc/yum.repos.d/
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable --now kubelet
kubeadm version
systemctl status kubeletkubeadm init
kubeadm init --ignore-preflight-errors=NumCPU,Memmkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/configkubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
mkdir /opt/devops
cd /opt/devops
vi deployment.yamlapiVersion: apps/v1 kind: Deployment metadata: name: tomcat labels: app: tomcat spec: replicas: 1 selector: matchLabels: app: tomcat template: metadata: labels: app: tomcat spec: containers: - name: tomcatserver image: sohyun2223/setting_tomcat:v2 ports: - containerPort: 8082vi service.yaml
apiVersion: v1 kind: Service metadata: name: tomcat-service spec: type: NodePort selector: app: tomcat ports: - protocol: TCP port: 8082 targetPort: 8080 nodePort: 30080vi Dockerfile
FROM tomcat:latest RUN cp -R /usr/local/tomcat/webapps.dist/* /usr/local/tomcat/webapps COPY ./*.war /usr/local/tomcat/webapps/
dnf -y install containerd
systemctl --now enable containerd
vi /etc/hosts3.35.136.101 k8s-control 3.35.141.134 tomcat-workermodprobe overlay
modprobe br_netfiltercat << EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOFcat << EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptalbes = 1
net.bridge.bridge-nf-call-ip6talbes = 1
net.ipv4.ip_forward = 1
EOFcat /etc/modules-load.d/k8s.conf
cat /etc/sysctl.d/k8s.conf
sysctl --systemlsmod | grep overlay
lsmod | grep br_netfiltersysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
containerd config default | tee /etc/containerd/config.toml
cat /etc/containerd/config.toml
vi /etc/containerd/config.toml
139행의 SystemdCgroup = false → true 없으면 추가하면 됨
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = truesystemctl restart containerd
# This overwrites any existing configuration in /etc/yum.repos.d/kubernetes.repo cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/ enabled=1 gpgcheck=1 gpgkey=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/repodata/repomd.xml.key exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni EOFcd /etc/yum.repos.d/
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable --now kubelet
kubeadm version
systemctl status kubeletkubeadm join 10.0.11.156:6443 --token h5c16x.i3tulqypte4defvu \
--discovery-token-ca-cert-hash sha256:f4a5213b540324147a205670c2fcafdfa7a4d60a005bc075306433d16846313b
dnf -y install docker
systemctl --now enable docker
systemctl status docker
docker -v
소스코드 빌드(메이븐) → .war 파일로 패키징 → Docker 이미지 빌드 및 push → kubectl 명령으로 K8s에 배포
작업 순서가 필요하기 때문에 item은 freestyle project를 선택하여 작업

Build Steps > Invoke top-level Maven targets

clean package
pom.xml


cd /var/lib/jenkins/workspace/1_test/target cd /opt/devops BUILD_NUM=$((BUILD_NUMBER + 1)) docker build -t sohyun2223/setting_tomcat:$BUILD_NUM . docker push sohyun2223/setting_tomcat:$BUILD_NUM
하지만 나는 그냥 v2 태그에서 계속 반복하겠다...
deployment.yaml 내에 image에 v2로 입력했기 때문
cd /var/lib/jenkins/workspace/1_test/target
cd /opt/devops
docker build -t sohyun2223/setting_tomcat:v2
docker push sohyun2223/setting_tomcat:v2

아니 그냥 ansible 써서 편하게 작업하겠음
ansible-playbook /opt/devops/docker_build.yaml
ansible-playbook /opt/devops/k8s.yaml


target/*.war
target
//opt/devops

이제 젠킨스에서 소스코드 관리에서 git 주소 입력
build step에 1. invoke top-level maven targets 선택해서 goals는 clean package, 고급에서 POM에는 pom.xml 입력
2. exectue shell 추가해서 거기다가 ansible-playbook /opt/devops/docker_build.yaml, ansible-playbook /opt/devops/k8s.yaml
소스코드 관리
Git 저장소 주소 입력 (예: https://github.com/xxx/yyy.git)
Build Step 1:
Invoke top-level Maven targets
Goals: clean package
POM: 고급 옵션에 pom.xml 직접 입력
→ Git에서 소스코드 받아서 Maven으로 빌드하고 최신 .war 파일 생성
Build Step 2:
Execute shell 추가
내용:
bash
ansible-playbook /opt/devops/docker_build.yaml
ansible-playbook /opt/devops/k8s.yaml
→
docker_build.yaml 실행:
방금 빌드된 .war 파일을 포함해서 Docker 이미지 생성
Docker Hub로 push
k8s.yaml 실행:
기존 Deployment 리소스가 있으면 삭제(delete)
최신 yaml로 apply하여 새로 배포
Service도 apply하여 서비스 오브젝트 최신화
실행 흐름 요약
git 저장소 pull
Maven 빌드로 .war 파일 생성
Ansible docker_build.yaml
Docker 빌드 & Docker Hub push
Ansible k8s.yaml
기존 배포(delete) 후 apply로 신규 생성
서비스 필요시 service.yaml도 apply
jenkins 인스턴스
k8s-control 인스턴스
k8s-worker 인스턴스
/etc/ansible/hosts
[docker]
GitHub 저장소에 접근할 SSH 키 등록(이미 진행)
Jenkins에서 Item(프로젝트) 생성: Freestyle or Pipeline Job
Build Steps > Invoke top-level Maven targets
clean package 등 입력 → .war 파일 생성 위치 확인
Jenkins Pipeline에 다음 단계 추가
Dockerfile 준비(소스 코드와 .war 파일 포함하도록)
Jenkins 빌드 후 단계(Post-build)에서 Docker 이미지 생성 및 Docker Hub 푸시 (docker build, docker push)
Docker Hub 접근을 위해 Jenkins에 Docker Hub 인증정보 등록(Credentials Plugin 활용, docker login)
Jenkins에서 이 yaml 파일을 활용(혹은 동적으로 이미지 태그만 바꿔치기 가능하게 처리)
Jenkins에서 빌드 후 단계(Post-build) 또는 Pipeline에서
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
실행하는 스테이지 추가
(프라이빗 이미지 쓸 경우) k8s에서 docker-registry 시크릿 생성해두기
실질적으로 진행할 작업 정리
Jenkins Job(Pipeline) 구성 및 스크립트 작성
빌드, 도커 이미지 생성/푸시, 쿠버네티스 배포 파이프라인 스크립트 완성(혹은 단계별 Post-build)
GitHub Webhook/자동 트리거 연동(변경 감지 후 자동 배포)
Jenkins에 Docker, kubectl 권한/인증 세팅(도커 허브 및 K8s 접근 토큰 등)
소스코드 빌드해서 .war 파일을 생성해
dockerfile 문서
그리고 docker hub에 업로드하고
내 docker hub 기반으로 pod가 생성되어야함(deployment.yaml, service.yaml 실행)
그러면 성공이겠쥬?!