EKS 클러스터는 terraform 으로 만들어져있는 상태
cloud9 을 통해 EKS 에 연결된 EC2 로 들어가서 작업
terraform 문서는 추후 업데이트
사전 작업
- 보안그룹
eks 가 초기에 보안그룹 2개를 할당하는것 같다
eks-cluster-sg 랑
eks-node, eks-cluster 인데
eks-node 보안그룹이 저렇게 제한된 포트 커넥트를 가지고 있어서 이걸 제거해 줘야 multiple tag 오류가 나지 않았다
- Helm 설치
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
chmod 700 get_helm.sh
./get_helm.sh
helm version --short | cut -d + -f 1
- aws-load-balancer-controller 설치
helm repo add eks https://aws.github.io/eks-charts
helm repo list
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=project-myeks --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set image.repository=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-load-balancer-controller
CI
젠킨스 서버 생성
EKS 클러스터 내 jenkins pod 만들어서 실습할때
docker in docker 를 구현해야 하는데
권한 문제 때문에 docker 가 설치가 안되서 jenkins 서버를 별도로 만들어줬다
t3a.small, ubuntu
[inbound : 22- 0.0.0.0/0 , 8080 - 0.0.0.0/0] [outbound : ALL - 0.0.0.0/0]
이 실습에선 안해줬는데
나중에 webhook 구현을 위해 EIP 를 할당해줘야 한다
도커 설치
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
웹에서 스크립트를 받아 개발환경에 빠르고 간단하게 사용 가능하다
권장하는 방법은 아님
Jenkins 설치
sudo docker run -itd --name jenkins -p 8080:8080 -p 50000:50000 -v /docker/jenkins:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -e TZ=Asia/Seoul -u root jenkins/jenkins:latest
Jenkins container에 docker, kustomize 설치
docker exec -it 젠킨스컨테이너이름 bash
curl -fsSL get.docker.com -o get-docker.sh
sh get-docker.sh
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
mv kustomize /usr/local/bin
kustomize version
ECR 생성
Jenkins 환경구성
server IP:8080 으로 접속
Jenkins 환경 구성
대쉬보드 - jenkins 관리 - 플러그인 관리 에서
docker-build-step , docker plugin, docker pipeline, AWS ECR 다운로드
플러그인 설치에 따라 container 를 재시작 해야 할 수도 있다
이후 대쉬보드 - jenkins 관리 - manage Credentials 이동
global - add Credentials
음.. 원래 ECR 로 하려고 했는데
계정 access key 는 최대 2개까지 만들 수 있고
그 조원 분들이 아마 각각 하나씩 가지고 계신거 같은데
미리 좀 얻어놓을껄
지금생각났다
어쩔수 없이 github, hub.docker 로 자격증명을 만들어줌
Github 자격증명 생성
kind : Username with Password
Username : Github 계정명
Password : github persnal access token
ID : 젠킨스 내에서 자격증명을 가리키기 위해 사용할 변수 이름
Docker Hub 자격증명 생성
kind : Username with Password
Username : Docker Hub 계정명
Password : Docker Hub persnal access token ( hub.docker - account settings - security - new access tokens )
ID : 젠킨스 내에서 자격증명을 가리키기 위해 사용할 변수 이름
ECR 자격증명 생성
kind : AWS credentails
Accesskey : aws 사용자 access key
SecretAccessKey : aws 사용자 secret access key
ID : 젠킨스 내에서 자격증명을 가리키기 위해 사용할 변수 이름
Jenkinsfile
pipeline {
agent any
// 해당 스크립트 내에서 사용할 로컬 변수들 설정-
// 레포지토리가 없으면 생성됨
// Credential들에는 젠킨스 크레덴셜에서 설정한 ID를 사용
environment {
//dockerHubRegistry = 'cyaninn/demo-eks-cicd'
//dockerHubRegistryCredential = 'credential-dockerhub'
awsecrRegistry = '605680513436.dkr.ecr.ap-northeast-2.amazonaws.com/groom-pj-app-for-eks'
awsecrRegistryCredentail = 'credential-AWS-ECR'
githubCredential = 'credential-github'
gitEmail = 'sounddevice3@gmail.com'
gitName = 'cyaninn-entj'
}
stages {
// 깃허브 계정으로 레포지토리를 클론한다.
stage('Checkout Application Git Branch') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: githubCredential, url: 'https://github.com/cyaninn-entj/mini-cicd-eks-project.git']]])
}
// steps 가 끝날 경우 실행한다.
// steps 가 실패할 경우에는 failure 를 실행하고 성공할 경우에는 success 를 실행한다.
post {
failure {
echo 'Repository clone failure'
}
success {
echo 'Repository clone success'
}
}
}
stage('Docker Image Build') {
steps {
// 도커 이미지 빌드
sh "docker build . -t ${awsecrRegistry}:${currentBuild.number}"
sh "docker build . -t ${awsecrRegistry}:latest"
}
// 성공, 실패 시 슬랙에 알람오도록 설정
post {
failure {
echo 'Docker image build failure'
//slackSend (color: '#FF0000', message: "FAILED: Docker Image Build '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}
success {
echo 'Docker image build success'
//slackSend (color: '#0AC9FF', message: "SUCCESS: Docker Image Build '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}
}
}
stage('Docker Image Push') {
steps {
// 젠킨스에 등록한 계정으로 ECR 에 이미지 푸시
withDockerRegistry([url: "https://${awsecrRegistry}", credentialsId: "ecr:ap-northeast-2:${awsecrRegistryCredentail}"]) {
sh "docker push ${awsecrRegistry}:${currentBuild.number}"
sh "docker push ${awsecrRegistry}:latest"
// 10초 쉰 후에 다음 작업 이어나가도록 함
sleep 10
}
}
post {
failure {
echo 'Docker Image Push failure'
sh "docker rmi ${awsecrRegistry}:${currentBuild.number}"
sh "docker rmi ${awsecrRegistry}:latest"
//slackSend (color: '#FF0000', message: "FAILED: Docker Image Push '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}
success {
echo 'Docker Image Push success'
sh "docker rmi ${awsecrRegistry}:${currentBuild.number}"
sh "docker rmi ${awsecrRegistry}:latest"
//slackSend (color: '#0AC9FF', message: "SUCCESS: Docker Image Push '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}
}
}
// updated docker image 태그를 git push
stage('Deploy') {
steps {
// git 계정 로그인, 해당 레포지토리의 main 브랜치에서 클론
git credentialsId: githubCredential,
url: 'https://github.com/cyaninn-entj/mini-cicd-eks-project.git',
branch: 'main'
/*
// 이미지 태그 변경 후 메인 브랜치에 푸시
sh "git config --global user.email ${gitEmail}"
sh "git config --global user.name ${gitName}"
sh "cd prod && kustomize edit set image ${awsecrRegistry}:${currentBuild.number}"
sh "git add kustomization.yaml"
sh "git status"
sh "git commit -m 'update the image tag'"
sh "git branch -M main"
sh "git push -u origin main"
*/
}
}
}
}
Dockerfile
# Use the official image as a parent image.
FROM node:current-slim
# Set the working directory
WORKDIR /home
# Copy the file from your host to your current location.
COPY app/ /home/
# Run the command inside your image filesystem
RUN npm install
# Inform Docker that the container is listening on the specified port at runtime
EXPOSE 3000
# Run the specified command within the container.
CMD ["npm", "start"]
# Copy the rest of your app's source code from your host to your image filesystem.
kustomization
kustomization.yaml
namePrefix: prod-
resources:
- deployment.yaml
- service.yaml
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-nginx-app
spec:
replicas: 1
revisionHistoryLimit: 3
selector:
matchLabels:
app: demo-nginx-app
template:
metadata:
labels:
app: demo-cicd-nginx-app
spec:
containers:
- image: cyaninn/demo-eks-cicd:latest
name: demo-nginx-app
ports:
- containerPort: 80
service.yaml
apiVersion: v1
kind: Service
metadata:
name: demo-nginx-app
spec:
ports:
- port: 80
targetPort: 80
selector:
app: demo-nginx-app
git repo 생성 + 연동
아이템 이름과 pipline 선택
definition 에 SCM 을 선택하고
scm 은 git 으로 선택
repo url 넣고 자격증명 선택
jenkinsfile 은 깃허브 디렉토리 최상단에 위치해야한다고 함
그래서 그냥 파일이름만 적고
브랜치 수정해줌
확인
+ cd prod
+ kustomize edit set image cyaninn/demo-eks-cicd:5
Error: error converting YAML to JSON: yaml: line 8: mapping values are not allowed in this context
Usage:
kustomize edit set image [flags]
kustomizez 파일이 잘못됬나보다
일단
그래도 hub.docker 에 이미지 빌드는 잘 되있는 모습
access 키 발급 때문에 나중에 repository 를 ecr 로 바꿔주었다.
Webhook
깃허브 리포지토리에서 setting - webhoook 에서 webhook을 추가해준다
일단 이렇게 add 해놨고
( payload URL 은 http:// 붙여줬다 )
ip:포트 뒤에 /github-webhook/ 을 붙여줘야 작동한다
그리고 jenkins 에 만들어놨던 pipeline 아이템에 들어가서 구성으로 들어간 후
플러그인을 설치해주고
기존 만든 pipeline 아이템의 구성으로 들어가서
hook trigger 로 트리거를 선택해준다.
이후 간단하게 코드 수정해서 push 작업을 해봤는데
(이때 webhook 주소에 그냥 ip:port 만 넣었었는데 webhook 을 캐치하지 못했음)
github hook log 에 가서 확인해보니 push 변화를 잡아냈고
이후 빌드까지 알아서 잘 하는 모습
이렇게 CI 끝
'Kubernetes > CICD' 카테고리의 다른 글
깃허브 웹훅이 작동하지 않을때 (0) | 2023.04.19 |
---|---|
Jenkins + ArgoCD + ECR + EKS 구성해보기 - CD -완- (0) | 2022.11.19 |
Jenkins + EKS 구성해보기 6 (테스트 성공) (0) | 2022.11.17 |
Jenkins + EKS 구성해보기 5 (참고) (0) | 2022.11.17 |
Jenkins + ArgoCD + EKS 구성해보기 4 (실패) (0) | 2022.11.16 |