齐仔学Docker

一、Docker简介

  Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器使用沙箱机制,相互之间隔离。
  那么,Docker的设计理念优势在哪里?这就要从传统项目开发部署流程说起。

  • 本地开发+测试,通过后编译打包发布到测试环境
  • 测试环境测试,通过后发布到生产环境

  这个过程中,经常会遇到本地开发环境没问题,发布到测试和生产环境出问题的状况。这种现象通常是运行环境或配置不同导致的。而Docker就可以将应用连同它的运行环境和配置一同打包,这样,在开发环境、测试环境和生产环境都是完全一致的,避免了上述问题。
  此外,Docker的设计思想来源于集装箱,彼此隔离,互不影响,这一点从Docer的logo就可以看出。
在这里插入图片描述
  与VM(虚拟机)相比,Docker只包含应用程序以及依赖库,基于libcontainer运行在宿主机上,并处于一个隔离的环境中,这使得Docker更加轻量高效,启动容器只需几秒钟之内完成。而VM是一个运行在宿主机之上的完整操作系统,VM运行自身操作系统会占用较多的CPU、内存、硬盘资源。
在这里插入图片描述  总体来讲,Docker的优点可以总结为:持续集成、版本控制、可移植性、隔离性和安全性。也可以基于Docker,方便的实现CI/CD (持续集成,持续部署),可以说是DevOps工程化的基础。
  注:DevOps 是dev(开发)和ops(运维)组合起来的一个名词,强调的是高效组织团队之间如何通过自动化的工具协作和沟通来完成软件的生命周期管理,从而更快、更频繁地交付更稳定的软件。

二、Docker安装

  Docker的官方文档上有非常详细的安装教程,本文以CentOS为例,文档地址如下:https://docs.docker.com/engine/install/centos/

  首先查看当前服务器环境:

#查看系统内核
[root@bogon ~]# uname -r
3.10.0-514.el7.x86_64

#查看系统版本
[root@bogon ~]# 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"

  Docker在CentOS上的安装步骤如下:

  1. 如果已经安装过,需要首先卸载:
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
  1. 安装需要的安装包:
sudo yum install -y yum-utils
  1. 配置镜像仓库,国外的慢,可以配置使用阿里云镜像库
#官方镜像库
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  
  1. 安装Docker引擎
#ce是社区版 ee是企业版
sudo yum install docker-ce docker-ce-cli containerd

    可以先更新软件包索引:

yum makecache fast
  1. 启动Dcker
sudo systemctl start docker
  1. 判断是否安装成功:
[root@bogon ~]# docker version
Client:
 Version:      1.9.1
 API version:  1.21
 Go version:   go1.4.3
 Git commit:   a34a1d5
 Built:        Fri Nov 20 17:56:04 UTC 2015
 OS/Arch:      linux/amd64

Server:
 Version:      19.03.5
 API version:  1.40
 Go version:   go1.12.12
 Git commit:   633a0ea
 Built:        2019-11-13T07:24:18.000000000+00:00
 OS/Arch:      linux/amd64
  1. 查看Docker 运行状态:
[root@bogon docker]# systemctl status docker -l
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 日 2020-08-16 01:06:21 CST; 4 weeks 0 days ago
     Docs: https://docs.docker.com
 Main PID: 2713 (dockerd)
    Tasks: 48
   Memory: 118.9M
   CGroup: /system.slice/docker.service
           ├─ 2713 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
           ├─13221 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 9090 -container-ip 172.17.0.2 -container-port 9090
           └─13487 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 3000 -container-ip 172.17.0.3 -container-port 3000

    显示绿色的Active,表示当前在运行。

  1. 测试Hello World
