Docker学习

Docker学习

看这个会好一点 https://www.kancloud.cn/docker_practice/docker_practice/469763

1. 基础

1.1 Docker概述

1.1.1 内容介绍

Docker是基于 Go语言开发的,是一个开源项目

官网:https://www.docker.com/

文档:https://docs.docker.com/

快速开始:https://docs.docker.com/get-started/overview/

社区:https://www.docker.com/docker-community

百度百科:https://baike.baidu.com/item/Docker/13344470?fr=aladdin

Docker技术 对比 虚拟机技术:

  • 虚拟机虚拟出一整套硬件,运行一个完整的操作系统,资源占用多、启动慢;

  • 而容器化技术直接运行在宿主机上,本身没有自己的内核,是轻量级的,而每个容器间是相互隔离的

利用 Docker后,可以一键运行、打包镜像、发布测试,实现应用更快速的交付和部署,实现更便捷的升级和扩、缩容。

1.1.2 基本组成

  • 镜像(image):类似模板,用于创建容器服务,通过一个镜像可以创建多个容器

  • 容器(container):独立运行一个或多个应用,通过镜像来创建

  • 仓库(repository):存放镜像的地方,分为 公有仓库和 私有仓库,类似 Maven仓库

1.2 Docker安装

1.2.1 Docker本体安装

官网教程:https://docs.docker.com/engine/install/ubuntu/

具体步骤:

  1. 解除安装旧的版本(Uninstall old versions)

    旧版本的 docker应用被称为 docker, docker.io 或者 docker-engine,如果这些已经安装了,就卸载它们

     sudo apt-get remove docker docker-engine docker.io containerd runc
    

    如果执行 apt命令反馈这些内容没有被安装也是正常的

    原有的信息一般默认保存在 /var/lib/docker目录下,如果想要彻底清楚这些内容,可以继续执行以下指令

    sudo apt-get purge docker-ce docker-ce-cli containerd.io # Uninstall the Docker Engine, CLI, and Containerd packages
    
     sudo rm -rf /var/lib/docker
     sudo rm -rf /var/lib/containerd # delete all images, containers, and volumes
    
  2. 选择支持的存储驱动程序

    Ubuntu上,Docker Engine支持以下 3种驱动: overlay2, aufsbtrfs

    默认使用 overlay2,如果需要使用其他的就得手动配置 链接

  3. 正式安装,可以采用不同的方式进行安装:

    • 大部分用户会 设置 Docker repositories并依据其进行安装,这种最简单
    • 少部分用户会下载 DEB package并且手动安装和手动更新,这种方式适合在断网的情况下进行安装
    • 在测试和开发环境下,部分用户会使用 脚本语言安装
  4. 使用 repositories进行安装

    1. 设置 repository

      sudo apt-get update # 更新 apt
      
      sudo apt-get install \ 
          apt-transport-https \
          ca-certificates \
          curl \
          gnupg \
          lsb-release # 安装相关的包
          
      curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 添加 Docker的依赖
      
       echo \
        "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
        $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 创建一个稳定的 repository, 可以在 stable关键词后添加 nightly 或 test关键字实现特殊的安装
      
    2. 实际安装 Docker

      sudo apt-get update # 更新 apt索引
      sudo apt-get install docker-ce docker-ce-cli containerd.io # 安装最新版本的 docker
      
    3. 安装旧版本的 Docker

      apt-cache madison docker-ce # 列出可以安装的版本
      sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io # 安装指定的版本
      
    4. 验证安装成功

      sudo docker run hello-world
      

  5. 使用 DEB package进行安装

    1. 下载 .deb文件,前往下载网址,选择你的 Ubuntu的版本(通过 lsb_release -a命令得到),选择/pool/stable,选择 amd64, armhf, arm64或者 s390x并且 下载 .deb文件

    2. 安装

      sudo dpkg -i /path/to/package.deb
      
    3. 验证

      sudo docker run hello-world
      

1.2.2 配置阿里云的镜像加速

阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

登陆后,左侧菜单选中镜像加速器就可以看到你的专属地址了

