Docker 入门笔记

2023-11-18

【狂神说Java】Docker最新超详细版教程通俗易懂
视频地址:https://www.bilibili.com/video/BV1og4y1q7M4?share_source=copy_web

Docker安装

基本组成

在这里插入图片描述
说明:

  • 镜像(image):

    docker镜像好比一个模板,可以通过这个模板来创建容器服务,tomcat镜像 ==> run ==> tomcat01容器(提供服务器),通过这个镜像可以创建多个容器,最终服务运行或者项目运行就是在容器中的。

  • 容器(container):

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

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

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

  • 仓库(repository):

    仓库就是存放镜像的地方。仓库分为公有仓库和私有仓库,Docker Hub(默认是国外的)

安装Docker

环境查看

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

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

安装

  1. 卸载旧的版本

    yum remove docker \
               docker-client \
               docker-client-latest \
               docker-common \
               docker-latest \
               docker-latest-logrotate \
               docker-logrotate \
               docker-engine
    
  2. 需要的安装包

    yum install -y yum-utils
    
  3. 设置镜像的仓库

    yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo				#默认是国外的
        				
    yum-config-manager \
    	--add-repo \
    	http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo		#推荐使用阿里云
    
  4. 更新yum软件包索引

    yum makecache fast
    
  5. 安装docker docker-ce 社区 docker-ee 企业

    yum install docker-ce docker-ce-cli containerd.io
    
  6. 启动docker

    [root@localhost /]# systemctl start docker				# 启动
    [root@localhost /]# docker version						# 查看
    Client: Docker Engine - Community
     Version:           20.10.11
     API version:       1.41
     Go version:        go1.16.9
     Git commit:        dea9396
     Built:             Thu Nov 18 00:38:53 2021
     OS/Arch:           linux/amd64
     Context:           default
     Experimental:      true
    
    Server: Docker Engine - Community
     Engine:
      Version:          20.10.11
      API version:      1.41 (minimum version 1.12)
      Go version:       go1.16.9
      Git commit:       847da18
      Built:            Thu Nov 18 00:37:17 2021
      OS/Arch:          linux/amd64
      Experimental:     false
     containerd:
      Version:          1.4.12
      GitCommit:        7b11cfaabd73bb80907dd23182b9347b4245eb5d
     runc:
      Version:          1.0.2
      GitCommit:        v1.0.2-0-g52b36a2
     docker-init:
      Version:          0.19.0
      GitCommit:        de40ad0  
    
  7. hello-world

    [root@localhost /]# docker run hello-world
    
    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/
    
  8. 查看镜像

    [root@localhost /]# docker images
    REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
    hello-world   latest    feb5d9fea6a5   2 months ago   13.3kB
    
  9. 卸载docker

    # 卸载依赖
    [root@localhost /]# yum remove docker-ce docker-ce-cli containerd.io
    
    # 删除资源
    [root@localhost /]# rm -rf /var/lib/docker
    [root@localhost /]# rm -rf /var/lib/containerd
    

配置阿里云镜像加速

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

Hello World

run 的流程和docker原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2dQdS54U-1638897089295)(E:\应用缓存\Typora图片\Hello Docker\image-20211128210450649.png)]

Docker常用命令

基础命令

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

帮助文档地址:https://docs.docker.com/engine/reference/commandline/

镜像命令

  1. docker image :查看所有本机上的镜像

    [root@localhost /]# docker images
    REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
    hello-world   latest    feb5d9fea6a5   2 months ago   13.3kB
    
    # 解释
    REPOSITORY		镜像的仓库源
    TAG				镜像的标签
    IMAGE ID		镜像的ID
    CREATED			镜像的创建时间
    SIZE			镜像的大小
    
    # 可选项
    Options:
      -a, --all             # 列出所有的镜像
      -q, --quiet           # 只显示镜像的ID
      
    
  2. docker search :搜索镜像

    [root@localhost /]# docker search mysql
    NAME            DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    mysql           MySQL is a widely used, open-source relation…   11741     [OK]
    mariadb         MariaDB Server is a high performing open sou…   4476      [OK]
    
    # 可选项
    --filter=STARS=5000		# 过滤STARS大于5000的
    [root@localhost /]# docker search mysql --filter=STARS=5000
    NAME      		DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    mysql     		MySQL is a widely used, open-source relation…   11741     [OK]
    
  3. docker pull :下载镜像,docker pull imageName [:tag]

    [root@localhost /]# docker pull mysql	# 不写tag,默认就是 latest
    Using default tag: latest
    latest: Pulling from library/mysql
    a10c77af2613: Pull complete				# 分层下载,docker image的核心(联合文件系统)
    b76a7eb51ffd: Pull complete
    258223f927e4: Pull complete
    2d2c75386df9: Pull complete
    63e92e4046c9: Pull complete
    f5845c731544: Pull complete
    bd0401123a9b: Pull complete
    3ef07ec35f1a: Pull complete
    c93a31315089: Pull complete
    3349ed800d44: Pull complete
    6d01857ca4c1: Pull complete
    4cc13890eda8: Pull complete	
    Digest: sha256:aeecae58035f3868bf4f00e5fc623630d8b438db9d05f4d8c6538deb14d4c31b	# 签名
    Status: Downloaded newer image for mysql:latest
    docker.io/library/mysql:latest			# 真实地址
    
    # 等价
    docker pull mysql
    docker pull docker.io/library/mysql:latest
    
    # 指定版本下载
    [root@localhost ~]# docker pull mysql:5.7
    5.7: Pulling from library/mysql
    a10c77af2613: Already exists			# 已经存在的不再下载
    b76a7eb51ffd: Already exists
    258223f927e4: Already exists
    2d2c75386df9: Already exists
    63e92e4046c9: Already exists
    f5845c731544: Already exists
    bd0401123a9b: Already exists
    2724b2da64fd: Pull complete
    d10a7e9e325c: Pull complete
    1c5fd9c3683d: Pull complete
    2e35f83a12e9: Pull complete
    Digest: sha256:7a3a7b7a29e6fbff433c339fc52245435fa2c308586481f2f92ab1df239d6a29
    Status: Downloaded newer image for mysql:5.7
    docker.io/library/mysql:5.7
    
    # 查看镜像
    [root@localhost ~]# docker images
    REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
    mysql         5.7       8b43c6af2ad0   11 days ago    448MB
    mysql         latest    b05128b000dd   11 days ago    516MB
    hello-world   latest    feb5d9fea6a5   2 months ago   13.3kB
    
  4. docker rmi :删除镜像

    [root@localhost ~]# docker rmi 8b43c6af2ad0
    Untagged: mysql:5.7
    Untagged: mysql@sha256:7a3a7b7a29e6fbff433c339fc52245435fa2c308586481f2f92ab1df239d6a29	# 只删除了5.7
    Deleted: sha256:8b43c6af2ad08d95cdcb415d245446909a6cbc1875604c48c4325972e5b00442
    Deleted: sha256:aad43f4d2f66438acd2d156216cd544a728851238714975c38d9a690f68afc57
    Deleted: sha256:7b9addbc002c1e828aee7ec5c2679b04a591b6fa2b96002701ddee9d4ed54395
    Deleted: sha256:b00f8e4e6ce8920fb563615503f232799ab380b338c3f2cbb5e86a2d762a6e80
    Deleted: sha256:8fbabb17fd7b46a59cc15301741bf73a527b862f59cc6e84fae15b4dd5c425c0
    [root@localhost ~]# docker images
    REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
    mysql         latest    b05128b000dd   11 days ago    516MB
    hello-world   latest    feb5d9fea6a5   2 months ago   13.3kB
    
    # 删除多个镜像
    docker rmi b05128b000dd b05128b000dd
    # 删除所有镜像
    docker rmi $(docker images -aq)
    

容器命令

有了镜像才可以创建容器,下载一个 centOS 镜像用来测试,即使用docker运行一个linux

  1. 下载centOS镜像

    [root@localhost /]# docker pull centos
    Using default tag: latest
    latest: Pulling from library/centos
    a1d0c7532777: Pull complete 
    Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
    Status: Downloaded newer image for centos:latest
    docker.io/library/centos:latest
    
    
  2. 新建运行容器

    docker run [可选参数] image
    
    # 参数说明
    --name="Name"		容器名字 tomcat01、tomcat02,用来区分容器
    -d					后台方式运行
    -i					以交互模式运行容器,通常与 -t 同时使用
    -t					为容器重新分配一个伪输入终端,通常与 -i 同时使用
    -p					指定端口映射,格式为:主机(宿主)端口:容器端口
    -P	 				随机端口映射,容器内部端口随机映射到主机的端口
    
  3. 启动并进入容器,注意@后的主机,容器内的centos是基础版本,很多命令都是不完善的

    [root@localhost /]# docker run -it centos /bin/bash
    [root@858435a0ad2c /]# ls
    bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    [root@858435a0ad2c /]# 
    
    
  4. 从容器退出

    # 停止容器并退出
    [root@858435a0ad2c /]# exit
    exit
    [root@localhost /]# ls
    bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    [root@localhost /]# 
    
    # 不停止容器退出 Ctrl+P+Q  
    [root@8aeea0ae4018 /]# [root@localhost /]# 
    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
    8aeea0ae4018   centos    "/bin/bash"   5 minutes ago   Up 5 minutes             optimistic_brown
    
    # 再进入
    [root@localhost /]# docker exec -it 8aeea0ae4018 /bin/bash
    [root@8aeea0ae4018 /]# 
    
  5. 列出运行的容器

    # docker ps
    		# 列出当前正在运行的容器
    -a  	# 列出当前正在运行的容器+带出历史运行过的容器
    -n=?	# 列出最近创建的n个容器
    -q  	# 静默模式,只显示容器编号
    
    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    [root@localhost /]# docker ps -a
    CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
    858435a0ad2c   centos    "/bin/bash"   5 minutes ago   Exited (0) 4 minutes ago             compassionate_burnell
    
    
  6. 删除容器

    # docker rm
    docker rm 容器ID						# 删除指定的容器,不能删除正在运行的容器,可强制删除:rm -f
    docker rm -f $(docker ps -aq)	 	 # 删除所有的容器
    docker ps -a -q | xargs docker rm	 # 删除所有的容器?
    
    [root@localhost /]# docker rm 858435a0ad2c		
    858435a0ad2c
    
    
  7. 启动停止容器

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

