[docker] 이미지가 변경된 후 도커 컨테이너를 업그레이드하는 방법
공식 mysql : 5.6.21 image를 가져 왔다고 가정 해 봅시다 .
여러 도커 컨테이너를 만들어이 이미지를 배포했습니다.
이 컨테이너는 MySQL 5.6.22가 출시 될 때까지 얼마 동안 실행되었습니다. mysql : 5.6의 공식 이미지는 새로운 릴리스로 업데이트되지만 컨테이너는 여전히 5.6.21로 실행됩니다.
이미지의 변경 사항 (예 : MySQL 배포판 업그레이드)을 기존의 모든 컨테이너에 전파하려면 어떻게해야합니까? 이 작업을 수행하는 올바른 Docker 방법은 무엇입니까?
답변
답변을 평가하고 주제를 연구 한 후 요약하고 싶습니다.
컨테이너를 업그레이드하는 Docker 방법은 다음과 같습니다.
응용 프로그램 컨테이너는 응용 프로그램 데이터를 저장해서는 안됩니다 . 이렇게하면 언제든지 다음과 같은 것을 실행하여 앱 컨테이너를 최신 버전으로 바꿀 수 있습니다.
docker pull mysql
docker stop my-mysql-container
docker rm my-mysql-container
docker run --name=my-mysql-container --restart=always \
-e MYSQL_ROOT_PASSWORD=mypwd -v /my/data/dir:/var/lib/mysql -d mysql
호스트 (볼륨으로 마운트 된 디렉토리) 또는 특수 데이터 전용 컨테이너 에 데이터를 저장할 수 있습니다 . 그것에 대해 더 읽어보기
- 볼륨 정보 (Docker 문서)
- 작은 도커 조각, 느슨하게 결합 됨 (Tom Offermann)
- Docker에서 영구 저장소 (예 : 데이터베이스)를 처리하는 방법 (스택 오버플로 질문)
컨테이너 내에서 업그레이드 응용 프로그램 (예 : yum / apt-get 업그레이드)은 안티 패턴으로 간주됩니다 . 응용 프로그램 컨테이너는 변경 불가능 하며, 재현 가능한 동작을 보장해야합니다. 일부 공식 응용 프로그램 이미지 (특히 mysql : 5.6)는 자체 업데이트하도록 설계되지 않았습니다 (apt-get 업그레이드가 작동하지 않음).
답변을 주신 모든 분들께 감사 드리고 싶습니다. 그래서 우리는 모든 다른 접근법을 볼 수있었습니다.
답변
볼륨을 호스트 디렉토리에 대한 링크로 마운트하는 것을 좋아하지 않으므로 완전히 docker 관리 컨테이너로 docker 컨테이너를 업그레이드하기위한 패턴을 생각해 냈습니다. 새 도커 컨테이너를 만들면 --volumes-from <container>
업데이트 된 이미지가있는 새 컨테이너에 도커 관리 볼륨의 소유권이 공유됩니다.
docker pull mysql
docker create --volumes-from my_mysql_container [...] --name my_mysql_container_tmp mysql
원본을 my_mysql_container
아직 즉시 제거 하지 않으면 업그레이드 된 컨테이너에 올바른 데이터가 없거나 위생 테스트에 실패한 경우 알려진 작업 컨테이너로 되돌릴 수 있습니다.
이 시점에서 나는 보통 컨테이너가 가지고있는 백업 스크립트를 실행하여 문제가 생길 경우에 대비하여 안전망을 제공합니다.
docker stop my_mysql_container
docker start my_mysql_container_tmp
이제 새 컨테이너에있을 것으로 예상되는 데이터가 있는지 확인하고 상태 확인을 실행할 수 있습니다.
docker rm my_mysql_container
docker rename my_mysql_container_tmp my_mysql_container
컨테이너가 컨테이너를 사용하는 동안 도커 볼륨이 달라 붙어 원래 컨테이너를 안전하게 삭제할 수 있습니다. 원래 컨테이너가 제거되면 새 컨테이너는 원래 이름을 그대로 사용하여 모든 것을 처음부터 예쁘게 만들 수 있습니다.
도커 컨테이너를 업그레이드하기 위해이 패턴을 사용하면 두 가지 주요 이점이 있습니다. 첫째, 볼륨을 업그레이드 된 컨테이너로 직접 전송할 수 있도록하여 호스트를 호스트에 볼륨을 마운트 할 필요가 없습니다. 두 번째로, 도커 컨테이너가 작동하지 않는 위치에 있지 않습니다. 따라서 업그레이드에 실패하면 원래 도커 컨테이너를 다시 회전시켜 이전의 작동 방식으로 쉽게 되돌릴 수 있습니다.
답변
더 일반적인 (mysql에 국한되지 않은) 답변을 제공하기 위해 …
- 한마디로
서비스 이미지 레지스트리 ( https://docs.docker.com/compose/compose-file/#image ) 와 동기화 하십시오 .
docker-compose pull
docker-compose 파일 또는 이미지가 변경된 경우 컨테이너를 다시 만듭니다.
docker-compose up -d
- 배경
컨테이너 이미지 관리는 docker-compose를 사용하는 이유 중 하나입니다 ( https://docs.docker.com/compose/reference/up/ 참조 )
서비스에 대한 기존 컨테이너가 있고 컨테이너 작성 후 서비스 구성 또는 이미지가 변경된 경우, docker-compose up은 컨테이너를 중지하고 다시 작성하여 마운트 된 볼륨을 보존하여 변경 사항을 선택합니다. 작성이 변경 사항을 선택하지 못하게하려면 –no-recreate 플래그를 사용하십시오.
마운트 된 외부 “볼륨”( https://docs.docker.com/compose/compose-file/#volumes 참조 ) 또는 데이터 컨테이너를 통해 docker-compose가 데이터 관리 측면을 다루고 있습니다.
이것은 이전 버전과의 호환성 및 데이터 마이그레이션 문제를 건드리지 않지만 Docker가 아닌 “응용 적”문제이며 릴리스 정보 및 테스트와 비교하여 확인해야합니다
답변
이 프로세스를 자동으로 수행하려면 (@Yaroslav에서 설명한 것과 동일한 설정으로 새 컨테이너를 다운로드, 중지 및 다시 시작하려는 경우) WatchTower를 사용할 수 있다고 덧붙이고 싶습니다. 컨테이너가 변경 될 때 컨테이너를 자동으로 업데이트하는 프로그램 https://github.com/v2tec/watchtower
답변
이 답변을 고려하십시오.
- 데이터베이스 이름은
app_schema
- 컨테이너 이름은
app_db
- 루트 비밀번호는
root123
컨테이너 내에 애플리케이션 데이터를 저장할 때 MySQL을 업데이트하는 방법
컨테이너를 잃으면 데이터를 잃을 수 있기 때문에 이것은 나쁜 습관으로 간주 됩니다. 좋지 않은 방법이지만 여기에 가능한 방법이 있습니다.
1) 데이터베이스 덤프를 SQL로 수행하십시오.
docker exec app_db sh -c 'exec mysqldump app_schema -uroot -proot123' > database_dump.sql
2) 이미지를 업데이트하십시오.
docker pull mysql:5.6
3) 컨테이너를 업데이트하십시오.
docker rm -f app_db
docker run --name app_db --restart unless-stopped \
-e MYSQL_ROOT_PASSWORD=root123 \
-d mysql:5.6
4) 데이터베이스 덤프를 복원하십시오.
docker exec app_db sh -c 'exec mysql -uroot -proot123' < database_dump.sql
외부 볼륨을 사용하여 MySQL 컨테이너를 업데이트하는 방법
외부 볼륨을 사용하는 것이 데이터를 관리하는 더 좋은 방법이며 MySQL을보다 쉽게 업데이트 할 수 있습니다. 컨테이너를 풀면 데이터가 손실되지 않습니다. docker-compose 를 사용 하여 단일 호스트에서 다중 컨테이너 Docker 응용 프로그램을 쉽게 관리 할 수 있습니다 .
1) docker-compose.yml
응용 프로그램을 관리하기 위해 파일을 작성하십시오 .
version: '2'
services:
app_db:
image: mysql:5.6
restart: unless-stopped
volumes_from: app_db_data
app_db_data:
volumes: /my/data/dir:/var/lib/mysql
2) docker-compose.yml
파일 과 동일한 폴더에서 MySQL을 업데이트 하십시오.
docker-compose pull
docker-compose up -d
참고 : 위의 마지막 명령은 MySQL 이미지를 업데이트하고 새 이미지로 컨테이너를 다시 만들고 시작합니다.
답변
위와 비슷한 답변
docker images | awk '{print $1}' | grep -v 'none' | grep -iv 'repo' | xargs -n1 docker pull
답변
docker-compose
custom 을 만들 때 사용하는 모습은 다음과 같습니다 Dockerfile
.
- 차별화 할 다음 버전 번호를 추가하여 사용자 정의 Dockerfile을 먼저 빌드하십시오. 예 :
docker build -t imagename:version .
새 버전을 로컬에 저장합니다. - 운영
docker-compose down
docker-compose.yml
1 단계에서 설정 한 새 이미지 이름을 반영하도록 파일을 편집하십시오 .- 를 실행하십시오
docker-compose up -d
. 로컬에서 이미지를 찾고 업그레이드 된 이미지를 사용합니다.
-편집하다-
위의 단계는 필요한 것보다 더 장황합니다. build: .
docker-compose 파일에 매개 변수를 포함시켜 작업 흐름을 최적화했습니다 . 단계는 이제 다음과 같습니다.
- 내 Dockerfile이 원하는 모양인지 확인하십시오.
- docker-compose 파일에서 이미지 이름의 버전 번호를 설정하십시오.
- 내 이미지가 아직 빌드되지 않은 경우 : 실행
docker-compose build
- 운영
docker-compose up -d
당시에는 알지 못했지만 docker-compose는 컨테이너를 먼저 내리지 않고 하나의 명령으로 컨테이너를 새 이미지로 업데이트하기에 충분합니다.