1.2.3 Docker安装 Nginx

  1. 搜索镜像 docker search nginx 或在 dockerhub上搜索
  2. 下载镜像 docker pull nginx
  3. 后台启动 docker run -d --name nginx01 nginx -p 3344:80
  4. 本机自测 curl localhost:3344
  5. 进入容器 docker exec -it nginx01 /bin/bash
  6. 查看配置 whereis nginx

1.2.4 Docker安装 Tomcat

  1. docker run -it --rm tomcat:9.0 即使没有 tomcat:9.0的镜像,也会自动下载,--rm表示用完就自动删除
  2. 正常下载镜像 docker pull tomcat:9.0
  3. 启动运行 docker run -d --name tomcat9 tomcat:9.0 -p 3355:8080
  4. 进入容器 docker exec -it tomcat9 /bin/bash
    • 会发现 linux命令缺少
    • 也没有 webapp路径
    • 是因为阿里云镜像的原因,默认下载最简版,会剔除很多内容
    • 解决办法是将 webapps.dist路径更名为 webappwebapps.dist中有正常的 tomcat内容

1.2.5 Docker安装 ES+Kibana

  1. dockerhub搜索 elasticsearch
  2. docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:tag , --net表示指定网络配置,因为 elasticsearch需要暴露多个端口所以会有多个 -p-e配置环境参数 因为 elasticsearch比较耗内存所以可以通过参数对其进行限制
  3. 查看容器状态 docker stats

1.2.6 可视化工具

Portainer

提供一个图形化界面管理工具

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

1.2.7 安装 MySQL

  1. docker pull myql:5.7 下载

  2. docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD="zhao" --name mysql01 mysql:5.7 启动

    -d: 后台运行

    -p: 端口映射

    -v: 卷挂载

    -e: 环境变量

    --name: 容器名称

1.2.8 部署 Redis集群

  1. 创建 Redis网卡

    docker network create myredisnet --subnet 172.38.0.0/16
    
  2. 通过脚本创建 6个 redis配置

    for port in $(seq 1 6); \do \mkdir -p /mydata/redis/node-${port}/conftouch /mydata/redis/node-${port}/conf/redis.confcat << EOF >/mydata/redis/node-${port}/conf/redis.confport 6379bind 0.0.0.0cluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000cluster-announce-ip 172.38.0.1${port}cluster-announce-port 6379cluster-announce-bus-port 16379appendonly yesEOFdone
    
  3. 逐个运行 redis容器

    docker run -p 6371:6379 -p 16371:16379 --name redis-1 \	-v /mydata/redis/node-1/data:/data \	-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \	-d --net myredisnet --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
    
  4. 集群启动

    redis-cli --cluster 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
    

1.3 Docker命令

官方文档:https://docs.docker.com/reference/

1.3.1 帮助命令

查看 Docker版本

docker version [OPTIONS]# -f, --format     使用指定的 Go语言模板规格化输出内容   docker version --format '{{.Server.Version}}'# --kubeconfig  指定 K8s的配置文件(已弃用)

查看 Docker系统信息

docker info [OPTIONS]# --format, -f   格式化输出   docker --debug info

获取帮助

docker --helpdocker xxx --help

1.3.2 镜像命令

查看镜像

docker images [OPTIONS] [REPOSITORY[:TAG]]# -a, --all         显示所有(默认会隐藏中间镜像)# -q, --quiet    只显示镜像 id# --digests      显示摘要# --no-trunc    不要截断输出# --format        格式化输出 # -f, --filter       根据条件过滤结果       docker images --filter "dangling=true"    docker images --filter "label=com.example.version=1.0"

  • REPOSITORY: 镜像的仓库源
  • TAG: 镜像的标签
  • IMAGE ID: 镜像的 id
  • CREATED: 镜像的创建时间
  • SIZE: 镜像的大小

搜索镜像

docker search [OPTIONS] TERM# --filter, -f      根据条件过滤结果,以键值对的形式进行过滤,如果有多个条件,就用多个 --filter    # --format       格式化输出             docker search --filter is-official=true --filter stars=3 busybox# --limit           限制展示的数量# --no-trunc    不要截断输出         docker search --filter=stars=3 --no-trunc busybox

下载镜像

