라즈베리 파이에 CI 서버 만들기

rasp 3 B fedora 기준으로 작성

repogitory, docker registry, build server, swarm cluster를 갖는 ci 서버를 설치 할 계획이다. 빌드서버로써의 성능은 좋지 않겠지만, 당장 쓸수있는 build server 용 machine 이 없으므로 raspi에 구축하고 개인 프로젝트의 CI/CD가 되도록 하는 것이 목표이다.

docker 설치

기본 docker 는 1.13 버전이라 너무 낮은 버전이다. 최신 CE 버전을 사용한다.

# 기존 docker 제거

sudo dnf remove docker

# repo 추가
sudo dnf -y install dnf-plugins-core
sudo dnf config-manager \
    --add-repo \
    https://download.docker.com/linux/fedora/docker-ce.repo

# docker ce 설치
sudo dnf install docker-ce

# 보안상으로 좋진 않지만 편리한 사용을 위해 docker group 추가
sudo usermod -aG docker bluemir


# docker enable/start
sudo systemctl enable docker 
sudo systemctl start docker 

swarm mode 로 만들기

k8s 도 있지만 설치가 쉬운 swarm mode 를 사용하기로 결정 나중에 확장 하면 node join 만 하면 된다.

docker swarm init 

gogs 설치

gogs 에서 armv8용 이미지를 제공하지 않으므로 직접 빌드 하여 사용

git clone http://github.com/gogs/gogs.git
cd gogs
docker build -t bluemir/arm-gogs:v1 -f Dockerfile.aarch64 .
# dockerfile 의 from을 수정 해야 할수도있음.

집에 여러대의 raspi 가 있기 때문에 공유기에서 port open 시 겹치지 않게끔 설정 나중에 필요하면 변경 하면 될듯

compose.swarm.yaml

version: '3.2'
services:
  gogs:
    image: bluemir/arm-gogs:v1
    deploy:
      replicas: 1
    networks:
      - backend
    volumes:
      - type: bind
        source: /home/bluemir/data/gogs
        target: /data
    ports:
      - "20080:3000"
      - "20022:22"
networks:
  backend:

stack deploy

# bind 할 폴더 미리 만들기
/home/bluemir/data/gogs
# deploy
docker swarm deploy -c compose.swarm.yaml ci

나중의 확장을 위해 nginx 추가

L7 역활을 할 nginx 추가, 이후 drone 이나 jenkins 등을 추가하면 virtual host 기능을 사용해서 분배되도록 할 예정 이후 cert 추가시에도 유리할듯함.

ci-nginx.conf

upstream gogs {
        server gogs:3000;
}

server {
        listen 80;
        server_name gogs.cluster.domain;
        location / {
                proxy_pass https://gogs;
        }
}

compose.swarm.yaml

version: '3.3'
services:
  nginx:
    image: arm64v8/nginx:1.15
    deploy:
      replicas: 1
    configs:
      - source: nginx-conf
        target: /etc/nginx/conf.d/ci.conf
    networks:
      - front
    ports:
      - 80:80
      - 443:443
  gogs:
    image: bluemir/arm-gogs:v2
    deploy:
      replicas: 1
    networks:
      - backend
      - front
    volumes:
      - type: volume
        source: gogs-data
        target: /data
networks:
  backend:
  front:
configs:
  nginx-conf:
    file: ./nginx-ci.conf
volumes:
  gogs-data:

겸사 겸사 gogs데이터도 volume으로 변경. 이후에 volume plugin 을 설정하는 것도 가능할듯

Drone 설치

https://github.com/drone/drone/issues/1767 다행히 arm64용 Image 를 제공할 생각인듯 함.

compose에 다음을 추가

  drone-server:
    image: drone/drone:0.9.0-alpha.3-linux-arm64
    deploy: 
      replicas: 1
    networks:
      - backend
      - front
    volumes:
      - type: volume
        source: drone-server-data
        target: /var/lib/drone/ 
    environment:
      DRONE_GOGS_SERVER: http://gogs:3000
      DRONE_SERVER_HOST: ${DRONE_HOST}
      DRONE_SERVER_PROTO: http
      DRONE_RUNNER_CAPACITY: 2
      DRONE_LOGS_DEBUG: "true"
      DRONE_RPC_SECRET: ${DRONE_SECRET}
  drone-agent:
    image: drone/agent:0.9.0-alpha.3-linux-arm64
    deploy: 
      mode: global
    networks:
      - backend
    volumes:
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock
    environment:
      DRONE_RPC_SERVER: http://drone-server:9000
      DRONE_RPC_SECRET: ${DRONE_SECRET}

nginx 에도 다음을 추가

upstream drone {
        server drone-server;
}
server {
        listen 80;
        server_name drone.cluster.domain;

        location / {
                proxy_set_header X-Forwarded-For $remote_addr;
                proxy_set_header X-Forwarded-Proto $scheme;

                proxy_pass http://drone;
        }
        # see http://docs.drone.io/setup-with-nginx/
}


이후 재배포 하면 drone이 설정 된다.

기타

이후 gogs에서 user를 만들면 CI가 setting 된다. 좀더 나은 사용성을 위해서는 nginx 대신 traefic 같은것을 사용하는게 좋아 보인다.

참고