Compose是用于定义和运行多容器Docker应用程序的工具。通过Compose,您可以使用YAML文件来配置应用程序的服务。然后,使用一个命令,就可以从配置中创建并启动所有服务。

Docker-Compose 安装:

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 
sudo chmod +x /usr/local/bin/docker-compose

  下载极其的慢,请耐心等待。

  安装完成后测试安装:

$ docker-compose --version 
docker-compose version 1.25.0, build 1110ad01

  根据官网的介绍,我们跟着官网的demo进行一个docker-compose的入门:

  确保已安装Docker Engine和Docker Compose。您无需安装Python或Redis,因为两者均由Docker映像提供。

1.为项目创建目录:

mkdir /composetest 
cd composetest

2.新建app.py在项目目录中创建一个名为的文件,并将其粘贴到:

import time 
 
import redis 
from flask import Flask 
 
app = Flask(__name__) 
cache = redis.Redis(host='redis', port=6379)
def get_hit_count(): retries
= 5 while True: try: return cache.incr('hits') except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5) @app.route('/') def hello(): count = get_hit_count() return 'Hello World! I have been seen {} times.\n'.format(count)

  在此示例中,redis是应用程序网络上的redis容器的主机名。我们为Redis使用默认端口6379

3.requirements.txt在项目目录中创建另一个名为的文件,并将其粘贴到:、

flask 
redis

4.在您的项目目录中,创建一个名为的文件Dockerfile并粘贴以下内容:

FROM python:3.7-alpine 
WORKDIR /code 
ENV FLASK_APP app.py 
ENV FLASK_RUN_HOST 0.0.0.0 
RUN apk add --no-cache gcc musl-dev linux-headers 
COPY requirements.txt requirements.txt 
RUN pip install -r requirements.txt 
COPY . . 
CMD ["flask", "run"]

5.新建 docker-compose.yml在项目目录中创建一个名为的文件,然后粘贴以下内容:

version: '3' #表示docker-compose的版本 
services:   #相当于原先的container ,一个service表示一个container 
  web:      #container的名字 
    build: . 
    ports: 
      - "5000:5000" #映射端口 
    networks: 
      - app-net     #网段 
  redis: 
    image: "redis:alpine" 
    networks: 
      - app-net 
 
networks:    #相当于docker network create app-net 
  app-net: 
    driver: bridge

  该Compose文件定义了两个服务:webredis

6.执行 docker-compose up 运行来启动应用程序

7.在浏览器中输入ip:5000 /以查看应用程序正在运行。您应该在浏览器中看到一条消息,内容为:

Hello World! I have been seen 1 times.

  docker-compose常见操作:

docker-compose version   --查看版本 
 
docker-compose up  --根据yml创建service 
                             指定yaml:docker-compose  up -f xxx.yaml 
                             后台运行:docker-compose up -d 
docker-compose ps --查看启动成功的service ,也可以使用docker ps 
 
docker-compose images   --查看images 
 
docker-compose stop/start   --停止/启动service 
 
docker-compose down  --删除service[同时会删除掉network和volume] 
 
docker-compose exec redis sh  --进入到某个service
  docker-compose up --scale web=5 -d --若要对python容器进行扩缩容
  docker-compose logs web  --日志

Docker Swarm:

  准备三台机器,都装上 Docker

  docker swarm是docker官方提供的一套容器编排系统。它的架构如下:

swarm是一系列节点的集合,而节点可以是一台裸机或者一台虚拟机。一个节点能扮演一个或者两个角色,manager或者worker。

  1. manager节点:Docker Swarm集群需要至少一个manager节点,节点之间使用Raft consensus protocol进行协同工作。通常,第一个启用docker swarm的节点将成为leader,后来加入的都是follower。当前的leader如果挂掉,剩余的节点将重新选举出一个新的leader。每一个manager都有一个完整的当前集群状态的副本,可以保证manager的高可用。
  2. worker节点:worker节点是运行实际应用服务的容器所在的地方。理论上,一个manager节点也能同时成为worker节点,但在生产环境中,我们不建议这样做。worker节点之间,通过control plane进行通信,这种通信使用gossip协议,并且是异步的。

搭建Swarm集群:

1.设置 manager

docker swarm init --advertise-addr=192.168.0.11

  这个时候需要注意观察日志。拿到worker node加入manager node的信息

docker swarm join --token SWMTKN-1-0a5ph4nehwdm9wzcmlbj2ckqqso38pkd238rprzwcoawabxtdq-arcpra6yzltedpafk3qyvv0y3 192.168.0.11:2377

