티스토리 뷰

728x90

설치 환경

  • 사내망, 폐쇄망 등 인터넷이 되지 않는 Master, Worker node 각각 1 PC

기본 내용

  • 아래 내용부터는 인터넷이 가능한 PC와 되지 않는 PC(Spnnaker가 배포될 PC)가 필요한데, 각각 Online PC, Offline PC로 명명한다.
  • 기본적으로 모든 Docker image는 Online PC에서 tar로 압축하여 Offline PC에서 load하여 사용한다.

 


Chartmuseum 설치

※ ALLOW_OVERWRITE=true 설정을 해주지 않으면, 같은 버전의 helm chart를 push하더라도 overwrite되지 않는다. 기본 false이므로 overwrite가 필요한 경우 반드시 설정해주어야한다.

Docker, On-premise 두가지로 설치해보았고, 한가지를 선택하면 된다. 개인적으로는 저장소는 안정성 측면에서 On-premise로 설치하는 것을 선호하는 편이다.

  • Docker
### [ Online PC ]
$ docker pull ghcr.io/helm/chartmuseum:v0.14.0
$ docker save -o chartmuseum.tar ghcr.io/helm/chartmuseum:v0.14.0 # tar를 Offline PC로 이동
### [ Offline PC ]
$ docker load -i chartmuseum.tar
$ docker run -d --rm -it \
  -p 8090:8080 \
  -e DEBUG=1 \
  -e STORAGE=local \
  -e STORAGE_LOCAL_ROOTDIR=/charts \
  -e ALLOW_OVERWRITE=true\
  -v /home/sunju/spinnaker/chartmuseum/charts:/charts \
  ghcr.io/helm/chartmuseum:v0.14.0
### [ Offline PC ]
### chartmuseum를 Online PC에서 다운로드 후 Offline PC로 이동한다.
$ curl -LO https://s3.amazonaws.com/chartmuseum/release/latest/bin/linux/amd64/chartmuseum
$ chmod +x chartmuseum
$ mv chartmuseum /usr/local/bin/chartmuseum


### chartmuseum 데몬 등록
# 1. 환경변수 파일 등록
vi /etc/default/chartmuseum
ARGS=\
--port=8090 \
--storage="local" \
--storage-local-rootdir="/home/sunju/chartmuseum/charts" \
--depth=1 \
--log-json \
--deisable-api="false" \
--allow-overwrite \
--basic-auth-user=myChartmuseumId \
--basic-auth-pass=myChartmuseumPass


### 2. chartmuseum service 파일 등록
vi /etc/systemd/system/chartmuseum.service
Requires=network-online.target
After=network-online.target
 
[Service]
EnvironmentFile=/etc/default/chartmuseum
User=root
Restart=always
ExecStart=/usr/local/bin/chartmuseum $ARGS
ExecStop=/usr/local/bin/chartmuseum step-down

[Install]
WantedBy=multi-user.target


### 3. chartmuseum service 실행
$ sudo systemctl start chartmuseum
$ sudo systemctl enable chartmuseum
$ sudo systemctl status chartmuseum
...
● chartmuseum.service - chartmuseum
   Loaded: loaded (/etc/systemd/system/chartmuseum.service; enabled; vendor preset: disabled)
   Active: active (running) since 5 2022-04-06 18:20:45 CST; 19h ago
...

Minio 설치

Kubernetes, On-premise 두가지로 설치해보았고, 한가지를 선택하면 된다. 개인적으로는 저장소는 안정성 측면에서 On-premise로 설치하는 것을 선호하는 편이다.

  • Kubernetes
### [ Online PC ]
$ docker pull minio/minio
$ docker save -o minio.tar minio/minio # tar를 Offline PC로 이동
### [ Offline PC ]
$ docker load -i minio.tar
### 1.spinnaker namespace 생성
$ vi spinnaker_ns.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: spinnaker
  
$ kubectl apply -f spinnaker_ns.yaml

### 2.minio PersistentVolume 생성
$ vi minio_pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: minio-pv
  namespace: spinnaker
  labels:
    app: minio
spec:
  storageClassName: minio-sc
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /home/sunju/spinnaker/minio/data
    
