什么,容器太多操作不过来?我选择Docker Compose梭哈(下)

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 什么,容器太多操作不过来?我选择Docker Compose梭哈(下)

4、新的问题


如果容器过多,那么每次启动容器都要-v xxx:xxx,这也很容易写错啊,写错一个字母都不行,还有,如果宿主机换地址了,这也需要批量更换容器的docker run -v的参数,机器太多不利于维护。


5、解决问题


共享容器诞生了!


5.1、共享容器概念


如果容器太多,每一次都要写-v xxx:xxx,过于复杂,也容易出错,这时候可以通过docker create创建共享容器,然后启动的时候通过--volumes-from指定创建的共享容器名称即可,也就是说可以把上面-v xxx:xxx这一串统一放到一个地方去管理,容器启动的时候直接引用这个统一配置即可,方便统一管理。


5.2、语法


# 创建共享容器语法,只是创建不是启动。最后的/bin/true 就是一个占位符,没啥乱用。
docker create --name 共享容器名称 -v 宿主机路径:容器内挂载路径 镜像名称 /bin/true
# 启动容器的时候通过--volumes-from 共享容器名称来使用共享容器挂载点
docker run --volumes-from 共享容器名称 --name xxx -d 镜像名称


5.3、实战


# 创建共享容器
docker create --name webpage -v /home/main/docker/webapps:/usr/local/tomcat/webapps tomcat /bin/true
# 采取共享容器的配置来启动容器
docker run -p 8300:8080 --volumes-from webpage --name t3 -d tomcat
# 在启动个
docker run -p 8400:8080 --volumes-from webpage --name t4 -d tomcat


5.4、验证&&好处


验证跟第一种-v的方式一样,修改内容,容器无感知。


相对于第一种方式的好处是:


  • 不用每次都写-v xxx:xxx这一长串不仅令人厌恶还容易出现错误的英文字母。


  • 更改路径,只修改一处即可。


三、DockerCompose


1、有什么用


比如我们要部署一个javaweb应用,那一般情况都需要三个容器:nginx容器、tomcat容器、mysql容器。这是最基本的,可能更复杂。那运维人员每次都需要单独启动这三个容器来支撑我们的web应用吗?有点复杂了。


docker-compose就是为了简化这个过程的,相当于是个脚本,把这三个容器用脚本统一来管理和启动。节省运维时间和避免出错率。也就是说多应用互相协同才能完成一件事的时候,是很好用的,否则直接Dockerfile就完了。


2、安装DockerCompose


基于Linux的安装。

参考的官方安装文档:https://docs.docker.com/compose/install/


执行如下两个命令就完事了:


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


如果第一个命令特别慢的话可以用如下命令代替,毕竟是国外网站


> curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose


安装完进行验证:


docker-compose --version


3、实战感受一下


先来感受一下docker-compose的威力,部署下WordPress来玩玩。不知道WordPress是啥的自己百度,就是一个开源博客。


为什么是部署WordPress,因为官方也是WordPress….面向官方文档学习…


官方文档安装WordPress的教程:https://docs.docker.com/compose/wordpress/


(1)建立如下目录


/home/main/docker/WordPress


(2)建立docker-compose.yml文件


cd /home/main/docker/WordPress
vi docker-compose.yml


(3)在docker-compose.yml里写上如下内容


version: '3.3'
services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress
   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
       WORDPRESS_DB_NAME: wordpress
volumes:
    db_data: {}


看不懂?正常,也没关系。这就是大名鼎鼎的docker-compose,就是一个一.yml为后缀结尾的脚本文件。他能自动帮我们部署我们配置的容器,比如上述有mysql容器和wordpress容器。我们还能看到端口是8000,这就够了。开干!


(4)执行脚本


# 先进入你的docker-compose.yml所在的目录
cd /home/main/docker/WordPress
# 执行脚本
docker-compose up -d


(5)结果分析


[root@izm5e3qug7oee4q1y4opibz WordPress]# docker-compose up -d
Creating network "wordpress_default" with the default driver
Creating volume "wordpress_db_data" with default driver
Pulling db (mysql:5.7)...
5.7: Pulling from library/mysql
afb6ec6fdc1c: Pull complete
....
0bdc5971ba40: Pull complete
Digest: sha256:d16d9ef7a4ecb29efcd1ba46d5a82bda3c28bd18c0f1e3b86ba54816211e1ac4
Status: Downloaded newer image for mysql:5.7
Pulling wordpress (wordpress:latest)...
latest: Pulling from library/wordpress
afb6ec6fdc1c: Already exists
3d895574014b: Pull complete
...
Digest: sha256:0b452b7b45fa770f12e864720abb01bef506f4abe273669402434e94323c97d7
Status: Downloaded newer image for wordpress:latest
Creating wordpress_db_1 ... done
Creating wordpress_wordpress_1 ... done


可以看到pulling db、pulling wordpress、done。大概了解到为我们创建了wordpress和wordpress所需要的mysql数据库。访问8000端口,大功告成!


image.png


4、和Dockerfile区别