[root@bogon ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete 
Digest: sha256:4cf9c47f86df71d48364001ede3a4fcd85ae80ce02ebad74156906caff5378bc
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

    打印出Hello from Docker! 证明可以成功使用。

  1. 查看下载下来的镜像
[root@bogon ~]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
hello-world          latest              sha256:bf756        8 months ago        13.34 kB
  1. 卸载Docker
#卸载依赖
sudo yum remove docker-ce docker-ce-cli containerd.io

#删除资源
sudo rm -rf /var/lib/docker

#Docker的默认资源路径
/var/lib/docker

三、Docker使用

    Docker的基本组成包括:镜像(image)、容器(container)、仓库(repository)
在这里插入图片描述
    其中,镜像(Image)是其他虚拟化技术(特别是虚拟机)中常常被使用的一个概念,可以理解为一个只读的文件包,其中包含了虚拟环境运行最原始文件系统的内容。Docker的镜像与虚拟机中的镜像还是有一定区别的。Docker中的一个创新是利用了AUFS(Advance UnionFS 一种联合文件系统)作为底层文件系统实现,通过这种方式,Docker实现了一种增量式的镜像结构。每次对镜像内容的修改,Docker都会将这些修改铸造成一个镜像层,而一个镜像其实就是由其下层所有的镜像层所组成的。每一个镜像层单独拿出来,与它之下的镜像层都可以组成一个镜像。
    另外,由于这种结构,Docker的镜像实质上是无法被修改的,因为所有对镜像的修改只会产生新的镜像,而不是更新原有的镜像。
    而容器则是用镜像创建的运行实例,也可以理解为被隔离出来的虚拟环境。
仓库(Repository)是集中存放镜像文件的场所,在设计和使用上都与GitHub类似。
    Docker文档:https://docs.docker.com/
    DockerHub地址:https://hub.docker.com/

    在Docker中,几个常用的基础命令如下:

#版本信息:
[root@bogon docker]# docker version
Client:
 Version:      1.9.1
 API version:  1.21
 Go version:   go1.4.3
 Git commit:   a34a1d5
 Built:        Fri Nov 20 17:56:04 UTC 2015
 OS/Arch:      linux/amd64

Server:
 Version:      19.03.5
 API version:  1.40
 Go version:   go1.12.12
 Git commit:   633a0ea
 Built:        2019-11-13T07:24:18.000000000+00:00
 OS/Arch:      linux/amd64

#Docker系统信息
[root@bogon docker]# docker info
Containers: 23
Images: 15
Server Version: 19.03.5
Storage Driver: overlay2
 Backing Filesystem: xfs
 Supports d_type: true
 Native Overlay Diff: false
Execution Driver: <not supported>
Logging Driver: json-file
Kernel Version: 3.10.0-514.el7.x86_64
Operating System: CentOS Linux 7 (Core)
CPUs: 4
Total Memory: 7.538 GiB
Name: bogon
ID: KD3A:DNMU:R5M6:6AKR:5VB6:HLXH:EEZF:IZOE:INJS:NOSI:IKNQ:UPJP
Labels:


#帮助命令docker images --help
[root@bogon docker]# docker --help
或 docker 命令 --help

    更多更详细的命令介绍可参见Docker官方文档:https://docs.docker.com/reference/

1. 常用镜像命令

#查看所有本地主机上的镜像
[root@bogon docker]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
hello-world          latest              sha256:bf756        8 months ago        13.34 kB

#选项(使用docker images --help 查看使用帮助文档 )
-a 查看所有镜像
-q 仅显示镜像id
# 搜索命令
[root@bogon docker]# docker search --help

Usage:	docker search [OPTIONS] TERM

Search the Docker Hub for images

  --automated=false    Only show automated builds
  --help=false         Print usage
  --no-trunc=false     Don't truncate output
  -s, --stars=0        Only displays with at least x stars

#仅搜索至少x颗星的:--stars
[root@bogon docker]# docker search --stars=3000 mysql 
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relati...   9958      [OK]       
mariadb   MariaDB is a community-developed fork of M...   3642      [OK]  

#或: -s
[root@bogon docker]# docker search -s=3000 mysql 
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relati...   9958      [OK]       
mariadb   MariaDB is a community-developed fork of M...   3642      [OK]
#下载镜像 docker pull [OPTIONS] NAME[:TAG|@DIGEST] 
# 不设置tag,默认使用latest版本。版本号可以从dockerhub上查询可用的版本
[root@bogon docker]# docker pull mysql 
Using default tag: latest
latest: Pulling from library/mysql
d121f8d1c412: Pull complete 
f3cebc0b4691: Pull complete 
1862755a0b37: Pull complete 
489b44f3dbb4: Pull complete 
690874f836db: Pull complete 
baa8be383ffb: Pull complete 
55356608b4ac: Pull complete 
dd35ceccb6eb: Pull complete 
429b35712b19: Pull complete 
162d8291095c: Pull complete 
5e500ef7181b: Pull complete 
af7528e958b6: Pull complete 
Digest: sha256:e1bfe11693ed2052cb3b4e5fa356c65381129e87e38551c6cd6ec532ebe0e808
Status: Downloaded newer image for mysql:latest

#Docker采用联合文件系统的设计,pull的时候分层下载,已经存在的层不会重复下载
#删除镜像: docker  rmi  镜像id
[root@bogon docker]# docker rmi  sha256:e1d7d
Untagged: mysql:latest
Untagged: mysql@sha256:e1bfe11693ed2052cb3b4e5fa356c65381129e87e38551c6cd6ec532ebe0e808
Deleted: sha256:e1d7dc9731daa2c79858307d65ef35f543daf97457b9c11b681f78bb86f7a158
Deleted: sha256:303dd82484b7080d07af8ab7f383755d8b4d723a2ade8c2e3a516ae59fbc1d63
Deleted: sha256:6346e1a264e283de286e399bc798b8e6a910176180aa1ef1acc54dbace18111a
Deleted: sha256:6c7a3d83131ddf3414e34e14826cbfb8f01a6d6486cd41d9a7a2bcc84350b4f0
Deleted: sha256:79b91792bcadd6668ab861a83623dedcc38574c5f033d2f8336671588a1c4de0
Deleted: sha256:00bdff03938c98e1fee710e8c447a1c30e7365859dd28e2a166792d7cd343fa9
Deleted: sha256:3fc742b087b51753835895403bd70b649bf2e4e32c5eb5f2f15c2b7d22409964
Deleted: sha256:00d53c8dcb5c8fd12fbfd2b3b25afcbc3a044e73f1fd395af231f86827238fcf
Deleted: sha256:007d9a78de83bec432afb0e4e847072a6943e853456fe21b70488d25c1c96bf4
Deleted: sha256:31fd54b7e8a4e80375cbfd9ead44c37e0ee03d8c4ca7ace27cc1896e9d40e2a2
Deleted: sha256:22d626b2851ecf92af46f616ce1ff0ef0879ef23b68be2fb92be3311f2308763
Deleted: sha256:5da80bf7a61d70d69c153f015cd2a5aa96594f36f3835ef6dbcd4da41da374f2
Deleted: sha256:07cab433985205f29909739f511777a810f4a9aff486355b71308bb654cdc868

# 删除所有镜像
docker  rmi  -f  ${docker images -aq}

2. 常用容器命令

# docker pull centos  下载centos镜像

#运行容器
docker run  [可选参数]  image
# 参数说明
--name=”Name”  容器名,tomcat01 tomcat02 用来区分容器
-d              后台方式运行
-it              使用交互方式运行,进入容器查看内容
-p
   -p ip :主机端口:容器端口
   -p 主机端口:容器端口
   -p 容器端口
   容器端口
-P                随机指定端口

#运行centos
docker run  -it  centos  /bin/bash
#退出到容器外,容器停止并退出 exit
# Ctr + p + q 退出后容器不停止
#查看运行的容器: docker ps 
默认  #当前正在运行的容器
-a    #显示所有容器=当前运行的容器+历史运行过的容器
-n=?  #显示醉经创建的?个容器
-q    #之显示容器的编号

#列出所有容器的id
docker ps -aq   
#删除指定容器,但不能删除运行着的,可通过-f参数强制删除
docker rm 容器id

#删除所有容器
docker rm ${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 镜像名
-->docker ps的时候却发现停止了

#原因是docker 容器使用后台运行,必须要有一个前台进程。如在使用docker run -d启动centos时,docker发现没有应用,就自杀了。
#查看日志命令
[root@bogon docker]# docker logs -f -t --tail=10 ba4f282d3932
ERRO[0000] Error parsing media type:  error: mime: no media type 
2020-09-13T05:00:06.882046191Z level=error ts=2020-09-13T05:00:06.881Z caller=file.go:216 component="discovery manager scrape" discovery=file msg="Error adding file watch" path=/opt/prometheus/groups/applicationgroups err="no such file or directory"
2020-09-13T05:05:06.883226231Z level=error ts=2020-09-13T05:05:06.881Z caller=file.go:216 component="discovery manager scrape" discovery=file msg="Error adding file watch" path=/opt/prometheus/groups/applicationgroups err="no such file or directory"

#-c 读取后面内容
docker run -d centos /bin/bash -c “while true ;do echo xxx;sleep 1; done”
#容器进程信息 :docker top 容器id

[root@bogon docker]# docker top ba4f282d3932
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
nfsnobo+            13248               13229               0                   9��03               ?                   00:28:34            /bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --web.console.libraries=/usr/share/prometheus/console_libraries --web.console.templates=/usr/share/prometheus/consoles
#查看容器元数据 :docker inspect 容器id
[root@bogon docker]# docker inspect ba4f282d3932
#进入容器:docker exec -it 容器id  /bin/bash  ,进入容器后开启一个新的终端
#或者: docker attach 容器id  ,是进入正在执行的终端
#从容器拷贝文件到主机(主机上拷到容器内,一般用卷挂载)
#只要容器在,无论是否运行都可以拷贝
docker cp 容器id:容器内路径 主机路径

    综上,Docker常用命令小结:
在这里插入图片描述    其他命令:

#docker commit 提交容器成为一个新的镜像,命令和git原理类似
docker commit -m=“提交的描述信息” -a=“作者” 容器id 目标镜像名:[TAG]
#将当前容器提交为tomcat02  1.0版本
docker commit -a=”qizai” -m=”add webapps” 容器id tomcat02:1.0

3. 容器数据卷

    在实际项目中,程序经常有保存数据的需求。如果将数据存放在容器中,容器删除数据就会丢失。因此,我们希望将数据存储在本地,容器之间可以有一个数据共享的技术。可以理解为目录的挂载,即将容器内的目录挂载到宿主机Linux上。
    数据卷的挂载有2种常用方式:命令方式和DockerFile方式。
    通过命令方式挂载如下:

#方式一:直接使用命令挂载 -v
docker run -it -v 主机目录:容器目录
(是双向绑定:容器目录产生的数据会同步到主机目录,主机目录产生的数据也会同步到容器目录)

#可以通过docker inspect 容器id  查看容器状况
其中的Mounts 信息就是挂载的情况

#使用场景:修改配置等,只需在本地修改,容器内会自动同步

    例子:部署mysql,将数据挂载出来

#获取镜像
docker pull mysql:5.7

#启动容器  -d 后台运行   -e 环境配置,此处配置root用户的密码
docker run -d -p 3310:3306  -v  /home/mysql/conf:/etc/mysql/cong.d  -v /home/mysql/dta:/var/lib/mysql  -e MY_SQL_ROOT_PASSWORD=123456  --name mysql01  mysql:5.7

#容器删除,发现数据没有丢失,实现了数据持久化功能

    具名挂载和匿名挂载:

#匿名挂载  仅指定容器内目录,不指定主机目录  -P 随机映射端口
docker run  -d  -P  --name nginx01  -v  /etc/nginx  nginx

#具名挂载  将卷起命为juming-nginx(前面不加斜杠,否则表示路径)
docker run -d -P --name nginx02  -v  juming-nginx:/etc/nginx  nginx

#查看挂载命令使用  docker  volume  --help

#查看所有卷的情况  docker volume  ls

#查看卷 docker volume inspect  juming-nginx
在不指定主机内路径的时候,名字为juming-ngix的卷挂载的位置 /var/lib/docker/volumes/juming-nginx/_data
通过具名挂载可以方便的找到数据卷

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

#拓展  ro  rw改变读写权限
#一旦设置了权限,容器对我们挂载出来的内容就有限定了
docker run -d -P nginx02 -v juming-nginx:/etc/nginx:ro  nginx
docker run -d -P nginx02 -v juming-nginx:/etc/nginx:rw  nginx

# ro 这个路径只能通过宿主机操作,容器内部无权修改
#rw 容器对这个路径可读可写

    通过DockerFile挂载如下:
    创建一个文件,命名为:dockerfile1,内容如下

FROM centos 

VLOLUME [“volume01”,”volume02”]

CMD echo “---end---”

CMD /bin/bash
#根据上述dockerfile构建镜像qizai/centos 前面不能有斜杠,最后的点不能丢表示当前目录
docker build -f  /home/docker-test-volume/dockerfile1 -t  qizai/centos:1.0  .

    volume01 和volume02 就是生成镜像的时候自动挂载的,这2个卷一定和外部的路径有同步。由于只写了容器内的路径,因此是属于匿名挂载。

#查看当前容器的挂载情况
docker inspect 容器id
(Mounts信息下就是挂载的情况)

    数据卷容器:多个容器之间同步数据,实现数据共享

#通过volume-from 继承docker01的挂载  ,docker01创建的数据,docker02里就有了
#docker01就叫数据卷容器
#如果删掉docker01,docker02和docker03的文件还是在的
docker run -it --name docker02 --volume-from  docker01  qqq/centos:1.0
docker run -it --name docker03 --volume-from  docker01  qqq/centos:1.0

    数据卷容器的生命周期会持续到没有容器使用为止。
    但是一旦持久化到本地,本地的数据是不会删除的。

4. Dockerfile

   DockerFile:是用来构建Docker镜像的文件,是一个命令参数脚本。
   构建步骤:

1)编写一个DockerFile文件
2)docker build 构建成为一个镜像
3)docker run 运行镜像
4)docker push 发布镜像(DockerHub,阿里云镜像仓库)

   基础知识:
