본문 바로가기
Coding

Go에서 Kubernetes 인터페이스 애플리케이션 빌드, 테스트 및 자동화하는 방법

by Jakegyllenhaal 2022. 4. 9.
반응형

Go에서 Kubernetes 인터페이스 애플리케이션 빌드, 테스트 및 자동화하는 방법

 

Unsplash의 Clovis Wood 사진 제공

Kubernetes의 Client-Go는 클러스터와 상호 작용하기 위한 모든 종류의 패키지를 제공합니다. 이러한 패키지에는 다음이 포함됩니다.

  • 그만큼 kubernetes 패키지에는 Kubernetes API에 액세스하기 위한 클라이언트 세트가 포함되어 있습니다.
  • 그만큼 discovery 패키지는 Kubernetes API 서버에서 지원하는 API를 검색하는 데 사용됩니다.
  • 그만큼 dynamic 패키지에는 임의의 Kubernetes API 개체에 대해 일반 작업을 수행할 수 있는 동적 클라이언트가 포함되어 있습니다.
  • 그만큼 plugin/pkg/client/auth 패키지에는 외부 소스에서 자격 증명을 얻기 위한 선택적 인증 플러그인이 포함되어 있습니다.
  • 그만큼 transport 패키지는 인증을 설정하고 연결을 시작하는 데 사용됩니다.
  • 그만큼 tools/cache 패키지는 컨트롤러를 작성하는 데 유용합니다.

위의 모든 패키지와 함께 Client-Go에는 가짜 클라이언트도 포함되어 있어 단위 테스트 범위를 쉽게 늘리기 위해 특정 Kubernetes 리소스의 생성, 읽기, 편집 및 제거를 목업할 수 있습니다.

KubeCon Europe 2019에서 저는 Go-Client 가짜 클라이언트를 사용하여 단위 테스트를 수행하는 방법에 대해 발표했습니다.

오늘은 Kubernetes 클러스터에서 작업을 수행하는 데 사용되는 간단한 클러스터 외부 애플리케이션을 만드는 방법을 살펴보겠습니다. 그런 다음 단위 테스트에서 Kubernetes API 호출을 조롱하고 GitLab을 사용하여 이러한 테스트 등의 실행을 자동화하는 방법을 보여 드리겠습니다!

시작하려면 몇 가지 프로그램을 설치해야 합니다.

  • Go — 오픈 소스 프로그래밍 언어.
  • MiniKube — macOS, Linux 및 Windows에서 로컬 Kubernetes 클러스터를 빠르게 설정하는 도구입니다. Docker, HyperV, Podman 등과 같은 MiniKube를 실행하려면 가상화 드라이버도 필요합니다. 자세한 정보는 여기에서 찾을 수 있습니다.

메모: 다른 클러스터를 사용할 수 있습니다. minikube에 따라 잘 작동합니다. kubectl 설정된 컨텍스트입니다. 이 가이드는 다음을 사용하여 작성되었습니다. minikube모든 사람이 액세스할 수 있기 때문입니다.

또한 다음에 대한 지식도 있어야 합니다.

  • Go Basics — 내가 작성했고 앞으로 다룰 코드는 Go에 있습니다. 기본적인 이해가 있는지 확인하십시오.
  • Kubernetes 기본 사항 — Kubernetes 클러스터 작업 및 kubectl 사용 방법을 이해합니다.
  • Kubernetes 비밀 — Kubernetes에 어떤 비밀이 있는지 이해합니다.

다음을 아는 것이 좋습니다.

  • Git 기초 — 포크를 생성하고 코드를 직접 수정하는 Git에 대해 알아두면 좋습니다.
  • GitLab CI — 내 코드는 GitLab에 있으며 단위 테스트 및 보안 스캔을 실행하기 위해 GitLab CI를 사용하고 있습니다.

다음 기능을 수행하는 secreto-server 프로젝트를 사용할 것입니다.

  • 일반 Kubernetes 비밀 생성
  • 지정된 네임스페이스당 비밀을 나열합니다.
  • 페이로드를 포함하는 비밀 데이터를 얻습니다.
  • 비밀 삭제