2.切换机器,分别执行上面的命令加入 swarm 集群。

3.进入到manager node查看集群状态 docker node ls

4.node类型的转换:

#可以将worker提升成manager,从而保证manager的高可用 
docker node promote worker01-node 
docker node promote worker02-node 
 
#降级可以用demote 
docker node demote worker01-node

   Swarm基本操作:

docker service create --name my-tomcat tomcat   --创建一个tomcat的service 
 
docker service ls  --查看当前swarm的service 
 
docker service logs my-tomcat  --查看service的启动日志 
 
docker service inspect my-tomcat    --查看service的详情 
 
docker service ps my-tomcat   --查看my-tomcat运行在哪个node上 
 
docker service scale my-tomcat=3    --水平扩展service 可以发现 其他node上都运行了一个my-tomcat的service 
docker service ls 
docker service ps my-tomcat

docker service rm my-tomcat -- 删除service

   如果某个node上的my-tomcat挂掉了,这时候会自动扩展

 多机通信overlay网络:

  业务场景:workpress+mysql实现个人博客搭建

传统手动方式实现:

01-创建mysql容器[创建完成等待一会,注意mysql的版本]

docker run -d --name mysql -v v1:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=examplepass -e MYSQL_DATABASE=db_wordpress mysql:5.6

02-创建wordpress容器[将wordpress的80端口映射到centos的8080端口]

docker run -d --name wordpress --link mysql -e WORDPRESS_DB_HOST=mysql:3306 -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=examplepass -e WORDPRESS_DB_NAME=db_wordpress -p 8080:80 wordpress

03-查看默认bridge的网络,可以发现两个容器都在其中

docker network inspect bridge

04-访问测试:浏览器中输入:ip[centos]:8080,一直下一步

使用docker compose创建:

  docker-compose的方式还是在一台机器中,网络这块很清晰

01-创建wordpress-mysql文件夹

mkdir -p /tmp/wordpress-mysql 
cd /tmp/wordpress-mysql

02-创建docker-compose.yml。文件内容 yml :

version: '3.1' 
 
services: 
 
  wordpress: 
    image: wordpress 
    restart: always 
    ports: 
      - 8080:80 
    environment: 
      WORDPRESS_DB_HOST: db 
      WORDPRESS_DB_USER: exampleuser 
      WORDPRESS_DB_PASSWORD: examplepass 
      WORDPRESS_DB_NAME: exampledb 
    volumes: 
      - wordpress:/var/www/html 
 
  db: 
    image: mysql:5.7 
    restart: always 
    environment: 
      MYSQL_DATABASE: exampledb 
      MYSQL_USER: exampleuser 
      MYSQL_PASSWORD: examplepass 
      MYSQL_RANDOM_ROOT_PASSWORD: '1' 
    volumes: 
      - db:/var/lib/mysql 
 
volumes: 
  wordpress: 
  db:

03-根据docker-compose.yml文件创建service

docker-compose up -d

04-访问测试:win10浏览器ip[centos]:8080,一直下一步

05-值得关注的点是网络

docker network ls 
docker network inspect wordpress-mysql_default

Swarm中实现:

  还是wordpress+mysql的案例,在docker swarm集群中怎么玩呢?

(1)创建一个overlay网络,用于docker swarm中多机通信 , 在 manager-node中执行:

docker network create -d overlay my-overlay-net 
docker network ls[此时worker node查看不到]

(2)创建mysql的service,在manager-node节点上执行:

docker service create --name mysql --mount type=volume,source=v1,destination=/var/lib/mysql --env MYSQL_ROOT_PASSWORD=examplepass --env MYSQL_DATABASE=db_wordpress --network my-overlay-net mysql:5.6
#查看service
docker service ls
docker service ps mysql

(3)创建wordpress的service,在manager-node节点上执行:

#创建service  [注意之所以下面可以通过mysql名字访问,也是因为有DNS解析] 
docker service create --name wordpress --env WORDPRESS_DB_USER=root --env WORDPRESS_DB_PASSWORD=examplepass --env WORDPRESS_DB_HOST=mysql:3306 --env WORDPRESS_DB_NAME=db_wordpress -p 8080:80 --network my-overlay-net wordpress 
#查看service 
    docker service ls 
    docker service ps mysql 
#此时mysql和wordpress的service运行在哪个node上,这时候就能看到my-overlay-net的网络

(4)测试 :浏览器访问ip[manager/worker01/worker02]:8080都能访问成功

(5)查看my-overlay-net