1)每个保留关键字(指令)都必须是大写字母
2)执行从上到下顺序执行
3)#表示注释
4)每一个指令都会创建一个新的镜像层,并提交。
在这里插入图片描述   DockerFile是面向开发的,是我们以后发布项目做镜像,就需要编写DockerFile。Docker镜像逐渐成为企业交付的标准。

   Docker三部曲:
1)DockerFile:构建文件,定义了一切的步骤,源代码。
2)DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品。
3)Docker容器:就是镜像运行起来,提供服务。

   DockerFile的常用指令如下图:

在这里插入图片描述
   FROM: 基础镜像,一切从这里开始构建 如:centos
2)MAINTAINER: 镜像是谁写的,留姓名和邮箱
3)RUN: Docker镜像构建的时候需要执行的命令
4)ADD: 添加内容 如:在centos的基础上添加上tomcat的压缩包
5)WORKDIR: 镜像的工作目录
6)VOLUME: 指定挂载的位置
7)EXPOSE: 暴露端口, 不指定的话需要运行时通过 -p 指定
8)CMD: 指定容器运行时执行的命令
9)ENTRYPOINT: 和CMD类似,区别在于,CMD时替换命令,而ENTRYPOINT是追加命令。
(如:CMD命令为ls -a,在执行的时候使用docker run -l 就会把ls -a替换为-l,命令就不成立了。而使用ENTRYPOINT的话就会在后面追加,变成 ls -a -l)
10)ONBUILD: 是一个特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。
11)COPY: 类似ADD,用于将文件拷贝到镜像中。
12)ENV:构建的时候设置环境变量。

   官网的CentOS7的DockerFile如下:

在这里插入图片描述
   实战测试:创建一个自己的CentOS: 官方的镜像很多命令没有,如vim ifconfig等,我们在原有CentOS基础上添加这些命令

1)创建名称为:mydockerfile-centos 的文件,内容如下:

FROM centos
MAINTAINER qizai<xxx@xx.com>

ENV MYPATH /usr/local    #键值对的形式,即设置MYPATH为/usr/local
WORKDIR  $MYPATH     #工作目录就设置为我们的MYPATH,$是取地址符

RUN yum -y install vim    #安装vim命令
RUN yum -y install net-tools  #安装网络相关的一些命令,如ifconfig等

EXPOSE 80  #启动时默认暴露80端口
CMD echo $MYPATH   #输出MYPATH
CMD echo “--- end ---”  #输出end
CMD /bin/bash        #默认进入的命令行 bash命令

2)构建:docker build -f mydockerfile-centos -t mycentos:0.1 .
(-f表示文件路径,-t 表示target,:0.1表示版本号,最后的点表示当前目录,不要丢掉)

3)docker images 即可看到刚才构建的镜像
4)docker run -it mycentos:0.1 运行我们创建的镜像
–> 执行pwd,发现当前在/usr/local ,也就是第4行,进来后默认在MYPATH目录下。不配置的话默认在根目录 / 下。
–> 另外测试发现vim和ifconfig命令也都可以使用了
–> docker history 镜像id :查看当前镜像的构建步骤,怎么生成的