먼저 MiniKube를 사용하여 클러스터를 만들고 Kubernetes 비밀과 상호 작용할 수 있는지 확인합니다. 그런 다음 응용 프로그램을 로컬로 실행하고 모든 응용 프로그램의 기능을 확인합니다.

Kubernetes 클러스터 생성

  1. MiniKube를 설치하십시오. 시작하기 페이지에서 OS 및 아키텍처에 기반한 Minikube 버전을 다운로드할 수 있습니다.

2. Minikube를 실행합니다. 필요한 패키지를 다운로드하는 데 몇 분이 걸릴 수 있지만 필요한 가상화 드라이버가 있는 한 Minikube를 실행하는 것은 간단합니다. Docker Desktop은 대부분 작동하지만 podman을 사용하여 다른 것을 시도하고 있습니다. 드라이버에 대한 자세한 내용은 Minikube 문서를 참조하십시오.

$ minikube startminikube v1.25.2 on Darwin 12.3 (arm64)
Using the podman (experimental) driver based on existing profile
Starting control plane node minikube in cluster minikube
Pulling base image ...
E0321 11:05:07.616563 66007 cache.go:203] Error downloading kic artifacts: not yet implemented, see issue #8426
Restarting existing podman container for "minikube" ...
Preparing Kubernetes v1.23.3 on Docker 20.10.12 ...E0321 11:05:13.251398 66007 start.go:126] Unable to get host IP: RoutableHostIPFromInside is currently only implemented for linux
▪ kubelet.housekeeping-interval=5m
Verifying Kubernetes components...
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
Enabled addons: storage-provisioner, default-storageclass
kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A'
Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

3. Minikube가 올바르게 실행되고 있는지 확인합니다. Minikube 노드의 상태가 준비 상태인지 확인하여 이를 수행할 수 있습니다.

$ minikube kubectl get nodesNAME STATUS ROLES AGE VERSION
minikube Ready control-plane,master 3m50s v1.23.3

4. 비밀을 만듭니다. 우리는 이것을 통해 할 것입니다 kubectl 비밀 API에 대한 액세스 권한이 있는지 확인하기 위한 것입니다. 나는 일반 비밀을 만들고있다 literal[shhh]=supersecret .

$ minikube kubectl create secret generic my-secret -- --from-literal=shhh=supersecretsecret/my-secret created

5. 이제 시크릿이 성공적으로 생성되었는지 확인해보자

YAML 모드에서 잡아서 base64로 인코딩된 것을 볼 수 있습니다. supersecret (c3VwZXJzZWNyZXQ=).

$ minikube kubectl get secrets my-secret -- -o yamlminikube kubectl get secrets my-secret -- -o yaml
apiVersion: v1
data:
shhh: c3VwZXJzZWNyZXQ=
kind: Secret
metadata:
creationTimestamp: "2022-03-20T21:16:48Z"
name: my-secret
namespace: default
resourceVersion: "728"
uid: 9fcb7814-77f1-44dc-b476-066db11598bd
type: Opaque
  1. GOPATH에 애플리케이션 복제
$ git clone git@gitlab.com:k2511/secreto-server.gitgit clone git@gitlab.com:k2511/secreto-server.git
Cloning into 'secreto-server'...
remote: Enumerating objects: 235, done.
remote: Counting objects: 100% (232/232), done.
remote: Compressing objects: 100% (121/121), done.
remote: Total 235 (delta 97), reused 177 (delta 69), pack-reused 3
Receiving objects: 100% (235/235), 282.99 KiB | 3.11 MiB/s, done.
Resolving deltas: 100% (97/97), done.$ cd secreto-server

2. 응용 프로그램 실행 파일을 빌드합니다. 나는 그것을 쉽게 만드는 Makefile을 만들었습니다. 이 명령이 실행되면 이라는 이름의 새 실행 파일이 생성되어야 합니다. secreto-server.

