[Week7] AWS EKS CI/CD (1/2)

오태경·2024년 4월 20일

본 게시물은 CloudNet@팀 Gasida(서종호) 님이 진행하시는
AWS EKS Workshop Study 내용을 기반으로 작성되었습니다.

Jenkins

  • 소프트웨어 개발 프로세스의 다양한 단계자동화하는 도구로서 중앙 소스 코드 리포지터리에서 최신 코드 가져오기, 소스 코드 컴파일, 단위 테스트 실행, 산출물을 다양한 유형으로 패키징, 산출물을 여러 종류의 환경으로 배포하기 등의 기능을 제공.
  • 젠킨스는 아파치 톰캣처럼 서블릿 컨테이너 내부에서 실행되는 서버 시스템이다. 자바로 작성됐고, 소프트웨어 개발과 관련된 다양한 도구를 지원.
  • 젠킨스는 DSL Domain Specific Language (jenkins file)로 E-E 빌드 수명 주기 단계를 구축한다.
  • 젠킨스는 파이프라인이라고 부르는 스크립트를 작성할 수 있는데, 이를 사용해서 각 빌드 단계마다 젠킨스가 수행할 태스트 및 하위 태스크의 순서를 정의.
    • 순차적이고 종속적인 단계가 시작부터 끝까지 실행되면 최종적으로 사용자가 실행할 수 있는 빌드가 생성됨.
    • 만약 빌드 프로세스를 진행하는 중에 특정 단계에서 실패가 발생하며, 이 단계의 출력 결과를 사용하는 다음 단계는 실행되지 않으며 빌드 프로세스 전체가 실패한다.
  • 다양한 Plugins 연동
    - Build Plugins : Maven, Ant, Gradle …
    - VCS Plugins : Git, SVN …
    - Languages Plugins : Java, Python, Node.js …


설치 & 환경 설정

# 실습 편리를 위해서 root 계정 전환
sudo su -

# Add required dependencies for the jenkins package
# https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/amazon-linux-install.html
sudo yum install fontconfig java-17-amazon-corretto -y
java -version
alternatives --display java
JAVA_HOME=/usr/lib/jvm/java-17-amazon-corretto.x86_64
echo $JAVA_HOME

# 젠킨스 설치
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum upgrade
sudo yum install jenkins -y
sudo systemctl daemon-reload
sudo systemctl enable jenkins && sudo systemctl start jenkins
sudo systemctl status jenkins

# 초기 암호 확인
sudo systemctl status jenkins
cat /var/lib/jenkins/secrets/initialAdminPassword

# 접속 주소 확인 
curl -s ipinfo.io/ip | awk '{ print "Jenkins = http://"$1":8080" }'



  • 접속 확인 및 초기 암호 입력

  • 제안 플러그인 설치

  • 초기 화면


Tools 설정

  • Jenkins 관리 -> Tools

  • JDK installations : jdk-17 , /usr/lib/jvm/java-17-amazon-corretto.x86_64 → Save

  • Item 생성

    • 새로운 Item 클릭 → Freestyle project -> 하단 OK 클릭
    • Build Steps → Add build step -> Execute shell
  • 빌드 실행

  • 빌드 결과 확인



Docker 사용

# jenkins 유저로 docker 사용 가능하게 설정
grep -i jenkins /etc/passwd
usermod -s /bin/bash jenkins
grep -i jenkins /etc/passwd

# jenkins 유저 전환
su - jenkins
whoami
pwd
docker info
exit

#
chmod 666 /var/run/docker.sock
usermod -aG docker jenkins

# Jeknins 유저로 확인
su - jenkins
docker info

# Dockerhub로 로그인 하기
docker login
Username: <자신의 계정명>
Password: <자신의 암호>

# myweb:v2.0.0 컨테이너 이미지 생성을 위한 Dockerfile 준비
# 실습을 위한 디렉터리 생성 및 이동
mkdir -p ~/myweb2 && cd ~/myweb2