docker pull [OPTIONS] NAME[:TAG|@DIGEST]# --all-tags, -a                                  下载所有标记的镜像                                               docker pull debian:jessie# --disable-content-trust                 跳过镜像检查                                                         docker pull myregistry.local:5000/testing/test-image# --platform                                     如果镜像支持多平台,那么就可以指定平台              docker pull --all-tags fedora# --quiet, -q                                     压制详细输出# 默认下载最新版本 latest,下载过程中采用分层下载 (docker image的核心处)# docker.io/library/mysql:latest 是真实地址    docker pull mysql 等价于  docker pull docker.io/library/mysql:latest 

删除镜像

docker rmi [OPTIONS] IMAGE [IMAGE...]# -f, --force      强制删除镜像                                 docker rmi fd484f19954f# --no-prune   不删除未指定标签的父镜像              docker rmi test1:latest

1.3.3 容器命令

我们只有在有了镜像后才可以创建容器,所以需要先使用 docker pull命令下载镜像

新建容器并启动

 docker run [OPTIONS] IMAGE [COMMAND] [ARG...]  # --add-host            指定一个主机 IP映射                                                docker run -it centos /bin/bash # --attach, -a            关联到  STDIN, STDOUT 和 STDERR # --dns                     指定 dns解析 # --name                  指定容器名称,用于区分 # --detach, -d           后台运行容器并且打印容器 ID # -- interactive, -i     保存 STDIN的开启,即使没有设置 --attach # --isolation             容器隔离 # --link                     添加到另一个容器的链接 # --publish, -p         发布指定容器端口           -p 主机端口:容器端口,          -p 容器端口,             -p ip:主机端口:容器端口 # --publish-all, -P     随机发布端口 

实际的运行步骤:

列出所有运行中的容器

 docker ps [OPTIONS]# --all, -a                 展示所有的容器,默认只展示正在运行中的容器# --filter, -f              依据条件,过滤输出结果# --format               格式化输出结果# --last, -n               展示 n个上次创建的容器# --latest, -l             展示最新创建的容器# --no-trunc           不截断输出

退出容器

exit   # 容器停止并退出Ctrl + p + q # 容器不停止退出

删除容器

docker rm [OPTIONS] CONTAINER [CONTAINER...]# --force, -f                强制删除正在运行的容器(采用 SIGKILL)              docker rm --force redis# --link, -l                   移除指定的链接                                                     docker rm --link /webapp/redis# --volumes, -v          删除与容器关联的匿名卷                                        docker rm $(docker ps --filter status=exited -q)

启动和停止容器的操作

docker start [OPTIONS] CONTAINER [CONTAINER...]                      # 启动容器docker restart [OPTIONS] CONTAINER [CONTAINER...]                   # 重启容器docker stop [OPTIONS] CONTAINER [CONTAINER...]                       # 停止当前正在运行的容器docker kill [OPTIONS] CONTAINER [CONTAINER...]                          # 强行停止当前正在运行的容器

1.3.4 常用的其他命令

后台启动

docker run -d 镜像名称

存在问题:

docker run -d centos命令执行后,容器自动停止了。因为 docker容器在后台运行,必须要有一个前台进程。

docker发现没有前台应用就会自动停止

查看日志

 docker logs [OPTIONS] CONTAINER# --details                 展示额外的日志细节# --follow, -f             跟随日志输出# --since                   从什么时候开始输出日志# --timestamp, -t      展示时间# --tail, -n                 从日志末尾展示行数# --until                    展示某个时间点前的日志

查看容器中的进程信息

docker top CONTAINER [ps OPTIONS]

查看镜像的元数据

docker inspect [OPTIONS] NAME|ID [NAME|ID...]# --format, -f           格式化输出                docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $INSTANCE_ID# --size, -s                如果类型是容器的话,就展示所有文件的大小# --type                   返回 JSON作为指定的格式

进入当前正在运行的容器