CMD与ENTRYPOINT指令的差别:

#一个简单的dockerfile,测试CMD指令
FROM centos
CMD [“ls”,-a”]

   这个dockerfile构建好run的时候即执行ls -a,列出工作目录下的所有文件
   如果使用docker run -l 就会报错,因为时直接将参数-l替换了原来的ls -a ,而-l不是个命令,因此就报错。

   将上述dockerfile中的CMD换成ENTRYPOINT ,再运行上述命令,就是在后面追加-l参数,可以正常执行。

实战:Tomcat镜像
1)准备文件:tomcat 和jdk的压缩包(tar.gz)
2)编写dockerfile文件(也可以再写一个readme.txt,不写也行)
命名推荐默认的:Dockerfile,构建的时候就不用使用-f指定dockerfile文件了

FROM centos
MAINTAINER qiyanli<xxx.com>

#拷贝文件
COPY readme.txt  /usr/local/readme.txt

#添加压缩包,ADD命令添加进去,会自动解压
ADD jdkxxx.tag.gz  /usr/local
ADD tomcat.xxx.tar.gz  /usr/local

#安装vim命令
RUN yum -y install vim

#配置环境变量和工作目录
ENV  MYPATH /usr/local
WORKDIR  $MYPATH

#配置JDK的环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH  $JAVA_HOME/lib/dt.jar;$JAVA_HOME/lib/tools.jar

