精华内容
下载资源
问答
  • Docker 教程
    千次阅读
    2019-08-01 17:18:01

    说明

    入门知识

    一、目标与安装

    二、容器

    三、服务

    四、Swarms

    五、栈

    六、部署应用

    Docker 开发

    更多相关内容
  • MAC下安装docker教程

    2021-01-10 08:46:48
    由于云主机很快就要到期了,还是在mac上先搭一下docker环境吧。 安装brew curl -LsSf http://github.com/mxcl/homebrew/tarball/master | sudo tar xvz -C/usr/local --strip 1 boot2docker方式(将要废弃) 安装...
  • docker教程

    2018-08-21 22:43:20
    Docker 入门教程,包括Linux/Windows/Mac平台从安装到使用及Docker-Compose教程
  • 如果要导出镜像到本地文件,可以使用 docker save 命令。 $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu 14.04 c4ff7513909d 5 weeks ago 225.4 MB ... $sudo docker save -o ubuntu_...
  • Docker教程

    2018-11-02 09:53:55
    Docker的基础, Docker的应用, Docker的实战,Docker的视频
  • 辛苦整理了OracleLinux7 CentOS7 Redhat7离线安装docker教程以及依赖。
  • Ubuntu 系列安装 Docker 官方网站上有各种环境下的 安装指南。 通过系统自带包安装 Ubuntu 14.04 版本系统中已经自带了 Docker 包,可以直接安装。 $ sudo apt-get update $ sudo apt-get install -y docker.io $ ...
  • CentOS 系列安装 Docker Docker 支持 CentOS6 及以后的版本。 CentOS6 对于 CentOS6,可以使用 EPEL 库安装 Docker,命令如下 $ sudo yum install ...
  • Mac OS X用户使用Docker Toolbox安装Docker软件, Docker Toolbox包含了下列的Docker 工具: Docker CLI客户端, 用来运行Docker Engine,并创建镜像和容器 Docker Machine, 在Mac OS X终端运行Docker Engine命令 ...
  • 什么是Docker_Registry和Docker_Hub?【Docker教程4】
  • Docker 教程Docker 命令 查看帮助 $ sudo docker help Docker 命令 命令 功能 attach Attach local standard input, output, and error streams to a running container build Build an image from a...
  • 主要介绍了Docker 教程Docker Hub详细介绍的相关资料,需要的朋友可以参考下
  • Centos下安装docker教程

    2021-01-11 04:41:19
    通过yum安装 需要root或者能sudo的权限 yum包更新到最新 $ sudo yum update 添加Docker yum源 $ sudo tee /etc/yum.repos.d/docker.repo <...name=Docker Repository baseurl=...安装Docker
  • 在Linux上安装Docker,具体几个步骤: 环境:windows7 虚拟机:Oracle VMVirtualBox Linux: ubuntukylin-14.04.1-amd64.iso JDK:1.7 一.环境准备 step1:安装虚拟机 step2:修改宿主机BIOS配置,详细步骤见文章://...
  • 星标/置顶公众号????,硬核文章第一时间送达!docker不是一个值得投入的领域,它解决的问题是Unix系统最初设计的一个疏忽。从一个不会用docker的小白,自己一步一步的摸索,中间也踩过...

    星标/置顶 公众号👇,硬核文章第一时间送达!

    be5ea759b5f1ce6c8388b3ecebd5e507.png

    docker不是一个值得投入的领域,它解决的问题是Unix系统最初设计的一个疏忽。从一个不会用docker的小白,自己一步一步的摸索,中间也踩过许多坑。但任然,坚持从哪里跌倒就从哪里爬起来。不求感动自己,但求人生无悔。 

    1 容器简介
    1.1 什么是 Linux 容器
    1.2 容器不就是虚拟化吗
    1.3 容器发展简史
    2 什么是 Docker?
    2.1 Docker 如何工作?
    2.2 Docker 技术是否与传统的 Linux 容器相同?
    2.3 docker的目标
    3 安装Docker
    3.1 Docker基础命令操作
    3.2 启动第一个容器
    3.3 Docker镜像生命周期
    4 docker镜像相关操作
    4.1 搜索官方仓库镜像
    4.2 获取镜像
    4.3 导出镜像
    4.4 删除镜像
    4.5 导入镜像
    4.6 查看镜像的详细信息
    5 容器的日常管理
    5.1 容器的起/停
    5.2 进入容器方法
    5.3 删除所有容器
    5.4 启动时进行端口映射
    6 Docker 数据卷的管理
    6.1 挂载时创建卷
    6.2 创建卷后挂载
    6.3 手动将容器保存为镜像
    7 Dockerfile自动构建docker镜像
    7.1 Dockerfile指令集
    7.2 创建一个Dockerfile
    7.3 使用Dcokerfile安装kodexplorer
    8 Docker中的镜像分层
    8.1 Docker 镜像为什么分层
    8.2 可写的容器层
    8.3 容器层的细节说明
    9 使用docker运行zabbix-server
    9.1 容器间的互联
    9.2 启动zabbix容器
    9.3 关于zabbix API
    10 docker 仓库(registry)
    10.1 创建一个普通仓库
    10.2 带basic认证的仓库
    11 docker-compose编排工具
    11.1 安装docker-compose
    11.2 编排启动镜像
    11.3 haproxy代理后端docker容器
    11.4 安装socat 直接操作socket控制haproxy
    12 重启docker服务,容器全部退出的解决办法
    12.1 在启动是指定自动重启
    12.2 修改docker默认配置文件
    13 Docker网络类型
    13.1 docker的网络类型
    13.2 不为容器配置网络功能
    13.3 与其他容器共享网络配置(Container)
    13.4 使用宿主机网络
    13.5 查看网络列表
    13.6 用PIPEWORK为docker容器配置独立IP
    13.7 Docker跨主机通信之macvlan
    14 docker企业级镜像仓库harbor
    14.1 使用容器的建议
    14.2 关于Docker容器的监控
    15 参考文献

    1 容器简介

    1.1 什么是 Linux 容器

    Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。

    54595689c97d1962e18cbaeadfc48325.png
    • 更加详细地来说,请您假定您在开发一个应用。您使用的是一台笔记本电脑,而且您的开发环境具有特定的配置。其他开发人员身处的环境配置可能稍有不同。您正在开发的应用依赖于您当前的配置,还要依赖于某些特定文件。与此同时,您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。您希望尽可能多在本地模拟这些环境,而不产生重新创建服务器环境的开销。

    • 因此,您要如何确保应用能够在这些环境中运行和通过质量检测,并且在部署过程中不出现令人头疼的问题,也无需重新编写代码和进行故障修复?答案就是使用容器。容器可以确保您的应用拥有必需的配置和文件,使得这些应用能够在从开发到测试、再到生产的整个流程中顺利运行,而不出现任何不良问题。这样可以避免危机,做到皆大欢喜。

    虽然这只是简化的示例,但在需要很高的可移植性、可配置性和隔离的情况下,我们可以利用 Linux 容器通过很多方式解决难题。无论基础架构是在企业内部还是在云端,或者混合使用两者,容器都能满足您的需求。

    1.2 容器不就是虚拟化吗

    是,但也不竟然。我们用一种简单方式来思考一下:

    虚拟化使得许多操作系统可同时在单个系统上运行。

    容器则可共享同一个操作系统内核,将应用进程与系统其他部分隔离开。

    d5b3abdfe54f58e6017cfddfb1fb1e97.png
    图-普通虚拟化技术和Docker的对比

    这意味着什么?首先,让多个操作系统在单个虚拟机监控程序上运行以实现虚拟化,并不能达成和使用容器同等的轻量级效果。事实上,在仅拥有容量有限的有限资源时,您需要能够可以进行密集部署的轻量级应用。Linux 容器可从单个操作系统运行,在所有容器中共享该操作系统,因此应用和服务能够保持轻量级,并行快速运行。

    1.3 容器发展简史

    0b973a1a6468a3a55f4854bd9d285143.png

    我们现在称为容器技术的概念最初出现在 2000 年,当时称为 FreeBSD jail,这种技术可将 FreeBSD 系统分区为多个子系统(也称为 Jail)。Jail 是作为安全环境而开发的,系统管理员可与企业内部或外部的多个用户共享这些 Jail。

    Jail 的目的是让进程在经过修改的 chroot 环境中创建,而不会脱离和影响整个系统 — 在 chroot 环境中,对文件系统、网络和用户的访问都实现了虚拟化。尽管 Jail 在实施方面存在局限性,但最终人们找到了脱离这种隔离环境的方法。

    但这个概念非常有吸引力。

    2001 年,通过 Jacques Gélinas 的 VServer 项目,隔离环境的实施进入了 Linux 领域。正如 Gélinas 所说,这项工作的目的是“在高度独立且安全的单一环境中运行多个通用 Linux 服务器 [sic]。” 在完成了这项针对 Linux 中多个受控制用户空间的基础性工作后,Linux 容器开始逐渐成形并最终发展成了现在的模样。

    2 什么是 Docker?

    “Docker” 一词指代多种事物,包括开源社区项目、开源项目使用的工具、主导支持此类项目的公司 Docker Inc. 以及该公司官方支持的工具。技术产品和公司使用同一名称,的确让人有点困惑。

    我们来简单说明一下:

    • IT 软件中所说的 “Docker” ,是指容器化技术,用于支持创建和使用 Linux 容器。

    • 开源 Docker 社区致力于改进这类技术,并免费提供给所有用户,使之获益。

    • Docker Inc. 公司凭借 Docker 社区产品起家,它主要负责提升社区版本的安全性,并将改进后的版本与更广泛的技术社区分享。此外,它还专门对这些技术产品进行完善和安全固化,以服务于企业客户。

    借助 Docker ,您可将容器当做重量轻、模块化的虚拟机使用。同时,您还将获得高度的灵活性,从而实现对容器的高效创建、部署及复制,并能将其从一个环境顺利迁移至另一个环境。

    2.1 Docker 如何工作?

    Docker 技术使用 Linux 内核和内核功能(例如 Cgroups 和 namespaces)来分隔进程,以便各进程相互独立运行。这种独立性正是采用容器的目的所在;它可以独立运行多种进程、多个应用程序,更加充分地发挥基础设施的作用,同时保持各个独立系统的安全性。

    容器工具(包括 Docker)可提供基于镜像的部署模式。这使得它能够轻松跨多种环境,与其依赖程序共享应用或服务组。Docker 还可在这一容器环境中自动部署应用程序(或者合并多种流程,以构建单个应用程序)。

    此外,由于这些工具基于 Linux 容器构建,使得 Docker 既易于使用,又别具一格 —— 它可为用户提供前所未有的高度应用程访问权限、快速部署以及版本控制和分发能力。

    2.2 Docker 技术是否与传统的 Linux 容器相同?

    否。Docker 技术最初是基于 LXC 技术构建(大多数人都会将这一技术与“传统的” Linux 容器联系在一起),但后来它逐渐摆脱了对这种技术的依赖。

    就轻量级虚拟化这一功能来看,LXC 非常有用,但它无法提供出色的开发人员或用户体验。除了运行容器之外,Docker 技术还具备其他多项功能,包括简化用于构建容器、传输镜像以及控制镜像版本的流程。

    f749cac2fa59310458412955691c7066.png

    传统的 Linux 容器使用 init 系统来管理多种进程。这意味着,所有应用程序都作为一个整体运行。与此相反,Docker 技术鼓励应用程序各自独立运行其进程,并提供相应工具以实现这一功能。这种精细化运作模式自有其优势。

    2.3 docker的目标

    docker的主要目标是"Build,Ship and Run any App,Angwhere",构建,运输,处处运行

    构建:做一个docker镜像

    运输:docker pull

    运行:启动一个容器

    每一个容器,他都有自己的文件系统rootfs.

    3 安装Docker

    环境说明

    # 需要两台几点进行安装
    [root@docker01 ~]# cat /etc/redhat-release 
    CentOS Linux release 7.2.1511 (Core) 
    [root@docker01 ~]# uname  -r 
    3.10.0-327.el7.x86_64
    [root@docker01 ~]# hostname -I
    10.0.0.100 172.16.1.100 
    [root@docker02 ~]# hostname -I
    10.0.0.101 172.16.1.101

    在两个节点上都进行操作

    wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
    sed -i 's#download.docker.com#mirrors.ustc.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
    yum install docker-ce -y

    修改在docker01配置:

    # 修改启动文件,监听远程端口
    vim /usr/lib/systemd/system/docker.service
    ExecStart\=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://10.0.0.100:2375 
    systemctl daemon\-reload
    systemctl enable docker.service 
    systemctl restart docker.service 
    # ps -ef检查进行,是否启动

    docker02测试

    [root@docker02 ~]# docker -H 10.0.0.100 info
    Containers: 0
     Running: 0
     Paused: 0
     Stopped: 0
    Images: 0
    Server Version: 17.12.0-ce
    Storage Driver: devicemapper
    ···

    3.1 Docker基础命令操作

    查看docker相关信息

    [root@docker01 ~]#  docker version  
    Client:
     Version:    17.12.0-ce
     API version:    1.35
     Go version:    go1.9.2
     Git commit:    c97c6d6
     Built:    Wed Dec 27 20:10:14 2017
     OS/Arch:    linux/amd64
    Server:
     Engine:
      Version:    17.12.0-ce
      API version:    1.35 (minimum version 1.12)
      Go version:    go1.9.2
      Git commit:    c97c6d6
      Built:    Wed Dec 27 20:12:46 2017
      OS/Arch:    linux/amd64
      Experimental:    false

    配置docker镜像加速

    vi /etc/docker/daemon.json
    { "registry-mirrors": ["https://registry.docker-cn.com"]
    }

    3.2 启动第一个容器

    [root@docker01 ~]# docker run -d -p 80:80 nginx
    Unable to find image 'nginx:latest' locally
    latest: Pulling from library/nginx
    e7bb522d92ff: Pull complete 
    6edc05228666: Pull complete 
    cd866a17e81f: Pull complete 
    Digest: sha256:285b49d42c703fdf257d1e2422765c4ba9d3e37768d6ea83d7fe2043dad6e63d
    Status: Downloaded newer image for nginx:latest
    8d8f81da12b5c10af6ba1a5d07f4abc041cb95b01f3d632c3d638922800b0b4d 
    # 容器启动后,在浏览器进行访问测试

    参数说明

    参数

    说明

    run

    创建并运行一个容器

    -d

    放入后台

    -p

    端口映射

    nginx

    镜像名称

    3.3 Docker镜像生命周期

    493fb5c8015e0a8ee4fdc1ff82b93ab8.png

    4 docker镜像相关操作

    4.1 搜索官方仓库镜像

    [root@docker01 ~]#  docker search centos
    NAME                      DESCRIPTION                    STARS    OFFICIAL               AUTOMATED
    centos                    The official build of CentOS.  3992     [OK]      
    ansible/centos7-ansible   Ansible on Centos7             105

    列表说明

    参数

    说明

    NAME

    镜像名称

    DESCRIPTION

    镜像说明

    STARS

    点赞数量

    OFFICIAL

    是否是官方的

    AUTOMATED

    是否是自动构建的

    4.2 获取镜像

    根据镜像名称拉取镜像

    [root@docker01 ~]# docker pull centos
    Using default tag: latest
    latest: Pulling from library/centos
    af4b0a2388c6: Downloading  34.65MB/73.67MB

    查看当前主机镜像列表

    [root@docker01 ~]# docker image list 
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    centos              latest              ff426288ea90        3 weeks ago         207MB
    nginx               latest              3f8a4339aadd        5 weeks ago         108MB

    拉第三方镜像方法

    docker pull index.tenxcloud.com/tenxcloud/httpd

    4.3 导出镜像

    [root@docker01 ~]# docker image list 
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    centos              latest              ff426288ea90        3 weeks ago         207MB
    nginx               latest              3f8a4339aadd        5 weeks ago         108MB
    # 导出
    [root@docker01 ~]# docker image save centos > docker-centos.tar.gz

    4.4 删除镜像

    [root@docker01 ~]# docker image rm centos:latest
    [root@docker01 ~]# docker image list 
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    nginx               latest              3f8a4339aadd        5 weeks ago         108MB

    4.5 导入镜像

    [root@docker01 ~]# docker image load -i docker-centos.tar.gz  
    e15afa4858b6: Loading layer  215.8MB/215.8MB
    Loaded image: centos:latest
    [root@docker01 ~]# docker image list 
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    centos              latest              ff426288ea90        3 weeks ago         207MB
    nginx               latest              3f8a4339aadd        5 weeks ago         108MB

    4.6 查看镜像的详细信息

    [root@docker01 ~]# docker image inspect centos

    5 容器的日常管理

    5.1 容器的起/停

    最简单的运行一个容器

    [root@docker01 ~]# docker run nginx

    创建容器,两步走(不常用)

    [root@docker01 ~]# docker create centos:latest  /bin/bash
    bb7f32368ecf0492adb59e20032ab2e6cf6a563a0e6751e58930ee5f7aaef204
    [root@docker01 ~]# docker start stupefied_nobel
    stupefied_nobel

    快速启动容器方法

    [root@docker01 ~]# docker run  centos:latest  /usr/bin/sleep 20;

    容器内的第一个进程必须一直处于运行的状态,否则这个容器,就会处于退出状态!

    查看正在运行的容器

    [root@docker01 ~]# docker container ls
        或
    [root@docker01 ~]# docker ps 
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    8708e93fd767        nginx               "nginx -g 'daemon of…"   6 seconds ago       Up 4 seconds        80/tcp              keen_lewin

    查看你容器详细信息/ip

    [root@docker01 ~]# docker container  inspect  容器名称/id

    查看你所有容器(包括未运行的)

    root@docker01 ~]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
    8708e93fd767        nginx               "nginx -g 'daemon of…"   4 minutes ago       Exited (0) 59 seconds ago                       keen_lewin
    f9f3e6af7508        nginx               "nginx -g 'daemon of…"   5 minutes ago       Exited (0) 5 minutes ago                        optimistic_haibt
    8d8f81da12b5        nginx               "nginx -g 'daemon of…"   3 hours ago         Exited (0) 3 hours ago                          lucid_bohr

    停止容器

    [root@docker01 ~]# docker stop 容器名称/id 
    或
    [root@docker01 ~]# docker container  kill  容器名称/id

    5.2 进入容器方法

    启动时进去方法

    [root@docker01 ~]# docker run -it #参数:-it 可交互终端
    [root@docker01 ~]# docker run -it nginx:latest  /bin/bash
    root@79241093859e:/#

    退出/离开容器

    1 | ctrl+p & ctrl+q

    启动后进入容器的方法

    启动一个docker

    [root@docker01 ~]# docker run -it centos:latest 
    [root@1bf0f43c4d2f /]# ps -ef 
    UID         PID   PPID  C STIME TTY          TIME CMD
    root          1      0  0 15:47 pts/0    00:00:00 /bin/bash
    root         13      1  0 15:47 pts/0    00:00:00 ps -ef

    attach进入容器,使用pts/0 ,会让所用通过此方法进如放入用户看到同样的操作。

    [root@docker01 ~]# docker attach 1bf0f43c4d2f
    [root@1bf0f43c4d2f /]# ps -ef 
    UID         PID   PPID  C STIME TTY          TIME CMD
    root          1      0  0 15:47 pts/0    00:00:00 /bin/bash
    root         14      1  0 15:49 pts/0    00:00:00 ps -ef

    自命名启动一个容器 --name

    [root@docker01 ~]# docker attach 1bf0f43c4d2f
    [root@1bf0f43c4d2f /]# ps -ef 
    UID         PID   PPID  C STIME TTY          TIME CMD
    root          1      0  0 15:47 pts/0    00:00:00 /bin/bash
    root         14      1  0 15:49 pts/0    00:00:00 ps -ef

    exrc 进入容器方法(推荐使用)

    [root@docker01 ~]# docker exec -it clsn1  /bin/bash 
    [root@b20fa75b4b40 /]# 重新分配一个终端
    [root@b20fa75b4b40 /]# ps -ef 
    UID         PID   PPID  C STIME TTY          TIME CMD
    root          1      0  0 16:11 pts/0    00:00:00 /bin/bash
    root         13      0  0 16:14 pts/1    00:00:00 /bin/bash
    root         26     13  0 16:14 pts/1    00:00:00 ps -ef

    5.3 删除所有容器

    [root@docker01 ~]# docker rm -f  `docker ps -a -q`
    # -f 强制删除

    5.4 启动时进行端口映射

    -p参数端口映射

    [root@docker01 ~]# docker run -d -p 8888:80  nginx:latest 
    287bec5c60263166c03e1fc5b0b8262fe76507be3dfae4ce5cd2ee2d1e8a89a9

    不同指定映射方法

    参数

    说明

    -p hostPort:containerPort    

    端口映射  -p 8080:80

    -p ip:hostPort:containerPort 

    配置监听地址 -p 10.0.0.100:8080:80

    -p ip::containerPort         

    随机分配端口 -p 10.0.0.100::80

    -p hostPort:containerPort:udp

    指定协议 -p 8080:80:tcp

    -p 81:80 –p 443:443          

    指定多个

    随机映射

    docker run -P (大P)# 需要镜像支持

    6 Docker 数据卷的管理

    6.1 挂载时创建卷

    挂载卷

    [root@docker01 ~]# docker run -d -p 80:80 -v /data:/usr/share/nginx/html nginx:latest
    079786c1e297b5c5031e7a841160c74e91d4ad06516505043c60dbb78a259d09

    容器内站点目录: /usr/share/nginx/html

    在宿主机写入数据,查看

    [root@docker01 ~]# echo "http://www.nmtui.com" >/data/index.html
    [root@docker01 ~]# curl 10.0.0.100
    http://www.nmtui.com

    设置共享卷,使用同一个卷启动一个新的容器

    [root@docker01 ~]# docker run -d -p 8080:80 -v /data:/usr/share/nginx/html nginx:latest 
    351f0bd78d273604bd0971b186979aa0f3cbf45247274493d2490527babb4e42
    [root@docker01 ~]# curl 10.0.0.100:8080
    http://www.nmtui.com

    查看卷列表

    [root@docker01 ~]# docker volume ls
    DRIVER              VOLUME NAME

    6.2 创建卷后挂载

    创建一个卷

    [root@docker01 ~]# docker volume create 
    f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
    [root@docker01 ~]# docker volume ls 
    DRIVER              VOLUME NAME
    local               f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521

    指定卷名

    [root@docker01 ~]# docker volume ls 
    DRIVER              VOLUME NAME
    local               clsn
    local               f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521

    查看卷路径

    [root@docker01 ~]# docker volume inspect clsn 
    [
        {
            "CreatedAt": "2018-02-01T00:39:25+08:00",
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/clsn/_data",
            "Name": "clsn",
            "Options": {},
            "Scope": "local"
        }
    ]

    使用卷创建

    [root@docker01 ~]# docker run -d -p 9000:80 -v clsn:/usr/share/nginx/html nginx:latest 
    1434559cff996162da7ce71820ed8f5937fb7c02113bbc84e965845c219d3503
    # 宿主机测试
    [root@docker01 ~]# echo 'blog.nmtui.com' >/var/lib/docker/volumes/clsn/_data/index.html 
    [root@docker01 ~]# curl 10.0.0.100:9000
    blog.nmtui.com

    设置卷

    [root@docker01 ~]# docker run  -d  -P  --volumes-from 079786c1e297 nginx:latest 
    b54b9c9930b417ab3257c6e4a8280b54fae57043c0b76b9dc60b4788e92369fb

    查看使用的端口

    [root@docker01 ~]# netstat -lntup 
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1400/sshd           
    tcp        0      0 10.0.0.100:2375         0.0.0.0:*               LISTEN      26218/dockerd       
    tcp6       0      0 :::9000                 :::*                    LISTEN      32015/docker-proxy  
    tcp6       0      0 :::8080                 :::*                    LISTEN      31853/docker-proxy  
    tcp6       0      0 :::80                   :::*                    LISTEN      31752/docker-proxy  
    tcp6       0      0 :::22                   :::*                    LISTEN      1400/sshd           
    tcp6       0      0 :::32769                :::*                    LISTEN      32300/docker-proxy  
    [root@docker01 ~]# curl 10.0.0.100:32769
    http://www.nmtui.com

    6.3 手动将容器保存为镜像

    本次是基于docker官方centos 6.8 镜像创建

    官方镜像列表:https://hub.docker.com/explore/

    启动一个centos6.8的镜像

    [root@docker01 ~]# docker pull  centos:6.8
    [root@docker01 ~]# docker run -it -p 1022:22 centos:6.8  /bin/bash
    # 在容器种安装sshd服务,并修改系统密码
    [root@582051b2b92b ~]# yum install  openssh-server -y 
    [root@582051b2b92b ~]# echo "root:123456" |chpasswd
    [root@582051b2b92b ~]#  /etc/init.d/sshd start

    启动完成后镜像ssh连接测试

    将容器提交为镜像

    [root@docker01 ~]# docker commit brave_mcclintock  centos6-ssh

    使用新的镜像启动容器

    [root@docker01 ~]# docker run -d  -p 1122:22  centos6-ssh:latest  /usr/sbin/sshd -D 
    5b8161fda2a9f2c39c196c67e2eb9274977e7723fe51c4f08a0190217ae93094

    在容器安装httpd服务

    [root@5b8161fda2a9 /]#  yum install httpd -y

    编写启动脚本脚本

    [root@5b8161fda2a9 /]# cat  init.sh 
    #!/bin/bash 
    /etc/init.d/httpd start 
    /usr/sbin/sshd -D
    [root@5b8161fda2a9 /]# chmod +x init.sh 
    # 注意执行权限

    注意执行权限

    再次提交为新的镜像

    [root@docker01 ~]# docker commit  5b8161fda2a9 centos6-httpd 
    sha256:705d67a786cac040800b8485cf046fd57b1828b805c515377fc3e9cea3a481c1

    启动镜像,做好端口映射。并在浏览器中测试访问

    [root@docker01 ~]# docker run -d -p 1222:22 -p 80:80  centos6-httpd /init.sh 
    46fa6a06644e31701dc019fb3a8c3b6ef008d4c2c10d46662a97664f838d8c2c

    7 Dockerfile自动构建docker镜像

    官方构建dockerffile文件参考:https://github.com/CentOS/CentOS-Dockerfiles

    7.1 Dockerfile指令集

    dockerfile主要组成部分:

    基础镜像信息 FROM centos:6.8
    
     制作镜像操作指令RUN yum insatll openssh-server \-y
    
     容器启动时执行指令 CMD \["/bin/bash"\]

    dockerfile常用指令:

    FROM 这个镜像的妈妈是谁?(指定基础镜像)
    
     MAINTAINER 告诉别人,谁负责养它?(指定维护者信息,可以没有)
    
     RUN 你想让它干啥(在命令前面加上RUN即可)
    
     ADD 给它点创业资金(COPY文件,会自动解压)
    
     WORKDIR 我是cd,今天刚化了妆(设置当前工作目录)
    
     VOLUME 给它一个存放行李的地方(设置卷,挂载主机目录)
    
     EXPOSE 它要打开的门是啥(指定对外的端口)
    
     CMD 奔跑吧,兄弟!(指定容器启动后的要干的事情)

    dockerfile其他指令:

    COPY 复制文件
    
    ENV  环境变量
    
    ENTRYPOINT  容器启动后执行的命令

    7.2 创建一个Dockerfile

    创建第一个Dockerfile文件

    # 创建目录
    [root@docker01 base]# cd /opt/base
    # 创建Dcokerfile文件,注意大小写
    [root@docker01 base]# vim Dockerfile
    FROM centos:6.8
    RUN yum install openssh-server -y 
    RUN echo "root:123456" |chpasswd
    RUN /etc/init.d/sshd start 
    CMD ["/usr/sbin/sshd","-D"]

    构建docker镜像

    [root@docker01 base]# docker image build  -t centos6.8-ssh . 
    -t 为镜像标签打标签  . 表示当前路径

    使用自构建的镜像启动

    [root@docker01 base]# docker run  -d -p 2022:22 centos6.8-ssh-b 
    dc3027d3c15dac881e8e2aeff80724216f3ac725f142daa66484f7cb5d074e7a

    7.3 使用Dcokerfile安装kodexplorer

    Dockerfile文件内容

    FROM centos:6.8
    RUN yum install wget unzip php php-gd php-mbstring -y && yum clean all
    # 设置工作目录,之后的操作都在这个目录中
    WORKDIR /var/www/html/
    RUN wget -c http://static.kodcloud.com/update/download/kodexplorer4.25.zip
    RUN unzip kodexplorer4.25.zip && rm -f kodexplorer4.25.zip
    RUN chown -R apache.apache .
    CMD ["/usr/sbin/apachectl","-D","FOREGROUND"]

    更多的Dockerfile可以参考官方方法。

    8 Docker中的镜像分层

    参考文档:http://www.maiziedu.com/wiki/cloud/dockerimage

    Docker 支持通过扩展现有镜像,创建新的镜像。实际上,Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。

    a11e22e28a12f8ca6250c62abd030111.png

    从上图可以看到,新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。

    8.1 Docker 镜像为什么分层

    镜像分层最大的一个好处就是共享资源。

    比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

    如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如 /etc 下的文件,这时其他容器的 /etc 是不会被修改的,修改只会被限制在单个容器内。这就是容器 Copy-on-Write 特性。

    8.2 可写的容器层

    当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

    f3ec6c11073c5995dfa07caa2b2ea178.png

    所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。

    8.3 容器层的细节说明

    镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /a,上层的 /a 会覆盖下层的 /a,也就是说用户只能访问到上层中的文件 /a。在容器层中,用户看到的是一个叠加之后的文件系统。

    文件操作说明

    文件操作

    说明

    添加文件

    在容器中创建文件时,新文件被添加到容器层中。

    读取文件

    在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后打开并读入内存。

    修改文件

    在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。

    删除文件

    在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。(只是记录删除操作)

    只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。

    这样就解释了我们前面提出的问题:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。

    9 使用docker运行zabbix-server

    9.1 容器间的互联

    在运行zabbix之前务必要了解容器间互联的方法

    # 创建一个nginx容器
    docker run -d -p 80:80 nginx
    # 创建容器,做link,并进入容器中
    docker run -it --link quirky_brown:web01 centos-ssh /bin/bash
    # 在容器中访问nginx容器可以ping通
    ping web01

    命令执行过程

    # 启动apache容器
    [root@docker01 ~]# docker run -d httpd:2.4  
    3f1f7fc554720424327286bd2b04aeab1b084a3fb011a785b0deab6a34e56955
    ^[[A[root@docker01 docker ps -a
    CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
    3f1f7fc55472        httpd:2.4           "httpd-foreground"   6 seconds ago       Up 5 seconds        80/tcp              determined_clarke
    # 拉取一个busybox 镜像
    [root@docker01 ~]# docker pull busybox 
    # 启动容器
    [root@docker01 ~]# docker run -it  --link determined_clarke:web busybox:latest   /bin/sh 
    / # 
    # 使用新的容器访问最初的web容器
    / # ping web 
    PING web (172.17.0.2): 56 data bytes
    64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.058 ms
    ^C
    --- web ping statistics ---
    1 packets transmitted, 1 packets received, 0% packet loss
    round-trip min/avg/max = 0.058/0.058/0.058 ms

    9.2 启动zabbix容器

    1、启动一个mysql的容器

    docker run --name mysql-server -t \
          -e MYSQL_DATABASE="zabbix" \
          -e MYSQL_USER="zabbix" \
          -e MYSQL_PASSWORD="zabbix_pwd" \
          -e MYSQL_ROOT_PASSWORD="root_pwd" \
          -d mysql:5.7 \
          --character-set-server=utf8 --collation-server=utf8_bin

    2、启动java-gateway容器监控java服务

    docker run --name zabbix-java-gateway -t \
          -d zabbix/zabbix-java-gateway:latest

    3、启动zabbix-mysql容器使用link连接mysql与java-gateway。

    docker run --name zabbix-server-mysql -t \
          -e DB_SERVER_HOST="mysql-server" \
          -e MYSQL_DATABASE="zabbix" \
          -e MYSQL_USER="zabbix" \
          -e MYSQL_PASSWORD="zabbix_pwd" \
          -e MYSQL_ROOT_PASSWORD="root_pwd" \
          -e ZBX_JAVAGATEWAY="zabbix-java-gateway" \
          --link mysql-server:mysql \
          --link zabbix-java-gateway:zabbix-java-gateway \
          -p 10051:10051 \
          -d zabbix/zabbix-server-mysql:latest

    4、启动zabbix web显示,使用link连接zabbix-mysql与mysql。

    docker run --name zabbix-web-nginx-mysql -t \
          -e DB_SERVER_HOST="mysql-server" \
          -e MYSQL_DATABASE="zabbix" \
          -e MYSQL_USER="zabbix" \
          -e MYSQL_PASSWORD="zabbix_pwd" \
          -e MYSQL_ROOT_PASSWORD="root_pwd" \
          --link mysql-server:mysql \
          --link zabbix-server-mysql:zabbix-server \
          -p 80:80 \
          -d zabbix/zabbix-web-nginx-mysql:latest

    9.3 关于zabbix API

    关于zabbix API可以参考官方文档:https://www.zabbix.com/documentation/3.4/zh/manual/api

    获取token方法

    # 获取token
    [root@docker02 ~]# curl -s -X POST -H 'Content-Type:application/json' -d '
    {
    "jsonrpc": "2.0",
    "method": "user.login",
    "params": {
    "user": "Admin",
    "password": "zabbix"
    },
    "id": 1
    }' http://10.0.0.100/api_jsonrpc.php
    {"jsonrpc":"2.0","result":"d3be707f9e866ec5d0d1c242292cbebd","id":1}

    10 docker 仓库(registry)

    10.1 创建一个普通仓库

    1、创建仓库

    docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry  registry

    2、修改配置文件,使之支持http

    [root@docker01 ~]# cat  /etc/docker/daemon.json 
    {
      "registry-mirrors": ["https://registry.docker-cn.com"],
      "insecure-registries": ["10.0.0.100:5000"]
    }

    重启docker让修改生效

    [root@docker01 ~]# systemctl restart  docker.service

    3、修改镜像标签

    [root@docker01 ~]# docker tag  busybox:latest  10.0.0.100:5000/clsn/busybox:1.0
    [root@docker01 ~]# docker images
    REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
    centos6-ssh                     latest              3c2b1e57a0f5        18 hours ago        393MB
    httpd                           2.4                 2e202f453940        6 days ago          179MB
    10.0.0.100:5000/clsn/busybox    1.0                 5b0d59026729        8 days ago          1.15MB

    4、将新打标签的镜像上传镜像到仓库

    [root@docker01 ~]# docker push   10.0.0.100:5000/clsn/busybox

    10.2 带basic认证的仓库

    1、安装加密工具

    [root@docker01 clsn]# yum install httpd-tools  -y

    2、设置认证密码

    mkdir /opt/registry-var/auth/ -p
    htpasswd \-Bbn clsn 123456  > /opt/registry-var/auth/htpasswd

    3、启动容器,在启动时传入认证参数

    docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry

    4、使用验证用户测试

    # 登陆用户
    [root@docker01 ~]# docker login 10.0.0.100:5000 
    Username: clsn  
    Password: 123456
    Login Succeeded
    # 推送镜像到仓库
    [root@docker01 ~]# docker push 10.0.0.100:5000/clsn/busybox 
    The push refers to repository [10.0.0.100:5000/clsn/busybox]
    4febd3792a1f: Pushed 
    1.0: digest: sha256:4cee1979ba0bf7db9fc5d28fb7b798ca69ae95a47c5fecf46327720df4ff352d size: 527
    #认证文件的保存位置
    [root@docker01 ~]# cat .docker/config.json 
    {
        "auths": {
            "10.0.0.100:5000": {
                "auth": "Y2xzbjoxMjM0NTY="
            },
            "https://index.docker.io/v1/": {
                "auth": "Y2xzbjpIenNAMTk5Ng=="
            }
        },
        "HttpHeaders": {
            "User-Agent": "Docker-Client/17.12.0-ce (linux)"
        }
    }

    至此,一个简单的docker镜像仓库搭建完成

    11 docker-compose编排工具

    11.1 安装docker-compose

    安装docker-compose

    # 下载pip软件
    yum install -y python2-pip
    # 下载 docker-compose
    pip install docker-compose

    国内开启pip 下载加速:http://mirrors.aliyun.com/help/pypi

    mkdir ~/.pip/
    cat > ~/.pip/pip.conf <<'EOF'
    [global]
    index-url = https://mirrors.aliyun.com/pypi/simple/
    [install]
    trusted-host=mirrors.aliyun.com
    EOF

    11.2 编排启动镜像

    1、创建文件目录

    [root@docker01 ~]# mkdir /opt/my_wordpress/
    [root@docker01 ~]# cd /opt/my_wordpress/

    2、编写编排文件

    [root@docker01 my_wordpress]# vim docker-compose.yml
    version: '3'
    services:
       db:
         image: mysql:5.7
         volumes:
           - /data/db_data:/var/lib/mysql
         restart: always
         environment:
           MYSQL_ROOT_PASSWORD: somewordpress
           MYSQL_DATABASE: wordpress
           MYSQL_USER: wordpress
           MYSQL_PASSWORD: wordpress
       wordpress:
         depends_on:
           - db
         image: wordpress:latest
         volumes:
           - /data/web_data:/var/www/html
         ports: 
           - "8000:80"
         restart: always
         environment:
           WORDPRESS_DB_HOST: db:3306
           WORDPRESS_DB_USER: wordpress
           WORDPRESS_DB_PASSWORD: wordpress

    3、启动

    [root@docker01 my_wordpress]# docker-compose up
      #启动方法:docker-compose up
      #后台启动方法:docker-compose up -d

    4、浏览器上访问http://10.0.0.100:8000

    进行wordpress的安装即可

    11.3 haproxy代理后端docker容器

    1、修改编排脚本

    [root@docker01 my_wordpress]# cat docker-compose.yml 
    version: '3'
    services:
       db:
         image: mysql:5.7
         volumes:
           - /data/db_data:/var/lib/mysql
         restart: always
         environment:
           MYSQL_ROOT_PASSWORD: somewordpress
           MYSQL_DATABASE: wordpress
           MYSQL_USER: wordpress
           MYSQL_PASSWORD: wordpress
       wordpress:
         depends_on:
           - db
         image: wordpress:latest
         volumes:
           - /data/web_data:/var/www/html
         ports: 
           - "80"
         restart: always
         environment:
           WORDPRESS_DB_HOST: db:3306
           WORDPRESS_DB_USER: wordpress
           WORDPRESS_DB_PASSWORD: wordpress

    2、同时启动两台wordpress

    [root@docker01 my_wordpress]# docker-compose scale wordpress=2 
    WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
    Starting mywordpress_wordpress_1 ... done
    Creating mywordpress_wordpress_2 ... done

    3、安装haproxy

    [root@docker01 ~]# yum install haproxy -y

    4、修改haproxy配置文件

    关于配置文件的详细说明,参考:https://www.cnblogs.com/MacoLee/p/5853413.html

    [root@docker01 ~]#cp /etc/haproxy/haproxy.cfg{,.bak}
    [root@docker01 ~]# vim /etc/haproxy/haproxy.cfg
    global
        log         127.0.0.1 local2
        chroot      /var/lib/haproxy
        pidfile     /var/run/haproxy.pid
        maxconn     4000
        user        haproxy
        group       haproxy
        daemon
        stats socket /var/lib/haproxy/stats level admin  #支持命令行控制
    defaults
        mode                    http
        log                     global
        option                  httplog
        option                  dontlognull
        option http-server-close
        option forwardfor       except 127.0.0.0/8
        option                  redispatch
        retries                 3
        timeout http-request    10s
        timeout queue           1m
        timeout connect         10s
        timeout client          1m
        timeout server          1m
        timeout http-keep-alive 10s
        timeout check           10s
        maxconn                 3000
    listen stats
        mode http
        bind 0.0.0.0:8888
        stats enable
        stats uri     /haproxy-status 
        stats auth    admin:123456
    frontend frontend_www_example_com
        bind 10.0.0.100:8000
        mode http
        option httplog
        log global
        default_backend backend_www_example_com
    backend backend_www_example_com
        option forwardfor header X-REAL-IP
        option httpchk HEAD / HTTP/1.0
        balance roundrobin
        server web-node1  10.0.0.100:32768 check inter 2000 rise 30 fall 15
        server web-node2  10.0.0.100:32769 check inter 2000 rise 30 fall 15

    5、启动haproxy

    systemctl start haproxy
    systemctl enable haproxy

    6、使用浏览器访问hapeoxy监听的8000端口可以看到负载的情况

    900d0e5a1baffe1b00d4304287d2c226.png

    7、使用浏览器访问 http://10.0.0.100:8888/haproxy-status

    可以看到后端节点的监控状况,

    778e83d02920841435d55a3d16bb87ad.png

    11.4 安装socat 直接操作socket控制haproxy

    1、安装软件

    yum install socat.x86\_64 -y

    2、查看帮助

    [root@docker01 web_data]# echo "help"|socat stdio /var/lib/haproxy/stats

    3、下线后端节点

    echo "disable server backend_www_example_com/web-node2"|socat stdio /var/lib/haproxy/stats

    4、上线后端节点

    echo "enable server backend_www_example_com/web-node3"|socat stdio /var/lib/haproxy/stats

    5、编写php测试页,放到/data/web_data下,在浏览器中访问可以查看当前的节点

    [root@docker01 web_data]# vim check.php
    <html>
        <head>
            <title>PHP测试</title>
        </head>
        <body>
            <?php  echo '<p>Hello World </p>'; ?>
            <?php  echo "访问的服务器地址是:"."<fontcolor=red>".$_SERVER['SERVER_ADDR']."</font>"."<br>";
            echo"访问的服务器域名是:"."<fontcolor=red>".$_SERVER['SERVER_NAME']."</font>"."<br>";
            ?>
        </body>
    </html>

    12 重启docker服务,容器全部退出的解决办法

    12.1 在启动是指定自动重启

    docker run  --restart=always

    12.2 修改docker默认配置文件

    # 添加上下面这行
    "live-restore": true

    docker server配置文件/etc/docker/daemon.json参考

    [root@docker02 ~]# cat  /etc/docker/daemon.json 
    {
      "registry-mirrors": ["https://registry.docker-cn.com"],
      "graph": "/opt/mydocker", # 修改数据的存放目录到/opt/mydocker/,原/var/lib/docker/
      "insecure-registries": ["10.0.0.100:5000"],
      "live-restore": true
    }

    重启生效,只对在此之后启动的容器生效

    [root@docker01 ~]# systemctl restart  docker.service

    13 Docker网络类型

    20436826d8fe345078d50fc54ccb4ca5.png

    13.1 docker的网络类型

    类型

    说明

    None

    不为容器配置任何网络功能,没有网络 --net=none

    Container

    与另一个运行中的容器共享Network Namespace,--net=container:containerID

    Host

    与主机共享Network Namespace,--net=host

    Bridge

    Docker设计的NAT网络模型(默认类型)

    Bridge默认docker网络隔离基于网络命名空间,在物理机上创建docker容器时会为每一个docker容器分配网络命名空间,并且把容器IP桥接到物理机的虚拟网桥上。

    13.2 不为容器配置网络功能

    此模式下创建容器是不会为容器配置任何网络参数的,如:容器网卡、IP、通信路由等,全部需要自己去配置。

    [root@docker01 ~]# docker run  -it --network none busybox:latest  /bin/sh 
    / # ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever

    13.3 与其他容器共享网络配置(Container)

    此模式和host模式很类似,只是此模式创建容器共享的是其他容器的IP和端口而不是物理机,此模式容器自身是不会配置网络和端口,创建此模式容器进去后,你会发现里边的IP是你所指定的那个容器IP并且端口也是共享的,而且其它还是互相隔离的,如进程等。

    [root@docker01 ~]# docker run  -it --network container:mywordpress_db_1  busybox:latest  /bin/sh 
    / # ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
    105: eth0@if106: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
        link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
        inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
           valid_lft forever preferred_lft forever

    13.4 使用宿主机网络

    此模式创建的容器没有自己独立的网络命名空间,是和物理机共享一个Network Namespace,并且共享物理机的所有端口与IP,并且这个模式认为是不安全的。

    [root@docker01 ~]# docker run  -it --network host  busybox:latest  /bin/sh

    13.5 查看网络列表

    [root@docker01 ~]# docker network list 
    NETWORK ID          NAME                  DRIVER              SCOPE
    b15e8a720d3b        bridge                bridge              local
    345d65b4c2a0        host                  host                local
    bc5e2a32bb55        mywordpress_default   bridge              local
    ebf76eea91bb        none                  null                local

    13.6 用PIPEWORK为docker容器配置独立IP

    参考文档:http://blog.csdn.net/design321/article/details/48264825

    官方网站:https://github.com/jpetazzo/pipework

    宿主环境:centos7.2

    1、安装pipework

    wget https://github.com/jpetazzo/pipework/archive/master.zip
    unzip master.zip 
    cp pipework-master/pipework  /usr/local/bin/
    chmod +x /usr/local/bin/pipework

    2、配置桥接网卡

    安装桥接工具

    yum install bridge-utils.x86\_64 -y

    修改网卡配置,实现桥接

    # 修改eth0配置,让br0实现桥接
    [root@docker01 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 
    TYPE=Ethernet
    BOOTPROTO=static
    NAME=eth0
    DEVICE=eth0
    ONBOOT=yes
    BRIDGE=br0
    [root@docker01 ~]# cat /etc/sysconfig/network-scripts/ifcfg-br0 
    TYPE=Bridge
    BOOTPROTO=static
    NAME=br0
    DEVICE=br0
    ONBOOT=yes
    IPADDR=10.0.0.100
    NETMASK=255.255.255.0
    GATEWAY=10.0.0.254
    DNS1=223.5.5.5
    # 重启网络
    [root@docker01 ~]# /etc/init.d/network restart

    3、运行一个容器镜像测试:

    pipework br0 \$\(docker run -d -it -p 6880:80 --name  httpd\_pw httpd\) 10.0.0.220/24\@10.0.0.254

    在其他主机上测试端口及连通性

    [root@docker01 ~]# curl 10.0.0.220
    <html><body><h1>It works!</h1></body></html>
    [root@docker01 ~]# ping 10.0.0.220 -c 1
    PING 10.0.0.220 (10.0.0.220) 56(84) bytes of data.
    64 bytes from 10.0.0.220: icmp_seq=1 ttl=64 time=0.043 ms

    4、再运行一个容器,设置网路类型为none:

    pipework br0 $(docker run -d -it --net=none --name test httpd:2.4) 10.0.0.221/24@10.0.0.254

    进行访问测试

    [root@docker01 ~]# curl 10.0.0.221
    <html><body><h1>It works!</h1></body></html>

    5、重启容器后需要再次指定:

    pipework br0 testduliip  172.16.146.113/24\@172.16.146.1 pipework br0 testduliip01 172.16.146.112/24\@172.16.146.1

    Dcoker跨主机通信之overlay可以参考:

    http://www.cnblogs.com/CloudMan6/p/7270551.html

    1.13.7 Docker跨主机通信之macvlan

    创建网络

    [root@docker01 ~]# docker network  create --driver macvlan  --subnet 10.1.0.0/24 --gateway 10.1.0.254 -o parent=eth0  macvlan_1
    33a1f41dcc074f91b5bd45e7dfedabfb2b8ec82db16542f05213839a119b62ca

    设置网卡为混杂模式

    ip link set eth0 promisc on

    创建使用macvlan网络容器

    [root@docker02 ~]# docker run  -it --network macvlan_1  --ip=10.1.0.222 busybox /bin/sh

    14 docker企业级镜像仓库harbor

    容器管理

    [root@docker01 harbor]# pwd
    /opt/harbor
    [root@docker01 harbor]# docker-compose stop

    1、安装docker、docker-compose

    下载 harbor

    cd /opt && https://storage.googleapis.com/harbor-releases/harbor-offline-installer-v1.3.0.tgz
    tar xf harbor-offline-installer-v1.3.0.tgz

    2、修改主机及web界面密码

    [root@docker01 harbor]# vim harbor.cfg 
        ···
        hostname = 10.0.0.100
        harbor_admin_password = Harbor12345
        ···

    3、执行安装脚本

    [root@docker01 harbor]# ./install.sh

    浏览器访问 http://10.0.0.11

    90e22d8cf82306a8c50ab87e090bd427.png

    添加一个项目

    93c2e535362234f2b6dc35e95347153d.png

    4、镜像推送到仓库的指定项目

    [root@docker02 ~]# docker  tag centos:6.8  10.0.0.100/clsn/centos6.8:1.0
    [root@docker02 ~]#  
    [root@docker02 ~]# docker images 
    REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
    busybox                     latest              5b0d59026729        8 days ago          1.15MB
    10.0.0.100/clsn/centos6.8   1.0                 6704d778b3ba        2 months ago        195MB
    centos                      6.8                 6704d778b3ba        2 months ago        195MB
    [root@docker02 ~]# docker login 10.0.0.100
    Username: admin
    Password: 
    Login Succeeded

    5、推送镜像

    [root@docker02 ~]# docker push 10.0.0.100/clsn/centos6.8 
    The push refers to repository [10.0.0.100/clsn/centos6.8]
    e00c9229b481: Pushing  13.53MB/194.5MB

    6、在web界面里查看

    4ea8cdd0753783d6c313c95866730e29.png

    14.1 使用容器的建议

    1. 不要以拆分方式进行应用程序发布

    2. 不要创建大型镜像

    3. 不要在单个容器中运行多个进程

    4. 不要再镜像内保存凭证,不要依赖IP地址

    5. 以非root用户运行进程

    6. 不要使用“最新”标签

    7. 不要利用运行中的容器创建镜像

    8. 不要使用单层镜像

    9. 不要将数据存放在容器内

    14.2 关于Docker容器的监控

    容器的基本信息

    包括容器的数量、ID、名称、镜像、启动命令、端口等信息

    容器的运行状态

    统计各状态的容器的数量,包括运行中、暂停、停止及异常退出

    容器的用量信息

    统计容器的CPU使用率、内存使用量、块设备I/O使用量、网络使用情况等资源的使用情况

    来源 | https://www.cnblogs.com/clsn/p/8410309.html

    往期推荐

    ☞ 专辑 | 趣味设计模式e01dc96216d16c297e8ce39f07075cca.gif

    ☞ 专辑 | 音视频开发

    ☞ 专辑 | C++ 进阶303a5ec23211488ce730ba432ca59889.gif

    ☞ 专辑 | 超硬核 Qt8acc63fcfef01080167f68744cf938f8.gif

    ☞ 专辑 | 玩转 Linux

    ☞ 专辑 | GitHub 开源推荐5944c80558ed821bdfea07bfb3473bb1.gif

    ☞ 专辑 | 程序人生

    关注公众「高效程序员」👇,一起优秀!

    回复 “入群” 进技术交流群,回复 “1024” 获取海量学习资源。

    展开全文
  • Docker教程.html

    2021-11-10 07:35:39
    Docker教程.html
  • Docker教程(超全总结)

    千次阅读 2022-04-20 10:52:50
    Docker基础+进阶总结,让你一文读懂Docker

    写在前面

    推荐一个不错的Docker讲解视频链接:https://www.bilibili.com/video/BV1og4y1q7M4

    【狂神说Java】Docker最新超详细版教程通俗易懂

    概述

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

    Docker Hub 网站: https://hub.docker.com/

    容器较为官方的解释

    一句话概括容器:容器就是将软件打包成标准化单元,以用于开发、交付和部署。

    • 容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。
    • 容器化软件适用于基于 Linux 和 Windows 的应用,在任何环境中都能够始终如一地运行。
    • 容器赋予了软件独立性,使其免受外在环境差异(例如,开发和预演环境的差异)的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。

    容器较为通俗的解释

    如果需要通俗地描述容器的话,我觉得容器就是一个存放东西的地方,就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样。我们现在所说的容器存放的东西可能更偏向于应用比如网站、程序甚至是系统环境。

    在这里插入图片描述

    虚拟化技术和容器化技术

    虚拟化技术

    首先,Docker 容器虚拟化技术为基础的软件,那么什么是虚拟化技术呢?

    简单点来说,虚拟化技术可以这样定义:

    虚拟化技术是一种资源管理技术,是将计算机的各种实体资源CPU内存磁盘空间网络适配器等),予以抽象、转换后呈现出来并可供分割、组合为一个或多个电脑配置环境。由此,打破实体结构间的不可切割的障碍,使用户可以比原本的配置更好的方式来应用这些电脑硬件资源。这些资源的新虚拟部分是不受现有资源的架设方式,地域或物理配置所限制。一般所指的虚拟化资源包括计算能力和数据存储。

    Docker 基于 LXC 虚拟容器技术

    Docker 技术是基于 LXC(Linux container- Linux 容器)虚拟容器技术的。

    LXC,其名称来自 Linux 软件容器(Linux Containers)的缩写,一种操作系统层虚拟化(Operating system–level virtualization)技术,为 Linux 内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。通过统一的名字空间和共用 API 来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得 Linux 用户可以容易的创建和管理系统或应用容器。

    LXC 技术主要是借助 Linux 内核中提供的 CGroup 功能和 name space 来实现的,通过 LXC 可以为软件提供一个独立的操作系统运行环境。

    cgroup 和 namespace 介绍:

    • namespace 是 Linux 内核用来隔离内核资源的方式。 通过 namespace 可以让一些进程只能看到与自己相关的一部分资源,而另外一些进程也只能看到与它们自己相关的资源,这两拨进程根本就感觉不到对方的存在。具体的实现方式是把一个或多个进程的相关资源指定在同一个 namespace 中。Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前 namespace 里的进程,对其他 namespace 中的进程没有影响。

      (以上关于 namespace 介绍内容来自https://www.cnblogs.com/sparkdev/p/9365405.html ,更多关于 namespace 的呢内容可以查看这篇文章 )。

    • CGroup 是 Control Groups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组 (process groups) 所使用的物力资源 (如 cpu memory i/o 等等) 的机制。

      (以上关于 CGroup 介绍内容来自 https://www.ibm.com/developerworks/cn/linux/1506_cgroup/index.html ,更多关于 CGroup 的呢内容可以查看这篇文章 )。

    cgroup 和 namespace 两者对比:

    两者都是将进程进行分组,但是两者的作用还是有本质区别。namespace 是为了隔离进程组之间的资源,而 cgroup 是为了对一组进程进行统一的资源监控和限制。

    Docker基本组成

    Docker 中有非常重要的三个基本概念,理解了这三个概念,就理解了 Docker 的整个生命周期。

    • 镜像(Image)
    • 容器(Container)
    • 仓库(Repository)

    理解了这三个概念,就理解了 Docker 的整个生命周期

    在这里插入图片描述

    Docker安装

    查看系统内核和系统信息

    命令:

    uname -r     #查看系统内核版本
    cat /etc/os-release  #查看系统版本
    

    示例:

    [root]# uname -r
    4.18.0-348.7.1.el8_5.x86_64
    
    [root]# cat /etc/os-release
    NAME="CentOS Linux"
    VERSION="8 (Core)"
    ID="centos"
    ID_LIKE="rhel fedora"
    VERSION_ID="8"
    PLATFORM_ID="platform:el8"
    PRETTY_NAME="CentOS Linux 8 (Core)"
    ANSI_COLOR="0;31"
    CPE_NAME="cpe:/o:centos:centos:8"
    HOME_URL="https://www.centos.org/"
    BUG_REPORT_URL="https://bugs.centos.org/"
    
    CENTOS_MANTISBT_PROJECT="CentOS-8"
    CENTOS_MANTISBT_PROJECT_VERSION="8"
    REDHAT_SUPPORT_PRODUCT="centos"
    REDHAT_SUPPORT_PRODUCT_VERSION="8"
    
    

    开始安装Docker

    卸载旧版本

    命令:

    yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
    

    示例:

    [root@iZ1608aqb7ntn9Z /]# yum remove docker \
    >                   docker-client \
    >                   docker-client-latest \
    >                   docker-common \
    >                   docker-latest \
    >                   docker-latest-logrotate \
    >                   docker-logrotate \
    >                   docker-engine
    No match for argument: docker
    No match for argument: docker-client
    No match for argument: docker-client-latest
    No match for argument: docker-common
    No match for argument: docker-latest
    No match for argument: docker-latest-logrotate
    No match for argument: docker-logrotate
    No match for argument: docker-engine
    没有软件包需要移除。
    依赖关系解决。
    无需任何处理。
    完毕!
    

    下载依赖安装包

    yum install -y yum-utils
    

    配置镜像仓库

    #国外的地址
    yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo  
        
    # 设置阿里云的Docker镜像仓库
    yum-config-manager \
        --add-repo \
        https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    

    示例:

    [root]# yum-config-manager \
    >     --add-repo \
    >     https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    添加仓库自:https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    

    更新yum软件包

    yum makecache fast 
    #更新索引的时候出错,即centos8没有该参数,解决办法为:去掉fast参数
    

    下载docker

    yum install docker-ce docker-ce-cli containerd.io   # 安装社区版
    yum install docker-ee docker-ee-cli containerd.io   # 安装企业版
    

    一般情况下安装社区版

    启动Docker

    命令:

    systemctl start docker   # 启动Docker
    docker version           # 查看当前版本号,是否启动成功
    systemctl enable docker  # 设置开机自启动
    

    示例:

    $ systemctl start docker
    
    $ docker version
    Client: Docker Engine - Community
     Version:           20.10.14
     API version:       1.41
     Go version:        go1.16.15
     Git commit:        a224086
     Built:             Thu Mar 24 01:47:44 2022
     OS/Arch:           linux/amd64
     Context:           default
     Experimental:      true
    
    Server: Docker Engine - Community
     Engine:
      Version:          20.10.14
      API version:      1.41 (minimum version 1.12)
      Go version:       go1.16.15
      Git commit:       87a90dc
      Built:            Thu Mar 24 01:46:10 2022
      OS/Arch:          linux/amd64
      Experimental:     false
     containerd:
      Version:          1.5.11
      GitCommit:        3df54a852345ae127d1fa3092b95168e4a88e2f8
     runc:
      Version:          1.0.3
      GitCommit:        v1.0.3-0-gf46b6ba
     docker-init:
      Version:          0.19.0
      GitCommit:        de40ad0
    
    

    Docker的HelloWorld

    命令:

    docker run hello-world
    

    示例:

    $ docker run hello-world
    Unable to find image 'hello-world:latest' locally  # 本地没有
    latest: Pulling from library/hello-world           # pull一个最新版
    2db29710123e: Pull complete                        # pull成功
    Digest: sha256:10d7d58d5ebd2a652f4d93fdd86da8f265f5318c6a73cc5b6a9798ff6d2b2e67
    Status: Downloaded newer image for hello-world:latest
    
    Hello from Docker!                                 # 运行结果
    This message shows that your installation appears to be working correctly.
    
    To generate this message, Docker took the following steps:
     1. The Docker client contacted the Docker daemon.
     2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
        (amd64)
     3. The Docker daemon created a new container from that image which runs the
        executable that produces the output you are currently reading.
     4. The Docker daemon streamed that output to the Docker client, which sent it
        to your terminal.
    
    To try something more ambitious, you can run an Ubuntu container with:
     $ docker run -it ubuntu bash
    
    Share images, automate workflows, and more with a free Docker ID:
     https://hub.docker.com/
    
    For more examples and ideas, visit:
     https://docs.docker.com/get-started/
    

    Docker卸载

    yum remove docker-ce docker-ce-cli containerd.io  # 卸载依赖
    rm -rf /var/lib/docker    # 删除资源  . /var/lib/docker是docker的默认工作路径
    

    配置阿里云镜像

    进入阿里云官网,搜索容器镜像服务

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dikPDByc-1628378213410)(Docker学习笔记.assets/image-20210803135001995.png)]

    执行命令

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

    Docker运行流程和原理

    在这里插入图片描述

    启动流程

    在这里插入图片描述

    运行原理

    在这里插入图片描述

    Docker整体架构

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p5ZfnhrM-1628378213415)(Docker学习笔记.assets/image-20210803134704395.png)]

    Docker常用命令

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

    管理镜像常用命令
    在这里插入图片描述

    创建容器

    容器限制

    基本命令

    命令:

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

    示例:

    $ docker info
    Client:
     Context:    default
     Debug Mode: false
     Plugins:
      app: Docker App (Docker Inc., v0.9.1-beta3)
      buildx: Docker Buildx (Docker Inc., v0.8.1-docker)
      scan: Docker Scan (Docker Inc., v0.17.0)
    
    Server:
     Containers: 1
      Running: 0
      Paused: 0
      Stopped: 1
     Images: 1
     Server Version: 20.10.14
    ......
    

    镜像命令

    docker images 查看本地主机的所有镜像

    示例:

    $ docker images
    REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
    hello-world   latest    feb5d9fea6a5   6 months ago   13.3kB
    

    列表参数介绍:

    # 解释:
    1.REPOSITORY  镜像的仓库源
    2.TAG  镜像的标签
    3.IMAGE ID 镜像的id
    4.CREATED 镜像的创建时间
    5.SIZE 镜像的大小
    
    # 可选参数
    -a/--all 列出所有镜像
    -q/--quiet 只显示镜像的id
    

    docker search 搜索镜像

    示例:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CzY36m6U-1628378213417)(Docker学习笔记.assets/image-20210803143107721.png)]

    #可选参数
    Search the Docker Hub for images
    Options:
      -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的镜像
    
    $ docker search mysql --filter=STARS=3000
    NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    mysql     MySQL is a widely used, open-source relation…   12427     [OK]
    mariadb   MariaDB Server is a high performing open sou…   4787      [OK]
    

    docker pull 镜像名[:tag] 下载镜像

    示例:

    $ docker pull mysql:5.7
    5.7: Pulling from library/mysql
    72a69066d2fe: Pull complete
    93619dbc5b36: Pull complete
    99da31dd6142: Pull complete
    626033c43d70: Pull complete
    37d5d7efb64e: Pull complete
    ac563158d721: Pull complete
    d2ba16033dad: Pull complete
    0ceb82207cd7: Pull complete
    37f2405cae96: Pull complete
    e2482e017e53: Pull complete
    70deed891d42: Pull complete
    Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
    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)
    

    容器命令

    docker run [可选参数] image 运行容器

    docker run [可选参数] image
    
    #参数说明
    --name="名字"           指定容器名字
    -d                     后台方式运行
    -it                    使用交互方式运行,进入容器查看内容
    -p                     指定容器的端口
    ( -p ip:主机端口:容器端口  配置主机端口映射到容器端口
      -p 主机端口:容器端口
      -p 容器端口)
    -P                     随机指定端口(大写的P)
    

    示例:

    $ docker run c20987f18b13
    2022-04-18 07:07:31+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
    2022-04-18 07:07:31+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
    2022-04-18 07:07:31+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
    2022-04-18 07:07:31+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
        You need to specify one of the following:
        - MYSQL_ROOT_PASSWORD
        - MYSQL_ALLOW_EMPTY_PASSWORD
        - MYSQL_RANDOM_ROOT_PASSWORD
    
    

    进入容器

    [root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -it [容器ID] /bin/bash
    

    exit 退出容器

    #exit 停止并退出容器(后台方式运行则仅退出)
    #Ctrl+P+Q  不停止容器退出
    [root@bd1b8900c547 /]# exit
    exit
    [root@iZwz99sm8v95sckz8bd2c4Z ~]#
    

    docker ps列出容器

    #docker ps 
         # 列出当前正在运行的容器
    -a   # 列出所有容器的运行记录
    -n=? # 显示最近创建的n个容器 (default -1)
    -q   # 只显示容器的编号
    -s   # 显示总文件大小
    
    
    $ docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    
    $ docker ps -a
    CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                      PORTS     NAMES
    703fad61eccb   c20987f18b13   "docker-entrypoint.s…"   2 minutes ago    Exited (0) 2 minutes ago              inspiring_feistel
    2e6f020d0299   c20987f18b13   "docker-entrypoint.s…"   3 minutes ago    Exited (1) 3 minutes ago              angry_stonebraker
    a4889b27716f   hello-world    "/hello"                 14 minutes ago   Exited (0) 14 minutes ago             trusting_mcclintock
    
    

    docker rm删除容器

    # 选项:
    -f   # 移除正在运行的容器(使用SIGKILL)
    -l   # 移除容器间的网络连接,而非容器本身
    -v   # 删除与容器关联的卷
    
    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 run -d ubuntu                                                   
    c21cd5dd2594ec109dfb7e8eeba6bd129291de1f1095389c9b31492e98360947
    
    #问题docker ps,发现ubuntu停止了
    
    #常见的坑,docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用了,就会自动停止
    #nginx,容器启动后发现自己没有提供服务,就会立刻停止,就是没有程序了
    

    查看日志

    $ docker logs --help
    
    Usage:  docker logs [OPTIONS] CONTAINER
    
    Fetch the logs of a container
    
    Options:
    -f       # 跟踪日志输出
    --since  # 显示某个开始时间的所有日志
    -t       # 显示时间戳
    -n      # 仅列出最新N条容器日志(默认为“全部”)
    
    常用:
    docker logs -tf 容器id
    docker logs --tail number 容器id #num为要显示的日志条数
    docker logs -n number 容器id     #num为要显示的日志条数
    
    #docker容器后台运行,必须要有一个前台的进程,否则会自动停止
    #编写shell脚本循环执行,使得centos容器保持运行状态
    $ docker run -d centos /bin/sh -c "while true;do echo hi;sleep 5;done"
    f51f3cbb27511b49d85c98fa62691a1a19397d4a272a8cc7d4769d3d6ec41f2a
    
    $ docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS         PORTS     NAMES
    f51f3cbb2751   centos    "/bin/sh -c 'while t…"   10 seconds ago   Up 9 seconds             busy_ride
    
    $ docker logs -tf --tail 10 f51f3cbb2751
    2022-04-18T07:24:27.364628955Z hi
    2022-04-18T07:24:32.365938530Z hi
    2022-04-18T07:24:37.367324268Z hi
    2022-04-18T07:24:42.368615239Z hi
    2022-04-18T07:24:47.369976390Z hi
    2022-04-18T07:24:52.371426169Z hi
    2022-04-18T07:24:57.372834380Z hi
    2022-04-18T07:25:02.374156939Z hi
    2022-04-18T07:25:07.375425598Z hi
    
    

    查看容器中进程信息

    # 命令 docker top 容器id
    $ docker top f51f3cbb2751
    UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
    root                17874               17853               0                   15:24               ?                   00:00:00            /bin/sh -c while true;do echo hi;sleep 5;done
    root                18164               17874               0                   15:25               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 5
    

    查看镜像的元数据

    $ docker inspect 容器id
    
    #docker inspect : 获取容器/镜像的元数据。
    
    #语法
    docker inspect [OPTIONS] NAME|ID [NAME|ID...]
    
    #OPTIONS说明:
    -f :指定返回值的模板文件。
    -s :显示总的文件大小。
    --type :为指定类型返回JSON。
    

    进入当前正在运行的容器

    方式一:

    
    
    # 我们通常容器使用后台方式运行的, 需要进入容器,修改一些配置
     
    # 命令
    docker exec -it 容器id /bin/bash
     
    # 测试
    $ docker exec -it df358bc06b17 /bin/bash
    [root@df358bc06b17 /]# ls       
    bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
    dev  home  lib64  media       opt  root  sbin  sys  usr
    [root@df358bc06b17 /]# ps -ef
    UID        PID  PPID  C STIME TTY          TIME CMD
    root         1     0  0 Aug11 pts/0    00:00:00 /bin/bash
    root        29     0  0 01:06 pts/1    00:00:00 /bin/bash
    root        43    29  0 01:06 pts/1    00:00:00 ps -ef
     
    # 方式二
    docker attach 容器id
     
    # docker exec       # 进入容器后开启一个新的终端,可以在里面操作
    # docker attach     # 进入容器正在执行的终端,不会启动新的进程
    
    #语法
    docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
    
    #OPTIONS说明:
    -d :分离模式: 在后台运行
    -i :即使没有附加也保持STDIN 打开
    -t :分配一个伪终端
    

    拷贝容器文件到主机

    拷贝容器的文件到主机中

    docker cp 容器id:容器内路径 目的主机路径
    
    #进入容器中
    
    $ docker cp 8b84603c410a:/home/test.java /home
    
    
    $ ls
    alex  arod  hello.java  neos  test.java
    
    #拷贝只是一个手动功能,未来我们使用 -v 卷的技术,可以实现自动同步
    

    常用命令小结

    在这里插入图片描述

    Docker图形化管理工具

    Docker UI

    命令:

    docker search dockerui
    docker pull abh1nav/dockerui
    docker run -d --privileged --name dockerui -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock abh1nav/dockerui  
    #放开物理机的9000端口对应Docker容器的9000端口
    

    示例:

    $ docker search dockerui
    NAME                           DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    abh1nav/dockerui               An updated version of crosbymichael/dockerui…   99                   [OK]
    kevan/dockerui                 Deprecated: Use  uifd/ui-for-docker             15                   [OK]
    ......
    
    $ docker pull abh1nav/dockerui
    Using default tag: latest
    latest: Pulling from abh1nav/dockerui
    Image docker.io/abh1nav/dockerui:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
    a3ed95caeb02: Pull complete
    5d3df020ecd3: Pull complete
    bebf5a3b4dfb: Pull complete
    e4452c0fe72b: Pull complete
    6167d9726b07: Pull complete
    53ebae19a314: Pull complete
    Digest: sha256:a9c6c5393f561a0f42f41cfa80572b666e745d9b419569c42bac1e5cf9ceda32
    Status: Downloaded newer image for abh1nav/dockerui:latest
    docker.io/abh1nav/dockerui:latest
    
    $ docker run -d --privileged --name dockerui -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock abh1nav/dockerui
    959047ff6deba1e5d31017024a41b611e48f416a6f87f2cad4f528801a260c52
    
    

    使用:

    访问:http://ip地址:9000
    

    会出现如下的界面:

    Shipyard

    镜像下载

    [docker@docker ~]$ docker pull alpine
    [docker@docker ~]$ docker pull library/rethinkdb
    [docker@docker ~]$ docker pull microbox/etcd
    [docker@docker ~]$ docker pull shipyard/docker-proxy
    [docker@docker ~]$ docker pull swarm
    [docker@docker ~]$ docker pull shipyard/shipyard   (#英文版)
    

    脚本安装shipyard

    #安装shipyard中文版
    
    curl http://dockerclub.net/deploy | bash -s
    

    Portainer

    命令:

    docker search portainer
    docker pull portainer/portainer
    docker run -d --name portainerUI -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
    
    

    示例:

    $ docker search portainer
    NAME                                   DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    portainer/portainer                    This Repo is now deprecated, use portainer/p…   2201
    portainer/portainer-ce                 Portainer CE - a lightweight service deliver…   1100
    ......                  
    
    $ docker pull portainer/portainer
    Using default tag: latest
    latest: Pulling from portainer/portainer
    94cfa856b2b1: Pull complete
    49d59ee0881a: Pull complete
    a2300fd28637: Pull complete
    Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
    Status: Downloaded newer image for portainer/portainer:latest
    docker.io/portainer/portainer:latest
    
    $ docker run -d --name portainerUI -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
    abbf483bd3df0e30eaeb3a0dd708776a6fbbf055e2c87bcb84177df7e86c8ac2
    

    使用:

    访问:http://ip地址:9000
    

    常见容器部署:Nginx, Tomcat, es + kibana

    Nginx

    命令:

    # 1. 查找镜像, 建议去docker官网搜索,可以看到帮助文档 https://registry.hub.docker.com/
    docker search nginx
    
    # 2. 下载镜像 pull
    docker pull nginx
    
    # 3. 运行测试
    docker images
    
    # 4.
    
    docker run -d --name nginx -p 3344:80 nginx   # 启动
    curl localhost:3344  # 本机测试访问
    # 备注
    # -d 后台运行
    # --name 给容器命名
    # -p 3334:80 将宿主机的端口3334映射到该容器的80端口
    
    
    # 进入容器
    $ docker exec -it nginx /bin/bash
    root@c70636684cd8:/# whereis nginx
    nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
    root@c70636684cd8:/# cd /etc/nginx/
    root@c70636684cd8:/etc/nginx# ls
    conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params
    
    # 关闭容器
    $ docker ps
    CONTAINER ID   IMAGE              COMMAND                  CREATED             STATUS             PORTS                                       NAMES
    c70636684cd8   nginx              "/docker-entrypoint.…"   11 minutes ago      Up 11 minutes      0.0.0.0:3344->80/tcp, :::3344->80/tcp       nginx
    959047ff6deb   abh1nav/dockerui   "./dockerui"             About an hour ago   Up About an hour   0.0.0.0:9000->9000/tcp, :::9000->9000/tcp   dockerui
    f51f3cbb2751   centos             "/bin/sh -c 'while t…"   About an hour ago   Up About an hour                                               busy_ride
    
    $ docker stop c70636684cd8
    c70636684cd8
    # 发现访问不了此网站
    

    测试访问:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Aqvif9AC-1628378213420)(Docker学习笔记.assets/image-20210804143438878.png)]

    Tomcat

    命令:

    # 官方的使用
    docker run -it --rm tomcat:9.0
    # 我们之前的启动都是后台的,停止了容器之后, 容器还是可以查到,docker run -it --rm 一般用来测试,用完就删
    
    # 下载再启动
    docker pull tomcat
    
    # 启动运行
    docker run -d -p 3355:8080 --name tomcat01 tomcat
    
    # 测试访问没有问题
    
    # 进入容器
    docker exec -it tomcat01 /bin/bash
    
    # 发现问题:1.linux命令少了, 2. webapps下内容为空,阿里云默认是最小的镜像,所有不必要的都剔除了
    # 保证最小可运行环境即可
    
    root@fd58d9c477e4:/usr/local/tomcat# cp -r webapps.dist/* webapps
    ## 网站恢复访问
    

    测试访问:

    es + kibana

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

    docker stats 查看资源占用情况

    # es 暴露的端口很多
    # es 十分的耗内存
    # es 的数据一般需要放置到安全目录! 挂载
    # --net somenetwork ?  网络配置
     
    # 启动elasticsearch
    docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
     
    $ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
    a920894a940b354d3c867079efada13d96cf9138712c76c8dea58fabd9c7e96f
     
    # 启动了linux就卡住了,docker stats 查看cpu状态
     
    # 测试一下es成功了
    $ curl localhost:9200
    {
      "name" : "a920894a940b",
      "cluster_name" : "docker-cluster",
      "cluster_uuid" : "bxE1TJMEThKgwmk7Aa3fHQ",
      "version" : {
        "number" : "7.6.2",
        "build_flavor" : "default",
        "build_type" : "docker",
        "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
        "build_date" : "2020-03-26T06:34:37.794943Z",
        "build_snapshot" : false,
        "lucene_version" : "8.4.0",
        "minimum_wire_compatibility_version" : "6.8.0",
        "minimum_index_compatibility_version" : "6.0.0-beta1"
      },
      "tagline" : "You Know, for Search"
    }
     
     
    # 增加内存限制,修改配置文件 -e 环境配置修改
    docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
    
    $ docker stats
    

    端口暴露的原理

    [外链图片转存中...(img-wrWtj9Ol-1628378213423)]

    可视化

    • portainer(先用这个)
    docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
     
    # 测试
    $ curl localhost:8088
    <!DOCTYPE html
    ><html lang="en" ng-app="portainer">
    ......
        ><!-- End Page Wrapper -->
      <script type="text/javascript" src="vendor.50213a000e42f5c05bcc.js"></script><script type="text/javascript" src="main.50213a000e42f5c05bcc.js"></script></body></html
    >
    
    # 外网访问 http://ip:8088
    
    

    • Rancher(CI/CD再用)

    Docker镜像讲解

    镜像是什么

    Docker镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含某个软件所需的所有内容,包括代码、库、环境变量、配置文件、运行时环境等。
    所有的应用,直接打包成Docker镜像,然后通过镜像创建出容器,然后就可以直接跑起来。

    如何得到镜像:

    • 从远程仓库下载,比如docker hub、阿里云的镜像仓库等。
    • 朋友拷贝给你。
    • 自己制作一个镜像DockerFile。

    通过对原有的镜像创建的容器进行一些修改(也可以不修改),然后通过Commit命令提交一个新的镜像。

    UnionFS(联合文件系统)

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

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

    Docker镜像加载原理

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

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

    • rootfs(root file system),包含典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同Unix操作系统发行版(Ubuntu,Centos等)。因为底层直接用Host的kernel,rootfs只包含最基本的命令,工具和程序就可以了。

    我们平时安装的虚拟机centos镜像好几个G,Docker安装的才200多M,因为对于一个精简的OS,rootfs可以很小,只需包含最基本的命令,工具和程序库就行了,因为底层直接使用宿主机的内核,自己只需提供rootfs(相当于操作内核的客户端)就可以,由此可见不同发行版的bootfs基本是一致的,roorfs有差别,因此不同的发行版可以公有bootfs。虚拟机是分钟级别,容器是秒级。

    第一个图仅仅是bootfs+rootfs,然后如果要制作一个emacs环境的镜像,就在这个基础上新加一层emacs镜像,如图二。如果要在添加一个Apache环境,那就再图二基础上加一个apache镜像。如图三。图中的每一层镜像都能进行复用。

    分层理解

    分层的镜像

    image-20210521222350269

    比如:上面的redis镜像。使用docker inspect redis镜像的ID 命令查看镜像的元信息,找到layer信息。

    image-20210521222535031

    由上图可以看到下载的redis镜像是由6个镜像一层层组成的。

    19-4

    这些镜像都是一个个独立可复用的镜像,如果下载其他镜像是,某一层镜像是已经存在本地的了,就不用在下载,直接复用该镜像,节省空间。比如上面下载redis镜像时,提示某个镜像已经存在。

    注意
    Docker镜像都是只读的,用镜像创建容器启动时,实际上是在原本的镜像上新建了一层可写层到原本镜像的顶部,这一层我们叫作容器层,容器层之下的叫作镜像层。

    在这里插入图片描述

    如上图,使用Tomcat镜像创建容器后,会在Tomcat镜像的基础上新建一个可写层,容器的写入是在可写层进行记录,然后使用commit命令把该容器创建一个新的镜像,实际上新的镜像是tomcat镜像+可写层镜像,以tomcat镜像为基础。通过下面介绍使用容器构建镜像,可以更好地理解。

    commit镜像

    命令:

    docker commit 提交容器成为一个新的副本
    docker commit -m="描述信息,类似git提交的信息" -a="作者" 容器id  目标镜像名:[TAG]$ 编辑容器后提交容器成为一个新镜像a
    

    实战测试

    #1.启动一个默认的tomcat
    docker run -it -p 8080:8080 tomcat
    #2.发现这个默认的tomcat是没有webapps的应用,镜像的原因,官方的镜像默认webapps下面是没有文件的
    
    #3.自己拷贝进去基本的文件
    cp -r webapps.dist/* webapps
    
    #4.将修改后的容器通过commit提交为新的镜像~我们以后就使用我们自己制作的镜像了
    docker commit =a="lixingze" -m="add webapps app" 容器ID tomcat02:1.0
    

    image-20210521224755933

    容器数据卷

    什么是容器数据卷

    为了实现数据持久化,使容器之间可以共享数据。可以将容器内的目录,挂载到宿主机上或其他容器内,实现同步和共享的操作。即使将容器删除,挂载到本地的数据卷也不会丢失。

    docker的理念回顾

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

    数据如果都在容器中,那么我们容器一旦删除,数据就会丢失 需求:数据可以持久化

    MySQL,容器删了,删库跑路 需求:MySQL数据可以存储在本地

    容器之间可以有一个数据共享的技术,Docker容器中产生的数据同步到本地

    这就是卷技术,目录的挂载将我们容器内的目录挂载到Linux上面

    容器的持久化和同步操作,容器间也是可以做数据共享的

    使用数据卷

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

    docker run -it -v 主机目录:容器内目录
    
    #测试
    $ docker run -it -v /home/ceshi:/home centos /bin/bash
    
    #启动后查看挂载情况
    $ docker inspect 990046eb50f5
    

    在这里插入图片描述

    测试文件的同步(在主机上改动,观察容器变化)

    在这里插入图片描述

    再来测试(测试通过)

    1. 停止容器

    2. 主机上修改文件

    3. 启动容器

    4. 容器内的数据依旧是同步的!

    好处:我们以后只要在本地进行修改即可,不需要每次都进入容器内部都能实现自动同步

    实战:安装MySQL

    思考:MySQL的数据持久化的问题!

    #获取镜像
    $ docker pull mysql
    
    #运行容器,需要做数据挂载 
    #安装启动mysql需要配置密码(注意)
    #官方测试:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
    
    #启动自己的
    -d 后台运行
    -p 端口映射
    -e 环境配置
    --name 容器名字
    
    $ 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=[password] --name mysql01 mysql
    
    #启动成功之后,在本地用数据库连接工具测试连接(我使用的Navicat Premium)
    
    #sql可视化工具连接到服务器的3310 ---- 3310 和容器内的3306映射,成功连接
    
    #在本地测试创建一个数据库,发现mysql/data 中增加了数据库数据
    

    image-20210524213345565

    假设删除了docker镜像

    发现,挂载到本地的数据卷依然没有丢失,这实现了容器数据持久化功能

    具名和匿名挂载

    #匿名挂载
    -v 容器内挂载
    docker run -d -P --name nginx01 -v /etc/nginx nginx    $ -P 随机指定端口
    
    #查看所有的volume的情况
    $ docker volume ls
    DRIVER    VOLUME NAME
    local     8026aa409bf4851f9056cc3092e27493db1ee654b461b1ea05c3bedfafed3e32
    #这里发现这种就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外的路径
    
    #具名挂载
    
    $ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
    72bf479b190b74d53256311e626bab459630af2028b9c9e1a83064c2ff745d9e
    
    $ docker volume ls
    $ docker volume ls
    DRIVER    VOLUME NAME
    local     8026aa409bf4851f9056cc3092e27493db1ee654b461b1ea05c3bedfafed3e32
    local     04862392ad0fcff6ecabd65989ae57e109a9963de0d517f4e8b305b44700795a
    local     d7111fd00a6d3704ec4bd5419eee07ba6c4bac699abe227b908f6d385188c472
    local     jumping-nginx
    
    
    # 通过-v 卷名:容器内的路径
    # 查看一下这个卷
    # docker volume inspect juming-nginx
     
    $ docker volume inspect juming-nginx
    [
        {
            "CreatedAt": "2022-04-19T14:52:24+08:00",
            "Driver": "local",
            "Labels": null,
            "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
            "Name": "jumping-nginx",
            "Options": null,
            "Scope": "local"
        }
    ]
    

    所有docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxxx/_data

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

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

    拓展

    #通过-v容器内路径,ro rw改变读写权限
    ro		read only #只读
    rw		read write #可读可写
    
    #一旦这个设置了容器权限,容器对我们挂载出来的内容就有限定了
    $ docker run -d -P --name nginx02 -v jumping-nginx:/etc/nginx:ro nginx  
    $ docker run -d -P --name nginx02 -v jumping-nginx:/etc/nginx:rw nginx  
    
    #ro 只要看到ro就说明这个路径是只能通过宿主机来操作,容器内部是无法操作
    

    初识DockerFile

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

    通过这个脚本可以生成一个镜像,镜像是一层一层的,脚本一个个的命令对应层数

    #创建一个dockerfile文件,名字可以随意,建议Dockerfile
    #文件中的内容 指令(大写) 参数
    FROM centos
    
    VOLUME ["volume01","volume02"]
    
    CMD echo "----end----"
    CMD /bin/bash    
    
    #这里的每个命令,就是镜像的一层
    

    部署容器

    1

    启动自己的容器

    2

    这个卷和外部一定有一个同步的目录!

    3

    在目录下新建一个测试用的文件

    3-1

    查看卷挂载的路径

    4

    测试一下刚才的文件是否同步到主机上了

    5

    成功。

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

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

    数据卷容器

    多个mysql同步数据!

    6

    #启动三个容器,通过我们自己写的镜像启动
    

    7

    CTRL+p+q 退出当前的docker01,通过docker01挂载docker02

    8

    同理创建一个docker03,在数据卷上新建的文件也会在其它容器上同步

    #只要通过 --volumes-from 我们就可以实现容器间的数据共享
    
    #当删除了docker01时,docker02和docker03经测试依然可以访问建立的文件
    

    多个mysql实现数据共享

    $ 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=[password] --name mysql01 mysql
    
    $ docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=[password] --name mysql02 --volumes-from mysql01 mysql
    
    #这个时候可以实现两个容器数据同步
    

    结论

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

    但是一旦持久化到了本地,这个时候,本地的数据是不会被删除的。

    DockerFile

    DockerFile介绍

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

    构建步骤:

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

    查看一下官方是怎么做的

    9

    10

    很多官方镜像都是基础包,我们通常会自己搭建自己的镜像。

    官方既然可以制作镜像,那我们也可以自己构建。

    DockerFile构建过程

    基础知识:

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

    2. 执行顺序从上到下

    3. #表示注释

    4. 每一个指令都会创建提交一个新的镜像层,并提交!

    Docker镜像原理

    Dockerfile概念及作用

    Dockerfile 关键字

    关键字作用备注
    FROM指定父镜像指定dockerfile基于那个image构建
    MAINTAINER作者信息用来标明这个dockerfile谁写的
    LABEL标签用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看
    RUN执行命令执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN [“command” , “param1”,“param2”]
    CMD容器启动命令提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD [“command” , “param1”,“param2”]
    ENTRYPOINT入口一般在制作一些执行就关闭的容器中会使用
    COPY复制文件build的时候复制文件到image中
    ADD添加文件build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务
    ENV环境变量指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value
    ARG构建参数构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数
    VOLUME定义外部可以挂载的数据卷指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME [“目录”]
    EXPOSE暴露端口定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
    WORKDIR工作目录指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径
    USER指定执行用户指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户
    HEALTHCHECK健康检查指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
    ONBUILD触发器当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大
    STOPSIGNAL发送信号量到宿主机该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
    SHELL指定执行脚本的shell指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell

    Dockerfile 案例

    dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单。

    步骤:开发、部署、上线运维

    Dockerfile:构建文件,定义了一切的步骤,源代码

    Dockerimage:通过Dockerfile构建生成的镜像,最终发布和运行的产品

    Docker容器:镜像运行起来提供服务

    DockerFile指令

    以前的时候我们是使用别人的,现在我们尝试用dockerfile构建一个自己的镜像

    FROM 		#基础镜像,一切从这里开始构建
    MAINTAINER	#镜像是谁写的,姓名+邮箱
    RUN			#镜像构建时需要运行的命令
    ADD			#步骤,tomcat镜像,这个tomcat压缩包;添加内容
    WORKDIR		#镜像工作目录
    VOLUME		#挂载的目录
    EXPOSE		#暴露端口配置
    CMD			#指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
    ENTRYPOINT	#指定这个容器启动的时候要运行的命令,可以追加命令
    ONBUILD		#当构建一个被继承DockerFile 这个时候就会运行 ONBUILD 的指令,触发指令
    COPY		#类似ADD,将我们的文件拷贝至镜像中
    ENV			#构建的时候设置环境变量
    

    11

    实战测试

    DockerHub中99%的镜像都是从基础镜像过来的 FROM scratch,然后配置需要的软件和配置来进行构建

    12

    创建一个自己的centos

    #1.编写DockerFile的文件
    
    $ cat mydockerfile-centos 
    FROM centos:7
    MAINTAINER lixingze<lixingzee@gmail.com>
    
    ENV MYPATH /user/local
    WORKDIR $MYPATH
    
    RUN yum -y install vim
    RUN yum -y install net-tools
    
    EXPOSE 80
    
    CMD echo $MYPATH
    CMD echo "-----end-----"
    CMD /bin/bash
    
    #2.通过这个文件构建镜像
    #命令 docker build -f dockerfile文件路径 -t 镜像名:[tag]
    
    $ docker build -f mydockerfile-centos -t mycentos:0.1 .
    
    Successfully built c8310c185c21
    Successfully tagged mycentos:0.1
    
    #3.测试运行
    

    对比之前原生的centos:增加之后的镜像默认进入了工作目录,且可以使用vim

    13

    我们可以列出本地进行的变更历史

    14

    我们平时拿到一个镜像,可以研究一下它是如何构建的了。

    CMD 和 ENTRYPOINT 区别

    CMD			#指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
    ENTRYPOINT	#指定这个容器启动的时候要运行的命令,可以追加命令
    

    测试CMD

    #1.编写dockerfile文件
    
    $ cat dockerfile-cmd-test
    FROM centos:7
    CMD ["ls","-a"]
    
    #2.构建镜像
    
    $ docker build -f dockerfile-cmd-test -t cmdtest .
    
    #3.启动容器
    
    $ docker run 608fe2c633ee
    .
    ..
    .dockerenv
    bin
    dev
    etc
    home
    lib
    lib64
    lost+found
    media
    mnt
    opt
    proc
    root
    run
    sbin
    srv
    sys
    tmp
    usr
    var
    
    #想追加一个命令 -ls -al
    
    $ docker run 608fe2c633ee -l
    docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
    
    #cmd的清理下 -l替换了["ls","-a"]命令,-l不是命令所以报错 !
    

    测试ENTRYPOINT

    # 1. 编写dockerfile文件
    $ vim dockerfile-entrypoint-test 
    FROM centos
    ENTRYPOINT ["ls", "-a"]
     
    # 2. 构建文件
    $ docker build -f dockerfile-entrypoint-test -t entrypoint-test .
     
    # 3. run运行 发现我们的ls -a 命令同样生效
    $ docker run entrypoint-test
    .
    ..
    .dockerenv
    bin
    dev
    etc
    home
    lib
     
    # 4. 我们的追加命令, 是直接拼接到ENTRYPOINT命令的后面的!
    $ docker run entrypoint-test -l
    total 56
    drwxr-xr-x  1 root root 4096 Aug 13 07:52 .
    drwxr-xr-x  1 root root 4096 Aug 13 07:52 ..
    -rwxr-xr-x  1 root root    0 Aug 13 07:52 .dockerenv
    lrwxrwxrwx  1 root root    7 May 11  2019 bin -> usr/bin
    drwxr-xr-x  5 root root  340 Aug 13 07:52 dev
    drwxr-xr-x  1 root root 4096 Aug 13 07:52 etc
    drwxr-xr-x  2 root root 4096 May 11  2019 home
    lrwxrwxrwx  1 root root    7 May 11  2019 lib -> usr/lib
    lrwxrwxrwx  1 root root    9 May 11  2019 lib64 -> usr/lib64
    drwx------  2 root root 4096 Aug  9 21:40 lost+found
     
    

    DockerFile中很多命令都十分相似,我们需要了解他们的区别,最好的学习方式就是测试并对比效果

    实战:Tomcat镜像

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

    15

    1. 编写dockerfile文件,官方命名Dockerfile,build会自动寻找这个文件,就不需要 -f 进行指定了
    $ cat Dockerfile
    FROM centos:7
    MAINTAINER lixingze<lixingzee@gmail.com>
    
    COPY README.txt /user/local/README.txt
    
    ADD jdk-8u202-linux-x64.tar.gz /usr/local
    ADD apache-tomcat-10.0.20.tar.gz /usr/local
    
    RUN yum -y install vim
    
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    ENV JAVA_HOME /usr/local/jdk1.8.0_202
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-10.0.20
    ENV CATALINA_BASH /usr/local/apache-tomcat-10.0.20
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    
    EXPOSE 8080
    
    CMD /usr/local/apache-tomcat-10.0.20/bin/startup.sh && tail -F /usr/local/apache-tomcat-10.0.20/bin/logs/catalina.out
    
    1. 构建镜像
    #docker build -t diytomcat .
    
    1. 启动镜像
    $ docker run -d -p 9090:8080 --name lxztomcat -v /home/lxz/build/tomcat/test:/usr/local/apache-tomcat-10.0.20/webapps/test -v /home/lxz/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-10.0.20/logs diytomcat
    f8fcb1d5565c7a00a46ff95ee7effb3b19a58931bb47b385cf6b11fe06cc4676
    
    1. 访问测试
    #本地测试
    curl localhost:9090
    

    访问网站

    16

    1. 发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了)

    在tomcat的test文件夹下建立文件夹WEB-INF ,在其中创建web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
      <display-name>FirstWebFontEnd</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    

    在test文件夹下创建index.jsp文件

    <%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>首页</title>
    <style>
        *{
        padding:0;
        margin:0;
        font-family:"微软雅黑";
    }
    .header{
        height:72px;
        background:#458fce ;
    }
    .header .logo{
        color:#fff ;
        line-height:70px;
        font-size:30px;
        margin-left:20px;
        display:inline-block;
        text-align:center;
    
    }
    a {
        color: #fff ;
        text-decoration: none ;
    }
    .header .login{
        float:right;
        color:#fff ;
        line-height:72px;
        margin-right:2px;
        display:inline-block;
    }
    .banner{
        height:380px;
        overflow:hidden;
        background: #ddd;
    }
    </style>
    </head>
    <body>
        <div class="header">
            <div class="logo">web实践</div>
            <div class ="login">
                <a href ="javascript:void(0)">登录</a>
                <span>|</span> 
                <a href ="javascript:void(0)">故事</a>
            </div>
        </div>
    Hello World!<br/>
    My blog is lxz9.com!<br/>
    </body>
    </html>
    

    发现:项目部署成功,可以正常访问页面http://IP地址:9090/test/

    17

    以后开发的步骤:需要掌握Dockerfile的编写,我们之后的一切都是使用docker镜像来进行

    发布自己的镜像

    DockerHub

    1. 地址https://hub.docker.com/ 注册自己的账号

    2. 确定这个账号可以登录

    3. 在我们的服务器上提交自己的镜像

    $ docker login --help
    
    Usage:  docker login [OPTIONS] [SERVER]
    
    Log in to a Docker registry.
    If no server is specified, the default is defined by the daemon.
    
    Options:
      -p, --password string   Password
          --password-stdin    Take the password from stdin
      -u, --username string   Username
    
    1. 登录完毕后就可以提交镜像了 docker push
    $ docker login -u xingzeli
    Password:
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    
    Login Succeeded
    

    5.提交镜像

    #如果报错可以更改镜像名称试试 尽量带上版本号
    $ docker tag diytomcat xingzeli/tomcat:1.0  
    
    $ docker push xingzeli/tomcat:1.0
    The push refers to repository [docker.io/xingzeli/tomcat]
    85d10e85e1ff: Pushed
    d3da19ae481a: Pushed
    533ab4087ebb: Pushed
    e7d29c8e7b5a: Pushed
    174f56854903: Mounted from library/centos
    1.0: digest: sha256:dff3c979a270967f2bc1b1e18170bb515c0e67938ee38f0971c1ecc7d58f06ac size: 1373
    

    提交的时候也是按照镜像层级来进行提交的

    阿里云镜像服务

    1. 登录阿里云

    2. 找到容器镜像服务

    3. 创建命名空间

    4. 创建容器镜像

    5. 浏览阿里云

    18

    小结:

    19

    Docker 网络

    理解Docker0

    清空所有环境

    # 1.列出所有的容器 ID:
    docker ps -aq
    
    # 2.停止所有的容器:
    docker stop $(docker ps -aq)
    
    # 3.删除所有的容器:
    docker rm $(docker ps -aq)
    
    # 4.删除所有的镜像:
    docker rmi $(docker images -q)
    

    20

    三个网络

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

    21

    Docker在官网下载Tomcat镜像里面没有ip addr等命令解决

    $ docker exec -it tomcat01 ip addr
    OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ip": executable file not found in $PATH: unknown
    #容器里执行ip addr 显示 ip command not found 与tomcat镜像有关,最新版的镜像阉割了很多命令,连最基本的yum命令都没有了,如果容器内有yum,可以用 yum install net-tools 之后用ifconfig也一样,如果没有yum 则进入容器 cat /etc/hosts
    

    解决方案:

    1. 进入上面你利用Tomcat镜像运行的容器。
    root 16:50:34 ~
    $ docker exec -it tomcat01 /bin/bash
    
    1. 执行下面两个命令
    root@7cc13e6f0963:/usr/local/tomca$ apt update
    root@7cc13e6f0963:/usr/local/tomca$ apt install -y iproute2
    
    #apt install -y net-tools
    #apt install -y iproute2
    #apt install -y iputils-ping
    
    1. 成功
    $ docker run -d -P --name tomcat01 tomcat
    
    $ docker exec -it tomcat01 ip addr
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
    70: eth0@if71: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    #查看容器的内部ip地址  ip addr ,  发现容器启动的时候会得到一个 eth0@if71 ip地址,这是由docker分配的
    
    
    #思考:linux能不能 ping 通容器内部?
    $ ping 172.17.0.2
    PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
    64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.028 ms
    64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.013 ms
    64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.014 ms
    
    #linux可以 ping 通docker容器内部
    

    原理:

    1. 我们每启动一个docker容器,docker就会给docker容器分配一个id,我们只要安装了docker,就会有一个网卡docker0

    桥接模式,使用的技术是veth-pair技术

    再次测试 ip addr

    20-1

    1. 再启动一个容器测试,发现又多了一对网卡

    20-2

    #我们发现这个容器带来的网卡都是一对一对的
    #veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连(可以通信)
    #正因为有这个特性, veth-pair 充当一个桥梁,连接各种虚拟网络设备的
    #Openstac,Docker容器之间的连接,OVS的连接,都是使用veth-pair技术
    
    1. 我们来测试下tomcat01和tomcat02是否可以ping通

    20-3

    $ docker exec -it tomcat02 ping 172.17.0.2
    PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
    64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.078 ms
    64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.032 ms
    64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.021 ms
    
    #结论:容器和容器之间是可以互相ping通的
    

    绘制一个网络模型图

    22

    结论:tomcat01 和tomcat02 是共用的一个路由器,docker0。

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

    小结

    docker使用的是Linux的桥接,宿主机中是一个docker容器的网桥 docker0

    23

    docker中所有网络接口都是虚拟的,虚拟的转发效率高!(内网传递文件)

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

    20-4

    –link

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

    $ docker exec -it tomcat02 ping tomcat01
    ping: tomcat01: Name or service not known
     
    # 如何可以解决呢?
    # 通过--link既可以解决网络连通问题
    $ docker run -d -P  --name tomcat03 --link tomcat02 tomcat
    24fe246a54f3e169b18db73e71f17694ffbe95900b885a4653a232023ad0635b
    
    $ docker ps
    CONTAINER ID   IMAGE     COMMAND             CREATED              STATUS              PORTS                                         NAMES
    24fe246a54f3   tomcat    "catalina.sh run"   About a minute ago   Up About a minute   0.0.0.0:49160->8080/tcp, :::49160->8080/tcp   tomcat03
    56140c84bab0   tomcat    "catalina.sh run"   33 minutes ago       Up 33 minutes       0.0.0.0:49159->8080/tcp, :::49159->8080/tcp   tomcat02
    7cc13e6f0963   tomcat    "catalina.sh run"   3 hours ago          Up 3 hours          0.0.0.0:49158->8080/tcp, :::49158->8080/tcp   tomcat01
    
    $ docker exec -it tomcat03 ping tomcat02
    PING tomcat02 (172.17.0.3) 56(84) bytes of data.
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.129 ms
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.100 ms
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.110 ms
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=4 ttl=64 time=0.107 ms
     
    # 反向可以ping通吗?
    $ docker exec -it tomcat02 ping tomcat03
    ping: tomcat03: Name or service not known
    
    
    
    $ docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    be0679d23977   bridge    bridge    local
    d334b9fee722   host      host      local
    e56141257cf7   none      null      local
    
    $ docker network inspect be0679d23977
    # 探究:inspect
    

    20-5

    其实这个tomcat03就是在本地配置了tomcat02的配置

    $ docker exec -it tomcat03 cat /etc/hosts
    127.0.0.1   localhost
    ::1 localhost ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
    172.17.0.3  tomcat02 56140c84bab0
    172.17.0.4  24fe246a54f3
    

    本质探究:–link 就是我们在hosts配置中增加了一个172.17.0.3 tomcat02 56140c84bab0

    我们现在玩Docker已经不建议使用–link了!

    自定义网络!不使用Docker0!

    Docker0的问题:它不支持容器名链接访问!

    自定义网络

    查看所有的docker网络

    $ docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    be0679d23977   bridge    bridge    local
    d334b9fee722   host      host      local
    e56141257cf7   none      null      local
    

    网络模式

    bridge: 桥接模式,桥接 docker 默认,自己创建的也是用brdge模式

    none: 不配置网络

    host: 和宿主机共享网络

    container:容器网络连通!(用的少, 局限很大)

    • 测试
    # 我们直接启动的命令默认有一个 --net bridge,而这个就是我们的docker0
    docker run -d -P --name tomcat01 tomcat
    docker run -d -P --name tomcat01 --net bridge tomcat
     
    # docker0特点,默认,容器名不能访问, --link可以打通连接!
    # 我们可以自定义一个网络!
    # --driver bridge
    # --subnet 192.168.0.0/16 可以支持255*255个网络 192.168.0.2 ~ 192.168.255.254
    # --gateway 192.168.0.1
    $ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
    340bd988f751b88da07e0213fc3941068eb5eb19dcd563b9fc9f4b952b1bc8db
    
    $ docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    be0679d23977   bridge    bridge    local
    d334b9fee722   host      host      local
    340bd988f751   mynet     bridge    local
    e56141257cf7   none      null      local
    

    我们自己的网络就创建好了

    20-6-1

    在自己创建的网络里面启动两个容器

    $ docker run -d -P --name tomcat-net-01 --net mynet tomcat
    a3aa944c9cba8b72a540fa58d914f098282be89dd81e7f29f9cef91249898749
    
    $ docker run -d -P --name tomcat-net-02 --net mynet tomcat
    93210c62a4f513800aa3cf00310eab710427f2f5d0e95a9e177a5e13fe06fe7a
    
    $ docker network inspect mynet
    [
        {
            "Name": "mynet",
            "Id": "340bd988f751b88da07e0213fc3941068eb5eb19dcd563b9fc9f4b952b1bc8db",
            "Created": "2022-04-20T20:37:39.632971496+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "192.168.0.0/16",
                        "Gateway": "192.168.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {
                "93210c62a4f513800aa3cf00310eab710427f2f5d0e95a9e177a5e13fe06fe7a": {
                    "Name": "tomcat-net-02",
                    "EndpointID": "b1aaabbb9c8c27797a3577fdb1563ac6a0a9a3c57c9533fdd49965a7a75315a9",
                    "MacAddress": "02:42:c0:a8:00:03",
                    "IPv4Address": "192.168.0.3/16",
                    "IPv6Address": ""
                },
                "a3aa944c9cba8b72a540fa58d914f098282be89dd81e7f29f9cef91249898749": {
                    "Name": "tomcat-net-01",
                    "EndpointID": "52395f6049507e7128621beffe1a2b96a7de9086af5540868fff62cfaa73e266",
                    "MacAddress": "02:42:c0:a8:00:02",
                    "IPv4Address": "192.168.0.2/16",
                    "IPv6Address": ""
                }
            },
            "Options": {},
            "Labels": {}
        }
    ]
     
    # 再次拼连接
    $ docker exec -it tomcat-net-01 ping 192.168.0.3
    PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
    64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.113 ms
    64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.093 ms
    
    # 现在不使用 --link也可以ping名字了!
    $ docker exec -it tomcat-net-01 ping tomcat-net-02
    PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
    64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.068 ms
    64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.096 ms
    64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.094 ms
    
    

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

    好处:

    redis - 不同的集群使用不同的网络,保证集群时安全和健康的

    mysql - 不同的集群使用不同的网络,保证集群时安全和健康的

    网络连通

    测试打通tomcat01 和 mynet

    20-6

    $ docker network connect  mynet tomcat01
     
    # 连通之后就是讲tomcat01 放到了mynet网路下
    # 一个容器两个ip地址:
    # 阿里云服务器,公网ip,私网ip
    
    # 连通ok
    $ docker exec -it tomcat01 ping tomcat-net-01
    PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
    64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.100 ms
    64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.085 ms
    
    # 02依旧无法连通,因为没有connect
    $ docker exec -it tomcat02 ping tomcat-net-01
    ping: tomcat-net-01: Name or service not known
    
    

    实战 部署Redis集群

    20-7

    20-8

    # 创建网卡
    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
    
    
    # 创建结点1
    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
    #创建结点2
    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
    #创建结点3
    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
    #创建结点4
    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
    #创建结点5
    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
    #创建结点6
    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
     
    # 创建集群
    $ docker exec -it redis-1 /bin/sh
    /data # ls
    appendonly.aof  nodes.conf
    /data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
    >>> Performing hash slots allocation on 6 nodes...
    Master[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: 541b7d237b641ac2ffc94d17c6ab96b18b26a638 172.38.0.11:6379
       slots:[0-5460] (5461 slots) master
    M: a89c1f1245b264e4a402a3cf99766bcb6138dbca 172.38.0.12:6379
       slots:[5461-10922] (5462 slots) master
    M: 259e804d6df74e67a72e4206d7db691a300c775e 172.38.0.13:6379
       slots:[10923-16383] (5461 slots) master
    S: 9b19170eea3ea1b92c58ad18c0b5522633a9e271 172.38.0.14:6379
       replicates 259e804d6df74e67a72e4206d7db691a300c775e
    S: 061a9d38f22910aaf0ba1dbd21bf1d8f57bcb7d5 172.38.0.15:6379
       replicates 541b7d237b641ac2ffc94d17c6ab96b18b26a638
    S: 7a16b9bbb0615ec95fc978fa62fc054df60536f0 172.38.0.16:6379
       replicates a89c1f1245b264e4a402a3cf99766bcb6138dbca
    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: 541b7d237b641ac2ffc94d17c6ab96b18b26a638 172.38.0.11:6379
       slots:[0-5460] (5461 slots) master
       1 additional replica(s)
    M: a89c1f1245b264e4a402a3cf99766bcb6138dbca 172.38.0.12:6379
       slots:[5461-10922] (5462 slots) master
       1 additional replica(s)
    S: 7a16b9bbb0615ec95fc978fa62fc054df60536f0 172.38.0.16:6379
       slots: (0 slots) slave
       replicates a89c1f1245b264e4a402a3cf99766bcb6138dbca
    S: 061a9d38f22910aaf0ba1dbd21bf1d8f57bcb7d5 172.38.0.15:6379
       slots: (0 slots) slave
       replicates 541b7d237b641ac2ffc94d17c6ab96b18b26a638
    M: 259e804d6df74e67a72e4206d7db691a300c775e 172.38.0.13:6379
       slots:[10923-16383] (5461 slots) master
       1 additional replica(s)
    S: 9b19170eea3ea1b92c58ad18c0b5522633a9e271 172.38.0.14:6379
       slots: (0 slots) slave
       replicates 259e804d6df74e67a72e4206d7db691a300c775e
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    
    
    

    docker搭建redis集群完成!

    在这里插入图片描述

    SpringBoot微服务打包Docker镜像

    1. 构建springboot项目

    2. 打包应用

    FROM java:8
     
    COPY *.jar /app.jar
     
    CMD ["--server.port=8080"]
     
    EXPOSE 8080
     
    ENTRYPOINT ["java", "-jar", "/app.jar"]
    
    1. 编写Dockerfile

    2. 构建镜像

    3. 发布运行

    # 把打好的jar包和Dockerfile上传到linux
    $ ll
    total 16140
    -rw-r--r-- 1 root root 16519871 Aug 14 17:38 demo-0.0.1-SNAPSHOT.jar
    -rw-r--r-- 1 root root      122 Aug 14 17:38 Dockerfile
     
    # 构建镜像,不要忘了最后有一个点
    $ docker build -t lixingze .
    Sending build context to Docker daemon  16.52MB
    Step 1/5 : FROM java:8
    8: Pulling from library/java
    5040bd298390: Pull complete 
    fce5728aad85: Pull complete 
    76610ec20bf5: Pull complete 
    60170fec2151: Pull complete 
    e98f73de8f0d: Pull complete 
    11f7af24ed9c: Pull complete 
    49e2d6393f32: Pull complete 
    bb9cdec9c7f3: Pull complete 
    Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
    Status: Downloaded newer image for java:8
     ---> d23bdf5b1b1b
    Step 2/5 : COPY *.jar /app.jar
     ---> d4de8837ebf9
    Step 3/5 : CMD ["--server.port=8080"]
     ---> Running in e3abc66303f0
    Removing intermediate container e3abc66303f0
     ---> 131bb3917fea
    Step 4/5 : EXPOSE 8080
     ---> Running in fa2f25977db7
    Removing intermediate container fa2f25977db7
     ---> d98147377951
    Step 5/5 : ENTRYPOINT ["java", "-jar", "/app.jar"]
     ---> Running in e1885e23773b
    Removing intermediate container e1885e23773b
     ---> afb6b5f28a32
    Successfully built afb6b5f28a32
    Successfully tagged lixingze:latest
     
    # 查看镜像
    $ docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    lixingze          latest              afb6b5f28a32        14 seconds ago      660MB
    tomcat              latest              2ae23eb477aa        8 days ago          647MB
    redis               5.0.9-alpine3.11    3661c84ee9d0        3 months ago        29.8MB
    java                8                   d23bdf5b1b1b        3 years ago         643MB
     
    # 运行容器
    $ docker run -d -P --name xiaofan-springboot-web lixingze
    fd9a353a80bfd61f6930c16cd92204532bfd734e003f3f9983b5128a27b0375e
    # 查看运行起来的容器端口(因为我们启动的时候没有指定)
    $ docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
    fd9a353a80bf        lixingze          "java -jar /app.jar …"   9 seconds ago       Up 8 seconds        0.0.0.0:32779->8080/tcp   xiaofan-springboot-web
    # 本地访问1
    $ curl localhost:32779
    {"timestamp":"2020-08-14T09:42:57.371+00:00","status":404,"error":"Not Found","message":"","path":"/"}
    # 本地访问2
    $ $ curl localhost:32779/hello
    hello, xiaofan
    # 远程访问(开启阿里云上的安全组哦)
    
    
    展开全文
  • Docker 镜像列出: 列出 使用 docker images 显示本地已有的镜像。 $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu 12.04 74fe38d11401 4 weeks ago 209.6 MB ubuntu precise 74fe38d...
  • Ubuntu安装docker教程

    千次阅读 2022-02-07 16:17:26
    Ubuntu安装docker教程

    官方教程

    这里给出我的安装配置过程,使用阿里源安装。
    1.卸载旧版本

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

    如果存在旧版本,我们需要使用该命令卸载它,不存在也没有关系,只是会报告没有安装这些软件包。
    2.安装一些必要的系统工具

    sudo apt-get update #获取软件最新源
    sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
    

    3.安装GPG证书

    curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
    

    在这里插入图片描述
    4.写入软件源信息

    sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
    

    在这里插入图片描述
    5.更新并安装docker引擎

    sudo apt-get -y update
    sudo apt-get -y install docker-ce docker-ce-cli containerd.io
    

    如果需要安装特定的docker版本,可以参照官网。

    6.测试是否安装成功

    sudo docker run hello-world
    

    在这里插入图片描述
    如上则说明安装成功。

    展开全文
  • 主要介绍了Docker 教程之数据管理详细介绍的相关资料,需要的朋友可以参考下
  • 生产环境部署docker教程,绝对生产环境,已经顺利上线!
  • 网上已经有很多介绍Docker安装的文章,自己的安装过程记录一下,为了博客文章结构的连贯性,为写下一篇R和Docker的相遇做为环境基础,同时也给自己一个备忘。 目录 Docker是什么? 在Linux Ubuntu中安装Docker ...
  • Docker 101 教程 注意:Docker 移动速度很快,本教程现已过时。 请参考我最近的 Docker 教程之一。 这些教程伴随着。 这个 repo 包括一个和 ,它们在 Ubuntu 14.04 LTS 服务器上提供了一个守护进程,以最大限度地...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 68,861
精华内容 27,544
关键字:

docker教程