105.【Docker】
Docker
Docker
弱小和无知不是生存的障碍,傲慢才是
(一)、Docker介绍
1.Docker概述
Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。
比喻:
要了解Docker是什么,从隐喻开始比使用技术解释更容易,而Docker本身是一个强大的隐喻:Docker的本意是码头工人。码头工人是这样的劳动者:当船只停靠在港口时,码头工人将商品移入和移出船只。箱子和物品的大小和形状各不相同,经验丰富的码头工人因其能够以经济有效的方式手工将货物装入船舶而受到重视。雇人搬东西并不便宜,但别无选择。
在有Docker之前,不同团队的码头工人被要求装载不同形状的物体到船上去:
有Docker之后:
- 船被设计为可以更有效的携带,装载和卸载预设形状的物品
- 不同的物品放在同样一个简单的容器中。载体不关心容器里面是什么
- 载体可以装载到其他地方,减少了港口装载的瓶颈
- 仅需一个码头工人来操作设计用来移动容器的机器
对于工作在软件方面的人来说,这应该是熟悉的。花费了大量时间和智力,将隐喻奇怪形状的软件变成了不同大小的异形船,其中包含其他形状奇特的软件,因此它们可以出售给其他地方的用户或企业。
2.Docker为什么会出现?
正常开发中,一套产品我们需要配置两套环境。第一个是开发环境、第二个是应用环境。
- 在我的电脑上能运行,为什么在你的电脑上不能运行?
- 版本更新,导致服务不可用。
- 环境配置十分的麻烦,每一个机器都需要部署环境。
猜想: 发布一个项目(jar+MySQL…),项目能不能带上环境打包?
我目前所了解的就是:
我们部署一个SpringBoot的jar包到阿里云服务器上,但是我们的数据库信息和表并不会跟着jar包进行运行上去。我们要自己在阿里云服务器上进行编写MySQL语句然后数据导入。耗时耗力!!!
- 没有Docker前: 开发人员->jar包-> 运维人员->部署环境
- 使用Docker后: 开发人员->(jar包+环境)
Docker隔离: Docker核心思想,打包装箱,每一个箱子都是相互隔离的。
- 没有Docker : 以前水果和核武器需要分开船只进行装
- 有Docker: 水果和核武器分别装箱可以放在一个船上。
3.Docker历史
Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 开放容器联盟(OCI)。
Docker 自开源后受到广泛的关注和讨论,至今其 GitHub 项目已经超过 4 万 6 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。
docker为什么会火:主要是十分轻巧
在容器出现之前,主要使用的虚拟机技术:
虚拟机:在windows中装一个vmware,通过这个软件我们可以虚拟出来一台或者多台电脑,比较笨重。
虚拟机也属于虚拟化技术,Docker容器技术,也是一种虚拟化技术。
vm,linux centos原生镜像(一台电脑) 隔离,需要开启多个虚拟机!
docker,隔离,镜像(最核心的环境 4m+jdk+mysql)十分小巧,运行镜像就行了,小巧,几个M kb 秒级启动
聊聊Docker
Docker是基于Go语言开发的。
Docker官网地址: https://www.docker.com/
Docker仓库地址: https://hub.docker.com/
Docker文档地址: https://docs.docker.com/
4.Docker能做什么?
之前的虚拟机技术
- 浪费资源,占用内存非常大。
- 冗余步骤非常多
- 启动很慢!
容器化技术
容器化技术不是模拟一个完整的操作系统!
比较Docker和虚拟机技术的不同:
- 传统虚拟机: 虚拟出一条硬件,运行一个完整的操作系统,然后再这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也米有虚拟我们的硬件,所以就轻便化了
- 每个容器间是互相隔离的,每个容器都是互不影响的。
DevOps (开发、运维)
应用更快速的交付和部署
- 传统 : 一堆帮助文件,安装程序
- Docker: 打包进行发布测试,一键运行
更便捷的升级和扩缩容
- 使用Docker之后,我们部署应用就和搭积木一样。
- 水平扩容便捷
更简单的系统运维
- 容器化之后,我们开发和测试的环境是高度一致的。
更高效的资源利用
- Docker 是内核级别的虚拟化,可以再一个物理机上运行很多的容器实列。
(二)、Docker的配置与使用
1.三大基本名词
- 镜像(image):
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像 => run =>tomcat01容器(提供服务),通过这个镜像可以创建多个容器(端口不同)(最终服务运行或者项目运行就是在容器中的)。
- 容器(container):
Docker利用容器技术可以独立运行一个或者一组应用,通过镜像来创建,启动,停止、删除、基本命令。目前就可以把这个容器理解为一个简易的linux系统
- 仓库(repository)
仓库就是存放镜像的地方!仓库分为公有和私有仓库!
Docker hub(默认是国外的) 阿里云…都有容器服务器(配置镜像加速!)
镜像就是类,容器就是实例化后的实体类,仓库就是用来存放镜像的地方
仓库-> 镜像 -> 容器
2.安装Docker
- 环境准备
- 需要会一点linux基础
- centos7
- 使用shell连接远程服务器进行操作
- 环境查看
系统内核: 5.10
[root@Jsxs ~]# uname -r
5.10.134-13.al8.x86_64
系统版本
[root@Jsxs ~]# cat /etc/os-release
NAME="Alibaba Cloud Linux"
VERSION="3 (Soaring Falcon)"
ID="alinux"
ID_LIKE="rhel fedora centos anolis"
VERSION_ID="3"
PLATFORM_ID="platform:al8"
PRETTY_NAME="Alibaba Cloud Linux 3 (Soaring Falcon)"
ANSI_COLOR="0;31"
HOME_URL="https://www.aliyun.com/"
- 开始安装
- 卸载旧的版本
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 \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4. 更新yum软件包索引
yum makecache fast
报错提示fast参数的问题,这是因为版本问题,centos8没有该参数。
解决办法为:去掉fast参数。
- 安装Docker
dnf -y install docker-ce --nobest
- 查看Docker是否安装成功
dnf list docker-ce
- 启动Docker服务。
systemctl start docker
- 查看Docker服务的运行状态。
systemctl status docker
active(running)标识运行成功!
- 测试hello-world
docker run hello-world
- 查看一下下载的hello-world镜像
docker images
3.卸载Docker
- 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
- 删除目录(运行环境/资源)
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
/var/lib/docker 默认工作路径
cd /var/lib/docker
4. 阿里云镜像加速
- 找到位置
2.找到对应服务
3 . 配置文件
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://v4smj1xc.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
成功展示:
5.回顾Hello-world流程
Run的运行流程图
6.底层原理
Docker是怎么工作的
docker是Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问,DockerServer接收到Docker-Client的指令,就会执行这个命令。
Docker为什么比虚拟机快(VM)?
-
Docker有着比虚拟机更少的抽象层
-
Docker用的是宿主机的内核,Vm需要Guest OS
所以新建一个新的容器时候,docker不需要像虚拟机一样重新加载一个操作系统内核,虚拟机的加载Guest OS,分钟级别,而docker利用宿主机的操作系统。省略了这个复杂的过程。
(三)、Docker命令
1.帮助命令
docker version #显示docker的版本信息。
docker info #显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help #帮助命令
帮助文档的地址: https://docs.docker.com/engine/reference/commandline/docker/
2.镜像命令
(1).查看镜像
docker images [-aq]
相当于一个表格
[root@Jsxs ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 18 months ago 13.3kB
#解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的时间
SIZE 镜像的大小
------------------------------------------------
#可选项
-a, --all #列出所有的镜像
-q, --quiet #只显示镜像id
[root@Jsxs ~]# docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 18 months ago 13.3kB
[root@Jsxs ~]# docker images -q
feb5d9fea6a5
[root@Jsxs ~]# docker images -aq #所有id
feb5d9fea6a5
(2).搜索镜像
[root@Jsxs ~]# docker search 镜像名 [--filter=条件]
实际上对应Docker商店
可选参数:
[root@Jsxs ~]# docker search --help
Usage: docker search [OPTIONS] TERM
Search Docker Hub for images
Options:
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print search using a Go template
--limit int Max number of search results
--no-trunc Don't truncate output
# 可选参数,通过收藏进行过滤
-f, --filter=STARS=3000 搜索出来的镜像就是STARS大于3000的
--------------------------------------------------------------
[root@Jsxs ~]# docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 13958 [OK]
mariadb MariaDB Server is a high performing open sou… 5319 [OK]
(3).下载镜像
如果不写版本号,默认就是最新
docker pull 镜像名[:版本号]
# 下载镜像,docker pull 镜像名[:tag]
[root@Jsxs ~]# docker pull mysql
Using default tag: latest # 如果不写tag,默认就是最新
latest: Pulling from library/mysql
bf5952930446: Pull complete # 分层下载,docker images 的核心,联合文件系统
8254623a9871: Pull complete
938e3e06dac4: Pull complete
ea28ebf28884: Pull complete
f3cef38785c2: Pull complete
894f9792565a: Pull complete
1d8a57523420: Pull complete
6c676912929f: Pull complete
ff39fdb566b4: Pull complete
fff872988aba: Pull complete
4d34e365ae68: Pull complete
7886ee20621e: Pull complete
Digest: sha256:c358e72e100ab493a0304bda35e6f239db2ec8c9bb836d8a427ac34307d074ed # 签名-防伪标志
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
5.7: Pulling from library/mysql
bf5952930446: Already exists # 已存在,表示共用,可以极大的节省内存
8254623a9871: Already exists
938e3e06dac4: Already exists
ea28ebf28884: Already exists
f3cef38785c2: Already exists
894f9792565a: Already exists
1d8a57523420: Already exists
5f09bf1d31c1: Pull complete # 没有的才需要下载更新
1b6ff254abe7: Pull complete
74310a0bf42d: Pull complete
d398726627fd: Pull complete
Digest: sha256:da58f943b94721d46e87d5de208dc07302a8b13e638cd1d24285d222376d6d84
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
# 查看本地镜像
[root@Jsxs ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 718a6da099d8 6 days ago 448MB
mysql latest 0d64f46acfd1 6 days ago 544MB
hello-world latest bf756fb1ae65 7 months ago 13.3kB
(4).删除镜像
-f 是全部删除,可以通过imageID来删除,也可以通过name来删除。
[root@abc ~]# docker rmi -f 镜像ID #删除指定的镜像
[root@abc ~]# docker rmi -f 镜像ID 镜像ID 镜像ID #删除多个镜像
[root@abc ~]# docker rmi -f $(docker images -aq) #删除所有镜像
3.容器命令
前提: 我们有了镜像才可以创建容器。下载一个Centos镜像来测试学习
(1).下载Centos镜像
docker pull centos # 拉去镜像
(2).新增容器并启动容器
docker run [可选参数] 容器名字
#参数说明
--name="Name" 容器名字 tomcat01 tomcat02用来区分容器
-d 后台运行方式
-it 使用交互方式,进入容器
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口映射到容器端口(常用)
-p 容器端口
容器端口
-P 随机指定端口
------------------------------------------------------
[root@Jsxs ~]# docker run -it centos /bin/bash # 启动并进入容器
[root@fa630255c36e /]# ls #查看容器内的centos,基础版本,很多命令都是不完善的,
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@fa630255c36e /]# exit # 从容器中退回到主机,且不再运行。只是不运行了,并不是删除,所以数据还在。
exit
退出容器
exit #直接退出容器并退出
ctrl+P+Q #容器不停止退出
-----------------------------------------------------------
[root@Jsxs /]# docker run -it centos /bin/bash #新建并启动
[root@6bb50fc7777f /]# [root@Jsxs /]# docker ps #列出正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6bb50fc7777f centos "/bin/bash" About a minute ago Up About a minute amazing_lumiere
[root@Jsxs /]# docker rm 6bb50fc7777f # 普通移除,移除不了正在运行的
Error response from daemon: You cannot remove a running container 6bb50fc7777f5ac25d954f1d12cdcf240e0ddd8ed5527477f6c1b28e92730ecf. Stop the container before attempting removal or force remove
[root@Jsxs /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6bb50fc7777f centos "/bin/bash" 2 minutes ago Up 2 minutes amazing_lumiere
[root@Jsxs /]# docker rm -f 6bb50fc7777f #强制删除正在运行的
6bb50fc7777f
[root@Jsxs /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
(3).列出容器
[root@Jsxs /]# docker ps #列出所有正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@Jsxs /]# docker ps -a #列出之前运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa630255c36e centos "/bin/bash" 5 minutes ago Exited (0) 2 minutes ago brave_bouman
e8d8887713bc hello-world "/hello" 2 hours ago Exited (0) 2 hours ago jolly_nobel
15ddd66064d0 hello-world "/hello" 2 weeks ago Exited (0) 2 weeks ago jolly_spence
e62816aec698 hello-world "/hello" 2 weeks ago Exited (0) 2 weeks ago vigilant_meitner
[root@Jsxs /]# docker ps -a -n=2 # 列出最近2个运行过的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa630255c36e centos "/bin/bash" 7 minutes ago Exited (0) 4 minutes ago brave_bouman
e8d8887713bc hello-world "/hello" 2 hours ago Exited (0) 2 hours ago jolly_nobel
[root@Jsxs /]# docker ps -aq # 列出最近运行的全部容器ID
fa630255c36e
e8d8887713bc
15ddd66064d0
e62816aec698
(4).删除容器
docker rm 容器id #删除指定的容器,不能删除正在运行的容 器,如果要强制删除 rm -rf
[root@Jsxs /]# docker ps -a #先列出所有的容器id
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa630255c36e centos "/bin/bash" 22 minutes ago Exited (0) 20 minutes ago brave_bouman
e8d8887713bc hello-world "/hello" 3 hours ago Exited (0) 3 hours ago jolly_nobel
15ddd66064d0 hello-world "/hello" 2 weeks ago Exited (0) 2 weeks ago jolly_spence
e62816aec698 hello-world "/hello" 2 weeks ago Exited (0) 2 weeks ago vigilant_meitner
[root@Jsxs /]# docker rm fa630255c36e #通过容器id进行删除
fa630255c36e
--------------------------
docker rm -f $(docker ps -aq) #删除所有的容器(后面 ${}是参数传递),历史记录也删除了
[root@Jsxs /]# docker rm -f $(docker ps -aq)
e8d8887713bc
15ddd66064d0
e62816aec698
[root@Jsxs /]# docker ps -aq
-----------------------------
docker ps -a -q|xargs docker rm #删除所有的容器
(5).启动和停止容器的操作
docker start 容器id #docker run 是创建容器并启动,加入关闭后再就要用这个docker start
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器,会给10s时间去处理后世
docker kill 容器id #强制停止当前容器,直接噶皮
4.其他命令语言
(1).后台启动容器
# 命令 docker run -d 镜像名
-----------------------------------------------------------
[root@Jsxs ~]# docker run -d centos #启动容器
1f521ebe85e64e8c4387a0b933d21c38437cbe62088b7f8b3731b44af12ce235
[root@Jsxs ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 问题 docker ps, 发现centos停止了
# 问题 docker ps, 发现centos停止了
# 常见的坑, docker 容器使用后台运行, 就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx, 容器启动后,发现自己没有提供服务,就会立即停止,就是没有程序了
(2). 查看容器的日志
docker logs -tf --tail number 容器id
-tf # 显示日志
--tail number # 显示日志条数
------------------------------------------------------------------------
[root@25cdb0f99d5b /]# [root@Jsxs ~]# docker ps #查看容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
25cdb0f99d5b centos "/bin/bash" 21 seconds ago Up 19 seconds thirsty_cray
[root@Jsxs ~]# docker logs -tf --tail 10 25cdb0f99d5b #实时打印日志,因为没有日志所以一直等待
^C
[root@Jsxs ~]# docker run -d centos /bin/sh -c "while true;do echo xiaofan;sleep 1;done" #编写一个脚本
be003d68204c8b3093277632abaa73e74a2e3e9230ae0c64223b1642d1d5eeab
[root@Jsxs ~]# docker ps #查看正在运行的脚本
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be003d68204c centos "/bin/sh -c 'while t…" 18 seconds ago Up 17 seconds clever_cannon
25cdb0f99d5b centos "/bin/bash" 5 minutes ago Up 5 minutes thirsty_cray
[root@Jsxs ~]# docker logs -tf --tail 10 be003d68204c #查看日志
2023-03-21T11:02:50.282553993Z xiaofan #以下是打印的日志
2023-03-21T11:02:51.284511479Z xiaofan
2023-03-21T11:02:52.286475299Z xiaofan
2023-03-21T11:02:53.288525375Z xiaofan
2023-03-21T11:02:54.290252993Z xiaofan
2023-03-21T11:02:55.292331800Z xiaofan
2023-03-21T11:02:56.294111690Z xiaofan
2023-03-21T11:02:57.296295842Z xiaofan
2023-03-21T11:02:58.298222418Z xiaofan
2023-03-21T11:02:59.300133879Z xiaofan
2023-03-21T11:03:00.302025977Z xiaofan
2023-03-21T11:03:01.303913764Z xiaofan
2023-03-21T11:03:02.305736445Z xiaofan
2023-03-21T11:03:03.307603920Z xiaofan
2023-03-21T11:03:04.309328998Z xiaofan
2023-03-21T11:03:05.311165252Z xiaofan
2023-03-21T11:03:06.312965880Z xiaofan
2023-03-21T11:03:07.314699791Z xiaofan
2023-03-21T11:03:08.316592003Z xiaofan
^C
(3).查看容器中进程信息
#命令 docker top 容器ID
--------------
[root@Jsxs ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be003d68204c centos "/bin/sh -c 'while t…" 13 minutes ago Up 13 minutes clever_cannon
[root@Jsxs ~]# docker top be003d68204c
用户id 进程id 父进程id
UID PID PPID C STIME TTY TIME CMD
root 557486 557465 0 19:01 ? 00:00:00 /bin/sh -c while true;do echo xiaofan;sleep 1;done
root 558648 557486 0 19:15 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
(4).查看容器的元数据
#命令 docker inspect 容器ID
----------------------------------------------------------
[root@Jsxs ~]# docker inspect be003d68204c
[
{
显示id的一部分
"Id": "be003d68204c8b3093277632abaa73e74a2e3e9230ae0c64223b1642d1d5eeab",
"Created": "2023-03-21T11:01:25.371743833Z", 时间
"Path": "/bin/sh", 路径
"Args": [
"-c",
"while true;do echo xiaofan;sleep 1;done" 信息
],
状态
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 11132,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-05-24T02:33:46.224199282Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
"ResolvConfPath": "/var/lib/docker/containers/c55c1a083e2e5e33d6a5577e4ac9d953718f746bcf79841a7b9fa7deb643c5a2/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/c55c1a083e2e5e33d6a5577e4ac9d953718f746bcf79841a7b9fa7deb643c5a2/hostname",
"HostsPath": "/var/lib/docker/containers/c55c1a083e2e5e33d6a5577e4ac9d953718f746bcf79841a7b9fa7deb643c5a2/hosts",
"LogPath": "/var/lib/docker/containers/c55c1a083e2e5e33d6a5577e4ac9d953718f746bcf79841a7b9fa7deb643c5a2/c55c1a083e2e5e33d6a5577e4ac9d953718f746bcf79841a7b9fa7deb643c5a2-json.log",
"Name": "/fervent_beaver",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/0c335307a36317a110766faea36b3c7c868ae5ee9b8c27a989edacf3b6892829-init/diff:/var/lib/docker/overlay2/b62e37aaada82eaec082715523ac39af7267a00be9af7f268d0cee3645b702e4/diff",
"MergedDir": "/var/lib/docker/overlay2/0c335307a36317a110766faea36b3c7c868ae5ee9b8c27a989edacf3b6892829/merged",
"UpperDir": "/var/lib/docker/overlay2/0c335307a36317a110766faea36b3c7c868ae5ee9b8c27a989edacf3b6892829/diff",
"WorkDir": "/var/lib/docker/overlay2/0c335307a36317a110766faea36b3c7c868ae5ee9b8c27a989edacf3b6892829/work"
},
"Name": "overlay2"
},
挂载
"Mounts": [],
"Config": {
"Hostname": "c55c1a083e2e",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"while true;do echo 123YX;sleep 1;done"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20210915",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
}
},
网络命令
"NetworkSettings": {
"Bridge": "",
"SandboxID": "9aed795b5d2eb0a3d6b31cd48f29acabf338aa036703b40e063df5af1b564490",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/9aed795b5d2e",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "4e0e7bcc423265a62a278215bf9200d8ed34e68a8a82e95b97390915831c6ba4",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "8d26d8f19fe79975f51b98bb21730e285b04a26e21cd0b5b4cbc02c01ea370e8",
"EndpointID": "4e0e7bcc423265a62a278215bf9200d8ed34e68a8a82e95b97390915831c6ba4",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
5.进入当前正在运行的容器
# 我们通常容器都是在后台运行,需要进入容器,修改一些配置
# 命令
docker exec -it 容器id bashshell
# 方式一
[root@Jsxs ~]# docker run -d centos /bin/sh -c "while true;do echo xiaofan;sleep 1;done"
45c2bee44852afd81e604ded7314a1477db87956d45956e95518a2b2810bb8b4
[root@Jsxs ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
45c2bee44852 centos "/bin/sh -c 'while t…" 6 seconds ago Up 5 seconds relaxed_greider
[root@Jsxs ~]# docker exec -it 45c2bee44852 /bin/bash
[root@45c2bee44852 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@45c2bee44852 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 11:23 ? 00:00:00 /bin/sh -c while true;do echo xiaofan;sleep 1;done
root 46 0 0 11:24 pts/0 00:00:00 /bin/bash
root 96 1 0 11:24 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root 97 46 0 11:24 pts/0 00:00:00 ps -ef
------------------------------------------------------
# 方式二
dcoker attach 容器id
# 测试
Docker version 20.10.16, build aa7e414
[root@localhost ~]# docker attach c55c1a083e2e
123YX
123YX
123YX
123YX
123YX
正在执行当前的代码...
==================================================================
# 区别
docker exec #进入容器后开启一个新的终端,可以在里面操作 (常用)
docker attach # 进入容器正在执行的终端,不会启动新的进程
6.从容器中拷贝文件到主机(光标在主机)
容器之间是互相隔离状态
#命令
docker cp 容器ID:容器内路径 目的主机路径
----------------------------------------------------------------------
[root@Jsxs ~]# docker ps -a # 查看所有的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@Jsxs ~]# clear
[root@Jsxs ~]# docker ps #只查看正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@Jsxs ~]# docker images # 查看所有的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 18 months ago 13.3kB
centos latest 5d0da3dc9764 18 months ago 231MB
[root@Jsxs ~]# docker run -it centos /bin/bash #创建一个新的容器并运行
[root@48fa8f942572 /]# [root@Jsxs ~]# docker ps #查看正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48fa8f942572 centos "/bin/bash" 13 seconds ago Up 13 seconds heuristic_cerf
[root@Jsxs ~]# cd /home #进入本机home目录
[root@Jsxs home]# ls #查看文件
aaa jsxs liloucun liloucunManger properties redis www
[root@Jsxs home]# docker attach 48fa8f942572 #进入正在运行的容器
[root@48fa8f942572 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@48fa8f942572 /]# cd /home #进入容器的虚拟机中的home目录
[root@48fa8f942572 home]# ls
[root@48fa8f942572 home]# touch test.java #在容器的虚拟机中的home目录创建文件
[root@48fa8f942572 home]# exit
exit #退出容器,并停止运行。只要不删除容器,数据还在
[root@Jsxs home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@Jsxs home]# docker cp 48fa8f942572:/homet/test.java /home
Error response from daemon: Could not find the file /homet/test.java in container 48fa8f942572
[root@Jsxs home]# docker cp 48fa8f942572:/home/test.java /home #移动
Successfully copied 1.536kB to /home
[root@Jsxs home]# ls #查看
aaa jsxs jsxs.java liloucun liloucunManger properties redis test.java www
#拷贝是一个手动过程,未来我们使用 -v卷的技术,可以实现自动
7.小结
(1).Docker 常用命令大全
#info|version
docker info #显示docker的系统信息,包括镜像和容器的数量
docker version #显示docker的版本信息。
#帮助命令
docker 命令 --help #帮助命令
#镜像命令
docker images #查看所有本地主机上的镜像 可以使用docker image ls代替
docker search #搜索镜像
docker pull #下载镜像 docker image pull
docker rmi #删除镜像 docker image rm
#容器命令
docker run 镜像id #新建容器并启动
docker ps 列出所有运行的容器 docker container list
docker rm 容器id #删除指定容器
#删除所有容器
docker rm -f $(docker ps -aq) #删除所有的容器
docker ps -a -q|xargs docker rm #删除所有的容器
#启动和停止容器
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kill 容器id #强制停止当前容器
#退出容器
exit #容器直接退出
ctrl +P +Q #容器不停止退出 ---注意:这个很有用的操作
#其他常用命令
docker run -d 镜像名 #后台启动命令
docker logs #查看日志
docker top 容器id #查看容器中进程信息ps
docker inspect 容器id #查看镜像的元数据
docker exec -it 容器名 操作命令 #进入当前容器后开启一个新的终端,可以在里面操作。(常用)
[root@Jsxs ~]# docker exec -it tomcat-net01 ping 192.168.0.3
docker attach 容器id/name # 进入容器正在执行的终端
docker cp 容器id:容器内路径 主机目的路径 #从容器内拷贝到主机上
Docker命令大全
docker attach #连接到正在运行中的容器
docker build #使用 Dockerfile 创建镜像
docker builder #管理builds
docker builder prune #清除build缓存
docker checkpoint #管理checkpoints
docker checkpoint create #从正在运行的容器创建检查点
docker checkpoint ls #列出容器的检查点
docker checkpoint rm #删除指定的检查点
docker commit #从容器创建一个新的镜像
docker config #管理Docker配置
docker config create #创建配置文件
docker config inspect #查看配置文件信息
docker config ls #显示docker里已经保存得配置文件
docker config rm #删除配置文件
docker container #管理容器
docker container prune #删除所有已停止的容器
docker context #管理contexts
docker context create #创建一个上下文
docker context export #将上下文导出到tar或kubecconfig文件中
docker context import #从tar或zip文件导入上下文
docker context inspect #在一个或多个上下文上显示详细信息
docker context ls #列出上下文
docker context rm #删除一个或多个上下文
docker context update #更新
docker context use #设置当前docker的上下文
docker cp #用于容器与主机之间的数据拷贝
docker create #创建一个新的容器但不启动它
docker diff #检查容器里文件结构的更改
docker events #从服务器获取实时事件
docker exec #在运行的容器中执行命令
docker export #将文件系统作为一个tar归档文件导出到STDOUT
docker history #查看指定镜像的创建历史
docker image #管理镜像
docker image inspect #显示一个或多个镜像的元数据
docker image ls #列出本地镜像
docker image prune #删除没有使用的镜像
docker image rm #删除一个或多个镜像
docker images #列出本地镜像
docker import #从归档文件中创建镜像
docker info #显示 Docker 系统信息,包括镜像和容器数
docker inspect #获取容器/镜像的元数据
docker kill #杀掉一个运行中的容器
docker load #导入使用 docker save 命令导出的镜像
docker login #登陆到一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub
docker logout #登出一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub
docker logs #获取容器的日志
docker manifest #管理manifest(实验,不应用于生产环境)
docker manifest annotate #向本地镜像清单添加附加信息
docker manifest create #创建用于注释和推入注册表的本地清单列表
docker manifest inspect #显示镜像清单或清单列表
docker manifest push #将清单列表推入仓库
docker manifest rm #从本地存储中删除一个或多个清单列表
docker network #管理网络
docker network connect #将容器连接到网络
docker network create #创建一个网络
docker network disconnect #断开容器的网络
docker network inspect #显示一个或多个网络的元数据
docker network ls #列出网络
docker network prune #删除所有没有使用的网络
docker network rm #删除一个或多个网络
docker node #管理集群(swarm)节点
docker node demote #从群集(swarm)管理器中降级一个或多个节点
docker node inspect #显示一个或多个节点的元数据
docker node ls #列出群集(swarm)中的节点
docker node promote #将一个或多个节点推入到群集管理器中
docker node ps #列出在一个或多个节点上运行的任务,默认为当前节点
docker node rm #从群集(swarm)删除一个或多个节点
docker node update #更新一个节点
docker pause #暂停容器中所有的进程
docker plugin #管理插件
docker plugin create #从rootfs和配置创建一个插件。插件数据目录必须包含config.json和rootfs目录。
docker plugin disable #禁用插件
docker plugin enable #启用插件
docker plugin inspect #显示一个或多个插件的元数据
docker plugin install #安装一个插件
docker plugin ls #列出所有插件
docker plugin push #将插件推送到注册表
docker plugin rm #删除一个或多个插件
docker plugin set #更改插件的设置
docker plugin upgrade #升级现有插件
docker port #列出指定的容器的端口映射,或者查找将PRIVATE_PORT NAT到面向公众的端口
docker ps #列出容器
docker pull #从镜像仓库中拉取或者更新指定镜像
docker push #将本地的镜像上传到镜像仓库,要先登陆到镜像仓库
docker rename #重命名容器
docker restart #重启容器
docker rm #删除一个或多个容器
docker rmi #删除一个或多个镜像
docker run #创建一个新的容器并运行一个命令
docker save #将指定镜像保存成 tar 归档文件
docker search #从Docker Hub查找镜像
docker secret #管理Docker secrets
docker secret create #从文件或STDIN创建一个秘密作为内容
docker secret inspect #显示有关一个或多个秘密的详细信息
docker secret ls #列出秘密
docker secret rm #删除一个或多个秘密
docker service #管理服务
docker service create #创建一个服务
docker service inspect #查看服务的元数据
docker service logs #获取服务的日志
docker service ls #列出服务
docker service ps #列出一个或多个服务的任务
docker service rm #删除一个或多个服务
docker service rollback #将更改恢复到服务的配置
docker service scale #缩放一个或多个复制服务
docker service update #更新服务
docker stack #管理堆栈
docker stack deploy #部署新的堆栈或更新现有堆栈
docker stack ls #列出现有堆栈
docker stack ps #列出堆栈中的任务
docker stack rm #删除堆栈
docker stack services #列出堆栈中的服务
docker start #启动一个或多个已经被停止的容器
docker stats #显示容器的实时流资源使用统计信息
docker stop #停止一个运行中的容器
docker swarm #管理集群(Swarm)
docker swarm ca #查看或旋转当前群集CA证书。此命令必须针对管理器节点
docker swarm init #初始化一个群集(Swarm)
docker swarm join #加入群集作为节点和/或管理器
docker swarm join-token #管理加入令牌
docker swarm leave #离开群集(Swarm)
docker swarm unlock #解锁群集(Swarm)
docker swarm unlock-key #管理解锁钥匙
docker swarm update #更新群集(Swarm)
docker system #管理Docker
docker system df #显示docker磁盘使用情况
docker system events #从服务器获取实时事件
docker system info #显示系统范围的信息
docker system prune #删除未使用的数据
docker tag #标记本地镜像,将其归入某一仓库
docker top #查看容器中运行的进程信息,支持 ps 命令参数
docker trust #管理Docker镜像的信任
docker trust inspect #返回有关key和签名的低级信息
docker trust key #管理登入Docker镜像的keys
docker trust key generate #生成并加载签名密钥对
docker trust key load #加载私钥文件以进行签名
docker trust revoke #删除对镜像的认证
docker trust sign #镜像签名
docker trust signer #管理可以登录Docker镜像的实体
docker trust signer add #新增一个签名者
docker trust signer remove #删除一个签名者
docker unpause #恢复容器中所有的进程
docker update #更新一个或多个容器的配置
docker version #显示 Docker 版本信息
docker volume #管理volumes
docker volume create #创建一个卷
docker volume inspect #显示一个或多个卷的元数据
docker volume ls #列出卷
docker volume prune #删除所有未使用的卷
docker volume rm #删除一个或多个卷
docker wait #阻塞运行直到容器停止,然后打印出它的退出代码
(四)、Docker部署软件实践
1.Docker安装Nginx
docker search nginx #搜索
docker pull nginx #拉去
docker images # 查看镜像
# -d后台运行
#--name给容器命名
#-p宿主机端口:容器内部端口
docker run -d --name nginx01 -p 3344:80 nginx # 创建容器并启动
curl localhost:3344 #运行测试
端口暴露的概念
开启安全组3344
利用外网也能访问的到
[root@Jsxs ~]# docker ps #查看正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec573efd8a87 nginx "/docker-entrypoint.…" 23 minutes ago Up 23 minutes 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
[root@Jsxs ~]# docker exec -it nginx01 /bin/bash #以交互式的方式启动名字叫做nginx01的容器
root@ec573efd8a87:/# whereis nginx #查找配置
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@ec573efd8a87:/# cd /etc/nginx #进入配置地址
root@ec573efd8a87:/etc/nginx# exit #离开,但是后台还在
exit
[root@Jsxs ~]#docker ps #查看正在运行的
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec573efd8a87 nginx "/docker-entrypoint.…" 32 minutes ago Up 32 minutes 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
[root@Jsxs ~]# docker stop ec573efd8a87 #停止
ec573efd8a87
考问题:我们每次都需要改动nginx配置,都需要进入容器内部?十分的麻烦,我们要是可以在容器外部提供一个映射路径,达到可以在容器外部修改文件名,容器内部就可以进行自动修改?-数据卷
2.Docker安装Tomcate
# 我们之前的启动器都是后台,停止容器之后,容器还是可以查到。 这种方式一般是
#用完就删除,常常用于测试。
docker run -it --rm tomcat:9.0
[root@Jsxs ~]# docker ps #查找正在运行的
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@Jsxs ~]# docker ps -a #查找历史记录
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec573efd8a87 nginx "/docker-entrypoint.…" 44 minutes ago Exited (0) 11 minutes ago nginx01
48fa8f942572 centos "/bin/bash" 14 hours ago Exited (0) 14 hours ago heuristic_cerf
-----------------------------------------------------------------
docker pull tomcat:9.0 #拉去指定版本
docker images #查看镜像
docker run -d -p 3355:8080 --name tomcat01 tomcat:9.0 # 后台 端口映射 名字 镜像:tage
配置安全组
外网访问成功!
docker exec -it tomcat01 /bin/bash
root@db99d2ee658c:/usr/local/tomcat# ll
bash: ll: command not found
root@db99d2ee658c:/usr/local/tomcat# ls -al
total 172
drwxr-xr-x 1 root root 4096 Dec 22 2021 .
drwxr-xr-x 1 root root 4096 Mar 22 01:32 ..
-rw-r--r-- 1 root root 18970 Dec 2 2021 BUILDING.txt
-rw-r--r-- 1 root root 6210 Dec 2 2021 CONTRIBUTING.md
-rw-r--r-- 1 root root 57092 Dec 2 2021 LICENSE
-rw-r--r-- 1 root root 2333 Dec 2 2021 NOTICE
-rw-r--r-- 1 root root 3378 Dec 2 2021 README.md
-rw-r--r-- 1 root root 6898 Dec 2 2021 RELEASE-NOTES
-rw-r--r-- 1 root root 16507 Dec 2 2021 RUNNING.txt
drwxr-xr-x 2 root root 4096 Dec 22 2021 bin
drwxr-xr-x 1 root root 4096 Mar 22 01:31 conf
drwxr-xr-x 2 root root 4096 Dec 22 2021 lib
drwxrwxrwx 1 root root 4096 Mar 22 01:31 logs
drwxr-xr-x 2 root root 4096 Dec 22 2021 native-jni-lib
drwxrwxrwx 2 root root 4096 Dec 22 2021 temp
drwxr-xr-x 2 root root 4096 Dec 22 2021 webapps
drwxr-xr-x 7 root root 4096 Dec 2 2021 webapps.dist
drwxrwxrwx 2 root root 4096 Dec 2 2021 work
root@db99d2ee658c:/usr/local/tomcat# cd webapps
root@db99d2ee658c:/usr/local/tomcat/webapps# ls
报出404错误,说明可以访问,但是tomcat有问题,不完整
# 发现问题: 1.linux命令少 2.没有webapps、阿里云镜像的原因,默认是最小的镜像,所有不必要的都剔除掉
# 保证
----------------------------------------------------------------------
[root@Jsxs ~]# docker ps #查看正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@Jsxs ~]# docker ps -a #查看历史且存在的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
db99d2ee658c tomcat:9.0 "catalina.sh run" 2 hours ago Exited (143) 2 hours ago tomcat01
ec573efd8a87 nginx "/docker-entrypoint.…" 3 hours ago Exited (0) 3 hours ago nginx01
48fa8f942572 centos "/bin/bash" 16 hours ago Exited (0) 16 hours ago heuristic_cerf
[root@Jsxs ~]# docker start db99d2ee658c #启动容器
db99d2ee658c
[root@Jsxs ~]# curl localhost:3355 #测试
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/9.0.56</h3></body></html>[root@Jsxs ~]# docker exec -it tomcat01 /bin/bash
root@db99d2ee658c:/usr/local/tomcat# ^C
root@db99d2ee658c:/usr/local/tomcat# whereis tomcat #查看目录
tomcat: /usr/local/tomcat
root@db99d2ee658c:/usr/local/tomcat# cd /usr/local/tomcat/webapps
root@db99d2ee658c:/usr/local/tomcat/webapps# ls
root@db99d2ee658c:/usr/local/tomcat/webapps# cd ..
root@db99d2ee658c:/usr/local/tomcat# ls #查看列表
BUILDING.txt CONTRIBUTING.md LICENSE NOTICE README.md RELEASE-NOTES RUNNING.txt bin conf lib logs native-jni-lib temp webapps webapps.dist work
root@db99d2ee658c:/usr/local/tomcat# webapps.dist/
bash: webapps.dist/: Is a directory
root@db99d2ee658c:/usr/local/tomcat# ls
BUILDING.txt CONTRIBUTING.md LICENSE NOTICE README.md RELEASE-NOTES RUNNING.txt bin conf lib logs native-jni-lib temp webapps webapps.dist work
root@db99d2ee658c:/usr/local/tomcat# cd webapps.dist
root@db99d2ee658c:/usr/local/tomcat/webapps.dist# ls
ROOT docs examples host-manager manager
root@db99d2ee658c:/usr/local/tomcat/webapps.dist# cd ..
# 复制文件webapps.dist目录下的文件 复制得到 webapps
root@db99d2ee658c:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@db99d2ee658c:/usr/local/tomcat# cd webapps
root@db99d2ee658c:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
再次测试:访问成功!!
我们以后要部署项目,如果每次都要进入容器十分麻烦?我要是可以在容器外部提供一个映射路径,webapps,我们在外部放置项目,就自动同步到内部就好了!
从以前的删库跑路 到现在的删容器跑路
3.Docker部署es+kilbana
es 暴漏的端口很多
es 十分的消耗内存
es 的数据一般需要放置到安全目录! 挂载
# es 暴露的端口很多!
# es 十分耗内存
# es 的数据一般需要放置到安全目录!挂载
# --net somenetwork ? 网络配置
# 启动elasticsearch
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
安装后会很卡
# 测试一下es是否成功启动
➜ ~ curl localhost:9200
{
"name" : "d73ad2f22dd3",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "atFKgANxS8CzgIyCB8PGxA",
"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"
}
#测试成功就关掉elasticSearch,防止耗内存
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker stats # 查看docker容器使用内存情况
-------------------------------------------------------------------------------------------------------
#测试成功就关掉elasticSearch,可以添加内存的限制,修改配置文件 -e 环境配置修改(看自己的容器号,这个可能也是copy别人的,所以号不一样)
➜ ~ docker rm -f d73ad2f22dd3 # stop命令也行
➜ ~ docker run -d --name elasticsearch01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
56d4fde935d2 elasticsearch01 0.52% 395.9MiB / 1.795GiB 21.54% 656B / 0B 106MB / 729kB 43
------------------------------------------------------------
[root@abc ~]# curl localhost:9200
{
"name" : "56d4fde935d2",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "VCzCca-fRmCpeINIBPUoTQ",
"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"
}
执行原理
4.可视化管理工具
- portainer(先用这个,这个不是最佳选择)
- 一个docker图形化管理工具
什么是portainer?
Docker图形管理工具!提供一个后台面板供我们操作。
1.安装
# 下载,安装,测试
docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
# 这时候就可以打开外网地址访问8088接口了
除了外网访问也可以内网访问
curl localhost:8088
选择本地
进去之后...
(五)、Docker镜像
1.镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
所有的应用,直接打包docker镜像,就可以直接跑起来,不需要运维部署环境了
如何得到镜像:
- 从远处仓库下载
- 朋友拷贝给你
- 自己制作一个镜像DockerFile
2.Docker镜像加载原理
(1).UnionFS(联合文件系统)
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础
。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
git每次操作都有记录,docker pull 下载时候看到一层一层的就是这个
A软件有的部分,B软件需要的话就不用重新下载了
(2).镜像加载原理
docker的镜像实际上由一层一层的渐渐系统组成,这种层级的文件UnionFS
bootfs(boot file system主要包含bootloader
和kernel
, bootloader
主要是引导加载kernel
, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs
。
rootfs (root file system),在bootfs之上。包含的就是典型 Linux 系统中的 /dev,/proc,/bin,/etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等
。
平时我们安装虚拟机的centos都是好几个G,为什么Docker这里才200M?因为是精简过的,引导没了,只有文件,效率最大化
。
对于一个精简的OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版, bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
虚拟机是分钟级别的,容器是秒级别的。
- 任何系统安装需要引导加载,所以Bootfs
- 黑屏-开机-系统 这过程就是种加载
- 容器就是小的虚拟机环境
- 底层的内核是不变的
3.镜像原理之分层理解
我们去下载一个镜像,注意观察下载的日志输出,可以看到是一层一层的在下载!
最大的好处,莫过于是资源共享。比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需要在磁盘上保留一份base镜像
,同时内存中只需要加载一份base镜像,这样就可以为多有的容器服务了,而且每一层都可以被共享!!!
查看镜像分层的方式可以通过docker image inspect 命令
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f",
"sha256:9b24afeb7c2f21e50a686ead025823cd2c6e9730c013ca77ad5f115c079b57cb",
"sha256:4b8e2801e0f956a4220c32e2c8b0a590e6f9bd2420ec65453685246b82766ea1",
"sha256:529cdb636f61e95ab91a62a51526a84fd7314d6aab0d414040796150b4522372",
"sha256:9975392591f2777d6bf4d9919ad1b2c9afa12f9a9b4d260f45025ec3cc9b18ed",
"sha256:8e5669d8329116b8444b9bbb1663dda568ede12d3dbcce950199b582f6e94952"
]
},
理解:
- 所有的 Docker|镜像都
起始于一个基础镜像层
,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。 - 举一个简单的例子,假如基于 Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
在添加额外的镜像层的同时,镜像始终是保持当前所有镜像的组合,理解这一点是非常重要的。下图距举了一个简单的例子,每个镜像包含三个文件,而镜像包含了来自两个镜像层的6个文件。
和搭积木一样。单个零件单个零件搭建。如果遇到不喜欢的,在原有的基础上进行替换掉不喜欢的部分即可。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。 Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系統。 Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顾名思义,每种存储引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点
。
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像顶部
!
顶层就是我们通常说的容器层,容器之下的都叫镜像层
镜像层是远程下载过来的,无法改变!!!。但是镜像层+操作可以组合成容器层,可以修改。理解的意思就是原有仓库镜像不能修改,但是操作后的镜像可以再次被我们打包成一个新的镜像。
4.提交镜像 【创建自己的镜像】
如果你想要保存当前的状态,就通过commit提交,获得一个镜像,就好比我们以前学习VM时候,快照
# docker commit 提交容器成为一个新的副本 # 命令和git原理类似
docker commit
-m="提交的描述信息"
-a="作者"
容器id 目标镜像名:[tag]
------------------------------------------------------------
[root@Jsxs ~]# docker ps #查看正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4aba86a517af portainer/portainer "/portainer" About an hour ago Up About an hour 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
db99d2ee658c tomcat:9.0 "catalina.sh run" 5 hours ago Up 2 hours 0.0.0.0:3355->8080/tcp, :::3355->8080/tcp tomcat01
[root@Jsxs ~]# docker commit -a="jsxs" -m="add webapps application" db99d2ee658c tomcat02:1.0 #打包,名字叫做tomcat02版本1.0
sha256:3cdc89385182ebcc15497f6ac38299ad3dd7e4449faa4f1ae4ee73f4874414ff
[root@Jsxs ~]# docker images #查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 1.0 3cdc89385182 8 seconds ago 685MB #自定义的镜像
nginx latest 605c77e624dd 14 months ago 141MB
tomcat 9.0 b8e65a4d736d 15 months ago 680MB
hello-world latest feb5d9fea6a5 18 months ago 13.3kB
centos latest 5d0da3dc9764 18 months ago 231MB
portainer/portainer latest 580c0e4e98b0 2 years ago 79.1MB
[root@Jsxs ~]# docker rmi 3cdc89385182 #删除镜像
Untagged: tomcat02:1.0
Deleted: sha256:3cdc89385182ebcc15497f6ac38299ad3dd7e4449faa4f1ae4ee73f4874414ff
Deleted: sha256:a5c33b51384b808f00ba9d8e3e4868e69bb9ff538669ae94dc5c5555d159d195
[root@Jsxs ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 14 months ago 141MB
tomcat 9.0 b8e65a4d736d 15 months ago 680MB
hello-world latest feb5d9fea6a5 18 months ago 13.3kB
centos latest 5d0da3dc9764 18 months ago 231MB
portainer/portainer latest 580c0e4e98b0 2 years ago 79.1MB
(六)、容器数据卷
1.什么是容器数据卷
将应用环境打包成一个镜像!
如果数据都在容器中,那么我们容器删除,数据就会丢失!
需求:数据可以持久化。比如:Docker安装了MySQL,容器删除了,删库跑路
!需求:MySQL的数据可以存储在本地。容器之间可以有一个数据共享的技术!docker容器中产生的数据,同步到本地
。这就是卷技术
,目录的挂载,将容器内的目录挂载在Linux上面。
总结一句话:容器的持久化和同步操作,容器间也是可以数据共享的。
2.使用数据卷 【容器和主机挂载】💥
(1). 挂载centOS (1)
docker run -it -v 主机目录:容器的目录 #做映射
-------------------------------------------------------------
# docker run -it -v 主机目录:容器的目录 镜像 /bin/bash
docker run -it -v /home/test:/home centos /bin/bash #挂载并启动
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d6db1a46fdb4 centos "/bin/bash" 3 minutes ago Up 3 minutes heuristic_volhard
4aba86a517af portainer/portainer "/portainer" 2 hours ago Up 2 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
查看挂在信息
docker inspect d6db1a46fdb4 #查看
创建一个新的文件,查看是否双向绑定
[root@d6db1a46fdb4 home]# touch test.java #容器种创建一个文件
容器关机,在主机中进行修改文件在容器上也是可以同步的
容器的数据卸载了,但容器还在
以后我们修改只需要在主机中进行修改就好了。
(2).挂载MySql
docker pull mysql:5.7 #拉取镜像
docker images #查看镜像
# 运行MySql,需要做数据挂载,安装MySQL需要配置密码
-v 挂载 #可以挂载多个
-d 后台
-p 端口映射
-e MYSQL_ROOT_PASSWORD=AAA 密码
# 在启动成功后,我们在本地使用sqlyog来测试连接一下# sqlyog--连接到服务器3310---3310和容器内部的3306进行映射,这个时候我们就可以连接上了# 在本地测试新建一个数据库,查看一下我们映射的路径是否ok
---------------------------------------------------------------
# 启动MySQL,并且把主机的3310映射到容器的3306端口 然后挂载 数据库的配置,和数据库的信息
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
navicat 连接到服务器的3310,3310与容器内3306映射 所以可以访问
测试链接..
window下创建一个数据库,并在linux下同步
本地 把容器给删除了,但数据依然存在
3.具名挂载 & 匿名挂载
(1).匿名挂载
# 匿名挂载,
注意这里使用-P表示的指定随机的端口号,没有指定主机的位置信息 -v 容器内路径
[root@Jsxs home]# docker run -d -P --name nginx01 -v /etc/nginx nginx
[root@Jsxs home]# docker volume ls #匿名挂载信息查询
DRIVER VOLUME NAME
local 0f4d71c052604b6e9e65800064b6e39c2b2d0b38f94b45beaa84792807c0c914
local ac54910cfd4d3b0a5e7a6d129d94a717161b7644110348224a32fb952f7fb0eb
# 这里发现,这种就是匿名挂载,我们在-v只写了容器内的路径,没有写容器外的路径
------------------------------------------------------------------------
# 查看卷的具体信息
[root@Jsxs home]# docker inspect ac54910cfd4d3b0a5e7a6d129d94a717161b7644110348224a32fb952f7fb0eb
[
{
"CreatedAt": "2023-03-22T15:59:12+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/ac54910cfd4d3b0a5e7a6d129d94a717161b7644110348224a32fb952f7fb0eb/_data",
"Name": "ac54910cfd4d3b0a5e7a6d129d94a717161b7644110348224a32fb952f7fb0eb", 挂载的具体目录的地址
"Options": null,
"Scope": "local"
}
]
(2).具名挂载
# 具名挂载
docker run -d -P --name 名字 -v 具名名字:容器路径 镜像
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
---------------------------------------------------------------------
[root@Jsxs home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
f026e984d67a6b522ca380cfa6eec6424e918a672e268388d93ac2b8d276a773
[root@Jsxs home]# docker volum ls
docker: 'volum' is not a docker command.
See 'docker --help'
[root@Jsxs home]# docker volume ls
DRIVER VOLUME NAME
local 0f4d71c052604b6e9e65800064b6e39c2b2d0b38f94b45beaa84792807c0c914
local ac54910cfd4d3b0a5e7a6d129d94a717161b7644110348224a32fb952f7fb0eb
local juming-nginx
# 查看卷的具体信息
[root@Jsxs home]# docker inspect juming-nginx
[
{
"CreatedAt": "2023-03-22T16:12:01+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data", 挂载的具体目录的地址
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
所有Docker内的卷,没有指定目录的情况下都是在: /var/lib/docker/volumes/
(3).判断匿名挂载和具名挂载
# 如何确定是匿名挂载还是具名挂载,还是指定路径挂载
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载,卷名没有路径/
-v 宿主机路径:容器内路径 # 指定路径挂载,一般/开头
(4).扩展
# 通过 -v 容器内路径:ro rw 改变读写权限
ro readonly # 只读
rw readwrite # 可读可写
# 一旦设置了这个容器权限,容器对我们挂载出来的内容就有了限定了
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法进行操作的
4.数据卷之DockerFile 【自定义镜像+挂载】💥
DockerFile 就是用来构建docker镜像的构建文件! 命令脚本!
通过这个脚本可以生成镜像,镜像是一层层的,脚本一个个的命令,每个命令都是一层!
1. 创建一个drockerfile文件,名字可以自定义
2. 文件中的内容:
FROM Centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
---------------------------------------------------------------编写
[root@Jsxs home]# cd docker-test-volume/
[root@Jsxs docker-test-volume]# ls
[root@Jsxs docker-test-volume]# clear
[root@Jsxs docker-test-volume]# vim dockerfile1
[root@Jsxs docker-test-volume]# cat dockerfile1
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
#创建自定义镜像->
# -f 文件 -t 名字
[root@Jsxs docker-test-volume]# docker build -f dockerfile1 -t centos-test:1.0 .
[+] Building 0.0s (5/5) FINISHED
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from dockerfile1 0.0s
=> => transferring dockerfile: 120B 0.0s
=> [internal] load metadata for docker.io/library/centos:latest 0.0s
=> [1/1] FROM docker.io/library/centos 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:0282d836c4f5ab8268cf4ebcf33ca7109bd03217f82358c4fa764466139852f2 0.0s
=> => naming to docker.io/library/centos-test:1.0
---------------------------------------------------------------查看
[root@Jsxs /]# docker images #查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 14 months ago 141MB
tomcat 9.0 b8e65a4d736d 15 months ago 680MB
mysql 5.7 c20987f18b13 15 months ago 448MB
hello-world latest feb5d9fea6a5 18 months ago 13.3kB
centos-test 1.0 0282d836c4f5 18 months ago 231MB #获取成功
centos latest 5d0da3dc9764 18 months ago 231MB
portainer/portainer latest 580c0e4e98b0 2 years ago 79.1MB
---------------------------------------------------------------启动
启动我们生成的镜像并查看
[root@Jsxs /]# docker run -it --name myCentos 0282d836c4f5 /bin/bash
[root@96c226405ba9 /]# ls -l
这个卷和外部一定有一个同步的目录 -> 匿名挂载
[root@96c226405ba9 /]# cd volume01 #进入数据卷01
[root@96c226405ba9 volume01]# ls
[root@96c226405ba9 volume01]# touch container.txt #创建一个文件
[root@96c226405ba9 volume01]# ls
container.txt
[root@96c226405ba9 volume01]# exit #离开
exit
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
96c226405ba9 0282d836c4f5 "/bin/bash" 7 minutes ago Exited (0) 28 seconds ago myCentos
4aba86a517af portainer/portainer "/portainer" 4 hours ago Up 4 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
[root@Jsxs /]# docker inspect 96c226405ba9 #查看容器的详细信息
查看文件是否同步出去了
[root@Jsxs /]# cd /var/lib/docker/volumes/
同步
这种方式未来的使用非常多,因为我们自己通常会构建自己的镜像
假设构建镜像的时候没有挂载,需要自己手动挂载镜像 -v 卷名:容器内路径
5.数据卷容器 【容器和容器挂载】
注意:
1.bin/bash是规定镜像启动时执行这条命令,centos镜像启动时默认会执行/bin/bash.所以这里可以省略。
2.可以通过镜像ID和镜像名创建容器
[root@Jsxs docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 14 months ago 141MB
tomcat 9.0 b8e65a4d736d 15 months ago 680MB
mysql 5.7 c20987f18b13 15 months ago 448MB
hello-world latest feb5d9fea6a5 18 months ago 13.3kB
centos-test 1.0 0282d836c4f5 18 months ago 231MB
centos latest 5d0da3dc9764 18 months ago 231MB
portainer/portainer latest 580c0e4e98b0 2 years ago 79.1MB
[root@Jsxs docker-test-volume]# docker run -it --name docker01 centos-test:1.0 #新建容器并启动
[root@d0680299dc2b /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Mar 22 09:53 dev
drwxr-xr-x 1 root root 4096 Mar 22 09:53 etc
drwxr-xr-x 2 root root 4096 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 4096 Sep 15 2021 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 211 root root 0 Mar 22 09:53 proc
dr-xr-x--- 2 root root 4096 Sep 15 2021 root
drwxr-xr-x 11 root root 4096 Sep 15 2021 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Mar 22 09:53 sys
drwxrwxrwt 7 root root 4096 Sep 15 2021 tmp
drwxr-xr-x 12 root root 4096 Sep 15 2021 usr
drwxr-xr-x 20 root root 4096 Sep 15 2021 var
drwxr-xr-x 2 root root 4096 Mar 22 09:53 volume01 #数据卷
drwxr-xr-x 2 root root 4096 Mar 22 09:53 volume02 #数据卷
# 在docker01不停止的情况下,启动docker02并挂载01
docker run -it --name docker02 --volumes-from docker01 centos-test:1.0
[root@15849a421f0d /]# ls -l #
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Mar 22 10:10 dev
drwxr-xr-x 1 root root 4096 Mar 22 10:10 etc
drwxr-xr-x 2 root root 4096 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 4096 Sep 15 2021 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 217 root root 0 Mar 22 10:10 proc
dr-xr-x--- 2 root root 4096 Sep 15 2021 root
drwxr-xr-x 11 root root 4096 Sep 15 2021 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Mar 22 10:10 sys
drwxrwxrwt 7 root root 4096 Sep 15 2021 tmp
drwxr-xr-x 12 root root 4096 Sep 15 2021 usr
drwxr-xr-x 20 root root 4096 Sep 15 2021 var
drwxr-xr-x 2 root root 4096 Mar 22 09:53 volume01
drwxr-xr-x 2 root root 4096 Mar 22 09:53 volume02
root@Jsxs ~]#cd volume01
root@Jsxs volume01]# touch docker01Create.txt
[root@Jsxs ~]# docker attach d0680299dc2b #进入到docker01
[root@d0680299dc2b /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
[root@d0680299dc2b /]# cd volume01
[root@d0680299dc2b volume01]# ls #发现也存在
docker01Create.txt
容器和容器键相互挂载了
再此创建docker03
[root@Jsxs /]# docker run -it --name docker03 --volumes-from docker01 centos-test:1.0
[root@db1ab3bfc102 /]# docker ps
bash: docker: command not found
[root@db1ab3bfc102 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
[root@db1ab3bfc102 /]# cd volume01
[root@db1ab3bfc102 volume01]# ls
docker01Create.txt
[root@db1ab3bfc102 volume01]# touch docker03
[root@db1ab3bfc102 volume01]# ls
docker01Create.txt docker03
[root@db1ab3bfc102 volume01]# [root@Jsxs /]#
[root@Jsxs /]# docker attach docker01
[root@d0680299dc2b volume01]# ls
docker01Create.txt docker03
删除docker01也就是我们的父容器
[root@Jsxs /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
db1ab3bfc102 centos-test:1.0 "/bin/sh -c /bin/bash" 3 minutes ago Up 3 minutes docker03
15849a421f0d centos-test:1.0 "/bin/sh -c /bin/bash" 31 minutes ago Up 31 minutes docker02
d0680299dc2b centos-test:1.0 "/bin/sh -c /bin/bash" 48 minutes ago Up 48 minutes docker01
4aba86a517af portainer/portainer "/portainer" 6 hours ago Up 5 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
[root@Jsxs /]# docker rm -f d0680299dc2b
d0680299dc2b
[root@Jsxs /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
db1ab3bfc102 centos-test:1.0 "/bin/sh -c /bin/bash" 4 minutes ago Up 4 minutes docker03
15849a421f0d centos-test:1.0 "/bin/sh -c /bin/bash" 32 minutes ago Up 32 minutes docker02
4aba86a517af portainer/portainer "/portainer" 6 hours ago Up 5 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
[root@Jsxs /]# docker attach docker02
[root@15849a421f0d volume01]# ls
docker01Create.txt docker03
6. 多个MySql数据共享
docker run -d -p 3310:3306
-v /etc/mysql/conf.d
-v /var/lib/mysql
-e MYSQL_ROOT_PASSWORD=338218
--name mysql01 mysql:5.7
docker run -d -p 3311:3306
-e MYSQL_ROOT_PASSWORD=338218
--name mysql02
--volumes-from mysql01 mysql:5.7
# 这个时候可以实现两个容器数据同步
结论:
- 容器之间配置信息的传递,数据卷容器的生命周期这一直持续到没有容器使用为止。(复制)
- 但是一旦持久化到了本地,这个时候,本地的数据不会被删除
(七)、DockerFile
dockerfile是用来构建docker镜像的文件,命令参数脚本
1.构建步骤:
- 编写一个dockerfile文件
- docker build构建为一个镜像
- docker run 运行镜像
- docker push发布镜像(DockerHub、阿里云镜像仓库)
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20201113" \
org.opencontainers.image.title="CentOS Base Image" \
org.opencontainers.image.vendor="CentOS" \
org.opencontainers.image.licenses="GPL-2.0-only" \
org.opencontainers.image.created="2020-11-13 00:00:00+00:00"
CMD ["/bin/bash"]
- 很多官方的镜像都是基础包,很多功能都没有(只是基础包)。我们通常会自己搭建自己的镜像
2.基础知识:
1、每个保留关键字(指令)都是必须是----大写字母!!!!!
2、执行从上到下顺序执行
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交
- dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
- Docker镜像逐渐成为了企业交付的标准,必须要掌握!!!
步骤:开发,部署,运维…缺一不可
- DockerFile:构建文件,定义了一切的步骤,源代码
- DockerImages:
通过DockerFile构建生成的镜像,最终发布和运行的产品
- Docker容器:
容器就是镜像运行起来提供服务的
3.DockerFile 指令
我们可以通过这些指令进行自定义基础镜像
FROM # 基础镜像,一切从这里开始
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤:往里面加东西:tomcat镜像,这个tomcat压缩包,添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 暴露端口配置
CMD # 指定容器运行时的shell命令,只有最后一个生效,可被替代
ENTRYPOINT # 指定容器运行时的shell命令,可以追加命令
ONBUILD # 当构建一个被继承DockerFile这个时候就会运行ONBUILD的指令,触发指令
COPY # 类似ADD,将我们文件拷贝到镜像中,但不会自动解压
ENV # 构建的时候设置环境变量
4.实战测试
Docker Hub中99%镜像都是从这个
Github-centos-7源码
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20201113" \
org.opencontainers.image.title="CentOS Base Image" \
org.opencontainers.image.vendor="CentOS" \
org.opencontainers.image.licenses="GPL-2.0-only" \
org.opencontainers.image.created="2020-11-13 00:00:00+00:00"
CMD ["/bin/bash"]
(1). 创建一个自己的centos
1. 编写一个DockerFile配置文件
FROM centos:7 #来源于哪?
MAINTAINER jsxs<2261203961@qq.com> #作者信息
ENV MYPATH /usr/local #设置默认pwd路径
WORKDIR $MYPATH #工作目录
RUN yum -y install vim #安装vim镜像
RUN yum -y install net-tools #安装工具镜像
EXPOSE 80 #暴漏端口80
CMD echo $MYPATH #输出文件
CMD echo "-----end---"
CMD /bin/bash #运行中执行这个命令
-------------------------------
2. 构建镜像
docker build -f mysockerfile -t jsxs-centos:1.0 .
3.测试运行
docker run -it --name jsxs-centos01 jsxs-centos:1.0
4. 研究怎么做的
docker history 0ab761aa5334
IMAGE CREATED CREATED BY SIZE COMMENT
0ab761aa5334 11 minutes ago CMD ["/bin/sh" "-c" "/bin/bash"] 0B buildkit.dockerfile.v0
<missing> 11 minutes ago CMD ["/bin/sh" "-c" "echo \"-----end---\""] 0B buildkit.dockerfile.v0
<missing> 11 minutes ago CMD ["/bin/sh" "-c" "echo $MYPATH"] 0B buildkit.dockerfile.v0
<missing> 11 minutes ago EXPOSE map[80/tcp:{}] 0B buildkit.dockerfile.v0
<missing> 11 minutes ago RUN /bin/sh -c yum -y install net-tools # bu… 25MB buildkit.dockerfile.v0
<missing> 11 minutes ago RUN /bin/sh -c yum -y install vim # buildkit 259MB buildkit.dockerfile.v0
<missing> 11 minutes ago WORKDIR / 0B buildkit.dockerfile.v0
<missing> 11 minutes ago ENV YPATH=/usr/local 0B buildkit.dockerfile.v0
<missing> 11 minutes ago MAINTAINER jsxs<2261203961@qq.com> 0B buildkit.dockerfile.v0
<missing> 18 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 18 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 18 months ago /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB
构建镜像
我们发现我们自定义的镜像增加了好多命令
5.CMD 与 ENTRYPOINT 区别
(1).CMD
覆盖
CMD
------------------------
[root@Jsxs dockerfile]# vim dockerfile-cmd-test #编写文件
FROM centos:7
CMD ["ls","-a"]
-------
# 构建文件 -f 打包的文件 -t 打包后的镜像标题
[root@Jsxs dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .
[+] Building 0.4s (5/5) FINISHED
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from dockerfile-cmd-test 0.1s
=> => transferring dockerfile: 76B 0.0s
=> [internal] load metadata for docker.io/library/centos:7 0.4s
=> CACHED [1/1] FROM docker.io/library/centos:7@sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:d53776618e7ca21294bf0d76a1042fa5976f2b0992727c1122ede2900cd8ba93 0.0s
=> => naming to docker.io/library/cmdtest 0.0s
-----
# 创建容器并执行
[root@Jsxs dockerfile]# docker run -it --name testcmd1 cmdtest
. .. .dockerenv anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
我们像追加一个命令 -l "ls -al"显示全部数据,-l;不是命令所以报错
[root@Jsxs dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jsxs-centos 1.0 0ab761aa5334 31 minutes ago 488MB
nginx latest 605c77e624dd 14 months ago 141MB
tomcat 9.0 b8e65a4d736d 15 months ago 680MB
mysql 5.7 c20987f18b13 15 months ago 448MB
cmdtest latest d53776618e7c 18 months ago 204MB
centos latest 5d0da3dc9764 18 months ago 231MB
centos-test 1.0 0282d836c4f5 18 months ago 231MB
portainer/portainer latest 580c0e4e98b0 2 years ago 79.1MB
[root@Jsxs dockerfile]# docker run d53776618e7c -l
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-l": executable file not found in $PATH: unknown.
我们需要编写一个完整的命令进行替换-
[root@Jsxs ~]# docker run d53776618e7c ls -al
total 64
drwxr-xr-x 1 root root 4096 Mar 22 14:38 .
drwxr-xr-x 1 root root 4096 Mar 22 14:38 ..
-rwxr-xr-x 1 root root 0 Mar 22 14:38 .dockerenv
-rw-r--r-- 1 root root 12114 Nov 13 2020 anaconda-post.log
lrwxrwxrwx 1 root root 7 Nov 13 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 Mar 22 14:38 dev
drwxr-xr-x 1 root root 4096 Mar 22 14:38 etc
drwxr-xr-x 2 root root 4096 Apr 11 2018 home
lrwxrwxrwx 1 root root 7 Nov 13 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 13 2020 lib64 -> usr/lib64
drwxr-xr-x 2 root root 4096 Apr 11 2018 media
drwxr-xr-x 2 root root 4096 Apr 11 2018 mnt
drwxr-xr-x 2 root root 4096 Apr 11 2018 opt
dr-xr-xr-x 225 root root 0 Mar 22 14:38 proc
dr-xr-x--- 2 root root 4096 Nov 13 2020 root
drwxr-xr-x 11 root root 4096 Nov 13 2020 run
lrwxrwxrwx 1 root root 8 Nov 13 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Apr 11 2018 srv
dr-xr-xr-x 13 root root 0 Mar 22 14:38 sys
drwxrwxrwt 7 root root 4096 Nov 13 2020 tmp
drwxr-xr-x 13 root root 4096 Nov 13 2020 usr
drwxr-xr-x 18 root root 4096 Nov 13 2020 var
(2).ENTRYPOINT
追加
vim dockerfile-cmd-entrypoint
FROM centos:7
ENTRYPOINT ["ls","-a"]
[root@Jsxs dockerfile]# docker build -f dockerfile-cmd-entrypoint -t entrypointtest .
[+] Building 15.4s (5/5) FINISHED
=> [internal] load build definition from dockerfile-cmd-entrypoint 0.0s
=> => transferring dockerfile: 89B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:7 15.4s
=> CACHED [1/1] FROM docker.io/library/centos:7@sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:dbcf4f99ed1cde79a9a4034b78ca79e0829f3e83bc9830a34065a1918f0dbcfa 0.0s
=> => naming to docker.io/library/entrypointtest 0.0s
[root@Jsxs dockerfile]# docker run
"docker run" requires at least 1 argument.
See 'docker run --help'.
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Create and run a new container from an image
[root@Jsxs dockerfile]#
[root@Jsxs dockerfile]# docker run entrypointtest
.
..
.dockerenv
anaconda-post.log
bin
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 拼接 追加
[root@Jsxs dockerfile]# docker run entrypointtest -l
total 64
drwxr-xr-x 1 root root 4096 Mar 22 14:46 .
drwxr-xr-x 1 root root 4096 Mar 22 14:46 ..
-rwxr-xr-x 1 root root 0 Mar 22 14:46 .dockerenv
-rw-r--r-- 1 root root 12114 Nov 13 2020 anaconda-post.log
lrwxrwxrwx 1 root root 7 Nov 13 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 Mar 22 14:46 dev
drwxr-xr-x 1 root root 4096 Mar 22 14:46 etc
drwxr-xr-x 2 root root 4096 Apr 11 2018 home
lrwxrwxrwx 1 root root 7 Nov 13 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 13 2020 lib64 -> usr/lib64
drwxr-xr-x 2 root root 4096 Apr 11 2018 media
drwxr-xr-x 2 root root 4096 Apr 11 2018 mnt
drwxr-xr-x 2 root root 4096 Apr 11 2018 opt
dr-xr-xr-x 223 root root 0 Mar 22 14:46 proc
dr-xr-x--- 2 root root 4096 Nov 13 2020 root
drwxr-xr-x 11 root root 4096 Nov 13 2020 run
lrwxrwxrwx 1 root root 8 Nov 13 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Apr 11 2018 srv
dr-xr-xr-x 13 root root 0 Mar 22 14:46 sys
drwxrwxrwt 7 root root 4096 Nov 13 2020 tmp
drwxr-xr-x 13 root root 4096 Nov 13 2020 usr
drwxr-xr-x 18 root root 4096 Nov 13 2020 var
6.实战Tomcat镜像
(1).准备 tomcat 与 jdk 安装包
(2).编写Dockerfile
文件
Dockerfile 是官方名字,我们启动的时候就会自动寻找这个名字。
[root@Jsxs jsxs]# touch readme.md
[root@Jsxs jsxs]# vim Dockerfile
FROM centos:7
MAINTAINER jsxs<2261203961@qq.com>
COPY readme.md /usr/local/readme.md
ADD jdk-8u202-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.73.tar.gz /usr/local
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_202
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.73
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.73
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.73/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.73/logs/catalina.out
(3).构建镜像
docker build -f Dockerfile -t diytomcat .
[+] Building 53.8s (11/11) FINISHED
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.2s
=> => transferring dockerfile: 665B 0.0s
=> [internal] load metadata for docker.io/library/centos:7 15.4s
=> [internal] load build context 4.0s
=> => transferring context: 190.09MB 3.3s
=> CACHED [1/6] FROM docker.io/library/centos:7@sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987 0.0s
=> [2/6] COPY readme.md /usr/local/readme.md 0.2s
=> [3/6] ADD jdk-8u202-linux-x64.rpm /usr/local 3.6s
=> [4/6] ADD apache-tomcat-9.0.73.tar.gz /usr/local 1.1s
=> [5/6] RUN yum -y install vim 20.3s
=> [6/6] WORKDIR /usr/local 0.2s
=> exporting to image 8.1s
=> => exporting layers 7.8s
=> => writing image sha256:0e1f35086fef111eaeda3d551188b84844a446a49bd6d24ef4319b16f06458ce 0.0s
=> => naming to docker.io/library/diytomcat 0.0s
(4).创建容器并开启
docker run -d -p 9090:8080 --name jsxstomcat -v /home/jsxs/test:/usr/local/apache-tomcat-9.0.73/webapps/test -v /home/jsxs/testlog/:/usr/local/apache-tomcat-9.0.73/logs diytomcat
----------------
# 解释,第一个挂载是将webapps下的test映射到本地tomcat下的test
-v /home/eric/build/tomcat/test:/usr/local/apache-tomcat-9.0.8/webapps/test
# 解释,第二个挂载是将apache-tomcat-9.0.8下的日志映射到本地tomcat下的tomcatlogs
-v /home/eric/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.8/logs
----------------------
(5).开启容器
[root@Jsxs ~]# docker exec -it 52300f8c0167b2d23726c7acb135081462a1a31cf31d1756654176f6f43c7f32 /bin/bash
[root@52300f8c0167 local]# pwd
/usr/local
[root@52300f8c0167 local]# ls
apache-tomcat-9.0.73 bin etc games include jdk1.8.0_202 lib lib64 libexec readme.md sbin share src
外网访问测试成功!!
(6).发布项目
(由于做了卷挂载,我们直接在本地编写项目就可以发布了)
[root@Jsxs test]# mkdir WEB-INF
[root@Jsxs test]# ls
WEB-INF
[root@Jsxs test]# cd WEB-INF/
[root@Jsxs WEB-INF]# vim web.xml
[root@Jsxs WEB-INF]# cat 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>
[root@Jsxs WEB-INF]# cd ..
[root@Jsxs test]# vim index.jsp
[root@Jsxs test]# cat index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello. xiaofan</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("-----my test web logs------");
%>
</body>
</html>
-----------------------------------------------------------------------------------
# 这是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>
-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
# 这是index.jsp内容
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello. xiaofan</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("-----my test web logs------");
%>
</body>
</html>
------------------------------------------------------------------
ls -tail -f #可以动态查看列表
发现:项目部署成功, 可以直接访问ok!
我们以后开发的步骤:需要掌握Dockerfile的编写! 我们之后的一切都是使用docker进行来发布运行的!
7.发布我们的镜像到DockerHub
2、注册账号,确定这个账号可以登录 邮箱 + 经典密码 注意首字母大写
3、登录服务器
用docker login -u [用户名],然后输入密码就可以登录成功
[root@Jsxs /]# docker login -u 2261203961
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
4、登录完毕后就可以提交上去镜像,就是一步 docker push
首先我们要创建一个仓库: 会帮助我们生成账号/仓库名
1. 创建tag
docker tag 需要提交镜像的id 账户名/仓库名:版本
2. 提交
docker push 账户名/仓库名:版本号![在这里插入图片描述](https://img-blog.csdnimg.cn/c5e405a5520c429bbd372b22e311f090.png)
8.发布我们的镜像到阿里云
-
登录阿里云
-
找到容器镜像服务:https://cr.console.aliyun.com/cn-beijing/instance/new
-
创建命名空间
-
然后创建仓库,创建完毕之后会出现操作指南
以下内容参考阿里云官方文档
docker pull 账户名/仓库名:[tag]
(八)、 Docker网络
1. 查看本机ip地址
root@Jsxs jsxs]# ip addr
详细解释:
有三个网络,代表三种不同环境。
两个容器之间是怎么通信的,用的是哪个网络进行链接的
# 问题: docker是如何处理容器网络访问的?
1.一定要是7版本
docker run -d -P --name tomcat01 tomcat:7 #创建一个容器并启动
-------
2.进入正在运行的容器,但是不用
# 进入的命令,但是不用
docker exec -it tomcat01 /bin/bash #这是进入命令,但是我们不用
-------
3.查看IP
docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
104: eth0@if105: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
-------
# 思考: 每一个容器都有一个ip地址,linux能否ping通容器内部?
[root@Jsxs jsxs]# 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.101 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.049 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.050 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.052 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.060 ms
#说明我们的linux可以ping通docker容器内部💥
(1).原理
1.正常家庭中: 路由器
路由器也是源头: 192.168.01。然后如果有链接到这个网络的就会变成192.168.02。遇9进1
手机wifi
相同的网关是能够ping通的。这也就是我们linux能够ping 通容器的原因。
- 测试容器和Linux的网卡
1、我们每启动一个docker容器,docker就会给docker容器分配一个ip
,我们只要安装了docker,就会有一个网卡 docker0
桥接模式 ,使用的技术是 evth-pair技术
再次测试ip addr,多了一对网卡
再次创建一个容器,我们发现又多了一对网卡
再次查看容器,我们发现容器的网卡和Linux的网卡一致
我们发现这些网卡都是一对对的
veth-pair 就是一对的虚拟设备接口,它们都是成对出现
的,一段连着协议,一段彼此相连
正因为有这个特性veth-pair充当一个桥梁
,连接各种虚拟网络设备OpenStack,Docker容器之间的连接
,OVS的连接,都是使用veth-pair技术
3.测试tomcat01和tomcat02是否可以ping通
[root@Jsxs jsxs]# docker exec -it tomcat01 ip addr #查看容器01的ip
---
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
104: eth0@if105: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@Jsxs jsxs]# docker exec -it tomcat02 ip addr 查看容器02的ip
---
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
106: eth0@if107: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
--- 127.0.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 39ms
rtt min/avg/max/mdev = 0.028/0.030/0.032/0.004 ms
[root@Jsxs jsxs]# docker exec -it tomcat02 ping 127.0.0.2 #容器02能ping通01
---
PING 127.0.0.2 (127.0.0.2) 56(84) bytes of data.
64 bytes from 127.0.0.2: icmp_seq=1 ttl=64 time=0.026 ms
64 bytes from 127.0.0.2: icmp_seq=2 ttl=64 time=0.027 ms
^C
--- 127.0.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 51ms
rtt min/avg/max/mdev = 0.026/0.026/0.027/0.005 ms
总结: 两个容器之间是相互ping通的
结论:tomcat01和tomcat02是共用的一个路由器,docker0
所有的容器在不指定网络的情况下,都是由docker0路由的,docker会给我们的容器分配一个默认的可用ip
(2).总结
Docker中所有的网络接口都是虚拟的,虚拟的转发效率比较高(内网传递文件,网速很快!
)
只要容器删除,对应的网桥就没了,那一对就没了。
2. --link 【容器名访问1-同网关下】
思考一个场景,我们编写了一个微服务,database url=ip:,项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以通过名字来访问容器?
我们开启两个容器,用容器名字 容器一ping容器2发现ping不同
[root@Jsxs ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84c6f65362d5 tomcat:7 "catalina.sh run" 8 seconds ago Up 6 seconds 0.0.0.0:32774->8080/tcp, :::32774->8080/tcp tomca02
36709d50b053 tomcat:7 "catalina.sh run" 22 seconds ago Up 20 seconds 0.0.0.0:32773->8080/tcp, :::32773->8080/tcp tomca01
4aba86a517af portainer/portainer "/portainer" 41 hours ago Up 41 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
[root@Jsxs ~]# docker exec -it tomcat02 ping tomcat01 #ping不通
Error response from daemon: No such container: tomcat02
如何才能让容器名能ping通容器名呢? --link
# 把容器三链接容器2
[root@Jsxs ~]# docker run -d -P --name tomca03 --link tomca02 tomcat:7
aaaf842b749d2c9c9abd9b1279fa6ee4528190069dbce885752bd8b850105dd9
#容器三ping 容器2 能够ping通
[root@Jsxs ~]# docker exec -it tomca03 ping tomca02
PING tomca02 (172.17.0.4) 56(84) bytes of data.
64 bytes from tomca02 (172.17.0.4): icmp_seq=1 ttl=64 time=0.123 ms
64 bytes from tomca02 (172.17.0.4): icmp_seq=2 ttl=64 time=0.084 ms
^C
--- tomca02 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 30ms
rtt min/avg/max/mdev = 0.084/0.103/0.123/0.022 ms
---------------
#链接只是单向链接,只有主动链接的那方才能ping到被动链接的一方.
[root@Jsxs ~]# docker exec -it tomca02 ping tomca03
ping: tomca03: Name or service not known
docker network
[root@Jsxs ~]# docker network command
Usage: docker network COMMAND #查看网络命令
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
[root@Jsxs ~]# docker network ls #列出所有网卡
NETWORK ID NAME DRIVER SCOPE
dd0a347647db bridge bridge local
3393698886d8 host host local
bc710e60b055 none null local
[root@Jsxs ~]# docker network inspect dd0a347647db #查看详情
发现找到了docker 0
查看主动连接方的域名映射
# 查看配置文件
[root@Jsxs ~]# docker exec -it tomca03 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.4 tomca02 84c6f65362d5
172.17.0.5 aaaf842b749d
我们查看03的域名映射配置文件,发现再配置文件中配置了
> >
其实这个tomcat03就是本地配置了tomcat02的配置
本质探究:–link就是我们在hosts配置中增加了一个172.17.0.3 tomcat02 9f6a048802b9
我们现在 玩Docker已经不建议使用–link了!
自定义网络!不适用于docker0!
docker0问题:他不支持容器名连接访问!
3.自定义网络 【容器名访问2-同网关下】
- 查看docker 所有的网络
[root@Jsxs ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
dd0a347647db bridge bridge local
3393698886d8 host host local
bc710e60b055 none null local
网络模式
- bridge:
桥接模式
,桥接 docker 默认,(自己创建的也是用brdge模式) - none: 不配置网络
- host:
和宿主机共享网络
- container:容器网络连通!(用的少, 局限很大)
清除之前的容器
[root@Jsxs ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4aba86a517af portainer/portainer "/portainer" 42 hours ago Up 42 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
[root@Jsxs ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:16:3e:03:83:df brd ff:ff:ff:ff:ff:ff
altname enp0s5
altname ens5
inet 172.31.191.78/20 brd 172.31.191.255 scope global dynamic noprefixroute eth0
valid_lft 312743668sec preferred_lft 312743668sec
inet6 fe80::216:3eff:fe03:83df/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:be:a4:a7:ab brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:beff:fea4:a7ab/64 scope link
valid_lft forever preferred_lft forever
37: vetheea9b46@if36: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 8a:63:65:91:25:5d brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::8863:65ff:fe91:255d/64 scope link
valid_lft forever preferred_lft forever
创建网络并配置
# 我们直接启动的命令默认有一个 --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 可以支持255*255个网络 192.168.0.2 ~ 192.168.255.254
# 网关(路由):💥
# --gateway 192.168.0.1
# 创建一个网络要具备子网掩码和网关
[root@Jsxs ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
5448dff92c6d110b8c8244680aefca28dd963c6922f55d70a0b68334fbff778b
[root@Jsxs ~]# docker network ls #列出所有网络
NETWORK ID NAME DRIVER SCOPE
dd0a347647db bridge bridge local
3393698886d8 host host local
5448dff92c6d mynet bridge local #我们发现配置过来了
bc710e60b055 none null local
[root@Jsxs ~]# docker network inspect mynet #查看自己配置的网络
[
{
"Name": "mynet",
"Id": "5448dff92c6d110b8c8244680aefca28dd963c6922f55d70a0b68334fbff778b",
"Created": "2023-03-24T07:17:20.449158739+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": {}
}
]
# 启动两个容器且链接的是我们自定义的网络,不是默认的docker0
[root@Jsxs ~]# docker run -d -P --name tomcat-net01 --net mynet tomcat:7
5fe933028495f925de8f41a5c3d8f3d135c9a16d56e5341e976089869574ef71
[root@Jsxs ~]# docker run -d -P --name tomcat-net02 --net mynet tomcat:7
2aafcc14d5be0bf195fa308bd01b1b2caa9bafcc2e791c9dcf3d2514d8e388ab
[root@Jsxs ~]# docker network inspect mynet #查看我们的网络
[
{
"Name": "mynet",
"Id": "5448dff92c6d110b8c8244680aefca28dd963c6922f55d70a0b68334fbff778b",
"Created": "2023-03-24T07:17:20.449158739+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": {
"2aafcc14d5be0bf195fa308bd01b1b2caa9bafcc2e791c9dcf3d2514d8e388ab": {
"Name": "tomcat-net02",
"EndpointID": "140baed084e3fbc4f0987ec28990f736c9b4f9aa6265b80c5f67a4cbe265147e",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16", #分给容器的ip
"IPv6Address": ""
},
"5fe933028495f925de8f41a5c3d8f3d135c9a16d56e5341e976089869574ef71": {
"Name": "tomcat-net01",
"EndpointID": "ef5d7b44cd33b061256e476a772cfcf5287ef90da4b16125949202eb0c8e2a8a",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16", #分配给容器的ip
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
# ping另一个容器的ip地址
[root@Jsxs ~]# docker exec -it tomcat-net01 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.136 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.091 ms
^C
--- 192.168.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 37ms
rtt min/avg/max/mdev = 0.091/0.113/0.136/0.024 ms
# ping另一个容器的容器名
[root@Jsxs ~]# docker exec -it tomcat-net01 ping tomcat-net02
PING tomcat-net02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.113 ms
64 bytes from tomcat-net02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.075 ms
^C
--- tomcat-net02 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 22ms
rtt min/avg/max/mdev = 0.075/0.094/0.113/0.019 ms
我们自定义的网络Docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络。
好处:
假如说我们现在有两个集群,第一个是redis,另外一个是mysql.我们为这两个集群各自搭建一个网络。网络之间是相互的隔离,它们每一个网络都有自己的子网,不同的集群使用不同的网络,保证集群式安全和健康的。
4.网络联通 【容器名访问3-不同网关下】
网段不同是不能链接的.比如redis容器的网段是172.161和mysql容器的网段192.468是不能访问的。(但可以通过ip)
准备工作: 两个容器为默认网关,两个容器为自定义网关
#利用默认的网关创建两个容器
[root@Jsxs ~]# docker run -d -P --name tomcat01 tomcat:7
eff41cae899dc04a3b7f4ffb6fc525c2eeb842ab967ce0650cbdd58e220e54e0
^[[A[root@Jsxs docker run -d -P --name tomcat02 tomcat:7
541a17ac68ce4358932876a7a47bee674679ba2449f9a6726cf9de2c5990ffee
[root@Jsxs ~]# docker ps #存在四个容器,两个是默认网关,两个是自定义网关
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
541a17ac68ce tomcat:7 "catalina.sh run" 7 seconds ago Up 6 seconds 0.0.0.0:32780->8080/tcp, :::32779->8080/tcp tomcat02
eff41cae899d tomcat:7 "catalina.sh run" 43 seconds ago Up 40 seconds 0.0.0.0:32779->8080/tcp, :::32778->8080/tcp tomcat01
2aafcc14d5be tomcat:7 "catalina.sh run" 27 minutes ago Up 27 minutes 0.0.0.0:32777->8080/tcp, :::32777->8080/tcp tomcat-net02
5fe933028495 tomcat:7 "catalina.sh run" 27 minutes ago Up 27 minutes 0.0.0.0:32776->8080/tcp, :::32776->8080/tcp tomcat-net01
4aba86a517af portainer/portainer "/portainer" 43 hours ago Up 43 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
不同网卡的容器通过容器名访问时联不通的
[root@Jsxs ~]# docker exec tomcat01 ping tomcat-net01
ping: tomcat-net01: Name or service not known
# 但是能够ping通ip地址
[root@Jsxs ~]# docker exec tomcat01 ping 192.168.02
PING 192.168.02 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=63 time=0.139 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=63 time=0.097 ms
如何解决?
不通网关下的tomcat之间无法直接连接(容器名字)。为了实现docker01网络中的中的tomcat01可以连接mynet网络中的tomcat-net-01.需要使用网络连通
开始联通操作!!
docker network connect 网络 容器
# 把docker0网关的容器01连同网关mynet
[root@Jsxs ~]# docker network connect mynet tomcat01
[root@Jsxs ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "5448dff92c6d110b8c8244680aefca28dd963c6922f55d70a0b68334fbff778b",
"Created": "2023-03-24T07:17:20.449158739+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": {
"2aafcc14d5be0bf195fa308bd01b1b2caa9bafcc2e791c9dcf3d2514d8e388ab": {
"Name": "tomcat-net02",
"EndpointID": "140baed084e3fbc4f0987ec28990f736c9b4f9aa6265b80c5f67a4cbe265147e",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"5fe933028495f925de8f41a5c3d8f3d135c9a16d56e5341e976089869574ef71": {
"Name": "tomcat-net01",
"EndpointID": "ef5d7b44cd33b061256e476a772cfcf5287ef90da4b16125949202eb0c8e2a8a",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
我们发现打通之后,就是将tomcat01放到mynet网络下。分配了另一个ip
"eff41cae899dc04a3b7f4ffb6fc525c2eeb842ab967ce0650cbdd58e220e54e0": {
"Name": "tomcat01",
"EndpointID": "cc25560f092acb93077d4180be28edd1199456b38fcc1251c09fc46ec449fbcb",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
就把容器tomcat01 加到了 mynet网络中了,mynet为其分配了另一个ip。
一个容器两个IP:阿里云服务:公网ip 私网ip
容器tomcat01成功打通网关能访问,但tomcat02没有打通不能访问
[root@Jsxs ~]# docker exec -it tomcat01 ping tomcat-net02
PING tomcat-net02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.109 ms
64 bytes from tomcat-net02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.083 ms
64 bytes from tomcat-net02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.072 ms
64 bytes from tomcat-net02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.071 ms
[root@Jsxs ~]# docker exec -it tomcat02 ping tomcat-net02
ping: tomcat-net02: Name or service not known
假设要跨网络操作别人的电脑,就需要使用docker network connect 联通
5.部署Redis集群
上面是主力机,下面是备用机
如果上面挂了,下面的就要去替代上面的。
[root@Jsxs ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4aba86a517af portainer/portainer "/portainer" 43 hours ago Up 43 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
[root@Jsxs ~]# docker network create redis --subnet 172.38.0.0/16
b30cea89bd6c28834a7cf459b4b86471a3897e2caa20064f3ac0d3dc0a8681bb
[root@Jsxs ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
dd0a347647db bridge bridge local
3393698886d8 host host local
5448dff92c6d mynet bridge local
bc710e60b055 none null local
b30cea89bd6c redis bridge local
-------------------------------------------------------------------------
通过脚本创建六个redis配置
直接复制到命令行运行即可
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf #再目录/mydata中
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@Jsxs ~]# 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@Jsxs ~]# cd /mydata
[root@Jsxs mydata]# ls
redis
[root@Jsxs mydata]# cd redis/
[root@Jsxs redis]# ls
node-1 node-2 node-3 node-4 node-5 node-6
---------------------------------------------------------------------------------
上面就是创建的6个redis配置
下面开始运行创建的6个节点
# 开始运行并创建6个容器,端口映射6379 名字 数据卷绑定 网络使用redis网络并绑定ip
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 6372:6379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
-v /mydata/redis/node-3/data:/data \
-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
-v /mydata/redis/node-4/data:/data \
-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.15 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
---
[root@Jsxs redis]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e0a19eb367dc redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 8 seconds ago Up 6 seconds 0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp redis-6
68cf748d322f redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 17 seconds ago Up 16 seconds 0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp redis-5
a5504370b19d redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 31 seconds ago Up 29 seconds 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp redis-4
f3d61ce52b42 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 39 seconds ago Up 38 seconds 0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp redis-3
175c61fc2523 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 53 seconds ago Up 52 seconds 0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp redis-2
d4050cf76348 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp redis-1
4aba86a517af portainer/portainer "/portainer" 44 hours ago Up 44 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
---
- 搭建集群
[root@Jsxs redis]# docker exec -it redis-1 /bin/bash
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/bash": stat /bin/bash: no such file or directory: unknown
[root@Jsxs redis]# docker exec -it redis-1 /bin/sh #启动集群1
/data # ls
appendonly.aof nodes.conf
#搭建集群
[root@Jsxs redis]# 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-replicas 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: a1a026ec68ef5d0f1089082bb5d9f3d986f0a920 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: e36cbe81e72f8b4ebfbf9a82b18fe11ea38c8720 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: 46e745ac115598f54975b2ad4432dc087d678df7 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: 121b91b02057378351c43b63abf62c7c5a281bf6 172.38.0.14:6379
replicates 46e745ac115598f54975b2ad4432dc087d678df7
S: 93ff81b2883180b3266186f42caed428d01b6199 172.38.0.15:6379
replicates a1a026ec68ef5d0f1089082bb5d9f3d986f0a920
S: af14b91dd41e0470d4c28702340716c48e61eb66 172.38.0.16:6379
replicates e36cbe81e72f8b4ebfbf9a82b18fe11ea38c8720
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: a1a026ec68ef5d0f1089082bb5d9f3d986f0a920 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: e36cbe81e72f8b4ebfbf9a82b18fe11ea38c8720 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 93ff81b2883180b3266186f42caed428d01b6199 172.38.0.15:6379
slots: (0 slots) slave
replicates a1a026ec68ef5d0f1089082bb5d9f3d986f0a920
M: 46e745ac115598f54975b2ad4432dc087d678df7 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 121b91b02057378351c43b63abf62c7c5a281bf6 172.38.0.14:6379
slots: (0 slots) slave
replicates 46e745ac115598f54975b2ad4432dc087d678df7
S: af14b91dd41e0470d4c28702340716c48e61eb66 172.38.0.16:6379
slots: (0 slots) slave
replicates e36cbe81e72f8b4ebfbf9a82b18fe11ea38c8720
[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:454
cluster_stats_messages_pong_sent:471
cluster_stats_messages_sent:925
cluster_stats_messages_ping_received:466
cluster_stats_messages_pong_received:454
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:925
127.0.0.1:6379> cluster nodes
e36cbe81e72f8b4ebfbf9a82b18fe11ea38c8720 172.38.0.12:6379@16379 master - 0 1679619838764 2 connected 5461-10922
93ff81b2883180b3266186f42caed428d01b6199 172.38.0.15:6379@16379 slave a1a026ec68ef5d0f1089082bb5d9f3d986f0a920 0 1679619838262 5 connected
46e745ac115598f54975b2ad4432dc087d678df7 172.38.0.13:6379@16379 master - 0 1679619839795 3 connected 10923-16383
121b91b02057378351c43b63abf62c7c5a281bf6 172.38.0.14:6379@16379 slave 46e745ac115598f54975b2ad4432dc087d678df7 0 1679619838000 4 connected
af14b91dd41e0470d4c28702340716c48e61eb66 172.38.0.16:6379@16379 slave e36cbe81e72f8b4ebfbf9a82b18fe11ea38c8720 0 1679619839565 6 connected
a1a026ec68ef5d0f1089082bb5d9f3d986f0a920 172.38.0.11:6379@16379 myself,master - 0 1679619837000 1 connected 0-5460
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
172.38.0.13:6379> get a
^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
121b91b02057378351c43b63abf62c7c5a281bf6 172.38.0.14:6379@16379 myself,master - 0 1679620066000 7 connected 10923-16383
a1a026ec68ef5d0f1089082bb5d9f3d986f0a920 172.38.0.11:6379@16379 master - 0 1679620067986 1 connected 0-5460
af14b91dd41e0470d4c28702340716c48e61eb66 172.38.0.16:6379@16379 slave e36cbe81e72f8b4ebfbf9a82b18fe11ea38c8720 0 1679620067484 6 connected
93ff81b2883180b3266186f42caed428d01b6199 172.38.0.15:6379@16379 slave a1a026ec68ef5d0f1089082bb5d9f3d986f0a920 0 1679620066453 5 connected
e36cbe81e72f8b4ebfbf9a82b18fe11ea38c8720 172.38.0.12:6379@16379 master - 0 1679620066553 2 connected 5461-10922
46e745ac115598f54975b2ad4432dc087d678df7 172.38.0.13:6379@16379 master,fail - 1679619945828 1679619945025 3 connected
停掉服务
[root@Jsxs ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e0a19eb367dc redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 13 minutes ago Up 13 minutes 0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp redis-6
68cf748d322f redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 13 minutes ago Up 13 minutes 0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp redis-5
a5504370b19d redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 13 minutes ago Up 13 minutes 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp redis-4
f3d61ce52b42 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 13 minutes ago Up 13 minutes 0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp redis-3
175c61fc2523 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 14 minutes ago Up 14 minutes 0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp redis-2
d4050cf76348 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 15 minutes ago Up 15 minutes 0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp redis-1
4aba86a517af portainer/portainer "/portainer" 44 hours ago Up 44 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
[root@Jsxs ~]# docker stop redis-3
redis-3
6.SpringBoot微服务打包Docker镜像
(1).构建SpringBoot项目并打包
两次测试是否能启动
(2).创建Dockerfile文件并编写配置
# 基础镜像来自java8
FROM java:8
# 拷贝当前路径下所有jar包,到项目的,重命名app.jar
COPY *.jar /app.jar
# 启动名命令
CMD ["--server.port=8080"]
# 暴露端口
EXPOSE 8080
# 执行命令
ENTRYPOINT ["java", "-jar", "/app.jar"]
(3).上传jar包和Dockerfile文件到linux
[root@Jsxs ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4aba86a517af portainer/portainer "/portainer" 44 hours ago Up 44 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
[root@Jsxs ~]# cd /home
[root@Jsxs home]# ls
jsxs liloucun liloucunManger properties www
[root@Jsxs home]# mkdir idea
[root@Jsxs home]# cd idea/
[root@Jsxs idea]# ls
[root@Jsxs idea]# ls
Dockerfile Docker-hello-0.0.1-SNAPSHOT.jar
[root@Jsxs idea]# docker build -t jsxs666 .
[+] Building 45.5s (7/7) FINISHED
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 304B 0.0s
=> [internal] load metadata for docker.io/library/java:8 15.9s
=> [internal] load build context 0.4s
=> => transferring context: 17.65MB 0.4s
=> [1/2] FROM docker.io/library/java:8@sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d 27.2s
=> => resolve docker.io/library/java:8@sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d 0.0s
=> => sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d 2.00kB / 2.00kB 0.0s
=> => sha256:fce5728aad85a763fe3c419db16885eb6f7a670a42824ea618414b8fb309ccde 18.54MB / 18.54MB 2.3s
=> => sha256:d23bdf5b1b1b1afce5f1d0fd33e7ed8afbc084b594b9ccf742a5b27080d8a4a8 4.73kB / 4.73kB 0.0s
=> => sha256:5040bd2983909aa8896b9932438c3f1479d25ae837a5f6220242a264d0221f2d 51.36MB / 51.36MB 13.6s
=> => sha256:76610ec20bf5892e24cebd4153c7668284aa1d1151b7c3b0c7d50c579aa5ce75 42.50MB / 42.50MB 11.3s
=> => sha256:60170fec2151d2108ed1420625c51138434ba4e0223d3023353d3f32ffe3cfc2 593.15kB / 593.15kB 2.7s
=> => sha256:e98f73de8f0d2ef292f58b004d67bc6e9ee779dcfaff7ebb3964649d4787b872 214B / 214B 3.0s
=> => sha256:11f7af24ed9cf47597dd6cf9963bb3e9109c963f0135e869a9e9b4999fdc12a3 242B / 242B 3.4s
=> => sha256:49e2d6393f32abb1de7c9395c04c822ceb2287383d5a90998f7bd8dbfd43d48c 130.10MB / 130.10MB 21.8s
=> => sha256:bb9cdec9c7f337940f7d872274353b66e118412cbfd433c711361bcf7922aea4 289.05kB / 289.05kB 11.7s
=> => extracting sha256:5040bd2983909aa8896b9932438c3f1479d25ae837a5f6220242a264d0221f2d 2.0s
=> => extracting sha256:fce5728aad85a763fe3c419db16885eb6f7a670a42824ea618414b8fb309ccde 0.5s
=> => extracting sha256:76610ec20bf5892e24cebd4153c7668284aa1d1151b7c3b0c7d50c579aa5ce75 1.9s
=> => extracting sha256:60170fec2151d2108ed1420625c51138434ba4e0223d3023353d3f32ffe3cfc2 0.1s
=> => extracting sha256:e98f73de8f0d2ef292f58b004d67bc6e9ee779dcfaff7ebb3964649d4787b872 0.0s
=> => extracting sha256:11f7af24ed9cf47597dd6cf9963bb3e9109c963f0135e869a9e9b4999fdc12a3 0.0s
=> => extracting sha256:49e2d6393f32abb1de7c9395c04c822ceb2287383d5a90998f7bd8dbfd43d48c 4.5s
=> => extracting sha256:bb9cdec9c7f337940f7d872274353b66e118412cbfd433c711361bcf7922aea4 0.0s
=> [2/2] COPY *.jar /app.jar 0.4s
=> exporting to image 1.7s
=> => exporting layers 1.7s
=> => writing image sha256:36b36b1a1129b33cd570a9dcef34190473009e60c75264f7df0d1c660f595560 0.0s
=> => naming to docker.io/library/jsxs666
(4).启动测试
[root@Jsxs idea]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jsxs666 latest 36b36b1a1129 44 seconds ago 661MB
tomcat 7 9dfd74e6bc2f 20 months ago 533MB
portainer/portainer latest 580c0e4e98b0 2 years ago 79.1MB
#启动容器
[root@Jsxs idea]# docker run -d -P --name jsxs66-springboot jsxs666
20c4bc16322db4a60aa96b9c4f24e25a4d40d93d7b9016ce363d261526e373b0
[root@Jsxs idea]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
20c4bc16322d jsxs666 "java -jar /app.jar …" 36 seconds ago Up 34 seconds 0.0.0.0:32782->8080/tcp, :::32781->8080/tcp jsxs66-springboot
4aba86a517af portainer/portainer "/portainer" 45 hours ago Up 44 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
[root@Jsxs idea]# curl localhost:32782 #测试
{"timestamp":"2023-03-24T01:42:32.441+00:00","status":404,"error":"Not Found","path":"/"}[root@Jsxs idea]# curl localhost:32782/hello
hello jsxs![root@Jsxs idea]#
更多推荐
所有评论(0)