docker exec [OPTIONS] CONTAINER COMMAND [ARG...] # 进入容器后开启一个新的终端,可以进行操作(常用)# --interactive , -i                      保持 STDIN开启# --detach, -d                            在后台运行容器# --tty, -t                                   设置一个伪TTY# --env, -e                                 设置环境变量#  --user, -u                               设置用户名或 用户 ID# --workdir, -w                          设置容器内的工作目录# eg: docker exec -d ubuntu_bash touch /tmp/execWorks#       docker exec -it ubuntu_bash bash#      docker exec -it -e VAR=1 ubuntu_bash bash#      docker exec -it ubuntu_bash pwd#      docker exec -it -w /root ubuntu_bash pwd
docker attach [OPTIONS] CONTAINER # 进入容器正在执行的终端,不会启动新的进程# --detach-keys                       复写分离的容器的键序列# --no-stdin                             不链接 STDIN# --sig-proxy                            将所有接收到的信号代理到进程# eg: docker attach topdemo

从容器中拷贝内容到主机

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-docker cp[OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH# --archive, -a                建造模式,拷贝所有的 uid/gid 的信息# --follow-link, -L           永远拷贝源路径下的符号链接

1.4 Docker镜像

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

所有应用都可以直接打包成 docker镜像,然后直接跑起来。

1.4.1 Docker镜像加载原理

UnionFS(联合文件系统)

Union文件系统是一种分层、轻量级且高性能的文件系统,它支持对文件系统的修改作为一次提交来逐层地叠加。同时可以将不同目录挂载到同一个虚拟文件系统下。

Union文件系统是 Docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

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

Docker镜像加载原理

Docker镜像实际上就是由 UnionFS文件系统组成的。

bootfs(boot file system)主要包含 bootloaderkernelbootloader主要是引导加载 kernel,Linux刚启动的时候会加载 bootfs文件系统,在 Docker镜像的最底层是 bootfs。类似典型的 Linex/Unix系统,包含 boot加载器和内核,当 boot加载完成之后整个内核就在内存中了,此时内存的使用权已由 bootfs交给了内核,此时系统也会卸载 bootfs

rootfs(root file system)bootfs之上,包含的就是最典型的 Linux系统中的 /dev, /proc, /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如 Ubuntu, CentOS等。

对于一个精简的 OS,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接使用 Host的 kernel,自己只需要提供 rootfs就可以了。由此可见,对于不同的 Linux发行版本,bootfs是基本一致的,rootfs会有差异,因此不同的发行版可以共用 bootfs

1.4.2 分层理解

Docker镜像采用分层结构,方便实现资源的共享。

多个镜像都从相同的基础镜像构建而来,那么宿主机只需要在磁盘上保留一份基础镜像即可,同时内存中也只需要加载一份基础镜像,这样就可以为所有的容器服务了,而且镜像的每一层都是可以被共享的。

查看镜像分层命令

docker image inspect [OPTIONS] IMAGE [IMAGE...]# --format, -f            格式化输出

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

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

在添加额外的镜像层的同时,镜像始终保持当前的所有镜像组合。

此外 Docker镜像都是只读的,当容器启动的时候,一个新的可写层会被加载到镜像的顶部,这一层就是容器层

1.4.3 提交自己的镜像

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]# --author, -a                  标注作者                           # --change, -c                 将对 dockerfile的简介应用到创建的新的镜像中# --message, -m             提交附带的信息                # --pause, -p                   在提交的过程中暂停容器# eg: docker commit --change='CMD ["apachectl", "-DFOREGROUND"]' -c "EXPOSE 80" c3f279d17e0a  svendowideit/testimage:version4#       docker commit c3f279d17e0a  svendowideit/testimage:version3#       docker commit --change "ENV DEBUG=true" c3f279d17e0a  svendowideit/testimage:version3

1.5 容器数据卷

将 Docker容器中产生的数据同步到本地,实现数据的持久化,即使在容器删除后,也可以保留数据。

容器数据卷技术,就可以实现 目录的挂载,将容器内的目录挂载到宿主机上,实现 容器的持久化和同步操作容器间的数据共享

1.5.1 使用数据卷

使用命令挂载

docker run -v 主机目录:容器目录 # eg:  docker  run  -v `pwd`:`pwd` -i -t  ubuntu pwd#        docker run --read-only -v /icanwrite busybox touch /icanwrite/here#        docker run -t -i -v /var/run/docker.sock:/var/run/docker.sock -v /path/to/static-docker-binary:/usr/bin/docker busybox sh#        docker run -t -i --mount type=bind,src=/data,dst=/data busybox sh

