실습

Jenkins

  1. EC2 인스턴스 생성

    • AMI: Amazon Linux 2

    • Instance Type: m5.large

    • IAM 역할: Session Manager 접근이 가능한 역할 부여

    • EBS 볼륨 크기: 20GiB

    • 보안그룹: 모든 IP 주소에서 80번 포트 접근 허가

  2. Session Manager를 통해서 위에서 생성한 EC2 인스턴스에 접근

  3. Docker 설치

    sudo yum install docker -y
  4. Docker 데몬 실행

    sudo systemctl enable docker
    sudo systemctl start docker
  5. Docker 볼륨 생성

    sudo docker volume create jenkins-home
  6. Jenkins 컨테이너 실행

    sudo docker container run -d -p 80:8080 -v jenkins-home:/var/jenkins_home -v "/var/run/docker.sock:/var/run/docker.sock" --name jenkins --privileged -u root youngwjung/jenkins
  7. Jenkins 초기 관리자 비밀번호 확인

    sudo docker exec jenkins bash -c "cat /var/jenkins_home/secrets/initialAdminPassword"
  8. 웹 브라우저를 열고 EC2 인스턴스 퍼블릭 IP 주소로 접속

  9. Select plugins to install 을 선택해서 아래와 같은 플러그인 설치

    • OWSAP Markup Formatter

    • Build Timeout

    • Credentials Binding

    • Timestamper

    • Workspace Cleanup

    • Pipeline

    • Pipeline: Stage View

    • Git

    • Git Parameter

    • Matrix Authorization Strategy

  10. Admin 유저 생성

  11. Jenkins URL 설정

  12. Jenkins 재시작

  13. 보안 설정: Manage JenkinsConfigure Global Security 로 이동 후 CSRF 설정에서 프록시 호환성 활성화

  14. 추가 플러그인 설치: Manage JenkinsManage Plugins 로 이동 후 아래와 같은 플러그인 설치

    • Docker Pipeline

    • Amazon ECR

Jenkins Pipeline 생성

  1. https://github.com/youngwjung/nginx 리포지토리를 Fork

  2. Private ECR 리포지토리 생성

  3. Crendentials 등록: Manage JenkinsManage CredentialsStore = JenkinsDomain: Global credentialsAdd Credentials

    • GitHub

      • Kind: Username with password

      • Username: 깃허브 아이디

      • Password: 깃허브 비밀번호

      • ID: GitHub

    • ECR

      • Kind: AWS Credentials

      • ID: ECR

      • Access Key ID: AWS 엑서스 키

      • Secret Access Key: AWS 시크릿 엑서스 키

  4. New ItemEnter an item namenginx 입력 → Pipeline 선택 → OK

  5. Pipeline script에 아래의 내용을 복사에서 붙여넣고 Save

    pipeline {
        agent any
        environment {
            dockerImage = ""
            appRepoUrl = ""
            manifestRepoUrl = ""
            ecrUrl = ""
        }
        parameters {
            gitParameter name: 'TAG',
                         type: 'PT_TAG',
                         defaultValue: 'v1.0.0'
        }
        stages {
            stage("checkout app code") {
                steps {
                    checkout(
                    [$class: 'GitSCM',
                    branches: [[name: "${params.TAG}"]],
                    extensions: [],
                    userRemoteConfigs: [[credentialsId: 'GitHub', url: "https://${appRepoUrl}"]]])
                }
            }
            stage("build") {
                steps {
                    script {
                        dockerImage = docker.build(ecrUrl)
                    }
                }
            }
            stage("push to ecr") {
                steps {
                    script {
                        sh 'rm  ~/.dockercfg || true'
                        sh 'rm ~/.docker/config.json || true'
                        docker.withRegistry("https://${env.ecrUrl}", 'ecr:ap-northeast-2:ECR') {
                            dockerImage.push("${params.TAG}")
                            dockerImage.push('latest')
                        }
                    }
                }
            }
            stage("update k8s manifest") {
                steps {
                    deleteDir()
                    checkout(
                    [$class: 'GitSCM',
                    branches: [[name: '*/main']],
                    extensions: [],
                    userRemoteConfigs: [[credentialsId: 'GitHub', url: "https://${manifestRepoUrl}"]]])
                    script {
                        sh "kustomize edit set image nginx=${env.ecrUrl}:${params.TAG}"
                        sh "git config user.name jenkins"
                        sh "git config user.email admin@jenkins.com"
                        withCredentials([usernameColonPassword(credentialsId: 'GitHub', variable: 'USERPASS')]) {
                            sh "git add . && git commit -m 'update image' && git push https://$USERPASS@${env.manifestRepoUrl} HEAD:main || true"
                        }
                    }
                }
            }
        }
    }
    • appRepoUrl: Forking한 NGINX 리포지토리 주소

    • manifestRepoUrl: Forking한 NGINX Manifest 리포지토리 주소

    • ecrUrl: ECR 리포지토리 주소

  6. v1.0.0 태그 생성

    • git tag -a v1.0.0 -m "v1.0.0"

    • git push origin --tags

  7. Build Now

ArgoCD (GitOps)

  1. ArgoCD 설치

    kubectl create namespace argocd
    kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
  2. 초기 어드민 비밀번호 확인

    kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
  3. argocd-server 서비스 종류를 Load Balancer로 변경

    kubectl -n argocd patch svc argocd-server -p '{"spec": {"type": "LoadBalancer"}}'
  4. argocd-server 서비스 엔드포인트 확인

    kubectl -n argocd get svc argocd-server
  5. 웹 브라우저에서 위에서 확인한 ELB 엔드포인트로 접속

  6. 초기 어드민 비밀번호로 로그인 - 유저이름: admin

  7. 새로운 애플리케이션 생성

    • Application Name: nginx

    • Project: default

    • Repository URL: nginx-manifest 리포지토리 URL

    • Path: .

    • Namespace: default

  8. Sync

  9. 생성된 Service의 호스트네임을 확인후에 웹 브라우저로 접속

  10. 애플리케이션 소스코드에서 index.html 파일을 수정하고 v1.0.1 태그 생성

  11. Jenkins 파이프라인에서 Build Parameter를 v1.0.1로 지정하고 빌드

  12. ArgoCD에서 Refresh 를 눌러서 Sync 상태를 확인하고 Out of Sync일 경우 동기화 진행

  13. Service 호스트네임으로 접속해서 index.html 수정분이 반영됐는지 확인

Last updated