$ kubectl apply -f minio_pv.yaml

### 3.minio 배포
$ vi minio.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: minio-pvc
  labels:
    app: minio
  namespace: spinnaker
spec:
  storageClassName: minio-sc
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: minio
  namespace: spinnaker
spec:
  replicas: 1
  serviceName: minio
  selector:
    matchLabels:
      app: minio
  template:
    metadata:
      labels:
        app: minio
    spec:
      containers:
      - name: minio
        image: minio/minio
        args:
        - server
        - /storage
        env:
        # MinIO access key and secret key
        - name: MINIO_ROOT_USER
          value: myMinioRootUser
        - name: MINIO_ROOT_PASSWORD
          value: myMinioRootPassword
        ports:
        - containerPort: 9000
        volumeMounts:
        - name: storage
          mountPath: "/storage"
      securityContext:
        runAsUser: 1000
        runAsGroup: 65535
        fsGroup: 65535
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: minio-pvc

---

apiVersion: v1
kind: Service
metadata:
  name: minio
  namespace: spinnaker
spec:
  ports:
    - port: 9000
      targetPort: 9000
      protocol: TCP
  selector:
    app: minio

$ kubectl apply -f minio.yaml
$ kubectl get po -n spinnaker
NAME                                READY   STATUS    RESTARTS   AGE
minio-0                             1/1     Running   0          145m
### [ Offline PC ]
### minio를 Online PC에서 다운로드 후 Offline PC로 이동한다.
### minio 다운로드
$ wget https://dl.min.io/server/minio/release/linux-amd64/minio
$ chmod +x minio
$ mv minio /usr/local/bin/minio


### minio 데몬 등록
# 1. 환경변수 파일 등록
vi /etc/default/minio
# Volume to be used for Minio server.
MINIO_VOLUMES="/home/hkmc/minio/data/"
# Use if you want to run Minio on a custom port.
MINIO_OPTS="--address :9000"
# Access Key of the server.
MINIO_ROOT_USER=myMinioRootUser
# Secret key of the server.
MINIO_ROOT_PASSWORD=myMinioRootPassword