其他常用命令

  1. 后台启动容器

    # docker run -d 镜像名
    [root@localhost /]# docker run -d centos
    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    
    # 问题:docker ps 发现 centos 停止了
    
    # 常见的坑:docker 容器使用后台运行,就必须要有一个前台进程,如 docker run -it centos /bin/bash
    #		  docker发现容器没有提供服务,就会自动停止
    
    
  2. 查看日志

    # 执行 docker logs -f -t --tail 容器ID,发现没有打印日志
    # 自定义一个shell脚本,在centos容器里执行
    [root@localhost /]# docker run -d centos /bin/sh -c "while true;do echo helloWorld;sleep 1;done"
    
    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  ......
    288bdccc178b   centos    "/bin/sh -c 'while t…"   ......
    
    # 显示日志
    # -f : 跟踪日志输出
    # -t : 显示时间戳
    # --tail num :仅列出最新N条容器日志
    [root@localhost /]# docker logs -tf --tail 10 288bdccc178b
    
    
  3. 查看容器中进程信息 ps

    # top命令
    [root@localhost /]# docker top 288bdccc178b
    UID    PID   PPID    C  STIME   TTY  TIME       CMD
    root   67615  67595  0  22:37    ?   00:00:00   /bin/sh -c while true;do echo helloWorld;sleep 1;done
    
  4. 查看容器/镜像元数据

    # docker inspect 容器ID
    
    [root@localhost /]# docker inspect 288bdccc178b
    [
        {
            "Id": "288bdccc178bbaf7f1adaa31dd017cc1bf49809fd2b55cc7bef3a930adfcfe97", # 容器ID(完整ID)
            "Created": "2021-11-30T14:37:43.870138648Z",
            "Path": "/bin/sh",
            "Args": [
                "-c",
                "while true;do echo helloWorld;sleep 1;done"						  # 执行的脚本
            ],
            
            ... ...
            
        }
    ]
    
    
  5. 进入当前正在运行的容器

    # 通常使用后台方式运行,需要进入容器
    # 方式一
    # 命令:docker exec -it 容器ID bashShell
    # 测试
    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  ......
    288bdccc178b   centos    "/bin/sh -c 'while t…"   ......          
    [root@localhost /]# docker exec -it 288bdccc178b /bin/bash
    [root@288bdccc178b /]# ps -ef
    UID         PID   PPID   ...	CMD
    root          1      0   ...	/bin/sh -c while true;do echo helloWorld;sleep 1;done
    root       1573      0   ...	/bin/bash
    root       1598      1   ...	/usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
    root       1599   1573   ...    ps -ef
    [root@288bdccc178b /]#
    
    # 方式二
    # docker attach 容器ID
    # 测试
    [root@localhost /]# docker attach 288bdccc178b
    helloWorld
    helloWorld
    helloWorld
    helloWorld
    # 停不了,关闭当前终端,重新打开一个终端
    [root@localhost /]# docker rm -f $(docker ps -qa)
    288bdccc178b
    eb429d6b97e8
    
    
    # docker exec		# 进入容器后开启一个新的终端(常用)
    # docker attach		# 进入容器正在执行的终端,不会启动新的进程
    
  6. 容器与主机之间的数据拷贝

    # 常用:容器拷贝到主机
    # docker cp 容器ID:容器内路径 目的主机路径
    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE     COMMAND       ......
    28b1861e8c82   centos    "/bin/bash"   ...... 
    
    # 进入docker容器,并新建文件,退出
    [root@localhost /]# docker attach 28b1861e8c82
    [root@28b1861e8c82 /]# cd /home/
    [root@28b1861e8c82 home]# ls
    [root@28b1861e8c82 home]# touch test.java
    [root@28b1861e8c82 home]# ls
    test.java
    [root@28b1861e8c82 home]# exit
    exit
    
    # 容器虽然停止了,但可以将拷贝数据出来
    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    [root@localhost /]# docker ps -a
    CONTAINER ID   IMAGE     COMMAND       ......
    28b1861e8c82   centos    "/bin/bash"   ...... 
    [root@localhost /]# docker cp 28b1861e8c82:/home/test.java /home/crater/Desktop/
    [root@localhost /]# ll
    total 0
    -rw-r--r--. 1 root root 0 Nov 30 23:30 test.java
    [root@localhost /]#
    
    # 拷贝是一个手动过程,以后使用 -v 卷技术,可以实现自动
    

小结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TSrGAnHv-1638897089297)(E:\应用缓存\Typora图片\Hello Docker\image-20211201001358970.png)]

可视化面板

目前先使用 portainer,它是一个图形化管理工具,提供一个后台面板供我们操作,后续 CI/CD 阶段再使用 Rancher

  • 安装

    [root@localhost /]# docker run -d -p 8088:9000 \
    --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
    Unable to find image 'portainer/portainer:latest' locally
    latest: Pulling from portainer/portainer
    94cfa856b2b1: Pull complete 
    49d59ee0881a: Pull complete 
    a2300fd28637: Pull complete 
    Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
    Status: Downloaded newer image for portainer/portainer:latest
    ffbfef16365ba483d173142cd3491ee950bf07ebd19a600a7028f642a0d519bd
    [root@localhost tomcat]# 
    
    
  • 访问,新建一个管理员,选择本地连接,可以看到当前的镜像,容器,卷挂载,网络的情况
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w3WCdWXM-1638897089298)(E:\应用缓存\Typora图片\Hello Docker\image-20211208001800705.png)]
    看看就行,不经常用

实战:Docker 安装 Nginx

  1. 搜索镜像,建议去dockerHub搜索,可以看到帮助文档

    [root@localhost /]# docker search nginx
    NAME                  DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    nginx                 Official build of Nginx.                        15893     [OK]
    jwilder/nginx-proxy   Automated Nginx reverse proxy for docker con…   2098                 [OK]
    ...
    
    
  2. 下载镜像

    [root@localhost /]# docker pull nginx
    Using default tag: latest
    latest: Pulling from library/nginx
    eff15d958d66: Pull complete
    1e5351450a59: Pull complete
    2df63e6ce2be: Pull complete
    9171c7ae368c: Pull complete
    020f975acd28: Pull complete
    266f639b35ad: Pull complete
    Digest: sha256:097c3a0913d7e3a5b01b6c685a60c03632fc7a2b50bc8e35bcaa3691d788226e
    Status: Downloaded newer image for nginx:latest
    docker.io/library/nginx:latest
    [root@localhost /]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
    nginx        latest    ea335eea17ab   13 days ago    141MB
    centos       latest    5d0da3dc9764   2 months ago   231MB
    
    
  3. 启动 nginx 容器

    [root@localhost /]# docker run -d --name nginx01 -p 18080:80 nginx
    WARNING: IPv4 forwarding is disabled. Networking will not work.
    2d8ac4924b7360618e620db920ce387a26bc9f928c563080f25060d3dae480a4
    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE  COMMAND                 ...   PORTS                                     NAMES
    2d8ac4924b73   nginx  "/docker-entrypoint.…"  ...   0.0.0.0:18080->80/tcp, :::18080->80/tcp   nginx01
    [root@localhost /]#
    
    
  4. 测试

    # docker run -d --name nginx01 -p 3334:80 nginx
    # -d 后台运行
    # --name 给容器命名
    # -p 3334:80 将宿主机的端口18080映射到该容器的80端口
    
    [root@localhost /]# curl localhost:18080
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    
    
  5. 进入容器

    [root@localhost /]# docker exec -it nginx01 /bin/bash
    root@2d8ac4924b73:/# whereis nginx
    nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
    root@2d8ac4924b73:/# cd /etc/nginx/
    root@2d8ac4924b73:/etc/nginx# 
    
    
  6. 端口暴露
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fgO8hSfb-1638897089299)(E:\应用缓存\Typora图片\Hello Docker\image-20211201205851816.png)]

实战:Docker 安装 Tomcat

  1. 直接运行(run),不需要下载(pull),docker会直接下载

    # 官方的教程
    # 之前的启动都是后台,停止后容器还是存在,--rm 一般用来测试,用完即删
    docker run -it --rm tomcat:9.0
    
    [root@localhost /]# docker run -it --rm tomcat:9.0
    Unable to find image 'tomcat:9.0' locally
    9.0: Pulling from library/tomcat
    5e0b432e8ba9: Pull complete
    a84cfd68b5ce: Pull complete
    e8b8f2315954: Pull complete
    0598fa43a7e7: Pull complete
    e0d35e3be804: Pull complete
    8fc448a0c88b: Pull complete
    dbdff6e5955b: Pull complete
    5daf3771e3d8: Pull complete
    5434ab540d86: Pull complete
    80f43f4b2f61: Pull complete
    Digest: sha256:f80d091e4a086fc1253cdc04011b5cd3c6820e8df5ff3047b0175e105435ba68
    Status: Downloaded newer image for tomcat:9.0
    Using CATALINA_BASE:   /usr/local/tomcat
    Using CATALINA_HOME:   /usr/local/tomcat
    Using CATALINA_TMPDIR: /usr/local/tomcat/temp
    Using JRE_HOME:        /usr/local/openjdk-11
    Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
    Using CATALINA_OPTS:
    NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
    ...
    04-Dec-2021 12:39:26.569 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
    ...
    # Ctrl + c
    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    [root@localhost /]# docker ps -a
    CONTAINER ID   IMAGE     COMMAND                  ...
    2d8ac4924b73   nginx     "/docker-entrypoint.…"   ...
    28b1861e8c82   centos    "/bin/bash"              ...
    [root@localhost /]#
    
    
  2. 不建议–rm,先下载

    [root@localhost /]# docker pull tomcat
    [root@localhost /]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
    tomcat       9.0       041804b6c268   23 hours ago   680MB
    tomcat       latest    49842ef82091   23 hours ago   680MB
    
    
  3. 运行,测试

    [root@localhost /]# docker run -d -p 28080:8080 --name tomcat01 tomcat
    
    # 测试访问 404
    # http://虚拟机ip:18080/
    
  4. 进入容器:

    # 1.Linux命令阉割 
    # 2.没有webapps,下载的阿里镜像默认是最小镜像,所有不必要的都剔除了,保证最小可运行的环境
    [root@localhost /]# docker exec -it tomcat01 /bin/bash
    root@107a5f9810e2:/usr/local/tomcat# cd webapps
    root@107a5f9810e2:/usr/local/tomcat/webapps# ls -la
    total 0
    
    # 页面文件都在webapps.dist目录下
    root@107a5f9810e2:/usr/local/tomcat/webapps# cd ..
    root@107a5f9810e2:/usr/local/tomcat# cd webapps.dist
    root@107a5f9810e2:/usr/local/tomcat/webapps.dist# ls -al
    total 4
    drwxr-xr-x.  7 root root   81 Nov  9 22:12 .
    drwxr-xr-x.  1 root root   30 Dec  3 14:18 ..
    drwxr-xr-x.  3 root root  223 Dec  3 14:17 ROOT
    drwxr-xr-x. 15 root root 4096 Dec  3 14:17 docs
    drwxr-xr-x.  7 root root   99 Dec  3 14:17 examples
    drwxr-xr-x.  6 root root   79 Dec  3 14:17 host-manager
    drwxr-xr-x.  6 root root  114 Dec  3 14:17 manager
    
    # 拷贝到webapps下 -r:递归
    root@107a5f9810e2:/usr/local/tomcat/webapps.dist# cd ..
    root@107a5f9810e2:/usr/local/tomcat# cp -r webapps.dist/* webapps/
    root@107a5f9810e2:/usr/local/tomcat# cd webapps
    root@107a5f9810e2:/usr/local/tomcat/webapps# ls -al
    total 4
    drwxr-xr-x.  1 root root   81 Dec  4 14:13 .
    drwxr-xr-x.  1 root root   57 Dec  3 14:18 ..
    drwxr-xr-x.  3 root root  223 Dec  4 14:13 ROOT
    drwxr-xr-x. 15 root root 4096 Dec  4 14:13 docs
    drwxr-xr-x.  7 root root   99 Dec  4 14:13 examples
    drwxr-xr-x.  6 root root   79 Dec  4 14:13 host-manager
    drwxr-xr-x.  6 root root  114 Dec  4 14:13 manager
    
    # 再次访问,加载出Tomcat页面
    