Dockerfile容器间通信需要--link或者桥接方式进行,而DockerCompose全自动的呀。也就是说单容器的话肯定Dockerfile了,但是多容器之间需要交互、有依赖关系,那用DockerCompose来统一管理那些零散的Dockerfile来达到自动构建部署的一体化脚本。


5、实战


5.1、需求描述


实战一个spring boot的项目,一个springboot的jar包依赖mysql数据库。我们用docker-compose完成自动化部署。


5.2、准备工作


5.2.1、 准备如下文件


[root@izm5e3qug7oee4q1y4opibz docker-compose-app]# pwd
/home/main/docker/docker-compose-app
[root@izm5e3qug7oee4q1y4opibz docker-compose-app]# ls -l
total 12
drwxr-xr-x 2 root root 4096 May 24 12:20 app
drwxr-xr-x 2 root root 4096 May 24 12:20 db
-rw-r--r-- 1 root root  335 May 24 12:20 docker-compose.yml


5.2.2、app


里面就是我们的springboot的jar包和制作镜像的Dockerfile文件。


[root@izm5e3qug7oee4q1y4opibz docker-compose-app]# ll app/
total 23492
-rw-r--r-- 1 root root     1071 May 24 12:19 application-dev.yml
-rw-r--r-- 1 root root     1457 May 24 12:19 application.yml
-rw-r--r-- 1 root root 24042957 May 24 12:20 bsbdj.jar
-rw-r--r-- 1 root root      154 May 24 12:20 Dockerfile


看下application-dev.yml的配置,主要看数据库配置:


spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://db:3306/bsbdj?useUnicode=true
    username: root
    password: root
    tomcat:
      init-s-q-l: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci
server:
  port: 80


这里我们发现猫腻了,数据库配置是db:3306,这不是平常的ip/域名神马的,这个是Mysql容器名称。所以这个服务依赖mysql服务,所以我们的主要目的就是利用DockerCompose来自动化操作多容器的Dockerfile文件来自动部署和初始化SQL的操作。


5.2.3、db


jar包所需要的数据库的sql文件和制作镜像的Dockerfile文件。


[root@izm5e3qug7oee4q1y4opibz docker-compose-app]# ll db/
total 35612
-rw-r--r-- 1 root root       69 May 24 12:20 Dockerfile
-rw-r--r-- 1 root root 36460577 May 24 12:20 init-db.sql


5.3、开始实战


5.3.1、app的Dockerfile


FROM openjdk:8u222-jre
WORKDIR /usr/local/bsbdj
ADD bsbdj.jar .
ADD application.yml .
ADD application-dev.yml .
EXPOSE 80
CMD ["java","-jar","bsbdj.jar"]


5.3.2、db的Dockerfile


FROM mysql:5.7
WORKDIR /docker-entrypoint-initdb.d
ADD init-db.sql .


这里有个细节:为什么是进入docker-entrypoint-initdb.d这目录在ADD sql?因为这个目录是个后门,这个目录下的sql文件会自动执行。我咋知道的?官方告诉我的:


https://hub.docker.com/_/mysql


image.png


5.3.3、最终Boss:docker-compose.yml


现在我们应用程序的Dockerfile和应用程序所依赖的数据库Dockerfile都已就绪。还剩下最后一个终极yml配置文件


# 目前最稳定版本:3.3,所以3.3就行。
version: '3.3'
services:
  ## 服务名称叫 db,还记得我们application-dev.yml的配置吗?数据库配置的是db,对应的就是这里了。
  db:
    # Dockerfile文件所属的目录。
    build: ./db/
    # always:宕机自动重启。牛逼的很。
    restart: always
    # 环境变量,类似于-e参数
    environment:
      MYSQL_ROOT_PASSWORD: root
  # 服务名称叫 app    
  app:
    # Dockerfile文件所属的目录。若app依赖db,则需要把db服务配置放到app的前面。
    build: ./app/
    # 依赖上面的db service
    depends_on:
      - db
    # 宿主机和容器的端口均为80。上面app的Dockerfile暴露的是80端口,所以这里容器是80  
    ports:
      - "80:80"
    restart: always


5.3.4、启动


# -d代表后台启动
docker-compose up -d


启动结果:


[root@izm5e3qug7oee4q1y4opibz docker-compose-app]# docker-compose up -d
Creating network "docker-compose-app_default" with the default driver
Building db
Step 1/3 : FROM mysql:5.7
 ---> a4fdfd462add
Step 2/3 : WORKDIR /docker-entrypoint-initdb.d
 ---> Running in d1ff6e4bb5a8
Removing intermediate container d1ff6e4bb5a8
 ---> d29a05c5bfcb
Step 3/3 : ADD init-db.sql .
 ---> 6ae6d9eb35ca
Successfully built 6ae6d9eb35ca
Successfully tagged docker-compose-app_db:latest
WARNING: Image for service db was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Building app
Step 1/7 : FROM openjdk:8u222-jre
8u222-jre: Pulling from library/openjdk
9a0b0ce99936: Pull complete
db3b6004c61a: Pull complete
f8f075920295: Pull complete
4901756f2337: Pull complete
9cfcf0e1f584: Pull complete
d6307286bdcd: Pull complete
Digest: sha256:3d3df6a0e485f9c38236eaa795fc4d2e8b8d0f9305051c1e4f7fbca71129b06a
Status: Downloaded newer image for openjdk:8u222-jre
 ---> 25073ded58d2