### 2. minio service 파일 등록
vi /etc/systemd/system/minio.service
[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio

[Service]
WorkingDirectory=/usr/local/
User=root
Group=root
EnvironmentFile=/etc/default/minio
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
# Let systemd restart this service always
Restart=always
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65536
# Specifies the maximum number of threads this process can create
TasksMax=infinity
# Disable timeout logic and wait until process is stopped
TimeoutStopSec=infinity
SendSIGKILL=no

[Install]
WantedBy=multi-user.target
# Built for ${project.name}-${project.version} (${project.name})


### 3. minio service 실행
$ sudo systemctl start minio
$ sudo systemctl enable minio
$ sudo systemctl status minio
...
● minio.service - MinIO
Loaded: loaded (/etc/systemd/system/minio.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2022-04-06 14:14:13 KST; 14min ago
...

Spinnaker 구성

- halyard에서는 기본적으로 몇가지 디렉터리 및 파일을 볼륨으로 저장하고 있어야한다. 예를 들면, Spinnaker 배포를 위한 /home/spinnaker/.hal 디렉터리, cloud provider 접근을 위한 config 파일 등이 필요하다. 일단 volume 설정을 해놓으면 spinnaker를 배포하면서 필요한 디렉터리들이 volume에 함께 생성되므로 처음부터 해당 파일들을 생성할 필요는 없다.

- ※ Offline PC에서는 BOM(Bill of Materials)를 통해 Spinnaker를 배포해해야 하므로 .boms 디렉터리에 대한 설정이 필요하다. BOM은 각 마이크로서비스들의 구성을 명세하고있다. Offline PC의 경우 BOM을 사용하여 local에서 이미지를 가져올 수 있도록 수정한다.

- 주요 디렉토리 구조

/opt/halyard/config halyard.yml     halyard 관련 config 파일
/home/spinnaker/.hal config     spinnaker configuration 파일
default profiles front50-local.yaml minio는 versioning을 지원하지 않기때문에 versioning false 설정을 위해 생성한 파일
.kube config   cloud provider 접근을 위한 config 파일 (파일과 디렉터리 이름은 변경 가능하다)
  .boms bom 1.24.2.yml bom 명세 파일
    clouddriver 1.24.2.yml 내용에 맞는 각 버전 디렉토리 및 파일 ex) deck의 경우  3.5.1-20201221155924/settings.js microservices config 파일
    deck
    dependencies
    echo
    fiat
    front50
    gate
    igor
    kayenta
    monitoring-daemon
    orca
    rosco
### [ Online PC ]
$ docker pull us-docker.pkg.dev/spinnaker-community/docker/halyard:stable
$ docker save -o halyard.tar us-docker.pkg.dev/spinnaker-community/docker/halyard:stable # tar를 Offline PC로 이동
### [ Offline PC ]
$ docker load -i halyard.tar
$ vi halyard.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: halyard
  namespace: spinnaker
spec:
  replicas: 1
  serviceName: halyard
  selector:
    matchLabels:
      app: halyard
  template:
    metadata:
      labels:
        app: halyard
    spec:
      containers:
      - name: halyard
        image: gcr.io/spinnaker-marketplace/halyard:stable
        volumeMounts:
        - name: hal
          mountPath: "/home/spinnaker/.hal"
        - name: kube
          mountPath: "/home/spinnaker/.kube"
        - name: config
          mountPath: "/opt/halyard/config"
        env:
        - name: HOME
          value: "/home/spinnaker"
        ports:
        - containerPort: 8064
          protocol: TCP
        readinessProbe:
          exec:
            command:
            - wget
            - --no-check-certificate
            - --spider
            - -q
            - http://localhost:8064/health
      securityContext:
        runAsUser: 1000
        runAsGroup: 65535
      volumes:
      - name: hal
        hostPath:
          path: /home/sunju/spinnaker/halyard
          type: DirectoryOrCreate
      - name: kube
        hostPath:
          path: /home/sunju/spinnaker/halyard/.kube
          type: DirectoryOrCreate
       - name: config
        hostPath:
          path: /home/sunju/spinnaker/hal_config
          type: DirectoryOrCreate
          
$ kubectl apply -f halyard.yaml
$ kubectl get po -n spinnaker
NAME                                READY   STATUS    RESTARTS   AGE
halyard-0                           1/1     Running   0          142m
  • Spinnaker 배포

halyard 커맨드 hal을 통해 config 설정부터 배포까지 가능하다 (https://spinnaker.io/docs/reference/halyard/commands/)

### [ Online PC ]

### 1. bom 파일 다운로드
$ hal version bom 1.24.2 #다운로드 된 1.24.2.yml bom 파일을 Offline PC /home/spinnaker/.hal/.boms/bom에 이동시킨다.


### 2. 각 마이크로 서비스 도커 이미지 tar 압축
# bom파일을 열어보면 각 마이크로 서비스 버전을 알 수 있다.

### 3. 각 마이크로 서비스 배포에 필요한 파일들을 다운로드한다.
# 인터넷이 되는 PC에서 gsutil을 통해 필요한 config 파일을 다운로드 
# (gsutil 설치: https://cloud.google.com/storage/docs/gsutil_install?hl=ko#install 
# (curl url이 보안상 제한되어 있는 경우 https://cloud.google.com/storage/docs/gsutil_install?hl=ko#expandable-1 참고하여 window에 설치한다.)
$ gsutil -m cp -r gs://halconfig .
# boms에 맞는 각 설정파일들을 halyard container에 이동시킬 예정이므로, 
# bom파일을 열어 각 서비스 버전에 맞는 디렉터리를 미리 빼두면 편리하다.
### [ Offline PC ]

### 1. 마이크로 서비스 도커 이미지 load
# Online PC에서 가져온 각 서비스별 tar 도커이미지를 load한다.
$ docker load -i clouddriver.tar #clouddriver, deck, echo, front50, gate, orca, rosco 필요

### 2. bom 설정 파일 구성
# Online PC에서 gsutil로 받아놓은 파일들 중 bom에서 각 서비스의 버전에 맞는 파일들을 이동시킨다.
# halyard container의 /home/spinnaker/.hal/.boms/${microservices}/${version}/과  /home/spinnaker/.hal/.boms/${microservices}/ 에 각각 위치시킨다.
# 예를들어, deck의 경우  /home/spinnaker/.hal/.boms/deck/3.5.1-20201221155924과 /home/spinnaker/.hal/.boms/deck/에 settings.js 파일을 위치시킨다.
# clouddriver, deck, echo, front50, gate, orca, rosco 필요
# /home/spinnaker/.hal/.boms/${microservices}/${version}/과  /home/spinnaker/.hal/.boms/${microservices}/ 두군데에 위치시키는 이유는 version과 일치하지 않을 시 /home/spinnaker/.hal/.boms/${microservices}/ 의 파일을 읽도록 되어있기 때문이다.

### 3. halyard 컨테이너 접속
$ kubectl exec -it halyard-0 -n spinnaker -- /bin/bash
bash-5.0$

### 4. halyard config 중 gcs 설정을 disable 시켜야한다.
# 해당 
$ vi /home/sunju/spinnaker/hal_config/halyard.yml 
...
gcs:
enabled: false
...

### 5. bom 명세 수정
# Online PC에서 다운받은 1.24.2.yml bom 파일을 halyard 컨테이너 기준 /home/spinnaker/.hal/.boms/bom로 이동한다.
# vi 1.24.2.yml #version앞에 local:을 붙여준다.
version: 1.24.2
timestamp: '2021-01-05 20:55:01'
services:
echo:
version: local:2.15.2-20201216030017
commit: 4acf2a63a957099a4c6a950457d6b23079c5ea23
...

### 6. Cloud Providers 설정
# Choose Cloud Providers
bash-5.0$ hal config provider kubernetes enable --no-validate
# account 추가
bash-5.0$ hal config provider kubernetes account add my-k8s-account \
    --provider-version v2\
    --context $(kubectl config current-context)
# artifacts 사용 enable
bash-5.0$ hal config features edit --artifacts true

### 7. Choose your Environment → Distributed installation
bash-5.0$ hal config deploy edit --type distributed --account-name my-k8s-account

### 8. Choose a Storage Service → Minio
# Minio는 versioning을 지원하지 않으므로, versioning disable
bash-5.0$ mkdir ~/.hal/default/profiles && \
    touch ~/.hal/default/profiles/front50-local.yaml
bash-5.0$ vi ~/.hal/default/profiles/front50-local.yaml
bash-5.0$ spinnaker.s3.versioning: false
# storage provider 설정
bash-5.0$ export MINIO_SECRET_KEY=myMinioRootUser
bash-5.0$ export MINIO_ACCESS_KEY=myMinioRootPassword
bash-5.0$ export ENDPOINT=http://minio:9000 # ENDPOINT는 minio 설치 방법에 따라 minio가 설치된 IP가 될 수 있다.
bash-5.0$ echo $MINIO_SECRET_KEY | \
hal config storage s3 edit --endpoint $ENDPOINT \
--access-key-id $MINIO_ACCESS_KEY \
--secret-access-key
# s3 storage provider enable 설정
bash-5.0$ hal config storage edit --type s3

### 9. Configure Helm Artifact Account -> chartmuseum
bash-5.0$ echo myChartmuseumId:myChartmuseumPass > chartmuseumAccount
bash-5.0$ hal config artifact helm enable
bash-5.0$ hal config artifact helm account add my-helm-account \
    --username-password-file chartmuseumAccount

### 10. Deploy Spinnaker
# version 선택
bash-5.0$ hal config version edit --version local:1.24.2
# spinnaker 배포
bash-5.0$ hal deploy apply

### 11. NodePort로 외부 통신을 열어준다. (실제 운영에서는 ingress를 통해 tls 및 도메인 설정등이 가능하다)
bash-5.0$ kubectl edit svc spin-deck -n spinnaker
...
  type: NodePort
  ports:
  - port: 9000
    protocol: TCP
    targetPort: 9000
    nodePort: 30300
    
bash-5.0$ kubectl edit svc spin-gate -n spinnaker
...
  type: NodePort
  ports:
  - port: 8084
    protocol: TCP
    targetPort: 8084
    nodePort: 30400
   
bash-5.0$ hal config security ui edit --override-base-url "http://IP address:30300"
bash-5.0$ hal config security api edit --override-base-url "http://IP address:30400"
bash-5.0$ hal deploy apply

$ kubectl get po -n spinnaker
NAME                                READY   STATUS    RESTARTS   AGE
halyard-0                           1/1     Running   0          142m
spin-clouddriver-5b8b599bbd-h7m5b   1/1     Running   0          138m
spin-deck-7558dbc646-cpwqf          1/1     Running   0          138m
spin-echo-556bb45877-vxgpj          1/1     Running   0          138m
spin-front50-7988979784-bk79d       1/1     Running   0          138m
spin-gate-5cb9f45947-qgc7k          1/1     Running   0          138m
spin-orca-67ff8dc76-g5xv6           1/1     Running   0          138m
spin-redis-c8f9995cc-gmd62          1/1     Running   0          138m
spin-rosco-5d5955d954-qjtr4         1/1     Running   0          138m

http://IP address 또는 domain:30300으로 접속


이슈 해결

1. Error retrieving contents of archive packer.tar.gz

- 원인: packer.tar.gz 파일을 못찾기 때문

- 해결: packer.tar.gz의 위치를 확인한다. (/home/spinnaker/.hal/.boms/rosco/0.23.0-20201208200018/ 혹은 /home/spinnaker/.hal/.boms/rosco/)

 

2. ERROR Unable to retrieve profile "clouddriver.yml": connect timed

- 원인: yml파일을 찾지 못하는 오류가 발생

- 해결: config 파일 셋팅이 누락되었을 수 있으니 확인 (gcs enable 설정을 false처리, 혹은 /home/spinnaker/.hal/.boms 경로에 각 microservices config 파일이 있는지 확인)

 

3. com.amazonaws.services.s3.model.AmazonS3Exception: Forbidden (Service: Amazon S3; Status Code: 403; Error Code: 403 Forbidden; Request ID: 1659BBAC07E9410E; S3 Extended Request ID: null)

- 원인: minio 계정 불일치

- 해결: minio 계정이 정확한지 확인 필요

 

4. java.net.UnknownHostException: spin-redis.spinnaker

- 원인: 방화벽

- 해결: 방화벽 OFF

 

5. Unrecognized VM option 'MaxRAMPercentage=50.0'

- 원인: deprecated BOM version 사용

- 해결:

① BOM version update (1.10.1 경우 발생한 오류이며, 1.24.2로 변경 후에는 미발생)

② 버전 변경이 어려운 경우 아래와 같이 처리 가능.

'/home/spinnaker/.hal/default/service-settings'에 각 pod yml 파일을 생성하여 JAVA_OPTS: -Xms, -Xmx1024m 설정을 해준다.

(clouddriver.yml ,deck.yml, echo.yml, front50.yml, gate.yml,  orca.yml,  rosco.yml 모두 설정 가능)

$ vi /home/spinnaker/.hal/default/service-settings/clouddriver.yml #필요 시 다른 서비스들도 설정
env:
JAVA_OPTS: "-Xms256m -Xmx1024m"

6. cannot read property 'rrb' of undefined

pinnaker UI 진입 시 로딩 화면만 나올 경우, 개발자모드를 확인 했을 때 아래와 같은 오류가 발생

- 원인: deprecated BOM version 사용

- 해결: BOM version update (1.10.1 경우 발생한 오류이며, 1.24.2로 변경 후에는 미발생)

 

7. org.pf4j.update.DefaultUpdateRepository

- 원인: plugin 관련 파일을 불러오지 못했기 때문.

- 해결: 아래 두 URL을 방화벽에서 오픈

728x90

'환경' 카테고리의 다른 글

git commit 기록 수정 / 삭제  (0) 2022.04.13
Jenkins + Spinnaker 기반 웹 애플리케이션 배포  (0) 2022.04.06
Spinnaker 개요  (0) 2022.04.06
Spinnaker 설치 및 설정 (online)  (0) 2022.04.06
Kubernetes 구성  (0) 2022.04.05
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31