在宿主机中对文件的修改,都会同步到容器中,无论容器是否处于开启状态。

1.5.2 具名挂载和匿名挂载

匿名挂载

docker run -d -P  -v /etc/nginx --name nginx01 nginx# -v后只标识了容器中的目录,没有标识宿主机中的目录# 默认会挂载到 /var/lib/docker/volumes/xxx

具名挂载

docker run -d -P -v /jvming:/etc/nginx --name nginx02 nginxdocker run -d -P -v /jvming:/etc/nginx:ro --name nginx02 nginx3# -v后既标识了容器目录也标识了宿主机目录# 如果此时 /jvming路径没有加 根号,那么也会挂载到 	/var/lib/docker/volumes/jvming下# ro表示只有宿主机能修改,容器对该路径没有写权限# rw表示容器可读可写

1.6 DockerFile

1.6.1 Dockerfile介绍

Dockerfile就是 Docker镜像的构建文件,通过 Dockerfile脚本文件生成镜像。

A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. Using docker build users can create an automated build that executes several command-line instructions in succession.

构建步骤:

  1. 编写一个 dockerfile文件
  2. docker build构建成为一个镜像
  3. docker push发布镜像(dockerhub, 阿里云镜像仓库)

比如 centos

FROM scratchADD centos-8-x86_64.tar.xz /LABEL org.label-schema.schema-version="1.0"  \			org.label-schema.name="CentOS Base Image"  \			org.label-schema.vendor="CentOS"\			org.label-schema.license="GPLv2"\			org.label-schema.build-date="20210915"			CMD ["/bin/bash"]
docker build [OPTIONS] PATH | URL | -# --build-arg                        设置编译时的变量# --cache-from                     作为# --compress                        使用 gzip进行压缩# --file, -f                               Dockerfile的名称(默认是 PATH/Dockerfile)#  --force-rm                         总是移除中间的容器# --iidfile                                将镜像 ID写入文件中# --isolation                           容器的隔离级别# --network                           设置编译运行时的网络模式# --pull                                  总是尝试下载最新的镜像# --rm                                    成功编译后移除中间容器# 

1.6.2 构建 Dockerfile

编写要求:

  1. 每个保留关键字(指令)都必须是大写的
  2. 执行顺序从上到下
  3. # 表示注释
  4. 每一个指令都会创建提交一个新的镜像层,并提交
  5. dockerfile是开发人员编写的,发布项目时需要编写 dockerfile文件

常用指令:

  • FROM:指定基础镜像
  • MAINTAINER:指定维护者的信息,姓名+邮箱
  • RUN:构建时需要运行的命令,会自动执行
  • ADD:构建时需要添加的文件,会自动解压
  • WORKDIR:镜像的工作目录
  • VOLUME:设置挂载卷的位置,挂载主机目录
  • EXPOSE:对外暴露的端口
  • CMD:容器启动后运行的命令,在 docker run命令中额外添加 参数时会覆盖 cmd中的内容
  • ENTRYPOINT:类似 CMD,在 docker run命令中额外添加的参数会追加到 cmd中的内容之后
  • ONBUILD:被继承时触发的指令
  • COPY:类似 ADD,将文件拷贝到镜像中
  • ENV:构建时设置环境变量
# 构建自己的 CENTOS Dockerfile文件FROM centosMAINTAINER oliq<yuanchuziwen@qq.com>ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATHCMD /bin/bash# 使用 docker build命令构建docker build -f mycentos -t mycentos:1.0 .# 测试运行docker run -it --name myos mycentos:1.0
# 构建自己的 tomcat DockerfileFROM centosMAINTAINER oliq<yuanchuziwen@qq.com>COPY readme.txt /usr/local/readme.txtADD jdk-8u11-linux-x64.tar.gz /usr/localADD apache-tomcat-9.0.22.tar.gz /usr/localRUN yum -y install vimENV MYPATH /usr/localWORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk1.8.0_11ENV CLASSPATH .:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/rt.jarENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080CMD $CATALINA_HOME/bin/startup.sh && tail -F $CATALINA_HOME/logs/catalina.out# 构建镜像docker build -t mytomcat # 如果把 dockerfile文件命名为 Dockerfile,那么就可以不用 -f 指定名称,可以自动识别# 测试运行docker run -d -p 9090:8080 --name mycat mytomcat \ 	-v /home/mytomcat/webapps:/usr/local/apache-tomcat-9.0.22/webapps \ 	-v /home/mytomcat/log:/usr/local/apache-tomcat-9.0.22/logs