Step 2/7 : WORKDIR /usr/local/bsbdj
 ---> Running in df4a4c352e71
Removing intermediate container df4a4c352e71
 ---> 0d88b2f13319
Step 3/7 : ADD bsbdj.jar .
 ---> aabaa119855d
Step 4/7 : ADD application.yml .
 ---> 7e1f7b4614cc
Step 5/7 : ADD application-dev.yml .
 ---> a8d36115592f
Step 6/7 : EXPOSE 80
 ---> Running in 26b44c9d57ef
Removing intermediate container 26b44c9d57ef
 ---> fd36f3cdd115
Step 7/7 : CMD ["java","-jar","bsbdj.jar"]
 ---> Running in 64bdeff2f1ce
Removing intermediate container 64bdeff2f1ce
 ---> 77d18bae9bbc
Successfully built 77d18bae9bbc
Successfully tagged docker-compose-app_app:latest
Creating docker-compose-app_db_1 ... done
Creating docker-compose-app_app_1 ... done


可以看到先为我们构建了mysql的镜像然后又构建了bsbdj.jar的镜像。最后执行了CMD ["java","-jar","bsbdj.jar"],这些过程全自动化。


查看容器


docker-compose ps


结果:


[root@izm5e3qug7oee4q1y4opibz docker-compose-app]# docker-compose ps
          Name                       Command             State          Ports       
------------------------------------------------------------------------------------
docker-compose-app_app_1   java -jar bsbdj.jar           Up      0.0.0.0:80->80/tcp 
docker-compose-app_db_1    docker-entrypoint.sh mysqld   Up      3306/tcp, 33060/tcp


然后访问http://ip:80即可看到效果。


6、补充


docker-compose其他命令可以用docker-compose --help查看。再说下docker-compose和Dockerfile区别,可以粗糙理解成Dockerfile是针对单容器的脚本,docker-compose是针对多Dockerfile的自动化脚本,他帮我们处理容器之间的依赖关系和其他需要人为干涉的操作。


四、上期答疑


上期回顾:面试官:你说你精通 Docker,那你来详细说说 Dockerfile 吧


1.ADD命令能否解压zip格式?多模块该怎么创建镜像?


ADD命令不能解压zip,亲测。能解压:tar, gzip, bzip2, etc。


多模块恰巧是今天的主角docker-compose,可以为每一个模块都书写一个Dockerfile,然后用docker-compose去管理这些带有依赖关系的模块。


如果是集群的话,首选k8s,docker warm什么的,毕竟docker-compose致命缺点仅限在单机上。


2.有了docker commit为啥还要Dockerfile?


docker commit都是黑箱操作,过一段时间后自己都不知道这个镜像是怎么做出来的,都安装了什么。但是使用Dockerfile构建的镜像,我们能清楚的知道都有哪一层,每层是干嘛的,修改也方便,易于维护。


END

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
23小时前
|
存储 Kubernetes Docker
Kubernetes(K8S)集群管理Docker容器(概念篇)
Kubernetes(K8S)集群管理Docker容器(概念篇)
|
1天前
|
存储 Ubuntu 安全
Docker容器常用命令
Docker容器常用命令
|
7天前
|
存储 运维 监控
构建高效稳定的Docker容器监控体系
【4月更文挑战第18天】 在现代微服务架构中,Docker容器已成为部署和运行应用的标准环境。随之而来的挑战是如何有效监控这些容器的性能与健康状况,确保系统的稳定性和可靠性。本文将探讨构建一个高效稳定的Docker容器监控体系的关键技术和方法,包括日志管理、性能指标收集以及异常检测机制,旨在为运维人员提供实用的指导和建议。
12 0
|
15天前
|
Linux Docker 容器
docker 容器常用命令
docker 容器常用命令
13 0
|
15天前
|
Linux Shell 虚拟化
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
27 0
|
15天前
|
存储 Linux Shell
centos 部署docker容器 安装 、基本使用方法(一)
centos 部署docker容器 安装 、基本使用方法(一)
29 0
|
24天前
|
Kubernetes 网络协议 Docker
Docker 容器的DNS
Docker 容器的DNS
28 1
|
1月前
|
Java Go 开发者
Docker容器技术简介及其与Go语言的结合点
【2月更文挑战第23天】本文首先概述了Docker容器技术的核心概念和优势,接着探讨了Go语言与Docker容器技术的结合点。通过阐述Docker的轻量级、可移植性和版本控制等特性,以及Go语言在容器化应用中的优势,本文旨在说明两者结合能够实现更高效、灵活的应用开发和部署。
|
1月前
|
Oracle 关系型数据库 数据库
|
27天前
|
关系型数据库 MySQL Nacos
【深入浅出Nacos原理及调优】「实战开发专题」采用Docker容器进行部署和搭建Nacos服务以及“坑点”
【深入浅出Nacos原理及调优】「实战开发专题」采用Docker容器进行部署和搭建Nacos服务以及“坑点”
47 1