$ make buildgo mod download
GOOS=darwin GOARCH=arm64 go build -o secreto-server .
chmod +x secreto-server

메모: 변경해야 할 수도 있습니다. $GOOS 그리고 $GOARCH M1 Mac에서 실행하지 않는 경우 Makefile의 변수. 자세한 내용은 여기를 참조하세요.

3. 애플리케이션을 로컬에서 실행합니다. 이것은 단지 전달함으로써 이루어집니다 -local 실행 파일을 실행할 때 플래그. 없이 실행 -local 플래그는 다른 인증 방법을 사용하기 때문에 Kubernetes 클러스터에서 애플리케이션을 실행해야 합니다.

$ ./secreto-server -local2022/03/20 16:18:30 KubeClient running with local configuration
2022/03/20 16:18:30 Starting server on the port 8080

설정하여 포트를 변경할 수도 있습니다. SECRETO_PORT 프로그램을 실행하기 전에 환경 변수.

이제 응용 프로그램이 실행 중입니다. 계속해서 작동하는지 확인합시다. 다른 터미널을 열고 해당 버전을 얻기 위해 서버에 요청을 보냄으로써 이를 수행할 수 있습니다.

$ curl http://localhost:8080/api/secreto/version{"version":1}

이제 작동하는 응용 프로그램이 있습니다! 응용 프로그램의 여러 기능을 확인하겠습니다.

비밀 추가

전달하여 비밀을 추가할 수 있습니다. name 그리고 payload secreto API 경로로 이동합니다. 당신도 추가했는지 확인하십시오 namespace 아래 그림과 같이 경로의 끝까지.

$ curl -X POST http://localhost:8080/api/secreto/default -d '{"name": "my-secret2", "payload": "my-secret-yoo"}'{"Secret Created Successfully":{"name":"my-secret2","namespace":"default","date":"2022-03-20 17:39:41 -0500 CDT","payload":"my-secret-yoo"}}

비밀 보기

모든 비밀을 나열하고 네임스페이스별로 정렬하고 페이로드를 조회할 수도 있습니다. 이것은 다른 경로에서 GET을 수행하여 수행됩니다.

  • /api/secreto: 모든 비밀을 나열합니다.
  • /api/secreto/{namespace}: {namespace}의 모든 비밀을 나열합니다.
  • /api/secreto/{namespace}/{name}: {namespace}의 {name} 비밀 데이터를 나열합니다.
