ㅡ.ㅡ

[Gitlab] CD/Kubectl 본문

WorkFlow

[Gitlab] CD/Kubectl

ekwkqk12 2021. 9. 25. 02:42

이전에 생성한 gitlab-admin SA와 dtzar/helm-kubectl 이미지를 활용해 Gitlab에서 CD작업을 진행한다.

k8s-conf/resource.yaml
저장소에 아래 이미지와 같이 k8s-conf에 생성할 리소스 파일을 준비해놓는다.

# 내부 접근용 서비스(ClusterIP) - 셀렉터의 라벨과 파드의 라벨 매칭
apiVersion: v1
kind: Service
metadata:
  name: springboot-svc-clusterip
spec:
  ports:
    - name: springboot-web-clusterip
      port: 7070
      targetPort: 8080
  selector:
    app: springboot
  type: ClusterIP

---
# 내/외부 접근용 서비스(Nodeport) - 노드의 포드 포워딩을 통해 접속
apiVersion: v1
kind: Service
metadata:
  name: springboot-svc-nodeport
spec:
  ports:
    - name: springboot-web-nodeport
      port: 7171
      targetPort: 8080
      nodePort: 31111 #오픈 포트 지정
  selector:
    app: springboot
  type: NodePort

---
# 외부 접근용 서비스(Nodeport) - 로드밸런서를 통해 접속
apiVersion: v1
kind: Service
metadata:
  name: springboot-svc-nlb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb" # NLB로 생성/미 지정 시 클래식
spec:
  ports:
    - name: springboot-web-nlb
      port: 80
      targetPort: 8080
  selector:
    app: springboot
  type: LoadBalancer

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  selector:
    matchLabels:
      app: springboot
  replicas: 2
  template:
    metadata:
      labels:
        app: springboot        
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: alpha.eksctl.io/nodegroup-name
                operator: In
                values:
                - work-ng

.gitlab-ci.yml
kubectl 명령어를 사용하기 위해 k8s api 서버에 인증할 값들을 CI/CD 변수로 등록 후 이미지가 저장된 레지스트리에 인증을한다.
CI 작업 후 생성된 이미지 파일의 태그 값을 resource파일에 추가하여 배포를 진행한다.
아래 .gitlab-ci.yml은 gitlab registry를 사용한것으로 ECR을 사용시 docker-server 값들을 ecr의 값으로 변경해주면 된다.

before_script:
  - export

# 스크립트에서 사용할 변수 설정
variables:
  DOCKER_TLS_CERTDIR: ''
  DOCKER_HOST: tcp://localhost:2375


services:
  - name: docker:19.03.13-dind


stages:
  - deploy


deploy_kubectl:
  stage: deploy
  image: dtzar/helm-kubectl:3.6.0
  environment:
    name: 클러스터 환경 범위명
  script:
    - kubectl config set-cluster k8s --server=$K8S_API
    - kubectl config set clusters.k8s.certificate-authority-data $CERTIFICATE_AUTHORITY_DATA_B64
    - kubectl config set-credentials gitlab --token=$USER_TOKEN
    - kubectl config set-context default --cluster=k8s --user=gitlab
    - kubectl config use-context default
    - kubectl create secret docker-registry --dry-run=client $KUBE_NAMESPACE-secret 
      --docker-server=$CI_REGISTRY 
      --docker-username=$TOKEN_USER 
      --docker-password=$TOKEN_PW -o yaml | kubectl apply -n $KUBE_NAMESPACE -f -
    - |
      cat >> ./k8s-conf/resource.yaml<< EOF
            containers:
              - name: hello-world
                image: $CI_REGISTRY/$TAG_COMMIT
                ports:
                  - containerPort: 8080
                    protocol: TCP
            imagePullSecrets:
            - name: $KUBE_NAMESPACE-secret
      EOF
    - cat ./k8s-conf/resource.yaml
    - kubectl get nodes
    - kubectl apply -f ./k8s-conf/resource.yaml -n $KUBE_NAMESPACE
    - kubectl annotate pod,deploy --all --overwrite -n $KUBE_NAMESPACE app.gitlab.com/env=$CI_ENVIRONMENT_SLUG
    - kubectl annotate pod,deploy --all --overwrite -n $KUBE_NAMESPACE app.gitlab.com/app=$CI_PROJECT_PATH_SLUG
    #- kubectl delete -f ./k8s-conf/resource.yaml -n $KUBE_NAMESPACE
  when: manual
  only:
    - master
  tags:
    - test1

CI/CD 변수
gitlab-runner를 통해 작업 시 CI/CD 변수를 정의하여 파이프라인 작업 실행 시 사용할 수 있다.
변수값 추출 스크립트(kubectl 명령어 되는 환경에서 실행)

echo '[+] ENV K8S_API'
kubectl config view --raw -o=jsonpath='{.clusters[0].cluster.server}'
echo -e '\n\n'

echo '[+] ENV CERTIFICATE_AUTHORITY_DATA_B64'
kubectl config view --raw -o=jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 --decode
echo -e '\n\n'

echo '[+] ENV USER_TOKEN'
GITLAB_SECRET=$(kubectl -n kube-system get secret | grep gitlab-admin-token | awk '{print $1}')
GITLAB_TOKEN=$(kubectl -n kube-system get secret $GITLAB_SECRET -o jsonpath='{.data.token}' | base64 --decode)
echo $GITLAB_TOKEN

K8S Node docker insecure-registries 설정
pod에서 이미지를 불러올때 https를 사용하지않으면 이미지를 못불러오는 이슈가 발생하여 pod가 생성되는 노드에 도커 설정을 변경해줘야한다
(gitlab registry에 https설정 시 해당 설정을 안해도 진행된다.)

vi /etc/docker/daemon.json

{
  "insecure-registries" : ["레지스트리 주소"],

systemctl restart docekr

PipeLine
gitlab CI/CD pipeline 작업 내역을 보면 실패없이 완료된것을 확인할 수 있고
Deployments 환경쪽을 확인해보면 pod가 정상적으로 배포된것을 확인할 수 있다.

'WorkFlow' 카테고리의 다른 글

[Jenkins] Jenkins  (0) 2021.09.26
[Gitlab] CD/Helm  (0) 2021.09.25
[Gitlab] CI/ECR  (3) 2021.09.20
[Gitlab] CI/GitLab Container Registry  (0) 2021.09.20
[Gitlab] Gitlab Runner 연동  (0) 2021.09.19