1.6.3 发布镜像 Dockerhub

  1. 在 Dockerhub上注册自己的账号

  2. 在服务器上登陆

    docker login [OPTIONS] [SERVER]# --password, -p                      密码# --password-stdin                  从标准输入中获取密码# --username. -u                      用户名# 如果想要登陆一个私人的路径,就需要指定服务器的名称           docker login localhost:8080# 使用 STDIN输入密码             cat ~/my_password.txt | docker login --username foo --password-stdin# Docker引擎能本地保存用户的凭据
    
  3. 将镜像发布上去

    docker push [OPTIONS] NAME[:TAG]     # --all-tags, -a                       将所有 tag的镜像都 push上去docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]docker image tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]         # Create a tag TARGET_IMAGE that refers to SOURCE_IMAGEdocker image push [OPTIONS] NAME[:TAG]# eg:   docker container commit c16378f943fe rhel-httpd:latest#        docker image tag rhel-httpd:latest registry-host:5000/myadmin/rhel-httpd:latest#        docker image push registry-host:5000/myadmin/rhel-httpd:latest
    

1.6.4 发布镜像到阿里云

  1. 登陆阿里云

  2. 创建命名空间

  3. 创建镜像仓库

1.7 Docker网络原理

1.7.1 Docker0

宿主机 每启动一个 Docker容器,就会给每个容器都分配一个 IP;

并且安装 Docker后会创建一个 Docker0网卡,采用桥接模式;

并且每一个新的容器的 IP都会注册到宿主机中,采用 evth-pair技术

并且容器之间、容器和宿主机之间也可以相互 ping通,不同容器之间网络连接都通过宿主机的 docker0网卡进行交互

将两个容器的网络进行连接,实现依据容器名的 ping通

docker run -d -P --name tomcat03 --link tomcat02 tomcat # 在两个容器的网络之间创建连接docker exec -it tomcat03 ping tomcat02 # 可以成功

实际是修改了容器中的 /etc/hosts文件内容

1.7.3 自定义网络

网络模式

  • bridge: 桥接
  • null:不配置网络
  • host:和宿主机共享
  • container:容器网络连通

创建网络

docker network create [OPTIONS] NETWORK# --attachable                            开启手动容器连接# --config-from                          从哪里拷贝配置# --config-only                           创建一个只能配置的网络# --driver, -d                               网络驱动(默认是桥接)# --gateway                                设置网关# --ingress                                  创建群路由网状网络# --internal                                 限制对网络的外部访问# --ip-range                                指定容器 ip选择的范围# --ipam-driver                          设置 IP地址管理驱动程序# 	--label                                    设置网络的元信息#eg:  docker run -itd --network=mynet busybox#       docker network create --driver=bridge --subnet=192.168.0.0/16 br0#       docker network create \#         --driver=bridge \#         --subnet=172.28.0.0/16 \#         --ip-range=172.28.5.0/24 \#         --gateway=172.28.5.254 \#         br0#       docker network create -d overlay \#           --subnet=192.168.10.0/25 \#           --subnet=192.168.20.0/25 \#           --gateway=192.168.10.100 \#           --gateway=192.168.20.100 \#           --aux-address="my-router=192.168.10.5" --aux-address="my-switch=192.168.10.6" \#           --aux-address="my-printer=192.168.20.5" --aux-address="my-nas=192.168.20.6" \#           my-multihost-network

使用自定义网络的好处:

  • 不同集群使用不同的网络,保证了集群的安全和健康
docker network connect [OPTIONS] NETWORK CONTAINER# --alias                              为容器添加网络的别名# --driver-opt                     网络驱动配置# --ip                                   IPV4地址# --ip6                                 IPV6地址# --link                                添加对另一个容器的连接# eg:            docker network connect multi-host-network container1#                  docker run -itd --network=multi-host-network busybox#                  docker network connect --ip 10.10.36.122 multi-host-network container2#                  docker network connect --link container1:c1 multi-host-network container2

