> For the complete documentation index, see [llms.txt](https://kubernetes.youngwjung.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kubernetes.youngwjung.com/extras/devops/lab.md).

# 실습

### Jenkins

1. EC2 인스턴스 생성&#x20;
   * AMI: Amazon Linux 2
   * Instance Type: m5.large
   * IAM 역할: Session Manager 접근이 가능한 역할 부여&#x20;
   * EBS 볼륨 크기: 20GiB
   * 보안그룹: 모든 IP 주소에서 80번 포트 접근 허가&#x20;
2. Session Manager를 통해서 위에서 생성한 EC2 인스턴스에 접근&#x20;
3. Docker 설치&#x20;

   ```
   sudo yum install docker -y
   ```
4. Docker 데몬 실행&#x20;

   ```
   sudo systemctl enable docker
   sudo systemctl start docker
   ```
5. Docker 볼륨 생성 &#x20;

   ```
   sudo docker volume create jenkins-home
   ```
6. Jenkins 컨테이너 실행  &#x20;

   ```
   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 초기 관리자 비밀번호 확인&#x20;

   ```
   sudo docker exec jenkins bash -c "cat /var/jenkins_home/secrets/initialAdminPassword"
   ```
8. 웹 브라우저를 열고 EC2 인스턴스 퍼블릭 IP 주소로 접속&#x20;
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 설정&#x20;
12. Jenkins 재시작
13. 보안 설정: **Manage Jenkins** → **Configure Global Security** 로 이동 후 CSRF 설정에서 프록시 호환성 활성화
14. 추가 플러그인 설치: **Manage Jenkins** → **Manage Plugins** 로 이동 후 아래와 같은 플러그인 설치
    * Docker Pipeline
    * Amazon ECR

### Jenkins Pipeline 생성&#x20;

1. <https://github.com/youngwjung/nginx> 리포지토리를 Fork
2. <https://github.com/youngwjung/nginx-manifest> 리포지토리를 Fork
3. Private ECR 리포지토리 생성&#x20;
4. Crendentials 등록: **Manage Jenkins** → **Manage Credentials** → **Store** = **Jenkins** → **Domain: Global credentials** → **Add Credentials**
   * GitHub
     * Kind: Username with password
     * Username: 깃허브 아이디
     * Password: 깃허브 비밀번호
     * ID: GitHub
   * ECR
     * Kind: AWS Credentials
     * ID: ECR
     * Access Key ID: AWS 엑서스 키&#x20;
     * Secret Access Key: AWS 시크릿 엑서스 키&#x20;
5. **New Item** → **Enter an item name**에 `nginx` 입력 → **Pipeline** 선택 → **OK**
6. Pipeline script에 아래의 내용을 복사에서 붙여넣고 **Save**&#x20;

   ```
   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 리포지토리 주소&#x20;
   * manifestRepoUrl: Forking한 NGINX Manifest 리포지토리 주소&#x20;
   * ecrUrl: ECR 리포지토리 주소&#x20;
7. &#x20;v1.0.0 태그 생성
   * `git tag -a v1.0.0 -m "v1.0.0"`
   * `git push origin --tags`
8. Build Now

### ArgoCD (GitOps)&#x20;

1. ArgoCD 설치&#x20;

   ```
   kubectl create namespace argocd
   kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
   ```

2. 초기 어드민 비밀번호 확인&#x20;

   ```
   kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
   ```

3. `argocd-server` 서비스 종류를 Load Balancer로 변경&#x20;

   ```
   kubectl -n argocd patch svc argocd-server -p '{"spec": {"type": "LoadBalancer"}}'
   ```

4. `argocd-server` 서비스 엔드포인트 확인&#x20;

   ```
   kubectl -n argocd get svc argocd-server
   ```

5. 웹 브라우저에서 위에서 확인한 ELB 엔드포인트로 접속&#x20;

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

7. 새로운 애플리케이션 생성&#x20;

   * Application Name: nginx
   * Project: default
   * Repository URL: `nginx-manifest` 리포지토리 URL
   * Path: .
   * Cluster URL: <https://kubernetes.default.svc>
   * Namespace: default

8. **Sync**

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

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

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

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

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