Docker镜像

镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码、运行时、库、环境变量和配置文件。

Docker镜像加载原理

UnionFS(联合文件系统)

Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同的目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

Docker镜像加载原理

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

bootfs(boot file system)主要包含 bootloader 和 kernel,bootloader 主要是引导加载 kernel,Linux刚启动时会加载 bootfs 文件系统,在 Docker 镜像的最底层是 bootfs。这一层与我们典型的 Linxu/Unix 系统是一样的,包含 boot 加载器和内核。当 boot 加载完成之后整个内核都在内存中了,此时内存的使用权由 bootfs 转交给内核,此时系统也会卸载 bootfs。

rootfs(root file system),在 bootfs 之上。包含的就是典型 Linxu 系统中的 /dev, /proc, /etc 等标准目录和文件。rootfs 就是各种不同操作系统发行版,比如Ubuntu,CentOS 等等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vSXY16c7-1638897089300)(E:\应用缓存\Typora图片\Hello Docker\image-20211204162318705.png)]
平时我们安装进虚拟机的CentOS都有好几个G,为什么Docker里才200M?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WogMhCAP-1638897089301)(E:\应用缓存\Typora图片\Hello Docker\image-20211204163233775.png)]
对于一个精简的OS,rootfs 可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用Host的Hernel,自己只需要提供 rootfs 就可以了。由此可见对于不同的 Linux 发行版,bootfs 基本是一致的,rootfs 会有差别,因此不同的发现版本可以公用 bootfs。

分层理解

分层的镜像

下载镜像的时候,从日志输出可以看出来,是一层一层下载
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5LueTuav-1638897089302)(E:\应用缓存\Typora图片\Hello Docker\image-20211204164811639.png)]
采用分层的结构,最大的好处是资源共享。比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需要在磁盘上保存一份Base镜像,同时内存中也只需要加载一份Base镜像,这样就可以为所有的容器服务,而且镜像的每一层都可以被共享。

查看镜像分层的方式可以通过 docker image inspect

[root@localhost /]# docker image inspect redis:latest
[
    {
        ... ...
        
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:9321ff862abbe8e1532076e5fdc932371eff562334ac86984a836d77dfb717f5",
                "sha256:aa2858ea5edc9c0981901a1b63b49a8f4a6e7099b4304b49e680ffdcc6b71b3e",
                "sha256:93079bf13a6d5fe7c4bd9f00cb96183f9d1db9968c4bd15b395df2f3867bf8e5",
                "sha256:9ca504b88e256aa6f6c04ec65aeeed6b926661ea30a0b97f829fbe230155241a",
                "sha256:9468a3f0498bd5cc298ce25ea6ce9c6adf14aa2ce152856b5f389510a9bb9e01",
                "sha256:b7851a62867d82784052d7662862adc0b47b2bddcddc89ae78307f75ba1b29ae"
            ]
        },
        
        ... ...
    }
]

理解:

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

比如基于Ubuntu 16.04 创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python 包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。

该镜像当前已经包含3个镜像层,如下图所示:
在这里插入图片描述
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
在这里插入图片描述
上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。

下图中展示了一个稍微复杂的三层镜像,在外部看起来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mOBhtjT7-1638897089305)(E:\应用缓存\Typora图片\Hello Docker\image-20211204173207378.png)]
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新的镜像层添加到镜像中。

Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像对外展示为统一的文件系统。

Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独特的特点。

Dcoker在 Windows 上仅支持 windowsfilter 一种存储引擎,改引擎基于 NTFS 文件系统之上实现了分层和CoW

下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r73g17cu-1638897089306)(E:\应用缓存\Typora图片\Hello Docker\image-20211204173540958.png)]

特点

Docker 镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。

这一层就是容器层,容器层之下都叫镜像层。

commit镜像

  • commit 命令

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

    # 1.官方默认的的Tomcat没有webapps应用
    
    # 2.将webapps.dist目录下的文件拷贝到webapps再访问,得到一个可以带有页面的tomcat
    
    # 3.使用commit命令将容器提交为一个镜像,之后就可以使用这给修改过的镜像 
    [root@localhost /]# docker commit -m "带页面的Tomcat" -a "Crater" 107a5f9810e2 tomcat_custom:1.0
    sha256:75fd976c5666188c46de812a0a1758adfc701e45dca27cfed80a3a08685351a9
    [root@localhost /]# docker images
    REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
    tomcat_custom   1.0       75fd976c5666   11 seconds ago   684MB
    tomcat          9.0       041804b6c268   25 hours ago     680MB
    tomcat          latest    49842ef82091   25 hours ago     680MB
    
    

容器数据卷

简介

Docker 将应用与运行的环境打包成容器运行,如果不使用docker commit命令生成新的镜像,那么在容器删除后,Dcoker 容器产生的数据也会被删除,为了可以保存数据,就要在 Dcoker 使用中使用数据卷,将容器内的目录,挂载到宿主 Linux 上。

卷就是目录或文件,存在于一个或多个容器中,由Docker挂载到容器,但卷不属于联合文件系统(Union FileSystem),因此能够绕过联合文件系统提供一些用于持续存储或共享数据的特性。

数据卷的特点:

  1. 数据卷可在容器之间共享或重用数据
  2. 卷中的更改可以直接生效
  3. 数据卷中的更改不会包含在镜像的更新中
  4. 数据卷的生命周期一直持续到没有容器使用它为止

数据卷的使用(-v)

直接使用命令挂载 -v

# docker run -it -v 主机目录:容器内目录

# 宿主Linux的home目录下只有陨石坑的用户目录
[root@localhost /]# cd /home
[root@localhost home]# ls
crater

# 启动一个centos容器,将容器的home目录挂载到宿主机的/home/test目录
[root@localhost home]# docker run -it -v /home/test:/home centos /bin/bash
[root@3222248f1b85 /]#

# 打开新的会话,看到宿主机上有了test目录
[root@localhost /]# cd /home
[root@localhost home]# ls
crater  test
[root@localhost home]#

