狂神docker学习笔记

狂神docker(基础+进阶)—学习笔记

狂神说docker

三体:弱小和无知不是生存的障碍,傲慢才是。

从基础到进阶,每个视频都有认真看,做笔记和练习,以此篇分享整个学习过程
画图网页

docker学习

  • docker 概述
  • docker 安装
  • docker 命令
    • 镜像命令
    • 容器命令
    • 操作命令
  • docker 镜像
  • 容器数据卷
  • dockerFile
  • docker 网络原理
  • idea整合docker                            ~~~~~~~~~~~~~~~~~~~~~~~~~~                            单机版
  • docker Compose
  • docker Swarm
  • CI\CD Jenkins

Docker 概述

Docker为什么出现?

一款产品:开发--上线  两套环境  应用环境,应用配置
				开发 ---- 运维 
		问题:我在我电脑上可以运行,版本更新,导致服务不可用,对于运维来说,考验十分大
			环境配置十分麻烦,每一个机器都要部署环境(集群redis,ES ,hadoop...)费时费力
			发布一个项目(jar+(redis mysql jdk ES)) 项目能不能都带上环境安装打包
			之前在服务器配置一个应用的环境 redis mysql jdk ES ,配置超麻烦,不能够跨平台,Windows,最后发布到Linux
		传统:开发jar,运维来做
		现在:开发打包部署上线,一套流程做完

		开发APP应用:Java --- apk -- 发布(应用商店)--- 张三使用apk ---安装即可用
		开发运维环境:Java -- jar(环境)--- 打包项目带上环境(镜像) -- (docker仓库:商店)-- 下载我们发布的镜像--直接运行即可

docker给以上问题,提出解决方案
在这里插入图片描述
docker的思想来自于集装箱

	jre -- 多个应用(端口冲突)---原来都是交叉的
	隔离:docker核心思想,打包装箱,每个箱子是相互隔离的
		水果	生化武器
	docker通过隔离机制,可以将服务器利用到极致

本质:所有的技术都是因为出现一些问题,我们需要解决,才去学习

docker的历史

2010年,几个搞IT的年轻人,就在美国成立了一家公司dotCloud
		做一些pass的云计算服务,LXC有关的容器技术
		他们将自己的技术(容器化技术)命名就是docker
	docker刚刚诞生的时候,没有引起行业的注意,dotCloud,就活不下去
2013年,docker开源
		开源
			开放源代码
		docker越来越多的人发现了docker的优点,火了,docker每个月都会更新一个版本
2014年4月9日,docker1.0发布

docker为什么这么火?因为十分轻巧

在容器技术出来之前,我们都是使用虚拟机技术!
虚拟机:在Windows中装一个Vmware,通过这个软件我们开源虚拟出来一台或者多台电脑,笨重
虚拟机也是属于虚拟化技术,docker容器技术,也是一种虚拟化技术

vm:Linux centos原生镜像(一个电脑)   隔离:需要开启多个虚拟机 	几个G	启动:几分钟
docker:隔离,镜像(最核心的环境4m + jdk + mysql)十分的小巧,运行镜像就可以了 		几个M  KB   秒级启动

到现在,所有的开发人员都要会docker

聊聊docker

docker是基于GO语言开发的,开源项目
官网
docker的文档 ( docker的文档是超级详细的)
仓库地址

docker能做什么

之前的虚拟机技术

在这里插入图片描述
虚拟机技术缺点
1. 资源占用十分多
2、冗余步骤多
3、启动很慢

容器化技术

容器化技术不是模拟的一个完整的操作系统
在这里插入图片描述
比较docker和虚拟机技术的不同

  • 传统的虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
  • 容器内的应用是直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便
  • 每个容器间是相互隔离,每个容器内都有一个属于直接的文件系统,互不影响

DevOps(开发、运维)

应用更快速的交付和部署
传统:一堆帮助文档,安装程序
docker:打包镜像发布测试,一键运行
更便捷的升级和扩缩容
使用了docker之后,我们部署应用就和搭积木一样
项目打包为一个镜像,扩展服务器A,服务器B
更简单的系统运维
在容器化之后,我们的开发,测试环境都是高度一致的
更高效的计算资源利用
docker是内核级别的虚拟化,可以在一个物理机上运行多个容器实例,服务器的性能可以被压榨到极致

Docker安装

docker的基本组成

在这里插入图片描述
docker的基本组成

		client					docker_host					repository	
			docker build			docker daemon
			docker pull			containers	  images
			docekr run
			
		客户端					服务器						远程资源库
			构建一个容器			守护进程
			拉取一个容器		容器		镜像
			运行一个容器	

镜像(image):
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务
eg: tomcat镜像===>run==>tomcat01容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)
容器(container):
docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的
启动,停止,删除,基本命令
目前就可以把这个容器理解为一个简易的Linux系统
仓库(repository):
仓库就是存放镜像的地方,分为公有仓库和私有仓库

  • docker hub (默认是国外的)
  • 阿里云 都有容器服务器(配置镜像加速)

安装docker

环境准备

1、Linux基础
2、centos7
3、远程连接服务器

环境查看

# 系统内核是 3.10以上
[root@k2 ~]# uname -r
5.4.194-1.el7.elrepo.x86_64
# 系统版本
[root@k2 ~]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

安装

安装步骤
1、 官方安装参考手册
2、确定是centos7及以上版本
3、yum 安装 gcc相关环境(需要确保 虚拟机可以上外网)

yum -y install gcc 
yum -y install gcc-c++ 

在这里插入图片描述
4、 安装

# 1、卸载旧的版本
yum remove docker \
               docker-client \
               docker-client-latest \
               docker-common \
               docker-latest \
               docker-latest-logrotate \
               docker-logrotate \
               docker-engine
# 2、需要的安装包
yum install -y yum-utils
# 3、设置镜像的仓库
yum-config-manager \
	--add-repo \
	https://download.docker.com/linux/centos/docker-ce.repo  #默认是国外的
	
yum-config-manager \
	--add-repo \
	https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 推荐使用阿里云的,比较快
# 更新yum软件包索引
yum makecache fast
# 4、安装docker   docker-ce 社区版   ee 企业版
yum install docker-ce docker-ce-cli containerd.io
# 5、启动docker
systemctl start docker
# 6、查看是否安装成功
docker version
# 7、hello-world
docker run hello-world
# 8、查看下载的这个 hello-world的镜像
docker images
# 9、卸载docker
	1)卸载依赖
		yum remove docker-ce docker-ce-cli containerd.io
	2)删除资源
		rm -rf /var/lib/docker        docker的默认工作路径
		rm -rf /var/lib/containerd
[root@k2 ~]# yum remove docker \
>                   docker-client \
>                   docker-client-latest \
>                   docker-common \
>                   docker-latest \
>                   docker-latest-logrotate \
>                   docker-logrotate \
>                   docker-engine
已加载插件:fastestmirror
参数 docker 没有匹配
参数 docker-client 没有匹配
参数 docker-client-latest 没有匹配
参数 docker-common 没有匹配
参数 docker-latest 没有匹配
参数 docker-latest-logrotate 没有匹配
参数 docker-logrotate 没有匹配
参数 docker-engine 没有匹配
不删除任何软件包
[root@k2 ~]# yum install -y yum-utils
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.cn99.com
 * elrepo: hkg.mirror.rackspace.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
base                                              | 3.6 kB     00:00     
docker-ce-stable                                  | 3.5 kB     00:00     
elrepo                                            | 3.0 kB     00:00     
extras                                            | 2.9 kB     00:00     
mysql-connectors-community                        | 2.6 kB     00:00     
mysql-tools-community                             | 2.6 kB     00:00     
mysql57-community                                 | 2.6 kB     00:00     
updates                                           | 2.9 kB     00:00     
(1/3): elrepo/primary_db                            | 547 kB   00:00     
(2/3): extras/7/x86_64/primary_db                   | 247 kB   00:00     
(3/3): updates/7/x86_64/primary_db                  |  16 MB   00:39     
软件包 yum-utils-1.1.31-54.el7_8.noarch 已安装并且是最新版本
无须任何处理
[root@k2 ~]# yum-config-manager \
> --add-repo \
> https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
已加载插件:fastestmirror
adding repo from: https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
[root@k2 ~]# yum makecache fast
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.cn99.com
 * elrepo: hkg.mirror.rackspace.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
base                                              | 3.6 kB     00:00     
docker-ce-stable                                  | 3.5 kB     00:00     
elrepo                                            | 3.0 kB     00:00     
extras                                            | 2.9 kB     00:00     
mysql-connectors-community                        | 2.6 kB     00:00     
mysql-tools-community                             | 2.6 kB     00:00     
mysql57-community                                 | 2.6 kB     00:00     
updates                                           | 2.9 kB     00:00     
元数据缓存已建立
[root@k2 ~]# yum install docker-ce docker-ce-cli containerd.io
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.cn99.com
 * elrepo: hkg.mirror.rackspace.com
 * extras: mirrors.cn99.com
 * updates: mirrors.cn99.com
软件包 3:docker-ce-20.10.16-3.el7.x86_64 已安装并且是最新版本
软件包 1:docker-ce-cli-20.10.16-3.el7.x86_64 已安装并且是最新版本
软件包 containerd.io-1.6.4-3.1.el7.x86_64 已安装并且是最新版本
无须任何处理
[root@k2 ~]# systemctl start docker
[root@k2 ~]# docker version
Client: Docker Engine - Community
 Version:           20.10.16
 API version:       1.41
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
[root@k2 ~]# docker images
REPOSITORY    TAG                IMAGE ID       CREATED        SIZE
hello-world   latest             feb5d9fea6a5   8 months ago   13.3kB

配置阿里云镜像加速

1、登录阿里云
登录阿里云–产品与服务–容器服务–容器镜像服务
)
2、找到镜像加速地址
镜像工具–镜像加速器–加速器地址
3、配置使用

# 1、创建目录
sudo mkdir -p /etc/docker
# 2、编写配置文件
sudo tee /etc/docker/daemon.json <<-'EOF'
{
 "registry-mirrors": ["https://qjx6666.mirror.aliyuncs.com"]
}
EOF
# 3、重启服务
sudo systemctl daemon-reload
# 4、重启docker
sudo systemctl restart docker

回顾hello world 流程

在这里插入图片描述

run的运行流程图
在这里插入图片描述

底层原理

docker是怎么工作的?
Docker是一个 Client-Server结构的系统,docker的守护进程运行在主机上,通过socket从客户端访问
DockerServer接收到Docker-Client的指令,就会执行这个命令
在这里插入图片描述
docker为什么比vm快?
1、docker有着比虚拟机更少的抽象层
2、docker利用的是宿主机的内核,VM需要的是Guest OS
在这里插入图片描述
所以说,新建一个容器的时候,docker不需要像虚拟机一样,重新加载一个操作系统内核,避免引导。虚拟机是加载Guest OS,分钟级别的,docker是利用宿主机的操作系统,省略了这个复杂的过程,秒级

在这里插入图片描述

docker的常用命令

帮助命令

docker version      显示docker的版本
docker info			查看docker的系统信息,包括镜像和容器的数量
docker 命令 --help		帮助命令		

命令的帮助文档

或者
[root@k2 ~]# docker images --help

Usage:  docker images [OPTIONS] [REPOSITORY[:TAG]]

List images

Options:
  -a, --all             Show all images (default hides intermediate images)
      --digests         Show digests
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print images using a Go template
      --no-trunc        Don't truncate output
  -q, --quiet           Only show image IDs

镜像命令

docker images 查看所有本地主机上的镜像

[root@k2 ~]# docker images
REPOSITORY    TAG                IMAGE ID       CREATED        SIZE
hello-world   latest             feb5d9fea6a5   8 months ago   13.3kB

# 解释
REPOSITORY		镜像的仓库源
TAG				镜像的标签
IMAGE ID 		镜像的id
CREATED			镜像的创建时间
SIZE			镜像的大小

# 可选项
	-a , --all		列出所有镜像
	-q, --quiet		只显示镜像的id

docker search 搜索镜像
hub搜索镜像

或者
[root@k2 ~]# docker search mysql
NAME                           DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                          MySQL is a widely used, open-source relation…   12635     [OK] 

# 可选项,通过搜索来过滤
--filter=STARS=5000     搜索出来的镜像,STARS大于5000

[root@k2 ~]# docker search redis --filter=STARS=5000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
redis     Redis is an open source key-value store that…   10937     [OK]    

docker pull 下载镜像

[root@k2 ~]# docker pull --help

Usage:  docker pull [OPTIONS] NAME[:TAG|@DIGEST]

Pull an image or a repository from a registry

Options:
  -a, --all-tags                Download all tagged images in the repository
      --disable-content-trust   Skip image verification (default true)
      --platform string         Set platform if server is multi-platform capable
  -q, --quiet                   Suppress verbose output
