Docker

Docker学习

  • Docker概述
  • Docker安装
  • Docker命令
  • Docker镜像
  • 容器数据卷
  • DockerFile
  • Docker网络原理
  • IDEA整合Docker
  • Docker Compose(集群)
  • Docker Swarm
  • CI\CD Jenkins流水线

Docker概述

Docker为什么会出现?

一款产品:开饭—上线!两套环境,应用环境,应用配置

开发-----运维。问题?明明在我的电脑上可以运行,怎么你这里就不行呢?版本更新导致服务不可用,对于运维来说,考验就十分大,开发即运维

环境配置是十分麻烦的,每一个机器都要部署环境(集群Redis,ES,Hadoop…) !费时费力

发布一个项目jar(Redis,MySQL,jdk,ES) ,项目能不能带上环境安装打包!

之前在服务器配置一个应用的环境Redis,Mysql,jdk,ES,Hadoop,配置超级麻烦,不能够跨平台。

Windows发布到Linux!环境差别很大

传统的运维:Jar,运维来做部署的事情

现在:开发打包部署上线,一套流程做完!


Docker给以上的问题提出了解决方案!


Docker的思想来自于集装箱,每个箱子都是相互隔离的。Dokcer通过隔离机制,可以将服务器利用到极致

Docker的历史

2010年,几个搞IT的年轻人,就在美国成立了一家公司,dotCloud

做一些pass的云计算服务!LXC有关的容器技术!

他们将自己的技术(容器化技术)命名,就是Docker!

Docker刚刚诞生的时候,没有引起行业的注意 dotCloud,就活不下去

开源,开放源代码

2013年,将Docker开源

Docker越来越多的人发现了Docker的优点!火了,Docker每个月都会更新一个版本!

2014年4月9日,Docker1.0发布

Docker为什么这么火? 十分的轻巧

在容器技术出来之前,我们都是使用虚拟机技术,VMware

虚拟机:在windows中装一个Vmware,通过这个软件我们可以虚拟出来一台或者多台电脑!笨重

虚拟机也是属于虚拟化技术,Docker容器技术,也是一种虚拟化技术!

vm:linux centos原生镜像(一个电脑)隔离,需要开发多个虚拟机
Docker:隔离,镜像(最核心的环境 4m,+jdk+mysql),十分的小巧,运行镜像就可以了,小巧。

到现在,所有开发人员都必须要会Docker


聊聊Docker

Docker是基于Go语言开发的,

官网地址

文档地址,Docker的文档是很详细的

Docker镜像中心 ,远程仓库

Docker能干嘛?

之前的虚拟机技术

虚拟机技术缺点:

  • 资源占用十分多
  • 冗余步骤多
  • 启动非常慢

容器化技术

容器化技术不是模拟的一个完整的操作系统

比较Docker和虚拟机技术的不同

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

DevOps(开发运维)

更快速的交付和部署

传统:一堆帮助文档,安装程序

Docker:打包镜像发布测试,一键运行

更便捷的升级和扩缩容
使用了Docker之后,我们部署应用就和搭积木一样

项目打包为一个镜像,扩展服务器A,服务器B。

更简单的系统运维

在容器化之后,我们的开发,测试环境都是高度一致的。

更高效的计算资源利用

Docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例!服务器的性能可以被压榨到极致

Docker安装

Docker的基本组成

镜像(image)

docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像====》tomcat容器(提供服务器),

通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器的)

容器(container)

Docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的。

启动,停止,删除,基本命令

目前就可以吧这个容器理解为一个简易的linux系统

仓库(repository)

仓库就是存放镜像的地方!

仓库分为共有仓库和私有仓库!

Docker Hub

阿里云。。。都有容器服务器(配置镜像加速)

安装Docker

环境准备

  • 需要会一点点linux基础
  • CentOS 7
  • 使用xshell连接远程服务器进行操作

环境查看

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

安装