# 查看容器元数据
[root@localhost home]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
3222248f1b85   centos    "/bin/bash"   15 minutes ago   Up 15 minutes             condescending_noether
[root@localhost home]# docker inspect 3222248f1b85
[
    {
        ... ...
        "Mounts": [		# 挂载
            {
                "Type": "bind",
                "Source": "/home/test",		# 宿主机目录
                "Destination": "/home",		# docker容器内目录
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
      	... ...
    }
]

# 在容器内的home目录下新建文件
[root@3222248f1b85 /]# cd /home
[root@3222248f1b85 home]# touch test.java
[root@3222248f1b85 home]# ls
test.java

# 在宿主机home/test目录下查看
[root@localhost home]# cd test
[root@localhost test]# ls
test.java

# 停止容器(没有客户端使用,退出就停止了)
[root@3222248f1b85 home]# exit
exit
[root@localhost home]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

# 在宿主机上修改文件,
[root@localhost test]# vim test.java
hello, linux update
~
~

# 再将容器启动并进入,查看修改
[root@localhost home]# docker ps -a
CONTAINER ID   IMAGE     COMMAND           ...
3222248f1b85   centos    "/bin/bash"       ...              
[root@localhost home]# docker start 3222248f1b85
3222248f1b85
[root@localhost home]# docker attach 3222248f1b85
[root@3222248f1b85 /]# cd /home
[root@3222248f1b85 home]# cat test.java
hello, linux update
[root@3222248f1b85 home]#

# 以上可以理解为双向绑定

实战:Docker 安装 MySQL(数据卷)

  1. 搜索并下载镜像

    [root@localhost /]# docker search mysql
    NAME                DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    mysql               MySQL is a widely used, open-source relation…   11784     [OK]
    ...
    [root@localhost /]# docker pull mysql:5.7
    ...
    [root@localhost home]# docker images
    REPOSITORY      TAG       IMAGE ID       CREATED        SIZE
    mysql           5.7       738e7101490b   2 days ago     448MB
    
    
  2. 在Linux下的MySQL默认的数据文档存储目录为/var/lib/mysql,默认的配置文件的位置/etc/mysql/conf.d,为了确保MySQL镜像或容器删除后,造成的数据丢失,下面建立数据卷保存MySQL的数据和文件。

    # 安装启动mysql需要设置密码 -e MYSQL_ROOT_PASSWORD
    [root@localhost /]# docker run -d \
    						-p 13306: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
    4a6cf19d4702f0b1c6e3a3ffd0c5eda1d0b66e6014efe23bfce07ad6764ce025
    [root@localhost /]#
    
    
  3. 用宿主机MySQL客户端连接测试

    # 连接测试
    [root@localhost /]# mysql -h 127.0.0.1 -P 13306 -u root -p
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 8
    Server version: 5.7.36 MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql>
    
    # 数据也同步到宿主机
    [root@localhost /]# cd /home/
    [root@localhost home]# ls
    crater  mysql  test
    
    # 之后及时将容器停止删除,挂载到宿主机的数据卷也不会丢失
    
    

具名挂载/匿名挂载

  • 匿名挂载

    匿名挂载就是在指定数据卷的时候,不指定容器路径对应的主机路径,这样对应映射的主机路径就是默认的路径/var/lib/docker/volumes/中自动生成一个随机命名的文件夹。

  • 运行并匿名挂载Nginx容器

    # -v只写了容器内的路径
    # -P: 随机端口映射
    [root@localhost /]# docker run -d -P --name nginx01 -v /etc/nginx nginx
    94b2dff070383e6d7c47e9423f4e795174cd81ec5984aca960867e3ede6677ba
    [root@localhost /]# docker volume ls
    DRIVER    VOLUME NAME
    local     078d4922722ca14400b3bbb3b0f2e3a63ff1c4f9ffc506b56e3cbb656beeffa1
    
    
  • 具名挂载

    具名挂载,就是指定文件夹名称,区别于指定路径挂载,这里的指定文件夹名称是在Docker指定的默认数据卷路径下的。通过docker volume ls命令可以查看当前数据卷的目录情况。

    [root@localhost /]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
    a1308fc3305f2dadb41eb03325ae41336623c07cb09c50030f41e8dc507aa2f1
    [root@localhost home]# docker volume ls
    DRIVER    VOLUME NAME
    local     078d4922722ca14400b3bbb3b0f2e3a63ff1c4f9ffc506b56e3cbb656beeffa1
    local     juming-nginx
    
    # 查看指定的数据卷信息
    # 命令:docker volume inspect 数据卷名称
    [root@localhost /]# docker volume inspect juming-nginx
    [
        {
            "CreatedAt": "2021-12-05T11:47:17+08:00",
            "Driver": "local",
            "Labels": null,
            "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
            "Name": "juming-nginx",
            "Options": null,
            "Scope": "local"
        }
    ]
    
    
    
  • 所有的docker容器的卷,没有指定目录时,都在/var/lib/docker/volumes/xxx/_data

    [root@localhost /]# cd /var/lib/docker/
    [root@localhost docker]# ls
    buildkit  containers  image  network  overlay2  plugins  runtimes  swarm  tmp  trust  volumes
    [root@localhost docker]# cd volumes/
    [root@localhost volumes]# ll
    total 24
    drwx-----x. 3 root root     19 Dec  5 11:40 078d4922722ca14400b3bbb3b0f2e3a63ff1c4f9ffc506b56e3cbb656beeffa1
    brw-------. 1 root root 253, 0 Dec  4 20:32 backingFsBlockDev
    drwx-----x. 3 root root     19 Dec  5 11:47 juming-nginx
    -rw-------. 1 root root  32768 Dec  5 11:47 metadata.db
    [root@localhost volumes]# cd juming-nginx/
    [root@localhost juming-nginx]# ls
    _data
    [root@localhost juming-nginx]# cd _data/
    [root@localhost _data]# ls
    conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params
    
    
  • 匿名挂载,具名挂载,指定路径挂载的命令区别如下:

    -v 容器内路径 			   #匿名挂载
    
    -v 卷名:容器内路径 		  #具名挂载
    
    -v /宿主机路径:容器内路径 	#指定路径挂载
    
  • 指定数据卷映射的相关参数:

    # ro —— readonly 只读:设置了只读,只能操作宿主机路径内的内容,不能在容器中操作对应的路径。
    # rw —— readwrite 可读可写
    [root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
    [root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
    
    

数据卷的使用(DockerFile)

初识DockerFile

DockerFile 就是镜像的构建文件,是一个命令脚本。通过脚本可以生成镜像。

  1. 新建脚本

    [root@localhost /]# cd /home
    [root@localhost home]# mkdir docker-test-volume
    [root@localhost home]# ls
    crater  docker-test-volume  mysql  test
    [root@localhost home]# cd docker-test-volume/
    [root@localhost docker-test-volume]# vim dockerfile1
    FROM centos
    
    VOLUME ["volume01","volume02"]
    
    CMD echo "-----end-----"
    CMD /bin/bash
    
  2. 构建镜像

    # -f: 		 指定要使用的Dockerfile路径
    # --tag, -t: 镜像的名字及标签
    # . :		 指定镜像构建过程中的上下文环境的目录,构建的时候,由用户指定构建镜像的上下文路径,而 docker build 会将这个路径下所有的文件都打包上传给 Docker 引擎,引擎内将这些内容展开后,就能获取到所有指定上下文中的文件了。
    [root@localhost docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 \
    												  -t crater/centos:1.0 .
    Sending build context to Docker daemon  2.048kB
    Step 1/4 : FROM centos
     ---> 5d0da3dc9764
    Step 2/4 : VOLUME ["volume01","volume02"]
     ---> Running in fd40a79d5652
    Removing intermediate container fd40a79d5652
     ---> 17e35a858d46
    Step 3/4 : CMD echo "-----end-----"
     ---> Running in 5d7c52c41b8f
    Removing intermediate container 5d7c52c41b8f
     ---> 44f1e6b80345
    Step 4/4 : CMD /bin/bash
     ---> Running in c1d3d217ca44
    Removing intermediate container c1d3d217ca44
     ---> 113c2f9874c1
    Successfully built 113c2f9874c1
    Successfully tagged crater/centos:1.0
    [root@localhost docker-test-volume]# docker images
    REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
    crater/centos   1.0       113c2f9874c1   6 minutes ago   231MB
    
    
  3. 运行测试,启动自己的容器

    [root@localhost docker-test-volume]# docker run -it 113c2f9874c1 /bin/bash
    [root@f753c107fdb6 /]# ls -al
    total 0
    drwxr-xr-x.   1 root root  38 Dec  5 07:03 .
    drwxr-xr-x.   1 root root  38 Dec  5 07:03 ..
    -rwxr-xr-x.   1 root root   0 Dec  5 07:03 .dockerenv
    lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
    drwxr-xr-x.   5 root root 360 Dec  5 07:03 dev
    drwxr-xr-x.   1 root root  66 Dec  5 07:03 etc
    drwxr-xr-x.   2 root root   6 Nov  3  2020 home
    lrwxrwxrwx.   1 root root   7 Nov  3  2020 lib -> usr/lib
    lrwxrwxrwx.   1 root root   9 Nov  3  2020 lib64 -> usr/lib64
    drwx------.   2 root root   6 Sep 15 14:17 lost+found
    drwxr-xr-x.   2 root root   6 Nov  3  2020 media
    drwxr-xr-x.   2 root root   6 Nov  3  2020 mnt
    drwxr-xr-x.   2 root root   6 Nov  3  2020 opt
    dr-xr-xr-x. 235 root root   0 Dec  5 07:03 proc
    dr-xr-x---.   2 root root 162 Sep 15 14:17 root
    drwxr-xr-x.  11 root root 163 Sep 15 14:17 run
    lrwxrwxrwx.   1 root root   8 Nov  3  2020 sbin -> usr/sbin
    drwxr-xr-x.   2 root root   6 Nov  3  2020 srv
    dr-xr-xr-x.  13 root root   0 Dec  4 12:28 sys
    drwxrwxrwt.   7 root root 171 Sep 15 14:17 tmp
    drwxr-xr-x.  12 root root 144 Sep 15 14:17 usr
    drwxr-xr-x.  20 root root 262 Sep 15 14:17 var
    drwxr-xr-x.   2 root root   6 Dec  5 07:03 volume01				# 这就是生成镜像的时候自动挂载的数据卷
    drwxr-xr-x.   2 root root   6 Dec  5 07:03 volume02
    [root@f753c107fdb6 /]#
    
    
  4. 这两个卷在宿主机一定有同步的目录,验证一下

    [root@f753c107fdb6 /]# cd volume01
    [root@f753c107fdb6 volume01]# touch container.txt
    [root@f753c107fdb6 volume01]# ls
    container.txt
    [root@f753c107fdb6 volume01]#
    
    
  5. 打开新的连接,查看容器信息,确认同步成功

    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS         PORTS     NAMES
    f753c107fdb6   113c2f9874c1   "/bin/bash"   3 minutes ago   Up 3 minutes             reverent_easley
    [root@localhost /]# docker inspect f753c107fdb6
    [
        {
            ... ...
            
            "Mounts": [
                {
                    "Type": "volume",
                    "Name": "603bec720317ffdbfb9b8842a0129db0baed044776db6daed05cee03af809ab1",
                    "Source": "/var/lib/docker/volumes/603bec720317ffdbfb9b8842a0129db0baed044776db6daed05cee03af809ab1/_data",
                    "Destination": "volume01",		# 匿名挂载
                    "Driver": "local",				
                    "Mode": "",
                    "RW": true,
                    "Propagation": ""
                },
                {
                    "Type": "volume",
                    "Name": "eef0a8efe168fc047dc55cbffcc7d52d7040ed654a95a30b72a0484a57f6613a",
                    "Source": "/var/lib/docker/volumes/eef0a8efe168fc047dc55cbffcc7d52d7040ed654a95a30b72a0484a57f6613a/_data",
                    "Destination": "volume02",		# 匿名挂载
                    "Driver": "local",
                    "Mode": "",
                    "RW": true,
                    "Propagation": ""
                }
            ],
            
            ... ...
        }
    ]
    [root@localhost /]# cd /var/lib/docker/volumes/603bec720317ffdbfb9b8842a0129db0baed044776db6daed05cee03af809ab1/_data/
    [root@localhost _data]# ls
    container.txt
    
    

这种方式使用很多,因为通常会自己构建镜像,如果构建镜像时没有挂载卷,在启动时就要手动挂载 -v

数据卷容器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v93Wn32j-1638897089307)(E:\应用缓存\Typora图片\Hello Docker\image-20211205152901461.png)]

  1. 启动3个自定义的 centos 容器
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TWtCDkbI-1638897089308)(E:\应用缓存\Typora图片\Hello Docker\image-20211205154402991.png)]

  2. 新的连接运行第2个
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gKfJgSBA-1638897089309)(E:\应用缓存\Typora图片\Hello Docker\image-20211205154305060.png)]

  3. 在 docker01 容器的 volume01 下创建文件,在 docker01 中也可以查询到

    docker01:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qjsJ4rH2-1638897089310)(E:\应用缓存\Typora图片\Hello Docker\image-20211205155038625.png)]
    docker02
    在这里插入图片描述

  4. 再启动一个 docker03,进入容器后就可以看到 docker01 创建的文件
    在这里插入图片描述

  5. 此时在 docker03 中新建文件,在 docker01 中也可以看到
    在这里插入图片描述在这里插入图片描述

  6. 即使停止,删除 docker01,docker02 和 docker03 还是可以访问这个文件,因为它们之间是拷贝的概念 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FBaOIdJl-1638897089314)(E:\应用缓存\Typora图片\Hello Docker\image-20211205160357351.png)]
    例如:

同步两个MySQL的数据库和配置文件,与上面的操作相同,首先建立数据卷,然后给另一个MySQL容器建立容器数据卷挂载。

[root@localhost home]# docker run -d -p 6603: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
[root@localhost home]# docker run -d -p 6604:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

【注】

容器之间配置的信息传递,数据卷容器的生命周期一直持续到没有容器使用为止

如果再持久化到宿主机,宿主机的数据不会被删除

DockerFile

Dockerfile是用来构建Docker镜像的文本文件,也可以说是命令参数脚本。docker build命令用于从Dockerfile构建镜像。可以在docker build命令中使用 -f标志指向文件系统中任何位置的Dockerfile。

Docker镜像发布的步骤:

  1. 编写一个dockerfile文件

  2. docker build 构建成为一个镜像

  3. docker run 镜像

  4. docker push 镜像(发布镜像到DockerHub、阿里云镜像仓库)

