Docker入门详细教程,全网最全!

Docker

Docker学习

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

Docker概述

Docker为什么会出现?

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

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

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

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

之前在服务器配置一个应用的环境Redis,Mysql,jdk,ES,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 $MYPATH


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

EXPOSE 80

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


# 2、再通过这个文件构建镜像
# 命令 docker build -f 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.txt

ADD 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 vim

ENV MYPATH /usr/local/
WORKDIR $MYPATH

ENV 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/javaee
                               http://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 --help

Usage:  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-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
[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 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
78: eth0@if79: <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@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 --help

Usage:  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:6379
   slots:[0-5460] (5461 slots) master
M: 2dd905acf6fd1a633c3c2d246fbc78ab166148a8 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 73bc0387c4e7006621cf71201b799a8611c51716 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 35f7de80fc3debca9e8fc6c84c6dfd88291f9695 172.38.0.14:6379
   replicates 73bc0387c4e7006621cf71201b799a8611c51716
S: 8a5ef9825fb194d43b02dcc731de3d2a7c28ca79 172.38.0.15:6379
   replicates fe1da2ced57ea42176134194c8f919478e938ec7
S: 090fda90e4dcd7ca8466987c7150e3302a9c8662 172.38.0.16:6379
   replicates 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:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 8a5ef9825fb194d43b02dcc731de3d2a7c28ca79 172.38.0.15:6379
   slots: (0 slots) slave
   replicates fe1da2ced57ea42176134194c8f919478e938ec7
M: 2dd905acf6fd1a633c3c2d246fbc78ab166148a8 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 35f7de80fc3debca9e8fc6c84c6dfd88291f9695 172.38.0.14:6379
   slots: (0 slots) slave
   replicates 73bc0387c4e7006621cf71201b799a8611c51716
S: 090fda90e4dcd7ca8466987c7150e3302a9c8662 172.38.0.16:6379
   slots: (0 slots) slave
   replicates 2dd905acf6fd1a633c3c2d246fbc78ab166148a8
M: 73bc0387c4e7006621cf71201b799a8611c51716 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.        # 创建成功啦
# 连接集群 -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:8

COPY *.jar /app.jar

CMD ["--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 Docker 最初是dotCloud 公司创始人Solomon Hykes 在法国期间发起的一个公司内部项目, 它是基于dotCloud 公司多年云服务技术的一次革新,并于2013 年3 月以Apache 2.0 授权 协议开源,主要项目代码在GitHub 上进行维护。Docker 项目后来还加入了Linux 基金会, 并成立推动开放容器联盟(OCI)。 Docker 自开源后受到广泛的关注和讨论,至今其GitHub 项目已经超过4 万6 千个星标和一 万多个fork。甚至由于Docker 项目的火爆,在2013 年底,dotCloud 公司决定改名为 DockerDocker 最初是在Ubuntu 12.04 上开发实现的;Red Hat 则从RHEL 6.5 开始对 Docker 进行支持;Google 也在其PaaS 产品中广泛应用DockerDocker 使用Google 公司推出的Go 语言进行开发实现,基于Linux 内核的 cgroup,namespace,以及AUFS 类的Union FS 等技术,对进程进行封装隔离,属于操作 系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容 器。最初实现是基于LXC,从0.7 版本以后开始去除LXC,转而使用自行开发的 libcontainer,从1.11 开始,则进一步演进为使用runC 和containerd。 Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极 大的简化了容器的创建和维护。使得Docker 技术比虚拟机技术更为轻便、快捷。 下面的图片比较了Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件 后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程 直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比 传统虚拟机更为轻便。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值