#配置tomcat的环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVAPATH/bin;$CATALINA_HOME/bin;$CATALINA_HOME/lib

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -f /usr/local/apache-tomcat-9.0.22/logs/catalina.out

3)构建镜像:docker build diytomcat . (后面的点不要丢掉,表示当前目录)
4)启动:docker run -d -p 9090:8080 --name qyltomcat -v /home/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test -v /home/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.22/logs diytomcat

(之后在/home/tomcat/test目录下的项目,就会自动使用tomcat发布)

5)进到容器内部:docker exec -it 容器id /bin/bash

测试:localhost:9090 可以访问成功
同理外网,使用ip:9090 也可以访问成功

6)发布web项目:发布到/home/tomcat/test目录下

5. Docker网络

1)查看本机网卡:ip addr

  • lo : 本机回环地址
  • eth0:阿里云内网地址
  • docker0:docker地址

在这里插入图片描述
2)docker是如何处理容器的网络访问的:

  • 启动tomcat:docker run -d -P --name tomcat01 tomcat
  • 查看docker容器的网卡:docker exec -it tomcat01 ip addr
    (不进到容器,直接查看网卡,追加命令。相当于命令的精简)
    在这里插入图片描述
    eth0@if262 是分配给容器的网卡地址。
    直接在宿主机上ping 容器的ip : ping 172.18.0.2 发现可以ping通