在 dockerHub 上,进入 centos 镜像,再进入 gitHub,发现它就是一段命令脚本。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eS9pV7m6-1638897089315)(E:\应用缓存\Typora图片\Hello Docker\image-20211205162658346.png)]

DockerFile构建过程

基础知识

  1. 每个保留关键字(指令)都是大写字母

  2. 执行从上到下顺序执行

  3. #标识注释

  4. 每一个指令都会创建提交一个新的镜像层,并提交
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0xXt7ibg-1638897089315)(E:\应用缓存\Typora图片\Hello Docker\image-20211205163448473.png)]
    dockerFile是面向开发的,通过编写 dockerfile 文件,来交付 docker 镜像,而不再是 jar 包

    DockerFile:构建文件,定义一切步骤,源代码

    DockerImages:通过 DockerFile 构建生成镜像,最终发布和运行

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

DockerFile指令

指令 说明
FROM 指定基础镜像,一切从这里开始构建
MAINTAINER 镜像是谁写的,姓名+邮箱
RUN 镜像构建的时候需要运行的命令
ADD 将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
WORKDIR 镜像的工作目录
VOLUME 挂载的目录
EXPOSE 保留端口配置
CMD 指定这个容器启动的时候要运行的命令(只有最后一个会生效)
EMTRYPOINT 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD 当构建一个被继承DockerFile,这个时候就会运行ONBUILD的指令(触发指令)
COPY 功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
ENV 构建的时候设置环境变量

一个形象的解释各个指令作用的图:
在这里插入图片描述

实战:dockerFile 生成镜像

  1. 新建 dockerFile 文件

    # FROM centos:该image文件继承官方的centos,后面加冒号如centos:7,用于指定镜像的版本
    # ENV MYPATH /usr/local:设置环境变量MYPATH 
    # WORKDIR $MYPATH:直接使用上面设置的环境变量,指定/usr/local为工作目录
    # RUN yum -y install:在/usr/local目录下,安装工具,安装后的依赖和工具都会打包到image文件中
    # EXPOSE 80:将容器80端口暴露出来,允许外部连接这个端口
    # CMD:指定容器启动的时候运行命令
    [root@localhost dockerfile]# pwd
    /home/dockerfile
    [root@localhost dockerfile]# cat mydockerfile-centos
    FROM centos
    MAINTAINER crater<1813059208@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. 执行build命令生成image文件,通过docker images来查看新生成的镜像文件。

    [root@localhost dockerfile]# docker build -f mydockerfile-centos -t mycentos:1.0 .
    Sending build context to Docker daemon  2.048kB
    Step 1/10 : FROM centos
     ---> 5d0da3dc9764
    Step 2/10 : MAINTAINER crater<1813059208@qq.com>
     ---> Running in b97b56f5bae1
    Removing intermediate container b97b56f5bae1
     ---> 23803eb3f0d4
    Step 3/10 : ENV MYPATH /usr/local
     ---> Running in 84d02a3b3439
    Removing intermediate container 84d02a3b3439
     ---> 9cea839951fb
    Step 4/10 : WORKDIR $MYPATH
     ---> Running in 1582d30cca1e
    Removing intermediate container 1582d30cca1e
     ---> 276cadad6988
    Step 5/10 : RUN yum -y install vim
     ---> Running in ef5139ff16d9
    Removing intermediate container ef5139ff16d9
     ---> d1cd7b5281ab
    Step 6/10 : RUN yum -y install net-tools
     ---> Running in 0767db58cf80
    Removing intermediate container 0767db58cf80
     ---> 647bb6ddcdbf
    Step 7/10 : EXPOSE 80
     ---> Running in 4a7e3aedbe42
    Removing intermediate container 4a7e3aedbe42
     ---> 539c29beeaec
    Step 8/10 : CMD echo $MYPATH
     ---> Running in c66571fe9bcf
    Removing intermediate container c66571fe9bcf
     ---> 1079255f9ace
    Step 9/10 : CMD echo "---end---"
     ---> Running in ae26e727b5be
    Removing intermediate container ae26e727b5be
     ---> 1fe21e0f06a8
    Step 10/10 : CMD /bin/bash
     ---> Running in 9463dad1a183
    Removing intermediate container 9463dad1a183
     ---> cc8c205a798d
    Successfully built cc8c205a798d
    Successfully tagged mycentos:1.0
    [root@localhost dockerfile]# docker images
    REPOSITORY      TAG       IMAGE ID       CREATED              SIZE
    mycentos        1.0       cc8c205a798d   About a minute ago   322MB
    ... ...
    
    
  3. 启动容器

    # 启动进入了工作目录/usr/local
    # 安装的两个工具可以执行
    [root@localhost dockerfile]# docker run -it mycentos:1.0
    [root@f6d2491fd0fc local]# pwd
    /usr/local
    [root@f6d2491fd0fc local]# ifconfig
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
            ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
            RX packets 8  bytes 656 (656.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
            inet 127.0.0.1  netmask 255.0.0.0
            loop  txqueuelen 1000  (Local Loopback)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    [root@f6d2491fd0fc local]# vim
    [root@f6d2491fd0fc local]#
    
    
  4. 通过docker history 镜像ID命令来查看镜像的构建步骤

    [root@localhost dockerfile]# docker history cc8c205a798d
    IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
    cc8c205a798d   5 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B
    1fe21e0f06a8   5 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B
    1079255f9ace   5 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B
    539c29beeaec   5 minutes ago   /bin/sh -c #(nop)  EXPOSE 80                    0B
    647bb6ddcdbf   6 minutes ago   /bin/sh -c yum -y install net-tools             27MB
    d1cd7b5281ab   6 minutes ago   /bin/sh -c yum -y install vim                   64MB
    276cadad6988   6 minutes ago   /bin/sh -c #(nop) WORKDIR /usr/local            0B
    9cea839951fb   6 minutes ago   /bin/sh -c #(nop)  ENV MYPATH=/usr/local        0B
    23803eb3f0d4   6 minutes ago   /bin/sh -c #(nop)  MAINTAINER crater<1813059…   0B
    5d0da3dc9764   2 months ago    /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
    <missing>      2 months ago    /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
    <missing>      2 months ago    /bin/sh -c #(nop) ADD file:805cb5e15fb6e0bb0…   231MB
    [root@localhost dockerfile]#
    
    

RUN、CMD、ENTRYPOINT

  • RUN命令与CMD命令的区别

    RUN命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件;CMD命令则是在容器启动后执行。
    一个 Dockerfile 可以包含多个RUN命令,但是只能有一个CMD命令。
    指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash),否则它会覆盖CMD命令。

  • CMD命令和ENTRYPOINT命令的区别

    CMD :指定容器启动的时候要运行的命令,只有最后一个会生效

    ENTRYPOINT :指定容器启动的时候要运行的命令,命令可以追加

