System Engineering/CI, CD

CI/CD #19. 쿠버네티스 harbor 연동 및 배포 # 쿠버네티스 private docker registry

ZunoXI 2021. 12. 22.

 

개요

쿠버네티스 harbor 연동 및 배포하기

Kubernetes with Harbor(Private Dokcer Registry)

바로 이전포스팅을 통해 젠킨스와 harbor간 파이프라인 자동빌드/자동배포를 위한 연동을 진행하였다. harbor덕분에 docker이미지가 이제 사내에 private하게 보관되는데, 이는 쿠버네티스 환경에서 helm이나 필자처럼 yaml파일을 이용한 배포를 진행할때 pull로 땡겨올 docker의 이미지도 harbor에서 가져온다는것을 의미한다. 이번 포스팅에서는 kubernetes 환경에서 어떻게 harbor의 이미지를 가져올 수 있는지 기술한다. 

 

 

 


 

 

 

1. node에 docker 인증서 등록

 

harbor관련 지속적으로 언급되는 부분인데 docker에서 pull할때 권한체크가 필요하기 때문에 쿠버네티스의 모든 node(docker pull을 할 가능성이 있는 혹은 pod가 생성될 수 있는)들에 인증서 설치가 필요하다. 이는 지난 포스팅에 있는 방법을 그대로 가져왔다. 적용방법은 각 node의 /etc/docker/certs.d/도메인명 위치에 crt, key 파일을 위치시킨 후 systemctl restart docker를해주면 된다. 

 

ex ) harbor의 domain명이 mydomain.com인 경우

$ mkdir /etc/docker/certs.d/mydomain.com
$ cp ~~.crt /etc/docker/certs.d/mydomain.com/
$ cp ~~.key /etc/docker/certs.d/mydomain.com/
$ systemctl restart docker

 

 

Verify repository client with certificates

 

docs.docker.com

 

 

 

2. 쿠버네티스 시크릿(Secret)생성

 

jenkins의 credentials와 같이 쿠버네티스에서 yaml파일을 통해 특정 pod를 생성하려고 할때는 secret을 참고하여 권한을 획득할 수 있다. 기본적으로 harbor와 같은 private registry에 접근하여 이미지를 가져오는 절차에 대한 공식가이드는 링크를 참고하면 좋을 것 같다.

 

프라이빗 레지스트리에서 이미지 받아오기

이 페이지는 프라이빗 도커 레지스트리나 리포지터리로부터 이미지를 받아오기 위해 시크릿(Secret)을 사용하는 파드를 생성하는 방법을 보여준다. 시작하기 전에 쿠버네티스 클러스터가 필요하

kubernetes.io

 

 

필자는 위 방법중에서도 Secret을 생성하는 방법을 택했다. 구축한 harbor 도메인이 mydomain.com, 계정은 1522274, PW는 Aa123456!이라는 가정하에 작성한다. (harbor 브라우저에 접근하여 계정 생성이 가능하다) 아래는 harbor라는 이름의 secret을 생성할 수 있는 명령어이다. 

 

$ kubectl create secret docker-registry harbor --docker-server=https://mydomain.com --docker-username=1522274 --docker-password=Aa123456! --docker-email=cross9308@naver.com

 

 

 

 

3. 배포 yaml 파일 수정

 

 

우선 jenkins에서 사용하던 jenkinsfile에는 kubernetes stage가 아래와 같이 명시되어있다. jenkins파일의 full버전은 링크를 참고하면 될 것 같고, 스테이지 내용은 jenkins서버에 설치되어있는 kubectl(kubeconfig로 서버내의 /u01/config에 원격접속할 쿠버네티스 kube-config 정보를 지정해줬다)이 원격 쿠버네티스의 디플로이먼트를 rollout 하는 내용이다. 즉, 원격 쿠버네티스 서버에서 이미지를 harbor서버로부터 다시 받아서 갱신해주겠다는 의미이다.

