"고객 데모를위한 조잡한 카페인 기반 프로토 타입"단계가 거의 끝 나가고 "미래에 대해 생각하기"단계로 전환되는 중형 프로젝트가 있습니다. 이 프로젝트는 소프트웨어 및 펌웨어가있는 Linux 기반 장치와 중앙 관리 웹 서버로 구성됩니다. 현재 10 개의 프로토 타입이 존재하며 1000 대 정도의 생산이 예상됩니다.
자동 업데이트 기술에 정통하지 않고 시간이 부족하기 때문에 소프트웨어 배포 / 자동 업데이트 전략을 신속하게 수행했으며 솔직히 말해서 짜증납니다. 현재 다음과 같이 구성되어 있습니다.
- 프로덕션 릴리스 브랜치가있는 호스팅 된 git repo (GitLab) (웹 서버 소스도 이와 동일한 리포지토리 및 기타 다른 리포지토리에 있음)
- 웹 인터페이스의 "배치 업데이트"버튼 :
- 프로덕션 릴리스 분기에서 최신 버전을 로컬 저장소 영역으로 가져 와서 임시 패키지 준비 준비 영역에 복사합니다.
- 준비 영역에서 레포에 저장된 살균 스크립트를 실행하여 관련없는 소스 파일 (예 : 서버 소스, 펌웨어 소스 등) 및 .git 파일을 제거합니다.
- 현재 git 해시를 업데이트 패키지의 파일에 씁니다 (아래에서 목적이 명확 해짐).
- 모두 잘 작동하면 gzip을 압축하고 이전 gzipped 패키지를 동일한 이름의 파일로 덮어 써서 서비스 할 준비를 한 다음 준비 영역을 삭제합니다.
- 서버에 현재 장치 소프트웨어의 사본 두 개가 동기화되어있을 것입니다. 최신 프로덕션 지점의 전체 로컬 git 저장소 및 이제 다음을 나타내는 것으로 가정 할 준비가 된 gzipped 패키지 같은 버전.
- 장치의 소프트웨어는라는 디렉토리에 자체적으로 포함되어 있습니다.이 디렉토리
/opt/example/current
는 현재 버전의 소프트웨어에 대한 심볼릭 링크입니다. - 부팅시 장치의 자동 업데이트 기능 :
do_not_update
파일 이 있는지 확인하고 존재하는 경우 추가 조치를 취하지 않습니다 (개발 장치의 경우 아래 참조).- 위에서 언급 한 텍스트 파일에서 현재 커밋 해시를 읽습니다.
- 해시를 쿼리 매개 변수로 사용하여 서버에 HTTP 요청을 작성합니다. 서버는 304 (해시는 최신 버전)로 응답하거나 gzip으로 업데이트 된 패키지를 제공합니다.
- 업데이트 패키지를받은 경우 다음 위치에 설치합니다
/opt/example
.- 업데이트 된 소프트웨어 정보 추출 폴더 이름이
stage
. - 업데이트 패키지에서 설치 후 스크립트를 실행하여 해당 업데이트에 필요한 로컬 변경 등을 수행합니다.
- 현재 소프트웨어 루트 폴더를에 복사
previous
(기존 파일이있는previous
경우 먼저 삭제 ) stage
폴더를에 복사latest
(기존 폴더가있는latest
경우 먼저 삭제 )- 보장
current
을 차례로 심볼릭 링크latest
. - 장치 재부팅 (펌웨어 업데이트가있는 경우 재부팅시 적용됨)
- 업데이트 된 소프트웨어 정보 추출 폴더 이름이
새로 구성된 장치에 초기 배포 문제도 있습니다. 장치는 현재 SD 카드를 기반으로하며 (여기서는 자체 범위의 문제가 있음)이 프로세스는 다음과 같이 구성됩니다.
- 안정적인 이전 버전의 소프트웨어가있는 SD 이미지가 있습니다.
- 이 이미지에서 SD 카드가 생성됩니다.
- 처음 부팅 할 때 다양한 최초 장치 별 (일련 번호 기반) 초기화가 수행 된 다음 자동 업데이터가 평소대로 최신 프로덕션 버전의 소프트웨어를 설치합니다.
또한 개발 장치에 대한 지원이 필요했습니다. 개발 장치의 경우 :
- 전체 로컬 자식 저장소는 장치에서 유지 관리됩니다.
current
심볼릭 링크는 개발 디렉토리를 가리 킵니다.do_not_update
자동 업데이트 프로그램이 프로덕션 업데이트로 개발 코드를 날려 버리지 못하게 하는 로컬 파일이 있습니다.
이제 배포 프로세스는 이론적으로 다음과 같습니다.
- 코드를 배포 할 준비가되면 릴리스 지점으로 푸시하십시오.
- 서버에서 "deploy update"버튼을 누릅니다.
- 이제 업데이트가 적용되고 다음에 확인할 때 장치가 자동 업데이트됩니다.
그러나, 거기 톤 연습 문제는 :
- 웹 서버 코드는 장치 코드와 동일한 저장소에 있으며 서버에는 로컬 git 저장소가 있습니다. 최신 웹 서버 코드는 최신 장치 코드와 동일한 브랜치에 없습니다. 디렉토리 구조에 문제가 있습니다. "업로드 배치"단추가 프로덕션 분기에서 최신 버전을 가져 오면 서버 코드의 서브 디렉토리로 가져옵니다. 즉, 처음부터 서버에 배포 할 때 배포를 시도하지 않으면 장치 제작 분기를 가져 와서이 하위 디렉터리를 수동으로 "시드"해야합니다. 부모 디렉토리의 웹 서버 브랜치 에서 장치 코드를 가져옵니다 . 스테이징 영역을 서버의 로컬 git repo의 하위 디렉토리로 만들면 해결할 수 있다고 생각합니다.
- 웹 서버는 현재 장치 소프트웨어의 git 해시를 지속적으로 유지하지 않습니다. 서버 시작시
git rev-parse HEAD
로컬 장치 소프트웨어 저장소에서 현재 해시를 검색합니다. 내가 머리를 감쌀 수없는 이유 때문에 여기에서 설명하지 않는 수많은 논리 오류가 발생합니다. 특히 서버를 다시 시작하면 서버가 새롭고 생산이없는 경우 때로는 서버를 다시 시작하는 것으로 충분합니다. 브랜치 레포는 아직 뽑혔습니다. 요청이있는 경우 해당 논리의 소스를 기꺼이 공유하지만이 게시물이 오래 걸립니다. - 어떤 이유로 살균 스크립트 (서버 측)가 실패하면 서버에 최신 리포지토리가 있지만 동기화되지 않은 / 실패 업데이트 패키지가 남아 있으므로
git rev-parse HEAD
실제로 존재하는 것과 일치하지 않는 해시를 반환합니다. 서버 명령 행에서 수동으로 수정해야합니다. 즉, 서버는 업데이트 패키지가 정확하지 않다는 것을 알지 못하며 항상 순수한 믿음으로 가정합니다. 이 점을 이전 지점과 결합하면 실제로 서버가 매우 취약합니다. - 가장 큰 문제 중 하나는 다음과 같습니다. 현재 장치에서 별도의 업데이터 데몬이 실행되고 있지 않습니다. Wi-Fi 인터넷 접속을 기다리는 합병증과 막판 해커로 인해 장치를 확인하고 업데이트하는 것은 주요 장치 제어 소프트웨어 자체입니다. 즉, 제대로 테스트되지 않은 버전으로 인해 프로덕션 환경으로 전환되고 제어 소프트웨어를 시작할 수없는 경우 더 이상 자체 업데이트 할 수 없으므로 존재하는 모든 장치가 기본적으로 차단됩니다. 이것은 생산에서 절대 악몽 일 것입니다. 운이 좋지 않은 시간에 전원이 꺼지면 단일 장치에 대해서도 마찬가지입니다.
- 다른 주요 문제점은 다음과 같습니다 . 증분 업데이트가 지원되지 않습니다. 예를 들어 장치가 한동안 켜지지 않으면 다음에 업데이트 할 때 여러 릴리스 버전을 건너 뛰면 직접 버전 건너 뛰기 업데이트를 수행 할 수 있어야합니다. 이로 인해 배포가 업데이트되면 주어진 업데이트를 이전 버전 위에 적용 할 수있게하는 악몽이됩니다. 또한 git 해시는 버전 번호가 아닌 버전을 식별하는 데 사용되므로 증분 업데이트를 용이하게하기 위해 버전을 사 전적으로 비교할 수 없습니다.
- 현재 지원하지 않는 새로운 요구 사항은 관리 서버 측에서 구성해야하는 일부 장치 별 구성 옵션 (키 / 값 쌍)이 존재해야한다는 것입니다. 소프트웨어 업데이트와 동일한 HTTP 요청 (어쩌면 HTTP 헤더 / 쿠키로 캡슐화 할 수 있음)로 장치 당 옵션을 장치에 다시 제공하는 것이 마음에 들지 않을 것입니다. 항상 별도의 HTTP 요청으로 만드십시오.
- 하드웨어 버전이 두 개 이상 존재하기 때문에 약간의 합병증이 있습니다. 하드웨어의 현재 버전은 실제로 초기 SD 이미지에 환경 변수로 저장되며 (자체를 식별 할 수 없음) 모든 소프트웨어는 모든 버전의 장치와 호환되도록 설계되었습니다. 펌웨어 업데이트는이 환경 변수를 기반으로 선택되며 업데이트 패키지에는 모든 버전의 하드웨어에 대한 펌웨어가 포함됩니다. 조금 어색하지만 나는 이것으로 살 수 있습니다.
- 현재 수동으로 장치에 업데이트를 업로드 할 수있는 방법이 없습니다 (오랫동안 말해서이 장치에는 두 개의 wifi 어댑터가 있습니다. 하나는 인터넷에 연결하고 다른 하나는 사용자가 장치를 구성하는 데 사용하는 AP 모드입니다. 장치의 로컬 웹 인터페이스에 "소프트웨어 업데이트"기능을 추가하려고합니다. 이것은 큰 문제는 아니지만 업데이트 설치 방법에 영향을 미칩니다.
- 다른 좌절과 전반적인 불안감.
그래서 ... 그것은 길었다. 그러나 내 질문은 이것으로 요약됩니다.
이 작업을 올 바르고 안전하게 수행하려면 어떻게해야합니까? 기존 프로세스를 약간 조정할 수 있습니까? 시간이 오래 걸리는 전략 / 기존 시스템이있어 자체 업데이트 시스템을 롤백 할 필요가 없습니까? 또는 내 자신의 롤을해야하는 경우 배포 / 업데이트 프로세스가 안전하고 성공하기 위해서는 무엇이 필요한가? 또한 믹스에 개발 장치를 포함시킬 수 있어야합니다.
질문이 명확하기를 바랍니다. 나는 그것이 약간 희미하다는 것을 알고 있지만, 이것이 전에 해결되어 성공적으로 해결 된 문제라는 것을 100 % 확신합니다. 현재 받아 들여진 전략이 무엇인지 모릅니다.