测试

  • 测试 CMD 命令

    [root@localhost dockerfile]# cat dockerfile-cmd-test
    FROM centos
    CMD ["ls","-a"]
    [root@localhost dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest:1.0 .
    Sending build context to Docker daemon  3.072kB
    Step 1/2 : FROM centos
     ---> 5d0da3dc9764
    Step 2/2 : CMD ["ls","-a"]
     ---> Running in 43d7ffc32f86
    Removing intermediate container 43d7ffc32f86
     ---> 9df9cd01732a
    Successfully built 9df9cd01732a
    Successfully tagged cmdtest:1.0
    [root@localhost dockerfile]# docker run cmdtest:1.0
    .
    ..
    .dockerenv
    bin
    dev
    etc
    home
    lib
    lib64
    lost+found
    media
    mnt
    opt
    proc
    root
    run
    sbin
    srv
    sys
    tmp
    usr
    var
    
    # 由于使用的是 CMD指令,命令无追加
    # -l取代了原本的ls -a,而-l命令不存在所以报错
    [root@localhost dockerfile]# docker run cmdtest:1.0 -l
    docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
    [root@localhost dockerfile]#
    
    
  • 测试 ENTRYPOINT 命令

    [root@localhost dockerfile]# cat dockerfile-entrypoint-test
    FROM centos
    ENTRYPOINT ["ls","-a"]
    [root@localhost dockerfile]# docker build -f dockerfile-entrypoint-test -t cmdtest:2.0 .
    Sending build context to Docker daemon  4.096kB
    Step 1/2 : FROM centos
     ---> 5d0da3dc9764
    Step 2/2 : ENTRYPOINT ["ls","-a"]
     ---> Running in 08abe39ea0bf
    Removing intermediate container 08abe39ea0bf
     ---> 95b862a8e4e7
    Successfully built 95b862a8e4e7
    Successfully tagged cmdtest:2.0
    
    # 运行镜像
    [root@localhost dockerfile]# docker run -it cmdtest:2.0
    .   .dockerenv  dev  home  lib64       media  opt   root  sbin  sys  usr
    ..  bin         etc  lib   lost+found  mnt    proc  run   srv   tmp  var
    
    # 追加命令,再次运行镜像。
    [root@localhost dockerfile]# docker run -it cmdtest:2.0 -l
    total 0
    drwxr-xr-x.   1 root root   6 Dec  5 12:39 .
    drwxr-xr-x.   1 root root   6 Dec  5 12:39 ..
    -rwxr-xr-x.   1 root root   0 Dec  5 12:39 .dockerenv
    lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
    drwxr-xr-x.   5 root root 360 Dec  5 12:39 dev
    drwxr-xr-x.   1 root root  66 Dec  5 12:39 etc
    drwxr-xr-x.   2 root root   6 Nov  3  2020 home
    lrwxrwxrwx.   1 root root   7 Nov  3  2020 lib -> usr/lib
    lrwxrwxrwx.   1 root root   9 Nov  3  2020 lib64 -> usr/lib64
    drwx------.   2 root root   6 Sep 15 14:17 lost+found
    drwxr-xr-x.   2 root root   6 Nov  3  2020 media
    drwxr-xr-x.   2 root root   6 Nov  3  2020 mnt
    drwxr-xr-x.   2 root root   6 Nov  3  2020 opt
    dr-xr-xr-x. 234 root root   0 Dec  5 12:39 proc
    dr-xr-x---.   2 root root 162 Sep 15 14:17 root
    drwxr-xr-x.  11 root root 163 Sep 15 14:17 run
    lrwxrwxrwx.   1 root root   8 Nov  3  2020 sbin -> usr/sbin
    drwxr-xr-x.   2 root root   6 Nov  3  2020 srv
    dr-xr-xr-x.  13 root root   0 Dec  4 12:28 sys
    drwxrwxrwt.   7 root root 171 Sep 15 14:17 tmp
    drwxr-xr-x.  12 root root 144 Sep 15 14:17 usr
    drwxr-xr-x.  20 root root 262 Sep 15 14:17 var
    [root@localhost dockerfile]#
    
    

实战:DockerFile 制作 Tomcat 镜像

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

    [root@localhost tomcat]# pwd
    /home/crater/tomcat
    [root@localhost tomcat]# ll
    total 153424
    -rw-r--r--. 1 root root  11579748 Dec  7 09:20 apache-tomcat-9.0.55.tar.gz
    -rw-r--r--. 1 root root 145520298 Aug 21 13:08 jdk-8u301-linux-x64.tar.gz
    [root@localhost tomcat]#
    
    
  2. 编写 Dockerfile,在压缩包所在目录下编写

    Dockerfile 是官方文件名,build 命令会自动寻找这个文件

    FROM centos
    MAINTAINER crater<1813059208@qq.com>
    
    COPY readme.txt /usr/local/readme.txt
    
    ADD jdk-8u301-linux-x64.tar.gz /usr/local
    ADD apache-tomcat-9.0.55.tar.gz /usr/local
    
    RUN yum -y install vim
    
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    ENV JAVA_HOME /usr/local/jdk1.8.0_301
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.55
    ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.55
    ENV PATH $PATH:/$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    
    EXPOSE 8080
    
    CMD /usr/local/apache-tomcat-9.0.55/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.55/bin/log/catalina.out
    
    
  3. 构建镜像

    [root@localhost tomcat]# ll
    total 153428
    -rw-r--r--. 1 root root  11579748 Dec  7 09:20 apache-tomcat-9.0.55.tar.gz
    -rw-r--r--. 1 root root       635 Dec  7 13:22 Dockerfile
    -rw-r--r--. 1 root root 145520298 Aug 21 13:08 jdk-8u301-linux-x64.tar.gz
    -rw-r--r--. 1 root root         0 Dec  7 13:30 readme.txt
    [root@localhost tomcat]# docker build -t diy_tomcat .
    Sending build context to Docker daemon  157.1MB
    Step 1/15 : FROM centos
     ---> 5d0da3dc9764
    Step 2/15 : MAINTAINER crater<1813059208@qq.com>
     ---> Using cache
     ---> bcc334ef04e6
    Step 3/15 : COPY readme.txt /usr/local/readme.txt
     ---> 9206ef85b7cb
    Step 4/15 : ADD jdk-8u301-linux-x64.tar.gz /usr/local
     ---> a434a1360f2c
    Step 5/15 : ADD apache-tomcat-9.0.55.tar.gz /usr/local
     ---> ccc6aa87831e
    Step 6/15 : RUN yum -y install vim
     ---> Running in 98baa6280dc2
     ... ...
    Removing intermediate container 98baa6280dc2
     ---> 6019082a9e28
    Step 7/15 : ENV MYPATH /usr/local
     ---> Running in ca38b8403256
    Removing intermediate container ca38b8403256
     ---> 1764e92045a8
    Step 8/15 : WORKDIR $MYPATH
     ---> Running in 71d67d69af5f
    Removing intermediate container 71d67d69af5f
     ---> 13d13f72f38a
    Step 9/15 : ENV JAVA_HOME /usr/local/jdk1.8.0_301
     ---> Running in 53798abb3abf
    Removing intermediate container 53798abb3abf
     ---> ddecdf93702b
    Step 10/15 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
     ---> Running in 0182a861f126
    Removing intermediate container 0182a861f126
     ---> f24d9263027c
    Step 11/15 : ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.55
     ---> Running in 544f68dcd93a
    Removing intermediate container 544f68dcd93a
     ---> 51f8f7e953e3
    Step 12/15 : ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.55
     ---> Running in 97c825f8b8d9
    Removing intermediate container 97c825f8b8d9
     ---> fcc34a736e24
    Step 13/15 : ENV PATH $PATH:/$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
     ---> Running in 61041d8d7a6f
    Removing intermediate container 61041d8d7a6f
     ---> b86f18843a8a
    Step 14/15 : EXPOSE 8080
     ---> Running in 5de116096fdf
    Removing intermediate container 5de116096fdf
     ---> d0fad2c29e37
    Step 15/15 : CMD /usr/local/apache-tomcat-9.0.55/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.55/bin/log/catalina.out
     ---> Running in a83d0b07acf3
    Removing intermediate container a83d0b07acf3
     ---> 778652bb32ed
    Successfully built 778652bb32ed
    Successfully tagged diy_tomcat:latest
    [root@localhost tomcat]#
    
    
  4. 查看自定义的镜像

    [root@localhost tomcat]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
    diy_tomcat   latest    778652bb32ed   3 minutes ago   673MB
    ... ...
    
  5. 启动自定义镜像,并访问,可以看到 tomcat 初始化页面

    [root@localhost /]# docker run -d -p 9090:8080 --name crater_tomcat \
    				-v /home/crater/tomcat/test:/usr/local/apache-tomcat-9.0.55/webapps/test \
    				-v /home/crater/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.55/logs diy_tomcat
    63789ca30679d843ae3f1e6daca0eff5736f9405d9364f4715ef82fdab795ad4
    [root@localhost /]# 
    
    # 数据卷也成功挂载
    [root@localhost tomcat]# pwd
    /home/crater/tomcat
    [root@localhost tomcat]# ll
    total 153428
    -rw-r--r--. 1 root root  11579748 Dec  7 09:20 apache-tomcat-9.0.55.tar.gz
    -rw-r--r--. 1 root root       635 Dec  7 13:22 Dockerfile
    -rw-r--r--. 1 root root 145520298 Aug 21 13:08 jdk-8u301-linux-x64.tar.gz
    -rw-r--r--. 1 root root         0 Dec  7 13:30 readme.txt
    drwxr-xr-x. 2 root root         6 Dec  7 14:26 test			# 数据卷
    drwxr-xr-x. 2 root root       197 Dec  7 14:26 tomcatlogs	# 数据卷
    [root@localhost tomcat]# 
    
    
    
  6. 发布一个自己的 web 项目,由于做了卷挂载,直接在宿主机编辑项目就可以发布

    test/WEB-INF/web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_2_5.xsd"
             version="2.5">
             
    </web-app>
    

    test/index.jsp

    <%@ page language="java" contentType="text/html;charset=UTF-8"%>
    <html>
    <head>
    <title>crater index</title>
    </head>
    <body>
    <%
    out.println("--- hello world ---");    
    %>
    </body>
    </html>
    

    访问 宿主机ip:9090/test,成功!

发布镜像到 DockerHub

  1. 在官网 https://hub.docker.com/ 注册账号

  2. 使用 docker login 命令,登录

    [root@localhost /]# 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
    
    # 登录成功
    [root@localhost /]# docker login -u crater18130
    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
    
    
  3. 提交镜像,docker pull

    dockerHub上传镜像的命名规范是 (用户名)/(镜像名):(版本号),但是构建镜像时的名称是 diy_tomcat,所以上传之前先用docker tag命令标记本地镜像

    # 直接push,拒绝
    [root@localhost /]# docker push diy_tomcat
    Using default tag: latest
    The push refers to repository [docker.io/library/diy_tomcat]
    5dd1286ad677: Preparing 
    68fa0de95b27: Preparing 
    c0212179b704: Preparing 
    538263ae5b1b: Preparing 
    74ddd0ec08fa: Preparing 
    denied: requested access to the resource is denied		# 拒绝
    
    # 打标签
    [root@localhost tomcat]# docker tag 3ef4c527cca3 crater18130/tomcat:1.0
    
    # 发布成功
    [root@localhost tomcat]# docker push crater18130/tomcat:1.0
    The push refers to repository [docker.io/crater18130/tomcat]
    d7bf6a439f9b: Pushed 
    d43e99405529: Pushed 
    05f42e93b576: Pushed 
    34563d205909: Pushed 
    74ddd0ec08fa: Pushed 
    1.0: digest: sha256:77c8f6ef54d7cedae2c0e4a09d51c1702542c15c2cfc55b4857876cee03affc0 size: 1373
    
    

发布镜像到阿里云容器服务

  1. 登录阿里云容器镜像服务,创建命名空间
    在这里插入图片描述

  2. 创建镜像仓库
    在这里插入图片描述

  3. 登录阿里云

    [root@localhost /]# docker login --username=辛小丰 registry.cn-hangzhou.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@localhost /]# 
    
    
  4. 打标签,推送

    # 打标签
    [root@localhost /]# docker tag 3ef4c527cca3 registry.cn-hangzhou.aliyuncs.com/crater_namespace/crater_repository:1.0
    [root@localhost /]# docker images
    REPOSITORY                                                             TAG       IMAGE ID       CREATED        SIZE
    crater18130/tomcat                                                     1.0       3ef4c527cca3   4 hours ago    673MB
    diy_tomcat                                                             latest    3ef4c527cca3   4 hours ago    673MB
    registry.cn-hangzhou.aliyuncs.com/crater_namespace/crater_repository   1.0       3ef4c527cca3   4 hours ago    673MB
    
    # 推送
    [root@localhost /]# docker push registry.cn-hangzhou.aliyuncs.com/crater_namespace/crater_repository:1.0
    The push refers to repository [registry.cn-hangzhou.aliyuncs.com/crater_namespace/crater_repository]
    d7bf6a439f9b: Pushed 
    d43e99405529: Pushed 
    05f42e93b576: Pushed 
    34563d205909: Pushed 
    74ddd0ec08fa: Pushed 
    1.0: digest: sha256:77c8f6ef54d7cedae2c0e4a09d51c1702542c15c2cfc55b4857876cee03affc0 size: 1373
    [root@localhost /]# 
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-edWQDx6T-1638897089318)(E:\应用缓存\Typora图片\Hello Docker\image-20211208000145513.png)]

以上内容小结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bZzQfHeE-1638897089319)(E:\应用缓存\Typora图片\Hello Docker\image-20211205211729195.png)]

Docker 网络

Docker0 详解

# 清除镜像、容器,干干净净学网络
[root@localhost /]# docker rm -f $(docker ps -aq)
[root@localhost /]# docker rmi -f $(docker images -aq)