$ curl -X GET http://localhost:8080/api/secreto[{"name":"default-token-m9wsq","namespace":"default","date":"2022-03-20 16:10:27 -0500 CDT","payload":""},{"name":"my-secret","namespace":"default","date":"2022-03-20 16:16:48 -0500 CDT","payload":"supersecret"},{"name":"yeet","namespace":"default","date":"2022-03-20 16:56:24 -0500 CDT","payload":"my-secret-yoo"},{"name":"default-token-dq5wr","namespace":"kube-node-lease","date":"2022-03-20 16:10:26 -0500 CDT","payload":""},{"name":"default-token-nwbxx","namespace":"kube-public","date":"2022-03-20 16:10:26 -0500 CDT","payload":""},{"name":"attachdetach-controller-token-cdfl4","namespace":"kube-system","date":"2022-03-20 16:10:14 -0500 CDT","payload":""},{"name":"bootstrap-signer-token-ljx9n","namespace":"kube-system","date":"2022-03-20 16:10:14 -0500 CDT","payload":""},{"name":"bootstrap-token-81dbvo","namespace":"kube-system","date":"2022-03-20 16:10:13 -0500 CDT","payload":""},{"name":"certificate-controller-token-9nqdf","namespace":"kube-system","date":"2022-03-20 16:10:15 -0500 CDT","payload":""},{"name":"clusterrole-aggregation-controller-token-wb95r","namespace":"kube-system","date":"2022-03-20 16:10:13 -0500 CDT","payload":""},{"name":"coredns-token-7sldt","namespace":"kube-system","date":"2022-03-20 16:10:14 -0500 CDT","payload":""},{"name":"cronjob-controller-token-l5msx","namespace":"kube-system","date":"2022-03-20 16:10:16 -0500 CDT","payload":""},{"name":"daemon-set-controller-token-ppr8p","namespace":"kube-system","date":"2022-03-20 16:10:16 -0500 CDT","payload":""},{"name":"default-token-mxzhs","namespace":"kube-system","date":"2022-03-20 16:10:26 -0500 CDT","payload":""},{"name":"deployment-controller-token-ctsrt","namespace":"kube-system","date":"2022-03-20 16:10:13 -0500 CDT","payload":""},{"name":"disruption-controller-token-kf9qs","namespace":"kube-system","date":"2022-03-20 16:10:14 -0500 CDT","payload":""},{"name":"endpoint-controller-token-kkp5b","namespace":"kube-system","date":"2022-03-20 16:10:13 -0500 CDT","payload":""},{"name":"endpointslice-controller-token-b4bwk","namespace":"kube-system","date":"2022-03-20 16:10:13 -0500 CDT","payload":""},{"name":"endpointslicemirroring-controller-token-g7bqq","namespace":"kube-system","date":"2022-03-20 16:10:15 -0500 CDT","payload":""},{"name":"ephemeral-volume-controller-token-t7s6h","namespace":"kube-system","date":"2022-03-20 16:10:14 -0500 CDT","payload":""},{"name":"expand-controller-token-wvhn8","namespace":"kube-system","date":"2022-03-20 16:10:26 -0500 CDT","payload":""},{"name":"generic-garbage-collector-token-q62cw","namespace":"kube-system","date":"2022-03-20 16:10:26 -0500 CDT","payload":""},{"name":"horizontal-pod-autoscaler-token-wmkcc","namespace":"kube-system","date":"2022-03-20 16:10:13 -0500 CDT","payload":""},{"name":"job-controller-token-9492p","namespace":"kube-system","date":"2022-03-20 16:10:26 -0500 CDT","payload":""},{"name":"kube-proxy-token-6z9ht","namespace":"kube-system","date":"2022-03-20 16:10:14 -0500 CDT","payload":""},{"name":"namespace-controller-token-lrwx8","namespace":"kube-system","date":"2022-03-20 16:10:15 -0500 CDT","payload":""},{"name":"node-controller-token-x9vwn","namespace":"kube-system","date":"2022-03-20 16:10:16 -0500 CDT","payload":""},{"name":"persistent-volume-binder-token-vdw68","namespace":"kube-system","date":"2022-03-20 16:10:26 -0500 CDT","payload":""},{"name":"pod-garbage-collector-token-jl9z2","namespace":"kube-system","date":"2022-03-20 16:10:16 -0500 CDT","payload":""},{"name":"pv-protection-controller-token-jv9d8","namespace":"kube-system","date":"2022-03-20 16:10:13 -0500 CDT","payload":""},{"name":"pvc-protection-controller-token-d4ccm","namespace":"kube-system","date":"2022-03-20 16:10:13 -0500 CDT","payload":""},{"name":"replicaset-controller-token-hbdj6","namespace":"kube-system","date":"2022-03-20 16:10:15 -0500 CDT","payload":""},{"name":"replication-controller-token-74kl8","namespace":"kube-system","date":"2022-03-20 16:10:13 -0500 CDT","payload":""},{"name":"resourcequota-controller-token-767r2","namespace":"kube-system","date":"2022-03-20 16:10:13 -0500 CDT","payload":""},{"name":"root-ca-cert-publisher-token-7zbhn","namespace":"kube-system","date":"2022-03-20 16:10:14 -0500 CDT","payload":""},{"name":"service-account-controller-token-vdxgt","namespace":"kube-system","date":"2022-03-20 16:10:26 -0500 CDT","payload":""},{"name":"service-controller-token-nvt8n","namespace":"kube-system","date":"2022-03-20 16:10:15 -0500 CDT","payload":""},{"name":"statefulset-controller-token-97d8r","namespace":"kube-system","date":"2022-03-20 16:10:26 -0500 CDT","payload":""},{"name":"storage-provisioner-token-nsblb","namespace":"kube-system","date":"2022-03-20 16:10:16 -0500 CDT","payload":""},{"name":"token-cleaner-token-wdbdn","namespace":"kube-system","date":"2022-03-20 16:10:15 -0500 CDT","payload":""},{"name":"ttl-after-finished-controller-token-rgjt4","namespace":"kube-system","date":"2022-03-20 16:10:16 -0500 CDT","payload":""},{"name":"ttl-controller-token-tzjfc","namespace":"kube-system","date":"2022-03-20 16:10:14 -0500 CDT","payload":""}]$ curl -X GET http://localhost:8080/api/secreto/default[{"name":"default-token-m9wsq","namespace":"default","date":"2022-03-20 16:10:27 -0500 CDT","payload":""},{"name":"my-secret","namespace":"default","date":"2022-03-20 16:16:48 -0500 CDT","payload":"supersecret"},{"name":"my-secret2","namespace":"default","date":"2022-03-20 16:56:24 -0500 CDT","payload":"my-secret-yoo"}]$ curl -X GET http://localhost:8080/api/secreto/default/my-secret{"name":"my-secret","namespace":"default","date":"2022-03-20 16:16:48 -0500 CDT","payload":"supersecret"}

