상세 컨텐츠

본문 제목

젠킨슨을 활용해 helm 배포하기

EKS - CI-CD

by drogva 2024. 3. 20. 21:43

본문

- 차트를 만들고 CI/CD 를 구축하고자 한다. 

-이번에는 젠킨슨만 사용하겠다.

-기반 환경 : EKS

 

 

 

 

-구조도 

- 헬름 차트 생성을 위한 기본 코드 설치 

helm create tks-contract


도커이미지는 저번에 RDS와 연동한 도커이미지를 쓰기로 했다.


- 보통  helm install __  하게되면 처음 service 가 노드포트를 통해 eks 에 들어온다. 
그 다음 service account 가 생성되며  deploy.yaml 로 인해 pod 가 생성된다.

마지막으로 ingress.yaml 까지 생성되며 자동으로 alb 를 통해 구현된다. 

pod (8080 포트) - 생성한 도커이미지 내부에 jar 파일이 있는데 8080 포트를 주로 쓴다. 그 외에 포트를 연결해 봤는데 연                                결이 안된다.   (TargetPort - argPort)

svc (노드 포트 27000 - 서비스 포트 9440)  : 외부에서 노드포트를 통해 들어오지만 결국엔 서비스 포트를 통해 ingress 와                                                                       연결된다. 

ingress(443포트) :  서비스포트 9440 과 리다이렉션을 통해 https 로 노출된다.

 

chart.yaml : chart를 정의한 파일

index.yaml: 헬름차트를 repo 에 add 할 때 생성되며 메타데이터를 포함하고 있다.

_helper.tpl : templates 폴더에서 사용할 변수들을 정의 - 

values.yaml : 변수를 지정해 놓은 yaml
sa.yaml:  svc 가 생성되고 그 다음에 sa 가 생긴다. 리소스에 관한 권한을 갖는다.  

-values.yaml

# Default values for tks-contract.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

namespace: tks

image:
  repository: 553186839963.dkr.ecr.ap-northeast-2.amazonaws.com/drogva:hi
  pullPolicy: Always

imagePullSecrets:
  - name: ecr-registry-secret  # 수정된 부분             ->  이 부부은  namespace: tks 에 배포될 것 이므로 미리 생성
serviceAccount:                                                             

create: true
  automount: true
  annotations: {}
  name: "tks-info"

args:
  port: 8080                                                                    -> pod 의 포트 :  svc 의 TargetPort 와 연결
  tksInfoAddress: tks-info.tks.svc
  tksInfoPort: 9110

podAnnotations: {}
podLabels: {}

podSecurityContext: {}
securityContext: {}

service:
  type: LoadBalancer                           -> svc 의 형식 nlb
  port: 9110

# ingress 설정을 추가합니다.
ingress:
  # Ingress를 활성화합니다.
  enabled: true
  # Ingress 클래스 이름을 지정합니다. (선택사항)
  className: "alb"
  # Ingress의 annotations를 추가합니다.
  annotations:
    kubernetes.io/ingress.class: "alb"
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:ap-northeast-2:553186839963:certificate/8c14b185-958d-4af1-8340-4930f6d6fb1d"
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
  # Ingress에 대한 호스트 정보를 설정합니다.
  hosts:
    # 호스트를 추가합니다.
    - host: http://www.seunghobet.link
      paths:
        # 경로를 설정합니다.
        - path: /
          pathType: Prefix                                                               
  # TLS 설정을 추가합니다.
  tls:
    # Secret 이름을 지정합니다.
    - secretName: tls-secret                                  ->  tls 은 비대칭키를 주고 받는 인증의 형식이다. 미리 생성해 놓는다. 

  # 백엔드 서비스 설정을 추가합니다.
  backend:
    service: jiral-tks-contract
    port:  # 백엔드 서비스 포트 설정
      number: 9110
    servicePort: 9110  # 서비스의 포트 번호

resources: {}

livenessProbe:
  httpGet:
    path: /
    port: http

readinessProbe:
  httpGet:
    path: /
    port: http

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80

volumes: []
volumeMounts: []
nodeSelector: {}
tolerations: []
affinity: {}

 

 

 ->  tls 은 비대칭키를 주고 받는 인증의 형식이다. 미리 생성해 놓는다. 

 

https://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/patterns/configure-mutual-tls-authentication-for-applications-running-on-amazon-eks.html

 

Amazon EKS에서 실행되는 애플리케이션에 대한 상호 TLS 인증을 구성합니다. - AWS 권장 가이드

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

이 방식대로 하면 생성된 crt 파일과 key 파일을 헬름차트가 배포되는 ns 에  미리 저장하여 놓는다. 

 

# ca.crt 파일을 base64로 인코딩하여 Kubernetes Secret 생성
kubectl create secret generic tls-secret --namespace=kpop --from-file=ca.crt=/path/to/ca.crt

# client.crt 파일을 base64로 인코딩하여 Kubernetes Secret에 추가
kubectl create secret generic tls-secret --namespace=kpop --from-file=client.crt=/path/to/client.crt --dry-run=client -o yaml | kubectl apply -f -