# Dockerfile 파일 생성
vi Dockerfile
FROM ubuntu:20.04
ENV TZ=Asia/Seoul VERSION=2.0.0 NICK=<자신의 닉네임>
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
    sed -i 's/archive.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list && \
    apt-get update && apt-get install -y apache2 figlet && \
    echo "$NICK Web Server $VERSION<br>" > /var/www/html/index.html && \
    echo "<pre>" >> /var/www/html/index.html && \
    figlet AEWS Study >> /var/www/html/index.html && \
    echo "</pre>" >> /var/www/html/index.html
EXPOSE 80
CMD ["usr/sbin/apache2ctl", "-DFOREGROUND"]

vi Dockerfile
FROM ubuntu:20.04
ENV TZ=Asia/Seoul VERSION=2.0.0 NICK=gasida
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
    sed -i 's/archive.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list && \
    apt-get update && apt-get install -y apache2 figlet && \
    echo "$NICK Web Server $VERSION<br>" > /var/www/html/index.html && \
    echo "<pre>" >> /var/www/html/index.html && \
    figlet AEWS Study >> /var/www/html/index.html && \
    echo "</pre>" >> /var/www/html/index.html
EXPOSE 80
CMD ["usr/sbin/apache2ctl", "-DFOREGROUND"]

# 모니터링
watch -d 'docker images; echo; docker ps'

-----------
# (참고) 이미지 빌드
docker build -t myweb:v2.0.0 -f /var/lib/jenkins/myweb2/Dockerfile