비밀 삭제

이제 이전에 생성한 비밀을 삭제해 보겠습니다. 이것은 비밀의 전체 경로에서 DELETE를 수행하여 수행됩니다.

$ curl -X DELETE http://localhost:8080/api/secreto/default/my-secret{"Secret Deleted Successfully":"my-secret"}

이제 응용 프로그램 코드를 살펴보겠습니다. 나는 주로 Kubernetes API와 상호 작용하는 부분을 살펴볼 것입니다. 응용 프로그램은 다음과 같이 분할됩니다.

  • middleware: 요청을 처리하고 응답을 생성하기 위한 모든 애플리케이션 로직을 포함합니다. 여기에는 비밀에 대해 다른 기능을 수행하기 위해 Kubernetes API와 통신하는 것이 포함됩니다.
  • router: 특정 URI의 호출을 미들웨어의 애플리케이션 로직으로 라우팅합니다.
  • model: 비밀을 표시하고 생성하기 위해 애플리케이션에서 사용되는 구조체를 포함합니다.
  • main.go: 응용 프로그램을 시작하고 web-server.

이제 소스 코드가 어떻게 작동하는지 살펴보겠습니다.

인증 및 설정

Kubernetes 클라이언트로 인증하는 것은 middleware.go에서 볼 수 있습니다. 이 기사에서는 클러스터 외부 인증에 대해 설명합니다.

이 코드는 Client-Go의 클러스터 외부 구성 예제에서 가져왔습니다. 주목해야 할 주요 부분은 다음과 같습니다.

  • Kubernetes 구성은 활성 상태인 항목을 확인하여 설정됩니다. ~/.kube/config 폴더
  • 홈 디렉토리가 없으면 다음을 전달해야 합니다. -kubeconfig 적절하게 로드하기 위해 Kubernetes 구성의 경로와 함께
  • 전역변수가 있다 ClientSet=client 계속 로드할 필요가 없도록 설정 kubeconfig 다음으로 명령을 실행할 수 있습니다. ClientSet

비밀 추가

비밀을 추가하기 위해 아래 코드는 요청을 수락하고 private createSecret 기능을 수행한 다음 사용자에게 응답을 반환합니다. 주목해야 할 주요 부분은 다음과 같습니다.

  • CORS에 대한 헤더를 설정합니다(예: Access-Control-Allow-Methods). 이를 통해 브라우저에서 다양한 유형의 메서드를 사용할 수 있습니다.
  • router.go에 정의된 URI 경로 {namespace}에서 네임스페이스에 대한 매개변수를 가져옵니다.
  • 요청 본문의 항목을 기반으로 Kubernetes API 호출을 생성합니다.
  • 실제 비밀을 인코딩하여 반환하거나 오류를 반환합니다.