# 下载镜像 docker pull 镜像名[:tag]
[root@k2 ~]# docker pull mysql
Using default tag: latest		如果不写tag,默认是latest
latest: Pulling from library/mysql
72a69066d2fe: Pull complete 	分量下载,docker image的核心 联合文件系统
93619dbc5b36: Pull complete 
99da31dd6142: Pull complete 
626033c43d70: Pull complete 
37d5d7efb64e: Pull complete 
ac563158d721: Pull complete 
d2ba16033dad: Pull complete 
688ba7d5c01a: Pull complete 
00e060b6d11d: Pull complete 
1c04857f594f: Pull complete 
4d7cfa90e6ea: Pull complete 
e0431212d27d: Pull complete 
Digest: sha256:e9027fe4d91c666666666666666f7738b66666666709
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest		真实地址

# 等价于
docker pull mysql
docker pull docker.io/library/mysql:latest

# 指定版本下载
docker pull mysql:5.7

在这里插入图片描述
docker rmi删除镜像

[root@k2 ~]# docker rmi -f 镜像ID		# 删除指定镜像
[root@k2 ~]# docker rmi -f 镜像ID 镜像ID 镜像ID     删除多个镜像
[root@k2 ~]# docker rmi -f $(docker images -aq)		删除全部镜像	

容器命令

说明:有了镜像才可以创建容器,Linux,下载一个centos镜像来测试学习

[root@k2 ~]# docker pull centos

新建容器并启动

docker run [可选参数] image 

# 参数说明
--name="name"		容器名字   Tomcat01   tomcat02  用来区分容器
-d 					后台方式运行
-it					使用交互方式运行,进入容器查看内容
-P					指定容器的端口,	-P 8080:8080
			-P ip:z主机端口:容器端口
			-P 主机端口:容器端口
			-P 容器端口
			容器端口
-p 					随机指定端口


# 测试,启动并进入容器
[root@k2 ~]# docker run -it mysql /bin/bash		
[root@6ae3c9bb6a51 /]# ls					#	查看容器内的mysql,基础版本,很多命令都是不完整的
bin  boot  dev  docker-entrypoint-initdb.d  entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var					

# 从容器中退回主机
[root@6ae3c9bb6a51 /]# exit
exit
[root@k2 /]# ls
bin   data  etc   lib    media  mydata  proc  run   srv  tmp  var
boot  dev   home  lib64  mnt    opt     root  sbin  sys  usr

列出所有运行的容器

# docker ps 命令
			# 列出当前正在运行的容器
	-a  	# 列出当前正在运行的容器 + 带出历史运行过的容器
	-n=? 	# 显示最近创建的容器
	-q 		# 只显示容器的编号
[root@k2 /]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@k2 /]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS                      PORTS     NAMES
6ae3c9bb6a51   centos         "/bin/bash"              6 minutes ago   Exited (0) 3 minutes ago              adoring_vaughan
1c1c8a07c2ed   feb5d9fea6a5   "/hello"                 14 hours ago    Exited (0) 14 hours ago               quirky_mahavira
[root@k2 /]# docker ps -n=1
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
6ae3c9bb6a51   centos    "/bin/bash"   9 minutes ago   Exited (0) 5 minutes ago             adoring_vaughan
[root@k2 /]# docker ps -aq
6ae3c9bb6a51
1c1c8a07c2ed

退出容器

exit 			# 直接容器停止并退出
ctrl+p+q 	# 容器不停止退出
[root@k2 /]# docker run -it centos /bin/bash
[root@2bc63e25611d /]# [root@k2 /]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
2bc63e25611d   centos    "/bin/bash"   17 seconds ago   Up 17 seconds             competent_almeida

删除容器

docker rm 容器id				删除指定容器,不能删除正在运行的容器,如果强制删除,rm -f
docker rm -f $(docker ps -aq)	删除所有容器
docker ps -a -q|xargs docker rm 删除所有容器
[root@k2 /]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                      PORTS     NAMES
2bc63e25611d   centos         "/bin/bash"              3 minutes ago    Up 3 minutes                          competent_almeida
6ae3c9bb6a51   centos         "/bin/bash"              16 minutes ago   Exited (0) 12 minutes ago             adoring_vaughan
1c1c8a07c2ed   feb5d9fea6a5   "/hello"                 14 hours ago     Exited (0) 14 hours ago               quirky_mahavira
7f40b43e271b   feb5d9fea6a5   "/hello"                 16 hours ago     Exited (0) 16 hours ago               youthful_northcutt
10b62dbb98ac   fe363d9a6ba4   "java -jar /app.jar …"   19 hours ago     Exited (143) 15 hours ago             66-springboot-web
[root@k2 /]# docker rm 2bc63e25611d			# 不能删除正在运行的容器
Error response from daemon: You cannot remove a running container 2bc63e25611dea862ad877730bc87b2dc9ee7bcb5bfb50dc604dc146700f1b41. Stop the container before attempting removal or force remove
[root@k2 /]# docker rm 6ae3c9bb6a51
6ae3c9bb6a51
[root@k2 /]# docker ps -aq
2bc63e25611d
1c1c8a07c2ed
7f40b43e271b
10b62dbb98ac
[root@k2 /]# docker rm -f $(docker ps -aq)
2bc63e25611d
1c1c8a07c2ed
7f40b43e271b
10b62dbb98ac
[root@k2 /]# docker ps -aq

启动和停止容器的操作

docker start 容器id			# 启动容器
docker restart 容器id		# 重启容器
docker stop 容器id			# 停止当前正在运行的容器
docker kill 容器id			# 强制停止当前的容器
[root@k2 /]# docker run -it centos /bin/bash
[root@990384ccba9f /]# exit
exit
[root@k2 /]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@k2 /]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS                      PORTS     NAMES
990384ccba9f   centos    "/bin/bash"   25 seconds ago   Exited (0) 18 seconds ago             funny_elgamal
[root@k2 /]# docker start 990384ccba9f
990384ccba9f
[root@k2 /]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED              STATUS         PORTS     NAMES
990384ccba9f   centos    "/bin/bash"   About a minute ago   Up 7 seconds             funny_elgamal
[root@k2 /]# docker stop 990384ccba9f
990384ccba9f
[root@k2 /]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

常用的其他命令

后台启动容器

# 命令 docker run -d 镜像名 
[root@k2 ~]# docker run -d centos

# 问题docker ps 发现,centos停止了

# 常见的坑,docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
[root@k2 /]# docker run -d centos
ed05d164f186f33599a6fc557632fac4fae02d6ab83e2aaec22ea5cca554640d
[root@k2 /]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@k2 /]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
ed05d164f186   centos    "/bin/bash"   3 minutes ago   Exited (0) 3 minutes ago             condescending_mcnulty
990384ccba9f   centos    "/bin/bash"   8 minutes ago   Exited (0) 7 minutes ago             funny_elgamal

查看日志

docker logs -tf --tail 容器,没有日志

# 自己编写一段shell脚本
[root@k2 /]# docker run -d centos /bin/sh -c "while true;do echo hello;sleep 2;done"

[root@k2 /]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS     NAMES
e705ce9ef994   centos    "/bin/sh -c 'while t…"   About a minute ago   Up About a minute             priceless_lichterman

# 显示日志
--tf 			显示日志
--tail number 	要显示日志条数
[root@k2 /]# docker logs -tf --tail 10 e705ce9ef994 
[root@k2 /]# docker run -d centos /bin/sh -c "while true;do echo hello;sleep 2;done"
e705ce9ef994919a5749b594269ca6fb3dec38d1b1b03aa7b732e42faeb75030 
[root@k2 /]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
e705ce9ef994   centos    "/bin/sh -c 'while t…"   13 seconds ago   Up 12 seconds             priceless_lichterman
[root@k2 /]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS     NAMES
e705ce9ef994   centos    "/bin/sh -c 'while t…"   About a minute ago   Up About a minute             priceless_lichterman
[root@k2 /]# docker logs -tf --tail 10 e705ce9ef994 
2022-05-26T09:42:34.542832791Z hello
2022-05-26T09:42:36.544598561Z hello
2022-05-26T09:42:38.546502476Z hello
2022-05-26T09:42:40.548252395Z hello
^Z
[2]+  已停止               docker logs -tf --tail 10 e705ce9ef994
[root@k2 /]# docker logs -tf  e705ce9ef994 
2022-05-26T09:41:18.474030912Z hello
2022-05-26T09:41:20.476489047Z hello

查看容器中进程信息 ps

# 命令    docker top 容器id
[root@k2 /]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
e705ce9ef994   centos    "/bin/sh -c 'while t…"   8 minutes ago   Up 8 minutes             priceless_lichterman
[root@k2 /]# docker top e705ce9ef994 
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                5624                27182               0                   17:50               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 2
root                27182               27163               0                   17:41               ?                   00:00:00            /bin/sh -c while true;do echo hello;sleep 2;done

查看镜像的元数据

# 命令    docker inspect 容器id

# 测试
[root@k2 /]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                        PORTS     NAMES
e705ce9ef994   centos    "/bin/sh -c 'while t…"   13 minutes ago   Up 13 minutes                           priceless_lichterman
199564832c3e   centos    "/bin/sh -C 'while t…"   14 minutes ago   Exited (127) 14 minutes ago             recursing_lewin
[root@k2 /]# docker inspect e705ce9ef994

在这里插入图片描述
进入当前正在运行的容器

# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置

# 命令 
docker exec -it 容器id bashshell 

