Docker进阶
1、Docker Compose
1.1 简介
之前使用Docker,首先需要编写一个DockerFile文件,然后使用docker build 命令使之成为一个镜像,接着使用docker run命令来执行,这些都是手动操作,并且只是针对单个容器!
如果是针对多个容器,如面对100个甚至更多的微服务,它们之间的依赖关系则更为复杂。这时使用Docker Compose 来轻松高效的管理容器,定义运行多个容器即可。
官方介绍
-
定义、运行多个容器
-
YAML file 配置文件
-
single command 命令有哪些?
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.
- 所有的环境都可以使用 Compose
Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.
三步骤:
Using Compose is basically a three-step process:
- Define your app’s environment with a
Dockerfile
so it can be reproduced anywhere.- Dockerfile 保证我们的项目在任何地方可以运行
- Define the services that make up your app in
docker-compose.yml
so they can be run together in an isolated environment.- services 什么是服务
- docker-compose.yml 这个文件怎么写
- Run
docker compose up
and the Docker compose command starts and runs your entire app. You can alternatively rundocker-compose up
using the docker-compose binary.- 启动项目
作用:批量容器编排
我的理解
Compose 是Docker官方的开源项目,需要安装!
Dockerfile 让程序在任何地方运行。 如我们的一个web服务,其中使用到了 redis、mysql、nginx … 多个容器,如果一直使用docker build、docker run等命令就会特别麻烦!
version: "3.9" # optional since v1.27.0
services:
web:
build: .
ports:
- "8000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
这时只要编写了docker-compose.yml文件,即便有100个服务,也只需要使用docker-compose up 一键启动运行即可!
Compose:重要的概念。
- 服务services, 容器,应用 (web、redis、mysql…)
- 项目project, 一组关联的容器,如博客(web、mysql…)
1.2 安装
1、下载
# 第一步:下载,这个网络十分慢,有可能还下载失败!
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /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
# 如果第一步没有下载下来,我们就手动去网站下载即可!
# 地址:https://github.com/docker/compose/releases
# 下载:docker-compose-Linux-x86_64
# 然后将文件上传到 /usr/loca1/bin/ 文件夹下,然后将其重命名为docker-compose
2、授权
# 第二步:修改此文件的权限,增加可执行
sudo chmod +x /usr/local/bin/docker-compose
# 版本信息
docker-compose version
1.3 体验
地址:https://docs.docker.com/compose/gettingstarted/
官方有一个 python 应用,是一个计数器应用,使用了 redis !
1 创建一个文件夹
[root@centos7 bin]# cd /home/
[root@centos7 home]# pwd
/home
[root@centos7 home]# mkdir composetest
[root@centos7 home]# cd composetest/
[root@centos7 composetest]# ll
总用量 0
2 创建一个应用文件 app.py 和其他文件 requirements.txt
[root@centos7 composetest]# vim app.py
[root@centos7 composetest]# cat 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)
if __name__=="__main__":
app.run(host="0.0.0.0", debug=True)
[root@centos7 composetest]# vim requirements.txt
[root@centos7 composetest]# cat requirements.txt
flask
redis
3 创建一个 Dockerfile 文件
[root@centos7 composetest]# vim Dockerfile
[root@centos7 composetest]# cat Dockerfile
FROM python:3.6-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
# 这告诉Docker:
# 从Python 3.6映像开始构建映像
# 将当前目录添加 .到 /code 映像中的路径中
# 将工作目录设置为 /code
# 安装Python依赖项
# 将容器的默认命令设置为 python app.py
4 编写 docker-compose.yml 文件
# 此文件是定义整个服务,需要的环境(web、redis)是完整的上线服务!
[root@centos7 composetest]# vim docker-compose.yml
[root@centos7 composetest]# cat docker-compose.yml
version: "3.8"
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: "redis:alpine"
# 此compose文件定义了两个服务,web和redis
# 该web服务:
# 1、使用从Dockerfile当前目录中构建的图像
# 2、将容器上的公开端口5000转发到主机上的端口5000,我们使用F1ask web服务器的默认端口5000
# 3、该redis服务使用从Docker Hub注册表中提取的公共 Redis映像
5 启动 compose 项目
[root@centos7 composetest]# docker-compose up
Creating network "composetest_default" with the default driver
Building web
Step 1/5 : FROM python:3.6-alpine
3.6-alpine: Pulling from library/python
59bf1c3509f3: Pull complete
......
流程:
1、创建网络
2、执行 docker-compose.yml 文件
3、启动服务
Creating composetest_web_1 … done
Creating composetest_redis_1 … done
4、启动成功
# 1、文件名 composetest
# 2、服务 web redis
# 3、按两次 Ctrl+C 可停止服务
1.4 自动的默认规则
docker images
[root@centos7 ~]# docker service ls
Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
默认的服务名
# 文件名_服务名_num
# 我们使用的是多个服务器,部署的是一个集群,我们的一个项目可能运行在 A服务器上,也可能运行在 B服务器上
# 所以 _num 指的是一个副本数量
# 例如,部署redis服务 ===> 4个副本
# 在集群状态下,服务都不可能只有一个运行实例
# 所以真实的项目都是弹性的、高可用(HA)、高并发(HC)、高性能(HP)
# kubectl service 负载均衡
网络规则
# 例如:10个服务 => 项目 (项目中的内容都在同个网络下,可以通过域名访问,而不是IP地址访问)
# 如果在同一个网络下,我们可以直接通过域名访问。
停止服务
- docker-compose down
- Ctrl + C
docker-compose
以前都是单个 docker run 启动容器,现在使用 docker-compose,通过 docker-compose 编写 yaml 配置文件,然后可以通过 compose 一键启动或停止所有服务。
Docker小结
1、Docker 镜像 run => 容器
2、DockerFile 构建镜像(服务打包)
3、docker-compose 启动项目(编排、多个微服务 / 环境)
4、Docker 网络
1.5 yaml 规则
docker-compose.yaml 核心!
官方地址:https://docs.docker.com/compose/compose-file/compose-file-v3/
# 3层!
version: "" # 版本
services: # 服务
服务1: web
# 服务配置
image:
build:
network:
......
服务2: redis
......
服务3: mysql
......
# 其他配置 网络/卷、全局规则
volumes:
networks:
configs:
1、官网文档
https://docs.docker.com/compose/compose-file/#specifying-durations
2、开源项目 compose.yaml
1.6 开源项目
搭建博客:
-
下载程序
-
安装数据库
-
配置
-
…
-
compose 应用 ===> 一键启动!
官网:https://docs.docker.com/samples/wordpress/
1 创建一个文件夹
[root@centos7 home]# mkdir my_wordpress
[root@centos7 home]# cd my_wordpress/
[root@centos7 my_wordpress]# ll
总用量 0
2 编写 docker-compose.yml 文件
[root@centos7 my_wordpress]# vim docker-compose.yml
[root@centos7 my_wordpress]# cat 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: {}
3 启动项目
[root@centos7 my_wordpress]# docker-compose up
Creating network "my_wordpress_default" with the default driver
Creating volume "my_wordpress_db_data" with default driver
Pulling db (mysql:5.7)...
5.7: Pulling from library/mysql
......
4 访问并搭建博客
总结:
-
1、下载项目(docker-compose.yaml)
-
2、如果需要文件(编写Dockerfile)
-
3、文件准备齐全(直接一键启动项目)
-
4、前台启动 docker-compose up
-
5、后台启动 docker-compose up -d
1.7 实战
1、编写项目微服务
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
server.port=8080
spring.redis.host=redis
@RestController
public class HelloController {
@Autowired
StringRedisTemplate redisTemplate;
@GetMapping("/hello")
public String hello() {
Long views = redisTemplate.opsForValue().increment("views");
return "hello world, views: " + views + "\n";
}
}
2、Dockerfile 构建镜像
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
3、docker-compose.yml 编排项目
version: "3.8"
services:
mcapp:
build: .
image: mcapp
depends_on:
- redis
ports:
- "8080:8080"
redis:
image: "redis:alpine"
4、上传到服务器启动 docker-compose up
[root@centos7 ~]# curl localhost:8080/hello
小结:
-
未来项目只要有 docker-compose 文件。 按照这个规则,启动编排容器!
-
网上开源项目: docker-compose 一键搞定。
-
假设项目要重新部署打包
docker-compose up --build # 重新构建!
1.8 总结
我们的项目最终会是一个完整的工程,工程中可能会有多个服务,服务最终会被运行成一个容器!
项目 compose:三层
-
工程 Porject
-
服务 服务
-
容器 运行实例
2、Docker Swarm
2.1 购买服务器
4台服务器 1核2G
到此,服务器购买完毕!1主,3从!
2.2 给4台机器安装 Docker
和我们单机安装一样
技巧:Xshell 直接同步操作,省时间!
安装步骤见:https://blog.csdn.net/weixin_45688268/article/details/125128616
2.3 工作模式
Docker Engine 1.12 introduces swarm mode that enables you to create a cluster of one or more Docker Engines called a swarm. A swarm consists of one or more nodes: physical or virtual machines running Docker Engine 1.12 or later in swarm mode.
There are two types of nodes: managers and workers.
- 有两个节点:管理节点
manager
,工作节点worker
- 操作都在
manager
节点 - Raft:一致性算法
If you haven’t already, read through the swarm mode overview and key concepts.
2.4 搭建集群
# 查看网络
[root@docker-1 ~]# docker network ls
# 查看 swarm 相关命令
[root@docker-1 ~]# docker swarm --help
# 查看 swarm init命令
[root@docker-1 ~]# docker swarm init --help
# 删除节点
docker swarm leave --force
服务器地址分为:私网、公网!
使用ip addr
命令查看私网ip地址
初始化docker-1节点 docker swarm init
[root@docker-1 ~]# docker swarm init --advertise-addr 172.20.96.22
docker swarm join --token SWMTKN-1-55k21yjnb47rishcdds3wgi89jo5hhs1o1tc5oa0r3jkr4lz0n-6f99ru92qml3dbbui1aisls14 172.20.96.22:2377
docker swarm join-token manager
docker swarm join 加入 一个节点
# 获取令牌
docker swarm join-token manager
docker swarm join-token worker
把后面的节点都搭建进去
加入docker-2节点到docker-1,使之成为worker节点
docker swarm join --token SWMTKN-1-55k21yjnb47rishcdds3wgi89jo5hhs1o1tc5oa0r3jkr4lz0n-6f99ru92qml3dbbui1aisls14 172.20.96.22:2377
加入docker-3节点到docker-1,使之成为worker节点
[root@docker-1 ~]# docker swarm join-token worker
加入docker-4节点到docker-1,使之成为manager节点
[root@docker-1 ~]# docker swarm join-token manager
查看搭建情况
已成功搭建:双主双从集群
总结:
-
1、生成主节点 init
-
2、加入( 管理者(manager)、工作者(worker) )
2.5 Raft协议
双主双从: 假设一个节点挂了!其他节点是否可以用!
Raft协议核心: 保证大多数节点存活才可以用。至少 >1台,如果是集群则至少大于3台!
实验:
1、将docker-1机器停止,即模拟docker-1主节点宕机! 则在双主节点中,另外一个主节点docker-4也不能使用了!
[root@docker-1 ~]# systemctl stop docker
[root@docker-4 ~]# docker node ls
2、可以将其他节点离开
# 现将docker-1节点重新启动
[root@docker-1 ~]# systemctl start docker
# 将docker-3节点去除
[root@docker-3 ~]# docker swarm leave
[root@docker-4 ~]# docker node ls
3、将docker-3节点变成主节点
[root@docker-1 ~]# docker swarm join-token manager
[root@docker-3 ~]# docker swarm join --token SWMTKN-1-4bmuo2dtjv1q8yqe0a5zr3fwu8bm9cdtwfoxmsk1izdeicxpk0-de3najc8etim4l4rwwykeib64 172.29.196.249:2377
[root@docker-3 ~]# docker node ls
4、worker节点就是工作的、管理命令都是在管理节点操作,
5、此时已经将3台机器设置为了管理节点。
测试:将docker-1主节点重新挂掉,看主节点docker-3 和 docker-4 是否还可以继续使用
总结:
-
搭建集群,要保证可用,则至少要有3个主节点
-
任何时候都要有 > 1 台管理节点存活才行
-
Raft协议: 保证大多数节点存活,才可以使用,达到高可用要求!
2.6 体会
-
理解
弹性
、扩缩容!
、集群
等词 -
以后告别 docker run来操作docker
-
最基本的都是使用 docker-compose up 来启动一个项目,但这也是单机的
-
使用集群来操作:docker swarm <===>
docker serivce
-
单个
容器
===>服务
-
容器 ==> 服务 ==> 副本 ,例如 redis 服务 ==> 10个副本 (同时开启10个redis容器)
体验:创建服务、动态扩展服务、动态更新服务
[root@docker-1 ~]# docker service --help
灰度发布:金丝雀发布
[root@docker-1 ~]# docker service create -p 8888:80 --name my-nginx nginx
docker run 容器启动!不具有扩缩容器
docker service 服务!具有扩缩容器,滚动更新,灰度发布等!
查看服务 REPLICAS(副本)
[root@docker-1 ~]# docker service ps my-nginx
[root@docker-1 ~]# docker service ls
动态扩缩容
[root@docker-1 ~]# docker service update --replicas 3 my-nginx
[root@docker-1 ~]# docker service scale my-nginx=3
给my-nginx服务添加3个副本
[root@docker-1 ~]# docker ps
移除服务
[root@docker-1 ~]# docker service rm my-nginx
[root@docker-1 ~]# docker service ls
总结:
-
只要是
服务
,就可以在集群中任意的节点
访问 -
服务可以有多个副本动态扩缩容实现高可用
-
理解 弹性、扩缩容等词
-
docker swarm 其实并不难,只要会搭建集群、会启动服务、会动态管理容器就可以了
2.7 概念总结
swarm
-
集群的管理和编排
-
docker可以初始化一个 swarm 集群,其他节点可以加入。(管理manager、工作者worker)
Node
- 就是一个docker节点
- 多个节点就组成了一个网络集群 (管理manager、工作者worker)
Service
- 任务,可以在管理节点manager或者工作节点worker来运行
- 它是一个核心,用于用户的访问
Task
- 容器内的命令
- 当做是细节任务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-buVWoCHp-1655893988741)(D:\Program Files\Markdown\screenshot\image-20220608205851444.png)]
逻辑是不变的
执行的命令
==> 管理节点 ==> api -> 调度 -> 工作节点(创建Task容器维护创建)
服务副本与全局服务
调整service以什么方式运行
[root@docker-1 ~]# docker service create --help
--mode string
Service mode (replicated, global, replicated-job,or global-job) (default "replicated")
docker service create --mode replicated --name mytom tomcat:7 默认的
docker service create --mode global --name haha alpine ping baidu.com
# 场景?日志收集
每一个节点有自己的日志收集器,过滤。把所有日志最终再传给日志中心
服务监控,状态性能
拓展
# 网络工具
[root@docker-1 ~]# yum install -y bridge-utils
# 动态扩缩容my-nginx服务
[root@docker-1 ~]# docker service scale my-nginx=5
# 查看my-nginx服务的网络模式
[root@docker-1 ~]# docker service inspect my-nginx
Swarm 中的网络模式: “PublishMode”: “ingress”
-
Overlay:使网络变成整体,“总分“的形式
-
ingress:特殊的 Overlay 网络! 具有负载均衡的功能! IPVS VIP!默认
虽然docker在4台机器上,实际网络是同一个! ingress 网络 ,是一个特殊的 Overlay 网络!
[root@docker-1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
9utdla68gg9x ingress overlay swarm
[root@docker-1 ~]# docker network inspect ingress
3、Docker Stack
docker-compose 单机部署项目!
# 单机启动
docker-compose up -d wordpress.yaml
Docker Stack 集群部署项目!
# 集群启动
docker stack deploy wordpress.yaml
# 查看相关命令
[root@docker-1 ~]# docker stack --help
参考网址:https://www.jianshu.com/p/25c529e3a3e6
# docker-compose 文件
version: '3.4'
services:
mongo:
image: mongo
restart: always
networks:
- mongo_network
deploy:
restart_policy:
condition: on-failure
replicas: 2
mongo-express:
image: mongo-express
restart: always
networks:
- mongo_network
ports:
- target: 8081
published: 80
protocol: tcp
mode: ingress
environment:
ME_CONFIG_MONGODB_SERVER: mongo
ME_CONFIG_MONGODB_PORT: 27017
deploy:
restart_policy:
condition: on-failure
replicas: 1
networks:
mongo_network:
external: true
4、Docker Secret
安全!配置密码,证书!
[root@docker-1 ~]# docker secret --help
5、Docker Config
统一配置!
[root@docker-1 ~]# docker config --help
学习方式:
- 网上找案例跑起来试试
- 查看命令帮助文档 --help
- 看官网
6、拓展到K8S
云原生时代
-
Go语言是并发语言!
-
Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言。Go 语言语法与 C 相近,但功能上有:内存安全,GC(垃圾回收),结构形态及 CSP-style 并发计算。
-
罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pike)及肯·汤普逊(Ken Thompson)于2007年9月开始设计Go,稍后Ian Lance Taylor、Russ Cox加入项目。Go是基于Inferno操作系统所开发的。Go于2009年11月正式宣布推出,成为开放源代码项目,并在Linux及[Mac OS X](https://baike.baidu.com/item/Mac OS X)平台上进行了实现,后来追加了Windows系统下的实现。在2016年,Go被软件评价公司TIOBE 选为“TIOBE 2016 年最佳语言”。 目前,Go每半年发布一个二级版本(即从a.x升级到a.y)。