docker network inspect my-overlay-net

Routing Mesh:

  通过前面的案例我们发现,部署一个wordpress的service,映射到主机的8080端口,这时候通过swarm集群中的任意主机ip:8080都能成功访问,这是因为什么?docker swarm中有自己的分布式存储机制.把问题简化:

docker service create --name tomcat -p 8080:8080 --network my-overlay-net tomcat

(1)记得使用一个自定义的overlay类型的网络

network my-overlay-net

(2)查看service情况

docker service ls 
docker service ps tomcat

(3)访问3台机器的ip:8080测试 :发现都能够访问到tomcat的欢迎页

Internal:

  在实战wordpress+mysql的时候,发现wordpress中可以直接通过mysql名称访问,这样可以说明两点,第一是其中一定有dns解析,第二是两个service的ip是能够ping通的,不妨再创建一个service,也同样使用上述tomcat的overlay网络,然后来实验

docker service create --name whoami -p 8000:8000 --network my-overlay-net -d  jwilder/whoami

(1)查看whoami的情况

docker service ps whoami

(2)在各自容器中互相ping一下彼此,也就是容器间的通信,tomcat容器中ping whoami

docker exec -it 9d7d4c2b1b80 ping whoami 
64 bytes from bogon (10.0.0.8): icmp_seq=1 ttl=64 time=0.050 ms 
64 bytes from bogon (10.0.0.8): icmp_seq=2 ttl=64 time=0.080 ms

whoami容器中ping tomcat

docker exec -it 5c4fe39e7f60 ping tomcat 
64 bytes from bogon (10.0.0.18): icmp_seq=1 ttl=64 time=0.050 ms 
64 bytes from bogon (10.0.0.18): icmp_seq=2 ttl=64 time=0.080 ms

(3)将whoami进行扩容

docker service scale whoami=3 
docker service ps whoami #manager,worker01,worker02

(4)此时再ping whoami service,并且访问whoami服务

#ping 
docker exec -it 9d7d4c2b1b80 ping whoami 
64 bytes from bogon (10.0.0.8): icmp_seq=1 ttl=64 time=0.055 ms 
64 bytes from bogon (10.0.0.8): icmp_seq=2 ttl=64 time=0.084 ms 
 
#访问 
docker exec -it 9d7d4c2b1b80 curl whoami:8000 [多访问几次] 
I'm 09f4158c81ae 
I'm aebc574dc990 
I'm 7755bc7da921

  通过上述的实验可以发现什么?whoami服务对其他服务暴露的ip是不变的,但是通过whoami名称访问8000端口,确实访问到的是不同的service,也就是说whoami service对其他服务提供了一个统一的VIP入口,别的服务访问时会做负载均衡。

Stack:

  有没有发现上述部署service很麻烦?要是能够类似于docker-compose.yml文件那种方式一起管理该多少?这就要涉及到docker swarm中的Stack,我们直接通过前面的wordpress+mysql案例看看怎么使用咯。

(1)新建service.yml文件

version: '3' 
 
services: 
 
wordpress: 
image: wordpress 
ports: 
- 8080:80 
environment: 
WORDPRESS_DB_HOST: db 
WORDPRESS_DB_USER: exampleuser 
WORDPRESS_DB_PASSWORD: examplepass 
WORDPRESS_DB_NAME: exampledb 
networks: 
- ol-net 
volumes: 
- wordpress:/var/www/html 
deploy: 
mode: replicated 
replicas: 3 
restart_policy: 
condition: on-failure 
delay: 5s 
max_attempts: 3 
update_config: 
parallelism: 1 
delay: 10s 
 
db: 
image: mysql:5.7 
environment: 
MYSQL_DATABASE: exampledb 
MYSQL_USER: exampleuser 
MYSQL_PASSWORD: examplepass 
MYSQL_RANDOM_ROOT_PASSWORD: '1' 
volumes: 
- db:/var/lib/mysql 
networks: 
- ol-net 
deploy: 
mode: global 
placement: 
constraints: 
- node.role == manager 
 
volumes: 
wordpress: 
db: 
 
networks: 
ol-net: 
driver: overlay

(2)根据service.yml创建service

docker statck deploy -c service.yml my-service

(3)常见操作

docker stack ls   --查看stack具体信息 
 
docker stack services my-service  --查看具体的service 
 
docker service inspect my-service-db   --查看某个service

(4)访问测试:浏览器ip[manager,worker01,worker02]:8080


发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Docker数据持久化及实战(Nginx+Spring Boot项目+MySQL)知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。