stage('Kubernetes deploy') {
        //kubernetesDeploy configs: "yf.yaml", kubeconfigId: 'kubeConfigReal'
        sh "/usr/local/bin/kubectl --kubeconfig=/u01/config rollout restart deployment/fe-deployment -n zuno"
    }

 

 

 

rollout해줄 kubernetes 오브젝트인 fe-deployment를 편집해주자. 필자의 경우 대시보드가 설치되어있는 쿠버네티스라 디플로이먼트 편집에 들어가서 작업했다.

{
  "kind": "Deployment",
  "apiVersion": "extensions/v1beta1",
  "metadata": {
    "name": "fe-deployment",
    "namespace": "zuno",
    "selfLink": "/apis/extensions/v1beta1/namespaces/zuno/deployments/fe-deployment",
    "uid": "f0359ce6-3ca5-4f43-b2af-349d87f6616e",
    "resourceVersion": "6142701",
    "generation": 11,
    "creationTimestamp": "2021-10-21T11:15:35Z",
    "labels": {
      "app": "fe"
    },
    "annotations": {
      "deployment.kubernetes.io/revision": "10"
    }
  },
  "spec": {
    "replicas": 3,
    "selector": {
      "matchLabels": {
        "app": "fe"
      }
    },
    "template": {
      "metadata": {
        "creationTimestamp": null,
        "labels": {
          "app": "fe"
        },
        "annotations": {
          "kubectl.kubernetes.io/restartedAt": "2021-12-02T15:06:55+09:00"
        }
      },
      "spec": {
        "containers": [
          {
            "name": "femvn",
            "image": "mydomain.com/fe/ver:latest",
            "ports": [
              {
                "containerPort": 8080,
                "protocol": "TCP"
              }
            ],
            "resources": {},
            "terminationMessagePath": "/dev/termination-log",
            "terminationMessagePolicy": "File",
            "imagePullPolicy": "Always"
          }
        ],
        "restartPolicy": "Always",
        "terminationGracePeriodSeconds": 30,
        "dnsPolicy": "ClusterFirst",
        "securityContext": {},
        "imagePullSecrets": [
          {
            "name": "harbor"
          }
        ],
        "schedulerName": "default-scheduler"
      }
    },
    "strategy": {
      "type": "RollingUpdate",
      "rollingUpdate": {
        "maxUnavailable": "25%",
        "maxSurge": "25%"
      }
    },
    "revisionHistoryLimit": 10,
    "progressDeadlineSeconds": 600
  },
  "status": {
    "observedGeneration": 11,
    "replicas": 3,
    "updatedReplicas": 3,
    "readyReplicas": 3,
    "availableReplicas": 3,
    "conditions": [
      {
        "type": "Available",
        "status": "True",
        "lastUpdateTime": "2021-12-02T05:07:11Z",
        "lastTransitionTime": "2021-12-02T05:07:11Z",
        "reason": "MinimumReplicasAvailable",
        "message": "Deployment has minimum availability."
      },
      {
        "type": "Progressing",
        "status": "True",
        "lastUpdateTime": "2021-12-02T06:07:02Z",
        "lastTransitionTime": "2021-12-02T06:04:28Z",
        "reason": "NewReplicaSetAvailable",
        "message": "ReplicaSet \"fe-deployment-776c65b5b8\" has successfully progressed."
      }
    ]
  }
}

 

 

 

여기서 중요한 부분은 이미지를 설정하는 부분과 이미지를 private으로 다운받을 경우 이에대한 secret을 선언하는 부분이다. 이부분만 잘 설정해주고 jenkins의 빌드트리거를 동작시켜주자.

 

`````

"image": "mydomain.com/fe/ver:latest",


`````

imagePullSecrets": [
          {
            "name": "harbor"
          }

`````

 

 

 

 

 

 

정상적으로 업데이트된것이 확인된다.

반응형

댓글