# (참고) 컨테이너 실행
docker run -d -p 80:80 --rm --name myweb myweb:v2.0.0
  • Item 생성

    • Build Steps : Execute shell
      # 이미지 빌드 및 컨테이너 실행
      cd /var/lib/jenkins/myweb2
      docker build -t myweb:v2.0.0 .
      docker run -d -p 80:80 --rm --name myweb myweb:v2.0.0
  • 빌드 실행 및 확인

    # 이미지 생성 확인
    docker images
    REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
    myweb        v2.0.0    5bdcb522b8d9   43 seconds ago   238MB
    ubuntu       20.04     33985b2ba010   9 days ago       72.8MB
    
    # 컨테이너 실행 확인
    docker ps
    CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS              PORTS                               NAMES
    b3db7a28035f   myweb:v2.0.0   "usr/sbin/apache2ctl…"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp, :::80->80/tcp   myweb
    
    # 접속 확인
    curl localhost
    tkops Web Server 2.0.0<br>
    <pre>
       _    _______        ______    ____  _             _
      / \  | ____\ \      / / ___|  / ___|| |_ _   _  __| |_   _
     / _ \ |  _|  \ \ /\ / /\___ \  \___ \| __| | | |/ _` | | | |
    / ___ \| |___  \ V  V /  ___) |  ___) | |_| |_| | (_| | |_| |
    /_/   \_\_____|  \_/\_/  |____/  |____/ \__|\__,_|\__,_|\__, |
                                                           |___/
    </pre>



Parameter 및 SCM 사용

  • Item 생성

    • 빌드 매개변수: String

      • 변수명(VERSION), Default Vault(v1.0.0)
      • 변수명(NICK), Default Vault(<자신의 계정명>)
    • 소스 코드 관리 : Git

      • Repo URL : https://github.com/<자신의 계정명>/aews-cicd
      • Branch : */main
      • Additional Behaviours → Sparse Checkout paths (Path) : 1
    • 빌드 유발 : Poll SCM (* * * * *)

    • Build Steps : Execute shell

      #
      cd /var/lib/jenkins/myweb2
      rm -rf Dockerfile
      wget https://raw.githubusercontent.com/$NICK/aews-cicd/main/1/Dockerfile
      docker build -t myweb:$VERSION .
      docker run -d -p 80:80 --rm --name myweb myweb:$VERSION

  • 빌드 트리거

    • GitHub 소스 코드 수정 후 빌드 자동 실행
  • 빌드 실행

    • 파라미터 입력하여 빌드


Pipeline 사용

  • Item 생성
  • Hello World 테스트

  • 환경 변수 사용

  • Tool 사용

  • 빌드 트리거 사용

  • 파라미터 사용

  • 빌드 후 조치(post) 사용

    • always: 항상 실행

    • changed: 현재 빌드의 상태가 이번 빌드의 상태와 달라졌다면 실행

    • success: 현재 빌드가 성공했다면 실행

    • failure: 현재 빌드가 실패했다면 실행

    • unstable: 현재 빌드의 상태가 불안하다면 실행



Jenkins with Kubernetes

사전 준비

# jenkins 사용자에서 아래 작업 진행
whoami
jenkins

mkdir ~/.kube

# root 계정에서 아래 복사 실행
cp ~/.kube/config /var/lib/jenkins/.kube/config
chown jenkins:jenkins /var/lib/jenkins/.kube/config

# jenkins 사용자에서 aws eks 사용(sts 호출 등)을 위한 자격증명 설정
aws configure
AWS Access Key ID [None]: AKIA5ILF2###
AWS Secret Access Key [None]: ###
Default region name [None]: ap-northeast-2

# jenkins 사용자에서 kubectl 명령어 사용 확인
kubectl get pods -A



파이프라인으로 Deployment & Service 배포

  • 배포 확인

    kubectl get pod,svc,ep
    
    NAME                              READY   STATUS    RESTARTS   AGE
    pod/awscli-pod-5bdb44b5bd-cczdb   1/1     Running   0          6d21h
    pod/awscli-pod-5bdb44b5bd-fwgtt   1/1     Running   0          6d21h
    pod/myweb-68f487c9f4-d7lb8        1/1     Running   0          4m24s
    pod/myweb-68f487c9f4-ppqx5        1/1     Running   0          4m12s
    pod/myweb-68f487c9f4-qvvhd        1/1     Running   0          4m24s
    pod/myweb-68f487c9f4-zgwf4        1/1     Running   0          4m13s
    
    NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    service/kubernetes   ClusterIP   10.100.0.1       <none>        443/TCP    7d2h
    service/myweb        ClusterIP   10.100.143.182   <none>        8080/TCP   5m18s
    
    NAME                   ENDPOINTS                                                        AGE
    endpoints/kubernetes   192.168.1.182:443,192.168.3.225:443                              7d2h
    endpoints/myweb        192.168.1.220:80,192.168.1.242:80,192.168.2.148:80 + 1 more...   5m18s
  • 접속 테스트용 파드 배포

    # 배포
    cat <<EOF | kubectl create -f -
    apiVersion: v1
    kind: Pod
    metadata:
     name: netpod
     labels:
       app: pod
    spec:
     containers:
     - name: netshoot-pod
       image: nicolaka/netshoot
       command: ["tail"]
       args: ["-f", "/dev/null"]
     terminationGracePeriodSeconds: 0
    EOF
  • 접속 테스트

    #
    kubectl exec -it netpod -- curl myweb:8080
    aews Web Server 1.0.0<br>
    <pre>
       _    _______        ______    ____  _             _
      / \  | ____\ \      / / ___|  / ___|| |_ _   _  __| |_   _
     / _ \ |  _|  \ \ /\ / /\___ \  \___ \| __| | | |/ _` | | | |
    / ___ \| |___  \ V  V /  ___) |  ___) | |_| |_| | (_| | |_| |
    /_/   \_\_____|  \_/\_/  |____/  |____/ \__|\__,_|\__,_|\__, |
                                                           |___/
    </pre>
    
    kubectl exec -it netpod -- curl myweb:8080 | grep Web
    aews Web Server 1.0.0<br>

0개의 댓글