# 测试	
[root@k2 /]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
e705ce9ef994   centos    "/bin/sh -c 'while t…"   21 minutes ago   Up 21 minutes             priceless_lichterman
[root@k2 /]# docker exec -it e705ce9ef994 /bin/bash
[root@e705ce9ef994 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@e705ce9ef994 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 09:41 ?        00:00:00 /bin/sh -c while true;do echo hello;sleep 2;done
root       674     0  0 10:03 pts/0    00:00:00 /bin/bash
root       698     1  0 10:03 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 2
root       699   674  0 10:03 pts/0    00:00:00 ps -ef

# 方式二
docker attach 容器id
# 测试
[root@k2 /]# docker attach  e705ce9ef994 
正在执行当前代码.......
[root@k2 ~]# docker rm -f $(docker ps -aq)    # 前面循环没停,直接全停了

docker exec   	# 进入容器后开启一个新的终端,可以在里面操作
docker attach	# 进入容器正在执行的终端,不会启动新的进程

从容器内拷贝文件到主机上

docker cp 容器id:容器内路径 目的的主机路径
[root@k2 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@k2 ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
centos       latest    5d0da3dc9764   8 months ago   231MB
[root@k2 ~]# docker run -it centos /bin/bash
[root@k2 ~]# docker run -it centos /bin/bash
[root@93823941b78c /]# [root@k2 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
93823941b78c   centos    "/bin/bash"   16 seconds ago   Up 15 seconds             romantic_sinoussi
[root@k2 ~]# cd /home/
[root@k2 home]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED              STATUS              PORTS     NAMES
93823941b78c   centos    "/bin/bash"   About a minute ago   Up About a minute             romantic_sinoussi
# 进入容器内部
[root@k2 home]# docker attach 93823941b78c
[root@93823941b78c /]# cd /home/
[root@93823941b78c home]# ls
# 在容器内新建一个文件
[root@93823941b78c home]# touch  test.java
[root@93823941b78c home]# ls
test.java  
[root@93823941b78c home]# exit
exit
[root@k2 home]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@k2 home]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
93823941b78c   centos    "/bin/bash"   3 minutes ago   Exited (0) 7 seconds ago             romantic_sinoussi
# 查看当前主机目录
[root@k2 home]# ls
idea  kuan.java
# 将文件拷贝到主机上
[root@k2 home]# docker cp 93823941b78c:/home/test.java /home/
[root@k2 home]# ls
idea  kuan.java  test.java
拷贝是一个手动过程,未来我们使用-v 卷的技术,可以实现,自动同步  /home  /home 

小结

在这里插入图片描述

attach	 	Attach to a running Container 		# 当前 shell下 attach 连接指定运行镜像
build	 	Build an image from a Dockerfile 	# 通过 Dockerfile 定制镜像
commit	 	Create a new image from a container changes 	# 提交当前容器为新的镜像
cp 		 	Copy files/folders from the containers filesystem to the host path 	# 从容器中拷贝指定文件或目录到宿主机中
create	 	Create a new container				# 创建一个新的容器,同run,但不启动容器
diff	 	Inspect changes on a container's filesystem 	# 查看 docker 容器变化
events	 	Get real time events form the server 	# 从 docker 服务获取容器实时事件
exec 	 	Run a command in an existing container	# 在已存在的容器上运行命令
export	 	Stream the containers of a container as a tar archive 	# 导出容器的内容流作为一个tar 归档文件【对应 import】
history  	show the history of an image		# 展示一个镜像形成历史
images 	 	list images							# 列出系统当前镜像
import	 	create a new filesystem image from the contents of a tarball 	# 从 tar 包中的内容创建一个新的文件系统映像【对应 export】
info	 	display system-wide infomation		# 显示系统相关信息
inspect	 	return low-level infomation on a container		# 查看容器详细信息
kill	 	kill a running container			# kill 指定 docker 容器
load	 	load an image from a tar archive	# 从一个 tar 包中加载一个镜像【对应 save】
login	 	register or login to the docker registry server		# 注册或者登陆一个 docker 源服务器
logout	 	log out from a docker registry server	# 从当前 docker registry退出
logs 	 	fetch the logs of a container		# 输出当前容器日志信息
port 	 	lookup the public-facing port which is NAT-ed to PRIVATE_PORT 	# 查看映射端口对应的容器内部源端口
pause	 	pause all processes within a container		# 暂停容器
ps		 	list containers						# 列出容器列表
pull 	 	pull an image or a repository from the docker registry server	# 从docker镜像源服务器拉取指定镜像或者库镜像
push	 	push an image or a repository to the docker registry server		# 推送指定镜像或者库镜像至docker源服务器
restart	 	restart a running container			# 重启运行的服务器
rm 		 	remove one or more containers		# 移除一个或者多个容器
rmi 	 	remove one or more images			# 移除一个或者多个镜像(无容器使用该镜像才可以删除,否则需删除相关容器才可继续或 -f 强制删除)
run 	 	run a command in a new container	# 创建一个新的容器并运行一个命令
save	 	save an image to a tar archive 		# 保存一个镜像为一个tar包【对应 load】
search 	 	search for an image on the docker hub 		# 在 docker hub 中搜索镜像
start	 	start a stopped container			# 启动容器
stop	 	stop a running container			# 启动容器
tag 	 	tag an image into a repository		# 给源镜像搭标签
top		 	lookup the running processes of a container		# 查看容器中运行的进程信息
unpause	 	unpause a paused container			# 取消暂停容器
version	 	show the docker version infomation		# 查看 docker 版本号
wait 	 	block until a container stops,then print its exit code 		# 截取容器停止时间的退出状态值

docker 的命令是十分多的,上面是最常用的容器和镜像的命令,之后会更多

作业练习

Docker 安装 Nginx

# 1、搜索镜像 search 建议去docker上搜索,可以看到详细信息和帮助文档
[root@k2 ~]# docker search nginx
# 2、下载镜像
[root@k2 ~]# docker pull nginx
# 3、运行测试
[root@k2 ~]# docker images     # 查看镜像
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
nginx         latest    de1111b9436b   36 hours ago   142MB

# -d 后台运行
# --name 给容器命名
# -p 宿主机端口:容器内部端口
[root@k2 ~]# docker run -d --name nginx01 -p 3344:80 nginx
50666666ad4e9e6b9666666666c8ec08666666633
[root@k2 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
50c35333a98   nginx     "/docker-entrypoint.…"   57 seconds ago   Up 57 seconds   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01
[root@k2 ~]# curl localhost:3344

# 查看浏览器 http://IP:3344/

# 进入容器
[root@k3 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
506666e98   nginx     "/docker-entrypoint.…"   38 minutes ago   Up 38 minutes   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01
[root@k3 ~]# docker exec -it nginx01 /bin/bash
root@506666e98:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@5066666e98:/# cd /etc/nginx/
root@5066666e98:/etc/nginx# ls
conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params
root@5066666e98:/etc/nginx# 

# 停止容器
root@503666w98:/etc/nginx# exit
exit
[root@k3 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
506666e98   nginx     "/docker-entrypoint.…"   43 minutes ago   Up 43 minutes   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01
[root@k3 ~]# docker stop 5066666e98
506666e98
# 查看浏览器 http://IP:3344/
[root@k2 home]# docker search nginx
NAME                                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
nginx                                             Official build of Nginx.                        16850     [OK]  
[root@k2 home]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete 
a9edb18cadd1: Pull complete 
589b7251471a: Pull complete 
186b1aaa4aa6: Pull complete 
b4df32aa5a72: Pull complete 
a0bcbecc962e: Pull complete 
Digest: sha256:0d17b56666666669f762b016666653c9b31
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@k2 home]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    605c77e624dd   4 months ago   141MB
[root@k2 home]# 
[root@k2 home]# docker run -d --name nignx01 -p 3344:80 nignx
Unable to find image 'nignx:latest' locally
^Z
[1]+  已停止               docker run -d --name nignx01 -p 3344:80 nignx
[root@k2 home]# docker run -d --name nginx01 -p 3344:80 nginx
781c217839666666665b6243d02249945f64ca03ccffee64
[root@k2 home]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
781c217839cb   nginx     "/docker-entrypoint.…"   8 seconds ago   Up 7 seconds   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01
[root@k2 home]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@k2 home]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
781c217839cb   nginx     "/docker-entrypoint.…"   7 minutes ago   Up 7 minutes   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01
[root@k2 home]# docker exec -it nginx01 /bin/bash
root@781c217839cb:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@781c217839cb:/# cd /etc/nginx/
root@781c217839cb:/etc/nginx# ls
conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params
root@781c217839cb:/etc/nginx# 

端口暴露概念
请添加图片描述
思考:每次修改Nginx配置文件,都要进入容器内,特麻烦?在容器外部提供一个映射路径,达到容器外修改文件,容器内自动修改? -v数据卷

作业:docker装一个Tomcat

# 官方的使用
docker run -it --rm tomcat:9.0
# 我们之前的启动都是后台,停止了容器之后,容器还是可以查到 docker run -it --rm tomcat:9.0,一般用来测试,用完就删除


# 下载再启动
docker pull tomcat

# 启动运行
docker run -d -p 3355:8080 --name tomcat01 tomcat 

# 测试访问没有问题
# IP:3355  访问失败

# 进入容器
 docker exec -it tomcat01 /bin/bash
 ls
# 发现问题:1、Linux命令缺失  2、没有WebApps,阿里云镜像的原因,默认是最小的镜像,所有不必要的都剔除,保证最小可运行的环境
 
[root@k3 ~]#  docker exec -it tomcat01 /bin/bash
root@c95eb14e8fd4:/usr/local/tomcat# 
root@c95eb14e8fd4:/usr/local/tomcat# ls
BUILDING.txt     LICENSE  README.md      RUNNING.txt  conf  logs            temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin          lib   native-jni-lib  webapps  work
root@c95eb14e8fd4:/usr/local/tomcat# cd webapps
root@c95eb14e8fd4:/usr/local/tomcat/webapps# ls
root@c95eb14e8fd4:/usr/local/tomcat/webapps# cd ..
root@c95eb14e8fd4:/usr/local/tomcat# cd webapps.dist/
root@c95eb14e8fd4:/usr/local/tomcat/webapps.dist# ls
ROOT  docs  examples  host-manager  manager
root@c95eb14e8fd4:/usr/local/tomcat/webapps.dist# cd ..
root@c95eb14e8fd4:/usr/local/tomcat# cp -r  webapps.dist/* webapps
root@c95eb14e8fd4:/usr/local/tomcat# cd webapps
root@c95eb14e8fd4:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager

思考:每次部署项目,都要进入容器内,特麻烦?在容器外部提供一个映射路径,webapps

docker 容器 tomcat + 网站

作业:部署es+kibana

# es 暴露的端口很多
# es 十分耗内存
# es 的数据一般需要放置到安全目录,挂载
# --net ? 网络配置

[root@k2 home]# docker network create somenetwork-net
# 启动 elasticsearch
docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2

# 启动了 Linux就卡住了,docker stats 查看CPU状态


# 查看docker stats 
# 赶紧关闭,增加内存的限制

# 赶紧关闭,增加内存的限制,修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch02 --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2


[root@k3 ~]# curl localhost:9200
{
  "name" : "73ca196f0e2b",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "Tp1Ui1grShONIGapLhiwgg",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

作业:使用 kibana连接es ? 思考网络如何才能连接过去
在这里插入图片描述

可视化

  • portainer(先用这个)
docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • Rancher(CI/CD调用)
什么是portainer?

Docker图形化界面管理工具,提供一个后台面板供我们操作

docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

访问测试:外网:8088

docker镜像讲解

镜像是什么

镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

即:所有的应用,直接打包成Docker镜像,就可以直接跑起来!

Docker镜像加载原理

UnionFS(联合文件系统)

Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交,来一层层的叠加。同时可以将不同目录,挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像概念),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

Docker镜像加载原理

Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS(联合文件系统)。

bootfs(boot file system):主要包含bootloader和kernel(Linux内核),bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,而在Docker镜像的最底层也是bootfs这一层,这与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后,整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs(root file system):rootfs在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
在这里插入图片描述

平时我们安装进虚拟机的CentOS系统都是好几个G,为什么Docker这里才200M?

[root@k2 home]# docker images centos
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
centos       latest    5d0da3dc9764   8 months ago   231MB

对于一个精简的OS系统,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用Host(宿主机)的kernel(也就是宿主机或者服务器的boosfs+内核),自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs部分。

这就是我们之前说:虚拟机的启动是分钟级的,容器的启动是秒级的

分层理解

分层的镜像

可以去下载一个镜像,注意观察下载的日志,可以看出是一层一层的在下载
在这里插入图片描述
多个镜像都是从相同的base镜像构建的,宿主机只需要在磁盘上保留一份Base镜像,同时内存中也只需要加载一份Base镜像,就可以应用在所有的容器服务之中了。而且镜像的每一层都可以被共享
使用 docker image inspect可以查看镜像元数据

[root@k2 home]#  docker image inspect redis:latest

加深理解

所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
  举一个简单的例子,假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
  该镜像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在这里插入图片描述
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而整体的镜像包含了来自两个镜像层的6个文件。

在这里插入图片描述

上图中的鏡像层跟之前图中的略有区别,主要目的是便于展示文件。

下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。

在这里插入图片描述
 这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
  Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

如上边的三层镜像,Docker最终会把所有镜像层堆叠并合并,对外提供统一的视图,如下图
在这里插入图片描述

特点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如何提交一个自己的镜像

commit镜像

docker commit 提交容器成为一个新的副本

# 命令和Git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名.[tag]

实战测试

# 1、启动一个默认的tomcat
# 2、发现这个默认的tomcat 是没有webapps应用,镜像的原因,官方的镜像默认webapps 下面是没有文件的
# 3、自己拷贝进去了基本的文件
# 4、将修改后的容器通过commit提交为一个镜像,我们以后使用修改后的镜像即可,这就是修改后的镜像
[root@k3 ~]# docker exec -it tomcat /bin/bash
root@e5fe938049b2:/usr/local/tomcat# 
root@e5fe938049b2:/usr/local/tomcat# ls
BUILDING.txt     LICENSE  README.md      RUNNING.txt  conf  logs            temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin          lib   native-jni-lib  webapps  work
root@e5fe938049b2:/usr/local/tomcat# cd webapps
root@e5fe938049b2:/usr/local/tomcat/webapps# ls
root@e5fe938049b2:/usr/local/tomcat/webapps# cd ..
root@e5fe938049b2:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@e5fe938049b2:/usr/local/tomcat# cd webapps
root@e5fe938049b2:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager  webapps.dist
root@e5fe938049b2:/usr/local/tomcat# exit
exit
[root@k3 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED         STATUS         PORTS                                       NAMES
e5fe938049b2   tomcat    "catalina.sh run"   3 minutes ago   Up 3 minutes   0.0.0.0:3355->8080/tcp, :::3355->8080/tcp   tomcat
[root@k3 ~]# docker commit -a="davina" -m="add webapps app" e5fe938049b2 tomcat02:1.0
sha256:e7ecf7f1a0163db9ce1206e43721bd5a47308e81579d3c8a1dae1da39c390664
[root@k3 ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
tomcat02              1.0       e7ecf7f1a016   24 seconds ago   689MB
tomcat                latest    5eb506608219   36 hours ago     685MB
如果想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们以前学习VM时候,快照

现在才算入门docker!!!

容器数据卷

什么是容器数据卷

docker的理念回顾

将应用和环境打包成一个镜像
数据?   ~  如果数据在容器中,那么容器删除,数据就会丢失       ~~~~~       需求:数据持久化
MySQL,容器删了,删库跑路,     ~~~    需求:MySQL数据可以存储在本地
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!也是目录的挂载,将我们容器内的目录,挂载到Linux上面
在这里插入图片描述
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!

使用数据卷

方式一:直接使用命令来挂载     ~~~     -v

docker run -it -v 主机目录:容器内目录

# 测试
[root@k2 home]# docker run -it -v /home/ceshi:/home centos /bin/bash

# 启动起来时候,我们可以通过 docker inspect 容器id

在这里插入图片描述
测试文件的同步
在这里插入图片描述

再来测试
1、停止容器
2、宿主机上修改文件
3、启动容器
4、容器内的数据依然是同
在这里插入图片描述
好处:我们以后修改只需要在本地修改即可,容器内会自动同步

实战:安装mysql

思考:MYsql的数据持久化的问题

# 获取镜像
docker pull mysql:5.7
# 运行容器,需要做数据挂载 
# 安装启动mysql,需要配置密码
# 官方测试:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=pwd -d mysql:tag

# 启动我们的mysql
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[root@k3 /]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

# 启动成功之后,在本地使用Navicat连接测试一下
连接到服务器的3310 ---- 3310和容器内的3306映射,就可以连接成功
[root@k3 /]# docker pull mysql:5.7
5.7: Pulling from library/mysql
c32ce6654453: Pull complete 
415d08ee031a: Pull complete 
7a38fec2542f: Pull complete 
352881ee8fe9: Pull complete 
b8e20da291b6: Pull complete 
66c2a8cc1999: Pull complete 
d3a3a8e49878: Pull complete 
172aabfba65c: Pull complete 
fea17d0b1d1e: Pull complete 
fff7f5411ca9: Pull complete 
c33d43428e07: Pull complete 
Digest: sha256:16e159331007eccc069822f7b731272043ed572a79a196a05ffa2ea127caaf67
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
[root@k3 /]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED             SIZE
tomcat02              1.0       e7ecf7f1a016   About an hour ago   689MB
tomcat                latest    5eb506608219   37 hours ago        685MB
nginx                 latest    de2543b9436b   42 hours ago        142MB
mysql                 5.7       a3d35804fa37   8 days ago          462MB
portainer/portainer   latest    12b0b8dced14   10 days ago         75.4MB
centos                latest    5d0da3dc9764   8 months ago        231MB
elasticsearch         7.6.2     f29a1ee41030   2 years ago         791MB
[root@k3 /]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
f3cc67b88ff4dbd55e63ec3327985ad7a9c1cdfb4bfefc6ceb7124f7eb123536

假设将容器删除

[root@k3 /]# docker rm -f mysql01
mysql01
[root@k3 /]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED             STATUS             PORTS                                       NAMES
e5fe938049b2   tomcat    "catalina.sh run"   About an hour ago   Up About an hour   0.0.0.0:3355->8080/tcp, :::3355->8080/tcp   tomcat
[root@k3 /]# docker ps -a
CONTAINER ID   IMAGE     COMMAND             CREATED             STATUS                        PORTS                                       NAMES
e5fe938049b2   tomcat    "catalina.sh run"   About an hour ago   Up About an hour              0.0.0.0:3355->8080/tcp, :::3355->8080/tcp   tomcat
[root@k3 mysql]# cd /home/
[root@k3 home]# ll
总用量 0
drwxr-xr-x. 2 root root 23 520 00:08 ceshi
drwxr-xr-x. 4 root root 30 520 00:26 mysql
[root@k3 home]# cd mysql/
[root@k3 mysql]# ll
总用量 4
drwxr-xr-x. 2 root    root    6 520 00:26 conf
drwxr-xr-x. 5 polkitd root 4096 520 00:26 data

发现,我们挂载到本地的数据卷依然没有丢失,这就实现了容器数据持久化功能

具名与匿名挂载

# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx04 -v /etc/nginx nginx

# 查看所有的volume的情况
[root@k3 mysql]# docker volume ls
DRIVER    VOLUME NAME
local     f171cbe47f213b28f4d483d5f70aaaa52e611ef1e5a0cca34375ccc3bd6f5a3e

# 这里发现,这个匿名挂载,在 -v 只写了容器内的路径,没有写容器外的路径

# 具名挂载
[root@k3 mysql]# docker run -d -P --name nginx05 -v juming-nginx:/etc/nginx nginx
78c0aca70fcc020f8daf0e9da4475e3453f8f7be360cc2743f9706e1a48e2880
[root@k3 mysql]# docker volume ls
DRIVER    VOLUME NAME
local     juming-nginx

# 通过 -v 卷名:容器内路径
查看一下这个卷

在这里插入图片描述
所有的docker容器内的卷,没有指定目录的情况下,都是在/var/lib/docker/volumes/xxxxx/_data
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用的具名挂载

[root@k3 mysql]# docker run -d -P --name nginx04 -v /etc/nginx nginx
12b4da52e66666666666666666666666666cd312c197
[root@k3 mysql]# docker volume ls
DRIVER    VOLUME NAME
local     f171cbe47f2136666666666666666cca34375ccc3bd6f5a3e
[root@k3 mysql]# docker run -d -P --name nginx05 -v juming-nginx:/etc/nginx nginx
78c0ac666666666666666666666666643f9706e1a48e2880
[root@k3 mysql]# docker volume ls
DRIVER    VOLUME NAME
local     f171cbe46666666666666666666666cc3bd6f5a3e
local     juming-nginx
# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径 					# 匿名挂载
-v 卷名:容器内路径				# 具名挂载
-v /宿主机路径::容器内路径		# 指定路径挂载

拓展:

# 通过 -v 容器内路径 :ro rw 改变读写权限
ro 	readonly	# 只读
rw 	readwrite	# 可读可写

# 一旦这个设置了容器权限,容器对我们挂载出来的内容就有了限定
docker run -d -P --name nginx05 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx05 -v juming-nginx:/etc/nginx:rw nginx

# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内都是无法操作

初识DockerFile

DockerFile就是用来构建docker镜像的构建文件

通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个一个的命令,每个命令都是一层

# 创建一个dockerfile文件,名字可以随机,建议dockerfile
# 文件中的内容    指令(大写)、参数
FROM centos 

VOLUME ["volume01","volume02"]

CMD echo ".....end...."
CMD /bin/bash
# 这里的每个命令,就是镜像的一层
# 启动自己写的容器

在这里插入图片描述
这个卷和外部一定一个同步的目录
在这里插入图片描述
查看一下卷挂载的路径
在这里插入图片描述

[root@k3 ~]# cd /home/
[root@k3 home]# mkdir docker-test-volume
[root@k3 home]# ll
总用量 0
drwxr-xr-x. 2 root root 23 520 00:08 ceshi
drwxr-xr-x. 2 root root  6 520 21:58 docker-test-volume
drwxr-xr-x. 4 root root 30 520 00:26 mysql
[root@k3 home]# cd docker-test-volume/
[root@k3 docker-test-volume]# vim dockerfile1
[root@k3 docker-test-volume]# cat dockerfile1 
FROM centos 

VOLUME ["volume01","volume02"]

CMD echo ".....end...."
CMD /bin/bash

[root@k3 docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 -t kuangshen/centos:1.0 .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
 ---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01","volume02"]
 ---> Running in 4b2875873838
Removing intermediate container 4b2875873838
 ---> 16f999ab4e62
Step 3/4 : CMD echo ".....end...."
 ---> Running in 2167a8190a0b
Removing intermediate container 2167a8190a0b
 ---> 5c2538632e52
Step 4/4 : CMD /bin/bash
 ---> Running in 96610439a302
Removing intermediate container 96610439a302
 ---> f29e4091c083
Successfully built f29e4091c083
Successfully tagged kuangshen/centos:1.0
[root@k3 docker-test-volume]# vim dockerfile1 
[root@k3 docker-test-volume]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
kuangshen/centos      1.0       f29e4091c083   8 minutes ago   231MB
centos                latest    5d0da3dc9764   8 months ago    231MB
elasticsearch         7.6.2     f29a1ee41030   2 years ago     791MB
[root@k3 docker-test-volume]# docker run -it f29e4091c083 /bin/bash
[root@08e521953b67 /]# ls -l
total 0
lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x.   5 root root 360 May 20 14:13 dev
drwxr-xr-x.   1 root root  66 May 20 14:13 etc
drwxr-xr-x.   2 root root   6 Nov  3  2020 home
lrwxrwxrwx.   1 root root   7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx.   1 root root   9 Nov  3  2020 lib64 -> usr/lib64
drwx------.   2 root root   6 Sep 15  2021 lost+found
drwxr-xr-x.   2 root root   6 Nov  3  2020 media
drwxr-xr-x.   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x.   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x. 288 root root   0 May 20 14:13 proc
dr-xr-x---.   2 root root 162 Sep 15  2021 root
drwxr-xr-x.  11 root root 163 Sep 15  2021 run
lrwxrwxrwx.   1 root root   8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x.   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x.  13 root root   0 May 17 11:08 sys
drwxrwxrwt.   7 root root 171 Sep 15  2021 tmp
drwxr-xr-x.  12 root root 144 Sep 15  2021 usr
drwxr-xr-x.  20 root root 262 Sep 15  2021 var
drwxr-xr-x.   2 root root   6 May 20 14:13 volume01
drwxr-xr-x.   2 root root   6 May 20 14:13 volume02
[root@k3 ~]# docker ps 
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                                       NAMES
08e521953b67   f29e4091c083   "/bin/bash"              9 minutes ago   Up 9 minutes                                               inspiring_golick
e6d17d636007   centos         "/bin/bash"              22 hours ago    Up 22 hours                                                laughing_joliot
[root@k3 ~]# docker inspect 08e521953b67

测试一下,刚才的文件是否同步出去了

这种方式我们未来使用的非常多,因为我们通常会构建自己的镜像

假设构建镜像时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径

数据卷容器

多个mysql同步数据
在这里插入图片描述

# 启动3个容器,通过刚才自己写的镜像启动

在这里插入图片描述

[root@k3 ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED        SIZE
kuangshen/centos      1.0       f29e4091c083   2 hours ago    231MB
centos                latest    5d0da3dc9764   8 months ago   231MB
[root@k3 ~]# docker run -it --name docker01 kuangshen/centos:1.0
[root@438dd0283032 /]# [root@k3 ~]# 
[root@k3 ~]# 
[root@k3 ~]# docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED              STATUS              PORTS                                       NAMES
438dd0283032   kuangshen/centos:1.0   "/bin/sh -c /bin/bash"   About a minute ago   Up About a minute                                               docker01
08e521953b67   f29e4091c083           "/bin/bash"              2 hours ago          Up 2 hours                                                      inspiring_golick
e6d17d636007   centos                 "/bin/bash"              24 hours ago         Up 24 hours                                                     laughing_joliot
[root@k3 ~]# docker run -it --name docker02 --volumes-from docker01 kuangshen/centos:1.0
[root@32faf9bf5a79 /]# 
[root@k3 ~]# docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS         PORTS                                       NAMES
32faf9bf5a79   kuangshen/centos:1.0   "/bin/sh -c /bin/bash"   3 minutes ago   Up 3 minutes                                               docker02
438dd0283032   kuangshen/centos:1.0   "/bin/sh -c /bin/bash"   6 minutes ago   Up 6 minutes                                               docker01
e6d17d636007   centos                 "/bin/bash"              24 hours ago    Up 24 hours                                                laughing_joliot
[root@k3 ~]# 
[root@k3 ~]# 
[root@k3 ~]# docker attach 438dd0283032
[root@438dd0283032 /]# ls -l
total 0
lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x.   5 root root 360 May 20 16:12 dev
drwxr-xr-x.   1 root root  66 May 20 16:12 etc
drwxr-xr-x.   2 root root   6 Nov  3  2020 home
lrwxrwxrwx.   1 root root   7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx.   1 root root   9 Nov  3  2020 lib64 -> usr/lib64
drwx------.   2 root root   6 Sep 15  2021 lost+found
drwxr-xr-x.   2 root root   6 Nov  3  2020 media
drwxr-xr-x.   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x.   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x. 304 root root   0 May 20 16:12 proc
dr-xr-x---.   2 root root 162 Sep 15  2021 root
drwxr-xr-x.  11 root root 163 Sep 15  2021 run
lrwxrwxrwx.   1 root root   8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x.   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x.  13 root root   0 May 17 11:08 sys
drwxrwxrwt.   7 root root 171 Sep 15  2021 tmp
drwxr-xr-x.  12 root root 144 Sep 15  2021 usr
drwxr-xr-x.  20 root root 262 Sep 15  2021 var
drwxr-xr-x.   2 root root   6 May 20 16:12 volume01
drwxr-xr-x.   2 root root   6 May 20 16:12 volume02
[root@438dd0283032 /]# cd volume01
[root@438dd0283032 volume01]# ls
[root@438dd0283032 volume01]# touch docker01.txt
[root@438dd0283032 volume01]# ls
docker01.txt
# 退到宿主机 ctrl+P+Q
[root@k3 ~]# docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS         PORTS                                       NAMES
32faf9bf5a79   kuangshen/centos:1.0   "/bin/sh -c /bin/bash"   6 minutes ago   Up 6 minutes                                               docker02
438dd0283032   kuangshen/centos:1.0   "/bin/sh -c /bin/bash"   9 minutes ago   Up 9 minutes                                               docker01
e6d17d636007   centos                 "/bin/bash"              24 hours ago    Up 24 hours                                                laughing_joliot
[root@k3 ~]# docker attach 32faf9bf5a79
[root@32faf9bf5a79 /]# cd volume01
[root@32faf9bf5a79 volume01]# ls
docker01.txt
[root@32faf9bf5a79 volume01]# 
# 测试,可以删除docker01,查看一下docker02和docker03是否可以访问这个文件
# 测试依然可以访问

在这里插入图片描述

多个MySQL实现数据共享

[root@k3 home]# docker run -d -p 3310:3306 -v /home/mysql/conf -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

[root@k3 home]# docker run -d -p 3310:3306  -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

# 这个时候,可以实现两个容器数据同步

结论:
1、容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止
2、一旦持久化到了本地,本地的数据是不会删除的

DockFile

DockFile介绍

dockerfile是用来构建docker镜像的文件! 就是命令参数脚本
构建步骤:
1、编写一个dockerfile文件
2、docker build 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像(DockerHub、阿里云镜像仓库)

DockFile构建过程

基础知识:
1、每个保留关键字(指令)都必须是大写字母
2、执行从上到下顺序执行
3、# 表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交
在这里插入图片描述
dockerfile是面向开发的,以后发布项目,做镜像,就需要编写dockerfile 文件,这个文件十分简单
Docker镜像逐渐成为企业交付的标准,必须要掌握!
步骤:
开发,部署,运维…缺一不可
DockerFile:构建文件,定义一切的步骤,源代码
DokcerImages:通过dockerFile构建生成的镜像,最终发布和运行的产品
Dokcer容器:容器就是镜像运行起来,提供服务器

DockerFile的指令

FROM 		# 基础镜像,一切从这里开始构建
MAINTAINER	# 镜像是谁写的,姓名+邮箱
RUN			# 镜像构建的是需要运行的命令
ADD			# 步骤:tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR		# 镜像的工作目录
VOLUME		# 挂载的目录
EXPOSE		# 保留端口配置
CMD 		# 指定容器启动时要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT 	# 指定容器启动时要运行的命令,可以追加命令
ONBUILD		# 当构建一个被继承 DockerFile时,就会运行这个指令,触发指令
COPY		# 类似ADD,将文件拷贝到镜像中
ENV			# 构建的时候,设置环境变量

在这里插入图片描述

实战测试

在这里插入图片描述

[root@k3 home]# cd /home
[root@k3 home]# mkdir dockerfile
[root@k3 home]# cd dockerfile
[root@k3 dockerfile]# docker images 
REPOSITORY            TAG       IMAGE ID       CREATED        SIZE
centos                latest    5d0da3dc9764   8 months ago   231MB
[root@k3 dockerfile]# docker run -it centos 
[root@ff53460fa928 /]# pwd
/
[root@ff53460fa928 /]# vim
bash: vim: command not found
[root@ff53460fa928 /]# ifconfig
bash: ifconfig: command not found
[root@ff53460fa928 /]# [root@k3 dockerfile]# 
[root@k3 dockerfile]# vim mydockerfile-centos

创建一个自己的centos

# 1、编写dockerfile的文件
[root@k3 dockerfile]# cat mydockerfile-centos
FROM centos
MAINTAINER davina<12346789@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo ".........end.........."
CMD /bin/bash

# 2、通过这个文件构建镜像
docker build -f mydockerfile-centos -t mycentos:0.1 .
# 命令
docker build -f dockerfile文件路径 -t 镜像名:[tag] .

# 3、测试运行
docker images
docker run -it mycentos:0.1
pwd
ifconfig
vim test 

对比:之前的原生的centos
1、工作目录是根目录
2、添加了一些命令

docker history (IMAGE ID)

CMD 和 ENTRYPOINT 区别

CMD 		# 指定容器启动时要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT 	# 指定容器启动时要运行的命令,可以追加命令

测试cmd

# 1、编写dockerfile文件
vim dockerfile-cmd-test 
FROM centos
CMD ["ls","-a"]

# 2、构建镜像
docker build -f dockerfile-cmd-test -t cmdtest .

# 3、run运行,ls -a 命令生效
docker run ...

# 想追加一个命令   -l 			ls -a 
docker run ... -l

# cmd 的清理下  -l 替换了cmd ["ls","-a"] 命令 ,-l 不是命令,所以报错

测试entrypoint

# 1、编写dockerfile文件
vim dockerfile-entrypoint-test 

FROM centos
ENTRYPOINT ["ls","-a"]

# 2、构建镜像
docker build -f dockerfile-entrypoint-test -t entrypointtest.

# 3、run运行,ls -a 命令生效
docker run ...

# 想追加一个命令   -l 			ls -a 
docker run ... -l

dockerfile中的很多命令都十分相似,需要了解他们的区别,可以对比他们然后测试

实战Tomcat镜像

1、准备镜像文件 tomcat 压缩包,jdk的压缩包
下载 xxxxx.tar.gz
2、编写dockerfile文件,官方命名 Dockerfile , build 会自动寻找这个文件,就不需要 -f
touch readme.txt
vim Dockerfile

FROM centos 
MAINTAINER davina<1234567@qq.com>

COPY  readme.txt /usr/local/readme.txt
ADD jdk-xxx.tar.gz /usr/local/
ADD apache-tomcat-xxx.tar.gz /usr/local/

RUN yum -y install vim 

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdkxxx 
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-xxx
ENV CATALINA_BASH /usr/local/apache-tomcat-xxx
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin 

EXPOSE 8080

CMD /usr/local/apache-tomcat-xxx/bin/startup.sh && tail -F /usr/local/tomcat-xxx/bin/logs/cataline.out

docker build -t diytomcat .
3、构建镜像

docker build -t diytomcat .

docker images
4、启动镜像

docker run -d -p 9090:8080 --name davinatomcat -v /home/davina/build/tomcat/test:/usr/local/apache-tomcat-xxx/webapps/test -v /home/davina/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-xxx/logs diytomcat

5、访问测试

docker exec -it ... /bin/bash 
ll
ls -l

curl localhost:9090

6、发布项目(由于做了卷挂载,直接在本地编写项目就可以发布)

cd /usr/  /test
mkdir WEB-INF
cd WEB-INF
vim web.xml
<?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>

vim index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello.davina</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("......my test web logs ........ " );
%>
</body>
</html>

访问 localhost:9090/test

发现:项目部署成功,可以直接访问

我们以后的开发步骤:需要掌握Dockerfile的编写,之后的一切都是使用docker镜像来发布运行

发布自己的镜像

发布到 DockerHub 上

1、地址 https://hub.docker.com/ 注册自己的账号
2、确定这个账号可以登录
3、在我们的服务器上提交镜像

docker login --help
docker login -u davina 

4、提交自己的镜像

docker push davina/diytomcat:1.0

# push 镜像的问题
# 解决,增加一个 tag 
docker tag [IMAGE ID] push davina/diytomcat:1.0
docker images
docker push davina/diytomcat:1.0

提交的时候,也是按照镜像的层级来提交的

发布到 阿里云上

1、登录阿里云
2、找到容器镜像服务
3、创建命名空间
4、创建容器镜像
5、浏览

小结

在这里插入图片描述

Docker 网络

理解Docker0

清空所有环境

[root@k2 ~]# docker rm -f $(docker ps -aq)
3ef6f9de6ce9
a69d884b5f4b
[root@k2 ~]# docker rmi -f $(docker images -aq)
Untagged: nginx:latest
Untagged: nginx@sha256:2d17cc4981bf1e22a87ef3b3dd20fbb72c3868738e3f307662eb40e2630d4320
Deleted: sha256:de2543b9436b7b0e2f15919c0ad4eab06e421cecc730c9c20660c430d4e5bc47
Deleted: sha256:2deefd67059cad4693c3ec996e7db36c70b4b0aa77d6401ece78f7a6448a976c
Untagged: mysql:5.7
Untagged: mysql@sha256:16e159331007eccc069822f7b731272043ed572a79a196a05ffa2ea127caaf67
Deleted: sha256:2dfc45a2fa416c9a9d8e5eca5507872dce078db1512d7a88d97bfd77381b2e3c
[root@k2 ~]# docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
[root@k2 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

测试

在这里插入图片描述

三个网络

问题,docker 是如何处理容器网络访问的?

[root@k2 /]# docker run -d -P --name tomcat01 tomcat

# 查看容器的内部网络地址	ip addr , 发现容器启动的时候会得到一个 etho$if262 ip地址,docker分配的

[root@k2 /]# docker exec -it tomcat01  ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  ..........
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 

如果 ip addr 报错

[root@k2 /]# docker exec -it tomcat01 ip addr
OCI runtime exec failed: exec failed: unable to start container process: exec: "ip": executable file not found in $PATH: unknown
[root@k2 /]# docker exec -it tomcat01 /bin/bash
root@c33985d3669a:/usr/local/tomcat# 
root@c33985d3669a:/usr/local/tomcat# apt update && apt install -y iproute2
root@c33985d3669a:/usr/local/tomcat# exit
exit
# 思考,Linux 能不能ping通容器内部
[root@k2 /]# ping  172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.050 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.029 ms

# Linux 可以,ping通docker容器内部

原理

1、我们每启动一个docker容器,docker就会给docker容器分配一个ip,只要安装了docker,就会有一个网卡docker0 是桥接模式,使用的技术是evth-pair技术
再次测试 ip addr

[root@k2 /]#  ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group 
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP 
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state 
15: vethbc038f8@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc 

2、再启动一个容器测试,发现又多了一对网卡

[root@k2 /]# docker run -d -P --name tomcat02 tomcat
e8e8c66666666666665e05c8e3bd6db57f3
[root@k2 /]#  ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group 
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP 
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state 
15: vethbc038f8@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc 
17: vetha5232c9@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc 
[root@k2 /]# 

* 我们发现这个容器带来的网卡,都是一对一对的
* evth-pair 就是一对虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
* 正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备
* OpenStac , Docker 容器之间的连接,OVS的连接,都是使用 evth-pair 技术

3、来测试下 Tomcat01 和Tomcat02 是否可以ping通

[root@k2 /]# docker exec -it tomcat02 ping  172.17.0.2

# 结论: 容器和容器之间可以互相ping

如果ping报错

[root@k2 /]# docker exec -it tomcat02 ping  172.17.0.2
OCI runtime exec failed: exec failed: unable to start container process: exec: "ping": executable file not found in $PATH: unknown

[root@k2 /]# docker exec -it tomcat02  /bin/bash
root@e8e8cfbbcd61:/usr/local/tomcat# apt-get update && apt-get install iputils-ping
Hit:1 http://deb.debian.org/debian bullseye InRelease                              
Hit:2 http://deb.debian.org/debian bullseye-updates InRelease                      
Hit:3 http://security.debian.org/debian-security bullseye-security InRelease
Reading package lists... Done                                
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  iputils-ping
0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 49.8 kB of archives.
After this operation, 116 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian bullseye/main amd64 iputils-ping amd64 3:20210202-1 [49.8 kB]
Fetched 49.8 kB in 0s (157 kB/s)     
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package iputils-ping.
(Reading database ... 12909 files and directories currently installed.)
Preparing to unpack .../iputils-ping_3%3a20210202-1_amd64.deb ...
Unpacking iputils-ping (3:20210202-1) ...
Setting up iputils-ping (3:20210202-1) ...
root@e8e8cfbbcd61:/usr/local/tomcat# exit
exit
[root@k2 /]# docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.038 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.042 ms
[root@k2 /]# 

绘制一个网络模型图
在这里插入图片描述
结论:tomcat01 和 tomcat02 是公用的一个路由器,docker0
       ~~~~~~        所有的容器不指定网络的情况下,都是docker0路由的,docker 会给容器分配一个默认的可用ip

小结

Docker 使用的是Linux的桥接,宿主机中是一个Docker容器的网络 Docker0
在这里插入图片描述
Docker 中的所有的网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)
只要容器删除,对应网桥一对就没了

–link

思考一个场景,编写一个微服务,database url=ip; 项目不重启,数据库ip换掉了,希望可以处理这个问题,可以名字来访问容器

[root@k2 /]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known

# 如何可以解决
# 通过 --link 就可以解决网络连接问题
[root@k2 /]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
cb77a58df319ac2410355eb8153e4aaea2ed3c45a9b30d5de39f314b4b427346
[root@k2 /]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.077 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.045 ms

#  反向可以ping通吗?
[root@k2 /]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known

其实 tomcat03就是在本地配置了Tomcat02的配置

# 查看 hosts 配置
[root@k2 /]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3      tomcat02 e8e8cfbbcd61
172.17.0.4      cb77a58df319

本质探究:–link 就是我们在hosts配置中增加了一个 tomcat02映射
我们现在玩docker 已经不建议使用 --link 了
自定义网络,不适用 docker0
docker0 问题:不支持容器名连接访问

自定义网络----容器互联

查看所有的docker网络

[root@k2 /]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
29505cc77bbf   bridge    bridge    local
b7c447beef3a   host      host      local
09316664fa6e   none      null      local

网络模式
bridge :桥接 docker (默认,自己搭建也使用bridge模式)
none : 不配置网络
host: 和宿主机共享网络
container:容器内网络连通
测试

[root@k2 /]# docker rm -f $(docker ps -aq)
9evgtgtge4514
[root@k2 /]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc 
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP>   
3: docker0: <BROADCAST,MULTICAST,UP> mtu 1500 
[root@k2 /]# docker  run -d -P --name tomcat01 --net bridge tomcat
ad18666666666666e622241666666666666666
[root@k2 /]# 
# 我们直接启动的命令  --net bridge ,这个就是我们的docker0
docker  run -d -P --name tomcat01  tomcat
docker  run -d -P --name tomcat01 --net bridge tomcat

# docker0 的特点:是默认的,域名不能访问, --link 可以打通连接

# 可以自定义一个网络
# --driver bridge
# --subnet 192.168.0.0/16 
# --gateway 192.168.0.1 
[root@k2 /]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
74657fc8666666666666666abe68045561ed9
[root@k2 /]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
29505cc77bbf   bridge    bridge    local
b7c447beef3a   host      host      local
74657fc8f106   mynet     bridge    local
09316664fa6e   none      null      local

自己的网络就创建好了

[root@k2 ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "74657fc8f1666666666666661dabe68045561ed9",
        "Created": "2022-05-25T01:48:05.384514751+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16"
                    "gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
[root@k2 ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
fe44da6666666666666664063a4d730849e4
[root@k2 ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
9343d5f57666666666666666917db6666cc7bb5
[root@k2 ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "7465766661dabe6666666666666661ed9",
        "Created": "2022-05-25T01:48:05.384514751+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16"
                     "gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "9343d5f6666666666666cf3821ecc7bb5": {
                "Name": "tomcat-net-02",
                "EndpointID": "1384666666b80d6666669006b9268d9182571",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "fe44da666666666730849e4": {
                "Name": "tomcat-net-01",
                "EndpointID": "ffe7daf5666666666666ad80633e1",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

再次测试ping连接

[root@k2 ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.081 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.056 ms

不使用 --link,也可以ping名字

[root@k2 ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.066 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.042 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.057 ms

我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐平时这样使用网络

好处:
Redis – 不同的集群使用不同的网络,保证集群是安全健康的
mysql – 不同的集群使用不同的网络,保证集群是安全健康的

网络连通

[root@k2 ~]# docker run -d -P --name tomcat03  tomcat
d7a8b6666666666c053ca6666668273
[root@k2 ~]# docker run -d -P --name tomcat04  tomcat
c166666666625b121a66666666092cdb
[root@k2 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                                         NAMES
c1a107b87899   tomcat    "catalina.sh run"   7 seconds ago    Up 6 seconds    0.0.0.0:49161->8080/tcp, :::49161->8080/tcp   tomcat04
d7a8b82d1b95   tomcat    "catalina.sh run"   11 seconds ago   Up 11 seconds   0.0.0.0:49160->8080/tcp, :::49160->8080/tcp   tomcat03
9343d5f57456   tomcat    "catalina.sh run"   29 minutes ago   Up 29 minutes   0.0.0.0:49159->8080/tcp, :::49159->8080/tcp   tomcat-net-02
fe44da7e8adb   tomcat    "catalina.sh run"   30 minutes ago   Up 30 minutes   0.0.0.0:49158->8080/tcp, :::49158->8080/tcp   tomcat-net-01
[root@k2 ~]# docker exec -it tomcat03 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known

在这里插入图片描述
在这里插入图片描述

# 测试打通 tomcat03 - mynet 
[root@k2 ~]# docker network connect mynet tomcat03

# 连通之后就是将 tomcat03 放到 mynet 网络下

# 一个容器,两个ip地址:
# 比如阿里云服务器,一个公网ip,一个私网ip
[root@k2 ~]# docker network connect mynet tomcat03
[root@k2 ~]# docker network inspect mynet 
[
    {
        "Name": "mynet",
        "Id": "74657fc86666666666e68045561ed9",
        "Created": "2022-05-25T01:48:05.384514751+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "9343d5f57456695e566666667bb5": {
                "Name": "tomcat-net-02",
                "EndpointID": "1384f2435fb80d745066666666d9182571",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "d7a8b82d1b956666666b996f9da4349c053ca1dd84f8273": {
                "Name": "tomcat03",
                "EndpointID": "0583fe2ffc6502adef3b766666666ec28761a63b0c6",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            },
            "fe44da7e8adb9616666666668eba22a34063a4d730849e4": {
                "Name": "tomcat-net-01",
                "EndpointID": "ffe7daf5853cb2b66666666666f1ad80633e1",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
# 03连通OK
[root@k2 ~]# docker exec -it tomcat03 ping tomcat-net-01  
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.080 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.056 ms

#  04 依然打不通
[root@k2 ~]# docker exec -it tomcat04 ping tomcat-net-01  
ping: tomcat-net-01: Name or service not known

结论:假设要跨网络操作别人,就需要使用docker network connect 连通

实战:部署Redis集群

在这里插入图片描述
shell脚本

# 创建网卡
docker network create redis --subnet 172.38.0.0/16

# 通过脚本创建六个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; 

docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; 

docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; 

# 创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-rep
licas 1
[root@k2 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED             STATUS             PORTS                                         NAMES
c1a107b87899   tomcat    "catalina.sh run"   34 minutes ago      Up 34 minutes      0.0.0.0:49161->8080/tcp, :::49161->8080/tcp   tomcat04
d7a8b82d1b95   tomcat    "catalina.sh run"   34 minutes ago      Up 34 minutes      0.0.0.0:49160->8080/tcp, :::49160->8080/tcp   tomcat03
9343d5f57456   tomcat    "catalina.sh run"   About an hour ago   Up About an hour   0.0.0.0:49159->8080/tcp, :::49159->8080/tcp   tomcat-net-02
fe44da7e8adb   tomcat    "catalina.sh run"   About an hour ago   Up About an hour   0.0.0.0:49158->8080/tcp, :::49158->8080/tcp   tomcat-net-01
e06d18697809   tomcat    "catalina.sh run"   17 hours ago        Up 17 hours        0.0.0.0:49157->8080/tcp, :::49157->8080/tcp   tomcat01
[root@k2 ~]# docker rm -f $(docker ps -aq)
c1a107b87899
d7a8b82d1b95
9343d5f57456
fe44da7e8adb
e06d18697809
[root@k2 ~]# docker network create redis --subnet 172.38.0.0/16
134b86666666695f576666666666beed
[root@k2 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
29505cc77bbf   bridge    bridge    local
b7c447beef3a   host      host      local
74657fc8f106   mynet     bridge    local
09316664fa6e   none      null      local
134b8cc63439   redis     bridge    local
[root@k2 ~]# docker network inspect redis
[
    {
        "Name": "redis",
        "Id": "134b8cc666666666666666d15c70d6beed",
        "Created": "2022-05-25T18:30:05.797037488+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.38.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
[root@k2 ~]# for port in $(seq 1 6); \
> do \
> mkdir -p /mydata/redis/node-${port}/conf
> touch /mydata/redis/node-${port}/conf/redis.conf
> cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
> port 6379
> bind 0.0.0.0
> cluster-enabled yes
> cluster-config-file nodes.conf
> cluster-node-timeout 5000
> cluster-announce-ip 172.38.0.1${port}
> cluster-announce-port 6379
> cluster-announce-bus-port 16379
> appendonly yes
> EOF
> done
[root@k2 ~]# cd /mydata/redis/
[root@k2 redis]# ls
node-1  node-2  node-3  node-4  node-5  node-6
[root@k2 redis]# cd node-1/conf/
[root@k2 conf]# cat redis.conf 
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.11
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
[root@k2 conf]# docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
> -v /mydata/redis/node-1/data:/data \
> -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
> -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; 
Unable to find image 'redis:5.0.9-alpine3.11' locally
5.0.9-alpine3.11: Pulling from library/redis
cbdbe7a5bc2a: Pull complete 
dc0373118a0d: Pull complete 
cfd369fe6256: Pull complete 
3e45770272d9: Pull complete 
558de8ea3153: Pull complete 
a2c652551612: Pull complete 
Digest: sha256:83a3af3666664ba86ad966666e35d0
Status: Downloaded newer image for redis:5.0.9-alpine3.11
693f88a5f666666666611ea8a669d2494666666a900f
[root@k2 conf]# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS          PORTS                                                                                      NAMES
693f88a5f828   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   11 seconds ago   Up 10 seconds   0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp   redis-1
.....
[root@k2 conf]# docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
> -v /mydata/redis/node-6/data:/data \
> -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
> -d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; 
51a543266666666666b3abf0
[root@k2 conf]# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED              STATUS              PORTS                                                                                      NAMES
51a54321333f   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   21 seconds ago       Up 20 seconds       0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp   redis-6
d7a37b7e1e49   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About a minute ago   Up 59 seconds       0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp   redis-5
359020af8325   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp   redis-4
37e7191b1760   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp   redis-3
6d4da93dbfc3   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   3 minutes ago        Up 3 minutes        0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp   redis-2
693f88a5f828   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   8 minutes ago        Up 8 minutes        0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp   redis-1
[root@k2 conf]# docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof  nodes.conf
/data # redis-cli -cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-repl
icas 1
Unrecognized option or bad number of args for: '-cluster'
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-rep
licas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: 7c7366666666641ae0dca 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: ef6666666666b4d5 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: d5d2666666dcbd39c 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: d966666666b18979c 172.38.0.14:6379
   replicates d5d23736666666c7e9666bd39c
S: 72588966666b44e 172.38.0.15:6379
   replicates 7c73d5e6666666666666666dca
S: 2a03a4d0db1aaa49c9e0003eb6b2831ec11b30ee 172.38.0.16:6379
   replicates ef9977666666666d5
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: 7c7366666666666666666dca 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: ef66666666e266666666b4d5 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 2a03666666666666666630ee 172.38.0.16:6379
   slots: (0 slots) slave
   replicates ef997769c6666666666666664d5
S: 72666666662666666666664e 172.38.0.15:6379
   slots: (0 slots) slave
   replicates 7c73d6666666666666666666dca
S: d9e06666666666666666679c 172.38.0.14:6379
   slots: (0 slots) slave
   replicates d5d23666666666666666666669c
M: d5666666666666666666d39c 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

进入集群,插数据

/data # redis-cli -c
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:908
cluster_stats_messages_pong_sent:894
cluster_stats_messages_sent:1802
cluster_stats_messages_ping_received:889
cluster_stats_messages_pong_received:908
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:1802
127.0.0.1:6379> cluster nodes
ef996666666fee6b4d5 172.38.0.12:6379@16379 master - 0 1653477040000 2 connected 5461-10922
2a03a4d066666661b30ee 172.38.0.16:6379@16379 slave ef9666666e6b4d5 0 1653477041517 6 connected
7c73d5e6666666dd66dca 172.38.0.11:6379@16379 myself,master - 0 1653477041000 1 connected 0-5460
7256666666d92f664e 172.38.0.15:6379@16379 slave 7c66661666660dca 0 1653477040717 5 connected
d9e66666979c 172.38.0.14:6379@16379 slave d5d236666666d39c 0 1653477041000 4 connected
d5d2666666bd39c 172.38.0.13:6379@16379 master - 0 1653477041724 3 connected 10923-16383
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK

另开一个窗口,停了redis-3

[root@k2 ~]# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS          PORTS                                                                                      NAMES
51a54321333f   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   16 minutes ago   Up 16 minutes   0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp   redis-6
d7a37b7e1e49   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   16 minutes ago   Up 16 minutes   0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp   redis-5
359020af8325   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   17 minutes ago   Up 17 minutes   0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp   redis-4
37e7191b1760   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   17 minutes ago   Up 17 minutes   0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp   redis-3
6d4da93dbfc3   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   18 minutes ago   Up 18 minutes   0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp   redis-2
693f88a5f828   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   24 minutes ago   Up 24 minutes   0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp   redis-1
[root@k2 ~]# docker stop redis-3
redis-3

docker搭建Redis集群完成

172.38.0.13:6379> get a
^Z[1]+  Stopped                    redis-cli -c
/data # redis-cli -c
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
172.38.0.14:6379> cluster nodes
2a66664d066666661b30ee 172.38.0.16:6379@16379 slave ef666666632410bd666664d5 0 1653477295000 6 connected
725866666925666666666e 172.38.0.15:6379@16379 slave 7c73d66666666666666666ca 0 1653477295280 5 connected
ef99766666666666666666 172.38.0.12:6379@16379 master - 0 1653477295000 2 connected 5461-10922
7c666666666666666666ca 172.38.0.11:6379@16379 master - 0 1653477296284 1 connected 0-5460
d56666666666666666d39c 172.38.0.13:6379@16379 master,fail - 1653477160569 1653477159000 3 connected
d9e0666666666666666666 172.38.0.14:6379@16379 myself,master - 0 1653477296000 7 connected 10923-16383
172.38.0.14:6379> 

我们使用docker之后,所有的技术都会慢慢的变得简单起来

idea整合docker

SpringBoot微服务打包Docker镜像

1、构建springboot项目
idea – Spring Initializr --下一步–Web (Spring Web)-- 完成
!](https://img-blog.csdnimg.cn/f9cadfa0001e4db69d2d3c22c73d2940.png)

#  依赖
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </dependency>
    </dependencies>
package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

 @RequestMapping("/hello")
 public String hello(){
     return "hello,davina";
 }
}

运行后,查看网页
在这里插入图片描述
2、打包应用
在这里插入图片描述
3、编写dockerfile

# demo -- 新建 --文件-- Dockerfile 输入如下
FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]

在这里插入图片描述

# 上传到Linux里
[root@k2 ~]# cd /home/
[root@k2 home]# ls
[root@k2 home]# mkdir idea
[root@k2 home]# ll
总用量 0
drwxr-xr-x. 2 root root 6 5月  25 21:39 idea
[root@k2 home]# cd idea/
[root@k2 idea]# ll
总用量 18060
-rw-r--r--. 1 root root 18487524 5月  25 21:43 demo-0.0.1-SNAPSHOT.jar
-rw-r--r--. 1 root root      122 5月  25 21:43 Dockerfile

4、构建镜像

[root@k2 idea]# docker build -t davina .
Sending build context to Docker daemon  18.49MB
Step 1/5 : FROM java:8
8: Pulling from library/java
5040bd298390: 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:c1ff613e8b666618156666666669d
Status: Downloaded newer image for java:8
 ---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
 ---> 814def847a05
Step 3/5 : CMD ["--server.port=8080"]
 ---> Running in c54e95b1fb61
Removing intermediate container c54e95b1fb61
 ---> c8b5a40794dc
Step 4/5 : EXPOSE 8080
 ---> Running in cdee05e19fea
Removing intermediate container cdee05e19fea
 ---> 9cce71680080
Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]
 ---> Running in 945e2c80dfd5
Removing intermediate container 945e2c80dfd5
 ---> fe363d9a6ba4
Successfully built fe363d9a6ba4
Successfully tagged davina:latest
[root@k2 idea]# docker images
REPOSITORY   TAG                IMAGE ID       CREATED          SIZE
davina       latest             fe363d9a6ba4   18 seconds ago   662MB
tomcat       latest             5eb506608219   7 days ago       685MB
redis        5.0.9-alpine3.11   3661c84ee9d0   2 years ago      29.8MB
java         8                  d23bdf5b1b1b   5 years ago      643MB

5、发布运行

[root@k2 idea]# docker run -d -P --name 66-springboot-web davina
10b66666666666666666666666666660b83
[root@k2 idea]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                         NAMES
10b62dbb98ac   davina    "java -jar /app.jar …"   13 seconds ago   Up 13 seconds   0.0.0.0:49163->8080/tcp, :::49163->8080/tcp   66-springboot-web
[root@k2 idea]# curl localhost:49163
{"timestamp":"2022-05-25T13:48:59.919+00:00","status":404,"error":"Not Found","path":"/"}[root@k2 idea]# curl localhost:49163/hello
hello,davina[root@k2 idea]# 

我们使用docker之后,交付给别人一个镜像即可

------------------------------------------Docker 下半场----------------------------------------------

Docker Compose

Docker
DockerFile build run 手动操作,单个容器
微服务,100个微服务,还有依赖关系
Docker Compose 轻松高效的管理容器,定义运行多个容器

官方介绍

https://docs.docker.com/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.

三个步骤:
1、 DockerFile 保证我们的项目在任何地方可以运行
2、 services 什么是服务
       ~~~~~~       docker-compose.yml 这个文件怎么写
3、启动项目

Using Compose is basically a three-step process:

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.

  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.

  3. Run docker compose up and the Docker compose command starts and runs your entire app. You can alternatively run docker-compose up using the docker-compose binary.

作用:批量容器编排

理解

Compose 是Docker官方的开源项目,需要安装
DockerFile 让程序在任何地方运行

docker-compose.yml 模板

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 up 100个服务

compose:重要的概念

  • 服务 services,容器 应用 (web、Redis 、mysql …)
  • 项目 project 一组关联的容器

安装

https://docs.docker.com/compose/install/
1、下载

 curl -SL https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-$(uname -s)-$(uname -m) -o  /usr/local/bin/docker-compose

# 这个可能快点
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.5.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

报错 curl: (35) Encountered end of file

[root@k2 ~]#  DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
[root@k2 ~]#  mkdir -p $DOCKER_CONFIG/cli-plugins
# 下载报错
[root@k2 ~]#  curl -SL https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:02:00 --:--:--     0
curl: (35) Encountered end of file
# 1、查看防火墙状态
[root@k2 ~]# firewall-cmd --state	
not running
# 2、开启防火墙
[root@k2 ~]# systemctl start firewalld.service
# 再次查看防火墙状态
[root@k2 ~]# firewall-cmd --state
running
# 3、开启端口(以端口443为例)
[root@k2 ~]# firewall-cmd --zone=public --add-port=443/tcp --permanent
success
# 4、重启防火墙
[root@k2 ~]# systemctl restart firewalld.service
# 5、重新载入防火墙
[root@k2 ~]# firewall-cmd --reload
success
# 6、查看已开启的端口
[root@k2 ~]# firewall-cmd --list-ports
443/tcp
# 再次下载
[root@k2 ~]#  curl -SL https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 25.2M  100 25.2M    0     0  3838k      0  0:00:06  0:00:06 --:--:-- 4797k

在这里插入图片描述
2、授权

sudo chmod +x /usr/local/bin/docker-compose 

在这里插入图片描述

体验

地址:https://docs.docker.com/compose/gettingstarted/

1、应用 app.py
2、Dockerfile 应用打包为镜像
3、docker-compose.yml 文件 (定义整个服务,需要的环境,比如:web、Redis)完整的上线服务
4、启动 compose 项目(docker-compose up)

[root@k2 bin]# curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   423  100   423    0     0    555      0 --:--:-- --:--:-- --:--:--   555
100 16.7M  100 16.7M    0     0  4641k      0  0:00:03  0:00:03 --:--:-- 6810k
[root@k2 bin]# cd /usr/local/bin/
[root@k2 bin]# ll
总用量 17176
-rw-r--r--. 1 root root 17586312 528 00:55 docker-compose
[root@k2 bin]# sudo chmod +x docker-compose
[root@k2 bin]# docker-compose version
docker-compose version 1.25.5, build 8a1c60f6
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019
[root@k2 bin]# cd /home/
[root@k2 home]# ll
总用量 0
drwxr-xr-x. 2 root root 88 528 00:55 composetest
[root@k2 home]# cd composetest/
[root@k2 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)
[root@k2 composetest]# cat requirements.txt 
flask
redis
[root@k2 composetest]# cat Dockerfile 
# syntax=docker/dockerfile:1
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
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
[root@k2 composetest]# cat docker-compose.yml 
version: "3"
services:
  web:
    build: .
    ports:
      - "8000:5000"
  redis:
    image: "redis:alpine"
[root@k2 composetest]# ll
总用量 16
-rw-r--r--. 1 root root 514 528 01:01 app.py
-rw-r--r--. 1 root root 109 528 01:04 docker-compose.yml
-rw-r--r--. 1 root root 281 527 19:05 Dockerfile
-rw-r--r--. 1 root root  12 527 19:04 requirements.txt
[root@k2 composetest]# docker-compose up
[root@k2 composetest]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED      STATUS      PORTS                                       NAMES
0b66dd46c747   redis:alpine      "docker-entrypoint.s…"   2 days ago   Up 2 days   6379/tcp                                    composetest_redis_1
0b9e54ee12f6   composetest_web   "flask run"              2 days ago   Up 2 days   0.0.0.0:8000->5000/tcp, :::8000->5000/tcp   composetest_web_1
[root@k2 composetest]# curl localhost:8000
Hello World! I have been seen 1 times.
[root@k2 composetest]# curl localhost:8000
Hello World! I have been seen 2 times.
[root@k2 composetest]# curl localhost:8000
Hello World! I have been seen 3 times.
[root@k2 composetest]# curl localhost:8000
Hello World! I have been seen 4 times.

报错

Creating network "composetest_default" with the default driver
ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule:  (iptables failed: iptables --wait -t nat -I DOCKER -i br-88260d8bd489 -j RETURN: iptables: No chain/target/match by that name.
 (exit status 1))

原因是关闭防火墙之后docker需要重启,执行以下命令重启docker即可

[root@k2 composetest]# service docker restart
docker ps
如果启动的只有一个,或者没有,重新启动
docker-compose build
docker-compose up 
docker ps

流程:
1、创建网络 Creating network
2、执行 docker-compose.yml
3、启动服务
docker-compose.yml

Creating composetest_web_1 … done
Creating composetest_redis_1 … done
在这里插入图片描述

1、文件名 composetest
2、服务
在这里插入图片描述
docker images
在这里插入图片描述

[root@k2 composetest]# 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.

3、网络规则
在这里插入图片描述
10个服务 => 项目(项目中的内容都在同个网络下,域名访问)
[root@k2 ~]# docker network inspect composetest_default
在这里插入图片描述
如果在同一个网络下,我们可以直接通过域名访问 HA

停止(在当前文件composetest目录下):
docker-compose stop 或者 ctrl+c

以前都是单个 docker run 启动容器
docker-compose ,通过docker-compose 编写yaml配置文件,可以通过compose 一键启动所有服务,停止

快速开始
通过docker compose 上构建一个简单的python web 应用程序,该应用程序使用flask框架并在Redis中维护一个计数器,用来记录该web应用被访问的次数
1、准备工作

yum install python-pip 	# pip 是 python 包管理工具
yum -y install epel-release 	# 报错的话执行

2、为项目创建目录

mkdir composetest
cd composetest

3、在项目目录中创建另一个名为 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
4、在项目目录中创建另一个名为requirements.txt 的文件,内容

flask
redis

5、在项目目录中创建另一个名为Dockerfile 的文件

FROM python:3.7-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

# 这告诉docker
从python:3.7 映像开始构建映像
将当前目录添加到 /code 映像中的路径中
将工作目录设置为 /code
安装 python 依赖项
将容器的默认命令设置为 python,app.py

6、在项目目录中创建另一个名为docker-compose.yml 的文件

version: "3"
services:
  web:
    build: .
    ports:
      - "8000:5000"
	volumes:
	  - .:/code
  redis:
    image: "redis:alpine"
	
# 此compose文件定义了两个服务,web和Redis
使用从Dockerfile 当前目录中构建的图像
将容器上的公开端口5000 转发到主机上的端口8000。 我们使用flack web 服务器的默认端口5000
该Redis服务使用从 docker hub 注册表中提取的公共Redis映像

7、使用compose构建和运行应用程序,在项目目录中,通过运行 docker-compose up 启动应用程序
docker-compose up

8、查看
docker ps

9、访问
curl localhost:8000
在这里插入图片描述

默认的服务名是:文件名_服务名_num
多个服务器 ,集群模式 , _num 是副本数量
启动服务,比如Redis服务 => 4个副本
未来是集群状态,服务都不可能只有一个运行实例,都会是弹性的,10个副本,都可用 HA 高并发
kubectl service 负载均衡

docker 小结:
1、docker 镜像,run=> 容器
2、dockerfile 构建镜像(服务打包)
3、docker-compose 启动项目(编排、多个微服务/环境)
4、docker 网络

yaml 规则
https://docs.docker.com/compose/compose-file/compose-file-v3/

yaml 是docker-compose 的核心

# 只有3层

version: "" 	# 版本
services:		# 服务
	服务1:web
		# 服务配置
		images
		build
		network
		....
	服务2:redis
		....
	服务3:redis
		....
# 其他配置 网络/卷、全局规则
volumes:
networks:
configs:

在这里插入图片描述

开源项目

博客
下载程序、安装数据库、配置 …
compose 应用 => 一键启动
1、下载项目(docker-compose.yml)
2、如果想要文件:dockerfile
3、文件准备齐全(直接一键启动项目)

https://docs.docker.com/samples/wordpress/

[root@k2 home]# cd /home/my_wordpress/
[root@k2 my_wordpress]# ll
总用量 4
-rw-r--r--. 1 root root 641 530 22:50 docker-compose.yml
[root@k2 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
    volumes:
      - wordpress_data:/var/www/html
    ports:
      - "8001:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  wordpress_data: {}
[root@k2 my_wordpress]# docker-compose up
网页访问
http://localhost:8001/

在这里插入图片描述
前面是,前台启动
后台启动
docker -d
docker-compose up -d
在这里插入图片描述
掌握:docker 基础,原理,网络,服务,集群模式,错误排查,日志查看
Linux docker k8s

实战

idea – Spring Initializr – Web(Spring Web),NoSQL(Spring Data Redis(Access+Driver))

1、编写项目微服务
在这里插入图片描述

# 1、编写HelloController 
package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @Autowired
    StringRedisTemplate RedisTemplate;

    @GetMapping("/hello")
    public String hello(){
        Long views = RedisTemplate.opsForValue().increment("views");
        return "hello,davina,views:"+views;

    }
}

# 2、编写application.properties
server.port=8080
spring.redis.host=redis

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.3'
services:
  davinaapp:
    build: .
    image: davinaapp
    depends_on:
      - redis
    ports:
    - "8080:8080"
  redis:
    image: "library/redis:alpine"

打jar包
在这里插入图片描述

4、丢到服务器
在这里插入图片描述

[root@k2 weifuwu]# ll
总用量 27048
-rw-r--r--. 1 root root 27686082 5月  31 00:13 demo1-0.0.1-SNAPSHOT.jar
-rw-r--r--. 1 root root      185 5月  31 00:13 docker-compose.yml
-rw-r--r--. 1 root root      120 5月  31 00:13 Dockerfile
[root@k2 weifuwu]# docker-compose up

http://ip:8080/hello

在这里插入图片描述
假设项目要重新部署打包

docker-compose up --build  # 重新构建

小结:
未来公司只要有 docker-compose 文件,按照这个规则,启动编排容器
公司: docker-compose ,直接启动
网上开源项目:docker-compose 一键搞定

总结:
工程、服务、容器

项目 compose :三层

  • 工程 project
  • 服务 服务
  • 容器 运行实例

Docker Swarm

购买服务器

集群方式去部署,4台阿里云服务器, 2核 4g

4台机器安装docker

和单机安装一样
技巧:shell同步操作(安装docker,配置阿里云镜像加速)

添加链接描述

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.
在这里插入图片描述

If you haven’t already, read through the swarm mode overview and key concepts.

搭建集群

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

docker swarm init --advertise-addr ip在这里插入图片描述初始化节点 docker swarm initdocker swarm join 加入一个节点

# 获取令牌
docker swarm join-token manager
docker swarm join-token worker
[root@k1 ~]# docker swarm init --advertise-addr 192.168.12.30
Swarm initialized: current node (twa2sqmjfhjf9ct4tve0s1c2f) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-3zscv60kuxs1w73666666666gtlfz8k 192.168.12.30:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

[root@k2 ~]#docker swarm join --token SWMTKN-1-3zscv60kuxs1w73666666666gtlfz8k 192.168.12.30:2377
This node joined a swarm as a worker.

[root@k3 ~]# docker swarm join --token SWMTKN-1-3zscv60kuxs1w73666666666gtlfz8k 192.168.12.30:2377
This node joined a swarm as a worker.
[root@k1 ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-3zscv6666666666666666ofit8j1a8666wvs 192.168.12.30:2377
[root@k4 ~]# docker swarm join --token SWMTKN-1-3zscv6666666666666666ofit8j1a8666wvs 192.168.122.30:2377
This node joined a swarm as a manager.
[root@k1 ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
tw66666666s1c2f *   k1         Ready     Active         Leader           20.10.16
twi666666s88fv4ai   k2         Ready     Active                          20.10.16
xkd66666665aefh     k3         Ready     Active                          20.10.16
4dh66666666e55y     k4         Ready     Active         Reachable        20.10.16

1、生成主节点 init
2、加入(管理者、worker)

目标:双主双从

Raft协议

双主双从:假设一个节点挂了,其他节点是否可以用
Raft协议:保证大多数节点存活才可以用 >1 集群至少>3台
实验:
1、将docker1机器停止,宕机。双主,另一个主节点也不能使用

[root@k1 ~]# systemctl stop docker
Warning: Stopping docker.service, but it can still be activated by:
  docker.socket
[root@k1 ~]# 
[root@k4 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@k4 ~]# docker swarm join --token SWMTKN-1-3zsc33333u666666666j1a8e86d69jcowuwvs 192.168.12.30:2377
Error response from daemon: This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one.
[root@k4 ~]# docker node ls
Error response from daemon: rpc error: code = Unknown desc = The swarm does not have a leader. It's possible that too few managers are online. Make sure more than half of the managers are online.
[root@k1 ~]# systemctl start docker
[root@k1 ~]# docker node ls

2、可以将其他节点离开

[root@k2 ~]# docker swarm leave
Node left the swarm.
[root@k2 ~]# 
[root@k1 ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
tw66666666661c2f *   k1         Ready     Active         Reachable        20.10.16
tw666666688fv4ai     k2         Down      Active                          20.10.16
xk6666666666aefh     k3         Ready     Active                          20.10.16
4dh666666665e55y     k4         Ready     Active         Leader           20.10.16
[root@k1 ~]# 

3、work就是工作的、管理节点操作,3台机器设置为了管理节点

[root@k1 ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-3zs6666666jcowuwvs 192.168.12.30:2377

[root@k2 ~]#  docker swarm join --token SWMTKN-1-3zs6666666jcowuwvs 192.168.12.30:2377
This node joined a swarm as a manager.
[root@k2 ~]# 
[root@k2 ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
tw6666666666666c2f     k1         Ready     Active         Reachable        20.10.16
oyhx1v66666666660c *   k2         Ready     Active         Reachable        20.10.16
twij666666668fv4ai     k2         Down      Active                          20.10.16
xk666666666666aefh     k3         Ready     Active                          20.10.16
4dh66666666666655y     k4         Ready     Active         Leader           20.10.16
[root@k3 ~]# docker node ls
Error response from daemon: This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager.
您在 /var/spool/mail/root 中有新邮件
[root@k3 ~]# 

[root@k1 ~]# systemctl stop docker
Warning: Stopping docker.service, but it can still be activated by:
  docker.socket
[root@k4 ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
twa2sqmjfhjf9ct4tve0s1c2f     k1         Down      Active         Unreachable      20.10.16
oyhx1v4hmd9vo6w2czlo6m50c     k2         Ready     Active         Unreachable      20.10.16
twijgssgk6ubkn6w6s88fv4ai     k2         Down      Active                          20.10.16
xkd6pfurmecsrzpdjjqx5aefh     k3         Ready     Active                          20.10.16
4dhqjmcdjwrt1vjwla685e55y *   k4         Ready     Active         Leader           20.10.16
[root@k4 ~]# 
[root@k2 ~]# systemctl stop docker  
Warning: Stopping docker.service, but it can still be activated by:
  docker.socket
[root@k4 ~]# docker node ls
Error response from daemon: rpc error: code = DeadlineExceeded desc = context deadline exceeded
[root@k4 ~]# 

十分简单:集群,可用,3个主节点 >1台管理节点存活
Raft协议:保证大多数节点存活才可以用 高可用

体会

弹性,扩缩容 ,集群
以后告别 docker run
docker-compose up 启动一个项目 ,单机
集群: swarm docker service
容器 => 服务
redis = 3份 ,容器
集群:高可用 , web -> redis (3台,不同的机器上)

体验:创建服务,动态扩展服务,动态更新服务
在这里插入图片描述
灰度发布,金丝雀发布

docker run 容器启动,不具有扩缩容性
docker service 服务, 具有扩缩容性 , 滚动更新

查看服务

[root@k1 ~]# docker service create -p 8888:80 --name my-nginx nginx
[root@k1 ~]# docker service ps my-nginx
ID             NAME         IMAGE          NODE      DESIRED STATE   CURRENT STATE          ERROR     PORTS
1o66663bt   my-nginx.1   nginx:latest   k2        Running         Running 22 hours ago             
[root@k1 ~]# docker service ls
ID             NAME       MODE         REPLICAS   IMAGE          PORTS
0f26666kr   my-nginx   replicated   1/1        nginx:latest   *:8888->80/tcp
[root@k2 ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED        STATUS        PORTS     NAMES
a766669df   nginx:latest   "/docker-entrypoint.…"   22 hours ago   Up 22 hours   80/tcp    my-nginx.1.1o7ayjvgj3bteh9zsr5bgl20r
[root@k2 ~]# 
[root@k1 ~]# docker service inspect my-nginx

动态扩缩容

[root@k1 ~]# docker service update --replicas 3 my-nginx
my-nginx
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 
# 四个节点,有一个docker ps,没东西,不影响网页访问 
[root@k1 ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
ae02e89974d7   nginx:latest   "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   80/tcp    my-nginx.2.fd55b58a3lsq6jf2jeendfid3
[root@k1 ~]# 
[root@k2 ~]# docker ps
[root@k3 ~]# docker ps
[root@k4 ~]# docker ps
# 网页访问: ip:8888/ (4个的ip都可以访问)

只要是一个服务,可以在集群中的任意节点访问。服务可以有多个节点,动态扩缩容,实现高可用
弹性 ,扩缩容

[root@k1 ~]# docker service update --replicas 10 my-nginx
my-nginx
overall progress: 10 out of 10 tasks 
1/10: running   [==================================================>] 
2/10: running   [==================================================>] 
3/10: running   [==================================================>] 
4/10: running   [==================================================>] 
5/10: running   [==================================================>] 
6/10: running   [==================================================>] 
7/10: running   [==================================================>] 
8/10: running   [==================================================>] 
9/10: running   [==================================================>] 
10/10: running   [==================================================>] 
verify: Service converged 
您在 /var/spool/mail/root 中有新邮件
[root@k2 ~]# docker ps
[root@k3 ~]# docker ps
[root@k4 ~]# docker ps
[root@k1 ~]# docker service update --replicas 1 my-nginx
my-nginx
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged 
[root@k2 ~]# docker ps
[root@k3 ~]# docker ps
[root@k4 ~]# docker ps

另一种扩缩容,更新副本数方式

[root@k2 ~]# docker service scale --help
[root@k1 ~]# docker service scale my-nginx=5
my-nginx scaled to 5
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@k1 ~]# docker service scale my-nginx=2
my-nginx scaled to 2
overall progress: 2 out of 2 tasks 
1/2: running   [==================================================>] 
2/2: running   [==================================================>] 
verify: Service converged 

移除服务

[root@k1 ~]# docker service --help

Usage:  docker service COMMAND

Manage services

Commands:
  create      Create a new service
  inspect     Display detailed information on one or more services
  logs        Fetch the logs of a service or task
  ls          List services
  ps          List the tasks of one or more services
  rm          Remove one or more services
  rollback    Revert changes to a service's configuration
  scale       Scale one or multiple replicated services
  update      Update a service

Run 'docker service COMMAND --help' for more information on a command.
[root@k1 ~]# docker service rm my-nginx
my-nginx
[root@k1 ~]# docker service ls
ID        NAME      MODE      REPLICAS   IMAGE     PORTS

docker swarm 并不难,只要会搭建集群、启动服务、动态管理容器就可以

概念总结

swarm
集群的管理和编号。docker可以初始化一个swarm集群,其他节点可以加入。(管理,工作者)
node
就是一个docker节点。多个节点就组成了一个网络集群。(管理,工作者)
service
就是一个任务。可以在管理节点或者工作节点运行。是核心。用户访问的是它。创建跟 docker run 一样
task
容器内的命令,一个细节任务
在这里插入图片描述

swarm 特点

1、docker engine 集成集群管理
使用docker engine cli 创建一个 docker engine 的swarm模式,在集群中部署应用程序服务
2、去中心化设计
swarm角色分为 manager 和worker 节点,manager节点故障不影响应用使用
3、扩容缩容
可以声明每个服务运行的容器数量,通过添加或删除容器数自动调整期望的状态
4、期望状态协调
swarm manager 节点不断监视集群状态,并调整当前状态和期望状态之间的差异。例如设置一个服务运行10个副本容器,如果两个副本的服务器节点崩溃,manager将创建两个
新的副本替代崩溃的副本,并将新的副本分配到可用的worker节点
5、多主机网络
可以为服务指定overlay网络,当初始化或者更新应用程序时,swarm manager 会自动为 overlay网络上的容器分配ip地址
6、服务发现
swarm manager 节点为集群中的每个服务分配唯一的DNS记录和负载均衡VIP。可以通过swarm内置的DNS服务器查询集群中每个运行的容器
7、负载均衡
实现服务副本负载均衡,提供入口访问。也可以将服务入口暴露给外部负载均衡器,再次负载均衡
8、安全传输
swarm 中的每个节点使用TLS相互验证和加密,确保安全的其他节点通信
9、滚动更新
升级时,逐步将应用更新到节点。如果出现问题,可以将任务回滚到先前版本

命令 ->管理 -> API -> 调度-> 工作节点(创建task容器)

服务副本与全局服务

在这里插入图片描述

调整service以什么方式运行

我们刚刚所有的服务都是随机分配的,我们的工作节点和我们的manageer节点都可以跑服务。但是我们的服务分为两种,一种是全局可以跑的service,还有一种是只能在副本上跑的service。全局的我们在任意节点都可以跑,但是工作节点,智能在我们的工作节点上跑。主要是通过命令的方式来进行操作的

--mode string
Service mode(replicated or global)(default "replicated")
docker service create --mode replicated --name mytom tomcat:8 #默认的方式
docker service create --mode global --name haha alphine ping baidu.com #指定方式执行
每个节点都有自己的日志收集器,过滤,把所有日志最终再传给日志中心,服务监控,状态性能

扩展:网络模式 “publishMode”:”ingress”

Swarm有三种网络模式:

overlay:在一个集群当中,即使我们跨机器,也可以把他集中起来。

ingress:特殊的overlay网络!具有负载均衡的功能,IPVS VIP
在这里插入图片描述
这个docker ingress就是我们的swarm的网络
[root@k1 ~]# docker network inspect ingress
在这里插入图片描述

Docker Stack

docker-compose单机部署项目
Docker stack部署,集群部署

#单机
docker-compose up -d wordpress.yaml

#集群
docker stack deploy

# docker-compose 文件,使用dockerstack案例

Docker Secret

安全 ,配置密码,。证书等等
在这里插入图片描述

Docker Config

配置
在这里插入图片描述
学习方式:网上找案例,跑起来,看帮助文档

扩展到k8s

云原生时代

k8s 10台机器以上

学习Go语言,是并发语言

docker 是go开发
k8s 是go 的项目
etcd 是go 的项目

  • 12
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值