查看宿主机的 ip 地址

  • ip addr

    只要安装 Docker,就会有一个网卡 docker0,是桥接模式,使用的是 evth-pair 技术。
    在这里插入图片描述
    问题:docker是如何访问网络的

  1. 启动一个 Tomcat 容器,进入容器查看网络设置

    [root@localhost /]# docker run -d -P --name tomcat01 tomcat
    

    容器启动后,Docker 给容器分配了一个 eth0@if49 的网卡

    如果不能使用ip addr命令,需要先进去容器安装一下:apt update && apt install -y iproute2
    在这里插入图片描述

  2. 尝试在宿主机 ping 容器,可以 ping 通 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CartPpON-1638897089321)(E:\应用缓存\Typora图片\Hello Docker\image-20211206130015207.png)]

  3. 再次查看宿主机的网络配置信息

    可以看到容器内部和Linux主机都会创建一个新的网卡,而这两个网卡都是成对的。使用的技术就是evth-pair。evth-pair 就是一对的虚拟设备接口,他们是成对出现的,一段连着协议,一段彼此相连。evth-pair充当一个桥梁,连接各种虚拟网络设备。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c2tp2kGD-1638897089322)(E:\应用缓存\Typora图片\Hello Docker\image-20211206130822129.png)]

  4. 再启动一个Tomcat容器,尝试容器之间的网络连接是否能够成功

    宿主机和容器查看网络配置信息,又多了一对网卡
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1MF9lq3a-1638897089323)(E:\应用缓存\Typora图片\Hello Docker\image-20211206140310676.png)]

  5. 尝试在tomcat02 容器中 ping tomcat01 容器:

    如果 ping 命令不存在,先进入容器执行 apt-get update && apt install iputils-ping
    在这里插入图片描述
    可以看到两个容器是可以连接上的。两个Tomcat容器之间的网络交互模型图如下:
    在这里插入图片描述

  6. 说明:

    Tomcat01 和 Tomcat02 都使用公用的路由器 docker0。所有的容器不指定网络下,都是由 docker0 路由的,Docker 会给我们容器默认分配一个随机的可用IP地址。

    容器网络互联的通用模型,如下图所示: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HuUQrG0X-1638897089325)(E:\应用缓存\Typora图片\Hello Docker\image-20211206175235169.png)]
    Docker 中所有的网络接口都是虚拟的,只要容器删除,容器对应的网桥也会删除。

容器互联

在微服务架构中,可以使用 Feign 通过服务名来访问其他微服务,docker也可以用容器名来访问

  1. 直接 ping 不通

    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE     COMMAND             ... ...	NAMES
    f508ef0a0614   tomcat    "catalina.sh run"   ... ...	tomcat02
    899fc7802e11   tomcat    "catalina.sh run"   ... ...	tomcat01
    [root@localhost /]# docker exec -it tomcat02 ping tomcat01
    ping: tomcat01: Temporary failure in name resolution
    
    
  2. 启动一个 tomcat03 容器使用 --link 连接已经启动的 tomcat02 容器,再用 tomcat03 容器 ping tomcat02,可以 ping 通

    [root@localhost /]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
    043bfed7a6b728895cbda5df6c2adce4290135034a19a510d2cfad440ab9b679
    [root@localhost /]# 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.175 ms
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.065 ms
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.068 ms
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=4 ttl=64 time=0.062 ms
    ^C
    --- tomcat02 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3000ms
    rtt min/avg/max/mdev = 0.062/0.092/0.175/0.047 ms
    [root@localhost /]#
    
    
  3. 但是使用 tomcat02 去 ping tomcat03 ,则还是 ping 不通

    [root@localhost /]# docker exec -it tomcat02 ping tomcat03
    ping: tomcat03: Temporary failure in name resolution
    
    
  4. 因为--link的原理是在 tomcat03 容器中的 /etc/hosts 文件上,添加容器名和ip地址的映射

    从文件中可以看出,docker exec -it tomcat03 ping f508ef0a0614 也可以 ping 通

    [root@localhost /]# docker exec -it tomcat03 cat /etc/hosts
    127.0.0.1       localhost
    ::1     localhost ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
    172.17.0.3      tomcat02 f508ef0a0614	# 容器名和ip地址的映射
    172.17.0.4      043bfed7a6b7
    
    
  5. tomcat02 容器中并没有添加容器名 tomcat03 和ip地址的映射

    [root@localhost /]# docker exec -it tomcat02 cat /etc/hosts
    127.0.0.1       localhost
    ::1     localhost ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
    172.17.0.3      f508ef0a0614
    [root@localhost /]#
    
    

目前--link设置容器互连的方式已经不推荐使用。因为这种方式基于 docker0,而 docker0 不支持容器名访问,所以更多地选择自定义网络

自定义网络 - 容器互联

容器使用自定义网络,就可以实现通过容器名来互相访问。

  • 查看 network 相关命令

    #帮助命令后显示下面信息
    [root@localhost /]# docker network --help
    
    Usage:	docker network COMMAND
    
    Manage networks
    
    Options:
          --help   Print usage
    
    Commands:
      connect     Connect a container to a network
      create      Create a network
      disconnect  Disconnect a container from a network
      inspect     Display detailed information on one or more networks
      ls          List networks
      prune       Remove all unused networks
      rm          Remove one or more networks
    
    Run 'docker network COMMAND --help' for more information on a command.
    
    # connect 将某个容器连接到一个docker网络
    # create 创建一个docker局域网络
    # disconnect 将某个容器退出某个局域网络
    # inspect 显示某个局域网络信息
    # ls 显示所有docker局域网络
    # prune 删除所有未引用的docker局域网络
    # rm 删除docker网络
    
  • 显示所有docker局域网络

    [root@localhost /]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    455712685c66   bridge    bridge    local
    67fbf49a4af5   host      host      local
    e97fdbcd0447   none      null      local
    [root@localhost /]#
    
    # bridge:	桥接,docker默认,自定义也使用bridge模式
    # none:		不配置网络
    # host:		和宿主机共享网络
    # container:容器联通,用得少,局限性大
    

    直接启动时,默认使用了参数 --network bridge

    docker run -d -P --name tomcat01
    docker run -d -P --name tomcat01 --network bridge
    

自定义网络

  • docker network create

    # --driver bridge			桥接模式
    # --subnet 192.168.0.0/16	子网,支持 192.168.0.2~192.168.255.254
    # --gateway 192.168.0.1		网关
    [root@localhost /]# docker network create \
    					--driver bridge \
    					--subnet 192.168.0.0/16 \
    					--gateway 192.168.0.1 \
    					mynet
    02d84cce3c4e0fa73af07fcb9f5d64400a1da8f15af8fcb2847dbf07e6c72f20
    [root@localhost /]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    455712685c66   bridge    bridge    local
    67fbf49a4af5   host      host      local
    02d84cce3c4e   mynet     bridge    local
    e97fdbcd0447   none      null      local
    [root@localhost /]#
    
    
  • 查看自定义网络信息

    [root@localhost /]# docker network inspect mynet
    [
        {
            "Name": "mynet",
            "Id": "02d84cce3c4e0fa73af07fcb9f5d64400a1da8f15af8fcb2847dbf07e6c72f20",
            "Created": "2021-12-06T23:07:37.938428846+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "192.168.0.0/16",
                        "Gateway": "192.168.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {},
            "Options": {},
            "Labels": {}
        }
    ]
    
    

启动两个容器,指定使用该自定义网络mynet,测试处于自定义网络下的容器,是否可以直接通过容器名进行网络访问

  • 启动两个容器,并查看网络信息

    [root@localhost /]# docker run -d -P --name tomcat-net-01 --net mynet tomcat:8.0
    12f782ea349059cf0242d9454b50a95b33bca1c39a15a0f1c855c81153a205be
    [root@localhost /]# docker run -d -P --name tomcat-net-02 --net mynet tomcat:8.0
    8dadae657abc170c6db2ff5a92275f420b396e493ac9d8452f73b990976d62ad
    [root@localhost /]# docker network inspect mynet
    [
        {
            "Name": "mynet",
            "Id": "02d84cce3c4e0fa73af07fcb9f5d64400a1da8f15af8fcb2847dbf07e6c72f20",
            "Created": "2021-12-06T23:07:37.938428846+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "192.168.0.0/16",
                        "Gateway": "192.168.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {
                "12f782ea349059cf0242d9454b50a95b33bca1c39a15a0f1c855c81153a205be": {
                    "Name": "tomcat-net-01",
                    "EndpointID": "1dac6b0006f3b19d733d664209054a1e6262e4295b89d654552ea915d18da7e2",
                    "MacAddress": "02:42:c0:a8:00:02",
                    "IPv4Address": "192.168.0.2/16",
                    "IPv6Address": ""
                },
                "8dadae657abc170c6db2ff5a92275f420b396e493ac9d8452f73b990976d62ad": {
                    "Name": "tomcat-net-02",
                    "EndpointID": "0b76911ae8112c99c14521cb90ff015179e43375b709703111024fe721c324db",
                    "MacAddress": "02:42:c0:a8:00:03",
                    "IPv4Address": "192.168.0.3/16",
                    "IPv6Address": ""
                }
            },
            "Options": {},
            "Labels": {}
        }
    ]
    
    
  • 尝试用 tomcat-net-01 去 ping 一下 tomcat-net-02,

    # Ip地址可以ping通
    [root@localhost /]# docker exec -it tomcat-net-01 ping 192.168.0.3
    PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
    64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.136 ms
    64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.076 ms
    ^C
    --- 192.168.0.3 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 2999ms
    rtt min/avg/max/mdev = 0.061/0.083/0.136/0.032 ms
    
    # 容器名称也可以ping通
    [root@localhost /]# 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.056 ms
    64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.064 ms
    ^C
    --- tomcat-net-02 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 3000ms
    rtt min/avg/max/mdev = 0.056/0.063/0.069/0.009 ms
    
    

自定义的网络默认维护了容器间的网络通信问题,推荐使用自定义实现网络互联。

网络联通

不同网络间的容器是无法进行网络连接的