1.8 IDEA 整合 Docker

  1. 创建 SpringBoot项目

  2. 编写好测试用的 Controller

    /** * @author :OliQ * @date :Created on 2021/9/21 13:56 */@RestControllerpublic class DockerController {    @RequestMapping("/docker")    public String hello() {        return "hello docker";    }}
    
  3. mvn package

  4. IDEA 的插件市场中 下载 Docker plugin

  5. 编写 Dockerfile

    FROM java:8COPY *.jar /app.jarCMD ["--server.port=8080"]EXPOSE 8080ENTRYPOINT ["java", "-jar", "/app.jar"]
    
  6. 将 jar包 和 Dockerfile传到 虚拟机

  7. docker build

  8. docker run

2. 进阶

2.1 Docker Compose

2.1.1 Compose介绍

使用 Docker Compose可以轻松进行高效的容器管理,定义运行多个容器

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.

Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.

Using Compose is basically a three-step process:

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
  3. Run docker compose up and the Docker compose command starts and runs your entire app. You can alternatively run docker-compose up using the docker-compose binary.

ComposeDocker官方的另一个开源项目,需要额外安装

一个 docker-compose.yml示例:

version: "3.9"  # optional since v1.27.0services:  web:    build: .    ports:      - "5000:5000"    volumes:      - .:/code      - logvolume01:/var/log    links:      - redis  redis:    image: redisvolumes:  logvolume01: {}

2.1.2 Compose安装

Docker Compose依赖 Docker Engine,所以实现要保证已经成功安装了本地的或远程的 Docker Engine

  1. 下载当前最新的 Docker Compose

     sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    
  2. 为下载的二进制文件赋予可执行权限

    sudo chmod +x /usr/local/bin/docker-compose
    
  3. 测试安装

    docker-compose --version
    
  4. 如果安装以后该命令无效,也可能是因为路径的问题,可以自己添加一个软连接

    sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose # 比如
    
  5. 如果要卸载 Dcoker Compose

    sudo rm /usr/local/bin/docker-compose  # 如果安装了 curl的话pip uninstall docker-compose                   # 如果安装了 pip的话
    

2.1.3 Compose初体验

https://docs.docker.com/compose/gettingstarted/

2.1.4 yaml文件编写规则

https://docs.docker.com/compose/compose-file/compose-file-v3/

# 版本号version: "3.9" # 服务services:	# 第一个服务	webapp: 		# 对第一个服务的配置		build: . 		ports: 			- "8080:8080"		volumes: 			- .:/code	# 第二个服务	redis:	# 其他配置(网络、全局规则)configs:networks: 

2.1.5 搭建 WordPress博客

https://docs.docker.com/samples/wordpress/

2.2 Docker Swarm

用于集群部署 Docker。多个 Docker节点组成一个网络集群。

2.2.1 搭建集群

  1. 在主节点处执行命令

    docker swarm init --advertise-addr <MANAGER-IP>
    
  2. 在主节点处获取加入Swarm的 token

    docker swarm join-token workerdocker swarm join-token manager
    
  3. 在从节点中或者其他主节点中执行 swarm join

    docker swarm join \  --token  SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \  192.168.99.100:2377
    
  4. 在主节点处查看集群状态

    docker node lsdocker info
    

2.2.2 Raft一致性协议

集群中主节点个数必须大于等于 3个

2.2.3 Swarm弹性机制

在集群状态下,容器视作服务,一个服务可以有多个副本。

docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]# eg:     docker service create --name redis redis:3.0.6#           docker service create --mode global --name redis2 redis:3.0.6#          docker service  create \# 				--with-registry-auth \#  				--name my_service \#  				registry.example.com/acme/my_image:latestdocker service update [OPTIONS] SERVICE# eg:         docker service update \#    				--mount-add type=volume,source=other-volume,target=/somewhere-else \ #   				myservice  #              docker service update --mount-rm /somewhere myservice   docker service scale SERVICE=REPLICAS [SERVICE=REPLICAS...] # eg:               docker service scale frontend=50
posted @ 2021-09-21 14:14  小么VinVin  阅读(47)  评论(0编辑  收藏  举报