(docker container run -> 컨테이너 배포 1개만 생성
기본) 도커 허브 -> 이미지 pull
컨테이너 한개만 배포한다면
DB-(-WEB -> 80 export)
DB 컨테이너 배포 -> WEB 컨테이너 배포(DB와 link, port를 외부에 노출)
삭제? 동일 환경을 또 만들어야 한다면?
이를 해결하기 위해 템플릿 파일 작성 -> yaml 파일
yaml 파일내에 필요한 환경을 구성하고 이를 docker-compose를 이용하여 배포한다.
docker-compose 는 도커엔진에 기본적으로 포함되어 있는 프로젝트가 아니므로 별도의 설치과정이 필요하다.
compose를 이용하면 환경배포, 환경 삭제를 한번에 진행할 수 있다.
yaml 파일이 있는 디렉토리에서 docker-compose down을 하면 yaml 파일을 읽고 해당 환경을 한번에 지울 수 있게된다. 재사용이 가능하다.
단, 지금까지의 모든 설정은 서버 1대 위에서 동작하는 것이다. -> 이때 사용자가 반드시 다른 포트로 접속한다고 보장할 수 없음.
여러 서버에 동일 컨테이너(서비스)를 배포할 수 있어야 한다.
모든 컨테이너는 동일 네트워크에서 연결되어야 한다. 물리적으로 불가능하지만 논리적으로 이를 연결할 수 있어야 한다. 또한 각 서버에 위치한 물리자원들(CPU, RAM)을 통합관리할 수 있어야 한다. 이를 위해서는 "cluster"와 클러스터 환경에서 컨테이너를 오케스트레이션 할 수 있어야 한다. 그래서 서버별로 ip를 나누어서 배포하는 방법이다.
서버에 배포할때 그 서버의 CPU중 한개를 4등분해서 컨테이너를 배포해라는 식으로 컨테이너들을 배포한다. 컨테이너 3개중에 필요없는 것은 또 지우는 등 통합관리가 필요하다.
만약 한 서버에 문제가 생기었다면 overlay를 타고 다른쪽으로 접속할 수 있게 해야 안정적인 서버를 운영할 수 있다.
또 이때 생길 수 있는 문제가 죽은 서버의 DB를 다른 웹서버와도 연결되어서 동작할 수 있게 만들어야 한다. 물리적으로는 불가능하지만 논리적으로 이를 연결할 수 있어야 함. 또한 각 서버에 위치한 물리자원들(CPU, RAM)을 통합관리할 수 있어야 한다.
이를 위해서 cluster와 클러스터 환경에서 컨테이너를 오케스트레이션 할 수 있어야 한다. -> 컨테이너 오케스트레이션 툴(docker swarm, k8s)
스웜 클래식 vs 스웜 모드(일반적으로 docker swarm을 얘기한다)
role과 label 하기
```
docker node ls
docker node inspect manager
```
하니까 위와같이 JSON 형태로 Label과 Role이 보인다.
manager 안에는 worker의 상태를 저장하고 있는 DB(클러스터, 노드정보 저장)가 존재한다.
각각의 노드들을 관리하기 위해 agent가 존재하고 manager에서는 manage(관리 도구)를 이용해서 worker들의 agent에 요청을 보내서 일을 수행한다.
결국 manager는 자신도 자신의 agent와 runtime(docker)을 가지고 있으므로 업무가 지시되면 manager도 업무 처리에 참여한다. 결국 manager가 서비스 생성을 명령하면 클러스터에 있는 모든 노드(manager, worker)는 이를 전달받고 처리한다.
매니저와 워커는 누가 토큰을 발급하고 이를 전달하는지에 달려있다.
[manager]
docker swarm init --advertise-addr=211.183.3.100
-> 토큰이 발행된다. (worker 가입용 토큰)
그래서 실재 토큰을 확인해보면 manager과 worker의 join-token이 다른 것을 확인할 수 있다.
마지막에 manager를 입력해 보면 추가매니저를 위한 토큰이 발행되어 있는 것을 확인할 수 있다.
안정적인 클러스터 운영을 위해서는 manager를 최소한 2대 운영해야 한다.
클러스터 환경내에서 동작중이던 manager가 없어진다면 해당 클러스터를 관리할 수 없게된다.
만약 동작중인 worker 중에 한 대를 manager로 운영하고 싶다면?
docker node promote worker1 <-> docker node demote worker1
매니저가 가입되어 있는 node를 클러스터에서 제외시키고 싶다면?
docker mode rm "ID" # 해당 노드의 상태가 Down 상태
docker mode rm --force "ID" # Active 상태에서도 강제로 제외시킴
만약 스스로 클러스터에서 떠나고 싶다면?
docker swarm leave # worker1에서 하기
---
실습
우리가 관리하는 서버가 1000대
이미지가 현재 없는 상태. 이 상태에서 docker-hub에 있거나 사설 저장소에 있는 이미지를 이용하여 서비스를 배포하고싶다면? -> 각 노드에 이미지를 다운로드 해 두어야 함
이를 극복하는 방법?
전체에 명령을 전달할 방법이 필요하다
1. 스크립트를 이용하거나 ansible/terraform 등을 이용하여 전체 서버에 이미지 다운로드 명령 전달
2. manager에서 명령을 노드에 전달할 때 이미지 pull을 전달하는 것이 아닌, 서비스 배포해라를 전달 (-> 그럼 각각의 노드들이 알아서 이미지를 받아와서 처리함). 대신 이미지 다운로드 속도가 차이나게 됨.
1, 2 모두 다 각자 docker login을 해야하는데 1번은 그게 가능하다.
docker login을 위와 명령어를 이용해 뿌릴 수 있다.
2번의 경우는 전에 워커에서 로그인 하는 것은 어려움이 있을 수 있으므로 다음과 같은 옵션을 이용할 수 있음 ( "--with-registry-auth" ) 이 경우 manager에서 사용한 로그인 정보를 통해 워커들이 별도의 인증 작업없이 이미지 다운 -> 서비스 배포가 가능해진다.
대신 manager만 로그인 해주자
```
docker service create --with-registry-auth --name testweb -p 8008:80 --replicas 4 nginx
```
이렇게 컨테이너들을 만들고 하나의 네트워크에 묶여 연계가 되면 이를 서비스라고 부른다.
서비스 목록확인
```
docker service ls # 서비스 종류 모두 보기
docker service ps testweb # 해당 서비스 상세
docker container ls # manager의 컨테이너 확인
```
```
docker service scale testweb=2
```
으로 해서 스케일을 조정하면 정말로 2개의 컨테이너만 남게된다. 이때 사라진 서비스로 접근해도 접속이 가능한데
그 이유는 overlay 네트워크가 존재하여 자동으로 다른 서버에 접속하기 때문이다.
네트워크 상태를 보면 위와같다.
1. ingress : 생성된 서비스(컨테이너)가 오버레이 네트워크를 통해 연결됨. 생성된 서비스들이 자동으로 연결되는 네트워크이며 외부와의 통신에 참여하는 것이 아니라 내부로 접속을 요청하는 경우 RR을 통해 연결을 수행한다.
2. docker-gwbridge : ingress 네트워크에 포함된 서비스들이 외부와 통신할 떄 사용하는 bridge이다.
따라서 docker container run을 통해 생성된 컨테이너들과 swarm 클러스터 상에 배치된 컨테이너는 서로 다른 네트워크에 배치되고 직접 통신되지 않는다.
또한 기본적으로 docker container run으로 생성된 컨테이너들은 ingress 네트워크에 연결될 수 없음.
```
docker service rm testweb # 서비스 삭제
docker network ls
```
네트워크는 그대로 남아있다.
---
global한 배포
```
docker service create --with-registry-auth --name testweb -p 8008:80 --mode global nginx
#docker service scale testweb=2 # 스케일 조정 지원 안함
```
--replicas 4 는 명시적으로 필요한 컨테이너 개수를 지정하는 방식
--mode global : swarm 클러스터에 참여하는 모든 노드에 각각 1개의 컨테이너 배포
롤링업데이트
기존 컨테이너가 포함하고 있는 내용을 동작중인 상태에서 변경하는 것이 아니다.
실제로는 기존 컨테이너가 중지되고 새로운 버전으로 생성된 컨테이너가 이 역활을 대체하는 것이다.
만약 기존 컨테이너로 돌아가고 싶다면 이를 롤백 할 수 있다.
대신 저장소가 필요함 -> 사설 저장소를 이용하기
도커는 docker hub, 사설저장소로 접속하여 이미지를 pull/push 할 때 인증정보를 포함하고 있는지, 해당 인증정보가 보안성을 갖추고 있는지를 확인하고 만약 해당 정보가 없다면 접속을 자동으로 차단시킨다.
```
# docker hub접속
docker pull centos:7
docker pull user1/centos:7
# private registry 접속
docker pull 1.1.1.1:5000/mycentos:1.0
```
실습의 편의를 위해 오늘은 인증정보없이 push, pull을 하더라도 도커가 이를 허용하도록 설정해보자.
```
docker container run -d --name registry -p 5000:5000 --restart=always registry
```
이렇게하면 private registry가 생성된다.
```
docker run -d -p 8080:8080 --name registry-web --restart=always --link registry -e REGISTRY_URL=http://registry:5000/v2 -e REGISTRY_NAME=localhost:5000 hyper/docker-registry-web
```
worker1에서 이미지를 받고 tag를 붙여서 private registry에 등록해보자
```
docker image pull centos:7
docker image tag centos:7 211.183.3.100:5000/mycentos:1.0
```
하면 위와같이 에러가 난다.
그래서 인증 파일을 만들어주자
```
sudo vi /etc/docker/daemon.json
sudo systemctl restart docker
```
```
# worker
{
"insecure-registries":["211.183.3.100:5000"]
}
# manager
{
"insecure-registries":["localhost:5000"]
}
# 만약 위처럼 입력했다면, manager에서 해당 이미지 pull 하기 위해
# docker image pull localhost:5000/mycentos:1.0
docker image tag centos:7 211.183.3.100:5000/mycentos:1.0
```
하고나면 이미지가 잘 올라간다
해당 이미지가 웹상에서 보인다.
롤링업데이트하기
이제 각 노드에서 이미지 pull 하기
```
docker build -t localhost:5000/myhttpd:blue
docker build -t localhost:5000/myhttpd:green
docker tag localhost:5000/myhttpd:blue 211.183.3.100:5000/myhttpd:blue
docker tag localhost:5000/myhttpd:green 211.183.3.100:5000/myhttpd:green
docker image push localhost:5000/myhttpd:blue
docker image push localhost:5000/myhttpd:green
```
```
docker service create -d -p 80:80 --name myhttpd --replicas 3 211.183.3.100:5000/myhttpd:blue
```
서비스 배포시 이미지이름은 localhost:5000/myhttpd:blue 이다.
매니저가 211.183.3.100:5000으로 접속하여 이미지를 pull하려고 하더라도 daemon.json에서는 insecure을 localhost:5000에 대해서만 인증을 적용하지 않겠다고 했으므로 해당 이미지를 pull 할 수 없다. 따라서 Round Robin에 의해 worker1 ~ worker3 에서 서비스가 배포된다.
하지만 211.183.3.100으로 웹 접속하더라도 오버레이를 통해 타 호스트에 있는 컨테이너로 부터 웹 서비스를 제공받을 수 있게된다.
```
docker service rollback myhttpd
```
이걸로 바꾸어서 다음부터는 진행하자
오후에는 컨테이너에 특정 변수, 파일내용, 비밀번호 등을 전송할 수 있는 config, secret 서비스 배포시 특정 노드, role, label에서만 서비스가 배포되도록 하기 위한 labeling 진행
[Secret/Config]
둘다 컨테이너로 특정 정보를 전달하기 위한 목적으로 사용한다.
컨테이너 내에서 사용이 되더라도 만약 컨테이너가 삭제되면 해당 secret, config는 휘발성 이므로 없어진다.
컨테이너 배포시 컨테이너에서 사용할 데이터를 따로 지정해왔다. 그런데 아예 이미지에 그런 내용을 넣으면 어떻겠냐는 것이다.
이미지는 정적인 결과물이므로 고정된 내용을 수정할 수 없다. 이미지를 만들었다면 고대로 컨테이너에 들어가지 수정되지 않는다.
우리가 ssh PW를 지정했는데 이걸 매번 지정하기 귀찮아서 ssh 패스워드를 넣었다고 가정하자. 이것의 단점은 이 이미지로 배포시 모든 컨테이너의 패스워드는 동일해진다.
그래서 패스워드, 변수같은 민감한 내용을 집어넣었는데 이 값이 매번 바뀌게 하고 싶다는 것이 핵심이다.
이미지 내에 secret을 설정한다. secret test1이라는 것을 만들고 그 안에 패스워드를 매번 바꾸어 넣고 배포한다.
---
이미지내에 패스워드, 변수, key 값등이 적용되어 있다면 이를 이용하여 생성한 모든 컨테이너는 동일한 pwd, 변수, key값을 사용할 수 밖에 없게된다. 이는 보안상 결함이라고 할 수 있다.
이 경우 이미지에 Secret/Config 를 사용하면 필요할 때마다 value를 변경하여 컨테이너를 배포하는 형식으로 각 컨테이너 별로 별개의 key, password, 변수 등을 전달할 수 있게된다.
이미지에 secret과 config를 정의하고 컨테이너 배포시 secret과 config의 값을 정의해 놓는다.
secret을 사용하면 Data가 암호화된다. 대신 컨테이너 안에서는 값을 볼 수 있다.
그럼 secret과 config의 차이는 암호화를 하고 안하고의 차이점이다.
Secret, Config는 docker container run으로는 사용할 수 없다.
오직 docker swarm에서만 사용할 수 있다. 만약 docker container 에서 패스워드를 적용하고자 한다면 -e PASS=test123과 같이 보안성이 없는 상태에서 데이터를 저장할 수 밖에 없다.
Secret은 컨테이너 내에서는 평문, 컨테이너 삭제시 함께 사라진다.(휘발성)
Secret -> 패스워드, ssh key, 인증서와 같이 중요한 데이터를 전송할 때 사용한다.
Config -> 설정파일, 변수와 같이 암호화가 필요하지 않은 경우에 사용한다.
사용하는 방법
1. secret/config 를 생성한다.
2. 서비스 생성시 "1" 에서 만든 결과물을 컨테이너의 어디에서 사용할 것인지 지어해준다.
Secret 생성하기
```
echo test123 | docker secret create mypwd - # secret 생성방법
docker secret create mypwd pwd.txt #이 방법으로도 패스워드를 만들 수 있다.
docker secret ls
```
```
docker secret inspect mypwd
```
실재로 test123 이라는 정보가 보이지는 않는다.
```
docker service create --name mysql --replicas 1 \
> --secret mypwd -e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/mypwd" \
> -e MYSQL_PASSWORD_FILE="/run/secrets/mypwd" \
> -e MYSQL_DATABASE="wordpress" mysql:5.7
```
mysql 내에서 사용할 root의 패스워드 -> 컨테이너 내에 있는 /run/secrets/mypwd 파일의 내용을 토대로 설정
--secret mypwd 를 적용하게 되면 mypwd의 내용을 컨테이너 내의 /run/secrets/mypwd에 기본적으로 붙여넣기 해준다.
이렇게하면 test123이라는 mypwd는 파일로 동작하여 /run/secrets/mypwd 에 저장된다. 이미지에서는 보이지 않고 컨테이너에서는 정상적으로 동작하게된다.
만들어진 위치로 가서 container의 상태를 확인해보자
```
docker container exec <NAMES> cat /run/secrets/mypwd
```
실재 결과를 확인할 수 있다.
관리자 한명이 전체 애플리케이션을 동일하게 배포한다면 secret을 사용하지 않고 패스워드를 직접 입력해도 상관없을 것이다.
하지만, 고객이 우리 클라우드 환경에서 컨테이너를 통해 애플리케이션을 배포하고자 한다면 고객이 입력한 패스워드가 외부에 노출이 되어서는 절대 안된다.
고객이 클라우드 환경에 들어와서 원하는 패스워드를 입력하면 해당 패스워드는 Secret으로 저장하여 외부 타 사용자, 클라우드 관리자 모두 볼 수 없도록 해야한다.
단, 일반적인 설정 파일의 내용이나 간단한 변수등은 보안이 필요하지 않으므로 이는 config를 이용하여 배포한다.
위와같이 Data 부분이 암호화되어 배포된다.
```
docker service create --replicas 1 -d -p 8001:80 --name webconfig1 --config source=webconfig,target=/usr/share/nginx/html/index.html nginx
```
위와같이 내용이 출력되는 것을 확인할 수 있다.
```
docker service ps webconfig1
```
하면 위와같이 worker2에서 동작중인것을 알 수 있음.
worker2에 가서 docker container exec "컨테이너이름" cat /usr/share/nginx/html/index.html
내용을 확인해 보면 config 만들때 사용했던 index.html의 내용을 확인할 수 있다.
외부에서는 http://211.183/3/100:8001
[도커 네트워크](4:45)
ingress : 로드밸런스에 참여한다.
== 노드가 3개가 있을때 이것들을 가로질러 overlay를 만들게 된다. 서비스를 배포하게 되면 overlay에 연결이 된다.
host가 첫번째 서버에 들어왔는데 문제가 생기면 옆에 있는 곳으로 간다. ingress 네트워크는 트래픽이 한쪽에 솔리지 않게끔 만들어준다.
이때 같은 주소로 접속이 두번 들어오는 경우를 생각해보자. 그러면 자동으로 트래픽을 분배해준다.
만약 서버1이 꺼지면 서버2, 서버3 으로 이동한다. 예전에는 tunnel을 구성해서 이를 해결했는데 지금은 그렇게 안해도 ingress에 물려 있으면 자동으로 가능해진다.
overlay를 별도로 만들고 그 네트워크 대역을 사용해 배포해보자
```
docker network create -d overlay --subnet 192.168.111.0/24 gildong
docker network ls
```
위와같이 생성된 gildong 네트워크는 전체 호스트를 가로지르는 오버레이 네트워크이며 SCOPE가 swarm이므로 스웜 클러스터에 참여하는 서비스들이 연결될 수 있는 네트워크이다. 그렇다면 서비스를 이용하여 만든 것(컨테이너)이 아니라 docker container run을 이용하여 만든 컨테이너는 gildong 네트워크에 연결이 가능한가? --net gildong 가능? 불가능함.
만약 docker container run을 이용하여 생성한 단독 컨테이너를 스웜 클러스터의 overlay 네트워크에 연결하고 싶다면 overlay 네트워크 생성시 --attachable을 붙여서 생성해야한다.
```
docker network create -d overlay --subnet 192.168.112.0/24 --attachable gildong2
docker network ls
```
--attachable을 붙여서만든 네트워크를 컨테이너에 붙여보자
```
docker container run -it --net gildong2 centos:7
docker container ls
docker container inspect <컨테이너 ID> | grep IPA
```
만들어진 컨테이너의 IP를 확인해보자, 그럼 위와같이 우리가 설정해 놓은 서브 네트워크 주소로 된것을 확인할 수 있다.
그림으로 치면 위와같은 그림을 그릴 수 있다. 이 상황에서 별도의 컨테이너를 만들어 DB로 사용한다. 그럼 나중에 컨테이너들의 백업용으로 활용할때 유용하게 사용할 수 있다.
[볼륨]
일반적으로 도커에서 사용하는 두가지 볼륨형태를 스웜에서도 사용할 수 있다.
1. file storage -> -v (또는 --volume)
-v /root:/root -> 호스트의 /root와 컨테이너의 /root를 마운트하는 방법
디렉토리와 디렉토리를 연결하는 방법
2. block storage
-v myvolume:/root -> 호스트의 디스크 myvolume을 호스트의 /root에 마운트하는 방법
위와같은 방법을 스웜에서도 사용할 수 있다.
```
docker service create -d --name testvol1 --mount type=volume,source=vol1,target=/root centos:7
```
worker1에서 볼륨이 만들어진것을 확인할 수 있다.
스웜 클러스터 내의 임의의 호스트에 vol1 이라는 볼륨이 생성되고 해당 볼륨을 testvol1이라는 서비스에 연결하여 사용한다. 해당 서비스는 자신의 /root 디렉토리가 vol1 이다.
```
docker service ps testvol1
```
일단... 위와같이 뜬다. 제대로 만들어지지는 않았나보다.
```
docker service rm testvol1
```
source=vol1을 사용하지 않으면 임의의 ID를 발행하고 해당 볼륨을 타겟 서비스의 /root와 연결해줌
위의 방법은 블록스토리지를 연결하는 방법
nfs 처럼 호스트의 특정 디렉토리와 마운트 하는 방법을 확용해본다.
```
docker service create --name testvol2 \
-d --mount type=bind,source=/root/host,target=/root/container centos:7
```
임의의 호스트의 /root/host 디렉토리와 컨테이너의 /root/container 디렉토리를 마운트 하는 방법으로 불륨을 제공하는 방식
하지만, 위의 방법처럼 컨테이너 또는 서비스에게 볼륨을 제공하지는 않는다.
이건 좋은 방법이 아니다.
서버 컨테이너중 하나가 죽었을 때 컨테이너를 다른곳으로 마이그레이션해줄 텐데
1. 이미 사용하는 같은 스토리지가 마운트 됨
2. 스토리지가 동기화 안됨
=> 외부 스토리지가 필요하다
이런 스토리지를 persistent storage라고 부른다.
k8s -> PV(Persistent Volume), PVC(Persistent Volume Create)
service -> replicas 4 -> (source=>host에 있는 /test, target=>컨테이어에 /var/www/html)
위에서 살펴본 스토리지는 컨테이너들과 아래의 호스트간 연결을 기본으로 하므로
만약 컨테이너 내의 특정 디렉토리와 호스트의 디렉토리를 연결했을 때 전체 호스트에 있는 컨테이너의 데이터를 동기화 하고 싶다면 모든 파일을 일일이 수정해야 하는 번거러움이 있다.
이를 위해 스웜 클러스터 외부에 별도로 스토리지를 준비하고 각 컨테이너는 이 스토리지에 연결하여 디스크 또는 디렉토리를 사용하는 방법을 적용해야 안정적으로 스토리지 제공이 가능하다. -> Persistent Storage(영구 스토리지)
이는 호스트, 컨테이너와 별개로 외부에 존재하는 스토리지 이며 네트워크를 통해 마운트 시켜 사용할 수 있다.
외부에다가 스토리지를 두고 컨테이너의 폴더를 연결하자.
이는 호스트, 컨테이너와 별개로 외부에 존재하는 스토리지이며 네트워크를 통해 마운트 시켜 사용할 수 있다.
PV(Persistent Volume), PVC(Persistent Volume Claim)
개발자가 자신이 원하는 크기의 디스크 사이즈, 사용용도(읽기/쓰기, 동시 여러명 접속 여부) 등을 지정하여 볼륨에게 요청하면 해당 요청에 적절한 볼륨을 개발자 서버에게 자동으로 연결해 주는 기술.
[라벨 사용하기](중요)
지금까지의 서비스 배포는 replicas 또는 global 을 이용하여 특정 개수만큼 또는 각 호스트 별로 1개씩 서비스를 배포하는 방식이었다. 이로인해 manager 에서도 서비스가 배포되는 일이 발생하는데, 만약 서비스 배포를 특정 노드에서만 배포하고 싶다면?
```
docker service rm $(docker service ls -q)
```
하면 위와같이 배포가 되는데
```
docker service ls
docker node inspect manager | grep Role
```
하면 위와같이 나오는데 이걸 배포할때 특정 Role에만 배포하라고 요청할 수 있다.
```
docker service create -d --name webtest --constraint 'node.role==worker' -p 80:80 --mode global nginx
# docker service create -d --name webtest --constraint 'node.hostname==worker1' -p 80:80 --mode global nginx
docker service ps webtest
```
하지만 이렇게 작게작게 분류하는게 아닌 label에 따라서 분류를 하고 싶다.
마치 worker1에 tag를 붙이는 것과 비슷하다
```
docker node update --label-add zone=seoul worker1
docker node update --label-rm zone worker1
```
Label이 붙었다. 구지 zone이 아니여도 괜찮은 것으로 보인다.
```
docker service create -d --name webtest --constraint 'node.labels.zone==seoul' -p 80:80 --mode global nginx
```
결과 위와같이 나오는 것을 확인할 수 있다.
Quiz.
우리회사는 MSP 업체이다. 우리회사가 관리하는 업체중에 samsung 이 있다.
삼성의 홈페이지는 https://www.samsung.com/sec/ 이다.
위 홈페이지 내용을 curl https://www.samsung.com/sec/ > samsungv1.html
파일의 title 을 수정하여 samsungv2.html 로 수정하라.
우리회사에서 삼성 홈페이지는 worker1, worker2 에서 관리하고 있다.
우리는 삼성 페이지를 centos:7 의 /var/www/html/ 아래에 samsungv1.html 로 첫번째 이미지(211.183.3.100:5000/samsung:1.0)를 만들고 samsungv2.html 로 두번째 이미지(211.183.3.100:5000/samsung:2.0)를 생성하여 사설 저장소에 미리 업로드 해 둔다.
먼저 첫번째 이미지를 이용하여 worker1, worker2 에 배포하고 외부에서 접속 상태를 확인한다. 이후 업데이트를 통해 타이틀이 변경되었는지를 확인한다.
단, 삼성을 위한 오버레이 네트워크는 samsung 으로 만들고 주소 대역은 10.10.3.0/24 로 할당한다.