3)原理:

  • 每启动一个docker容器,就会给容器分配一个ip。容器和宿主机之间桥接模式,使用的技术是evth-pair技术

  • 此时,再在宿主机上指定ip addr, 发现多了一个网卡262 ,后面的veth96781f@if261,意为恰好和docker容器中的261是一对绑定关系。
    在这里插入图片描述
       evth-pair就是一对虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连。

  • 再启动一个tomcat02容器,又产生一对网卡263 @ 264

  • 在tomcat02上ping tomcat01: docker exec -it tomcat02 ping 172.18.0.2
    发现可以ping通。

  • tomcat01和tomcat02是怎么ping通的呢,网络模型如下:
    在这里插入图片描述   结论:tomcat01和tomcat02共用一个路由器docker0。所有容器在不指定网络的情况下,都是通过docker0路由的,docker会给每个容器分配一个默认的可用ip。

   网络类型:A类 ,B类,C类
   255.255.0.0/16 255*255 - 1(回环地址) -1(广播地址)= 65535

   Docker中所有的网络接口都是虚拟的,传输效率高。容器删除,对应的一对网桥就消失了。

   Docker每次启动会重新分配ip,数据库的ip就会变,服务就连不上数据库了。

  • 如何不用ip,使用服务名来连接
  • --link ,但是已经过时不推荐了
#启动2个tomcat,在一个上ping另一个
docker exec -it tomcat02 ping tomcat01
==>发现ping不通

#使用--link命令再启动一个tomcat
docker run  -d -P --nsme tomcat03 --link tomcat02 tomcat
#使用tomcat03 ping tomcat02
docker exec -it tomcat03  ping tomcat02
==>可以ping通
#使用tomcat02 ping tomcat03
docker exec -it tomcat02  ping tomcat03
==>发现ping不通
#docker network --help  列出网络相关的命令帮助信息

#查看tomcat03的host配置:
docker exec -it tomcat03 cat /etc/hosts
==>发现有一条:127.18.0.3  tomcat02  51345236462343
--link相当于再本地绑定了host,请求tomcat02就会直接转发到127.18.0.3

#给tomcat02绑定上tomcat03才能使用服务名ping通tomcat03

   目前已不建议使用–link,弃用docker0,改用自定义网络,避开docker0不支持容器名来凝结访问的限制。

4)Docker自定义网络:

#查看所有的docker网络
docker network ls

#docker 网络模式
bridge :桥接模式 docker默认的网络模式,自定义网络也使用桥接模式
none:不配置网络
host:和宿主机共享网络
container:容器网络联通,用的比较少,局限性较大

#直接启动的,有一个默认的 --net bridge
docker run -d -P --name tomcat01 tomcat
等价于:docker run -d -P --name tomcat01 --net bridge tomcat
#默认使用docker0,但域名不能访问,需通过--link打通,已不建议使用

#自定义网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
--> driver 采用桥接模式,不加默认也是这个
-->subnet 子网掩码,16位可容纳65535个ip
-->gateway 网关,相当于路由器的地址,从192.168.0.1出去
-->名称为mynet

#查看mynet配置
docker network inspect mynet
 
#使用mynet启动2个tomcat
docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat

#测试是否可以ping通
docker exec -it tomcat-net-01 ping 192.168.0.3
docker exec -it tomcat-net-01 ping tomcat-net-02
-->发现不使用--link,直接可以通过ip和服务名都能ping通

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

   好处:不同的集群使用不同的网络,保证集群安全和健康。

   不同的网络之间也是可以打通的。

5)网络连通:
   docker0网络下有2个tomcat容器,mynet网络下有2个tomcat容器,docker0下的容器时ping不通mynet下的容器的。

#查看docker network 帮助命令
docker network --help

#使用connect参数将一个容器连接到另一个网络
#查看使用方法:docker network connect --help 

#打通docker0下的tomcat01和mynet网络连通
dcoker network connect mynet tomcat01
#此时再使用docker network inspect mynet 发现连通后时直接把tomcat01添加到mynet网络下了。
#也就是一个容器,2个ip地址
#再测试发现tomcat01和tomcat-net-01可以ping通了

6. 微服务打包成Docker镜像

   SpringBoot 微服务打包成Docker镜像:
1)编写SpringBoot程序
2)打成jar包
3)安装Docker插件,编写Dockerfile

FROM java:8

COPY *.jar  /app.jar

CMD [--server.port=8080]

EXPOSE 8080

ENTRYPORT [“java”,-jar”,/app.jar”]

4)把jar包和Dockerfile上传到服务器。
5)doker build -t qizai666 生成qizai666镜像
6)docker run -d -P --name test qizai666
7)docker ps 查看容器,可知道端口为32779
8)访问:localhost:32779/hello 发现可以正常访问

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值