狂神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有关的容器技术他们将自己的技术(容器化技术)命名就是dockerdocker刚刚诞生的时候,没有引起行业的注意,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 daemondocker pull            containers    imagesdocekr 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、卸载docker1)卸载依赖yum remove docker-ce docker-ce-cli containerd.io2)删除资源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 - CommunityVersion:           20.10.16API 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 --helpUsage:  docker images [OPTIONS] [REPOSITORY[:TAG]]List imagesOptions:-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 --helpUsage:  docker pull [OPTIONS] NAME[:TAG|@DIGEST]Pull an image or a repository from a registryOptions:-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/bashls
# 发现问题: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 5月  20 00:08 ceshi
drwxr-xr-x. 4 root root 30 5月  20 00:26 mysql
[root@k3 home]# cd mysql/
[root@k3 mysql]# ll
总用量 4
drwxr-xr-x. 2 root    root    6 5月  20 00:26 conf
drwxr-xr-x. 5 polkitd root 4096 5月  20 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 5月  20 00:08 ceshi
drwxr-xr-x. 2 root root  6 5月  20 21:58 docker-test-volume
drwxr-xr-x. 4 root root 30 5月  20 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 $MYPATHRUN yum -y install vim
RUN yum -y install net-toolsEXPOSE 80CMD 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 $MYPATHENV 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 8080CMD /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 -lcurl 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
donedocker 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:6379slots:[0-5460] (5461 slots) master
M: ef6666666666b4d5 172.38.0.12:6379slots:[5461-10922] (5462 slots) master
M: d5d2666666dcbd39c 172.38.0.13:6379slots:[10923-16383] (5461 slots) master
S: d966666666b18979c 172.38.0.14:6379replicates d5d23736666666c7e9666bd39c
S: 72588966666b44e 172.38.0.15:6379replicates 7c73d5e6666666666666666dca
S: 2a03a4d0db1aaa49c9e0003eb6b2831ec11b30ee 172.38.0.16:6379replicates 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:6379slots:[0-5460] (5461 slots) master1 additional replica(s)
M: ef66666666e266666666b4d5 172.38.0.12:6379slots:[5461-10922] (5462 slots) master1 additional replica(s)
S: 2a03666666666666666630ee 172.38.0.16:6379slots: (0 slots) slavereplicates ef997769c6666666666666664d5
S: 72666666662666666666664e 172.38.0.15:6379slots: (0 slots) slavereplicates 7c73d6666666666666666666dca
S: d9e06666666666666666679c 172.38.0.14:6379slots: (0 slots) slavereplicates d5d23666666666666666666669c
M: d5666666666666666666d39c 172.38.0.13:6379slots:[10923-16383] (5461 slots) master1 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)-- 完成

