再一次的 Docker :多重容器篇
Craig Wyzik from Olympia, WA, USA, File:Hanjin Hamburg (ship, 2011) 003.jpg, CC BY 2.0 https://creativecommons.org/licenses/by/2.0, via Wikimedia Commons
Dockerize apps
Why multi-container
- 容器的特色為隔絕(isolation)。把容器們的服務(service)隔絕起來是個好主意。
Food Trucks
Two containers
這個程式會需要兩個程序的容器:
- Flask
- Elasticsearch (ES)
The Elasticsearch Image
docker pull docker.elastic.co/elasticsearch/elasticsearch:6.3.2
docker run -d --name es -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:6.3.2
--name es
docker container ls
docker container logs es
curl 0.0.0.0:9200
flask and dockerfile
Type...
docker run -P --rm yourusername/foodtrucks-web
Unable to connect to ES. Retying in 5 secs...
Unable to connect to ES. Retying in 5 secs...
Unable to connect to ES. Retying in 5 secs...
Out of retries. Bailing out...
為什麼上不了呢?
Docker Network
0.0.0.0 是宿主端訪問 ES 容器的 IP。其他容器不能靠 0.0.0.0 訪問 ES 容器。
The IP 0.0.0.0 is the IP to access ES container from the host machine. Another container will not be able to access this on the same IP address.
If it's not 0.0.0.0, which IP address will the container accessed?
docker 裝好後,一開始就會建立三個網路實體:
docker network ls
NETWORK ID NAME DRIVER SCOPE
c2c695315b3a bridge bridge local
a875bec5d6fd host host local
ead0e804a67b none null local
bridge
: 橋接。預設網路容器。
The problem
- Flask 容器該怎麼知道
es
就是172.17.0.2
呢?如果 IP 變動的話,又該怎麼辦呢? - bridge 網路並不安全,因為因為所有容器都能訪問它。如何阻絕我們自己的網路呢?
答案:
Define our own networks while keeping them isolated using the
docker network
command.
network create
docker network create foodtrucks-net
docker network ls
docker container stop es
docker container rm es
docker run -d --name es --net foodtrucks-net -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:6.3.2
docker network inspect foodtrucks-net
docker run -it --rm --net foodtrucks-net yourusername/foodtrucks-web bash
再度試試 http://0.0.0.0:5000
吧。
Script
git clone https://github.com/prakhar1989/FoodTrucks
cd FoodTrucks
./setup-docker.sh
Docker Compose
- 用途:輕鬆建立並執行多個 docker 程式。
- 檔案:
docker-compose.yml
- 原本是 Fig 專案演變的。
- 用途:
- production
- staging
- development
- testing
- CI workflow
docker-compose.YML
services:
es:
image: docker.elastic.co/elasticsearch/elasticsearch:6.3.2
container_name: es
environment:
- discovery.type=single-node
ports:
- 9200:9200
volumes:
- esdata1:/usr/share/elasticsearch/data
web:
image: yourusername/foodtrucks-web
command: python3 app.py
depends_on:
- es
ports:
- 5000:5000
volumes:
- ./flask-app:/opt/flask-app
image
: 必須。volumes
: 容器掛載點。程式的所在。depends_on
: 要先開depends_on
指定的容器,才能開現在這個容器。
Startup Docker Compose
- Go to the directory
docker-compose.yml
existed. - Stop and remove old containers by running
docker stop
anddocker rm
. - Run
docker-compose up
.
Let's stop the services and re-run in detached mode...
- CTRL+C
docker-compose up -d
docker-compose ps
anddocker network inspect
docker-compose down -v
to stop the app
What Next?
我打算實戰、給專案添加合適的 Volume, 再看看能不能上 GCP。