[查看帮助文档]([root@iZwz90og9utae1lg37hyz7Z ~]# cat /etc/os-release NAME=“CentOS Linux” VERSION=“7 (Core)” ID=“centos” ID_LIKE=“rhel fedora” VERSION_ID=“7” PRETTY_NAME=“CentOS Linux 7 (Core)” ANSI_COLOR=“0;31” CPE_NAME=“cpe:/o:centos:centos:7” HOME_URL=“https://www.centos.org/” BUG_REPORT_URL=“https://bugs.centos.org/” CENTOS_MANTISBT_PROJECT=“CentOS-7” CENTOS_MANTISBT_PROJECT_VERSION=“7” REDHAT_SUPPORT_PRODUCT=“centos” REDHAT_SUPPORT_PRODUCT_VERSION=“7”)

明确说明需要centos7以上才支持,首先需要卸载久的版本

# 1、卸载旧的版本
$ sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
# 2、需要的安装包
$ sudo yum install -y yum-utils# 3、设置镜像的仓库
$ sudo yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo # 默认是从国外的!$ sudo yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo  # 使用阿里云的,十分快# 更新yum软件包索引
[root@iZwz90og9utae1lg37hyz7Z ~]# yum makecache fast# 4、安装docker引擎 docker-ce 社区版    ee企业版
$ sudo yum install docker-ce docker-ce-cli containerd.io# 5、启动docker
$ sudo systemctl start docker# 6、使用 docker version 测试是否安装成功

# 7、测试hello-world
$ sudo docker run hello-world

# 8、查看一下下载的这个hello world在不在
[root@iZwz90og9utae1lg37hyz7Z ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        4 months ago        13.3kB
# 9、卸载docker
$ sudo yum remove docker-ce docker-ce-cli containerd.io # 卸载依赖
$ sudo rm -rf /var/lib/docker # 删除资源(docker默认的资源路径)

阿里云镜像加速

1、登入阿里云,找到容器镜像服务

2、找到镜像加速地址

3、配置使用

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://ggb52j62.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

回顾HelloWorld流程

run的流程分析图

底层原理

Docker是怎么工作的?

Docker是一个Client-Server 结构的系统,Docker的守护进程进行在主机上,通过Socket从客户端访问!

DockerServer接收到Docker-Client的指令,就会执行这个命令

Docker为什么比VM快

  • Docker有比虚拟机更少的抽象层
  • Docker利用的是宿主机的内核,VM是需要GuestOS。

所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导,虚拟机是加载Guest OS,分钟级别的,

而docker是利用宿主机的操作系统,省略了这个复杂的过程,是秒级别的。

Docker的常用命令

帮助命令

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

帮助文档的命令:https://docs.docker.com/reference/

镜像命令

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

[root@iZwz90og9utae1lg37hyz7Z /]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        4 months ago        13.3kB# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的版本信息,标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小# 可选项-a, --all             # 列出所有镜像-q, --quiet           # 只显示镜像id

docker search 搜索镜像

[root@iZwz90og9utae1lg37hyz7Z /]# docker search mysql
NAME                              DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   9566                [OK]
mariadb                           MariaDB is a community-developed fork of MyS…   3473                [OK]# 可选项
--filter=STARS=3000 # 过滤收藏数大于3000的[root@iZwz90og9utae1lg37hyz7Z /]# docker search mysql  --filter=STARS=3000
NAME                DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql               MySQL is a widely used, open-source relation…   9566                [OK]
mariadb             MariaDB is a community-developed fork of MyS…   3473                [OK]

**docker pull ** 下载镜像

# 下载镜像 docker pull 镜像名[:tag]
[root@iZwz90og9utae1lg37hyz7Z /]# docker pull mysql
Using default tag: latest # 如果不写版本,默认下载最新版
latest: Pulling from library/mysql
afb6ec6fdc1c: Pull complete # 分层下载:docker image的核心,联合文件系统
0bdc5971ba40: Pull complete
97ae94a2c729: Pull complete
f777521d340e: Pull complete
1393ff7fc871: Pull complete
a499b89994d9: Pull complete
7ebe8eefbafe: Pull complete
597069368ef1: Pull complete
ce39a5501878: Pull complete
7d545bca14bf: Pull complete
211e5bb2ae7b: Pull complete
5914e537c077: Pull complete
Digest: sha256:a31a277d8d39450220c722c1302a345c84206e7fd4cdb619e7face046e89031d # 签名 防伪
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址# 其实这两个命令是等价的
docker pull mysql
docekr pull docker.io/library/mysql:latest# 指定版本下载
[root@iZwz90og9utae1lg37hyz7Z /]# docker pull mysql:5.7
5.7: Pulling from library/mysql
afb6ec6fdc1c: Already exists
0bdc5971ba40: Already exists
97ae94a2c729: Already exists
f777521d340e: Already exists
1393ff7fc871: Already exists
a499b89994d9: Already exists
7ebe8eefbafe: Already exists
4eec965ae405: Pull complete
a531a782d709: Pull complete
270aeddb45e3: Pull complete
b25569b61008: Pull complete
Digest: sha256:d16d9ef7a4ecb29efcd1ba46d5a82bda3c28bd18c0f1e3b86ba54816211e1ac4
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

docker rmi -f 删除镜像

[root@iZwz90og9utae1lg37hyz7Z /]# docker rmi -f 镜像id                    # 删除指定镜像
[root@iZwz90og9utae1lg37hyz7Z /]# docker rmi -f 镜像id 镜像id 镜像id        # 删除多个镜像(空格分开)
[root@iZwz90og9utae1lg37hyz7Z /]# docker rmi -f $(docker images -qa)      #骚操作,采用联合查询删除所有镜像

容器命令

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

docker pull centos

新建容器并启动

docker run[可选参数] 镜像id#参数说明
--name = "Name"  #给容器取个别名   tomcat01 tomcat02
-d                  #后台方式运行
-it                 #使用交互方式运行,进入容器查看内容
-p(小写)                    #指定容器的端口,8080:8080-p 主机端口:容器端口 (常用)-p 容器端口
-P(大写)                    #随机指定端口# 测试,启动并进入容器
[root@iZwz90og9utae1lg37hyz7Z /]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              470671670cac        4 months ago        237MB
[root@iZwz90og9utae1lg37hyz7Z /]# docker run -it  470671670cac /bin/bash[root@eea5ced1bcb8 /]# ls   # 查看容器内容的centos,基础版本很多命令不完善
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
# 从容器中退回主机
[root@eea5ced1bcb8 /]# exit

列出所有运行中的容器

# docker ps 命令#列出当前正在运行的容器
-a  #列出当前正在运行的容器+带出历史运行过的容器
-n=? #显示最近创建的容器
-q # 只显示容器的编号[root@iZwz90og9utae1lg37hyz7Z /]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS
[root@iZwz90og9utae1lg37hyz7Z /]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS
eea5ced1bcb8        470671670cac        "/bin/bash"         5 minutes ago       Exited (127) 2 minutes ago
7c6d68fe38bf        bf756fb1ae65        "/hello"            29 minutes ago      Exited (0) 29 minutes ago
47934e45992d        bf756fb1ae65        "/hello"            3 hours ago         Exited (0) 3 hours ago                           [root@iZwz90og9utae1lg37hyz7Z /]# docker ps -a -n=1
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS
eea5ced1bcb8        470671670cac        "/bin/bash"         9 minutes ago       Exited (127) 6 minutes ago                       [root@iZwz90og9utae1lg37hyz7Z /]# docker ps -aq
eea5ced1bcb8
7c6d68fe38bf
47934e45992d

退出容器

exit #直接容器停止并退出
Ctrl+P+Q  #容器不停止退出

删除容器

docker rm 容器id                   #删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm-f
docekr rm -f $(docker ps -aq)    #删除所有的容器
docker ps -a -q|xargs docker rm  #删除所有的容器

启动和停止容器的操作

docker start 容器id        #启动容器
docker restart 容器id     #重启容器
docker stop 容器id        #停止当前正在运行的容器
docker kill 容器id        #强制停止当前容器

常用的其他命令

后台启动容器

# docker run -d 镜像名
[root@iZwz90og9utae1lg37hyz7Z /]# docker run -d centos
# 问题:docker ps ,发现centos停止了??
#常见的坑:docker容器使用后天运行,就必须要有一个前天进程,docker发现没有应用,就会自动停止
#nginx,容器启动后,发现自己没有提供服务,就会立即停止,就是没有程序了

查看日志

docker logs [可选项]
-tf             # 显示日志
--tail number   # 显示日志条数
[root@iZwz90og9utae1lg37hyz7Z /]# docker logs -tf --tail 10 容器id

查看容器中的进程信息 ps

#命令 docker top 容器id [root@iZwz90og9utae1lg37hyz7Z ~]# docker top d7f8882680a1
UID                 PID                 PPID                C                   STIME               TTY                 TIME
root                22262               22245               0                   17:40               pts/0               00:00:00

查看镜像的元数据

#命令 docker inspect 容器id# 测试
[root@iZwz90og9utae1lg37hyz7Z ~]# docker inspect d7f8882680a1
[{"Id": "d7f8882680a11fa697b52b00487f927becadff47500d9164be3ef3c5b5151f94","Created": "2020-05-30T09:40:07.580695306Z","Path": "/bin/bash","Args": [],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 22262,"ExitCode": 0,"Error": "","StartedAt": "2020-05-30T09:40:07.935601958Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee","ResolvConfPath": "/var/lib/docker/containers/d7f8882680a11fa697b52b00487f927becadff47500d9164be3ef3c5b5151f94/resolv.conf","HostnamePath": "/var/lib/docker/containers/d7f8882680a11fa697b52b00487f927becadff47500d9164be3ef3c5b5151f94/hostname","HostsPath": "/var/lib/docker/containers/d7f8882680a11fa697b52b00487f927becadff47500d9164be3ef3c5b5151f94/hosts","LogPath": "/var/lib/docker/containers/d7f8882680a11fa697b52b00487f927becadff47500d9164be3ef3c5b5151f94/d7f8882680a11fa697b52b00487f927becadff47500d9164be3ef3c5b5151f94-json.log","Name": "/gallant_austin","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,"Capabilities": null,"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/ca896847bd3647809cf2bb90a22239e99a33cee8158cfcd958020aebff46b284-init/diff:/var/lib/docker/overlay2/e1d29bc072eab6c1fafe40da590a23718c50eb94cf0dc9b63a6445795d2e2e69/diff","MergedDir": "/var/lib/docker/overlay2/ca896847bd3647809cf2bb90a22239e99a33cee8158cfcd958020aebff46b284/merged","UpperDir": "/var/lib/docker/overlay2/ca896847bd3647809cf2bb90a22239e99a33cee8158cfcd958020aebff46b284/diff","WorkDir": "/var/lib/docker/overlay2/ca896847bd3647809cf2bb90a22239e99a33cee8158cfcd958020aebff46b284/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "d7f8882680a1","Domainname": "","User": "","AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Tty": true,"OpenStdin": true,"StdinOnce": true,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/bash"],"Image": "centos","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {"org.label-schema.build-date": "20200114","org.label-schema.license": "GPLv2","org.label-schema.name": "CentOS Base Image","org.label-schema.schema-version": "1.0","org.label-schema.vendor": "CentOS","org.opencontainers.image.created": "2020-01-14 00:00:00-08:00","org.opencontainers.image.licenses": "GPL-2.0-only","org.opencontainers.image.title": "CentOS Base Image","org.opencontainers.image.vendor": "CentOS"}},"NetworkSettings": {"Bridge": "","SandboxID": "3c28f68ab437d44fc52e3132fe473dac6f8c4f217860af2c44164863c6e6b192","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/3c28f68ab437","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "518937c65fb1d275e0dfb828fee65418dda8ddc497a6e0cbc62867474f3b808b","Gateway": "172.17.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:11:00:02","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "912b291ba3c83933000fd3176a476f87bbbb02aa38d5ef59511f5a2e4fc43e2b","EndpointID": "518937c65fb1d275e0dfb828fee65418dda8ddc497a6e0cbc62867474f3b808b","Gateway": "172.17.0.1","IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:02","DriverOpts": null}}}}
]

进入当前正在运行的容器(重要常用)

# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
# 命令
# 方式一:
docker exec -it 容器id bashshell
[root@iZwz90og9utae1lg37hyz7Z ~]# docker exec -it d7f8882680a1 /bin/bash
# 进入容器后的操作
[root@d7f8882680a1 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 09:40 pts/0    00:00:00 /bin/bash
root        17     0  0 09:53 pts/1    00:00:00 /bin/bash
root        30    17  0 09:53 pts/1    00:00:00 ps -ef#方式二:
docker attach 容器id
#测试
[root@d7f8882680a1 /]# docker attach d7f8882680a1
正在执行当前的代码。。。# docker exec       #进入容器后进入一个新的终端,可以在里面操作
# docker attach     #进入容器正在执行的终端,不会启动新的进程

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

docker cp 容器id:容器内路径  目的主机路径
# 测试,将容器内的test.java文件复制到主机的home目录下# 进入容器内部
[root@iZwz90og9utae1lg37hyz7Z home]# docker attach d7f8882680a1
[root@d7f8882680a1 /]# cd /home
# 在容器内部创建一个文件
[root@d7f8882680a1 home]# touch test.java
[root@d7f8882680a1 home]# ls
test.java
# 退出容器
[root@d7f8882680a1 home]# exit
exit
# 将文件拷贝出来到主机上
[root@iZwz90og9utae1lg37hyz7Z /]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                            PORTS
d7f8882680a1        centos              "/bin/bash"         34 minutes ago      Exited (127) About a minute ago
[root@iZwz90og9utae1lg37hyz7Z /]# docker cp d7f8882680a1:/home/test.java /home
[root@iZwz90og9utae1lg37hyz7Z /]# cd home
[root@iZwz90og9utae1lg37hyz7Z home]# ls
test.java  www#问题? 拷贝是手动过程,未来我们使用 -v卷的技术,可以实现自动同步

命令小结

docker的命令是十分多的,特此做个 笔记总结:


体验docker

1、使用Docker安装Nginx

# 1、搜索镜像 search 建议去docker hub搜索,可以看到帮助文档信息
# 2、下载镜像 pull
# 3、启动
[root@iZwz90og9utae1lg37hyz7Z ~]# docker run -d --name myNginx -p 3344:80 nginx
# 4、启动成功后,本地测试
[root@iZwz90og9utae1lg37hyz7Z ~]# curl localhost:3344
# http://112.74.167.52:3344/
# 注意:这里可能会有个小问题,如果这里没有正常放回界面,应该是阿里云的安全组那边没有开放端口,进入ECS控制台添加安全组开放端口即可
# 5、进入nginx容器
[root@iZwz90og9utae1lg37hyz7Z ~]# docker exec -it myNginx /bin/bash
$测试:
[root@iZwz90og9utae1lg37hyz7Z ~]# docker exec -it myNginx /bin/bash
# 进入容器了
root@b645aa7b2116:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@b645aa7b2116:/# cd /etc/nginx
root@b645aa7b2116:/etc/nginx# ls
conf.d  fastcgi_params  koi-utf  koi-win  mime.types  modules  nginx.conf  scgi_params  uwsgi_params  win-utf
root@b645aa7b2116:/etc/nginx#

端口暴露的概念

思考的问题? 每次改动nginx配置文件,都需要进入容器内??十分麻烦,要是可以在容器外部提供一个映射路径,达到在容器外修改文件,容器内就能自动修改,那就OK, -v数据卷技术可以实现

2、使用docker安装一个tomcat

# 官方的使用
docker run -it --rm tomcat:9.0
# 我们之前的启动都是后台,停止了容器之后,容器还是可以查到,docker  -it --rm ,用完即删除,用来测试用# 下载启动
[root@iZwz90og9utae1lg37hyz7Z ~]# docker pull tomcat   下载镜像
[root@iZwz90og9utae1lg37hyz7Z ~]# docker run -d -p 3355:8080 --name myTomcat tomcat  # 运行# localhost:3355   报404的错误,这个时候说明外网已经可以访问了# 进入容器
[root@iZwz90og9utae1lg37hyz7Z ~]# docker exec -it myTomcat /bin/bash
root@d03c0c1b5ef3:/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
# 发现问题,webapps目录下面为空,阉割版,所有访问的时候没有内容,阿里云镜像的原因,默认是最小的镜像。保证最小可运行的环境
复制webapps.dist中的内容到webapps目录下即可正常访问

思考:我们以后要部署项目,如果每次都要进入容器的话就很麻烦,要是可以在容器外部提供一个映射路径 ,webapps,在外部放置项目就自动同步到内部就好了!

3、部署ES+kibana

# es 暴露的端口很多
# es十分耗内存
# es的数据一般需要放置到安全目录!挂载# --net somenetwork 这个是网络配置
# 启动es 下载安装一步到位
$ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2# 启动了 linux就卡住,内存爆炸了
# docker stats 查看cpu状态# 增加内存限制  -e
$ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2 # 查看内存消耗
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK
859d68a4564b        elasticsearch       0.40%               338.9MiB / 1.795GiB   18.44%              0B / 0B             0B / # 访问测试
[root@pihao ~]# curl localhost:9200
{"name" : "859d68a4564b","cluster_name" : "docker-cluster","cluster_uuid" : "67U8HpnDTPS9vqQJEaAkWg","version" : {"number" : "7.6.2","build_flavor" : "default","build_type" : "docker","build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f","build_date" : "2020-03-26T06:34:37.794943Z","build_snapshot" : false,"lucene_version" : "8.4.0","minimum_wire_compatibility_version" : "6.8.0","minimum_index_compatibility_version" : "6.0.0-beta1"},"tagline" : "You Know, for Search"
}

使用kibana连接elasticsearch,网络怎么连接呢?

容器内部之间要怎么进行连接呢

可视化

  • portainer
  • Rancher(CI/CD)

什么是portainer?

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

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

访问测试:http://112.74.167.52:8088/

选择本地:

可视化面板,平时用的不多!


Docker镜像讲解

镜像是什么

所有的应用,直接打包docker镜像,就可以直接跑起来,包括代码、库、环境变量和皮遏制文件;

如何得到镜像:

  • 从远程仓库下载

  • 朋友拷贝

  • 自己制作一个镜像DockerFile

Docker镜像加载原理

UnionFS (联合文件系统)

docker的镜像实际上由一层一层的文件系统组成,这种从层级的文件系统UnionFS

分层理解

所有的docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。

特点

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!

如何提交一个自己的镜像??


commit镜像

docker commit 提交容器成为一个新的副本
# 命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]

实战观测:

官网提供的tomcat镜像的webapps目录是空的,那我们就做一个webapps目录下面有文件的,然后发布

# 启动一个默认的tomcat
# 发现这个默认的tomcat是没有webapps应用
# 我自己进去拷贝了基本的文件
# 将我们操作过的容器通过commit提交作为一个镜像,我们以后就使用这个修改过的镜像即可,这就我我们自己的一个修改过的镜像,结合maven的  mvn  install理解[root@pihao ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS
f44a55d3dd55        tomcat              "catalina.sh run"   7 minutes ago       Up 7 minutes        0.0.0.0:8080->8080/tcp
[root@pihao ~]# docker commit -a="pihao" -m="add webapps application" f44a55d3dd55 tomcat_pihao:1.0

通过实操至此,差不多算是入门docker了!!!! 继续加油~~~


容器数据卷

什么是容器数据卷

docker理念

将应用和环境打包成一个镜像!

数据?如果数据都在容器中,那么我们容器删除,数据也会丢失,需求:数据可以持久化

Mysql,容器删了,那就是删库跑路了,需求:Mysql数据可以存储在本地。

容器之间可以有一个数据共享的技术!docker容器中产生的数据,同步到本地

这就是数据卷技术,目录的挂载,将我们容器内的目录,挂载到Linux上面。

总结:容器的持久化和同步操作!容器间也是可以数据共享的

使用数据卷

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

[root@pihao ~]# docker run -it -v 主机目录:容器内目录 镜像id
# 测试:
[root@pihao home]# docker run -it -v /home/ceshi:/home centos /bin/bash# 启动起来之后我们通过docker inspect 容器id  查看元数据
[root@pihao home]# docker inspect 6a08f0d81c50
 "Mounts": [        挂载  -v 卷{"Type": "bind",           "Source": "/home/ceshi",   主机内地址"Destination": "/home",    docker容器内地址"Mode": "","RW": true,"Propagation": "rprivate"}],#同步测试

继续测试:

  • 停止容器
  • 在宿主机上修改文件
  • 启动容器
  • 容器内的数据依旧是同步的

好处:我们以后修改只需要在本地修改即可,容器会自动同步过去!


实战:Mysql数据同步

思考:Mysql的数据持久化问题!

# 获取镜像
[root@pihao ~]# docker pull mysql:5.7# 安装启动mysql,需要配置密码的,这是要注意点
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag     # 官方提供的设置密码命令# 运行镜像,做数据挂载
[root@pihao ~]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
tomcat_pihao          1.0                 8512e11068c0        12 hours ago        652MB
portainer/portainer   latest              1ec116aed60c        46 hours ago        79.1MB
mysql                 5.7                 a4fdfd462add        9 days ago          448MB
tomcat                9.0                 1b6b1fe7261e        2 weeks ago         647MB
tomcat                latest              1b6b1fe7261e        2 weeks ago         647MB
nginx                 latest              9beeba249f3e        2 weeks ago         127MB
elasticsearch         7.6.2               f29a1ee41030        2 months ago        791MB
centos                latest              470671670cac        4 months ago        237MB
# 可以做多个数据挂载 :     /etc/mysql/conf.d(这个是mysql的配置文件目录)     /var/lib/mysql(这个是mysql的数据库目录)
-d 后台运行
-d 端口映射
-v 卷挂载
-e 环境配置
--name 取别名
# 启动第一个mysql
[root@pihao ~]# 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测试连接mysql
# Navicat连接到服务器的3310,------3310和容器内的3306做了映射,这个时候就能连上了# 在本地测试创建一个数据库,查看一下映射路径是否也创建了

假设将容器删除,发现我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据的持久化功能!

具名和匿名挂载

# 匿名挂载
-v 容器内路径 (不写主机的路径)
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看所有的volume情况
[root@pihao data]# docker volume ls
DRIVER              VOLUME NAME
local               0bd6ec25d165dfd5e55ec8d7376a619f720e71c94b062fef5bcd9d643890202f
local               5352b1b1d189180f75ae95a4aba702af3eab6dbf22c7196ee0b73491ca78ae39
# 这里发现,这就是匿名挂载,因为我们在-v的时候只写了容器内的路径,而没有取名字# 具名挂载
# 再开一个nginx   这时给容器内的路径取一个名字:juming
[root@pihao /]# docker run -d -P -v juming:/etc/nginx --name nginx02 nginx
20bfd4124e5fadaf25a9dce86dfb8d216ade483db25e1d767b144f695b2c74ab
[root@pihao /]# docker volume ls
DRIVER              VOLUME NAME
local               juming # 取的名字# 通过-v  卷名:容器内路径
# 查看卷的信息  docker volume inspect 卷名
[root@pihao /]# docker volume inspect juming
[{"CreatedAt": "2020-05-31T10:53:25+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/juming/_data",     "Name": "juming","Options": null,"Scope": "local"}
]

所有的docker容器内的卷,没有指定目录的情况下都是在: /var/lib/docker/volumes/xxxx/_data

我们通过具名挂载,可以方便的找到我们的一个卷,大多数情况下载使用的 具名挂载

# 如何确实是具名挂载还是匿名挂载??还是指定路径挂载
-v 容器内路径                #匿名挂载
-v 卷名:容器内路径            #具名挂载
-v /宿主机路径:容器内路径  #指定路径挂载

拓展:

# 通过 -v 容器内路径:ro  rw  改变读写权限
#   ro      read only           只读
#   rw      read and write      可读可写
#   一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
[root@pihao /]# docker run -d -P -v juming:/etc/nginx:ro --name nginx01 nginx
[root@pihao /]# docker run -d -P -v juming:/etc/nginx:rw --name nginx02 nginx#  ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的

初识DockerFile

DockerFile就是用来构建docker镜像的构建文件:命令脚本!先体验一下!

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

# 创建一个dockerfile文件,名字可以随便取,建议dockerfile01
# 文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]     # 这里其实是匿名挂载,在容器外部必定会生成一个目录与它同步
CMD echo "------end------"
CMD bin/bash
#这里每个命令都是镜像的一层# 将命令打包
[root@pihao docker_volume_test]# docker build -f dockerfile01 -t pihao/centos:1.0 .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos---> 470671670cac
Step 2/4 : VOLUME ["volume01","volume02"]---> Running in ce323b96416b
Removing intermediate container ce323b96416b---> d8f8fdc5edd8
Step 3/4 : CMD echo "------end------"---> Running in cedae7372d3a
Removing intermediate container cedae7372d3a---> 136048f7f683
Step 4/4 : CMD bin/bash---> Running in d381121bac22
Removing intermediate container d381121bac22---> 9f36ff977d42
Successfully built 9f36ff977d42
Successfully tagged pihao/centos:1.0
[root@pihao docker_volume_test]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
pihao/centos          1.0                 9f36ff977d42        14 seconds ago      237MB  # 打包好的镜像
# 启动一下自己生成的容器
[root@pihao docker_volume_test]# docker run -it 9f36ff977d42 /bin/bash
[root@0f1d1bf75b84 /]# ls -l
drwxr-xr-x  2 root root 4096 May 11  2019 srv
dr-xr-xr-x 13 root root    0 May 31 04:31 sys
drwxrwxrwt  7 root root 4096 Jan 13 21:49 tmp
drwxr-xr-x 12 root root 4096 Jan 13 21:49 usr
drwxr-xr-x 20 root root 4096 Jan 13 21:49 var
drwxr-xr-x  2 root root 4096 May 31 04:31 volume01  # 这两个目录就是我们生成镜像的时候自动挂载的,数据卷目录
drwxr-xr-x  2 root root 4096 May 31 04:31 volume02

这个卷:volume01,volume02 在外部一定有一个与它同步的目录!

# 使用inspect命令查看一下这个容器的卷挂载路径
[root@pihao ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS
48bbedc992a3        9f36ff977d42        "/bin/bash"         41 minutes ago      Up 41 minutes
[root@pihao ~]# docker inspect 48bbedc992a3
"Mounts": [{"Type": "volume","Name": "56e6675052e05ea4a9b08eb72ca9bd776627c6e360a6b4ffbd205519cc82eff2","Source": "/var/lib/docker/volumes/56e6675052e05ea4a9b08eb72ca9bd776627c6e360a6b4ffbd205519cc82eff2/_data","Destination": "volume01","Driver": "local","Mode": "","RW": true,"Propagation": ""},{"Type": "volume","Name": "670c6b43a2af71397c18a85e92b393745eb9bf0b1318e5dd0529a6c39eacba83","Source": "/var/lib/docker/volumes/670c6b43a2af71397c18a85e92b393745eb9bf0b1318e5dd0529a6c39eacba83/_data","Destination": "volume02","Driver": "local","Mode": "","RW": true,"Propagation": ""}]
# 发现 volume01 和volume02 挂载的同步文件在主机的   /var/lib/docker/volumes/xxxx/_date目录下

查看同步情况:

在容器内的volume01下创建一个container.txt文件

然后在volume01文件对应的主机同步目录中查看是否已经同步完成:

这种方式在以后的工作中经常使用,因为我们通常会构建自己的镜像!

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

数据卷容器

场景:多个mysql同步数据,容器与容器之间信息交互

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

启动pihao/centos:1.0 ,取名为docker01

启动pihao/centos:1.0 ,取名为docker02 --volumes-from docker01

现在要做的操作:

在docker01的volume01中新建一个文件夹docker01,看看会不会同步的到docker02的volume01中

# 进入容器docker01 新建文件夹docker01
[root@pihao docker_volume_test]# docker ps
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS              PORTS               NAMES
4b8f6d78b9ea        pihao/centos:1.0    "/bin/sh -c bin/bash"   7 minutes ago       Up 7 minutes   docker02
9dda52409402        pihao/centos:1.0    "/bin/sh -c bin/bash"   14 minutes ago      Up 14 minutes   docker01
[root@pihao docker_volume_test]# docker attach 9dda52409402
[root@9dda52409402 /]# ls
opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01  volume02
[root@9dda52409402 /]# cd volume01
[root@9dda52409402 volume01]# mkdir docker01
[root@9dda52409402 volume01]# ls
docker01# 进入容器docker02,查看文件是否被同步过来
[root@pihao ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS              PORTS
4b8f6d78b9ea        pihao/centos:1.0    "/bin/sh -c bin/bash"   12 minutes ago      Up 12 minutes    docker02
9dda52409402        pihao/centos:1.0    "/bin/sh -c bin/bash"   19 minutes ago      Up 19 minutes    docker01
[root@pihao ~]# docker attach 4b8f6d78b9ea
[root@4b8f6d78b9ea /]# ls
opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01  volume02
[root@4b8f6d78b9ea /]# cd volume01
[root@4b8f6d78b9ea volume01]# ls
docker01  # 发现已经被同步过来(docker01创建的数据同步到了docker02上)

启动pihao/centos:1.0 ,取名为docker03 -volumes–from docker01

# 进入docker01,检查文件是否同步过来
[root@pihao ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS              PORTS               NAMES
c5c69147c3e0        pihao/centos:1.0    "/bin/sh -c bin/bash"   3 minutes ago       Up 3 minutes     docker03
4b8f6d78b9ea        pihao/centos:1.0    "/bin/sh -c bin/bash"   25 minutes ago      Up 25 minutes    docker02
9dda52409402        pihao/centos:1.0    "/bin/sh -c bin/bash"   32 minutes ago      Up 32 minutes    docker01
[root@pihao ~]# docker attach 9dda52409402
[root@9dda52409402 volume01]# ls
docker01  docker03  # 发现docker03已经同步过来了
# 测试 可以删除docker01,查看一下docker02和docker03是否还可以访问volume01这个文件夹
# 发现依旧存在

多个mysql实现数据共享

# mysql01
[root@pihao ~]# docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7# mysql02
[root@pihao ~]# docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7# 这个时候,就可以实现两个容器数据同步
结论:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止
但是一旦持久化到了本地,本地的数据是不会删除的

DockerFile

DockerFile介绍

dockerfile 是用来构建docker镜像的文件,!命令参数脚本

构建步骤

  • 编写一个dockerfile文件
  • docker build 构建一个镜像
  • docker run 运行镜像
  • docker push 发布镜像(DockerHub\阿里云镜像仓库)

看看官方是怎么做的??DockerHub上随便搜一个镜像

发现跳转到github,发现也是一组命令构成

官方既然可以制作镜像,我们也可以!!!

DockerFile构建过程

基础知识:

  • 每个保留关键字(指令)都必须是大写字母
  • 执行从上到下顺序执行
  • #表示注释
  • 每个指令都是创建提交一个新的镜像层,并提交!

dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单

简单地说,之前将你写的代码打包生成war包或者jar包,现在呢?公司要求将你的代码打包生成docker镜像

Docker镜像逐渐成为企业交付的标准,必须要掌握~~~~

步骤:开发,部署,。。。缺一不可

  • DokcerFile: 构建文件,定义了一切的步骤,源代码

  • DockerImages: 通过DockerFile构建生成的镜像,最终发布和运行的产品,原来是jar,war

  • Docker容器: 容器就是镜像运行起来提供服务的


DockerFile的指令

以前的话我们就是使用别人的,现在我们知道这些指令后,我们来练习自己写一个镜像!

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

实战测试:构建自己的centos

Docker Hub中,百分之九九的镜像都是从这个基础镜像过来的 FROM scratch,然后配置需要的软件和配置来进行构建

创建一个自己的centos

# 1、编写dockerfile的配置文件(我在home目录下编写一个了mydockerfile-centos的文件,内容如下)
FROM centos
MAINTAINER pihao<827699764@qq.com>ENV MYPATH /usr/local
WORKDIR $MYPATHRUN yum -y install vim
RUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATH
CMD echo "----------------end------------"
CMD /bin/bash# 2、再通过这个文件构建镜像
# 命令 docker build -f dockerfile文件路径 -t 镜像名字:【TAG】
[root@pihao dockerfile]# docker build -f mydockerfile-centos -t mycentos:1.0 .# 执行结果:
Successfully built 844b891d4781
Successfully tagged mycentos:1.0# 3、测试运行

对比:之前的centos

我们增加之后的镜像

查看镜像历史变更:

# 我们可以列出本地进行的变更历史 docker history 镜像id
[root@pihao dockerfile]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mycentos            1.0                 844b891d4781        15 minutes ago      321MB
centos              latest              470671670cac        4 months ago        237MB
[root@pihao dockerfile]# docker history mycentos:1.0
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
844b891d4781        15 minutes ago      /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B
cc7835c68b84        15 minutes ago      /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B
617d78fe4151        15 minutes ago      /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B
fbfd40657f5c        15 minutes ago      /bin/sh -c #(nop)  EXPOSE 80                    0B
6ce2a8dca855        15 minutes ago      /bin/sh -c yum -y install net-tools             24MB
3639c1768f75        15 minutes ago      /bin/sh -c yum -y install vim                   59.8MB
301d6576cf44        15 minutes ago      /bin/sh -c #(nop) WORKDIR /usr/local            0B
f7cd9d68bb8d        15 minutes ago      /bin/sh -c #(nop)  ENV MYPATH=/usr/local        0B
3c2904681fb0        15 minutes ago      /bin/sh -c #(nop)  MAINTAINER pihao<82769976…   0B
470671670cac        4 months ago        /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>           4 months ago        /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
<missing>           4 months ago        /bin/sh -c #(nop) ADD file:aa54047c80ba30064…   237MB

我们平时拿到一个镜像,可以研究一下它是怎么做的??

CMD 和 ENTRYPOINT的区别

测试CMD

# dockerfile
FROM centos
CMD ["ls","-a"]
# 这个命令非常简单,及时启动这个容器的时候执行 ls -a 这个命令
# 构建容器
[root@pihao dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest:1.0 .
# 运行容器,发现 li -a 生效
[root@pihao dockerfile]# docker run  cmdtest:1.0
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
[root@pihao dockerfile]## 想追加一个命令 -l  期待效果如: ls -al
[root@pihao dockerfile]# docker run cmdtest:1.0 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.# 发现有问题,因为在cmd的清理下, -l替换了CMD["ls","-a"]的命令,-l不是命令,所以报错# 命令换成 ls -al即可
[root@pihao dockerfile]# docker run cmdtest:1.0 ls -al
total 56
drwxr-xr-x   1 root root 4096 May 31 11:29 .
drwxr-xr-x   1 root root 4096 May 31 11:29 ..
-rwxr-xr-x   1 root root    0 May 31 11:29 .dockerenv
lrwxrwxrwx   1 root root    7 May 11  2019 bin -> usr/bin
drwxr-xr-x   5 root root  340 May 31 11:29 dev
drwxr-xr-x   1 root root 4096 May 31 11:29 etc
drwxr-xr-x   2 root root 4096 May 11  2019 home

测试ENTRYPOINT

# dockerfile
FROM centos
ENTRYPOINT ["ls","-a"]
# 构建容器
[root@pihao dockerfile]# docker build -f dockerfile-entrypoint-test -t entrypoint-test:1.0 .
# 运行容器,发现 li -a 生效
[root@pihao dockerfile]# docker run entrypoint-test:1.0
.
..
.dockerenv
bin
dev
etc
home
lib
lib64# 想追加一个命令 -l  期待效果如: ls -al
[root@pihao dockerfile]# docker run entrypoint-test:1.0 -l
total 56
drwxr-xr-x  1 root root 4096 May 31 11:42 .
drwxr-xr-x  1 root root 4096 May 31 11:42 ..
-rwxr-xr-x  1 root root    0 May 31 11:42 .dockerenv
lrwxrwxrwx  1 root root    7 May 11  2019 bin -> usr/bin
drwxr-xr-x  5 root root  340 May 31 11:42 dev
drwxr-xr-x  1 root root 4096 May 31 11:42 etc
drwxr-xr-x  2 root root 4096 May 11  2019 home
# 运行成功
# 发现这里的  -l  直接追加到了ENTRYPOINT ["ls","-a"]中

DockerFile中很多命令都十分相似,需要了解他们的区别,最好就是通过对比的方式来学习

实战:Tomcat镜像


1、准备镜像文件tomcat压缩包,jdk的压缩包

[root@pihao tomcat]# ls -l
-rw-r--r-- 1 root root   9722154 May 31 20:00 apache-tomcat-8.5.45.tar.gz
-rw-r--r-- 1 root root 180362463 May 31 19:56 jdk-11.0.4_linux-x64_bin.tar.gz
-rw-r--r-- 1 root root         0 May 31 20:17 readme.txt   # readme.txt  空文件

2、编写dockerfile文件,官方命名 Dockerfile ,build会自动寻找这个文件,就不需要 -f 指定了

FROM centos
MAINTAINER pihao<827699764@qq.com>COPY readme.txt /usr/local/readme.txtADD jdk-11.0.4_linux-x64_bin.tar.gz /usr/local/
ADD apache-tomcat-8.5.45.tar.gz /usr/local/RUN yum -y install vimENV MYPATH /usr/local/
WORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk-11.0.4
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.45
ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.45
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin  # 这里注意,linux的path环境变量是【冒号:】分隔的EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.45/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.45/logs/catalina.out

3、构建镜像

[root@pihao tomcat]# docker build -t diytomcat .   # 注意:这里的-f不用写,因为先前的dockerfile的名字就是Dockerfile
.
.
.
Successfully built 31d4a6fa8956
Successfully tagged diytomcat:latest
# 构建成功

4、启动这个容器

[root@pihao tomcat]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
diytomcat           latest              31d4a6fa8956        6 minutes ago       614MB
# 说明 -v 这里挂载了webapps目录 和 logs目录
[root@pihao tomcat]# docker run -d -p 9090:8080 --name pihao-diy-tomcat -v /home/tomcat/test:/usr/local/apache-tomcat-8.5.45/webapps/test -v /home/tomcat/logs:/usr/local/apache-tomcat-8.5.45/logs diytomcat

5、访问测试

6、发布项目(由于做了卷挂载,我们直接在本地发布项目)

# 切换到主机的/tomcat/test目录,创建WEB-INF目录
[root@pihao test]# mkdir WEB-INF
[root@pihao test]# ls
WEB-INF
[root@pihao WEB-INF]# ls
index.jsp  web.xml

web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"version="2.5"></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>菜鸟教程(runoob.com)</title>
</head>
<body>
Hello World!<br/>
<%
out.println("你的 IP 地址 " + request.getRemoteAddr());
%>
</body>
</html>

访问地址:主机ip:9090/test,项目部署成功,可以直接访问ok

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

发布自己的镜像到DockerHub

DockerHUb
  • 地址:https://hub.docker.com/ 注册自己的账号
  • 确定这个账号可以登入
  • 在服务器上提交自己的镜像
[root@pihao ~]# docker login --helpUsage:  docker login [OPTIONS] [SERVER]Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.Options:-p, --password string   Password--password-stdin    Take the password from stdin-u, --username string   Username
  • 登入完毕后就可以提交镜像了,就是一步 docker push
[root@pihao ~]# docker login -u pihao
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-storeLogin Succeeded # 登入成功
[root@pihao ~]#
[root@pihao ~]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
truevoly/oracle-12c   latest              21789d4d876f        16 months ago       5.7GB
jaspeen/oracle-11g    latest              0c8711fe4f0f        4 years ago         281MB
[root@pihao ~]# docker push jaspeen/oracle-11g
The push refers to repository [docker.io/jaspeen/oracle-11g]
5f70bf18a086: Preparing
7a080c2f6e4d: Layer already exists
59af826791e8: Layer already exists
69264aa86d7e: Layer already exists
denied: requested access to the resource is denied   # 发现给拒绝了,因为这里是根据名字上传到仓库,而这里的是jaspeen账号,那肯定没有权限
[root@pihao ~]# 所以要把这个名字改成自己账号的名字,可以使用docker tag 命令

docker tag 修改镜像名字

发布自己的镜像到阿里云服务器上

  • 1、登入阿里云

  • 2、找到容器镜像服务

  • 3、创建命名空间

  • 4、创建容器镜像

  • 5、浏览阿里云页面信息

  • 6、push到阿里云仓库

    # 退出之前的账号
    [root@pihao ~]# docker logout
    Removing login credentials for https://index.docker.io/v1/
    # 登入阿里云的账号
    [root@pihao ~]# docker login --username=决魂耗子 registry.cn-shenzhen.aliyuncs.com
    # 密码是开通阿里云镜像服务时的那个密码
    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
    [root@pihao ~]#
    
    [root@pihao ~]# docker images
    REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
    truevoly/oracle-12c   latest              21789d4d876f        16 months ago       5.7GB
    jaspeen/oracle-11g    latest              0c8711fe4f0f        4 years ago         281MB
    pihao/oracle-11g      latest              0c8711fe4f0f        4 years ago         281MB
    # 按照阿里云页面提示修改镜像的 tag
    [root@pihao ~]# docker tag jaspeen/oracle-11g registry.cn-shenzhen.aliyuncs.com/docker-pihao-01/pihao-test:1.0
    [root@pihao ~]# docker images
    REPOSITORY                                                     TAG                 IMAGE ID            CREATED             SIZE
    truevoly/oracle-12c                                            latest              21789d4d876f        16 months ago
    jaspeen/oracle-11g                                             latest              0c8711fe4f0f        4 years ago
    pihao/oracle-11g                                               latest              0c8711fe4f0f        4 years ago
    registry.cn-shenzhen.aliyuncs.com/docker-pihao-01/pihao-test   1.0                 0c8711fe4f0f        4 years ago
    # 提交,ok
    [root@pihao ~]# docker push registry.cn-shenzhen.aliyuncs.com/docker-pihao-01/pihao-test
    The push refers to repository [registry.cn-shenzhen.aliyuncs.com/docker-pihao-01/pihao-test]
    5f70bf18a086: Pushed
    7a080c2f6e4d: Pushing [==>                                                ]  4.903MB/108.7MB
    59af826791e8: Pushed
    69264aa86d7e: Pushing [=>                                                 ]  5.404MB/172.3MB

    阿里云镜像的就参考官网文档即可

    小结

Docker网络

理解Docker0

请求所有环境做测试

三个网络

# 问题:docker 是如何处理容器网络访问的,比如容器内的tomcat怎么连接mysql呢??
[root@pihao ~]# docker run -d tomcat -P --name tomcat01 tomcat
# 查看容器的内部网络地址  ip addr 发现容器启动的时候会得到一个 eth0@if79 的ip地址,这时docker分配的
[root@pihao ~]# docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
78: eth0@if79: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group defaultlink/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever
[root@pihao ~]## 思考,linux能不能ping同容器内部!
[root@pihao ~]# 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.094 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.081 ms# linux可以ping通docker容器内部

原理

1、我们每启动一个docker容器,docker就会给容器分配一个ip,我们只要安装了Docker,就会有一个网卡docker0

桥接模式,我们使用的技术是veth-pair技术

再次测试 ip addr,(启动了一个tomcat01容器之后),发现多了一个网络 79: vetha37f3dc@if78(跟容器内的那个地址类似)

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

# 而且还发现这些容器带来的网卡都是一对一对的
# veth-pair技术就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
# 正因为有这个特性,veth-pair 充当一个侨联,连接各种虚拟网络设备

3、我们现在在Docker中启动了tomcat01,tomcat02两个容器,而这两个容器之间是互相独立的,那么他们之间能够ping通嘛?

# tomcat02 的ip是 172.17.0.2
[root@pihao ~]# docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.139 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.096 ms
# 结论: 容器和容器之间是可以Ping 通的,因为都是在同一个网段下 docker0   172.17.0.1

绘制一个网络连接模型图:

结论:tomcat01 和tomcat02是共用的一个路由器,docker01

所有的容器不指定网络的情况下,都是由Docker0来路由的,docker会给每个容器分配一个可用 IP

255.255.0.1/16 可以存25535个地址

255.255.0.1/24 可以存255个地址

小结

Docker使用的是Linxux桥接,宿主机中是一个Docker容器的网桥 docker0

Docker中的所有的网络接口都是虚拟的。虚拟的转发效率高。(内网传递文件,速度非常快 10m 10 m的)

只要容器删除,对应的网桥一对也就删除了!

思考一个场景,我们编写了一个微服务,database url = ip:xxxxxx,而我们每次启动容器的时候ip会变化,能不能通过某种技术,我们直接来ping 通容器的名字,作用效果就像SpringCloud中的feign,通过微服务的名字就能实现远程调用。高可用


–link

不用通过网络,直接通过容器的名字来访问

[root@pihao ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
d4c7d8ebced2        tomcat              "catalina.sh run"   45 minutes ago      Up 45 minutes       0.0.0.0:32769->8080/tcp   tomcat02
081e1f8db911        tomcat              "catalina.sh run"   59 minutes ago      Up 59 minutes       0.0.0.0:32768->8080/tcp   tomcat01
# 想直接通过容器名字来访问,发现行不通
[root@pihao ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
# 如何解决呢??
# 在启动一个tomcat03 启动是使用  --link 命令指定要连接的容器tomcat02
[root@pihao ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
9ec98d9557a1f2424212eda8e036883006cc970ab09daa84391c05e3ec70f2d3
# 通过--link,就可以直接使用容器名字访问
[root@pihao ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.135 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.103 ms
# 缺陷,反向可以ping通嘛??
[root@pihao ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
[root@pihao ~]# 发现反向连接就不行

探究 :inspect

[root@pihao ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
e12a90f69e50        bridge              bridge              local
7514a428f3d0        host                host                local
f1f4981f4fbb        none                null                local
[root@pihao ~]# docker network inspect e12a90f69e50
[{"Name": "bridge","Id": "e12a90f69e507dae3504769ee12399ec18e427de2d29b675cbf593e4b01f371c","Created": "2020-06-01T09:17:54.742162379+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": null,"Config": [{      # docker0的信息"Subnet": "172.17.0.0/16",     # 255*255"Gateway": "172.17.0.1"   # 路由}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": { # 容器内的信息"081e1f8db911bcca7288c0ed3eee687c36a290c0f9b9f5e523a8099389342c91": {"Name": "tomcat01","EndpointID": "c9b47b00655cb11db1735d74ce346ada99b79ad9f399c7686ca944f145a018d1","MacAddress": "02:42:ac:11:00:02","IPv4Address": "172.17.0.2/16","IPv6Address": ""},"9ec98d9557a1f2424212eda8e036883006cc970ab09daa84391c05e3ec70f2d3": {"Name": "tomcat03","EndpointID": "e1bf65587d0ae28997b46dc2ffe49fc9ea89f27ac072e34b62573440da6ca66f","MacAddress": "02:42:ac:11:00:04","IPv4Address": "172.17.0.4/16","IPv6Address": ""},"d4c7d8ebced2387ece1ea16052d3d38c085434552ab9141c171531402295c69c": {"Name": "tomcat02","EndpointID": "5bd840c78f1a6da803ef55c2086f3961db45a897309e30aff1be1d77d01dcd0e","MacAddress": "02:42:ac:11:00:03","IPv4Address": "172.17.0.3/16","IPv6Address": ""}},"Options": {"com.docker.network.bridge.default_bridge": "true","com.docker.network.bridge.enable_icc": "true","com.docker.network.bridge.enable_ip_masquerade": "true","com.docker.network.bridge.host_binding_ipv4": "0.0.0.0","com.docker.network.bridge.name": "docker0","com.docker.network.driver.mtu": "1500"},"Labels": {}}
]
[root@pihao ~]#
docker inpect tomcat03(使用了--kink连接 tomcat02 ),查看如下图,有一个Links

还有一种方式查看它的连接配置,就是进入容器内容,查看它的映射路径,看看是不是用容器的名字来映射对应的地址 比如:tomcat02: 172.17.0.3
[root@pihao ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1       localhost
172.17.0.3      tomcat02 d4c7d8ebced2 # 找到了,在这里,不知可以使用容器的名字,还能使用容器id来访问
172.17.0.4      9ec98d9557a1
[root@pihao ~]#

再来查看一下tomcat02的配置

[root@pihao ~]# docker exec -it tomcat02 cat /etc/hosts
127.0.0.1       localhost
172.17.0.3      d4c7d8ebced2
[root@pihao ~]# 发现这里并没有配置tomcat03的路径,那就不能通过tomcat03来访问了,那就再次使用 -- link了

本质探究: --link就是我们在hosts配置中增加了一个172.17.0.3 tomcat02 d4c7d8ebced2

其实我们在使用Docker 已经不建议使用 --link了!!

我们要自定义网络,不使用默认的Docker0网络

Docker0的问题:他不支持容器名连接访问

自定义网络

# 查看所有的docker 网络
[root@pihao ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
e12a90f69e50        bridge              bridge              local
7514a428f3d0        host                host                local
f1f4981f4fbb        none                null                local
[root@pihao ~]#

网络模式

  • bridge 桥接:在docker上搭桥(默认,自己创建也是用bridge模式)

  • none : 不配置网络

  • host : 主机,和宿主机共享网络

  • container : 容器内网络连通(用的少,局限性很大)

测试

# 我们之前直接启动的命令,--net bridge,默认会有这个参数,这个就是我们的docker0
[root@pihao ~]# docker run -d -P --name tomcat01 tomcat
[root@pihao ~]# docker run -d -P --name tomcat01 --net bridge tomcat# docker0特点,默认使用的,域名不能访问, --link可以打通连接# 我们可以自定义一个网络
[root@pihao ~]# docker network create --helpUsage:  docker network create [OPTIONS] NETWORK
Create a network
Options:--attachable           Enable manual container attachment--aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])-d, --driver string        Driver to manage the Network (default "bridge")     # 桥接--gateway strings      IPv4 or IPv6 Gateway for the master subnet       # 指定网关-o, --opt map              Set driver specific options (default map[])--scope string         Control the network's scope--subnet strings       Subnet in CIDR format that represents a network segment # 设置子网(必须要配置)
[root@pihao ~]#

创建一个自己的网络

#  --driver bridge
# --subnet 192.168.0.0/16    支持范围: 192.168.0.2~192.168.255.255
# --gateway 192.168.0.1
[root@pihao ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
8f69e37f277cb7c27c28852076b9d5beafa73c597c2464bbf6d1418710c3e6be
[root@pihao ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
e12a90f69e50        bridge              bridge              local
7514a428f3d0        host                host                local
8f69e37f277c        mynet               bridge              local   # 我们自定义的网络
f1f4981f4fbb        none                null                local
[root@pihao ~]#

查看自己的网络

再次启动tomcat测试,启动的时候指定我们自己定义的网络 mynet

[root@pihao ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
b5db4c5c94d049c6caaef2b2ae39c34e9470ac0c4dd44a59bea77b57cce98649
[root@pihao ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
28129f9f6304265405274bfbfe3b348a7f70ece8f3772fafed7d955c17ff78ef

启动完毕后再来检查我们的 mynet 网络

最后自定义网络能不能通过容器名来访问,不使用 --link

[root@pihao ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.128 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.105 ms
# 发现可以,没问题

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

好处:保证不同的集群使用不同的网络,保证集群是安全和健康的。因为都在不同的网段!!

网络连通

现有的容器及所在网络:

使用docker0网络下的tomcat01来 Ping 一下mynet 网络下的tomcat-net-01

[root@pihao ~]# docker exec -it tomcat01 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known
[root@pihao ~]# 发现不行,肯定不行呀,因为这都属于不同的网段下了
# 思考:那如果我想要他能ping通,该怎么操作呢??

图示:

注意:这里说的 要打通 还不是两个网络直接打通(Docker0打通mynet),而是 容器与网卡打通(tomcat-01 与mynet打通)!!!

如何打通??

# 测试打通 tomcat01  -  mynet
[root@pihao ~]# docker network connect mynet tomcat01
# 打通之后查看一下网络
[root@pihao ~]# docker network inspect mynet
# 发现连通之后就是将 tomcat01 放到了mynet 网络下
# 这就是所谓的一个容器两个 IP

再来使用 tomcat01 ping 一下 tomcat-net-01

[root@pihao ~]# docker exec -it tomcat01 ping tomcat-net-01
# 发现现在通了(不同的网卡的容器)
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.098 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.100 ms# 而tomcat02是Ping不通的,因为tomcat02没有和 mynet 打通
[root@pihao ~]# docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known
[root@pihao ~]#

结论:假设要跨网络去操作别人,就需要使用 docker network connect 网络名 容器名 来打通!!!

实战:部署Redis集群

集群模式:分片+高可用+负载均衡

# 创建redis集群的网卡
[root@pihao ~]# docker network create redis --subnet 172.38.0.0/16
# 通过脚本创建六个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >>/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
# shell配置文件的脚本ok# 启动 第一个 redis
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# 启动 第二个 redis
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# 启动 第三个 redis
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# 启动 第四个 redis
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# 启动 第五个 redis
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# 启动 第六个 redis
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf# 六个redis启动后:
[root@pihao conf]# docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED              STATUS              PORTS                                              NAMES
8be3b0272fa5        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   2 seconds ago        Up 1 second         0.0.0.0:6376->6379/tcp, 0.0.0.0:16376->16379/tcp   redis-6
7daf1edb4fa3        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   30 seconds ago       Up 29 seconds       0.0.0.0:6375->6379/tcp, 0.0.0.0:16375->16379/tcp   redis-5
277223569dd6        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6374->6379/tcp, 0.0.0.0:16374->16379/tcp   redis-4
e5455ca3d11b        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   2 minutes ago        Up 2 minutes        0.0.0.0:6373->6379/tcp, 0.0.0.0:16373->16379/tcp   redis-3
af4a01eb4e49        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   4 minutes ago        Up 4 minutes        0.0.0.0:6372->6379/tcp, 0.0.0.0:16372->16379/tcp   redis-2
2250d384e975        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   6 minutes ago        Up 6 minutes        0.0.0.0:6371->6379/tcp, 0.0.0.0:16371->16379/tcp   redis-1
[root@pihao conf]## 进入启动一个 redis-1的容器
[root@pihao conf]# docker exec -it redis-1 /bin/sh  (注意:这里发现redis没有  /bin/bash命令  只有 /bin/sh 命令)
# 默认进来的是 /data 目录
/data # ls 查看到有两个文件
appendonly.aof  nodes.conf
# 创建集群
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
# 三台主机master
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
# 三台从机slave
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379 # 15是11的从机
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379 # 16是12的从机
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379 # 14是13的从机
M: fe1da2ced57ea42176134194c8f919478e938ec7 172.38.0.11:6379slots:[0-5460] (5461 slots) master
M: 2dd905acf6fd1a633c3c2d246fbc78ab166148a8 172.38.0.12:6379slots:[5461-10922] (5462 slots) master
M: 73bc0387c4e7006621cf71201b799a8611c51716 172.38.0.13:6379slots:[10923-16383] (5461 slots) master
S: 35f7de80fc3debca9e8fc6c84c6dfd88291f9695 172.38.0.14:6379replicates 73bc0387c4e7006621cf71201b799a8611c51716
S: 8a5ef9825fb194d43b02dcc731de3d2a7c28ca79 172.38.0.15:6379replicates fe1da2ced57ea42176134194c8f919478e938ec7
S: 090fda90e4dcd7ca8466987c7150e3302a9c8662 172.38.0.16:6379replicates 2dd905acf6fd1a633c3c2d246fbc78ab166148a8
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: fe1da2ced57ea42176134194c8f919478e938ec7 172.38.0.11:6379slots:[0-5460] (5461 slots) master1 additional replica(s)
S: 8a5ef9825fb194d43b02dcc731de3d2a7c28ca79 172.38.0.15:6379slots: (0 slots) slavereplicates fe1da2ced57ea42176134194c8f919478e938ec7
M: 2dd905acf6fd1a633c3c2d246fbc78ab166148a8 172.38.0.12:6379slots:[5461-10922] (5462 slots) master1 additional replica(s)
S: 35f7de80fc3debca9e8fc6c84c6dfd88291f9695 172.38.0.14:6379slots: (0 slots) slavereplicates 73bc0387c4e7006621cf71201b799a8611c51716
S: 090fda90e4dcd7ca8466987c7150e3302a9c8662 172.38.0.16:6379slots: (0 slots) slavereplicates 2dd905acf6fd1a633c3c2d246fbc78ab166148a8
M: 73bc0387c4e7006621cf71201b799a8611c51716 172.38.0.13:6379slots:[10923-16383] (5461 slots) master1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.        # 创建成功啦
# 连接集群 -c 表示的是连接集群  不加的话表示单机
/data # redis-cli -c
127.0.0.1:6379>

查看集群信息

开始测试

# set k1 v1

# docker stop

# get k1 看看能不能拿到值,发现拿到值了,并且发现是通过14这太从机获取到的,说明高可用生效了

docker 搭建redis完成

## 再次查看集群信息,发现172.38.0.13:6379@16379 master,fail,并且172.38.0.14:6379@16379 myself,maste(13挂了,14成了主机)
172.38.0.14:6379> cluster nodes
8a5ef9825fb194d43b02dcc731de3d2a7c28ca79 172.38.0.15:6379@16379 slave fe1da2ced57ea42176134194c8f919478e938ec7 0 1591447999393 5 connected
090fda90e4dcd7ca8466987c7150e3302a9c8662 172.38.0.16:6379@16379 slave 2dd905acf6fd1a633c3c2d246fbc78ab166148a8 0 1591448000397 6 connected
35f7de80fc3debca9e8fc6c84c6dfd88291f9695 172.38.0.14:6379@16379 myself,master - 0 1591448000000 7 connected 10923-16383
fe1da2ced57ea42176134194c8f919478e938ec7 172.38.0.11:6379@16379 master - 0 1591447999000 1 connected 0-5460
73bc0387c4e7006621cf71201b799a8611c51716 172.38.0.13:6379@16379 master,fail - 1591447080985 1591447080000 3 connected
2dd905acf6fd1a633c3c2d246fbc78ab166148a8 172.38.0.12:6379@16379 master - 0 1591447999000 2 connected 5461-10922
172.38.0.14:6379>

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

SpringBoot微服务打包Docker镜像

1、构建SpringBoot项目

2、打包应用

3、编写dockerfile

FROM java:8COPY *.jar /app.jarCMD ["--server.port=8080"]EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

4、构建镜像

5、发布运行

[root@pihao eclipse]# ls
Dockerfile  docker-test-0.0.1-SNAPSHOT.jar   # 只要这两个文件
[root@pihao eclipse]# docker build -t pihao-docker-test .
Sending build context to Docker daemon  16.47MB
Step 1/5 : FROM java:8
8: Pulling from library/java
5040bd298390: Pull complete
fce5728aad85: Pull complete
76610ec20bf5: Pull complete
60170fec2151: Pull complete
e98f73de8f0d: Pull complete
11f7af24ed9c: Pull complete
49e2d6393f32: Pull complete
bb9cdec9c7f3: Pull complete
Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
Status: Downloaded newer image for java:8---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar---> cd9911f3fe9c
Step 3/5 : CMD ["--server.port=8080"]---> Running in 5926ef3df86e
Removing intermediate container 5926ef3df86e---> 12bf641f1df0
Step 4/5 : EXPOSE 8080---> Running in 1e5a2f7bf6c6
Removing intermediate container 1e5a2f7bf6c6---> 658947a6d2b7
Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]---> Running in 4296335cbd4c
Removing intermediate container 4296335cbd4c---> d6df5ff457b9
Successfully built d6df5ff457b9
Successfully tagged pihao-docker-test:latest
# 查看构建的镜像
[root@pihao eclipse]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
pihao-docker-test   latest              d6df5ff457b9        12 seconds ago      660MB
tomcat              latest              1b6b1fe7261e        3 weeks ago         647MB
redis               5.0.9-alpine3.11    3661c84ee9d0        6 weeks ago         29.8MB
java                8                   d23bdf5b1b1b        3 years ago         643MB
# 运行容器
[root@pihao eclipse]# docker run -d -P --name springbootweb-docker pihao-docker-test
39d59e8a9bc26264b418c387f147caac40884eaaf31544c50b29a37dfc8d41
# 查看随机随机生成的端口
[root@pihao eclipse]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
39d59e8a9bc2        pihao-docker-test   "java -jar /app.jar …"   41 seconds ago      Up 40 seconds       0.0.0.0:32777->8080/tcp   springbootweb-docker
# 访问测试
[root@pihao eclipse]# curl localhost:32777/hello
hello
[root@pihao eclipse]#
# 完美运行

思考:如果有很多镜像呢??100个镜像,要怎么管理??

Docker Compose

Docker Swarm

CI/CD之Jenkins

只要学不死,就往死里学!!!

Docker入门详细教程,全网最全!相关推荐

  1. Docker入门详细教程

    目录 Docker的介绍 Docker的思想 集装箱 标准化 运输方式 存储方式 API接口 隔离 Docker的组成 镜像 容器 仓库 Docker的运行机制 拉取镜像的执行流程 启动容器的执行流程 ...

  2. NMAP入门详细教程

    NAMP入门详细教程 一.功能: 网络扫描和嗅探. 二.原理: 使用TCP/IP协议栈指纹准确地判断目标主机的相关信息. 三.作用: 识别活跃主机 识别开放端口以及相关的服务 识别主机的系统指纹 路由 ...

  3. spring入门详细教程(五)

    前言 本篇紧接着spring入门详细教程(三),建议阅读本篇前,先阅读第一篇,第二篇以及第三篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/ ...

  4. Spring入门详细教程(四)

    前言 本篇紧接着spring入门详细教程(三),建议阅读本篇前,先阅读第一篇,第二篇以及第三篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/ ...

  5. Spring入门详细教程(三)

    前言 本篇紧接着spring入门详细教程(二),建议阅读本篇前,先阅读第一篇和第二篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/p/101 ...

  6. Spring入门详细教程(二)

    前言 本篇紧接着spring入门详细教程(一),建议阅读本篇前,先阅读第一篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/p/1016553 ...

  7. ThinkJS框架入门详细教程(二)新手入门项目

    一.准备工作 参考前一篇:ThinkJS框架入门详细教程(一)开发环境 安装thinkJS命令 npm install -g think-cli 监测是否安装成功 thinkjs -v 二.创建项目 ...

  8. Pandas入门详细教程

    作者:luanhz 来源:小数志 导读 本文主要是对pandas进行入门详细介绍,通过本文你将系统性了解pandas为何会有数据分析界"瑞士军刀"的盛誉. 行文二级目录 01 关于 ...

  9. numpy入门详细教程(一)

    本讲主要介绍对numpy库和numpy库的N维数组对象:ndarray的基本了解.更多内容请看numpy入门详细教程(二) numpy: NumPy是一个开源的Python科学计算基础库,包含: • ...

最新文章

  1. 【深度学习】孪生网络(Siamese Network)的模式和训练过程
  2. 九度OJ 1011:最大连续子序列 (DP)
  3. sublimeText3 工具
  4. python 实现杨辉三角(依旧遗留问题)
  5. dpkg and apt
  6. GDCM:将PAPYRUS 3.0文件转换为dcm文件的的测试程序
  7. 【git】【eclipse】免密/SSH 方式连接免登录
  8. 超微服务器 旧系统盘 新服务器,超微服务器做系统
  9. 今天的就每天练习这招的企业即时通讯
  10. 你的袜子还是干的吗?
  11. 以WinGrub 引导安装Fedora 4.0 为例,详述用WinGrub来引导Linux的安装
  12. VRRP协议与keepalived原理及功能实例演示
  13. DEDE 织梦 CMS 文章采集不到
  14. h5判断百度、高德、腾讯地图客户端是否安装及调起客户端导航
  15. opencv(16) ROI区域图像叠加图像混合
  16. 【网络工程】交换机各层作用,100路监控摄像是否_该采用核心交换机吗
  17. 如何写工学硕士学位论文
  18. 爬虫总结(二)-- scrapy
  19. CentOs6.5 详细安装步骤
  20. 面试题48:最长不含重复字符的子字符串

热门文章

  1. 【递推】Ybt_平铺方案
  2. python 列表的操作
  3. 斯坦福和NLTK英语短语词组抽取工具原理及源码理解
  4. linux 列转行函数,GP行转列、列转行函数
  5. [HDRP] PBR Lit shader(一.基础用法篇)
  6. 什么是以太坊大都会:终极指南
  7. 基于微信小程序的服装童装商城+后台管理系统(SSM+mysql)-JAVA.VUE【毕业设计、论文、源码、开题报告】
  8. check的3种用法
  9. Tomcat启动报错 More than one fragment with the name [spring_web] was found. This is not legal with relat
  10. win7 matlab 读 grib2数据