# client.key 파일을 base64로 인코딩하여 Kubernetes Secret에 추가
kubectl create secret generic tls-secret --namespace=kpop --from-file=client.key=/path/to/client.key --dry-run=client -o yaml | kubectl apply -f -

# server.crt 파일을 base64로 인코딩하여 Kubernetes Secret에 추가
kubectl create secret generic tls-secret --namespace=kpop --from-file=server.crt=/path/to/server.crt --dry-run=client -o yaml | kubectl apply -f -

# server.key 파일을 base64로 인코딩하여 Kubernetes Secret에 추가
kubectl create secret generic tls-secret --namespace=kpop --from-file=server.key=/path/to/server.key --dry-run=client -o yaml | kubectl apply -f -

 

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "tks-contract.fullname" . }}                              ->  차트에서 정의된 이름이다.
  namespace: {{ .Values.namespace }}                                       -> 변수에서 지정한 ns
  labels:
    {{- include "tks-contract.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      {{- include "tks-contract.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      labels:
        {{- include "tks-contract.labels" . | nindent 8 }}
        {{- with .Values.podLabels }}
        {{- toYaml . | nindent 8 }}
        {{- end }}
    spec:
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      serviceAccountName: {{ include "tks-contract.serviceAccountName" . }}
      securityContext:
        {{- toYaml .Values.podSecurityContext | nindent 8 }}
      containers:
        - name: {{ .Chart.Name }}
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
          image: "{{ .Values.image.repository }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: tks-contract
              containerPort: {{ .Values.args.port }}                       -> 이 부분을 추가해 줬다. pod 의 포트가 될 것이다.
              protocol: TCP
          args: [
            "-port", "{{ .Values.args.port }}",
            "-info-address", "{{ .Values.args.tksInfoAddress }}",           -> 이 부분을 추가해 줬다. pod 의 포트가 될 것이다.
            "-info-port", "{{ .Values.args.tksInfoPort }}"
          ]
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
      {{- end }}

 

 

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: {{ include "tks-contract.fullname" . }}
  namespace: {{ .Values.namespace }}
  labels:
    {{- include "tks-contract.labels" . | nindent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports: 
    - port: {{ .Values.service.port }}                                       -> 변수에서 지정한 포트 9440
      targetPort: {{ .Values.args.port }}                                  -> pod 포트 8080     (연결)
      protocol: TCP
  selector:
    {{- include "tks-contract.selectorLabels" . | nindent 4 }}

 

 

ingress.yaml

{{- if .Values.ingress.enabled -}}
{{- $fullName := include "tks-contract.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
  {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
  {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
  {{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
  name: {{ $fullName }}
  namespace: {{ .Values.namespace }}
  labels:
    {{- include "tks-contract.labels" . | nindent 4 }}
  {{- with .Values.ingress.annotations }}
  annotations:
    {{- toYaml . | nindent 4 }}
  {{- end }}
spec:
  {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
  ingressClassName: {{ .Values.ingress.className }}
  {{- end }}
  {{- if .Values.ingress.tls }}
  tls:
    {{- range .Values.ingress.tls }}
    - hosts:
        {{- range .hosts }}
        - {{ . | quote }}
        {{- end }}
      secretName: {{ .secretName }}
    {{- end }}
  {{- end }}
  rules:
    {{- range .Values.ingress.hosts }}
    - host: {{ .host | quote }}
      http:
        paths:
          {{- range .paths }}
          - path: {{ .path }}
            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
            pathType: {{ .pathType }}
            {{- end }}
            backend:
              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
              service:
                name: {{ $fullName }}
                port:
                  number: {{ $svcPort }}                    -> svc 의 포트
              {{- else }}
              serviceName: {{ $fullName }}
              servicePort: {{ $svcPort }}
              {{- end }}
          {{- end }}
    {{- end }}
{{- end }}

 

 


2. helm repo add 하여 chart 를 업로드

- chart 가 저장될 빈 레포지토리를 클론한다. git clone

- helm package .       :tar 파일로 압축한다. values.yaml 은 제외되나 helm install 의 경우에 포함된다. values.yaml 을 수정                                     할 수도 있다.

- helm repo index .    : index.yaml   이 생성된다.  helm cli 를 통해 탐색하고 설치하기 위해 필요하다.

- git add . 

- git commit -m "Add mychart Helm chart"     :변경사항을 커밋하고 푸쉬한다.

- helm repo add jiral https://raw.githubusercontent.com/drogva/jiral/main/ "jiral" has been added to your repositories :헬름저장소에 추가 - git hub의 레포지토리 주소를 반영한다.

- helm install tks-contract jiral/tks-contract

: 헬름 설치 및 배포

 

3. 확인 

 

pod ,svc, ing 가 자동으로 실행된 모습이다.

이제 이것을 젠킨슨 활용해 ci/cd 자동화 프로세스를 구축해 볼 것이다.

도커이미지를 빌드하고 도커 이미지를 사용해 헬름으로 배포하는 프로세스를 구축.

 

helm repo :  GitHub - drogva/jiral

 

GitHub - drogva/jiral

Contribute to drogva/jiral development by creating an account on GitHub.

github.com

:

'EKS - CI-CD' 카테고리의 다른 글

젠킨슨을 활용하여 helm 배포 - 2  (0) 2024.03.20

관련글 더보기