#  依赖
<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:8COPY *.jar /app.jarCMD ["--server.port=8080"]EXPOSE 8080ENTRYPOINT ["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/loglinks:- redisredis: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  CurrentDload  Upload   Total   Spent    Left  Speed0     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  CurrentDload  Upload   Total   Spent    Left  Speed0     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  CurrentDload  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 5月  28 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 5月  28 00:55 composetest
[root@k2 home]# cd composetest/
[root@k2 composetest]# cat app.py
import timeimport redis
from flask import Flaskapp = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)def get_hit_count():retries = 5while True:try:return cache.incr('hits')except redis.exceptions.ConnectionError as exc:if retries == 0:raise excretries -= 1time.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 5月  28 01:01 app.py
-rw-r--r--. 1 root root 109 5月  28 01:04 docker-compose.yml
-rw-r--r--. 1 root root 281 5月  27 19:05 Dockerfile
-rw-r--r--. 1 root root  12 5月  27 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 timeimport redis
from flask import Flaskapp = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)def get_hit_count():retries = 5while True:try:return cache.incr('hits')except redis.exceptions.ConnectionError as exc:if retries == 0:raise excretries -= 1time.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:- .:/coderedis: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# 服务配置imagesbuildnetwork....服务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 5月  30 22:50 docker-compose.yml
[root@k2 my_wordpress]# cat docker-compose.yml
version: "3.3"services:db:image: mysql:5.7volumes:- db_data:/var/lib/mysqlrestart: alwaysenvironment:MYSQL_ROOT_PASSWORD: somewordpressMYSQL_DATABASE: wordpressMYSQL_USER: wordpressMYSQL_PASSWORD: wordpresswordpress:depends_on:- dbimage: wordpress:latestvolumes:- wordpress_data:/var/www/htmlports:- "8001:80"restart: alwaysenvironment:WORDPRESS_DB_HOST: dbWORDPRESS_DB_USER: wordpressWORDPRESS_DB_PASSWORD: wordpressWORDPRESS_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 {@AutowiredStringRedisTemplate 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:8COPY *.jar /app.jarCMD ["--server.port=8080"]EXPOSE 8080ENTRYPOINT ["java","-jar","/app.jar"]

3、docker-compose.yml 编排项目

version: '3.3'
services:davinaapp:build: .image: davinaappdepends_on:- redisports:- "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 uphttp://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:2377To 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 --helpUsage:  docker service COMMANDManage servicesCommands:create      Create a new serviceinspect     Display detailed information on one or more serviceslogs        Fetch the logs of a service or taskls          List servicesps          List the tasks of one or more servicesrm          Remove one or more servicesrollback    Revert changes to a service's configurationscale       Scale one or multiple replicated servicesupdate      Update a serviceRun '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 的项目

狂神docker学习笔记相关推荐

  1. 狂神 Docker学习笔记 从基础到进阶 一步到位

    Docker 学习笔记 感谢狂神的分享.附上B站视频链接. https://www.bilibili.com/video/BV1og4y1q7M4?from=search&seid=92256 ...

  2. Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)

    文章目录 1. Dockerfile介绍 2. Dockerfile指令说明 3. 制作Centos镜像 3.1 编写Dockerfile的文件 3.2 通过这个文件构建镜像(注意最后加个点!!!) ...

  3. 十分钟了解Docker(我的Docker学习笔记)

    Docker学习笔记 碎碎念 背景知识 Docker是什么 Docker有什么用 Docker原理 Docker实践 Install Docker Engine on Ubuntu 常用命令操作实践 ...

  4. Docker:学习笔记(1)——基础概念

    Docker:学习笔记(1)--基础概念 Docker是什么 软件开发后,我们需要在测试电脑.客户电脑.服务器安装运行,用户计算机的环境各不相同,所以需要进行各自的环境配置,耗时耗力.为了解决这个问题 ...

  5. Docker学习笔记 之 Docker安装配置使用

    简介 Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机).bare met ...

  6. docker学习笔记(四)使用docker搭建环境

    参考:汤小洋老师的教学视频 docker学习笔记(一)[docker 介绍.卸载.安装.配置加速] docker学习笔记(二)docker常用命令 docker学习笔记(三)镜像 docker学习笔记 ...

  7. docker学习笔记(二)docker常用命令

    参考:汤小洋老师的教学视频 docker学习笔记(一)[docker 介绍.卸载.安装.配置加速] docker学习笔记(三)镜像 docker学习笔记(四)使用docker搭建环境 docker学习 ...

  8. docker学习笔记(三)镜像

    参考:汤小洋老师的教学视频 docker学习笔记(一)[docker 介绍.卸载.安装.配置加速] docker学习笔记(二)docker常用命令 docker学习笔记(四)使用docker搭建环境 ...

  9. docker学习笔记(五)如何创建自己的阿里云镜像仓库(这是2021版的阿里云教程)

    参考:汤小洋老师的教学视频 docker学习笔记(一)[docker 介绍.卸载.安装.配置加速] docker学习笔记(二)docker常用命令 docker学习笔记(三)镜像 docker学习笔记 ...

最新文章

  1. Python 之 Numpy (六)分割
  2. hdu4549 M斐波那契数列
  3. 【算法】Floyd-Warshall算法(任意两点间的最短路问题)(判断负圈)
  4. [攻防世界 pwn]——get_shell
  5. 我是永远不可能出轨的,除非......
  6. JS module的导出和导入
  7. Linux安装包下载地址(国内)
  8. 统计学习方法9—EM算法
  9. 跨浏览器(IE/FF/OPERA)JS代码小结
  10. 2021军校高考成绩查询时间,2021考军校难吗 军校录取分数线是多少
  11. python中哪些词是敏感字词_敏感词库(收集2017年最新最全敏感词) 2017 最新版
  12. Adobe Illustrator CS3
  13. 电脑知识与技术杂志电脑知识与技术杂志社电脑知识与技术编辑部2022年第15期目录
  14. hdu5773 LIS+贪心
  15. 实验:配置Trunk
  16. 微信小程序让凌乱的代码整齐好看紧凑
  17. Android 查看内存使用工具 (procstats)
  18. 移动端页面布局方式,简单记录一下
  19. 二维张量 乘以 三维张量_通量vs张量流误解
  20. BZOJ 4888 [Tjoi2017] 异或和

热门文章

  1. 现代大学英语精读第二版(第四册)学习笔记(原文及全文翻译)——16B - Is Everybody Happy?(人人都幸福吗?)
  2. 阴阳师真八歧大蛇最低配置攻略,蛇黑切
  3. IOS开发之 ---- 苹果系统代码汉字转拼音
  4. 吉林大学计算机技术(电子信息)专业(专硕)解读
  5. GoLang音视频转码
  6. 树莓派烧写OpenWrt系统后外接华为ME909或移远EC20 4G LTE模块实现4G软路由即MiFi
  7. android开机默认打开指定程序,android 开机默认进入指定Launcher
  8. PTA乙级 1068 万绿丛中一点红——20分
  9. android 语音和输入法按钮切换,android 切换系统语言,输入法也随之切换
  10. 自制Base64编码解码器