Docker 学习笔记

感谢狂神的分享。附上B站视频链接。

https://www.bilibili.com/video/BV1og4y1q7M4?from=search&seid=9225650362300658796&spm_id_from=333.337.0.0

目录

  • Docker 学习笔记
    • Docker概述
      • (1) 基本介绍
      • (2) 应用场景
      • (3) Docker 的优势
      • (4)虚拟化技术和容器化技术
    • Docker安装
      • Docker的基本组成
      • 安装
      • 阿里云镜像加速
      • Docker 运行流程图
      • 底层原理
      • Docker常用命令
        • 基础命令
        • 镜像命令
          • docker images 查看本地主机的所有镜像
          • docker search 搜索镜像
          • docker pull 镜像名[:tag] 下载镜像
          • 指定版本下载
          • **docker rmi** 删除镜像
        • 容器命令
          • 新建容器并启动
          • 进入容器
          • 退出容器
          • 列出运行过的容器
          • 删除容器
          • 启动和停止容器
        • 其他命令
          • **后台启动容器**
          • **查看容器中进程信息**
          • **查看镜像元数据**
          • **进入当前正在运行的容器**
          • 从容器内拷贝文件到主机上
        • 命令小结
    • 作业练习
      • Docker 安装 nginx
      • Docker 安装tomcat
      • Docker 部署 es+kibana
    • 图形化管理工具Portaniner安装
    • Docker镜像详解
      • 镜像是什么?
      • Docker镜像加载原理
      • 分层理解
      • 提交镜像
    • 容器数据卷
      • 什么是容器数据卷
      • 使用数据卷
      • 实战:安装Mysql
      • 具名和匿名挂载
      • 初识Dockerfile
      • 数据卷容器
    • Dockerfile
      • DockerFile构建过程
      • DockerFile的指令
        • Dockerfile示例
      • 实战测试
      • 实战:Tomcat镜像
      • 发布自己的镜像
    • Docker网络
      • 理解docker0
      • 小结:
      • --link
      • 自定义网络
      • 网络连通
      • 实战:部署Redis集群
    • Spirngboot微服务打包Docker镜像
    • Docker Compose
      • 简介
      • 安装
      • 初体验入门
        • 开始使用 Docker Compose
          • 先决条件
          • 第 1 步:设置
          • 第 2 步:创建 Dockerfile
          • 第 3 步:在 Compose 文件中定义服务
          • 第 4 步:使用 Compose 构建并运行您的应用程序
          • 第 5 步:编辑 Compose 文件以添加绑定挂载
          • 第 6 步:使用 Compose 重新构建并运行应用程序
          • 第 7 步:更新应用程序
          • 第 8 步:尝试其他一些命令
      • 小结
      • docker-compose.yaml 规则
    • 实战开源项目-WordPress
      • 快速入门:撰写和 WordPress
        • 定义项目
        • 构建项目
        • 在网络浏览器中打开 WordPress
        • 关闭和清理
      • 实战微服务
    • 小结
    • Docker Swarm
      • 节点如何工作
        • 管理节点
        • 工作节点
        • 换个角色
      • Service
        • serices、tasks、containers
        • swarm 接收服务并且调度任务给 worker 节点manager:
        • 服务副本和全局服务
      • 搭建集群
      • 实战: 创建 nginx 服务、动态扩展服务、动态更新服务
      • 概念总结
        • swarm
        • Node
        • Service
        • Task
      • 网络
      • 小结
    • Docker stack
      • 介绍:
    • Docker Secret
      • 什么是Docker Secret
      • Docker Secret的创建与使用
      • 实战 mysql
      • Secret在Stack中的使用
    • Docker Config
      • 基本命令
      • 使用
    • CI/CD之Jenkins (流水线)
      • CI - 持续集成
      • CD // 持续交付
    • CD与DevOps关系
    • 写在最后

Docker概述

(1) 基本介绍

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。官网:https://docs.docker.com/

(2) 应用场景

  • Web 应用的自动化打包和发布。

  • 自动化测试和持续集成、发布。

  • 在服务型环境中部署和调整数据库或其他的后台应用。

  • 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。

(3) Docker 的优势

Docker 是一个用于开发,交付和运行应用程序的开放平台。Docker 使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助 Docker,您可以与管理应用程序相同的方式来管理基础架构。通过利用 Docker 的方法来快速交付,测试和部署代码,您可以大大减少编写代码和在生产环境中运行代码之间的延迟。

1、快速,一致地交付您的应用程序。Docker 允许开发人员使用您提供的应用程序或服务的本地容器在标准化环境中工作,从而简化了开发的生命周期。

容器非常适合持续集成和持续交付(CI / CD)工作流程,请考虑以下示例方案:

您的开发人员在本地编写代码,并使用 Docker 容器与同事共享他们的工作。
他们使用 Docker 将其应用程序推送到测试环境中,并执行自动或手动测试。
当开发人员发现错误时,他们可以在开发环境中对其进行修复,然后将其重新部署到测试环境中,以进行测试和验证。
测试完成后,将修补程序推送给生产环境,就像将更新的镜像推送到生产环境一样简单。

2、响应式部署和扩展
Docker 是基于容器的平台,允许高度可移植的工作负载。Docker 容器可以在开发人员的本机上,数据中心的物理或虚拟机上,云服务上或混合环境中运行。

Docker 的可移植性和轻量级的特性,还可以使您轻松地完成动态管理的工作负担,并根据业务需求指示,实时扩展或拆除应用程序和服务。

3、在同一硬件上运行更多工作负载
Docker 轻巧快速。它为基于虚拟机管理程序的虚拟机提供了可行、经济、高效的替代方案,因此您可以利用更多的计算能力来实现业务目标。Docker 非常适合于高密度环境以及中小型部署,而您可以用更少的资源做更多的事情。

(4)虚拟化技术和容器化技术

虚拟化技术特点:1.资源占用多 2.冗余步骤多 3.启动很慢

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

比较Docker和虚拟机的不同:

1.传统虚拟机,虚拟出硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件。

2.Docker容器内的应用直接运行在宿主机的内核,容器是没有自己的内核的,也没有虚拟硬件。

3.每个容器都是相互隔离的,每个容器都有属于自己的文件系统,互不影响。

容器化带来的好处:

Docker安装

Docker的基本组成

Docker的基本组成图如下:

说明:

安装

Install on CentOS

#安装gcc相关环境
yum -y install gcc yum-y install gcc-c++#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 http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #更新yum软件包索引
yum makecache fast#4、安装  docker-ce 社区版
yum install -y docker-ce docker-ce-cli containerd.io#5、启动
systemctl start docker#6、检查版本信息
docker version#7、hello-world
docker run hello-world#8、查看镜像
docker images#学会了安装,了解一下卸载。 卸载依赖 删除文件夹yum remove docker-ce docker-ce-cli containerd.iorm -rf /var/lib/dockerrm -rf /var/lib/containerd

如果不行,手动删除 https://www.cnblogs.com/kingsonfu/p/11582495.html

阿里云镜像加速

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

Docker 运行流程图

底层原理

Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socker从客户端访问!Docker Server接收到Docker-Client的指令,就会执行这个指令!

Docker为什么比VM Ware快?

1、Docker比虚拟机更少的抽象层

2、docker利用宿主机的内核,VM需要的是Guest OS

Docker新建一个容器的时候,不需要像虚拟机一样重新加载一个操作系统内核,直接利用宿主机的操作系统,而虚拟机是需要加载Guest OS。

Docker常用命令

基础命令

docker version          #查看docker的版本信息
docker info             #查看docker的系统信息,包括镜像和容器的数量
docker 命令 --help       #帮助命令(可查看可选的参数)
docker COMMAND --help

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

镜像命令

docker images 查看本地主机的所有镜像
[root@wangjingkai lib]#  docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    feb5d9fea6a5   5 months ago   13.3kB#解释:
1.REPOSITORY  镜像的仓库源
2.TAG  镜像的标签
3.IMAGE ID 镜像的id
4.CREATED 镜像的创建时间
5.SIZE 镜像的大小
# 可选参数
-a/--all 列出所有镜像
-q/--quiet 只显示镜像的id
docker search 搜索镜像

#可选参数Search the Docker Hub for imagesOptions:-f, --filter filter   Filter output based on conditions provided--format string   Pretty-print search using a Go template--limit int       Max number of search results (default 25)--no-trunc        Don't truncate output#搜索收藏数大于3000的镜像
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   10308     [OK]
mariadb   MariaDB is a community-developed fordockerk of MyS…   3819      [OK]
docker pull 镜像名[:tag] 下载镜像
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker pull mysql
Using default tag: latest            #如果不写tag默认就是latest
latest: Pulling from library/mysql
6ec7b7d162b2: Pull complete          #分层下载,docker image的核心-联合文件系统
fedd960d3481: Pull complete
7ab947313861: Pull complete
64f92f19e638: Pull complete
3e80b17bff96: Pull complete
014e976799f9: Pull complete
59ae84fee1b3: Pull complete
ffe10de703ea: Pull complete
657af6d90c83: Pull complete
98bfb480322c: Pull complete
6aa3859c4789: Pull complete
1ed875d851ef: Pull complete
Digest: sha256:78800e6d3f1b230e35275145e657b82c3fb02a27b2d8e76aac2f5e90c1c30873 #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest  #下载来源的真实地址  #docker pull mysql等价于docker pull docker.io/library/mysql:latest
指定版本下载
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
6ec7b7d162b2: Already exists
fedd960d3481: Already exists
7ab947313861: Already exists
64f92f19e638: Already exists
3e80b17bff96: Already exists
014e976799f9: Already exists
59ae84fee1b3: Already exists
7d1da2a18e2e: Pull complete
301a28b700b9: Pull complete
529dc8dbeaf3: Pull complete
bc9d021dc13f: Pull complete
Digest: sha256:c3a567d3e3ad8b05dfce401ed08f0f6bf3f3b64cc17694979d5f2e5d78e10173
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
docker rmi 删除镜像
#1.删除指定的镜像id
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  镜像id
#2.删除多个镜像id
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  镜像id 镜像id 镜像id
#3.删除全部的镜像id
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  $(docker images -aq)

容器命令

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