아래 코드는 시크릿을 생성하기 위해 Client-Go를 사용하는 private 함수입니다. 주목해야 할 주요 부분은 다음과 같습니다.

  • metav1.ObjectMeta 지도에 캡슐화된 비밀 페이로드와 함께 설정됩니다. secretData 그리고 secretDataBytes
  • 함수에서 전송된 데이터를 기반으로 하는 Kubernetes v1.Secret은 Secret 생성을 위해 Kubernetes API에 전달됩니다.
  • 시크릿 생성이 성공하면 Secreto 객체를 생성하고 이를 리턴하기 전에 시크릿의 데이터로 채웁니다.

비밀 보기

비밀을 보는 데 사용되는 몇 가지 기능이 있습니다. 그들은 Client-Go를 사용하여 Kubernetes의 비밀과 정보를 수집합니다. 대부분의 기능이 비슷하기 때문에 비밀 정보를 얻는 방법에 대해 설명하겠습니다. 주목해야 할 주요 부분은 다음과 같습니다.

  • CORS에 대한 헤더를 설정합니다(예: Access-Control-Allow-Methods). 이를 통해 브라우저에서 다양한 유형의 메서드를 사용할 수 있습니다.
  • URI 경로에서 네임스페이스 및 이름에 대한 매개변수를 가져옵니다. {namespace}/{name} router.go에 정의되고 Kubernetes API에 대한 호출을 생성합니다.
  • 실제 비밀을 인코딩하여 반환하거나 오류를 반환합니다.

아래 코드는 Client-Go를 사용하여 세부 정보를 얻는 비밀을 설명하기 위해 Client-Go를 사용하는 private 함수입니다.

func getSecretDetails(namespace string, name string) (*v1.Secret, error) {
secret, err := ClientSet.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil { return nil, err } return secret, nil }  

비밀 삭제

비밀을 삭제하는 것은 매우 간단합니다. 주목해야 할 주요 부분은 다음과 같습니다.

  • CORS에 대한 헤더를 설정합니다(예: Access-Control-Allow-Methods). 이를 통해 브라우저에서 다양한 유형의 메서드를 사용할 수 있습니다.
  • URI 경로에서 네임스페이스 및 이름에 대한 매개변수를 가져옵니다. {namespace}/{name} router.go에 정의되고 Kubernetes API에 대한 호출을 생성합니다.
  • 비밀이 성공적으로 삭제되었다는 메시지를 반환하거나 오류를 반환합니다.

아래 코드는 비밀을 삭제하기 위해 Client-Go를 사용하는 비공개 함수입니다.

func deleteSecret(name string, namespace string) error {
err := ClientSet.CoreV1().Secrets(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
return err
}
return nil }  

이제 응용 프로그램 내의 모든 다른 기능을 보았으므로 계속해서 몇 가지 단위 테스트를 작성하겠습니다. 단위 테스트는 애플리케이션의 여러 부분에 대한 개별 테스트로, 로직을 확인하고 애플리케이션이 제대로 작동하는지 확인하는 데 중요합니다.

내가 작성한 모든 단위 테스트는 middleware_test.go에 있습니다.

일반 설정

다른 단위 테스트에 대한 테스트 값을 설정하는 함수를 만들었습니다. 당신은 볼 수 있습니다 setupSecrets() 다른 비밀과 찾고자 하는 예상 값을 생성하는 함수입니다.

조롱 클라이언트 - 이동

ClientSet 에 정의된 전역 변수입니다. 미들웨어.고. 테스트 내에서 덮어쓰므로 모든 요청이 Kubernetes 클러스터와 통신하지 않고 가짜 값을 반환할 수 있습니다. 가짜 클라이언트는 모의 객체와 값을 반환하는 요청을 합니다.

