CI/CD 구축

아키텍쳐 Overview


teamcity workflow



cicd workflow


0. 도커 레지스트리 서버 생성

# insecure access
vim C:\Users\k230303\.docker/daemon.json
	{
		"insecure-registries": ["172.16.6.77:5000"]
	}
# 도커 이미지 삭제
docker images | grep -v regi | awk '{ print "docker rmi " $3}' | sh
openssl genrsa -des3 -out server.key 2048
openssl req -new -key server.key -out server.csr

openssl rsa -in server.key -out server.key
echo subjectAltName=IP:172.16.6.77,IP:127.0.0.1 > extfile.cnf
openssl x509 -req -days 10000 -signkey server.key -in server.csr -out server.crt -extfile extfile.cnf

sudo cp ~/docker-registry/server.crt /usr/local/share/ca-certificates/

sudo update-ca-certificates

docker run -d -p 5000:5000 --restart=always --name my_registry \
	-v /home/krms/docker-registry/volume/:/data \
	-v /home/krms/docker-registry/certs/:/certs \
	-e REGISTRY_HTTP_ADDR=0.0.0.0:5000 \
	-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt \
	-e REGISTRY_HTTP_TLS_KEY=/certs/server.key \
	registry:2.6
scp -r krms@172.16.6.77:~/docker-registry/certs ~/

# 윈도우는 server.crt 더블클릭하여 직접설치
# docker 재시작

# 깃bash에서 확인
curl https://172.16.6.77:5000/v2/_catalog -k
	{"repositories":["my_image"]}

curl https://172.16.6.77:5000/v2/_catalog

# 클라이언트 PC에서 도커 리포지토리로 push/pull 테스트
docker tag my_image 172.16.6.77:5000/my_image

docker login 172.16.6.77:5000
docker push 172.16.6.77:5000/my_image
docker pull 172.16.6.77:5000/my_image

docker push jnuho/testgohttp_dockerhub:latest

## TeamCity가 아닌 로컬-> 레지스트리 테스트
go mod init devportal.kaonrms.com/konnect/YAML/on-premise/testgohttp
go mod tity
docker build -t my_image -f ./build/Dockerfile .
docker images
	REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
	my_image     latest    0bbcb61acb59   6 seconds ago   320MB


docker tag my_image 172.16.6.77:5000/my_image

winpty docker login http://172.16.6.77:5000
docker push 172.16.6.77:5000/my_image
docker pull 172.16.6.77:5000/my_image

# 로컬 pc환경-> 도커 레지스트리서버
docker images
	mY-image ...

docker tag my_image 172.16.6.77:5000/my_image:latest
docker push 172.16.6.77:5000/my_image:latest
docker pull 172.16.6.77:5000/my_image:latest

git bash에 .crt 인증서 추가

cat server.crt server.key > server.pem
openssl x509 -in server.crt -inform DER -out server.pem -outform PEM
# 로컬
scp -r server.crt krms@172.16.6.222:/home/krms

# 바스티온
cp -r /home/krms/server.crt /etc/docker/certs.d/172.16.6.77:5000

# 바스티온 -> 도커 레지스트리 서버
docker login 172.16.6.77:5000

1. Gitlab 서버 생성

version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    container_name: gitlab
    restart: always
    ports:
      - '8080:80'
      - '1443:443'
      - '1001:22'
    volumes:
      # - './config:/etc/gitlab' # env variable를 override하므로 커멘트처리!
      - './logs:/var/log/gitlab'
      - './data:/var/opt/gitlab'
		environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://172.16.6.77:8080'
				nginx['listen_port'] = 80
				nginx['listen_https'] = false
    shm_size: '512m'

  agent01:
    container_name: agent01
    image: jetbrains/teamcity-agent:${TEAMCITY_VERSION}-linux-sudo
    ports:
      - "9090:9090"
    privileged: true
    volumes:
      - ./agent/conf:/data/teamcity_agent/conf
      - ./certs:/usr/local/share/ca-certificates
    tty: true
    user: "root"
    environment:
      - DOCKER_IN_DOCKER=start
      - SERVER_URL=http://172.16.6.84:8111
      - AGENT_NAME=agent01
    shm_size: '256m'
    command: >
      sh -c "update-ca-certificates && service docker start && /run-agent.sh && tail -f /dev/null"
