Docker 基础使用
一、Docker入门
1. Docker 为什么会出现
2. DevOps(开发、运维)
3. 名词解释
- 镜像(image)
- Docker 镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat 镜像 ===> run ===> tomcat01 容器, 通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)
- 容器(container)
- Docker 利用容器技术,独立运行一个或者一组应用, 通过镜像来创建的
- 启动,停止,删除,基本命令!
- 就目前可以把这个容器理解为一个建议的 linux 系统
- 仓库(repository)
- 存放镜像的地方
- Docker Hub(默认是国外的)
- 阿里云,都有容器服务(配置镜像加速!)
4. 安装 docker
4.1 安装前环境查看
1 | 系统内核 |
4.2 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
4.3 使用 Docker 仓库进行安装
1. 设置仓库
1 | 更新apt包索引 |
秘钥添加验证
1
2
3
4
5
6
79DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 通过搜索指纹的后8个字符,验证您现在是否拥有带有指纹的密钥。
sudo apt-key fingerprint 0EBFCD88
pub rsa4096 2017-02-22 [SCEA]
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ unknown] Docker Release (CE deb) <docker@docker.com>
sub rsa4096 2017-02-22 [S]
2. 安装 Docker Engine-Community
1 | 更新 apt 包索引 |
3. 卸载 docker
1 | 删除安装包: |
4.4 查看 docker 版本
1 | 需要给予sudo权限 |
4.5 阿里云镜像加速
为何配置?
- 国内从 DockerHub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。
- Docker 官方和国内很多云服务商都提供了国内加速器服务,建议根据运行 docker 的云平台选择对应的镜像加速服务。
配置步骤
登录阿里云服务器,找到
容器镜像服务
找到镜像加速器
配置使用
- ```shell
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-‘EOF’
{
“registry-mirrors”: [“https://6nl6ynme.mirror.aliyuncs.com“]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
- 另外可配置多个,如`AZURE` -> `dockerhub.azk8s.cn` (/etc/docker/daemon.json)
## 5\. 底层原理
- 底层原理
- Docker Engine 是一个客户端-服务器应用程序,具有以下主要组件:
- 一个服务器,它是一种长期运行的程序,称为守护进程(dockerd 命令)
- 一个 REST API,它指定程序可以用来与守护进程对话并指示它做什么的接口。
- Docker 是一个**Client Server 结构的系统**,Docker 守护进程运行在主机上,然后通过 Socket 连接从客户 端访问,守护进程从客户端接受命令并管理运行在主机上的容器。**容器,是一个运行时环境就是我们所说的集装箱。**
<img src="https://s2.loli.net/2023/02/27/JStoUsImMv85ALO.png" style="zoom:80%;" />
- 为什么 Docker 比 Vm 快
- docker 有着比虚拟机更少的抽象层。*由于 docker 不需要 Hypervisor 实现硬件资源虚拟化,*运行在 docker 容器上的程序直接使用的都是实际物理机的硬件资源。
- **docker 利用的是宿主机的内核,而不需要 Guest OS**。因此,当新建一个 容器时,docker 不需要和虚拟机一样重新加载一个操作系统内核。避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载 Guest OS,返个新建过程是分钟级别的。**而 docker 由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个 docker 容器只需要几秒钟。**
![](https://img-blog.csdnimg.cn/20200411132454634.png)
## 6. 避免权限问题
```shell
sudo groupadd docker #添加docker用户组
sudo gpasswd -a $USER docker #将登陆用户加入到docker用户组中
newgrp docker #更新用户组
docker ps #测试docker命令是否可以使用sudo正常使用
- ```shell
二、Docker 基本命令
1. Docker 的常用命令
2. 帮助命令
1 | docker版本信息 |
2. 镜像命令
images - 查看所有本地主机上的镜像
1 | bayyy@bayzju:/$ sudo docker images |
search - 查找镜像
1 | 可选项 |
pull - 下拉镜像
1 | 下载镜像 docker pull 镜像名[:tag] |
rmi - 删除镜像
1 | docker rmi -f IMAGE ID # 删除指定镜像 |
3. 容器命令
说明: 我们有了镜像才可创建容器,linux,下载一个 centos 镜像来测试学习
1 | docker pull centos |
新建容器并启动 run
1 | docker run [options] image |
列出所有的运行的容器 ps
1 | docker ps # 列出当前正在运行的容器 |
退出容器 exit
1 | exit # 直接退出容器并关闭 |
删除容器 rm
1 | docker rm 容器id # 删除指定容器,不能删除正在运行的容器 |
启动和停止容器的操作
1 | docker start 容器id # 启动容器 |
4. 常用的其他命令
后台启动容器 docker run -d
1 | 命令 docker run -d 镜像名 |
查看日志 docker log
1 | docker logs -tf --tail number 容器id |
查看容器中进程信息 ps
1 | 命令 docker top 容器id |
查看镜像的元数据 inspect
1 | 命令docker inspect 容器id |
进入当前正在运行的容器 exec / attach
1 | 我们通常容器使用后台方式运行的, 需要进入容器,修改一些配置 |
从容器中拷贝文件到主机 cp
1 | docker cp 容器id:容器内路径 目的地主机路径 |
小结图
1 | attach Attach to a running container # 当前she11下attach连接指定运行镜像 |
三、Docker 部署软件实战
1.Docker 部署软件实战
Docker 安装 Nginx
1 | 1. 搜索镜像 search 建议去docker hub搜索,可以看到帮助文档 |
端口暴露概念
2. Docker 安装 Tomcat
1 | 官方的使用 |
3. Docker 部署 es + kibana
1 | es 暴露的端口很多 |
4. 可视化
portainer(先用这个)
1 | docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer |
Rancher(CI/CD 再用)
三、Docker 原理
1. Docker 镜像加载原理
UnionFS(联合文件系统)
UnionFS(联合文件系统):Union 文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker 镜像加载原理
docker 的镜像实际上由一层一层的文件系统组成,这种层级的文件系统 UnionFS。
- bootfs(boot file system)主要包含 bootloader 和 kernel,bootloader 主要是引导加载 kernel,Linux 刚启动时会加载 bootfs 文件系统,在 Docker 镜像的最底层是 bootfs。这一层与我们典型的 Linux/Unix 系统是一样的,包含 boot 加载器和内核。当 boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 bootfs。
- rootfs(root file system),在 bootfs 之上。包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc 等标准目录和文件。rootfs 就是各种不同的操作系统发行版,比如 Ubuntu,Centos 等等。
对于一个精简的 OS,rootfs 可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用 Host 的 kernel,自己只需要提供 rootfs 就可以。由此可见,对于不同的 linux 发行版,bootfs 基本是一致的,rootfs 会有差别,因此不同的发行版可以公用 bootfs。
2. 分层原理
下载时候的日志输出是一层一层的在下载。
有多个镜像都从相同的 Base 镜像构建而来,那么宿主机只需在磁盘上保留一份 base 镜像,同时内存中也只需要加载一份 base 镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过 docker image inspect 命令 —>
layers
所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。举一个简单的例子,假如基于 Ubuntu Linux16.04 创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python 包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。该镜像当前已经包含 3 个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
Docker 镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
3. commit 镜像
1 | docker commit 提交容器成为一个新的版本 |
实战测试
1 | 1. 启动一个默认的tomcat |
五、容器数据卷
1. 容器数据卷
1.1. docker 的理解回顾
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享技术!Docker 容器中产生的数据,同步到本地!
这就是卷技术,目录的挂载,将我们容器内的目录挂载到 linux 目录上面!
总结: 容器的持久化和同步操作!容器间数据也是可以共享的!
1.2. 使用数据卷
方式一:直接使用命令来挂载 -v
方式二:使用 Dockerfile
1 | docker run -it -v 主机目录:容器目录 |
1.3. 实战:安装 MySQL
思考:MySQL 的数据持久化的问题!
1 | 获取镜像 |
1.4. 匿名和具名挂载
1 | 匿名挂载 |
所有 docker 容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxxx/_data
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用的是具名挂载
1 | 如何确定是具名挂载还是匿名挂载,还是指定路径挂载! |
拓展
1 | 通过 -v 容器内容路径 ro rw 改变读写权限 |
六、DockerFile
初始 DockerFile
DockerFile 就是用来狗之间 docker 镜像的构建文件!命令脚本!先体验一下!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层!
1 | 创建一个dockerfile文件, 名字可以随机 |
1 | 启动自己的容器 |
这个卷和外部一定有一个同步的目录!
测试一下刚才的文件是否同步到主机上了!
这种方式我们未来使用的十分多, 因为我们通常会构建自己的镜像!
假设构建镜像时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径!
数据卷容器
多个 mysql 同步数据!
多个 mysql 实现数据共享
1 | docker run -d -p 3344:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 |
结论
容器之间配置信息的传递, 数据卷容器的声明周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
DockerFile
dockerFile 是用来构建 docker 镜像的文件!命令参数脚本!
构建步骤
编写一个 dockerFile 文件
docker build 构建成为一个镜
docker run 运行镜像
docker push 发布镜像(DockerHub、阿里云镜像)
- 官方:
很多官方镜像都像是基础包,很多功能都不具备,我们通常会自己搭建自己的镜像!
官方既然可以制作镜像,能我们一样可以!
DockerFile 构建过程
基础知识:
- 每个保留关键字(指令)都是必须大写字母
- 执行从上到下顺序执行
#
表示注释- 每个指令都会创建提交一个新的镜像层,并提交!
dockerFile 是面向开发的, 我们以后要发布项目, 做镜像, 就需要编写 dockefile 文件, 这个文件十分简单!
Docker 镜像逐渐成为企业的交互标准,必须要掌握!
步骤:开发,部署, 运维….. 缺一不可!
DockerFile: 构建文件, 定义了一切的步骤,源代码
DockerImages: 通过 DockerFile 构建生成的镜像, 最终发布和运行的产品!
Docker 容器:容器就是镜像运行起来提供服务器
DockerFile 指令说明
1 | FROM # 基础镜像,一切从这里开始构建 |
创建一个自己的 centos
- 给 centos 增加
vim
、ifconfig
等功能
1 | 1. 编写Dockerfile的文件 |
我们可以列出本地进行的变更历史 docker history image_ID
CMD 和 ENTRYPOINT 区别
1 | CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效可被替代 |
七、Dockerfile 制作 tomcat 镜像
准备 Dockerfile
1. 准备镜像文件 tomcat 压缩包,jdk 的压缩包!
2. 编写 Dockerfile 文件,官方命名Dockerfile
, build 会自动寻找这个文件,就不需要-f 指定了!
1 | [root@iZ2zeg4ytp0whqtmxbsqiiZ tomcat]# cat Dockerfile |
生成启动镜像
1. 构建镜像
docker build -t diytomcat .
2. 启动镜像
docker run -d -p 3344:8080 --name xiaofantomcat1 -v /home/xiaofan/build/tomcat/test:/usr/local/apache-tomcat-9.0.37/webapps/test -v /home/xiaofan/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.37/logs diytomcat
3. 访问测试
4. 发布项目(由于做了卷挂载, 我们直接在本地编写项目就可以发布了)
在本地编写 web.xml 和 index.jsp 进行测试
<?xml version="1.0" encoding="UTF-8"?><web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> </web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="utf-8"><title>hello. xiaofan</title></head><body>Hello World!<br/><%System.out.println("-----my test web logs------");%></body></html>
发现:项目部署成功, 可以直接访问 ok!
我们以后开发的步骤:需要掌握 Dockerfile 的编写! 我们之后的一切都是使用 docker 进行来发布运行的!
发布自己的镜像到 Docker Hub
- 确定这个账号可以登录
在我们的服务器上提交自己的镜像
1
2
3
4
5
6
7
8
9push到我们的服务器上
docker push diytomcat
The push refers to repository [docker.io/library/diytomcat]2eaca873a720: Preparing 1b38cc4085a8: Preparing 088ebb58d264: Preparing c06785a2723d: Preparing 291f6e44771a: Preparing denied: requested access to the resource is denied
拒绝
push镜像的问题?
The push refers to repository [docker.io/1314520007/diytomcat]An image does not exist locally with the tag: 1314520007/diytomcat
解决,增加一个tag
docker tag diytomcat 1314520007/tomcat:1.0
发布到阿里云镜像服务上
- 登录阿里云
- 找到容器镜像服务
- 创建命名空间
- 创建容器镜像
- 点击仓库名称,参考官方文档即可
总结
八、Docker 容器互联
1. Docker 网络
链接 Docker0
测试网络 ip addr
三个网络
1 | 问题: docker是如何处理容器网络访问的? |
原理
- 我们每启动一个 docker 容器, docker 就会给 docker 容器分配一个 ip, 我们只要安装了 docker,就会有一个网卡 docker0 桥接模式,使用的技术是 veth-pair 技术!
再次测试 ip addr
- 再启动一个容器测试, 发现又多了一对网卡
1 | 我们发现这个容器带来网卡,都是一对对的 |
我们测试一下 tomcat01 和 tomcat02 之间是否可以 ping 通!
结论:容器与容器之间是可以相互 ping 通的!
绘制一个网络模型图
结论:tomcat01 和 tomcat02 是共用的一个路由器,docker0
所有容器不指定网络的情况下,都是 docker0 路由的,doucker 会给我们的容器分配一个默认的可用 IP
小结
Docker 使用的是 Linux 的桥接,宿主机中是一个 Docker 容器的网桥 docker0.
Docker 中的所有的网络接口都是虚拟的,虚拟的转发效率高!(内网传递文件!)
只要容器删除,对应的网桥一对就没有了!
-- link
思考一个场景,我们编写了一个微服务,database url =ip; 项目不重启,数据 ip 换掉了,我们希望可以处理这个问题,可以按名字来进行访问容器
1 | 通过--link解决网络连通问题 |
其实这个 tomcat03 就是在本地配置了 tomcat02 的配置?
1 | bayyy@bayzju ~/D/t/dockerfile> docker exec -it tomcat3 cat /etc/hosts |
本质探究:—link 就是我们在 hosts 配置中增加了一个 172.17.0.3 tomcat02 f22ed47ed1be
我们现在玩 Docker 已经不建议使用—link 了!
自定义网络!不使用 Docker0!
Docker0 的问题:它不支持容器名链接访问!
- 自定义网络
查看所有的 docker 网络
2.1 网络模式
bridge: 桥接模式,桥接 docker 默认,自己创建的也是用 brdge 模式
none: 不配置网络
host: 和宿主机共享网络
container:容器网络连通!(用的少, 局限很大)
测试
1 | 我们直接启动的命令默认有一个 --net bridge,而这个就是我们的docker0 |
我们自己创建的网络就 ok 了!
在自己创建的网络里面启动两个容器
1 | docker run -d -P --name tomcat01 --net mynet tomcat |
我们自定义的网络 docker 都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络
2.2 好处
- 可以直接通过容器名进行网络连接
- 不同的集群使用不同的网络,保证集群时安全和健康的
- 网络连通
docker network connect net_name container_name
测试打通 tomcat01 和 mynet
1 | docker network connect mynet tomcat01 |
结论:假设要跨网络 操作别人,就要使用 docker network connect 连通…..!
实战:部署 redis
1 | 创建网卡 |
docker 搭建 redis 集群完成!
SpringBoot 微服务打包 Docker 镜像
- 构建 springboot 项目
? IDEA2020 Ultimate 版本激活方案 亲测有效
打包应用
编写 Dockerfile
FROM java:8 COPY *.jar /app.jarCMD [“—server.port=8080”] EXPOSE 8080 ENTRYPOINT [“java”, “-jar”, “/app.jar”]
构建镜像
发布运行!
把打好的 jar 包和 Dockerfile 上传到 linux[root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# lltotal 16140-rw-r—r— 1 root root 16519871 Aug 14 17:38 demo-0.0.1-SNAPSHOT.jar-rw-r—r— 1 root root 122 Aug 14 17:38 Dockerfile # 构建镜像,不要忘了最后有一个点[root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# docker build -t xiaofan666 .Sending build context to Docker daemon 16.52MBStep 1/5 : FROM java:88: Pulling from library/java5040bd298390: Pull complete fce5728aad85: Pull complete 76610ec20bf5: Pull complete 60170fec2151: Pull complete e98f73de8f0d: Pull complete 11f7af24ed9c: Pull complete 49e2d6393f32: Pull complete bb9cdec9c7f3: Pull complete Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9dStatus: Downloaded newer image for java:8 —-> d23bdf5b1b1bStep 2/5 : COPY *.jar /app.jar —-> d4de8837ebf9Step 3/5 : CMD [“—server.port=8080”] —-> Running in e3abc66303f0Removing intermediate container e3abc66303f0 —-> 131bb3917feaStep 4/5 : EXPOSE 8080 —-> Running in fa2f25977db7Removing intermediate container fa2f25977db7 —-> d98147377951Step 5/5 : ENTRYPOINT [“java”, “-jar”, “/app.jar”] —-> Running in e1885e23773bRemoving intermediate container e1885e23773b —-> afb6b5f28a32Successfully built afb6b5f28a32Successfully tagged xiaofan666:latest # 查看镜像[root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZExiaofan666 latest afb6b5f28a32 14 seconds ago 660MBtomcat latest 2ae23eb477aa 8 days ago 647MBredis 5.0.9-alpine3.11 3661c84ee9d0 3 months ago 29.8MBjava 8 d23bdf5b1b1b 3 years ago 643MB # 运行容器[root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# docker run -d -P —name xiaofan-springboot-web xiaofan666fd9a353a80bfd61f6930c16cd92204532bfd734e003f3f9983b5128a27b0375e# 查看运行起来的容器端口(因为我们启动的时候没有指定)[root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESfd9a353a80bf xiaofan666 “java -jar /app.jar …” 9 seconds ago Up 8 seconds 0.0.0.0:32779->8080/tcp xiaofan-springboot-web# 本地访问 1[root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# curl localhost:32779{“timestamp”:”2020-08-14T09:42:57.371+00:00”,”status”:404,”error”:”Not Found”,”message”:””,”path”:”/“}# 本地访问 2[root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# [root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# curl localhost:32779/hellohello, xiaofan# 远程访问(开启阿里云上的安全组哦)
以后我们使用了 Docker 之后,给别人交互的就是一个镜像即可!
九,Docker Compose
Docker Compose
简介
Docker
Dockerfile build 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 什么是服务。
- Run
docker-compose up
and Compose starts and runs your entire app.- 启动项目
作用:批量容器编排
我自己的理解
Compose 是 Docker 官方的开源项目,需要安装!
Dockerfile
让程序在任何地方运行。web 服务、redis、mysql、nginx… 多个容器。 run
Compose
version: '2.0'services: web: build: . ports: - "5000:5000" volumes: - .:/code - logvolume01:/var/log links: - redis redis: image: redisvolumes: logvolume01: {}
docker-compose up 100 个服务
Compose:重要概念
- 服务 services, 容器、应用(web、redis、mysql…)
- 项目 project。 一组关联的容器
安装
下载
官网提供 (没有下载成功)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授权
chmod +x /usr/local/bin/docker-compose
体验(没有测试通过)
地址:https://docs.docker.com/compose/gettingstarted/
python 应用。 计数器。redis!
应用 app.py
Dockerfile 应用打包为镜像
FROM python:3.6-alpineADD . /codeWORKDIR /codeRUN pip install -r requirements.txtCMD ["python", "app.py"] # 官网的用来flask框架,我们这里不用它# 这告诉Docker# 从python3.7开始构建镜像# 将当前目录添加到/code印像中的路径中# 将工作目录设置为/code# 安装Python依赖项# 将容器的默认命令设置为python app.py
Docker-compose yaml 文件(定义整个服务,需要的环境 web、redis) 完整的上线服务!
version: '3.8'services: web: build: . ports: - "5000:5000" volumes: - .:/code redis: image: "redis:alpine"
启动 compose 项目 (docker-compose up)
流程:
- 创建网络
- 执行 Docker-compose.yaml
- 启动服务
yaml 规则
docker-compose.yaml 核心!
https://docs.docker.com/compose/compose-file/#compose-file-structure-and-examples
开源项目:博客
https://docs.docker.com/compose/wordpress/
下载程序、安装数据库、配置….
compose 应用 => 一键启动
- 下载项目(docker-compse.yaml)
- 如果需要文件。Dockerfile
- 文件准备齐全,一键启动项目即可
实战:自己编写微服务上线
编写项目微服务
Dockerfile 构建镜像
FROM java:8 COPY *.jar /app.jarCMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java", "-jar", "/app.jar"]
docker-compose.yml 编排项目
version '3.8'services: xiaofanapp: build: . image: xiaofanapp depends_on: - redis ports: - "8080:8080" redis: image: "library/redis:alpine"
丢到服务器运行 docker-compose up
docker-compose down # 关闭容器 docker-compose up —build # 重新构建
总结:
工程、服务、容器
项目 compose: 三层
- 工程 Project
- 服务
- 容器 运行实例! docker k8s 容器
十,Docker Swarm
Docker Swarm
集群
购买服务器
登录阿里云账号,进入控制台,创建实例
4台服务器2G
到此,我们的服务器购买成功!
四台机器安装 docker
和我们单机安装一样
技巧: xshell 直接同步操作,省时间!
Swarm 集群搭建
-
docker swarm init —help ip addr # 获取自己的 ip(用内网的不要流量) [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker swarm init —advertise-addr 172.16.250.97Swarm initialized: current node (otdyxbk2ffbogdqq1kigysj1d) is now a manager. To add a worker to this swarm, run the following command: docker swarm join —token SWMTKN-1-3vovnwb5pkkno2i3u2a42yrxc1dk51zxvto5hrm4asgn37syfn-0xkrprkuyyhrx7cidg381pdir 172.16.250.97:2377 To add a manager to this swarm, run ‘docker swarm join-token manager’ and follow the instructions.
初始化结点docker swarm init
docker swarm join 加入一个结点!
# 获取令牌docker swarm join-token managerdocker swarm join-token worker
[root@iZ2ze58v8acnlxsnjoulk6Z ~]# docker swarm join --token SWMTKN-1-3vovnwb5pkkno2i3u2a42yrxc1dk51zxvto5hrm4asgn37syfn-0xkrprkuyyhrx7cidg381pdir 172.16.250.97:2377This node joined a swarm as a worker.
把后面的结点都搭建进去
100 台!
- 生成主节点 init
- 加入(管理者,worker)
Raft 协议
双主双从:假设一个结点挂了!其他结点是否可以用!
Raft 协议:保证大多数结点存活才可以使用,只要>1, 集群至少大于 3 台!
实验:
1、将 docker1 机器停止。宕机!双主,另外一个结点也不能使用了!
- 可以将其他结点离开
docker swarm leave
- worker 就是工作的,管理结点操作! 3 台结点设置为了管理结点。
- Docker swarm 集群增加节点
十分简单:集群,可用! 3 个主节点。 > 1 台管理结点存活!
Raft 协议:保证大多数结点存活,才可以使用,高可用!
体会
弹性、扩缩容!集群!
以后告别 docker run!
docker-compose up!启动一个项目。单机!
集群: swarm docker-service
k8s service
容器 => 服务!
容器 => 服务! => 副本!
redis => 10 个副本!(同时开启 10 个 redis 容器)
体验:创建服务、动态扩容服务、动态更新服务
灰度发布(金丝雀发布)
docker run 容器启动! 不具有扩缩容器 docker service 服务! 具有扩缩容器,滚动更新!
查看服务
动态扩缩容
[root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker service update --replicas 3 my-nginx1/3: running [==================================================>] 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker service scale my-nginx=5my-nginx scaled to 5overall progress: 3 out of 5 tasks overall progress: 3 out of 5 tasks overall progress: 3 out of 5 tasks overall progress: 5 out of 5 tasks 1/5: running [==================================================>] 2/5: running [==================================================>] 3/5: running [==================================================>] 4/5: running [==================================================>] 5/5: running [==================================================>] verify: Service converged [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker service scale my-nginx=1my-nginx scaled to 1overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged
移出!docker service rm
docker swarm 其实并不难
只要会搭建集群、会启动服务、动态管理容器就可以了!
概念的总结
swarm
集群的管理和编号,docker 可以初始化一个 swarm 集群,其他结点可以加入。(管理,工作者)
Node
就是一个 docker 结点,多个结点就组成了一个网络集群(管理、工作者)
Service
任务,可以在管理结点或者工作结点来运行。核心,用户访问。
Task
容器内的命令、细节任务!
service
命令 -> 管理 -> api -> 调度 -> 工作结点(创建 Task 容器维护创建!)
服务副本和全局服务
调整 service 以什么方式运行
--mode string Service mode (replicated or global) (default "replicated") docker service create --mode replicated --name mytom tomcat:7 默认的docker service create --mode global --name haha alpine ping www.baidu.com
拓展: 网络模式 “PublishMode”:”ingress”
Swarm:
Overlay:
ingress:特殊的 Overlay 网络!负载均衡的功能!ipvs vip!
[root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker network lsNETWORK ID NAME DRIVER SCOPE74cecd37149f bridge bridge local168d35c86dd5 docker_gwbridge bridge local2b8f4eb9c2e5 host host localdmddfc14n7r3 ingress overlay swarm8e0f5f648e69 none null local [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker network inspect ingress[ { "Name": "ingress", "Id": "dmddfc14n7r3vms5vgw0k5eay", "Created": "2020-08-17T10:29:07.002315919+08:00", "Scope": "swarm", "Driver": "overlay", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "10.0.0.0/24", "Gateway": "10.0.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": true, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "ingress-sbox": { "Name": "ingress-endpoint", "EndpointID": "9d6ec47ec8309eb209f4ff714fbe728abe9d88f9f1cc7e96e9da5ebd95adb1c4", "MacAddress": "02:42:0a:00:00:02", "IPv4Address": "10.0.0.2/24", "IPv6Address": "" } }, "Options": { "com.docker.network.driver.overlay.vxlanid_list": "4096" }, "Labels": {}, "Peers": [ { "Name": "cea454a89163", "IP": "172.16.250.96" }, { "Name": "899a05b64e09", "IP": "172.16.250.99" }, { "Name": "81d65a0e8c03", "IP": "172.16.250.97" }, { "Name": "36b31096f7e2", "IP": "172.16.250.98" } ] }]
其他命令学习方式
Docker Stack
docker-compose 单机部署项目 docker stack 集群部署 # 单机 docker-compose up -d wordpress.yaml# 集群 docker stack deploy wordpress.yaml
Docker Secret
安全!配置密码!证书! [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker secret —help Usage: docker secret COMMAND Manage Docker secrets Commands: create Create a secret from a file or STDIN as content inspect Display detailed information on one or more secrets ls List secrets rm Remove one or more secrets
Docker Config
配置![root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker config —help Usage: docker config COMMAND Manage Docker configs Commands: create Create a config from a file or STDIN inspect Display detailed information on one or more configs ls List configs rm Remove one or more configs