不同Docker网络之间的容器需要连接的话,需要把作为调用方的容器注册一个ip到被调用方所在的网络上。

  • 期望进行如图连接
    在这里插入图片描述

  • 环境准备,并尝试 tomcat-01 连接 mynet 网络下的 tomcat-net-01 容器

    [root@localhost /]# docker run -d -P --name tomcat-01 tomcat:8.0
    e88b94df9e19eb155054ed1fa3baf8fb2f8b2814119c8b5b67c17ce6221586a1
    [root@localhost /]# docker run -d -P --name tomcat-02 tomcat:8.0
    cb368feb578e25544c3700fcc3ef1cb98421e131f47ced4de88d4d4369c925f1
    [root@localhost /]# docker ps
    CONTAINER ID   IMAGE        COMMAND             		... ... 				NAMES
    cb368feb578e   tomcat:8.0   "catalina.sh run"   		... ... 				tomcat-02
    e88b94df9e19   tomcat:8.0   "catalina.sh run"   		... ... 				tomcat-01
    8dadae657abc   tomcat:8.0   "catalina.sh run"   		... ... 				tomcat-net-02
    12f782ea3490   tomcat:8.0   "catalina.sh run"   		... ... 				tomcat-net-01
    
    # 尝试连接,失败
    [root@localhost /]# docker exec -it tomcat-01 ping tomcat-net-01
    ping: unknow host tomcat-net-01
    
    
  • 容器tomcat-01连接到 mynet 网络上。查看mynet的网络详情,看到 mynet 给容器tomcat-01分配了一个ip地址

    一个容器,两个地址

    [root@localhost /]# docker network connect mynet tomcat-01
    [root@localhost /]# docker network inspect mynet
    [
        {
            "Name": "mynet",
            "Id": "02d84cce3c4e0fa73af07fcb9f5d64400a1da8f15af8fcb2847dbf07e6c72f20",
            "Created": "2021-12-06T23:07:37.938428846+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "192.168.0.0/16",
                        "Gateway": "192.168.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {
                "12f782ea349059cf0242d9454b50a95b33bca1c39a15a0f1c855c81153a205be": {
                    "Name": "tomcat-net-01",
                    "EndpointID": "1dac6b0006f3b19d733d664209054a1e6262e4295b89d654552ea915d18da7e2",
                    "MacAddress": "02:42:c0:a8:00:02",
                    "IPv4Address": "192.168.0.2/16",
                    "IPv6Address": ""
                },
                "8dadae657abc170c6db2ff5a92275f420b396e493ac9d8452f73b990976d62ad": {
                    "Name": "tomcat-net-02",
                    "EndpointID": "0b76911ae8112c99c14521cb90ff015179e43375b709703111024fe721c324db",
                    "MacAddress": "02:42:c0:a8:00:03",
                    "IPv4Address": "192.168.0.3/16",
                    "IPv6Address": ""
                },
                "e88b94df9e19eb155054ed1fa3baf8fb2f8b2814119c8b5b67c17ce6221586a1": {
                    "Name": "tomcat-01",
                    "EndpointID": "960cd6f0169535def51eb8f1371efc950766c54557b28390d61bac4e2f2aa91d",
                    "MacAddress": "02:42:c0:a8:00:04",
                    "IPv4Address": "192.168.0.4/16",
                    "IPv6Address": ""
                }
            },
            "Options": {},
            "Labels": {}
        }
    ]
    [root@localhost /]#
    
    
  • 再次并尝试 tomcat-01 连接 mynet 网络下的 tomcat-net-01 容器,成功!

    实现不同网络之间的容器互联!

    [root@localhost /]# docker exec -it tomcat-01 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.248 ms
    64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.063 ms
    64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.112 ms
    64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.062 ms
    ^C
    --- tomcat-net-01 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3000ms
    rtt min/avg/max/mdev = 0.062/0.121/0.248/0.076 ms
    [root@localhost /]#
    
    

SprinigBoot 微服务打包 Docker 镜像

  1. 新建一个 SpringBoot 项目,只有一个 controller,Maven打包成 jar 包

    package com.example.docker_demo.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * 作者: Crater
     * 创建时间: 2021/12/8 0:46
     */
    @RestController
    public class HelloController {
    
        @RequestMapping("/hello")
        public String hello() {
            return "hello crater\n";
        }
    
    }
    
  2. 编写 Dockerfile

    FROM java:8
    COPY *.jar /app.jar
    CMD ["--server.port=8080"]
    EXPOSE 8080
    ENTRYPOINT ["java","-jar","/app.jar"]
    
    
  3. 上传服务器,生成镜像

    [root@localhost idea]# pwd
    /home/crater/idea
    [root@localhost idea]# ll
    total 16340
    -rw-r--r--. 1 root root 16727840 Dec  8 00:47 docker_demo-0.0.1-SNAPSHOT.jar
    -rw-r--r--. 1 root root      114 Dec  8 00:53 Dockerfile
    [root@localhost idea]# docker build -t demo .
    Sending build context to Docker daemon  16.73MB
    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
     ---> 78d4953d85d7
    Step 3/5 : CMD ["--server.port=8080"]
     ---> Running in ca0d5b9f2d45
    Removing intermediate container ca0d5b9f2d45
     ---> 0881428042d6
    Step 4/5 : EXPOSE 8080
     ---> Running in bc1cbe2204a0
    Removing intermediate container bc1cbe2204a0
     ---> d86cac9cd3ac
    Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]
     ---> Running in ed4b68a2a83c
    Removing intermediate container ed4b68a2a83c
     ---> 7c2d1f4b0356
    Successfully built 7c2d1f4b0356
    Successfully tagged demo:latest
    [root@localhost idea]# 
    
  4. 发布运行

    [root@localhost idea]# docker images
    REPOSITORY                  TAG       IMAGE ID       CREATED              SIZE
    demo                        latest    7c2d1f4b0356   About a minute ago   660MB
    [root@localhost idea]# docker run -d -p 8080:8080 demo
    1e6d18bbd2f1a48c057bc61ff2dca165c2fbff6f7a132719c86354c44380c040
    [root@localhost idea]# curl localhost:8080/hello
    hello crater
    [root@localhost idea]# 
    
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Docker 入门笔记 的相关文章

随机推荐

  • 51单片机——ADC模数转换、DAC数模转换PWM C语言入门编程

    目录 ADC XPT2046 1 ADC模数转换 数码管上显示AD模块采集电位器的阻值 热敏的温度值 光敏的光值 DAC PWM 1 DAC数模转换 DAC PWM 模块上的指示灯DA1呈呼吸灯效果 由暗变亮再由亮变暗 ADC ADC an
  • 聊聊技术专家谈阿里云史诗级故障

    序言 什么是技术专家 其实也是很懂 是做的时间足够长呢 还是说经历的厂比较多 还是说纸上谈兵比较牛逼 专家嘛 大家都懂的 只会弹别人 喔 是谈别人 原来不是弹 有本事技术专家谈谈自己呗 风言风语 阿里云出现史诗级故障 处理的时间足够长 然后
  • 过去式加ed的发音_「初中英语语法大全」不规则动词过去式和过去分词巧记方法...

    动词的过去式和过去分词是初中英语教学中的重点 而有些动词的不规则变化是这些重点中的难点 但这些不规则变化也不是毫无规律可循的 现将初中英语中一些常用的不规则动词变化介绍如下 一 原形 过去式和过去分词的词形和读音都相同的单词 结尾字母一般是
  • 计算机视觉项目实战(一)、图像滤波和图像混合 Image Filtering and Hybrid Images

    图像滤波和图像混合 Image Filtering and Hybrid Images 项目要求 项目原理 主要函数 my imfilter 函数解释 输入参数 输出参数 主要实现步骤 gen hybrid image 函数解释 输入参数
  • java中JSONArray 遍历方式

    第一种 java8 遍历JSONArray 拼接字符串 public static void main String args JSONArray jSONArray new JSONArray JSONObject jb new JSON
  • Linux中退出编辑模式的命令

    vi 文件 回车后就进入进入编辑模式 按 o 进行编辑 编辑结束 shift 退出编辑模式 然后输入退出命令 1 保存不退出 w 保存文件但不退出vi 编辑 w 强制保存 不退出vi 编辑 w file 将修改另存到file中 不退出vi
  • CNN可视化技术 -- CAM & Grad-CAM详解及pytorch简洁实现

    文章目录 前言 1 CAM Class Activation Map 2 Grad CAM 3 PyTorch中的hook机制 4 Grad CAM的PyTorch简洁实现 参考资料 前言 CNN中的特征可视化大体可分为两类 细节信息 ZF
  • Redis实战篇一 (短信登录)

    Redis企业实战 黑马点评 项目整体架构 项目部署 后端部署 前端部署 短信登陆 基于Session实现登录 集群的Session共享问题 基于Redis实现共享session登录 解决状态登录刷新的问题 登录拦截器的优化 本期学习路线
  • SVN导出版本增量包

    showlog 选择一个或者多个版本 右键 Compare with previous version 选择一个或者多个文件 右键 Expore selection to 最后导出的文件会有其相应的路径
  • 全志F1C200s芯片处理器参数介绍

    F1C200s是全志的一款高度集成 低功耗的移动应用处理器 可用于多种多媒体音视频设备中 全志F1C200s基于ARM 9架构 集成了DDR 它支持高清视频解码 包括H 264 H 263 MPEG 1 2 4等 它还集成了音频编解码器和I
  • cucumber测试_延长Cucumber测试生命周期

    cucumber测试 总览 本文涉及两件事 我如何使beforeAll和AfterAll生命周期事件在Cucumber中发生 在Cucumber测试运行之前 如何使用TestContainers设置被测系统 不 您正在尝试在博客上进行SEO
  • node.js升级报错digital envelope routines unsupporte最简单解决方案

    背景 本地将nodejs 16升级成nodejs18运行时报错digital envelope routines unsupported 报错 Error error 0308010C digital envelope routines u
  • cytoscape插件下载_cytoscape五步曲之三:安装各种插件

    软件安装我就不多说了 直接去官网下载即可 请务必下载3 x版本 我讲的是 最新版教程 本次讲解如何给cytoscape安装插件 cytoscape本身是一个平台 学者可以在上面开发各种各样功能的插件实现不同的分析需求 类似于R语言这个平台
  • mysql中varbinary什么意思_MySQL中的数据类型binary和varbinary详解

    前言 BINARY和VARBINARY与 CHAR和VARCHAR类型有点类似 不同的是BINARY和VARBINARY存储的是二进制的字符串 而非字符型字符串 也就是说 BINARY和VARBINARY没有字符集的概念 对其排序和比较都是
  • 当我被酱香拿铁刷屏后......

    这两天 朋友圈刮起了酱香风 跨界里的新宠儿酱香拿铁卖爆了 不得不说瑞幸是懂跨界的 短短一天时间 酱香拿铁已售出 542 万杯 销售额超一亿元 谁能想到年轻人的第一杯茅台竟然是瑞幸卖出去的 这可能也是星巴克最无语的一天吧 瑞幸的订单长到可以直
  • python多进程cpu的占用率很低_Python 中的进程池与多进程

    封面图片来源 沙沙野 内容概览 进程池 进程池和多进程的性能测试 进程池的其他机制 进程池的回调函数 进程池 如果有多少个任务 就开启多少个进程 实际上并不划算 由于计算机的 cpu 个数是非常有限的因此开启的进程数量完全和 cpu 个数成
  • LOAM算法详解

    激光SLAM 帧间匹配方法 Point to Plane ICP NDT Feature based Method 回环检测方法 Scan to Scan Scan to Map LOAM创新点 定位和建图的分离 里程计模块 高频低质量的帧
  • 在pycharm中更新pip失败

    尝试了网上的各种方法 各种翻车 删除虚拟环境中的这两个文件夹 包括pip 有只删除pip 21 1 2 dist info这个个文件夹然后重新安装pip之后在更新 我试了没有用 下载 get pip py 文件 转到 https boots
  • drive数据集_英伟达的最强人脸GAN开源了,它吃的高清数据集也开源了

    栗子 假装发自 凹非寺 量子位 出品 公众号 QbitAI 你大概还没忘记 英伟达去年年底推出的GAN 它合成的人脸甚至骗得过肉眼 如今 它终于有了自己的名字 叫StyleGAN 顾名思义 GAN的生成器 是借用风格迁移的思路重新发明的 能
  • Docker 入门笔记

    狂神说Java Docker最新超详细版教程通俗易懂 视频地址 https www bilibili com video BV1og4y1q7M4 share source copy web Docker安装 基本组成 说明 镜像 imag