docker exec -it gitlab /bin/bash
echo $GITLAB_OMNIBUS_CONFIG
	external_url 'http://172.16.6.77:8080'
	nginx['listen_port'] = 80
	nginx['listen_https'] = false

2. TeamCity 서버 생성

version: '3'
services:
  teamcity:
    image: jetbrains/teamcity-server:${TEAMCITY_VERSION}
    ports:
      - "8111:8111"
    volumes:
      - './data_dir:/data/teamcity_server/datadir'
      - './teamcity-server-logs:/opt/teamcity/logs'
    user: "root"
    shm_size: '128m'
TEAMCITY_VERSION=2022.04
By adding the teamcity_network to the teamcity and teamcity-agent-1 services, you are creating a network bridge that allows these containers to communicate with each other over this network. Since the teamcity container is on this network and needs to access the external machine at 172.16.6.77:5000, the Docker network will handle the routing between the two.

In other words, the teamcity_network serves as a bridge network that connects the containers within it, and also provides a route to the external machine. When you specify a network for a container, Docker automatically adds a network interface to the container and assigns it an IP address within that network. This allows the containers on the same network to communicate with each other and also communicate with external machines on the same network.

By defining an external network, you are telling Docker that this network already exists and Docker should not try to create it. Therefore, when you start your Docker-compose file with the teamcity_network network, Docker will connect the containers to this pre-existing network, allowing them to communicate with each other and with external machines like the one at 172.16.6.77:5000.

3. TeamCity 에이전트 생성

version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    container_name: gitlab
    restart: always
    ports:
      - '8080:80'
      - '1443:443'
      - '1001:22'
    volumes:
      - './config:/etc/gitlab'
      - './logs:/var/log/gitlab'
      - './data:/var/opt/gitlab'
    shm_size: '512m'

  agent01:
    container_name: agent01
    image: jetbrains/teamcity-agent:${TEAMCITY_VERSION}-linux-sudo
    ports:
      - "9090:9090"
    privileged: true
    volumes:
      - ./agent/conf:/data/teamcity_agent/conf
      - ./certs:/usr/local/share/ca-certificates
        #- /var/run/docker.sock:/var/run/docker.sock # mount Docker socket
    tty: true
    user: "root"
    environment:
      - DOCKER_IN_DOCKER=start
      - SERVER_URL=http://172.16.6.84:8111
      - AGENT_NAME=agent01
    shm_size: '256m'
    command: >
      sh -c "update-ca-certificates && service docker start && /run-agent.sh && tail -f /dev/null"

4. Gitlab 프로젝트 생성

git clone https://devportal.kaonrms.com/konnect/YAML/on-premise/testgohttp.git

cd testgohttp
touch main.go
mkdir build
touch ./build/Dockerfile
go mod init devportal.kaonrms.com/konnect/YAML/on-premise/testgohttp
package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello World!")
	})

	http.ListenAndServe(":8080", nil)
}
FROM golang:1.17-alpine as builder

WORKDIR /app

COPY . .

RUN go build -o main .

EXPOSE 8080

CMD ["./main"]

5. TeamCity 프로젝트 생성

#!/bin/bash

hash=%build.vcs.number%
shortHash=${hash:0:7}
echo "###teamcity[setParameter name='GitShortHash' value='$shortHash']"
sync
echo 1 > /proc/sys/vm/drop_caches

6. TeamCity 백업

# TeamCity agent02 추가 후 신규 서버에 agent02 추가되는지 테스트
cd ~krms/test_gitlab
docker-compose down
docker-compose up -d

# TeamCity 신규 서버 구동 후 'Restore from backup'
# TeamCity_Backup_20230317_012048.zip 선택
cd ~krms
mkdir -p 2nd_test_teamcity/data_dir/import
cp test_teamcity/docker-compose.yml 2nd_test_teamcity/

cd ~krms/test_teamcity
docker-compose down

cd ~krms/2nd_test_teamcity
docker-compose up -d

7. TeamCity 프로젝트 단위 백업 또는 복사