docker pull centos
新建容器并启动
docker run [可选参数] image#参数说明
--name="名字"           指定容器名字
-d                     后台方式运行
-it                    使用交互方式运行,进入容器查看内容
-p                     指定容器的端口
(
-p ip:主机端口:容器端口  配置主机端口映射到容器端口
-p 主机端口:容器端口
-p 容器端口
)
-P                     随机指定端口(大写的P)
进入容器
[root@wangjingkai ~]# docker run -it centos /bin/bash
[root@1f90b860e9a0 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
退出容器
#exit 停止并退出容器(后台方式运行则仅退出)
#Ctrl+P+Q  不停止容器退出  大写需要打开
[root@wangjingkai ~]# docker run -it centos /bin/bash
[root@1f90b860e9a0 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@1f90b860e9a0 /]# exit
exit
[root@wangjingkai ~]# docker run -it centos /bin/bash
[root@07a8ecf21ce3 /]# [root@wangjingkai ~]# docker run -it centos /bin/bash
列出运行过的容器
#docker ps # 列出当前正在运行的容器
-a   # 列出所有容器的运行记录
-n=? # 显示最近创建的n个容器
-q   # 只显示容器的编号[root@wangjingkai ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED              STATUS              PORTS     NAMES
07a8ecf21ce3   centos    "/bin/bash"   About a minute ago   Up About a minute             sweet_almeida
[root@wangjingkai ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED              STATUS                          PORTS     NAMES
c9c60a05d726   centos    "/bin/bash"   42 seconds ago       Exited (0) 39 seconds ago                 strange_bouman
07a8ecf21ce3   centos    "/bin/bash"   About a minute ago   Up About a minute                         sweet_almeida
1f90b860e9a0   centos    "/bin/bash"   2 minutes ago        Exited (0) About a minute ago             xenodochial_robinson
31d11c1fb31e   centos    "/bin/bash"   6 minutes ago        Exited (0) 5 minutes ago                  nice_leavitt
删除容器
docker rm 容器id                 #删除指定的容器,不能删除正在运行的容器,强制删除使用 rm -f
docker rm -f $(docker ps -aq)   #删除所有的容器
docker ps -a -q|xargs docker rm #删除所有的容器
启动和停止容器
docker start 容器id          #启动容器
docker restart 容器id        #重启容器
docker stop 容器id           #停止当前运行的容器
docker kill 容器id           #强制停止当前容器

其他命令

后台启动容器
#命令 docker run -d 镜像名#问题 docker ps,发现 centos 停止了
#常见的坑:: docker容器使用后台运行,就必须要有要一个前台进程,doqker发现没有应用,就会自动停止[root@wangjingkai ~]# docker run -d centos
b570968cad70ce6d75af86585efa9697c16beac62423437b9917b04b4b915eda
[root@wangjingkai ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES#编写shell脚本循环执行,使得centos容器保持运行状态
[root@wangjingkai ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
centos       latest    5d0da3dc9764   5 months ago   231MB[root@wangjingkai ~]# docker run -d centos /bin/sh -c "while true;do echo wangjingkai;sleep 1;done;"
d9c1a0d0fa372fd2eec14a0fef629cc017791776d873d060850468b6ab414115
[root@wangjingkai ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
d9c1a0d0fa37   centos    "/bin/sh -c 'while t…"   3 seconds ago   Up 3 seconds             competent_leavitt#显示日志
-t #时间戳
-f #跟随最近的日志打印
--tail number #要显示的行数 最后[number]行[root@wangjingkai ~]# docker logs -tf --tail 10 d9c1a0d0fa37
2022-03-09T08:10:32.877583150Z wangjingkai
2022-03-09T08:10:33.880475447Z wangjingkai
2022-03-09T08:10:34.883497238Z wangjingkai
2022-03-09T08:10:35.886207215Z wangjingkai
2022-03-09T08:10:36.889473108Z wangjingkai
2022-03-09T08:10:37.892314077Z wangjingkai
2022-03-09T08:10:38.895312541Z wangjingkai
2022-03-09T08:10:39.898172307Z wangjingkai
2022-03-09T08:10:40.901211128Z wangjingkai
2022-03-09T08:10:41.904595609Z wangjingkai
2022-03-09T08:10:42.907655169Z wangjingkai
2022-03-09T08:10:43.910632377Z wangjingkai
查看容器中进程信息
#命令 docker top 容器id
[root@wangjingkai ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
d9c1a0d0fa37   centos    "/bin/sh -c 'while t…"   7 minutes ago   Up 7 minutes             competent_leavitt
#UID 用户id  PID  进程id  PPID 父进程ID
[root@wangjingkai ~]# docker top d9c1a0d0fa37
UID                 PID                 PPID                C                   STIME
root                8189                8171                0                   16:09
root                9120                8189                0                   16:17
查看镜像元数据
#命令 dokcer inspect 容器id#测试
[root@wangjingkai ~]# docker inspect d9c1a0d0fa37
[{"Id": "d9c1a0d0fa372fd2eec14a0fef629cc017791776d873d060850468b6ab414115","Created": "2022-03-09T08:09:51.388191458Z","Path": "/bin/sh","Args": ["-c","while true;do echo wangjingkai;sleep 1;done;"],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 8189,"ExitCode": 0,"Error": "","StartedAt": "2022-03-09T08:09:51.762065224Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6","ResolvConfPath": "/var/lib/docker/containers/d9c1a0d0fa372fd2eec14a0fef629cc017791776d873d060850468b6ab414115/resolv.conf","HostnamePath": "/var/lib/docker/containers/d9c1a0d0fa372fd2eec14a0fef629cc017791776d873d060850468b6ab414115/hostname","HostsPath": "/var/lib/docker/containers/d9c1a0d0fa372fd2eec14a0fef629cc017791776d873d060850468b6ab414115/hosts","LogPath": "/var/lib/docker/containers/d9c1a0d0fa372fd2eec14a0fef629cc017791776d873d060850468b6ab414115/d9c1a0d0fa372fd2eec14a0fef629cc017791776d873d060850468b6ab414115-json.log","Name": "/competent_leavitt","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "default","PortBindings": {},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"CapAdd": null,"CapDrop": null,"CgroupnsMode": "host","Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "private","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsernsMode": "","ShmSize": 67108864,"Runtime": "runc","ConsoleSize": [0,0],"Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": null,"BlkioDeviceWriteBps": null,"BlkioDeviceReadIOps": null,"BlkioDeviceWriteIOps": null,"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"KernelMemory": 0,"KernelMemoryTCP": 0,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": null,"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/3bb0b75b11c836eec81100afd5e543763bea131e37b7b270494413e1c0812c54-init/diff:/var/lib/docker/overlay2/b8f39ac06260a61c2029e005d14540939852fa7b95ff70bb20637375edd30060/diff","MergedDir": "/var/lib/docker/overlay2/3bb0b75b11c836eec81100afd5e543763bea131e37b7b270494413e1c0812c54/merged","UpperDir": "/var/lib/docker/overlay2/3bb0b75b11c836eec81100afd5e543763bea131e37b7b270494413e1c0812c54/diff","WorkDir": "/var/lib/docker/overlay2/3bb0b75b11c836eec81100afd5e543763bea131e37b7b270494413e1c0812c54/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "d9c1a0d0fa37","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/sh","-c","while true;do echo wangjingkai;sleep 1;done;"],"Image": "centos","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {"org.label-schema.build-date": "20210915","org.label-schema.license": "GPLv2","org.label-schema.name": "CentOS Base Image","org.label-schema.schema-version": "1.0","org.label-schema.vendor": "CentOS"}},"NetworkSettings": {"Bridge": "","SandboxID": "2e2eb59de84883f4e7967b6b4e61921bba9f2774280b28acf1872f7942384795","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/2e2eb59de848","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "6f38e9d756041c8f5c4cbd70e7c81753831e78c2525f2b953f3bc66c0225e46f","Gateway": "172.18.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.18.0.2","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:12:00:02","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "7f9e905853e256d73202907a925d8057bd9279cab2c98a973f27badba252c1d1","EndpointID": "6f38e9d756041c8f5c4cbd70e7c81753831e78c2525f2b953f3bc66c0225e46f","Gateway": "172.18.0.1","IPAddress": "172.18.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:12:00:02","DriverOpts": null}}}}
]
进入当前正在运行的容器
#我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置。#命令
#方式1
docker exec -it 容器id bashShell
[root@wangjingkai ~]# docker exec -it d9c1a0d0fa37 /bin/bash
[root@d9c1a0d0fa37 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var#方式2
docker attch 容器id
[root@wangjingkai ~]# docker attach d9c1a0d0fa37#docker exec 进入容器后开启一个新的终端,可以在里面操作
#docker attach  进入容器正在执行的终端,不会启动新的进程。
从容器内拷贝文件到主机上
docker cp 容器id: 容器内路径   目的的主机路径#查看当前主机目录下的文件
[root@wangjingkai home]# ls
admin  apache-tomcat-9.0.52  hilde  swap  wjk
[root@wangjingkai home]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@wangjingkai home]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                       PORTS     NAMES
fece35d969e5   centos    "/bin/bash"   5 minutes ago   Exited (127) 3 minutes ago             nice_carver
[root@wangjingkai home]# docker start fece35d969e5
fece35d969e5
[root@wangjingkai home]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
fece35d969e5   centos    "/bin/bash"   5 minutes ago   Up 4 seconds             nice_carver#进入容器内部
[root@wangjingkai home]# docker attach fece35d969e5
[root@fece35d969e5 /]# cd /home
[root@fece35d969e5 home]# ls
test.java
#在容器内部新建一个文件
[root@fece35d969e5 home]# touch wang.java
[root@fece35d969e5 home]# exit
exit
[root@wangjingkai home]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@wangjingkai home]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                      PORTS     NAMES
fece35d969e5   centos    "/bin/bash"   6 minutes ago   Exited (0) 13 seconds ago             nice_carver
#从容器内拷贝文件到主机上
[root@wangjingkai home]# docker cp fece35d969e5:/home/wang.java /home
[root@wangjingkai home]# ls
admin  apache-tomcat-9.0.52  hilde  swap  wang.java  wjk#拷贝是一个手动过程,未来我们使用 -v 卷 的技术,可以实现 自动同步。

命令小结

attach    Attach to a running container  #当前shell下attach连接指定运行镜像
build     Build an image from a Dockerfile  #通过Dockerfile定制镜像
commit    Create a new image from a container's changes  #提交当前容器为新的镜像
cp    Copy files/folders from a container to a HOSTDIR or to STDOUT  #从容器中拷贝指定文件或者目录到宿主机中
create    Create a new container  #创建一个新的容器,同run 但不启动容器
diff    Inspect changes on a container's filesystem  #查看docker容器变化
events    Get real time events from the server#从docker服务获取容器实时事件
exec    Run a command in a running container#在已存在的容器上运行命令
export    Export a container's filesystem as a tar archive  #导出容器的内容流作为一个tar归档文件(对应import)
history    Show the history of an image  #展示一个镜像形成历史
images    List images  #列出系统当前镜像
import    Import the contents from a tarball to create a filesystem image  #从tar包中的内容创建一个新的文件系统映像(对应export)
info    Display system-wide information  #显示系统相关信息
inspect    Return low-level information on a container or image  #查看容器详细信息
kill    Kill a running container  #kill指定docker容器
load    Load an image from a tar archive or STDIN  #从一个tar包中加载一个镜像(对应save)
login    Register or log in to a Docker registry#注册或者登陆一个docker源服务器
logout    Log out from a Docker registry  #从当前Docker registry退出
logs    Fetch the logs of a container  #输出当前容器日志信息
pause    Pause all processes within a container#暂停容器
port    List port mappings or a specific mapping for the CONTAINER  #查看映射端口对应的容器内部源端口
ps    List containers  #列出容器列表
pull    Pull an image or a repository from a registry  #从docker镜像源服务器拉取指定镜像或者库镜像
push    Push an image or a repository to a registry  #推送指定镜像或者库镜像至docker源服务器
rename    Rename a container  #重命名容器
restart    Restart a running container  #重启运行的容器
rm    Remove one or more containers  #移除一个或者多个容器
rmi    Remove one or more images  #移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
run    Run a command in a new container  #创建一个新的容器并运行一个命令
save    Save an image(s) to a tar archive#保存一个镜像为一个tar包(对应load)
search    Search the Docker Hub for images  #在docker
hub中搜索镜像
start    Start one or more stopped containers#启动容器
stats    Display a live stream of container(s) resource usage statistics  #统计容器使用资源
stop    Stop a running container  #停止容器
tag         Tag an image into a repository  #给源中镜像打标签
top       Display the running processes of a container #查看容器中运行的进程信息
unpause    Unpause all processes within a container  #取消暂停容器
version    Show the Docker version information#查看容器版本号
wait         Block until a container stops, then print its exit code  #截取容器停止时的退出状态值

作业练习

Docker 安装 nginx

#1、搜索镜像
docker search nginx
#2、拉取镜像
docker pull nginx
#3、启动
# -d 后台运行 --name 起名   -p 3344:80 将宿主机的端口3334映射到该容器的80端口
docker run -d --name nginx01 -p 3344:80 nginx
#测试
[root@wangjingkai curl-7.56.1]# curl localhost:3344
<!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>
[root@wangjingkai curl-7.56.1]# 

注意:如果提示-bash: curl: command not found

就是没安装curl :解决方案 安装即可。

csdn推荐 :https://blog.csdn.net/sqlquan/article/details/106105065?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3.pc_relevant_antiscan_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3.pc_relevant_antiscan_v2&utm_relevant_index=6

小细节:我是通过地址下载到本地电脑上,xshell,rz 上传到服务器里,在进行安装的.注意要进入目录执行 ./ 命令。

端口暴露的概念

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

Docker 安装tomcat

#1、拉取 tomcat
docker pull tomcat#2、启动运行
docker run -d -p 3355:8080 --name tomcat01 tomcat #3、测试访问没问题,但是没有页面
#发现问题,1、linux命令少了 2、webpps目录为空,因为阿里云镜像的缘故,它默认是最小的镜像,所有不必要的都会被剔除掉,保证最小的可运行环境。
#解决办法:把webapps.dist 里的文件 复制到 webapps 下cp -r webapps.dist/* webapps

Docker 部署 es+kibana

添加 ’-e ES_JAVA_OPTS=“-Xms128m -Xmx512m” ‘ 配置ElasticSearch的虚拟机占用的内存大小。

$ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms128m -Xmx512m" elasticsearch:7.6.2

图形化管理工具Portaniner安装

Portaniner是Docker的图形化管理工具,类似的工具还有Rancher(CI/CD再用)

下载运行Portaniner镜像并运行,设置本机映射端口为8088

[root@wangjingkai ~]# docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

Docker镜像详解

镜像是什么?

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

Docker镜像加载原理

分层理解

提交镜像

使用docker commit 命令提交容器成为一个新的版本docker commit -m=“提交的描述信息”  -a="作者" 容器id 目标镜像名:[TAG]

测试

#1、启动一个默认的tomcat
[root@wangjingkai ~]# docker run -d -p 8080:8080 --name tomcat02 tomcat
#2、发现这个默认的tomcat是没有webapps应用,镜像的原因,官方的镜像默认 webapps下面是没有文件的!#3、我自己拷贝进去了基本的文件
[root@wangjingkai ~]# docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED              STATUS              PORTS                    NAMES
05129a70a3a2   tomcat                "catalina.sh run"        About a minute ago   Up About a minute   0.0.0.0:8080->8080/tcp   tomcat02
8975a1f21c6e   portainer/portainer   "/portainer"             40 minutes ago       Up 40 minutes       0.0.0.0:8088->9000/tcp   bold_feynman
34d94a481c82   nginx                 "/docker-entrypoint.…"   5 hours ago          Up 5 hours          0.0.0.0:3344->80/tcp     nginx01
[root@wangjingkai ~]# docker exec -it 05129a70a3a2 /bin/bash
root@05129a70a3a2:/usr/local/tomcat# ls
BUILDING.txt     LICENSE  README.md  RUNNING.txt  conf  logs        temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin          lib   native-jni-lib  webapps  work
root@05129a70a3a2:/usr/local/tomcat# cp -r webapps.dist/* webapps#4、将我们操作过的容器通过commit提交为一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像
[root@wangjingkai ~]# docker commit -a="wangjingkai" -m"add webapps app" 05129a70a3a2 tomcat02:1.0

容器数据卷

什么是容器数据卷

docker的理念回顾

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

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

使用数据卷

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

#docker run -it -v 主机目录:容器内目录
#测试
[root@wangjingkai ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@d23be47d3c54 /]#

这个时候容器外的/home/ceshi 目录 就和容器内 /home 目录进行了同步绑定,数据会一致。无论是里面还是外面新增数据。都会同步。删除文件也会同步。

测试删除容器,外面的数据是否还在。依旧存在。

实战:安装Mysql

#获取镜像
[root@wangjingkai ceshi]# docker pull mysql:5.7#运行容器,需要做数据挂载!# 安装启动mysq1 ,需要配置密码的,这是要注意点!
#官方配置启动mysqk
#这里是my-secret-pw 是后面docker secret所学
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#启动我们的
-d #后台运行
-p #端口映射
-v #数据卷挂载
-e #环境配置
--name #容器名字
[root@wangjingkai ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql01 mysql:5.7#启动成功之后,用Navicat 测试连接成功。
#navicat -- 通过主机名,账号,密码,端口 连接到服务器。 端口3310 映射 服务器的3306.

具名和匿名挂载

# 匿名挂载
-v 容器内目录
-P 大写的P是随机映射端口
docker run -d -P --name nginx01 -v /etc/nginx nginx#docker volume --help
[root@wangjingkai ~]# docker volume --helpUsage:  docker volume COMMANDManage volumesCommands:create      Create a volumeinspect     Display detailed information on one or more volumesls          List volumesprune       Remove all unused local volumesrm          Remove one or more volumesRun 'docker volume COMMAND --help' for more information on a command.
# 查看所有 volume卷 的情况
[root@wangjingkai ~]# docker volume ls
DRIVER    VOLUME NAME
local     789c3bb335a0bc47e65ccc8c684b495883bf02a4ba1177af4986ca9e90119aef
这种就是匿名挂载。在 -v 的时候只写了内部地址。#具名挂载
#通过 -v 卷名:容器内地址
[root@wangjingkai ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
4ed26bc6b0a782bd66d7898334a72a85bc0c3da88c9e6acfb9d997b61d96c32a
[root@wangjingkai ~]# docker volume ls
DRIVER    VOLUME NAME
local     juming-nginx#查看一下这个卷
[root@wangjingkai ~]# docker volume inspect juming-nginx
[{"CreatedAt": "2022-03-10T16:30:37+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/xxxx

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

初识Dockerfile

Dockerfile 就是用来构建docker镜像的构建文件! 命令脚本

通过这个脚本可以生成镜像,镜像是一层一层,脚本就是一个一个命令,每个命令就是一层。

#编写dockerfile
[root@wangjingkai docker-test-volume]# vim dockerfile1
#编写指令
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end-----"
CMD /bin/bash
#查看
[root@wangjingkai docker-test-volume]# cat dockerfile1
FROM centos
VOLUME ["volume01,"volume02""]  #匿名挂载
CMD echo "----end-----"
CMD /bin/bash
#每个命令就是一层。

#通过自己写的镜像启动容器
[root@wangjingkai docker-test-volume]# docker run -it 4cdffc814ce2 /bin/bash

生成一个镜像,在创建的时候挂载出来。这个就存在一个和外部同步的目录。

查看一下卷挂载的路径

同步成功。

这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像!

假设构建镜像时候没有挂载卷,要手动挂载 -v 卷名:容器内地址

数据卷容器

#  --volumes--from

数据是共享的且是拷贝的概念。

Dockerfile

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

构建步骤:

1、编写一个dockerfile文件

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

3、docker run 运行镜像

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

DockerFile构建过程

DockerFile的指令

#命令都需要大写,但是我看着不舒服,大写不认识单词,小写方便记录。上面是正确的。
#示例
from centos:7
maintainer "wjk302658980@qq.com"
run mkdir -p /usr/local/java && mkdir -p /usr/local/tomcat
add jdk-11.0.11_linux-x64_bin.tar.gz /usr/local/java
workdir /usr/local
volume
expose 8080
cmd ["/usr/local/tomcat/apache-tomcat-9.0.46/bin/catalina.sh","run"]
entrypoint
onbuild
copy
env JAVA_HOME /usr/local/java/jdk-11.0.11/
env PATH $PATH:$JAVA_HOME/bin

Dockerfile示例

# 使用标准openjdk环境
FROM openjdk:latest# dockerfile build 环境变量 按需使用
ARG NAME=test-docker-image
ARG VERSION=0.0.1
ARG PROFILES=test
# 项目打包后的包名
ENV JAR_FILE=test-server-0.0.1-SNAPSHOT.jar
# 项目服务目录
ENV PROJECT_DIR=project
# 服务根目录
ENV ROOT_DIR=/home/testserver#在容器运行时声明一个 volume, 在容器中创建目录
VOLUME $ROOT_DIR
VOLUME /usr/local/src/soft/template# 添加镜像属性
LABEL name=$NAME version=$VERSION email="j1y1p1@hotmail.com"# maven 构建项目 先构建项目jar包,然后用copy或add将jar包导入镜像,是两步操作# 导入 JAR 到镜像中的指定目录
COPY target/$JAR_FILE $ROOT_DIR# Create a script 由于ENTRYPOINT无法使用dockerfile中定义的环境变量
# 所以需要按照指定的环境变量生成运行脚本,并输出到文件,之后ENTRYPOINT运行脚本文件就行了
RUN echo "java -Xms1024m -Xmx1024m -jar $ROOT_DIR/$JAR_FILE --spring.profiles.active=$PROFILES" > /run_module.sh# run 执行命令
ENTRYPOINT ["/bin/bash", "/run_module.sh"]# 指定默认暴露端口, 这样在容器运行时可以知道应该映射哪些端口
EXPOSE 8888

实战测试

创建一个自己的 centos

#1、编写dockerfile文件
FROM centos:7
MAINTAINER wangjingkai<302658980@qq.com>ENV MYPATH /usr/local
WORKDIR $MYPATHRUN yum -y install vim
RUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATH
CMD echo -----end-----
CMD /bin/bash#2、通过这个文件构建镜像
#docker build -f dockerfile路径名 -t 镜像名:[tag]  

原来是centos没有vim编辑,ifconfig

可以列出本例镜像的变更历史

[root@wangjingkai dockerfile]# docker history caa7cc75976e
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
caa7cc75976e   3 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B
7566ced72bd7   3 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B
97dec348839b   3 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B
31ca87252ee3   3 minutes ago   /bin/sh -c #(nop)  EXPOSE 80                    0B
c68fe8901852   3 minutes ago   /bin/sh -c yum -y install net-tools             161MB
b58d71b69792   5 minutes ago   /bin/sh -c yum -y install vim                   216MB
22b78729c30e   7 minutes ago   /bin/sh -c #(nop) WORKDIR /usr/local            0B
2b2cd8bae358   7 minutes ago   /bin/sh -c #(nop)  ENV MYPATH=/usr/local        0B
2ec9c8973b1e   7 minutes ago   /bin/sh -c #(nop)  MAINTAINER wangjingkai<30…   0B
eeb6ee3f44bd   6 months ago    /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>      6 months ago    /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
<missing>      6 months ago    /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4…   204MB

实战:Tomcat镜像

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

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

FROM centos:7
MAINTAINER wangjingkai<302658980@qq.com>COPY readme.txt /usr/local/readme.txtADD jdk-8u241-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.52.tar.gz /usr/local/RUN yum -y install vimENV MYPATH /usr/local
WORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk1.8.0_241
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.52
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.52
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CALATINA_HOME/binEXPOSE 8080CMD /usr/local/apache-tomcat-9.0.52/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.52/bin/logs/catalina.
out

3、构建镜像

#docker build -t diytomcat .    (后面有个点)

4、启动镜像

[root@wangjingkai tomcat]# docker run -d -p 9090:8080 --name wangjingkaitomcat -v /home/wjk/tomcat/test:/usr/local/apache-tomcat-9.0.52/webapps/test -v /home/wjk/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.52/logs diytomcat

5、访问测试

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">  </web-app>

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello wangjingkai</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("---my test web log");
%>
</body>
</html>

发布自己的镜像

上传到dockerhub

1、登陆

[root@wangjingkai ~]# docker login -u  wangjingkaidockerhub
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded
[root@wangjingkai ~]#

2、上传

#docker push (用户名)/镜像名:tag
docker push wangjingkaidockerhub/tomcat:1.0

3、退出

[root@wangjingkai ~]# docker logout

阿里云镜像服务上

1、登陆阿里云

2、容器镜像服务

3、创建命名空间

4、创建镜像仓库

5、操作

  1. 登录阿里云Docker Registry
$ docker login --username=原名陌生哦 registry.cn-hangzhou.aliyuncs.com

用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。

您可以在访问凭证页面修改凭证密码。

  1. 从Registry中拉取镜像
$ docker pull registry.cn-hangzhou.aliyuncs.com/wangjingkai/wangjingkai:[镜像版本号]
  1. 将镜像推送到Registry
$ docker login --username=原名陌生哦 registry.cn-hangzhou.aliyuncs.com
$ docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/wangjingkai/wangjingkai:[镜像版本号]
$ docker push registry.cn-hangzhou.aliyuncs.com/wangjingkai/wangjingkai:[镜像版本号]

请根据实际镜像信息替换示例中的[ImageId]和[镜像版本号]参数。

  1. 选择合适的镜像仓库地址

从ECS推送镜像时,可以选择使用镜像仓库内网地址。推送速度将得到提升并且将不会损耗您的公网流量。

如果您使用的机器位于VPC网络,请使用 registry-vpc.cn-hangzhou.aliyuncs.com 作为Registry的域名登录。

  1. 示例

使用"docker tag"命令重命名镜像,并将它通过专有网络地址推送至Registry。

$ docker imagesREPOSITORY                                                         TAG                 IMAGE ID            CREATED             VIRTUAL SIZEregistry.aliyuncs.com/acs/agent                                    0.7-dfb6816         37bb9c63c8b2        7 days ago          37.89 MB$ docker tag 37bb9c63c8b2 registry-vpc.cn-hangzhou.aliyuncs.com/acs/agent:0.7-dfb6816

使用 “docker push” 命令将该镜像推送至远程。

$ docker push registry-vpc.cn-hangzhou.aliyuncs.com/acs/agent:0.7-dfb6816

小结:

Docker网络

理解docker0

[root@wangjingkai ~]# ip addr
#本机回环地址
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
#阿里云内网地址
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:16:3e:0b:ec:97 brd ff:ff:ff:ff:ff:ffinet 172.17.28.181/18 brd 172.17.63.255 scope global dynamic eth0valid_lft 309500498sec preferred_lft 309500498sec
#docker0 地址
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:ac:04:5a:d5 brd ff:ff:ff:ff:ff:ffinet 172.18.0.1/16 brd 172.18.255.255 scope global docker0valid_lft forever preferred_lft forever

3个网络

#问题:docker是如何处理容器网络访问的?

网络模型图

结论:tomcat01和tomcat02是公用的一个路由器 docker0

所有的容器不指定网络的情况下,都是由docker0路由的。docker会给我们的容器分配一个默认可用的ip 0~255

小结:

Docker 容器里的网络 核心使用了Linux的虚拟化网络技术,在容器内和docker0分布创建了一个虚拟网卡,通过veth-pair进行连接通信。

Docker 中所有的网络接口都是虚拟的。虚拟的转发效率高。(例如 内网传递的速度就特别快。飞秋)

只要容器删除,对应网桥就没了。

–link

思考一个场景,我们编写了一个微服务,database url=ip:,项目不重启,数据库ip换掉了,我们希望名字来进行访问容器?

通过link

自定义网络

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

好处:

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

网络连通

连接一个容器到一个网络

docker network connect mynet tomcat01

实战:部署Redis集群

shell脚本

#创建网卡
docker network create redis --subnet 172.38.0.0/16#通过脚本创建六个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat  << EOF >> /mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done#脚本启动
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \-v /mydata/redis/node-${port}/data:/data \-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf#启动一个redis
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \-v /mydata/redis/node-1/data:/data \-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf#启动第二个redis
docker run -p 6372:6379 -p 16372:16379 --name redis-2 \-v /mydata/redis/node-2/data:/data \-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf#启动第三个redis
docker run -p 6373:6379 -p 16373:16379 --name redis-3 \-v /mydata/redis/node-3/data:/data \-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#启动第四个redis
docker run -p 6374:6379 -p 16374:16379 --name redis-4 \-v /mydata/redis/node-4/data:/data \-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf#启动第五个redis
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \-v /mydata/redis/node-5/data:/data \-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf#启动第六个redis
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \-v /mydata/redis/node-6/data:/data \-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf#创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.
15:6379 172.38.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: 4c5124a0384f5dcc16fc2c46d4d898a00eac2af1 172.38.0.11:6379slots:[0-5460] (5461 slots) master
M: 0a901487d8ff15de9e41706fbd5bb0bd99e9b052 172.38.0.12:6379slots:[5461-10922] (5462 slots) master
M: cf80266d6a94f9f200ad0e75824a36e7d00ab1f0 172.38.0.13:6379slots:[10923-16383] (5461 slots) master
S: c419506c3dfd89bb3c10c9a4e71798c6928841d9 172.38.0.14:6379replicates cf80266d6a94f9f200ad0e75824a36e7d00ab1f0
S: b4607c2b19afd41f034ab49dac4dd7826d32cd34 172.38.0.15:6379replicates 4c5124a0384f5dcc16fc2c46d4d898a00eac2af1
S: 0a300109789e90a5713f9b453cf6827e573a4d38 172.38.0.16:6379replicates 0a901487d8ff15de9e41706fbd5bb0bd99e9b052
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: 4c5124a0384f5dcc16fc2c46d4d898a00eac2af1 172.38.0.11:6379slots:[0-5460] (5461 slots) master1 additional replica(s)
S: b4607c2b19afd41f034ab49dac4dd7826d32cd34 172.38.0.15:6379slots: (0 slots) slavereplicates 4c5124a0384f5dcc16fc2c46d4d898a00eac2af1
S: c419506c3dfd89bb3c10c9a4e71798c6928841d9 172.38.0.14:6379slots: (0 slots) slavereplicates cf80266d6a94f9f200ad0e75824a36e7d00ab1f0
S: 0a300109789e90a5713f9b453cf6827e573a4d38 172.38.0.16:6379slots: (0 slots) slavereplicates 0a901487d8ff15de9e41706fbd5bb0bd99e9b052
M: cf80266d6a94f9f200ad0e75824a36e7d00ab1f0 172.38.0.13:6379slots:[10923-16383] (5461 slots) master1 additional replica(s)
M: 0a901487d8ff15de9e41706fbd5bb0bd99e9b052 172.38.0.12:6379slots:[5461-10922] (5462 slots) master1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered./data # redis-cli -c
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:174
cluster_stats_messages_pong_sent:175
cluster_stats_messages_sent:349
cluster_stats_messages_ping_received:170
cluster_stats_messages_pong_received:174
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:349
127.0.0.1:6379> cluster nodes
b4607c2b19afd41f034ab49dac4dd7826d32cd34 172.38.0.15:6379@16379 slave 4c5124a0384f5dcc16fc2c46d4d898a00eac2af1 0 1648627924537 5 connected
c419506c3dfd89bb3c10c9a4e71798c6928841d9 172.38.0.14:6379@16379 slave cf80266d6a94f9f200ad0e75824a36e7d00ab1f0 0 1648627923033 4 connected
0a300109789e90a5713f9b453cf6827e573a4d38 172.38.0.16:6379@16379 slave 0a901487d8ff15de9e41706fbd5bb0bd99e9b052 0 1648627924537 6 connected
cf80266d6a94f9f200ad0e75824a36e7d00ab1f0 172.38.0.13:6379@16379 master - 0 1648627924000 3 connected 10923-16383
0a901487d8ff15de9e41706fbd5bb0bd99e9b052 172.38.0.12:6379@16379 master - 0 1648627924035 2 connected 5461-10922
4c5124a0384f5dcc16fc2c46d4d898a00eac2af1 172.38.0.11:6379@16379 myself,master - 0 1648627923000 1 connected 0-5460127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
172.38.0.13:6379> get a
"b"
172.38.0.13:6379> get a
^C
/data # redis-cli -c
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
172.38.0.14:6379> cluster nodes
c419506c3dfd89bb3c10c9a4e71798c6928841d9 172.38.0.14:6379@16379 myself,master - 0 1648628529000 7 connected 10923-16383
4c5124a0384f5dcc16fc2c46d4d898a00eac2af1 172.38.0.11:6379@16379 master - 0 1648628531534 1 connected 0-5460
0a300109789e90a5713f9b453cf6827e573a4d38 172.38.0.16:6379@16379 slave 0a901487d8ff15de9e41706fbd5bb0bd99e9b052 0 1648628530031 6 connected
0a901487d8ff15de9e41706fbd5bb0bd99e9b052 172.38.0.12:6379@16379 master - 0 1648628530532 2 connected 5461-10922
b4607c2b19afd41f034ab49dac4dd7826d32cd34 172.38.0.15:6379@16379 slave 4c5124a0384f5dcc16fc2c46d4d898a00eac2af1 0 1648628530532 5 connected
cf80266d6a94f9f200ad0e75824a36e7d00ab1f0 172.38.0.13:6379@16379 master,fail - 1648628462156 1648628461847 3 connected

Spirngboot微服务打包Docker镜像

1、构建SpringBoot项目

2、打包运行

3、编写Dockerfile

#版本java8
FROM java:8
#把所有的jar复制到app.jar下
COPY *.jar /app.jar
#端口
CMD ["--server.port=8080"]
#暴露8080端口
EXPOSE 8080
#执行脚本命令 java -jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]

4、上传jar和Dockerfile文件到服务器上

5、构建镜像

[root@wangjingkai idea]# docber build -t wangjingkai666 .

6、发布运行

docker run -d -P --name helloDockerfile wangjingkai666 [root@wangjingkai idea]# docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS          PORTS                     NAMES
33aecd9f2feb   wangjingkai666   "java -jar app.jar -…"   21 seconds ago   Up 20 seconds   0.0.0.0:49156->8080/tcp   helloDockerfile
[root@wangjingkai idea]# curl localhost:49156/hello
hello,Dockerfile

Docker Compose

简介

Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。

您可以使用 YAML 文件来配置应用程序的服务

使用一个命令,您可以从您的配置中创建并启动所有服务

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 适用于所有环境:生产、登台、开发、测试以及 CI 工作流程。

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.

使用 Compose 基本上是一个三步过程:

Using Compose is basically a three-step process:

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.

    • 定义你的应用环境通过一个Dockerfile,以便可以在任何地方复制它。
  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
    • 定义构成您的应用程序的服务 通过docker-compose.yml 以便它们可以在隔离环境中一起运行。
    • services 什么服务
    • docker-compose.yml 怎么写
  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.
    • 运行docker compose up,Docker compose 命令启动并运行您的整个应用程序。您也可以docker-compose up使用 docker-compose 二进制文件运行。

狂神的理解

Compose 是Docker官方的开源项目。不在Docker内。需要安装。

Dockerfile 让程序在任何地方运行。 web服务,redis服务、。。。多个容器

一个docker-compose.yml看起来像这样:

nkversion: "3.9"  # optional since v1.27.0
services:web:build: .ports:- "8000:5000"volumes:- .:/code- logvolume01:/var/loglinks:- redisredis:image: redis
volumes:logvolume01: {}

Compose: 重要的概念

  • 服务services , 容器。应用。(web、redis、mysql…)
  • 项目project。 一组关联的容器。

ca

我的理解:

Compose是单机多容器的一键部署解决方案。

安装

1、运行以下命令下载 Docker Compose 的当前稳定版本:

对着官网来。https://docs.docker.com/compose/install/

此时2022-3-30 版本1.29.2

curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose#国内 速度快一些curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

出现报错:

curl: (1) Protocol “https” not supported or disabled in libcurl

错误原因:curl是利用URL语法在命令行方式下工作的开源文件传输工具。默认安装不支持https协议。

因为https协议是加密安全的基于http的协议,需要使用openssl的静态库,所以需要支持https就必须下载openssl。

1、如果已有openssl 找到curl目录下

2、./configure 查看最后的

3、如果为no 则输入下列命令

 ./configure --prefix=/usr/local/curl --with-ssl#重新编译make#安装make install

curl 就可以支持https了。

2、授权:对二进制文件应用可执行权限:

sudo chmod +x /usr/local/bin/docker-compose

3、测试安装

docker-compose --version

初体验入门

官网入门用例:https://docs.docker.com/compose/gettingstarted/

先决条件

开始使用 Docker Compose

预计阅读时间:11分钟

在此页面上,您将构建一个在 Docker Compose 上运行的简单 Python Web 应用程序。该应用程序使用 Flask 框架并在 Redis 中维护一个命中计数器。虽然示例使用 Python,但即使您不熟悉此处演示的概念,也应该可以理解。

先决条件

确保您已经安装了Docker Engine 和Docker Compose。您不需要安装 Python 或 Redis,因为它们都是由 Docker 映像提供的。

第 1 步:设置

定义应用程序依赖项。

  1. 为项目创建一个目录:

    $ mkdir composetest
    $ cd composetest
    
  2. 在项目目录中创建一个名为的文件app.py并将其粘贴到:

    vim app.py
    
    import timeimport redis
    from flask import Flaskapp = Flask(__name__)
    cache = redis.Redis(host='redis', port=6379)def get_hit_count():retries = 5while True:try:return cache.incr('hits')except redis.exceptions.ConnectionError as exc:if retries == 0:raise excretries -= 1time.sleep(0.5)@app.route('/')
    def hello():count = get_hit_count()return 'Hello World! I have been seen {} times.\n'.format(count)
    

    在此示例中,redis是应用程序网络上的 redis 容器的主机名。我们使用 Redis 的默认端口,6379.

    处理瞬态错误

    注意get_hit_count函数的编写方式。如果 redis 服务不可用,这个基本的重试循环让我们可以多次尝试我们的请求。这在应用程序上线时启动时很有用,但如果在应用程序的生命周期内需要随时重新启动 Redis 服务,这也会使我们的应用程序更具弹性。在集群中,这也有助于处理节点之间的瞬时连接中断。

  3. 在您的项目目录中创建另一个名为的文件requirements.txt并将其粘贴到:

    vim `requirements.txt`
    
    flask
    redis
    
第 2 步:创建 Dockerfile

在此步骤中,您将编写一个构建 Docker 映像的 Dockerfile。该映像包含 Python 应用程序所需的所有依赖项,包括 Python 本身。

在您的项目目录中,创建一个名为Dockerfile并粘贴以下内容的文件:

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

这告诉 Docker:

  • 从 Python 3.7 映像开始构建映像。
  • 将工作目录设置为/code.
  • 设置命令使用的环境变量flask
  • 安装 gcc 和其他依赖项
  • 复制requirements.txt并安装 Python 依赖项。
  • 向镜像添加元数据以描述容器正在侦听端口 5000
  • 将项目中的当前目录复制.到镜像中的workdir .
  • 将容器的默认命令设置为flask run.

有关如何编写 Dockerfile 的更多信息,请参阅 Docker 用户指南 和Dockerfile 参考。

第 3 步:在 Compose 文件中定义服务

在您的项目目录中创建一个名为的文件docker-compose.yml并粘贴以下内容:

version: "3.9"
services:web:build: .ports:- "8000:5000"redis:image: "redis:alpine"

这个 Compose 文件定义了两个服务:webredis.

网络服务

该服务使用从当前目录中web构建的图像。Dockerfile然后它将容器和主机绑定到暴露的端口,8000. 此示例服务使用 Flask Web 服务器的默认端口,5000.

Redis 服务

redis服务使用 从 Docker Hub 注册表中提取的公共Redis映像。

第 4 步:使用 Compose 构建并运行您的应用程序
  1. 在您的项目目录中,通过运行docker-compose up.

    $ docker-compose upCreating network "composetest_default" with the default driver
    Creating composetest_web_1 ...
    Creating composetest_redis_1 ...
    Creating composetest_web_1
    Creating composetest_redis_1 ... done
    Attaching to composetest_web_1, composetest_redis_1
    web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
    redis_1  | 1:C 17 Aug 22:11:10.480 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    redis_1  | 1:C 17 Aug 22:11:10.480 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1, just started
    redis_1  | 1:C 17 Aug 22:11:10.480 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
    web_1    |  * Restarting with stat
    redis_1  | 1:M 17 Aug 22:11:10.483 * Running mode=standalone, port=6379.
    redis_1  | 1:M 17 Aug 22:11:10.483 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
    web_1    |  * Debugger is active!
    redis_1  | 1:M 17 Aug 22:11:10.483 # Server initialized
    redis_1  | 1:M 17 Aug 22:11:10.483 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
    web_1    |  * Debugger PIN: 330-787-903
    redis_1  | 1:M 17 Aug 22:11:10.483 * Ready to accept connections
    

    Compose 拉取 Redis 映像,为您的代码构建映像,并启动您定义的服务。在这种情况下,代码在构建时被静态复制到映像中。

    • 默认的服务名:文件名_服务名_num, num表示的是副本数量
  2. 在浏览器中输入 http://localhost:8000/ 以查看正在运行的应用程序。

    如果您在 Linux、Docker Desktop for Mac 或 Docker Desktop for Windows 上本地使用 Docker,那么 Web 应用程序现在应该在您的 Docker 守护程序主机上的端口 8000 上进行侦听。将您的 Web 浏览器指向 http://localhost:8000 以查找Hello World消息。如果这不能解决,您也可以尝试 http://127.0.0.1:8000。

    您应该会在浏览器中看到一条消息:

    Hello World! I have been seen 1 times.
    

  3. 刷新页面。

    数字应该增加。

    Hello World! I have been seen 2 times.
    

  4. 切换到另一个终端窗口,然后键入docker image ls以列出本地图像。

    此时列出图像应返回redisweb

    $ docker image lsREPOSITORY        TAG           IMAGE ID      CREATED        SIZE
    composetest_web   latest        e2c21aa48cc1  4 minutes ago  93.8MB
    python            3.4-alpine    84e6077c7ab6  7 days ago     82.5MB
    redis             alpine        9d8fa9aa0e5b  3 weeks ago    27.5MB
    

    您可以使用docker inspect <tag or id>.

  5. 停止应用程序,方法是docker-compose down 在第二个终端的项目目录中运行,或者在启动应用程序的原始终端中按 CTRL+C。

第 5 步:编辑 Compose 文件以添加绑定挂载

在您的项目目录中编辑docker-compose.yml以添加服务的 绑定挂载web

version: "3.9"
services:web:build: .ports:- "8000:5000"volumes:- .:/codeenvironment:FLASK_ENV: developmentredis:image: "redis:alpine"

volumes密钥将主机上的项目目录(当前目录)挂载到/code容器内,允许您即时修改代码,而无需重建映像。environment键设置 FLASK_ENV环境变量,它告诉flask run在开发模式下运行并在更改时重新加载代码。这种模式应该只在开发中使用。

第 6 步:使用 Compose 重新构建并运行应用程序

在您的项目目录中,键入docker-compose up以使用更新的 Compose 文件构建应用程序,然后运行它。

$ docker-compose upCreating network "composetest_default" with the default driver
Creating composetest_web_1 ...
Creating composetest_redis_1 ...
Creating composetest_web_1
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
...

Hello World再次在 Web 浏览器中检查消息,然后刷新以查看计数增量。

共享文件夹、卷和绑定装载

  • 如果您的项目在Users目录 ( cd ~) 之外,那么您需要共享您正在使用的 Dockerfile 和卷的驱动器或位置。如果您收到运行时错误,指示未找到应用程序文件、卷安装被拒绝或服务无法启动,请尝试启用文件或驱动器共享。C:\Users对于位于(Windows) 或/Users(Mac)之外的项目,卷挂载需要共享驱动器 ,并且对于使用Linux 容器的 Docker Desktop for Windows 上的任何项目都是必需的。有关更多信息,请参阅Docker for Mac 上的文件共享,以及有关如何 管理容器中的数据的一般示例。
  • 如果您在较旧的 Windows 操作系统上使用 Oracle VirtualBox,您可能会遇到此VB 故障单中所述的共享文件夹问题。较新的 Windows 系统满足Docker Desktop for Windows的要求,不需要 VirtualBox。
第 7 步:更新应用程序

由于应用程序代码现在使用卷安装到容器中,因此您可以对其代码进行更改并立即查看更改,而无需重建映像。

更改问候语app.py并保存。例如,将Hello World! 消息更改为Hello from Docker!

return 'Hello from Docker! I have been seen {} times.\n'.format(count)

在浏览器中刷新应用程序。应更新问候语,并且计数器仍应递增。

第 8 步:尝试其他一些命令

如果您想在后台运行您的服务,您可以将-d标志(用于“分离”模式)传递给docker-compose up并用于docker-compose ps查看当前正在运行的内容:

$ docker-compose up -dStarting composetest_redis_1...
Starting composetest_web_1...$ docker-compose psName                      Command               State           Ports
-------------------------------------------------------------------------------------
composetest_redis_1   docker-entrypoint.sh redis ...   Up      6379/tcp
composetest_web_1     flask run                        Up      0.0.0.0:8000->5000/tcp

docker-compose run命令允许您为您的服务运行一次性命令。例如,要查看 web服务可以使用哪些环境变量:

$ docker-compose run web env

请参阅docker-compose --help查看其他可用命令。您还可以为 bash 和 zsh shell 安装命令完成,它还会显示可用的命令。

如果您使用 Compose 开始docker-compose up -d,请在完成后停止您的服务:

$ docker-compose stop

您可以使用命令将所有内容都关闭,完全删除容器down 。传递--volumes也删除 Redis 容器使用的数据卷:

$ docker-compose down --volumes

至此,您已经了解了 Compose 的基本工作原理。

网络规则

多个服务 = 项目(项目中的内容都在同个网络下,可域名访问)

如果在同一个网络下,可以直接通过域名访问


小结

小细节:依赖文件 requirements.txt

Docker镜像 run->容器
DockerFile 构建镜像(服务打包)
docker-compose 启动项目(编排、打包、运行多个服务、环境)
Docker 网络

docker-compose.yaml 规则

官网介绍

# 总共三层
version: '' # 版本
services:  #服务服务1: web# 服务配置images:port:network: depends_on: # 启动依赖(顺序)...服务2: redis...
# 其他配置 网络、卷、全局规则
volumes:
network: 

实战开源项目-WordPress

官网

快速入门:撰写和 WordPress

预计阅读时间:3分钟

您可以使用 Docker Compose 在使用 Docker 容器构建的隔离环境中轻松运行 WordPress。本快速入门指南演示了如何使用 Compose 设置和运行 WordPress。在开始之前,请确保您已 安装 Compose。

定义项目

  1. 创建一个空的项目目录。

    您可以将目录命名为易于记忆的名称。此目录是您的应用程序映像的上下文。该目录应该只包含构建该图像的资源。

    这个项目目录包含一个docker-compose.yml完整的文件,它本身就是一个好的入门 wordpress 项目。

    提示:您可以为此文件使用 a.yml或扩展名。.yaml他们都工作。

  2. 切换到您的项目目录。

    例如,如果您将目录命名为my_wordpress

    $ cd my_wordpress/
    
  3. 创建一个docker-compose.yml用于启动您的 WordPress博客的文件和一个带有卷挂载的单独MySQL实例以实现数据持久性:

    version: "3.9"services:db:image: mysql:5.7volumes:- db_data:/var/lib/mysqlrestart: alwaysenvironment:MYSQL_ROOT_PASSWORD: somewordpressMYSQL_DATABASE: wordpressMYSQL_USER: wordpressMYSQL_PASSWORD: wordpresswordpress:depends_on:- dbimage: wordpress:latestvolumes:- wordpress_data:/var/www/htmlports:- "8000:80"restart: alwaysenvironment:WORDPRESS_DB_HOST: dbWORDPRESS_DB_USER: wordpressWORDPRESS_DB_PASSWORD: wordpressWORDPRESS_DB_NAME: wordpress
    volumes:db_data: {}wordpress_data: {}
    

备注

  • docker 卷db_datawordpress_data持久化 WordPress 对数据库的更新,以及已安装的主题和插件。了解有关 docker 卷的更多信息
  • WordPress Multisite 仅适用于端口80443.

构建项目

现在,docker-compose up -d从您的项目目录运行。

docker-compose up在分离模式下运行,拉取所需的 Docker 映像,并启动 wordpress 和数据库容器,如下例所示。

$ docker-compose up -dCreating network "my_wordpress_default" with the default driver
Pulling db (mysql:5.7)...
5.7: Pulling from library/mysql
efd26ecc9548: Pull complete
a3ed95caeb02: Pull complete
<...>
Digest: sha256:34a0aca88e85f2efa5edff1cea77cf5d3147ad93545dbec99cfe705b03c520de
Status: Downloaded newer image for mysql:5.7
Pulling wordpress (wordpress:latest)...
latest: Pulling from library/wordpress
efd26ecc9548: Already exists
a3ed95caeb02: Pull complete
589a9d9a7c64: Pull complete
<...>
Digest: sha256:ed28506ae44d5def89075fd5c01456610cd6c64006addfe5210b8c675881aff6
Status: Downloaded newer image for wordpress:latest
Creating my_wordpress_db_1
Creating my_wordpress_wordpress_1

注意:WordPress Multisite 仅适用于端口80和/或443. 0.0.0.0如果您收到有关绑定到端口80443 (取决于您指定的端口)的错误消息,则您为 WordPress 配置的端口可能已被其他服务使用。

在网络浏览器中打开 WordPress

至此,WordPress 应该已经在8000你的 Docker Host 的端口上运行了,你可以以 WordPress 管理员的身份完成“著名的五分钟安装”。

注意: WordPress 站点不能立即在端口上可用,8000 因为容器仍在初始化中,可能需要几分钟才能首次加载。

如果您使用的是 Docker Desktop for Mac 或 Docker Desktop for Windows,您可以将 http://localhost其用作 IP 地址,并http://localhost:8000在 Web 浏览器中打开。

关闭和清理

该命令docker-compose down会删除容器和默认网络,但会保留您的 WordPress 数据库。

该命令docker-compose down --volumes删除容器、默认网络和 WordPress 数据库。

实战微服务

  1. 编写微服务

  2. Dockerfile 构建镜像

    FROM java:8
    COPY *.jar /app.jar
    CMD ["--server.port=8080"]
    EXPOSE 8080
    ENTRYPOINT ["java","-jar","/app.jar"]
    
  3. docker-compose.yml 编排项目

    version: '3.3'services:app:build: .image: appdepends_on:- redisports:- "8080:8080"redis:image: "redis:alpine"
  4. docker-compose up 启动运行

小结

  • Docker Compose 是一个开源项目,用来统一编排多个应用的
  • 多个应用=服务->这些应用都会在同一个网络下->可通过域名直接访问
  • 默认的服务名为:文件夹名称_镜像名_副本数量(运行数量)
  • Dockerfile 用于构建镜像,docker-compose.yaml 用于编排项目,同时组装多个应用
  • docker-compose.yaml 文件结构总共三层
    • docker compose版本
    • 服务
    • 其他配置
  • 如何使用:
    1. 准备好项目并编写 Dockerfile(可省略,如果直接使用仓库镜像的话)
    2. 编写docker-compose.yaml 编排项目
    3. 在当前目录(docker-compose.yaml文件所在目录)运行 docker-compose up; 停止 docker-compose down

Docker Swarm

集群方式的部署、

使用VM 创建四个虚拟机。(别问为什么没用云服务器, 问就是穷)

需要的问题解决方案放在博客里。

https://editor.csdn.net/md/?articleId=123874053

节点如何工作

预计阅读时间:2分钟

Docker Engine 1.12 引入了 swarm 模式,使您能够创建一个由一个或多个 Docker 引擎组成的集群,称为 swarm。一个 swarm 由一个或多个节点组成:在 swarm 模式下运行 Docker Engine 1.12 或更高版本的物理机或虚拟机。

有两种类型的节点:管理器工作器。

如果您还没有,请通读 swarm 模式概述和 关键概念。

管理节点

Manager 节点处理集群管理任务:

  • 维护集群状态
  • 调度服务
  • 服务群模式HTTP API 端点

使用Raft实现,管理器维护整个 swarm 和在其上运行的所有服务的一致内部状态。出于测试目的,可以使用单个管理器运行 swarm。如果单管理器集群中的管理器发生故障,您的服务将继续运行,但您需要创建一个新集群才能恢复。

为了利用 swarm 模式的容错特性,Docker 建议您根据组织的高可用性要求实现奇数个节点。当您有多个管理器时,您可以从管理器节点的故障中恢复而无需停机。

  • 一个三管理器群最多可以容忍一名管理器的损失。

  • 一个五管理器群最多可以同时丢失两个管理器节点。

  • 一个N管理器集群最多可以容忍丢失 (N-1)/2管理器。

  • Docker 建议一个 swarm 最多使用七个管理器节点。

    重要提示:添加更多管理器并不意味着增加可扩展性或提高性能。一般来说,情况正好相反。

工作节点

工作节点也是 Docker 引擎的实例,其唯一目的是执行容器。Worker 节点不参与 Raft 分布式状态,不做调度决策,也不服务于 swarm 模式的 HTTP API。

您可以创建一个由一个管理器节点组成的集群,但如果没有至少一个管理器节点,您就不能拥有一个工作程序节点。默认情况下,所有Manager 也是工人。在单个管理节点集群中,您可以运行类似docker service create的命令,并且调度程序将所有任务放在本地引擎上。

要防止调度程序将任务放置在多节点集群中的管理器节点上,请将管理器节点的可用性设置为Drain。调度器优雅地停止Drain模式节点上的任务,并在一个 Active节点上调度任务。调度程序不会将新任务分配给Drain 可用的节点。

请参阅docker node update 命令行参考以了解如何更改节点可用性。

换个角色

您可以通过运行将工作节点提升为管理器docker node promote。例如,当您将管理节点脱机进行维护时,您可能希望提升工作节点。请参阅节点提升。

Service

serices、tasks、containers

swarm 接收服务并且调度任务给 worker 节点manager:

manager:

  1. 接收命令并创建service
  2. 循环创建并调度 service
  3. 分配 ip 地址给task
  4. 分配 task 给节点
  5. 命令 worker 运行 task

worker node:

  1. 连接并确认被分配的 task
  2. 执行 tasks

服务副本和全局服务

只能在节点运行,提供相同的内容

For a replicated service, you specify the number of identical tasks you want to run. For example, you decide to deploy an HTTP service with three replicas, each serving the same content.

可在任意位置运行

A global service is a service that runs one task on every node. There is no pre-specified number of tasks. Each time you add a node to the swarm, the orchestrator creates a task and the scheduler assigns the task to the new node. Good candidates for global services are monitoring agents, an anti-virus scanners or other types of containers that you want to run on every node in the swarm.

--mode
docker service create --mode replicated 默认的   --mode global
场景:
日志收集:每一个节点有自己的日志收集器,过滤,再把所有日志最终传给日志中心。
服务监控

搭建集群

# 第一台机器 初始化为manager节点
[root@localhost ~]# docker swarm init --advertise-addr 192.168.230.128
Swarm initialized: current node (ury2qyztaj54axkg67q3kqesy) is now a manager.To add a worker to this swarm, run the following command:
#执行这段命令是作为worker加入docker swarm join --token SWMTKN-1-0zc1dw53ijhztlw8ke0s9tq04l1pgyck5mmqh5khnulanwq60d-efkiq3jdmjf5koxa9thr43gzx 192.168.230.128:2377
# 要作为作为manger加入的话执行docker swarm join-token manager获取令牌
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.# 第二台、第三台机器加入,作为一个worker加入
[root@localhost ~]# docker swarm join --token SWMTKN-1-0zc1dw53ijhztlw8ke0s9tq04l1pgyck5mmqh5khnulanwq60d-efkiq3jdmjf5koxa9thr43gzx 192.168.230.128:2377
This node joined a swarm as a worker.# 第四台机器作为 manager 加入
# 先在第一台机器执行 docker swarm join-token manager 同理也可得到worker
# 将得到的token复制到第四台机器
[root@localhost ~]# docker swarm join --token SWMTKN-1-0zc1dw53ijhztlw8ke0s9tq04l1pgyck5mmqh5khnulanwq60d-c8lrxfz4tq0zdrqyj2hgh553d 192.168.230.128:2377
This node joined a swarm as a manager.
# 这里可能会报错:Error response from daemon: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: Error while dialing dial tcp 192.168.0.108:2377: connect: no route to host"这个错误是因为将node节点加入swarm中导致的,原因就是manager节点这台机器上的防火墙没有关闭。只要把manager这台机器上的防火墙关闭即可:
#这里因为是我VM 所以直接关了,阿里云可以直接开放端口2377即可。
#停止防火墙
[root@centos-7 ~]# systemctl stop firewalld.service
#永久关闭防火墙
[root@centos-7 ~]# systemctl disable firewalld.service# 也可以使用命令 使 worker 升级为 manager节点
docker node promote# 查看集群信息
[root@localhost ~]# docker node ls
ID                            HOSTNAME                STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
1yhk7xykb008hgxlwykqd7ao2     localhost.localdomain   Ready     Active                          20.10.14
ryqtqead5yfaoiiade1xzw6te     localhost.localdomain   Ready     Active                          20.10.14
tu7vum1aj24lgsz71886ia5bh *   localhost.localdomain   Ready     Active         Reachable        20.10.14
ury2qyztaj54axkg67q3kqesy     localhost.localdomain   Ready     Active         Leader           20.10.14#扩展:worker节点 使用 docker swarm leave 就可离开。 Manager  需要强制离开 docker swarm leave -f

实战: 创建 nginx 服务、动态扩展服务、动态更新服务

#docker run 容器启动、不具备扩缩容器
#docker service 集群启动、具备扩缩能力  使用它的前提是已经搭建好集群了[root@localhost ~]# docker service --help
Usage:  docker service COMMAND
Manage services
Commands:create      Create a new service #创建inspect     Display detailed information on one or more services #详情logs        Fetch the logs of a service or task #日志ls          List servicesps          List the tasks of one or more servicesrm          Remove one or more servicesrollback    Revert changes to a service's configuration scale       Scale one or multiple replicated services #扩缩容update      Update a service #更新# 启动 nginx
[root@localhost ~]# docker service create -p 8888:80 --name my-nginx nginx
j5yu04xqlfe1wel9pl66pigeg
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged # 查看my-nginx 服务的状态  非 Leader 节点上是不能查看的
[root@localhost ~]# docker service ps my-ngnix
ID             NAME             IMAGE          NODE                    DESIRED STATE   CURRENT STATE                ERROR                              PORTS
zyo6ytclwh1z   my-nginx.1       nginx:latest   localhost.localdomain   Running         Running about a minute ago
#查看服务
[root@localhost ~]# docker service ls
ID             NAME       MODE         REPLICAS   IMAGE          PORTS
j5yu04xqlfe1   my-nginx   replicated   1/1        nginx:latest   *:8888->80/tcp# 扩容到3个副本 集群中的任意节点都可访问,实现高可用 == docker service scale my-nginx=3
# 也可以使用 docker service update --replicas 3 my-nginx  -d 后台启动
[root@localhost ~]# docker service update --replicas 3 my-nginx
my-ngnix
overall progress: 1 out of 3 tasks
1/3: running
2/3: preparing
3/3: preparing

概念总结

swarm

集群的管理和编排。docker可初始化一个 swarm 集群,其他节点可加入(manager、worker)

Node

就是一个docker节点。多个节点组成了一个网络集群(manager、worker)

Service

服务、可管理节点或者工作节点运行

Task

容器内的命令

网络

官网

网络模式:PublishMode:ingress

Overlay:加一层,由中间这层去统一调度到任意机器

ingress:特殊的 Overlay 网络,具有负载均衡功能 IPVS VIP

[root@localhost ~]# docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
34a48b87b6cc   bridge            bridge    local
836c7b6605fd   docker_gwbridge   bridge    local
88167e9c740f   host              host      local
q0lno7d93ndl   ingress           overlay   swarm
6162453aafff   none              null      local
[root@localhost ~]# docker network inspect q0lno7d93ndl

小结

  • Docker Swarm 是docker-compose的集群版,采用的是 Raft 协议

    • 最多容忍 N-1/2个节点 挂掉
  • 两种类型的节点
    • manager:主节点

      • 可查看集群信息、扩缩容、运行服务等
    • worker:工作节点
      • 仅可运行服务,不允许控制扩缩容等
  • service=多个服务=多个node节点
    • 服务=task+容器
  • 服务分为全局服务和服务副本(默认)
  • 常用命令
# 初始化为manager节点
docker swarm init --advertise-addr ip地址# 作为manager加入(在manager执行)
docker swarm join-token manager #将得到的命令复制到要加入的节点中# 作为worker 加入(在manager执行)
docker swarm join-token worker #将得到的命令复制到要加入的节点中# worker 升级为 manager节点
docker node promote# 查看集群信息  leader为manager节点,Reachable 为后备manager节点(挂掉之后会选举出新的)
docker node ls# 离开集群
docker swarm leave# 启动服务 eg:nginx
# 之前 docker 的参数都可用
docker service create -p 8000:80 --name my-nginx nginx# 查看服务状态
docker service ps 服务名称# 查看服务列表(只能在manager执行)
docker service ls# 扩缩容,两种方式
docker service update --replicas 数量 名字|服务id
docker service scale 名字|服务id=数量

Docker stack

介绍:

Docker Compose,缺点是不能在分布式多机器上使用;我们还介绍了Docker swarm,缺点是不能同时编排多个服务,所以才有了Docker Stack,可以在分布式多机器上同时编排多个服务。

案例

https://www.jianshu.com/p/d250b91c7adf

一个stack 是一组相互关联的 service,这组 service共享依赖,可被安排在一起运行和扩展

# docker-compose 单机部署
docker-compose up -d # docker stack 集群部署
# docker stack deploy -c [docker-compose.yml] [service name]
docker stack deploy -c docker-compose.yml mygoweb
docker stack deploy myapps --compose-file=/wordpress.yaml# 查看所有stack
docker stack ls

Docker Secret

什么是Docker Secret

官网描述:Manage Docker secrets 管理 Docker 机密

  • 用户名密码
  • SSH Key
  • TLS认证
  • 任何不想让别人看到的数据

我们知道有的service是需要设置密码的,比如mysql服务是需要设置密码的:

比如:docker-compose.yml中的service密码都是明文,这样就导致了不是很安全。

我们知道manager节点保持状态的一致是通过Raft Database这个分布式存储的数据库,它本身就是将信息进行了secret,所以可以利用这个数据库将一些敏感信息,例如账号、密码等信息保存在这里,然后通过给service授权的方式允许它进行访问,这样达到避免密码明文显示的效果。

总之,secret的Swarm中secret的管理通过以下步骤完成:

  • secret存在于Swarm Manager节点的的Raft Database里
  • secret可以assign给一个service,然后这个service就可以看到这个secret
  • 在container内部secret看起来像文件,实际上就是内存

Docker Secret的创建与使用

[root@localhost ~]# docker secret --help
Usage:  docker secret COMMAND
Manage Docker secrets
Commands:create      Create a secret from a file or STDIN as contentinspect     Display detailed information on one or more secretsls          List secretsrm          Remove one or more secrets[root@localhost ~]# docker secret create --help
Usage:  docker secret create [OPTIONS] SECRET [file|-]
Create a secret from a file or STDIN as content
#可以看到说明secret可以来自于一个文件或者一个标准输出。那么也就是Secret的创建有两种方式,分别是:
#基于命令行创建
#基于文件的创建
Options:-d, --driver string            Secret driver-l, --label list               Secret labels--template-driver string   Template driver#首先先创建一个文件用于存放mysql密码 密码为:root
[root@localhost home]# vim mysql-password
[root@localhost home]# cat mysql-password
root#创建secret 基于文件创建
#这些都是建立在有一个集群的基础上的。要搭建好docker swarm.
#mysql-pass是secret的名称,mysql-password是我们建立存储密码的文件,这样执行后就相当于将文件中的密码存储在Swarm中manager节点的Raft Database中了
[root@localhost home]# docker secret create mysql-pass mysql-password
uwrfxavvhpm3opyx7hyvdxkhk#为了安全起见,现在可以直接将这个文件删掉,因为Swarm中已经有这个密码了。
[root@localhost home]#  rm -f mysql-password#查看secret列表
[root@localhost home]# docker secret ls
ID                          NAME         DRIVER    CREATED              UPDATED
uwrfxavvhpm3opyx7hyvdxkhk   mysql-pass             About a minute ago   About a minute ago#创建secret 基于命令创建
#docker secret create [OPTIONS] CONFIG file|-
[root@localhost home]# echo "root" | docker secret create mysql-pass2 -
#查看secret列表
[root@localhost home]# docker secret ls
ID                          NAME          DRIVER    CREATED         UPDATED
uwrfxavvhpm3opyx7hyvdxkhk   mysql-pass              2 minutes ago   2 minutes ago
9mis56r456xj55tkvnn3npq42   mysql-pass2             7 seconds ago   7 seconds ago#查看更多信息
# docker secret inspect mysql-pass2
[{"ID": "9mis56r456xj55tkvnn3npq42","Version": {"Index": 101},"CreatedAt": "2022-04-01T02:42:51.986190083Z","UpdatedAt": "2022-04-01T02:42:51.986190083Z","Spec": {"Name": "mysql-pass2","Labels": {}}}
]#删除secret
[root@localhost home]# docker secret rm  mysql-pass2
mysql-pass2
[root@localhost home]# docker secret ls
ID                          NAME         DRIVER    CREATED         UPDATED
uwrfxavvhpm3opyx7hyvdxkhk   mysql-pass             4 minutes ago   4 minutes ago
#Secret在单容器中的使用
#容器中查看secret,启动一个服务后,将其授权给特定的服务使其可以看到
#docker service create -secret mysql-pass(密码名字) 创建服务时可以给服务暴露出secret#创建服务
[root@localhost home]# docker service create --name demo --secret mysql-pass busybox sh -c "while true; do sleep 3600; done"
l5tc9hplb9kdue0ogu7tzazc2
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged
#查看这个服务运行在那个节点上
[root@localhost home]# docker service ls
ID             NAME       MODE         REPLICAS   IMAGE            PORTS
l5tc9hplb9kd   demo       replicated   1/1        busybox:latest
j5yu04xqlfe1[root@localhost home]# docker service ps demo
ID             NAME      IMAGE            NODE                    DESIRED STATE   CURRENT STATE                ERROR     PORTS
c1b8oz3ppbn6   demo.1    busybox:latest   localhost.localdomain   Running         Running about a minute agomy-ngnix   replicated   3/3        nginx:latest     *:8888->80/tcp#可以看到这个服务运行在localhost.localdomain主机的节点上,去这个节点上进入到容器内部,查看secret:
[root@localhost home]# docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED              STATUS              PORTS     NAMES
bd823abfcf67   busybox:latest   "sh -c 'while true; …"   About a minute ago   Up About a minute             demo.1.c1b8oz3ppbn685shhvg83egik
[root@localhost home]# docker exec -it bd823abfcf67 /bin/sh
/ # cd /run/secrets/
/run/secrets # ls
mysql-pass
/run/secrets # cat mysql-pass
root

实战 mysql

#mysql服务#关于mysql镜像官网有关于secret的描述:
#作为通过环境变量传递敏感信息的替代方法,_FILE可以将其附加到先前列出的环境变量中,从而使初始化脚本从容器中存在的文件中加载那些变量的值。
#特别是,这可用于从/run/secrets/<secret_name>文件中存储的Docker Secret加载密码。例如:
#$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-root -d mysql:tag
#目前,这仅支持MYSQL_ROOT_PASSWORD,MYSQL_ROOT_HOST,MYSQL_DATABASE,MYSQL_USER,和MYSQL_PASSWORD。#所以我们需要先创建一个文件secret用于存储数据库的敏感信息,因为之前已经创建过,这里无需再创建:#再次查看secret 命令多打打才不容易忘记
[root@localhost home]# docker secret ls
ID                          NAME         DRIVER    CREATED         UPDATED
uwrfxavvhpm3opyx7hyvdxkhk   mysql-pass             4 minutes ago   4 minutes ago#启动mysql服务:
[root@localhost home]# docker service create --name db-mysql --secret mysql-pass -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-pass mysql:5.7
w1ptd75g4locdme9zct7opiy2
overall progress: 0 out of 1 tasks
1/1: preparing
^COperation continuing in background.
Use `docker service ps w1ptd75g4locdme9zct7opiy2` to check progress.
[root@localhost home]# docker service ps w1ptd75g4locdme9zct7opiy2
ID             NAME         IMAGE       NODE                    DESIRED STATE   CURRENT STATE             ERROR     PORTS
fv4arc2gq6y8   db-mysql.1   mysql:5.7   localhost.localdomain   Running         Preparing 3 minutes ago#查看mysql服务在那个节点上:
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                 NAMES
55feeb983b81   mysql:5.7      "docker-entrypoint.s…"   2 minutes ago    Up 2 minutes    3306/tcp, 33060/tcp   db-mysql.1.fv4arc2gq6y8g7lr1m4c7sefn
#在该节点中进入该服务的容器中查看secret:
[root@localhost ~]# docker exec -it 55feeb983b81 /bin/sh
# cd /run/secrets/
# ls
mysql-pass
# cat mysql-pass
root#这样知道了密码就可以进入到mysql数据库中了。
# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36 MySQL Community Server (GPL)Copyright (c) 2000, 2021, Oracle and/or its affiliates.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> 

Secret在Stack中的使用

Stack利用的就是docker-compose.yml文件来部署stack,那么如何在docker-compose.yml中来定义secret呢?

mysql:image: mysqlsecrets:- my-pwenvironment:MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql-pass #制定secretMYSQL_DATABASE: wordpress

显然我们在运行这个docker-compose.yml文件之前必须先要进行对应的secret文件的创建。然后就可以通过docker stack deploy命令来部署这个stack了。

部分参考 https://www.cnblogs.com/shenjianping/p/12272847.html 感谢博主分享。

Docker Config

在集群环境中配置文件的分发,可以通过将配置文件放入镜像中、设置环境变量、挂载volume、挂载目录的方式,当然也可以通过 docker config 来管理集群中的配置文件,这样的方式也更加通用。

基本命令

#一切命令从help学起
[root@localhost home]# docker config --helpUsage:  docker config COMMAND
Manage Docker configs
Commands:create      Create a config from a file or STDINinspect     Display detailed information on one or more configsls          List configsrm          Remove one or more configsRun 'docker config COMMAND --help' for more information on a command.[root@localhost home]# docker config create --help
Usage:  docker config create [OPTIONS] CONFIG file|-
Create a config from a file or STDIN(stdin 标准输入)
#可以看出创建可以分为 文件创建,命令创建
Options:-l, --label list               Config labels--template-driver string   Template driver#文件创建
[root@localhost home]# vim default.conf
[root@localhost home]# cat default.conf
server {listen       88;server_name  localhost;location / {root   /usr/share/nginx/html;index  index.html index.htm;}
}#创建config
[root@localhost home]# docker config create conf default.conf
ouyt1mlylntrzyd4qw74f5qx6#查看config
[root@localhost home]# docker config ls
ID                          NAME      CREATED          UPDATED
ouyt1mlylntrzyd4qw74f5qx6   conf      19 seconds ago   19 seconds ago#从标准输入创建
#Usage:  docker config create [OPTIONS] CONFIG file|-
[root@localhost home]#  echo "listen 80" | docker config create conf2  -
[root@localhost home]# docker config ls
ID                          NAME      CREATED          UPDATED
ouyt1mlylntrzyd4qw74f5qx6   conf      7 minutes ago    7 minutes ago
7eqao1yfzpjqfk4zhh35o7osj   conf2     34 seconds ago   34 seconds ago#查看config详细信息
[root@localhost home]# docker config inspect conf
[{"ID": "ouyt1mlylntrzyd4qw74f5qx6","Version": {"Index": 117},"CreatedAt": "2022-04-01T03:29:25.097432457Z","UpdatedAt": "2022-04-01T03:29:25.097432457Z","Spec": {"Name": "conf","Labels": {},"Data": "c2VydmVyIHsKICAgIGxpc3RlbiAgICAgICA4ODsKICAgIHNlcnZlcl9uYW1lICBsb2NhbGhvc3Q7CgogICAgbG9jYXRpb24gLyB7CiAgICAgICAgcm9vdCAgIC91c3Ivc2hhcmUvbmdpbngvaHRtbDsKICAgICAgICBpbmRleCAgaW5kZXguaHRtbCBpbmRleC5odG07CiAgICB9Cn0K"}}
]#对conf进行base64解码
[root@localhost home]# docker config inspect -f '{{json .Spec.Data}}' conf | cut -d '"' -f2 | base64 -d
#出现结果
server {listen       88;server_name  localhost;location / {root   /usr/share/nginx/html;index  index.html index.htm;}
}#删除secret
[root@localhost home]# docker config rm conf2

使用

#docker config
#使用nginx镜像创建容器
#在conf配置中,将nginx的监听端口改成了88 --config source=conf,
#然后再替换掉nginx中的默认80端口的配置文件 target=/etc/nginx/conf.d/default.conf,
#创建service时,将容器内部端口88端口映射成主机上90端口,-p 90:88
#后台运行。-d
[root@localhost ~]# docker service create --name nginx-01 --config source=conf,target=/etc/nginx/conf.d/default.conf -p 90:88 nginx:latest
yuu4hnqk2masmlr11v4tya83y
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged
#测试[root@localhost ~]# curl http://127.0.0.1:90
<!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>

CI/CD之Jenkins (流水线)

CI/CD是实现敏捷和Devops理念的一种方法。

具体而言,CI/CD 可让持续自动化和持续监控贯穿于应用的整个生命周期(从集成和测试阶段,到交付和部署)。这些关联的事务通常被统称为“CI/CD 管道”,由开发和运维团队以敏捷方式协同支持。

CI - 持续集成

定义: is the practice of merging all developers' working copies to a shared mainline
several times a day持续集成指的是,频繁地(一天多次)将代码集成到主干。

CI是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法。CI 的核心概念是持续集成、持续交付和持续部署。作为一个面向开发和运营团队的解决方案,CI 主要针对在集成新代码时所引发的问题(亦称“集成地狱”)。

持续集成强调开发人员提交了新代码之后,立刻自动的进行构建、(单元)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。

持续集成的目的

就是让产品可以快速迭代,同时还能保持高质量**。**它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例
,就不能集成。

持续集成过程中很重视自动化测试验证结果,对可能出现的一些问题进行预警,以保障最终合并的代码没有问题。

持续集成的作用

  • 代码库存越是积压,就越得不到生产检验,积压越多,代码间交叉感染的概率越大,下个发布(release)的复杂度和风险越高,持续集成可以保证团队开发人员提交代码的质量,减轻了软件发布时的压力;
  • 持续集成中的任何一个环节都是自动完成的,无需太多的人工干预,有利于减少重复过程以节省时间、费用和工作量;
  • 及早的发现代码中的问题,及早解决,代码越早推送(PUSH)出去,用户能越早用到,快就是商业价值;

特点

  • 它是一个自动化的周期性的集成测试过程,从检出代码、编译构建、运行测试、结果记录、测试统计等都是自动完成的,无需人工干预;
  • 需要有专门的集成服务器来执行集成构建;
  • 需要有代码托管工具支持;

CD // 持续交付

It aims at building, testing, and releasing software with greater speed and frequency

CD与DevOps关系

持续交付与DevOps的含义很相似,所以经常被混淆。但是它们是两个不同的概念。

DevOpsfa范围更广,它以文化变迁为中心,特别是软件交付过程所设计的多个团队之间的合作。一种思想。

CD持续交付,是一种自动化交付的手短,关注点在于将不同的过程集中起来,并且更快,更频繁的执行这些过程。

写在最后

  • 笔记纯自己花时间整理,只希望能帮助到更多的人。
  • 若再许我少年时,一两黄金一两梦

关于打赏:

打赏后如需要笔记,请主动发支付信息到邮箱 302658980@qq.com,备注需要的笔记名称。笔记持续更新。

ps:

另外本人创建了一个java交流群,可以在群里交流各自问题,看到了有能力的情况下,会尽力帮忙解决。

即为交流,希望是愿意交流的人才进来,一起努力、进步。

需要进群的 发送邮件 302658980@qq.com 备注 进群即可。(无需打赏)

如果本文有帮到了你,可以帮忙点个赞,谢谢支持。

狂神 Docker学习笔记 从基础到进阶 一步到位相关推荐

  1. Docker:学习笔记(1)——基础概念

    Docker:学习笔记(1)--基础概念 Docker是什么 软件开发后,我们需要在测试电脑.客户电脑.服务器安装运行,用户计算机的环境各不相同,所以需要进行各自的环境配置,耗时耗力.为了解决这个问题 ...

  2. 狂神docker学习笔记

    狂神docker(基础+进阶)-学习笔记 狂神说docker 三体:弱小和无知不是生存的障碍,傲慢才是. 从基础到进阶,每个视频都有认真看,做笔记和练习,以此篇分享整个学习过程 画图网页 docker ...

  3. MySQL学习笔记-从基础到进阶

    MySQL自学笔记 MySQL 基础 SQL SQL通用语法 SQL分类 DDL数据操作 数据类型 DML数据操作 DQL数据操作 DCL数据控制 函数 约束 多表查询 事务 进阶 存储引擎 **索引 ...

  4. 【狂神说】Docker 学习笔记【基础篇】

    学习思想而非学技术,技术日新月异,唯有思想长盛不衰,润泽后生 学习资料: [狂神说Java]Docker最新超详细版教程通俗易懂_哔哩哔哩_bilibili Docker快速入门总结笔记_huangj ...

  5. 狂神SpringSecurity学习笔记(基础)

    文章目录 前言 一.为什么使用SpringSecurity 一.关于SpringSecurity 导入模板素材 定制首页 前言 笔记整理来源于狂神视频https://www.bilibili.com/ ...

  6. Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)

    文章目录 1. Dockerfile介绍 2. Dockerfile指令说明 3. 制作Centos镜像 3.1 编写Dockerfile的文件 3.2 通过这个文件构建镜像(注意最后加个点!!!) ...

  7. Docker 学习笔记 - 进阶四 Docker网络和 Docker compose

    Docker 学习笔记 - 进阶四 Docker网络和 Docker compose 4. docker 网络 4.1 docker network是什么 4.1.1 docker不启动,默认网络情况 ...

  8. 十分钟了解Docker(我的Docker学习笔记)

    Docker学习笔记 碎碎念 背景知识 Docker是什么 Docker有什么用 Docker原理 Docker实践 Install Docker Engine on Ubuntu 常用命令操作实践 ...

  9. Docker学习笔记 之 Docker安装配置使用

    简介 Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机).bare met ...

最新文章

  1. EyeQ进展The Evolution of EyeQ
  2. 相当全面的Numpy使用总结.pptx
  3. jvm(11)-晚期(运行期)优化
  4. java 9999 符号_按格式生成序号,如0001,0002...9999
  5. 李开复写给大学生的第四封信的一些笔录
  6. 483. Smallest Good Base
  7. 你会用LaTeX写毕业论文么?
  8. 牛客真题编程——day16
  9. Elastic Stack
  10. Linux 打开文件显示: No such file or directory
  11. #7220. 「微课 3.6.2 例 1」亚瑟王
  12. Linux入坑手册(鸟哥的私房菜)
  13. 水果店文案:水果柿子文案高级感,水果柿子发圈文案
  14. snmp v3 参数_snmp v3的安全配置 snmp认证与加密配置(53)
  15. linux串口互斥,UART0串口编程之在UC/OS—II中遭遇的危机
  16. 把多个不连续的commit合并成一个commit
  17. 如何停止定时任务@Scheduled
  18. python 树莓派摄像头_Python实现树莓派摄像头持续录像并传送到主机的步骤
  19. Java 堆默认大小
  20. Topcoder 2016 TCO Algorithm Algo Semifinal 1 Hard ColorfunPath [网络流]

热门文章

  1. 北京某高端养老机构开业3年 : 1次失信,2场官司,3项处罚,处在高危中的养老行业如何应对多维度经营风险?
  2. 手机被偷完整找回方案
  3. 32位eclipse使用64位jdk问题
  4. HLK-W801-LVGL8之横屏显示
  5. 【openGauss】Oracle到postgresql的字符集名称映射表
  6. 微信小程序云开发完整案例
  7. 微信公众号开发整理(四)--音乐消息回复
  8. FATE学习:五种不同的API提交FATE任务
  9. 解决js newDate()苹果手机日期格式显示NaN
  10. mac m1使用picGo + gitee搭建免费图床