ClientSet = fake.NewSimpleClientset()

모의 요청

HTTP 테스트를 위한 유틸리티를 제공하고 요청을 "기록"할 수 있는 httptest를 사용하여 요청을 조롱할 수 있습니다. 주의해야 할 몇 가지 사항은 다음과 같습니다.

  • 요청이 생성되고 테스트 변수가 requestBody에 전달됩니다.
  • 그만큼 CreateSecret 함수는 가짜와 함께 호출됩니다 w http.ResponseWriter, r *http.Request 우리가 생성한

테스트 실행

이제 테스트를 완료했으므로 계속해서 실행할 수 있습니다. 다음 명령을 실행하여 수행할 수 있습니다.

$ make testgo test -v ./...
? gitlab.com/k2511/kube-secreto [no test files]
=== RUN TestProcessSecrets
--- PASS: TestProcessSecrets (0.00s)
=== RUN TestGetSecretsClient
--- PASS: TestGetSecretsClient (0.00s)
=== RUN TestGetSecretDetailsClient
--- PASS: TestGetSecretDetailsClient (0.00s)
=== RUN TestCreateSecretClient
--- PASS: TestCreateSecretClient (0.00s)
=== RUN TestDeleteSecretClient
--- PASS: TestDeleteSecretClient (0.00s)
=== RUN TestGetSecretsByNamespace
--- PASS: TestGetSecretsByNamespace (0.00s)
=== RUN TestGetSecretDetails
--- PASS: TestGetSecretDetails (0.00s)
=== RUN TestCreateSecret
--- PASS: TestCreateSecret (0.00s)
=== RUN TestDeleteSecret
--- PASS: TestDeleteSecret (0.00s)
=== RUN TestGetVersion
--- PASS: TestGetVersion (0.00s)
PASS
ok gitlab.com/k2511/kube-secreto/internal/server/middleware 1.406s
? gitlab.com/k2511/kube-secreto/internal/server/models [no test files]
? gitlab.com/k2511/kube-secreto/internal/server/router [no test files]

저는 CI용 GitLab을 사용하여 빌드, 테스트 및 애플리케이션 컨테이너를 레지스트리로 푸시하는 작업을 자동화하고 있습니다. 이렇게 하면 코드를 푸시할 때마다 이러한 기능을 수동으로 수행할 필요가 없습니다.

내 애플리케이션이 자동으로 테스트되어 애플리케이션 로직을 확인할 수 있도록 GitLab을 구성할 수 있습니다. 내 애플리케이션도 빌드되고 컨테이너화되어 내 컨테이너 레지스트리에 푸시됩니다. GitLab SAST를 사용하여 내 소스 코드가 안전한지 확인할 수도 있습니다.

내 GitLab Yaml은 다음과 같습니다.

이제 최신 실행 중인 GitLab Pipeline을 보면 다음을 볼 수 있습니다.

  • 빌드 단계: 실행 build 애플리케이션을 빌드하고 docker-build 애플리케이션 컨테이너를 빌드하고 내 컨테이너 레지스트리에 푸시합니다.
  • 테스트 단계: unit 단위 테스트를 실행하고 커버리지 보고서를 생성합니다. gosec-sast 그리고 semgrep-sast 용도 gosec 그리고 semgrep 각기 에게 취약점에 대한 애플리케이션 소스 코드 스캔

보안 탭을 클릭하면 해결해야 하는 몇 가지 취약점을 심각도별로 정렬하여 볼 수 있습니다.

하나를 클릭하면 설명, 위치, CVE 및 솔루션이 제공됩니다. 또한 취약성을 무시하거나 기밀 문제를 만들어 허가 없이 다른 사람에게 알리지 않고 다른 사람과 함께 수정 작업을 수행할 수 있습니다.

GitLab에는 다른 멋진 CICD 도구와 함께 살펴볼 수 있는 보안 스캐너가 더 있습니다.

반응형

댓글