docker入门

文章目录


1.虚拟化分类

1.主机虚拟化

Type-I : hyversior

type-II: vmware

2.容器级虚拟化

1.Linux Namespaces 用户隔离机制

在这里插入图片描述

要想很好的额使用命名空间,内核版本应该在3.8以后

2.Control Groups(cgroups) 统一调度资源

容器级虚拟化技术 使用控制组 进行用户空间 的资源使用能力

  • blkio: 块设备IO
  • cpu: CPU
  • cpuacct: CPU资源使用报告
  • cpuset: 多处理平台上的cpu集合
  • devices: 设备访问
  • freezer: 挂起或恢复任务
  • memory: 内存用量及报告
  • perf_event: 对cgroup中的任务进行统一性能的测试
  • net_cls: cgroup中的任务创建的数据报文的类被标示符
3.小结

有了namspaces 和cgroups 我们就可以很好的使用容器虚拟化技术,但是仍然没有主机虚拟化完善 用的的容器技术 就是 namespaces cgroups chroot进行实现的。

4.LXC (Linux Container)

是容器技术的增强版,复制大量的容器很难

  • lxc-create: 快速创建一个容器(用户空间)
  • template: 完成内部各个命令的安装

5.docker简介

核心是LXC 是二次封装的发行版,使用镜像技术,

一个容器只运行一个进程

镜像内的文件

这也会有一个问题,每一个进程只运行与自己的单独空间之中,这个容器内部的所有环境都是为了进程建立的,以前共享的文件只放一份就行了,坏处现在有多份,占用了更多的空间,通常在一个系统上出现故障了,我们会使用一组跟踪工具, 以前在一个名称空间中,工具只准备一份,可以对多个服务进行调试,现在容器的话每个命名空间都自带一个工具,就只能对当前的命名空间做调试,所以工具只是用的时候再启动,不用的时候是不需要启动的,现在调试 没有工具,还要突破边界,给运维带来了极大的不便利,但是给开发带来了极大的便利。只要有docker ,只要docker run 就可以了。以后无论使用任何语言 都可以 打成镜像 都可以docker run。正是有了docker的出现,极大的降低了软件的部署的难度。维护上在一个分支就可以操作,发布操作可以使用编排工具来操作,运维的核心在维稳,

对运维来说,使用docker就没调试工具。以后做镜像就要为每个容器做调试工具。

分层构建,一个功能在一层上实现,联合挂载,

谷歌创建了CNCF k8s赋予了它 行程了开源

容器编排工具

  • nmp
  • machine+swarm+compose
  • mesos+marathon
  • kubernets -> k8s
  • libcontainer --> runC

6.Docker基础用法

内核中要支撑两种技术 namespaces cgroups

  • 架构C/S架构的应用程序

在这里插入图片描述

支持socket套接字,

启动容器基于镜像使用,镜像也需要在本地存储,docker pull 使用https协议,docker的api也是一个result的api,使用docker只需要把docker下载即可,先下载镜像,加速访问,使用阿里云镜像,docker建立了一个自己的国内镜像加速cn,

企业版 ee

社区版 ce

## docker由三部分组成:

  • The Docker daemon
    The Docker daemon (dockerd) listens for Docker APl requests and manages Dockerobjects such as images, containers,networks, and volumes.
    The Docker client
    ·The Docker client (docker) is the primary way that many Docker users interact withDocker.

  • The docker command uses the Docker API.·Docker registries
    ·A Docker registry stores Docker images.
    · Docker Hub and Docker Cloud are public registries that anyone can use, and Dockeris configured to look for imagcs on 1Docker Hub by default.

  • You can even run your own private rlgistry.

docker tag

registry提供存储,提供下载,提供认证。

一个服务是一个仓库,版本用tag来标识

在这里插入图片描述

镜像和容器的关系

就是程序和进程的关系。

镜像:静态

容器:动态

镜像文件事只读的。

docker安装

yum install -y yum-utils device-mapper-persistent-data lvm2 \
&& yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo \
&& yum install  -y docker-ce docker-ce-cli containerd.io \
&& systemctl start docker \
&& yum -y install epel-release \
&& yum -y install python-pip \
&& pip install --upgrade pip \
&& pip install docker-compose

依赖的基础环境

  • 64 bits CPU

  • Linux Kernel 3.10+

  • Linux Kernel cgroups and namespaces

  • Centos7

“Exxtras” repository"

容器创建

docker create 

docker container create

docker version 版本

[root@c7-45 ~]# docker version
Client: Docker Engine - Community
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 17:03:45 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.13
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       4484c46d9d
  Built:            Wed Sep 16 17:02:21 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.3.7
  GitCommit:        8fba4e9a7d01810a393d5d25a3621dc101981175
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

docker info 查看详细信息

[root@c7-45 ~]# docker info
Client:
 Debug Mode: false

Server:
 Containers: 2
  Running: 1
  Paused: 0
  Stopped: 1
 Images: 4

docker search --filter=stars=50 nginx

[root@c7-45 ~]# docker search --filter=stars=50 nginx
NAME                          DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
nginx                         Official build of Nginx.                        13911               [OK]                
jwilder/nginx-proxy           Automated Nginx reverse proxy for docker con…   1900                                    [OK]
richarvey/nginx-php-fpm       Container running Nginx + PHP-FPM capable of…   791                                     [OK]
linuxserver/nginx             An Nginx container, brought to you by LinuxS…   127                                     
jc21/nginx-proxy-manager      Docker container for managing Nginx proxy ho…   101                                     
tiangolo/nginx-rtmp           Docker image with Nginx using the nginx-rtmp…   99                                      [OK]
bitnami/nginx                 Bitnami nginx Docker Image                      90                                      [OK]
alfg/nginx-rtmp               NGINX, nginx-rtmp-module and FFmpeg from sou…   77                                      [OK]
jlesage/nginx-proxy-manager   Docker container for Nginx Proxy Manager        64                                      [OK]
nginxdemos/hello              NGINX webserver that serves a simple page co…   62                                      [OK]

alpine版本:

缺少工具 ,最小镜像

–no-trync显示完整的信息

[root@c7-45 ~]#   docker image ls --no-trunc
REPOSITORY                TAG                 IMAGE ID                                                                  CREATED             SIZE
busybox                   latest              sha256:f0b02e9d092d905d0d87a8455a1ae3e9bb47b4aa3dc125125ca5cd10d6441c9f   9 days ago          1.23MB
myrepo.com:5000/busybox   latest              sha256:6858809bf669cc5da7cb6af83d0fae838284d12e1be0182f92f6bd96559873e3   6 weeks ago

容器操作

[root@c7-45 ~]# docker run --help

Usage:	docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

-t, --tty  中断
-i, --interactive 交互式访问
--name 赋予名字
--network 加入网络
-d 后台启动

  • 示例:启动一个b1容器
[root@c7-45 ~]# docker run --name b1 -it busybox
/ # 
/ # 
/ # 
/ # 
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # ls /
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # ls /bin      #都是busybox别名
[                  fsck.minix         mknod              showkey
[[                 fsfreeze           mkpasswd           shred
acpid              fstrim             mkswap             shuf
add-shell          fsync              mktemp             slattach
addgroup           ftpd               modinfo            sleep

示例:创建busybox httpd服务

[root@c7-45 ~]# docker run --name b2 -it busybox
/ # mkdir /data/html -p
/ # vi /data/html/index.html
/ # httpd -f -h /data/html/     
-f 前台启动
-h 指定家目录

另开一个窗口进行查看

[root@c7-45 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
744c322cf4d9        busybox             "sh"                     48 seconds ago      Up 47 seconds                                        b2
0c41996829f9        registry:2.6.2      "/entrypoint.sh /etc…"   4 weeks ago         Up 45 minutes       0.0.0.0:443->443/tcp, 5000/tcp   registry

[root@c7-45 ~]# docker inspect b2 | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.3",
                    "IPAddress": "172.17.0.3",

[root@c7-45 ~]# curl 172.17.0.3
busybox

启动一个停止的不带守护进程的shell容器

[root@c7-45 ~]# docker start --help

Usage:	docker start [OPTIONS] CONTAINER [CONTAINER...]

Start one or more stopped containers

Options:
  -a, --attach                  Attach STDOUT/STDERR and forward signals
      --checkpoint string       Restore from this checkpoint
      --checkpoint-dir string   Use a custom checkpoint storage directory
      --detach-keys string      Override the key sequence for detaching
                                a container
  -i, --interactive             Attach container's STDIN
[root@c7-45 ~]# docker start -i -a b2
/ # 
/ # 
/ # 

停止 删除镜像

[root@c7-45 ~]# docker kill b2
b2
[root@c7-45 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
0c41996829f9        registry:2.6.2      "/entrypoint.sh /etc…"   4 weeks ago         Up 51 minutes       0.0.0.0:443->443/tcp, 5000/tcp   registry
[root@c7-45 ~]# docker rm b2
b2
[root@c7-45 ~]# 

示例: exec 绕过容器进入redis容器

[root@c7-45 ~]# docker exec -it kvstorl /bin/sh
/data # ps
PID   USER     TIME  COMMAND
    1 redis     0:00 redis-server
   22 root      0:00 /bin/sh
   27 root      0:00 ps
/data # netstat -ntlp
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:6379            0.0.0.0:*               LISTEN      -
tcp        0      0 :::6379                 :::*                    LISTEN      -
/data # redis-cli
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> exit
/data # 

docker logs + 容器名 查看日志

docker容器管理的常用操作

在这里插入图片描述

docker 容器状态转换

在这里插入图片描述

7.Docker镜像管理基础

  • Docker镜像含有启动容器所需要的文件系统及其内容,因此,其用于创建并启动docker容器
    • 采用分层构建机制,最底层为bootfs,其之为rootfs
      • bootfs:用于系统引导的文件系统,包括bootloader和kernel,容器启动完成后会被卸载以节约内存资源;
      • rootfs:位于bootfs之上,表现为docker容器的根文件系统;
        • 传统模式中,系统启动之时,内核挂载rootfs时会首先将其挂载为“只读"模式,完整性自检完成后将其重新挂载为读写模式;
        • docker中,rootfs由内核挂载为“只读"模式,而后通过“联合挂载"技术额外挂载一个“可写"层;

在这里插入图片描述

1. Docker Image Layer

  • 位于下层的镜像称为父镜像(parent image),最底层的称为基础镜像(base image)
  • 最上层为 “可读层”,其下均为“只读”层

在这里插入图片描述

每次下载软件都会封装一个层,启动容器时,各个层联合挂载

2.Aufs (联合挂载)

  • advanced multi-layered unification filesystem:高级多层统一文件系统·用于为Linux文件系统实现“联合挂载”
  • aufs是之前的OnionFS的重新实现,2006年由Junjiro Okajima开发;
  • Docker最初使用aufs作为容器文件系统层,它目前仍作为存储后端之一来支持;
  • aufs的竞争产品是overlayfs,后者自从3.18版本开始被合并到Linux内核;
  • docker的分层镜像,除了aufs,docker还支持btrfs,devicemapper和vfs等
    • 在Ubuntu系统下,docker默认Ubuntu的 aufs;而在CentOS7上,用的是devicemapper;

3.docker info 查看是否支持多层联合挂载

[root@c7-45 docker]# docker info
Client:
 Debug Mode: false

Server:
 Containers: 4
  Running: 2
  Paused: 0
  Stopped: 2
 Images: 6
 Server Version: 19.03.13
 Storage Driver: overlay2   #前端支持olerlay2  建构在xfs
   Backing Filesystem: xfs   #后端支持xfs

4.Docker Registry

  • 启动容器时,docker daemon会试图从氐地获取相关的镜像;本地镜像不存在时,其将从Registry中下载该镜像并保存到本地;
    • The Registry is a stateless, highly scalable server side application that stores and lets youdistribute Docker images.
      在这里插入图片描述
1.仓库分类
  • Registry用于保存docker镜像,包括镜像的层次结构和元数据

  • 用户可自建Registry,也可使用官方的Docker Hub

  • 分类

    • Sponsor Registry:第三方的registry,供客户和Docker社区使用
    • Mirror Registry:第三方的registry,只让客户使用
    • Vendor Registry:由发布Docker镜像的供应商提供的registry
    • Private Registry:通过设有防火墙和额外的安全层的私有实体提供的registry

    ps: 私有仓库指定使用https 如使用http 需要格外设置

2.组成部分 Registry(repository and index)
  • Repository

    • 由某特定的docker镜像的所有迭代版本组成的镜像仓库

    • 一个Registry中可以存在多个Repository

      • Repository可分为“顶层仓库“和”用户仓库“
      • 用户仓库名称格式为"用户名/仓库名"
3.Docker Registry 使用
  • Docker Registry中的镜像通常由开发人员制作,而后推送至”公共“或”私有“Registry上保存,供其他人员使用,例如“部署”到生产环境。

    在这里插入图片描述

云原生:面向云化而生的。

5.Docker Hub 所支持的命令

  • Docker Hub provides the following major features
    • Image Repositories
      • Find and pull images from community and official libraries, and manage, push to, and pull fromprivate image libraries to which you have access.
    • Automated Builds
      • Automatically create new images when you make changes to a source code repository…
    • Webhooks
      • A feature of Automated Builds,Webhooks let you trigger actions after a successful push to arepository.
    • Organizations
      • Create work groups to manage access to image repositories…
    • GitHub and Bitbucket Integration
      • Add the Hub and your Docker Images to your current workflows.

9.镜像相关的操作

  • 镜像的生成途径
    • Dockerfile
    • 基于容器制作
    • Docker Hub automated builds

在这里插入图片描述

10.基于容器制作镜像

  • Create a new image from a container’s changes
  • Usage
    • docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]I

在这里插入图片描述

11.docker commit 提交一个镜像

我们基于busybox 创建一个 前台启动为httpd的新镜像 web服务器

# 为防止数据丢失  使用-p pause 暂停选项 
[root@c7-45 docker]# docker commit -p b1
sha256:2964051eb697b6275cbb30d26c2a05b403e63da1aef20e0de603f553f3e4a793


[root@c7-45 docker]# docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
<none>                    <none>              2964051eb697        11 seconds ago      1.23MB
busybox                   latest              f0b02e9d092d        10 days ago         1.23MB

#给镜像打tag
[root@c7-45 docker]# docker tag 2964051eb697 ylmcr7/busybox_httpd:v0.1
[root@c7-45 docker]# docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
ylmcr7/busybox_httpd      v0.1                2964051eb697        2 minutes ago       1.23MB
busybox                   latest              f0b02e9d092d        10 days ago         1.23MB


[root@c7-45 docker]# docker tag ylmcr7/busybox_httpd:v0.1 ylm/httpd:v0.1
[root@c7-45 docker]# docker images ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
[root@c7-45 docker]# docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
ylm/httpd                 v0.1                2964051eb697        4 minutes ago       1.23MB
ylmcr7/busybox_httpd      v0.1                2964051eb697        4 minutes ago       1.23MB
busybox                   latest              f0b02e9d092d        10 days ago         
[root@c7-45 docker]# docker image rm ylm/httpd:v0.1
Untagged: ylm/httpd:v0.1
[root@c7-45 docker]# docker tag ylmcr7/busybox_httpd:v0.1 ylm/httpd:latest
[root@c7-45 docker]# docker inspect busybox:latest 
],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"sh\"]"

#镜像最后执行的命令
  • 改变最后执行的命令 例如以前是/bin/sh 现在改成 httpd
/ # which httpd
/bin/httpd

制作了一个

docker commit -a “ylm” -c ‘CMD ["/bin/httpd","-f","-h","/data/html"]’ -p b1 ylm/httpd:v0.2

[root@c7-45 ~]# docker commit -h
Flag shorthand -h has been deprecated, please use --help

Usage:	docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Create a new image from a container's changes

Options:
  -a, --author string    Author (e.g., "John Hannibal Smith
                         <hannibal@a-team.com>")
  -c, --change list      Apply Dockerfile instruction to the created image
  -m, --message string   Commit message
  -p, --pause            Pause container during commit (default true)

# 基于b1这个容器创建了一个 作者为 ylm 最后执行命令为 /bin/httpd -f前台启动  -h 指定夹目录 的ylm/httpd:v0.2的新镜像
[root@c7-45 ~]# docker commit -a "ylm" -c 'CMD ["/bin/httpd","-f","-h","/data/html"]' -p b1 ylm/httpd:v0.2 

sha256:c7735cc926a7e52095996985b3a9b504088ca9f86f729c3b0a3fa97301122286

基于ylm/httpd:v0.2创建一个镜像并查看

[root@c7-45 ~]# docker run --name t2  ylm/httpd:v0.2 


[root@c7-45 docker]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
757e9f3bba72        ylm/httpd:v0.2      "/bin/httpd -f -h /d…"   9 seconds ago       Up 8 seconds 

[root@c7-45 docker]# docker inspect t2
            ],
            "Cmd": [
                "/bin/httpd",
                "-f",
                "-h",
                "/data/html"

                    "IPAddress": "172.17.0.4",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:04",
                    "DriverOpts": null
                }
            }
        }
    }
]
[root@c7-45 docker]# curl 172.17.0.5
curl: (7) Failed connect to 172.17.0.5:80; No route to host
[root@c7-45 docker]# curl 172.17.0.4
<h1>busybox</h1>

基于busybox创建的一个前台启动的httpd镜像成功。

12推送镜像到docker hub

docker push 推送的标签必须和仓库名一致 才能直接推送

[root@c7-45 docker]# docker push ylmcr7/busybox_httpd:v.02
The push refers to repository [docker.io/ylmcr7/busybox_httpd]
3d08ff9a3fe4: Pushed 
d2421964bad1: Pushed 
v.02: digest: sha256:e58a57198b3b9b769fe1e25e8754b3607721f9539edaabced68a1946f9bbc24d size: 734

13.镜像的导入和导出

docker save -o 保存

[root@c7-45 docker]# docker save ylm/httpd:v0.2 -o httpd
[root@c7-45 docker]# ls
httpd

docker load -i 导出

[root@c7-45 docker]# docker load -i httpd 
Loaded image: ylm/httpd:v0.2

8.容器虚拟化网络概述

  • 现在linux内核在内核级支持6种名称空间
  1. UTS :主机名和用户名
  2. NET 网络
  3. USER :用户的
  4. Mount 挂载文件系统的
  5. IPC 进程间通信
  6. PID 进程id

协议栈 网络设备的隔离

1.ovs

Open VSwitch

用纯软件的方式模拟一个交换机

名称空间数量超过网卡数量 可以使用虚拟网卡的方式,用纯软件的方式,来模拟一组设备的使用,Linux内核支持两种级别的模拟,一种是二层设备,一种是三层的设备,我们的物理网卡算是2层设备,他就是工作在链路层,能封装物理报文,实现在各设备之间实现报文转发的组件,这个组件完全可以在LInux纸上 ,利用Linux内核的支持,物理网卡 工作在二层,创建虚拟网卡接口,每一个是成对出现的,可以模拟一根网线的两头,一头插在主要机制上,一头插在交换机上,Linux原生支持二层虚拟网桥设备,用软件来构建一个交换机,brctl进行实现,一头分配给名称空间,一头连在交换机上, 如果两个名称空间是同一个网段,就可以实现通信。

2.SDN

软件(定义)驱动的网络

现在在云计算的大潮下,构建云计算中心,网络之上虚拟机通信,需要软硬件结合起来才能实现,需要把传统意义上的网络平面,控制平面,数据平面,给隔离开来,将控制平面隔离到一个专业的平面之上,实现全局调度。不仅需要硬件的支持,还需要虚拟机上构建复杂的网络,因为在虚拟机上装docker,或者其他虚拟机。

3.一个物理主机多个交换机的模式实现通信原理

在这里插入图片描述

C1想要实现和C3进行互通,再做一对网卡 ,一个在S1上,一个在S2上,C1和C3通信,要经过路由转发,因为他们在不同的网段中,路由器是三层设备,在Linux上使用一个单独的名称空间 ,就可以支持,再做一个容器,什么事也不干,就当作路由器使用,借助真实的内核,来实现报文转发,但是得模拟出网卡来,让他们之间建立关系,

4.跨物理服务器通信

  • 桥接 :

    • 却点 产生风暴
  • NAT :

    • 缺点: 效率非常低
    • 优点: 网络易于管理
  • Overlay Network

    • 优点:请求直达目标主机
1.桥接
  • 桥接可以实现,但是风险大,有风暴产生

在这里插入图片描述

vmware虚拟机实现主机之间的通信使用桥接,C1通信C5是把物理网卡当作交换机来用,能接受MAC不是自己的报文,做一个软网卡,真正为物理机接收报文,这样通信的代价很大 ,容器产生风暴。在大网络下,使用桥接,无疑是自找死路。除非使用大二层技术隔离开来。

2.NAT

在这里插入图片描述

  • 网络易于管理

C3把网关指向S2,我们把S2当作宿主机的网卡使用,S2的IP和C3是同网段,我们把C3的网关指向S2,在物理机上打开核心转发,当C3和C6通信时,先送给S2到达物理内核,目标一判定不是自己的,查路由表要到达C6,经由物理网卡,送出去,但是包回不来,因为C3是私有地址,实现包能回来,最好是C3报文送走离开H1之前,要把源IP改成物理网卡的IP地址,这样C5回复的时候,回复给H1就行了,NAT网络就能实现跨主机通讯,这样的话会有i一个问题,C5、C6通讯时因为都是私有地址,许需要NAT网络实现,两级NAT,C6无法被C3看到,实现NAT网络的地址能呗看到,就要把他们暴漏出去,DNAT,要想访问C6,就要先访问H2的物理网卡IP地址,使其作为DNAT发给C6,C3出来的时候是SNAT出来的,跨物理主机让两个虚拟主机进行通讯,一定要经由两级NAT,C3出去的时候SNAT,到达H2的时候DNAT,做了两次转换,效率不高。他们之间通讯发,互相看不见对方,C3以为是和H2通讯,C6以为和H1同讯,这样做会让网络易于管理

3.Overlay Network

在这里插入图片描述

  • 叠加网络

简单原理,依然不只是一个物理机,物理机的物理网卡,在虚拟机上我们 做一个虚拟的桥,让个容器连接到这个虚拟的桥上来,通信时,借用物理网络来完报文的隧道转发,这样可以实现C1可以直接看见C5。物理主机本来实现物理网卡就连接在一起,他们是可以直接通信的,C1和物理网络不在用以网段,但是和C5在同一网段,C1发送报文,先送给桥,桥会知道C5不在本机的物理服务器上,所以这个报文会从物理网卡发出去,但是发出去之前要做隧道转发

C1的源地址时C1,目标地址时C5,报文不动,他会额外再封装一个报文,源地址是C1所在的H1的物理网卡地址,目标地址是C5所在的H2的物理网卡地址,所以就发给H2,H2主机拆完第一个报文封装,看到目标地址是C5的,所以就直接要给本地的软交换机,由软网桥交给C5,C1本来就是一个三层网络,本来该封装2层,但是他借助的其他网络,封装了3.4层的报文,就是UDP和TCP守护,再封装一个IP守护,来实现两级三层封装,从而实现的报文转发,这样用一个IP承载另外一个IP的叫隧道,和LVS道理是一样的。这样C1就可以直接向C5发请求,这种网络就要叠加网络,用隧道实现

9.Docker容器网络

1.bridge

容器间共享名称空间,实现可以使用环回路由进行访问。共享网络空间。

[root@c7-45 docker]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
19d2a53694c2        bridge              bridge              local

这里的桥接不是物理桥,不是nat桥,本机之上自动创建一个纯粹的软交换机docker0,他也可以当网卡使用,即可扮演二层的交换设备,也可以扮演二层的网卡设备,不给他地址,就是交换机,给他地址,他技能当交换机,又能到网卡,172.17.0.1,每启动一个容器,就自动分配一对网卡的地址,一半在容器上,一半在docker0桥上,docker0桥默认是一个nat桥。每启动一个容器后,

我们使用brctl来查看

yum -y install bridge-utils


[root@c7-45 docker]# brctl show 
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02421ab44607	no		veth7911a5b
										vethbdcf189
										vethc6802ee
wget代替curl
  • 同docker0桥上的容器互相访问 无法使用curl 就用
/data # wget -O -  -q http://172.17.0.4
<h1>busybox</h1>

-O 文件不保存直接展示
- 当前终端上来
  • 物理机也可以访问
[root@c7-45 docker]# curl http://172.17.0.4

<h1>busybox</h1>

不同物理机,容器互相访问,只能做DNAT,在物理机上卡一个端口,使用DNAT的方式分到达我们的容器。

添加一个DNAT规则,以便他呗外部的其他主机访问,

在这里插入图片描述

容器间共享名称空间,实现可以使用环回路由进行访问。共享网络空间。
在这里插入图片描述

2.host

容器和物理机共享名称空间

[root@c7-45 docker]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
5a9f8c271f11        host                host                local

让容器使用宿主机的网络名称空间

3.none

没有任何网络,不能执行网络通讯,就是一座孤岛。

有些容器只处理数据,就可以不给他网络。

4.docker容器网络模型总结

4种网络

在这里插入图片描述

  1. closed container 封闭式容器,只有lo接口。
  2. 使用桥接式接口,接到docker0桥上,他拥有一个虚拟网卡,通过容器接口连到docker0上,默认172.17. 没有指定,默认就是桥接nat网络。
  3. 联盟式网络,让两个容器,有一部分名称空间是隔离的,文件系统 (mount),用户(user),pid各是各的,UTS,IPC,NET共享同一组网络设备,共享同一组网卡,用一组lo,之间可以通过lo通信了。
  4. 开放式网络,直接共享宿主机的网络名称空间,能连接到物理网卡。
  5. –network 使用网络选项

模拟设备存储名称空间的切换

在这里插入图片描述

1.查看是否安装软件包
[root@c7-45 docker]# rpm -q iproute
iproute-4.11.0-25.el7_7.2.x86_64
2.创建两个名称空间
[root@c7-45 docker]# ip  netns help
Usage: ip netns list
       ip netns add NAME
       ip netns set NAME NETNSID
       ip [-all] netns delete [NAME]
       ip netns identify [PID]
       ip netns pids NAME
       ip [-all] netns exec [NAME] cmd ...
       ip netns monitor
       ip netns list-id
       
#分别是r1 和r2   
[root@c7-45 docker]# ip netns add r1
[root@c7-45 docker]# ip netns add r2

#查看还没有ip地址
[root@c7-45 docker]# ip netns exec r1 ifconfig -a
lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@c7-45 docker]# ip netns exec r2 ifconfig -a
lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

3.创建两块网卡
#创建一堆虚拟网卡
[root@c7-45 docker]# ip link add name veth1.1 type veth peer name veth1.2
[root@c7-45 docker]# ip link show 

21: veth1.2@veth1.1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 66:e0:0f:ff:c8:46 brd ff:ff:ff:ff:ff:ff
22: veth1.1@veth1.2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether de:2c:10:40:e8:98 brd ff:ff:ff:ff:ff:ff
4.将一块网卡放到r1
[root@c7-45 docker]# ip link set dev veth1.2 netns r1
#只剩一块1.1网卡了
[root@c7-45 docker]# ip link show
22: veth1.1@if21: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether de:2c:10:40:e8:98 brd ff:ff:ff:ff:ff:ff link-netnsid 3
5.更改网卡名字
[root@c7-45 docker]# ip netns exec r1 ifconfig -a
lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth1.2: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether 66:e0:0f:ff:c8:46  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@c7-45 docker]# ip netns exec r1 ip link set dev veth1.2 name eth0   #更改为eth0
[root@c7-45 docker]# ip netns exec r1 ifconfig -a
eth0: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether 66:e0:0f:ff:c8:46  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
6.赋予vet1.1一个ip地址
[root@c7-45 docker]# ifconfig veth1.1 10.1.0.1/24 up

[root@c7-45 docker]# ifconfig
veth1.1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 10.1.0.1  netmask 255.255.255.0  broadcast 10.1.0.255
        ether de:2c:10:40:e8:98  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
7.赋予r1 的eth0一个ip地址
[root@c7-45 docker]# ip netns exec r1 ifconfig eth0 10.1.0.2/24 up
[root@c7-45 docker]# ip netns exec r1 ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.1.0.2  netmask 255.255.255.0  broadcast 10.1.0.255
        inet6 fe80::64e0:fff:feff:c846  prefixlen 64  scopeid 0x20<link>
        ether 66:e0:0f:ff:c8:46  txqueuelen 1000  (Ethernet)
        RX packets 6  bytes 516 (516.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6  bytes 516 (516.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
8.宿主机 ping r1
[root@c7-45 docker]# ping 10.1.0.2
PING 10.1.0.2 (10.1.0.2) 56(84) bytes of data.
64 bytes from 10.1.0.2: icmp_seq=1 ttl=64 time=0.103 ms
64 bytes from 10.1.0.2: icmp_seq=2 ttl=64 time=0.034 ms
9.赋予r2一个网卡 和一个ip地址
[root@c7-45 docker]# ip link set dev veth1.1 netns r2
[root@c7-45 docker]# ip netns exec r2 ifconfig
[root@c7-45 docker]# ip netns exec r2 ifconfig veth1.1 10.1.0.3/24 up
[root@c7-45 docker]# ip netns exec r2 ifconfig
veth1.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.1.0.3  netmask 255.255.255.0  broadcast 10.1.0.255
        inet6 fe80::dc2c:10ff:fe40:e898  prefixlen 64  scopeid 0x20<link>
        ether de:2c:10:40:e8:98  txqueuelen 1000  (Ethernet)
        RX packets 12  bytes 936 (936.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 19  bytes 1522 (1.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
10. r2去ping r1
[root@c7-45 docker]# ip netns exec r2 ping 10.1.0.2
PING 10.1.0.2 (10.1.0.2) 56(84) bytes of data.
64 bytes from 10.1.0.2: icmp_seq=1 ttl=64 time=0.047 ms
64 bytes from 10.1.0.2: icmp_seq=2 ttl=64 time=0.035 ms
^C
--- 10.1.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.035/0.041/0.047/0.006 ms

这样就实现了 两块网卡 在两个虚拟机上 进行了通讯,再借助bridge-utils

10.Docker容器网络实践

1.none

模拟实现第一种封闭式容器 没有ip

[root@c7-45 ~]# docker run --name t1 -it  --network none --rm busybox:latest
/ # ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

2.bridge

  • 默认主机名是自己的id
[root@c7-45 ~]# docker run --name t1 -it  --network bridge --rm busybox:latest
/ # hostname
94625c55d726
  • 使用-h 指定主机名
[root@c7-45 ~]# docker run --name t1 -it  --network bridge -h t1.ylm.com --rm busybox:latest
/ # hostname
t1.ylm.com
  • 容器想通过主机名 和其他容器进行通讯,域名解析
/ # 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.5	t1.ylm.com t1
/ # cat /etc/resolv.conf    #和宿主机一样的DNS服务器

nameserver 223.5.5.5
nameserver 223.6.6.6
/ # nslookup      #解析
BusyBox v1.32.0 (2020-10-12 23:47:18 UTC) multi-call binary.

Usage: nslookup [-type=QUERY_TYPE] [-debug] HOST [DNS_SERVER]

Query DNS about HOST

QUERY_TYPE: soa,ns,a,aaaa,cname,mx,txt,ptr,any
/ # nslookup -type=A www.baidu.com         #是能正常的解析的
Server:		223.5.5.5
Address:	223.5.5.5:53

Non-authoritative answer:
www.baidu.com	canonical name = www.a.shifen.com
Name:	www.a.shifen.com
Address: 61.135.185.32
Name:	www.a.shifen.com
Address: 61.135.169.121
  • –dns 指定域名服务器
[root@c7-45 ~]# docker run --name t1 -it  --network bridge -h t1.ylm.com --dns 114.114.114.114  --rm busybox:latest
/ # cat /etc/resolv.conf 
nameserver 114.114.114.114
  • –dns-search 指定搜索域
[root@c7-45 ~]# docker run --name t1 -it  --network bridge -h t1.ylm.com --dns 114.114.114.114 --dns-search ilinux.io --rm busybox:latest
/ # cat /etc/resolv.conf 
search ilinux.io
nameserver 114.114.114.114
  • –add-host 外部注入DNS解析
[root@c7-45 ~]# docker run --name t1 -it  --network bridge -h t1.ylm.com --dns 114.114.114.114 --dns-search ilinux.io  --add-host www.ylm.com:1.1.1.1 --rm busybox:latest
/ # 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
1.1.1.1	www.ylm.com
172.17.0.5	t1.ylm.com t1
  • 可以为docker run命令使用

    • "——hostname HOSTNAME"选项为容器指定主机名,例如
      ·~]# docker run --rm —-net bridge --hostname bbox.magedu.com busybox:latest nslookupbbox.magedu.com
    • "–dns DNS_SERVER_IP"选项能够为容器指定所使用的dns服务器地址,例如
      ·~]# docker run --rm --dns 172.16.0.1 busybox:latest nslookup docker.com
    • ."–add-host HOSTNAME:IP"选项能够为容器指定本地主机名解析项,例如
      ~]# docker run–rm --dns 172.16.0.1 ——add-host “docker.com:172.16.0.100” busybox:latestnslookup docker.com
  • node02是ping 不通node01的,但是可以通过设置下一跳

[root@c7-45 ~]# docker run --name t1 -it  --network bridge -h t1.ylm.com --dns 114.114.114.114 --dns-search ilinux.io  --add-host www.ylm.com:1.1.1.1 --rm busybox:latest
/ # 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
1.1.1.1	www.ylm.com
172.17.0.5	t1.ylm.com t1
PING 10.0.0.45 (10.0.0.45) 56(84) bytes of data.
64 bytes from 10.0.0.45: icmp_seq=1 ttl=64 time=0.628 ms
^C
--- 10.0.0.45 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.628/0.628/0.628/0.000 ms
root@ylm-ubuntu:~# ping 172.17.0.5
PING 172.17.0.5 (172.17.0.5) 56(84) bytes of data.
^C
--- 172.17.0.5 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1029ms

我们通过暴露端口来解决这个问题,

Docker容器通过暴露端口是其他主机进行访问,暴漏给物理机的物理网卡的动态端口 30000-32767之间的随机端口。

  • —p选项的使用格式
    • -p
      ·将指定的容器端口映射至主机所有地址的一个动态端口·
    • -p :
      ·将容器端口映射至指定的主机端口·
    • -p ::
      ·将指定的容器端口映射至主机指定的动态端口.
    • -p ::
      ·将指定的容器端口映射至主机指定的端口·“
    • 动态端口”指随机端口,具体的映射结果可使用docker port命令查看
-p
示例:起一个web服务,暴露自己的80端口,映射给宿主机一个随机端口
[root@node01 ~]# docker run --name myweb --rm -p 80 ylmcr7/busybox_httpd:v.02 

iptables规则查看  删除容器后 规则自动删除bash

[root@c7-45 ~]# docker port myweb
80/tcp -> 0.0.0.0:32769
root@node02:~# curl 10.0.0.45:32769

<h1>busybox</h1>

在这里插入图片描述

-p ::
[root@node01 ~]# docker run --name myweb --rm -p 10.0.0.45::80 ylmcr7/busybox_httpd:v.02
[root@c7-45 ~]# docker port myweb
80/tcp -> 10.0.0.45:32768     #不是0.0.0.0的动态端口了  而实10.0.0.45的

在这里插入图片描述

-p::
[root@node01 ~]# docker run --name myweb --rm -p 80:80 ylmcr7/busybox_httpd:v.02
-p ::
[root@node01 ~]# docker run --name myweb --rm -p10.0.0.45:8080:80 ylmcr7/busybox_httpd:v.02 
[root@c7-45 ~]# docker port myweb
80/tcp -> 10.0.0.45:8080

在这里插入图片描述

-P
  • “一P"选项或"——publish-all"将容器的所有计划要暴露端口全部映射至主机端口
    • 计划要暴露的端口使用使用—-expose选项指定
    • ·例如
      ·~]# docker run -d -P —-expose 2222–expose 3333—-name web busybox:latst /bin/ httpd-p
      2222 -f
    • 查看映射结果
      ·~]# docker port web
  • ·如果不想使用默认的docker0桥接口,或者需要修改此桥接口的网络属性,可通过为docker daemon命令使用一b、–bip、–fixed-cidr、–default-gateway、-—dns以及-―mtu等选项进行设定
Joined container
  • 联盟式容器是指使用某个已存在容器的网络接口的容器,接口被联盟内的各容器共享使用;因此,联盟式容器彼此间完全无隔离,例如·

    • 创建一个监听于2222端口的http服务容器
      ·~]# docker run -d -it --rm -p 2222 busybox:latest /bin/httpd -p 2222 -f
    • 创建一个联盟式容器,并查看其监听的端口
      ·~]# docker run -it —-rm --net container:web —-namejoined busybox:latest netstat —tan
  • 联盟式容器彼此间虽然共享同一个网络名称空间,但其它名称空间如User、Mount等还是隔离的

  • 联盟式容器彼此间存在端口冲突的可能性,因此,通常只会在多个容器上的程序需要程序loopback接口互相通信、或对某已存的容器的网络属性进行监控时才使用此种模式的网络模型

  • 示例 我们启动容器b1

[root@node01 ~]# docker run --name b1 -it --rm busybox
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:05  
          inet addr:172.17.0.5  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:516 (516.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

使用–network container:b1让b2使用b1的网络名称空间,发现ip一致,文件系统是隔离的

[root@c7-45 ~]# docker run --name b2 -it --network container:b1 --rm busybox
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:05  
          inet addr:172.17.0.5  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:656 (656.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
  • 文件系统是隔离的
/ # mkdir /tets1    #b1
/ # 


ls: /tets1: No such file or directory    #b2
/ # 
  • 网络是互通的
#b1
/ # echo '123' >/tets1/index.html
/ # httpd -h
httpd: option requires an argument -- h
BusyBox v1.32.0 (2020-10-12 23:47:18 UTC) multi-call binary.

/ # httpd -f -h /tets1/
#b2访问127.0.0.1
/ # wget -O - -q 127.0.0.1
123
使用host网络使用的是宿主机的端口
[root@node01 ~]# docker run --name b2 --network host -it --rm busybox
/ # ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:1A:B4:46:07  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:1aff:feb4:4607/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:73 errors:0 dropped:0 overruns:0 frame:0
          TX packets:83 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:5321 (5.1 KiB)  TX bytes:8130 (7.9 KiB)

ens33     Link encap:Ethernet  HWaddr 00:0C:29:0F:D4:3A  
          inet addr:10.0.0.45  Bcast:10.0.0.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe0f:d43a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:50388 errors:0 dropped:0 overruns:0 frame:0
          TX packets:27720 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:32202859 (30.7 MiB)  TX bytes:3571714 (3.4 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:873909 errors:0 dropped:0 overruns:0 frame:0
          TX packets:873909 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:728783815 (695.0 MiB)  TX bytes:728783815 (695.0 MiB)

/ # echo '123' >/tmp/index.html
/ # httpd -h /tmp/ -p 81
/ # netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 :::81                   :::*                    LISTEN      10/httpd

在这里插入图片描述

更改默认docker0的网段

自定义docker@桥的网络属性信息:/etc/docker/daemon .json文件

{
	"bip" : ""192.168.1.5/24",
	"-fixed-cidr": “i0.20.0./16",
	"fixed-cidr-v6":“2001:db8: : /64","mtu" : 1500,
	"-efault-gateway" : "10.20.1.1",
	"default-gateway-v6": "2001 :db8:abcd : :89",
	"dns" :[ "10.20.1.2", "10.20.1.3"]
}

核心选项为bip,即bridge ip之意,用于指定docker@桥自身的IP地址;其它选项可通过此地址计算得出。

  • 示例
[root@node1 ~]# vim /etc/docker/daemon.json 
{
  "registry-mirrors": ["https://jk2v9c0j.mirror.aliyuncs.com"],
  "bip" : "192.168.1.5/24"
}
root@node1 ~]# systemctl restart docker
[root@node1 ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.1.5  netmask 255.255.255.0  broadcast 192.168.1.255
        ether 02:42:c0:3c:85:d3  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

3.Docker sock

dockerd守护进程的C/S,其默认仅监听Unix S0cket格式的地址,/var/run/docker . sock;如果使用TCP套接字,

/etc/docker/daemon.ison;
	"hosts" :["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]

也可向dockerd直接传递"-H|–host"选项;

更改node1 的配置文件

[root@node1 ~]# cat /etc/docker/daemon.json
{
	"registry-mirrors": ["https://jk2v9c0j.mirror.aliyuncs.com"],
  	"bip" : "192.168.1.5/24",
	"hosts" :["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]
}

node2使用-H参数可以查看node1的docker状态

root@node02:/etc/docker# docker -H 10.0.0.45:2375 ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
root@node02:/etc/docker# docker -H 10.0.0.45:2375 image ls
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
ylmcr7/busybox_httpd   v.02  

docker启动错误:https://blog.csdn.net/weixin_46380571/article/details/109275946

11.创建一个网络

1.查看命令参数

[root@node1 ~]# docker network create --help

Usage:	docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which copying the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment

2.创建一个网络

[root@node1 ~]# docker network create -d bridge --subnet "172.26.0.0/16" --gateway "172.26.0.1" mybr0
bfff0e9e4f07900630e941c107b85ef71bf87592035f0fee74e615356cc22061
[root@node1 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
783bb0db3adb        bridge              bridge              local
5a9f8c271f11        host                host                local
bfff0e9e4f07        mybr0               bridge              local
e54ece365094        none                null                local
[root@node1 ~]# ifconfig
br-bfff0e9e4f07: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.26.0.1  netmask 255.255.0.0  broadcast 172.26.255.255
        ether 02:42:80:95:6b:cf  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 28  bytes 2032 (1.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        
        
# -d 指定brdige驱动
#--subnet 指定子网网段
#--gateway 指定网关地址
#mybr0  新创建的名字

3.查看新创建的网络

[root@node1 ~]# ifconfig
br-bfff0e9e4f07: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.26.0.1  netmask 255.255.0.0  broadcast 172.26.255.255
        ether 02:42:80:95:6b:cf  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 28  bytes 2032 (1.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

4.给网卡改名

[root@node1 ~]# ip link set dev docker1 down
[root@node1 ~]# ip link set dev br-bfff0e9e4f07 name docker1
[root@node1 ~]# ip link set dev docker1 up
[root@node1 ~]# ifconfig
docker1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.26.0.1  netmask 255.255.0.0  broadcast 172.26.255.255
        ether 02:42:80:95:6b:cf  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

5.创建t1使用mybr0网络

[root@node1 ~]# docker run --name t1 -it --net mybr0 busybox:latest
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:1A:00:02  
          inet addr:172.26.0.2  Bcast:172.26.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:13 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1102 (1.0 KiB)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # 

6.创建t2使用默认网络

[root@node1 ~]# docker run --name t2 -it --net bridge busybox:latest
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:01:01  
          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:11 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:962 (962.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # 

7.实现两个不通网段之间的容器互通

参考 :https://blog.csdn.net/anqixiang/article/details/96286749

原理就是 创建一对网卡,赋予其ip地址,分别挂载到两个容器上,实现点到点的通信。

1.宿主机开启核心转发
[root@node1 ~]# cat /proc/sys/net/ipv4/ip_forward
1
2.创建一对网卡
[root@node1 ~]# ip link add name veth2.1 type veth peer name veth2.2
[root@node1 ~]# ip link show

23: veth2.2@veth2.1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether ee:1a:1f:46:e9:a6 brd ff:ff:ff:ff:ff:ff
24: veth2.1@veth2.2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 2a:4c:56:ee:85:8d brd ff:ff:ff:ff:ff:ff
3.找到进程号,然后创建网络名称空间的跟踪文件
[root@node1 ~]# docker inspect -f '{{.State.Pid}}' t1
8212
[root@node1 ~]# docker inspect -f '{{.State.Pid}}' t2
8362
[root@node1 ~]# mkdir -p /var/run/netns
[root@node1 ~]# ln -s /proc/8212/ns/net /var/run/netns/8212
[root@node1 ~]# ln -s /proc/8362/ns/net /var/run/netns/8362
4.赋予网卡ip 并配置路由
[root@node1 ~]# ip link set veth2.1 netns 8212
[root@node1 ~]# ip netns exec 8212 ip addr add 10.1.1.1/32 dev veth2.1
[root@node1 ~]# ip netns exec 8212 ip link set veth2.1 up
[root@node1 ~]# ip netns exec 8212 ip route add 10.1.1.2/32 dev veth2.1

[root@node1 ~]# ip link set veth2.2 netns 8362
[root@node1 ~]# ip netns exec 8362 ip addr add 10.1.1.2/32 dev veth2.2
[root@node1 ~]# ip netns exec 8362 ip link set veth2.2 up
[root@node1 ~]# ip netns exec 8362 ip route add 10.1.1.1/32 dev veth2.2
5.查看网卡
  • t2
/ # ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:1a:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.26.0.2/16 brd 172.26.255.255 scope global eth0
       valid_lft forever preferred_lft forever
24: veth2.1@if23: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue qlen 1000
    link/ether 2a:4c:56:ee:85:8d brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.1/32 scope global veth2.1
       valid_lft forever preferred_lft forever
  • t1
/ # ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:c0:a8:01:01 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever
23: veth2.2@if24: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue qlen 1000
    link/ether ee:1a:1f:46:e9:a6 brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.2/32 scope global veth2.2
       valid_lft forever preferred_lft forever
6.测试
  • t1
/ # echo '123' >/tmp/index.html
/ # httpd -h /tmp/
/ # curl 10.1.1.2
sh: curl: not found
/ # wget -O - -q http://10.1.1.2
123
  • t2
/ #  wget -O - -q http://10.1.1.2
123

12.Docker存储卷

1.数据卷简介

Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层
·如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即“写时复制(COW)"机制

在这里插入图片描述

基于NFS共享文件夹,可以实现集群化的存储。

只要有状态的,就要由存储卷:mysql redis

无状态的 LVS 负载均衡

2.为什么会用到数据卷

  • 关闭并重启容器,其数据不受影响;但删除Docker容器,则其更改将会全部丢失
  • 存在的问题
    • 存储于联合文件系统中,不易于宿主机访问;
    • 容器间数据共享不便
    • 删除容器其数据会丢失
  • 解决方案:“卷(volume)"
    • “卷"是容器上的一个或多个"目录”,此类目录可绕过联合文件系统,与宿主机上的某目录“绑定(关联)"

在这里插入图片描述

3.数据卷作用

  • Data volumes provide several useful features for persistent or shared data

    • Volume于容器初始化之时即会创建,由base image提供的卷中的数据会于此期间完成复制
    • Data volumes can be shared and reused among containers
    • Changes to a data volume are made directly
    • Changes to a data volume will not be included when you update an image.
    • Data volumes persist even if the container itself is deleted
  • Volume的初衷是独立于容器的生命周期实现数据持久化,因此删除容器之时既不会删除卷,也不会对哪怕未被引用的卷做垃圾回收操作;

  • 卷为docker提供了独立于容器的数据管理机制

    • 可以把“镜像"想像成静态文件,例如"程序”,把卷类比为动态内容,例如“数据”;于是,镜像可以重用,而卷可以共享;
    • 卷实现了“程序(镜像)"和“数据(卷)"分离,以及“程序(镜像)"和“制作镜像的主机"分离,用户制作镜像时无须再考虑镜像运行的容器所在的主机的环境;

在这里插入图片描述

4.存储卷的类型

  • Docker有两种类型的卷,每种类型都在容器中存在一个挂载点,但其在宿主机上的位置有所不同;
    • Bind mount volume(指定宿主机的目录进行挂载)
      • a volume that points to a user-specified location on the host file system·
  • Docker-managed volume(只需要指明容器内的挂载点)
    • the Docker daemon creates managed volumes in a portion of the host’s file system that’s owned byDocker

在这里插入图片描述

5.在容器中使用Volumes

  • 为docker run命令使用-v选项即可使用Volume

    • Docker-managed volume
      • ~]# docker run-it-name bbox1 -v /data busybox
      • ~]# docker inspect -f {{.Mounts}} bbox1
        • 查着bbox1容器的卷、卷标识符及挂载的主机目录

    示例:

    #1.挂载/data目录到宿主机
    [root@node1 ~]# docker run --name b2 -it -v /data busybox:latest 
    / # ls /
    bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
    
    #2.查看宿主机上挂载点的位置
    
    [root@node1 ~]# docker inspect -f {{.Mounts}} b2
    [{bind  /var/lib/docker/volumes/8c0baac8b7c5a8146efb160810b0c2ae6222ece4f57b8b5778c7dfb9c0400590/_data /data   true rprivate}]
    
    #3.进入宿主机数据卷写入内容
    [root@node1 _data]# pwd
    /var/lib/docker/volumes/8c0baac8b7c5a8146efb160810b0c2ae6222ece4f57b8b5778c7dfb9c0400590/_data
    [root@node1 _data]# echo '123' >>test.index
    [root@node1 _data]# cat test.index 
    123
    [root@node1 _data]# cat test.index 
    123
    hello
    
    #4.容器内查看 文件时共享的
     / # ls data/
    test.index
    / # echo "hello " >> test.index
    / # ls
    bin         dev         home        root        test.index  usr
    data        etc         proc        sys         tmp         var
    / # rm -rf test.index 
    / # ls
    bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
    / # pwd
    /
    / # cd /data/
    /data # ls
    test.index
    /data # echo 'hello' >> test.index 
    
    • Bind-mount Volume
      • ~]# docker run -it -v HOSTDIR:VOLUMEDIR—-name bbox2 busybox
      • ~]# docker inspect -f {{.Mounts }} bbox2
#1.指定本机/data/volumes/b2目录挂载到容器/data
docker run --name b2 -it --rm -v /data/volumes/b2:/data busybox:latest

#2.查看挂载点
[root@node1 ~]# docker inspect -f {{.Mounts}} b2
[{bind  /data/volumes/b2 /data   true rprivate}]

#3.宿主机挂载点写入文件
[root@node1 _data]# cd /data/volumes/b2/
[root@node1 b2]# echo '1234' >>test.index


#4.容器内可以看到
/data # cat test.index 
1234

#5.挂载其他容器也是可以看到 实现持久化存储
[root@node1 b2]# docker run --name b3 -it --rm -v /data/volumes/b2:/data busybox:latest
/ # cat /data/test.index 
1234

ps :docker inspect 过滤语法

[root@node1 ~]# docker inspect -f {{.NetworkSettings.IPAddress}} b3
192.168.1.1
.是基于根  依次类推

6.复制数据卷

  • There are two ways to share volumes between containe
    • 多个容器的卷使用同一个主机目录,例如
      • ~]# docker run -it—-name c1 -v /docker/volumes/v1:/data busybox·
      • ~]#docker run -it --name c2 -v /docker/volumes/v1:/ data busybox
    • 复制使用其它容器的卷,为docker run命令使用-—volumes-from选项
      • ~]# docker run -it --name bbox1 -v /docker/volumes/v1:/data busybox
      • ~]# docker run -it —-name bbox2 --volumes-from bbox1busybo

示例:

#1.创建一个底层容器infracon 指定数据卷到容器内/data/web/html目录
[root@node1 ~]# docker run --name infracon -it -v /data/indracon/volume/:/data/web/html busybox:latest 
#创建容器复制 infracon的网络和数据卷
[root@node1 ~]# docker run --name nginx --network container:infracon --volumes-from infracon -it busybox:latest

#验证数据卷
[root@node1 ~]# docker inspect -f {{.Mounts}} infracon
[{bind  /data/indracon/volume /data/web/html   true rprivate}]
[root@node1 ~]# docker inspect -f {{.Mounts}} nginx
[{bind  /data/indracon/volume /data/web/html   true rprivate}]

#验证网络
[root@node1 ~]# docker inspect -f {{.NetworkSettings.IPAddress}} infracon
192.168.1.3
[root@node1 ~]# docker inspect -f {{.NetworkSettings.IPAddress}} nginx
# 无ip

7.做一个lnmp

只暴漏nginx的端口,tomcat之间只lo接口上,
在这里插入图片描述

docker-compose 单机编排工具

11.Dockerfile详解

1.镜像相关的操作

  • 镜像生成的途径
    • Dockerfile
    • 基于容器制作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5isWJhP7-1623723370205)(/Users/yingliming/Nutstore Files/我的坚果云/github/clpe/docker/assets/iShot2020-10-28-09.04.10.png)]

2.About Dockerfile

Dockerfile是基于源码生成一个镜像

纯文本文件。包含了一些指令而已

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bmwJ7fWd-1623723370206)(/Users/yingliming/Nutstore Files/我的坚果云/github/clpe/docker/assets/iShot2020-10-28-09.04.19.png)]

3.Dockerfile Format

  • Format
    • #comment(注释信息 使用#)
    • INSTRUCTION arguments.(指令加参数)
  • 指令不区分大小写
    • 但是约定俗成的都使用大写
  • Docker runs 在Dockerfile中是有顺序的
  • 基于一个已存在的镜像之上

4.环境变量

  1. 如果NAME没有值 使用tom
[root@ylm_aliyun ~]# echo ${NAME:-tom}
tom
[root@ylm_aliyun ~]# NAME=jerry
[root@ylm_aliyun ~]# echo ${NAME:-tom}
jerry

#如果NAME有值 则使用tom 
[root@ylm_aliyun ~]# echo ${NAME:+tom}
tom
[root@ylm_aliyun ~]# unset NAME
[root@ylm_aliyun ~]# echo ${NAME:+tom}

[root@ylm_aliyun ~]#

5.Dockerfile Instructions

FROM
  • FROM指令最重要的一个必须为Dockerfile文件开篇的第一个非注释行,用于为映像文件构建过程指定基准镜像,后续的指令运行于此基础镜像所提供的运行环境
  • 基准镜像可以使用任何可用镜像,默认情况下,docker build 会在docker主机上查找指定的镜像文件,若其不存在,会在Docker Hub拉取所需镜像文件。
    • 如果找不到,docker build 会返回一个错误信息
  • Syntax
    • FROM [:] 或
    • FROM @
      • 指定为base image 的名称
      • base image 的标签,为可选项,默认为latest
FROM busybox:latest
MAINTANIER(depreacted)
  • 用于让dockerfile提供制作者的信息

  • Dockerfile 并没有规定MAINTANIER的位置,但推荐其防与FROM指令之后

  • Syntax

    • MAINTAINER<author’s detail>
      • <author’s detail>可以是任何信息,但约定俗成的一般是作者名称及邮箱地址
      • MAINTANIER “ylm ylmcr7@163.com”
  • LABEL (新版本中可以使用LABEl标签)

MAINTAINER ylm
#LABEL maintainer="ylm" app="httpd"
COPY
  • 用于docker主机复制文件至创建的新映像文件

  • Syntax

    • COPY …或
    • COPY["",…""]
      • :要复制的源文件或目录,支持使用通配符
      • :目标路径,即正在创建的image的文件系统路径;建议为使用绝对路径,COPY指定则以WORKDIR为其起始路径
    • 注意:在路径中有空白字符时,通常使用第二种格式,用引号
  • 文件复制准则

    • 必须是build上下文中的路径,不能是其父目录中的文件
    • 如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制
    • 如果指定了多个,或在中使用了通配符,则必须是一个目录,且必须以 / 结尾。
    • 如果事先不存在,它将会被自动创建,这也包括其父目录路径。
COPY index.html /data/web/html/
  • 示例:复制文件
[root@ylm_aliyun ~]# cat Dockerfile
FROM busybox:latest
MAINTAINER ylm
#LABEL maintainer="ylm"
COPY index.html /data/web/html/
[root@ylm_aliyun ~]# echo '123' > index.html  #文件必须提前创建好
[root@ylm_aliyun ~]# docker build -t testhttpd:v1.1 ./
[root@ylm_aliyun ~]# docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
testhttpd                  v1.1                625095fcb64f        26 seconds ago      1.23MB

#命令执行完 容器就结束了
[root@ylm_aliyun ~]# docker run --name web1 --rm testhttpd:v1.1 cat /data/web//html/index.html
123
  • 示例:复制目录
[root@ylm_aliyun ima]# cat Dockerfile
FROM busybox:latest
MAINTAINER ylm
#LABEL maintainer="ylm"
COPY index.html /data/web/html/
COPY yum.repos.d/ /etc/yum.repos.d/
[root@ylm_aliyun ima]# docker build -t testhttpd:v1.2 ./
[root@ylm_aliyun ima]# docker run --name web1 --rm testhttpd:v1.2 ls /etc/yum.repos.d
CentOS-Base.repo
docker-ce.repo
epel-testing.repo
epel.repo
epel.repo.rpmnew
ADD
  • ADD指令类似于COPY指令,ADD指令支持TAR文件和URL路径

  • Syntax

    • ADD…或
    • ADD[",…"]
  • 操作准则

    • 同COPY命令
    • 如果是url,不以 / 结尾,则指定文件将被下载并直接被创建为;如果以/结尾,则文件名URL指定的文件将被直接下载并保存为/
    • 如果是一个本地系统上的压缩格式tar文件,他将被展开为一个目录,其行为类似于"tar -x"命令,然后,通过URL获取到的tar文件将不会被自动展开。
    • 如果有多个,或其间接或直接使用了通配符,则必须是一个以/结尾的目录路径;如果不以/结尾,则其被视为一个普通文件,的内容被直接写入到;
  • 示例:当URL时, 无法自动解压

[root@ylm_aliyun ima]# cat Dockerfile
FROM busybox:latest
MAINTAINER ylm
#LABEL maintainer="ylm"
COPY index.html /data/web/html/
COPY yum.repos.d/ /etc/yum.repos.d/
ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/local/src/

[root@ylm_aliyun ima]# docker build -t testhttpd:v1.3 ./

[root@ylm_aliyun ima]# docker run --name web1 --rm testhttpd:v1.3 ls /usr/local/src/
nginx-1.18.0.tar.gz

示例:是tar时 自动解压

[root@ylm_aliyun ima]# cat Dockerfile
FROM busybox:latest
MAINTAINER ylm
#LABEL maintainer="ylm"
COPY index.html /data/web/html/
COPY yum.repos.d/ /etc/yum.repos.d/
# ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/local/src/
ADD nginx-1.18.0.tar.gz /usr/local/src/
[root@ylm_aliyun ima]# docker build -t testhttpd:v1.4 ./
[root@ylm_aliyun ima]# docker run --name web1 --rm testhttpd:v1.4 ls /usr/local/src/
nginx-1.18.0
WORKDIR
  • 用于为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定工作目录

  • Syntax

    • WORKDIR
      • 在Dockerfile文件中,WORKDIR指令可以出现多次,其路径也可以为相对路径,,不过,其是相对于以前一个WORKDIR指令指定的路径
      • 另外,WORKDIR也可以调用由ENV指令定义的变量
    • 例如:
      • WORKDIR /var/log
      • WORKDIR $STATEPATH
WORKDIR /usr/local/
VOLUME
  • 用于在imag中创造一个挂载点目录,已挂载Docker Host上的卷或其他容器上的卷
  • Syntax
    • VOLUME 或
    • VOLUME [""]
  • 如果挂载点目录路径下此前文件存在,docker run命令会在卷挂载完成之后将此前所有的文件复制到新挂载的卷中
[root@ylm_aliyun ima]# cat Dockerfile
FROM busybox:latest
MAINTAINER ylm
#LABEL maintainer="ylm"
COPY index.html /data/web/html/
COPY yum.repos.d/ /etc/yum.repos.d/

# ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/local/src/

WORKDIR /usr/local/
ADD nginx-1.18.0.tar.gz ./src/
VOLUME /data/mysql/

[root@ylm_aliyun ima]# docker build -t testhttpd:v1.5 ./
[root@ylm_aliyun ima]# docker run --name web1 --rm testhttpd:v1.5 mount
/dev/vda1 on /data/mysql type ext4 (rw,relatime,data=ordered)

#创建一个只存活60s的卷
# docker run --name web1 --rm testhttpd:v1.5 sleep 60
# docker inspect -f {{.Mounts}} web1
EXPOSE
  • 用于为容器打开指定要监听的端口实现与外部通信
  • Syntax
    • EXPOSE [/] [[/]…]
      • 用于指定传输层协议,可以tcp、ump 默认是tcp
    • EXPOSE 一次可以指定多个端口 例如
      • EXPOSE 11211/udp 11211/tcp
[root@ylm_aliyun ima]# cat Dockerfile
FROM busybox:latest
MAINTAINER ylm
#LABEL maintainer="ylm"
COPY index.html /data/web/html/
COPY yum.repos.d/ /etc/yum.repos.d/
# ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/local/src/
WORKDIR /usr/local/
ADD nginx-1.18.0.tar.gz ./src/
VOLUME /data/mysql/
EXPOSE 80/tcp

[root@ylm_aliyun ima]# docker build -t testhttpd:v1.6 ./

[root@ylm_aliyun ima]# docker run --name web1 --rm testhttpd:v1.6 /bin/httpd -f -h /data/web/html/
[root@ylm_aliyun ima]# docker inspect -f {{.NetworkSettings.IPAddress}} web1
172.17.0.2
[root@ylm_aliyun ~]# curl 172.17.0.2
123

#并没有端口暴露在外面  EXPOSE 定义一个待暴露的端口 
[root@ylm_aliyun ima]# docker port web1
[root@ylm_aliyun ima]#


#使用-P 就会把端口暴露在外面
#[root@ylm_aliyun ima]# docker run --name web1 --rm -P testhttpd:v1.6 /bin/httpd -f -h /data/web/html/
#[root@ylm_aliyun ima]# docker port web1
80/tcp -> 0.0.0.0:32768
ENV
  • 用于为镜像定义所需的环境变量,并可为Dockerfile只中位于其后的其他指令(如ENV 、ADD、COPY)所调用
  • 调用格式为 v a r i a b l e n a m e 或 variable_name或 variablename{variable_name}
  • Syntax
    • ENV 或
    • ENV =…
  • 第一种格式中,之后的所有内容均会被视作其的组成部分,因此,一次只能设置一个变量;
  • 第二种格式可用一次设置多个变量,每个变量为一个"="的键值对,如果中包含空格,可以以反斜线( \ )进行转义,也可通过加引号进行标示;另外,反斜线也可用于续行;
  • 定义多个变量时,建议使用第二种格式,以便在同一层完成所有功能
[root@ylm_aliyun ima]# cat Dockerfile
FROM busybox:latest
MAINTAINER ylm
#LABEL maintainer="ylm"
ENV DOC_ROOT=/data/web/html/ \
    WEB_SERVER_PACKAGE="nginx-1.18.0"
COPY index.html ${DOC_ROOT:-/data/web/html/}
COPY yum.repos.d/ /etc/yum.repos.d/
# ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/local/src/
WORKDIR /usr/local/
ADD ${WEB_SERVER_PACKAGE}.tar.gz ./src/
VOLUME /data/mysql/
EXPOSE 80/tcp

[root@ylm_aliyun ima]# docker build -t testhttpd:v1.7 ./
[root@ylm_aliyun ima]# docker run --name web1 --rm -P testhttpd:v1.7  ls /usr/local/src/
nginx-1.18.0
[root@ylm_aliyun ima]# docker run --name web1 --rm -P testhttpd:v1.7  ls /data/web/html
index.html

#使用printenv输出环境变量  dockerfile中定义的变量是在容器启动中使用的
[root@ylm_aliyun ima]# docker run --name web1 --rm -P testhttpd:v1.7  printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=3ae11372d440
DOC_ROOT=/data/web/html/
WEB_SERVER_PACKAGE=nginx-1.18.0
HOME=/root
  • docker run时也可以指定环境变量
[root@ylm_aliyun ima]# docker run --name web1 --rm -P -e WEB_SERVER_PACKAGE="nginx-1.18.1" testhttpd:v1.7  printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=3c4308699134
WEB_SERVER_PACKAGE=nginx-1.18.1
DOC_ROOT=/data/web/html/
HOME=/root
#不会影响docker build的值
[root@ylm_aliyun ima]# docker run --name web1 --rm -P -e WEB_SERVER_PACKAGE="nginx-1.18.1" testhttpd:v1.7 ls /usr/local/src
nginx-1.18.0

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mLjPx0dC-1623723370207)(/Users/yingliming/Nutstore Files/我的坚果云/github/clpe/docker/assets/iShot2020-10-28-09.04.31.png)]

RUN
  • 用于h指定docker build过程中运行的程序,其可以是任何命令

  • Syntax

    • RUN 或
    • RUN ["","",""]
  • 第一种格式中,通常是一个shell命令,且以“/bin/sh -c”来运行它,这意味着此进程在容器中的PID不为1,不能接收Unix信号,因此,当使用docker stop 命令停止容器时,此进程收不到SIGTERM信号;

  • 第二种语法格式中的参数是一个JSON格式的数组,其中为要运行的命令,后面的为传递给命令的选项或参数;然而,此种格式指定的命令不会以"/bin/sh -c"来发起,因此常见的shell操作如变量替换以及通配符(? . *)替换将不会进行;不过,如果要运行的命令依赖于此shell特性的话,可以将其替换为类似下面的格式

    • RUN ["/bin/bash","-c","","<param 1>"]
  • 注意: JSON数组中,要使用双引号

  • 示例:

[root@ylm_aliyun ima]# cat Dockerfile
FROM busybox:latest
MAINTAINER ylm
#LABEL maintainer="ylm"
ENV DOC_ROOT=/data/web/html/ \
    WEB_SERVER_PACKAGE="nginx-1.18.0"
COPY index.html ${DOC_ROOT:-/data/web/html/}
COPY yum.repos.d/ /etc/yum.repos.d/
ADD http://nginx.org/download/${WEB_SERVER_PACKAGE}.tar.gz /usr/local/src/
WORKDIR /usr/local/
#ADD ${WEB_SERVER_PACKAGE}.tar.gz ./src/
VOLUME /data/mysql/
EXPOSE 80/tcp

RUN cd /usr/local/src && \
    tar -xf ${WEB_SERVER_PACKAGE}.tar.gz && \
    mv ${WEB_SERVER_PACKAGE} webserver
    
[root@ylm_aliyun ima]# docker build -t testhttpd:v1.8 ./
[root@ylm_aliyun ima]# docker run --name web1 --rm -P -e WEB_SERVER_PACKAGE="nginx-1.18.1" -it testhttpd:v1.8 ls /usr/local/src
nginx-1.18.0.tar.gz  webserver
CMD
  • 是定义一个镜像软件在启动容器时默认要运行的程序

  • 类似于RUN指令,CMD指令也可以用于运行任何命令或应用程序,不过,二者的运行时间不通

    • RUN指令运行于映像文件构建过程中,而CMD指令运行于Dockerfile构建出的新映像文件启动一个容器时
    • CMD指令的首要目的在于为启动的容器指定默认要运行的容器,且运行结束后,容器也将终止;不过。CMD指定的命令其可以被docker run的命令行选项所覆盖
    • 在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效
  • Syntax

    • CMD 或
      • id 不为1 没法使用docker stop去停止它
      • 例如nginx如果不是s ystemctl来管理。而是基于shell进程运行的子进程。要把它放入后台。必须加入 COMMAND & 符号,加上&并不能剥离与shell的关系,他的父进程仍然是sehll。如果我们exit推出了shell,那shell退出时,会把他的子进程带走.要实现shell退出后,子进程不退出,需要加上nohub COMMAND & 这样就可以送到后台并且剥离于当前shell,我们使用exec COMMAND 取代shell,称为id为1 的子进程,shell退出。
    • CMD ["","",""]或
      • 这种格式时执行为id为1的进程,可接收,可以执行系统发过来的信号,
      • 如果指令有空白字符时
    • CMD ["",""]
  • 前两种语法格式的意义同RUN

  • 第三种则用于为ENTRYPOINT指令提供默认值

  • 示例:更改模式bash进程为我们自己的服务

[root@ylm_aliyun ima2]# cat Dockerfile
FROM busybox
LABEL maintainer="ylm" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
    echo '<h1>Busybox httpd server</h1>' >${WEB_DOC_ROOT}/index.html
CMD /bin/httpd -f -h ${WEB_DOC_ROOT}   #这是调用shell进程区启动。会解析shell进程
[root@ylm_aliyun ima2]# docker build -t httpd:v1.6 ./

#在这个镜像中我们已经定义了 默认的程序不是shell了,而是httpd,以往我们加个-it就自动进入交互接口了,现在加-it是没有用的。


#验证  运行的是httpd。解析shell
[root@ylm_aliyun ima2]# docker inspect -f {{.Config.Cmd}} httpd:v1.6
[/bin/sh -c /bin/httpd -f -h ${WEB_DOC_ROOT}]

#基于此运行一个容器
[root@ylm_aliyun ima2]# docker run --name web1 -it --rm -P httpd:v1.6
#卡住了 因为默认运行程序 是httpd服务,加-it没有用,httpd没有交互式接口,以往加-it就直接进入交互接口了,现在加-it没有用了。

#使用ps查看。web2运行的httpd服务,不是shell,是shell的子进程,默认没有交互式接口,-it是登录不进去的
[root@ylm_aliyun ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
832166d8c2d6        httpd:v1.6          "/bin/sh -c '/bin/ht…"   4 minutes ago       Up 4 minutes                            web1
#我们可以使用exec 额外登录进去试试
[root@ylm_aliyun ~]# docker exec -it web1 /bin/sh
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/httpd -f -h /data/web/html/    #对应显示的为1,默认执行了exec 
    6 root      0:00 /bin/sh
   11 root      0:00 ps
   
 #这样docker kill就可以停掉  验证了镜像默认启动的命令被我们改掉了  shell解析也是成功 的
 
 / # printenv
WEB_DOC_ROOT=/data/web/html/
HOSTNAME=832166d8c2d6
SHLVL=1
HOME=/root
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/

#环境变量是在dockerfile中注入的,所以run的时候也可以使用, /bin/httpd -f -h /data/web/html/这个命令也确实在run中执行, 有些环境变量在run的时候也是可以被使用的,但是有的在build的时候已经被执行过了,
  • 去掉shell无法解析变量的情况
#这种方式并不会以shell子进程的方式来解析
CMD ["/bin/httpd", "-f","-h ${WEB_DOC_ROOT}"]

#启动镜像后查看没有/bin/sh了  直接显示的是${WEB_DOC_ROOT},没能解析
[root@ylm_aliyun ima2]# docker inspect -f {{.Config.Cmd}} httpd:v2.0
[/bin/httpd -f -h ${WEB_DOC_ROOT}]

#默认不会运行为shell的子进程,无法解析shell变量 
[root@ylm_aliyun ima2]# docker run --name web1 -it --rm -P httpd:v2.0
httpd: can't change directory to ' ${WEB_DOC_ROOT}': No such file or directory
  • 手动添加shell解析
[root@ylm_aliyun ima2]# cat Dockerfile
FROM busybox
LABEL maintainer="ylm" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
    echo '<h1>Busybox httpd server</h1>' >${WEB_DOC_ROOT}/index.html
#CMD ["/bin/httpd", "-f","-h ${WEB_DOC_ROOT}"]
CMD ["bin/sh","-c","/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
#CMD /bin/httpd -f -h ${WEB_DOC_ROOT}

[root@ylm_aliyun ima2]# docker build -t httpd:v2.2 ./
[root@ylm_aliyun ima2]# docker run --name web1 -it --rm -P httpd:v2.2
[root@ylm_aliyun ima2]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@ylm_aliyun ima2]# docker run --name web1 -it -P httpd:v2.2
[root@ylm_aliyun ima2]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
9addade97e56        httpd:v2.2          "bin/sh -c /bin/http…"   13 seconds ago      Exited (0) 12 seconds ago                       web1
[root@ylm_aliyun ima2]# docker logs web1
#没有任何日志输出。
原因:
解析变量还是有问题的,找不到路径,找到路径也没有文件类似的格式, 要么就是启动的不是id为1的进程导致的

排查:将变量改成路径
[root@ylm_aliyun ima2]# cat Dockerfile
FROM busybox
LABEL maintainer="ylm" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
    echo '<h1>Busybox httpd server</h1>' >${WEB_DOC_ROOT}/index.html
#CMD ["/bin/httpd", "-f","-h ${WEB_DOC_ROOT}"]
#CMD ["bin/sh","-c","/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
CMD ["bin/sh","-c","/bin/httpd","-f","-h /data/web/html/"]
#CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
[root@ylm_aliyun ima2]# docker build -t httpd:v2.3 ./
[root@ylm_aliyun ima2]# docker run --name web1 -it --rm -P httpd:v2.3
[root@ylm_aliyun ima2]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@ylm_aliyun ima2]# docker ps -a   #定义的--rm 所以被删除了   
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
#还是启动不了说明不是变量的问题 而是我们/bin/sh -c id号导致的,大部分情况。只要命令没有问题 /bin/sh -c是不会出错的
  • 第三种格式演示 结和下一个命令

  • init (内核启动的进程)

    • nginx 为shell启动的进程所有程序都会占用shell进程来启动
    • command & 后台启动但是未脱离shell 父进程依然是shell。如果退出shell,所有父进程退出前会把它的子进程消除掉
    • nohub command & 送到后台启动剥离和shell关系
  • nginx

  • exec COMMAND取代shell进程 shell退出 称为id为1的进程

很多时候我们在容器中启动一个子进程时,可以不基于shell,要基于shell,并且不违背这个主进程,一定时id为1的 通过exec COMMAND来是实现

exec 顶替shell的id为1. shell退出 它就成为了id为1的进程

ENTRYPOINT
  • 类似CMD指定的功能,用于为容器指定默认的程序,从而使得容器像是一个单独的可执行程序。

  • 与CMD命令不同,由ENTRYPOINT启动的程序不会被docker run命令指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序。

    • 不过,docker run的命令–entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序
  • Syntax

    • ENTRYPOINT
    • ENTRYPOINT ["","",""]
  • docker run 命令传入的命令参数会覆盖CMD指令的内容,并且附加到ENTRYPOINT命令作为其参数使用。

  • Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效

  • 示例:我们可以指定命令进行覆盖 启动的程序 ,如果我们不想让其覆盖,那么CMD做不到,ENTRYPOINT可以做到

docker run --name web1 -it --rm -P httpd:v2.3 /bin/httpd -f -h /data/web/html/
  • 示例:使用ENTRYPOINT指令后docker run 加参数 并不会覆盖指定的默认程序
[root@ylm_aliyun ima2]# cat Dockerfile 
FROM busybox
LABEL maintainer="ylm" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
    echo '<h1>Busybox httpd server</h1>' >${WEB_DOC_ROOT}/index.html
#CMD ["/bin/httpd", "-f","-h ${WEB_DOC_ROOT}"]
#CMD ["bin/sh","-c","/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
#CMD ["bin/sh","-c","/bin/httpd","-f","-h /data/web/html/"]
ENTRYPOINT /bin/httpd -f -h ${WEB_DOC_ROOT}
[root@ylm_aliyun ima2]# docker run --name web2 -it --rm -P httpd:v2.4

[root@ylm_aliyun ~]# docker exec -it web2 /bin/sh
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/httpd -f -h /data/web/html/
    6 root      0:00 /bin/sh
   11 root      0:00 ps
/ # 
#服务是正常启动的。

[root@ylm_aliyun ima2]# docker run --name web2 -it --rm -P httpd:v2.4 ls /data/web/html/
#此时并没有运行
/ # [root@ylm_aliyun ~]# docker exec -it web2 /bin/sh
/ # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/httpd -f -h /data/web/html/
    6 root      0:00 /bin/sh
   11 root      0:00 ps -ef
/ # 

#使用的ENTRYPOINT指令后。 odkcer run 传递的参数没有被覆盖。还会被当作参数传递给ENTRYPOINT的参数 依然运行的是httpd服务   所以这是与CMD的区别
  • 示例CMD和ENTRYPOINT同时存在

    CMD会被当作参数传给ENTRYPOIJNT

[root@ylm_aliyun ima2]# cat Dockerfile 
FROM busybox
LABEL maintainer="ylm" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
    echo '<h1>Busybox httpd server</h1>' >${WEB_DOC_ROOT}/index.html
#CMD ["/bin/httpd", "-f","-h ${WEB_DOC_ROOT}"]
CMD ["/bin/httpd", "-f","-h ${WEB_DOC_ROOT}"]
#CMD ["bin/sh","-c","/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
#CMD ["bin/sh","-c","/bin/httpd","-f","-h /data/web/html/"]
ENTRYPOINT /bin/sh -c

[root@ylm_aliyun ima2]# docker inspect httpd:v2.5

#相当于传递了参数CMD 变成了/bin/sh -c 自己调用了自己
            "Cmd": [
                "/bin/httpd",
                "-f",
                "-h ${WEB_DOC_ROOT}"
            ],
            "Image": "sha256:1772a732bb2493baa603ffacbe08b65247c509f4fc8876244f96d5779eac7456",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/bin/sh",
                "-c",
                "/bin/sh -c"
            ],





#如果要明确使用自己的变量,我们可以加上双引号
ENTRYPOINT ["/bin/sh","-c"]
[root@ylm_aliyun ima2]# docker inspect httpd:v2.6


            "Cmd": [
                "/bin/httpd",
                "-f",
                "-h ${WEB_DOC_ROOT}"
            ],
            "Image": "sha256:1772a732bb2493baa603ffacbe08b65247c509f4fc8876244f96d5779eac7456",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/bin/sh",
                "-c"
            ],
#启动一个容器 确实是httpd服务为后台运行的
[root@ylm_aliyun ima2]# docker run --name web3 -it -P httpd:v2.6
[root@ylm_aliyun ima2]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
74ff5a8866a5        httpd:v2.6          "/bin/sh -c /bin/htt…"   5 seconds ago       Exited (0) 4 seconds ago                       web3

#运行了ls 解析有问题
[root@ylm_aliyun ima2]# docker run --name web3 -it -P httpd:v2.6 ls /data
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var

#把他当成一个参数传出来
[root@ylm_aliyun ima2]# docker run --name web3 -it -P httpd:v2.6 "ls /data"
web





——————————————————————————————————————重点------------------------------------
FROM busybox
LABEL maintainer="ylm" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
    echo '<h1>Busybox httpd server</h1>' >${WEB_DOC_ROOT}/index.html
#CMD ["/bin/httpd", "-f","-h ${WEB_DOC_ROOT}"]
CMD ["/bin/httpd", "-f","-h ${WEB_DOC_ROOT}"]
#CMD ["bin/sh","-c","/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
#CMD ["bin/sh","-c","/bin/httpd","-f","-h /data/web/html/"]
ENTRYPOINT ["/bin/sh","-c"]



CMD会被当成默认参数传给ENTRYPOINT,就是ENTRYPOINT没有值时 才会使用他  我们面执行了“ls /data”  就会当成参数传给ENTRYPOINT , 就不会使用默认参数了,我们这里的参数时传给了CMD ,除非使用ENTRYPOINT,否则ENTRYPOINT是不会被覆盖的。
指定一个灵活的nginx镜像
  1. 查看nginx启动路径
[root@ylm_aliyun nginx]# docker run --name nginx1 -it nginx:1.14-alpine /bin/sh
/ # which nginx
/usr/sbin/nginx
/ # ls /etc/nginx/
conf.d                  koi-utf                 nginx.conf              uwsgi_params.default
fastcgi.conf            koi-win                 nginx.conf.default      win-utf
fastcgi.conf.default    mime.types              scgi_params
fastcgi_params          mime.types.default      scgi_params.default
fastcgi_params.default  modules                 uwsgi_params
  1. Dockerfile
[root@ylm_aliyun nginx]# cat Dockerfile 
FROM nginx:1.14-alpine
LABEL maintainer="ylm"
ENV NGX_DOC_ROOT="/data/web/html/"
ADD entrypoint.sh /bin/
ADD index.html ${NGX_DOC_ROOT}
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
#让nginx启动在前台  daemon off;  
#-g 是全局参数 global
#没有指定路径,会默认运行/etc/nginx/nginx.conf,nginx.conf会默认运行conf.d下面的所有文件

ENTRYPOINT ["/bin/entrypoint.sh"]
#我们用这个脚本,通过环境变量生成配置文件了,entrypoint是先要运行的,CMD是把参数传递给ENTRYPOINT的,entrypoint运行完才运行CMD,这个脚本要引用这个参数并运行它,

首先用entrypoint.sh初始化出来一个配置文件,这个脚本会触发sehll进程,在里面生成一个配置文件,初始化之后会运行CMD,会把CMD当作顶替自己的进程,nginx启动了,shell进程也就推出了,"/usr/sbin/nginx","-g","daemon off;"成为了唯一的进程。

  1. 编辑脚本
[root@ylm_aliyun nginx]# cat entrypoint.sh 
#!/bin/sh
#
cat > /etc/nginx/conf.d/www.conf << EOF
server {
	server_name $HOSTNAME;
	listen ${IP:-0.0.0.0}:${PORT:-80};
	root ${NGX_DOC_ROOT:-/usr/share/nginx/html};
}
EOF

exec "$@"

#传递所有参数,并替代当前进程

[root@ylm_aliyun nginx]# cat index.html 
<h1>this is nginx</h1>
  1. build镜像
[root@ylm_aliyun nginx]# docker build -t nginx:v2.0 ./

[root@ylm_aliyun nginx]# docker run --name myweb1 --rm -P nginx:v2.0
  1. 基于镜像启动一个容器 传入传镜变量
[root@ylm_aliyun nginx]# docker run --name myweb1 --rm -P -e "PORT=8080" nginx:v2.0
  1. 验证参数
[root@ylm_aliyun nginx]# docker exec -it myweb1 /bin/sh
/ # netstat -ntlp
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:8080            0.0.0.0:*               LISTEN      1/nginx -g daemon o
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx -g daemon o
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 nginx: master process /usr/sbin/nginx -g daemon 
    8 nginx     0:00 nginx: worker process
    9 root      0:00 /bin/sh
   15 root      0:00 ps
/ # cat /etc/nginx/conf.d/www.conf 
server {
	server_name 8bf0df43733f;
	listen 0.0.0.0:8080;
	root /data/web/html/;
}
/ # wget -O - -q 8bf0df43733f:8080
<h1>this is nginx</h1>

USER
  • 用于指定运行image时的或运行Dockerfile中任何RUN、CMD或ENTRYPOINT指令指定的程序时的用户名或UID
  • 默认情况下,container的运行身份为root用户
  • Syntax
    • USER|
    • 需要注意的是,可以为任意数字,但实践中其必须为/etc/passwd中某用户的有效UID,否则,docker run命令将运行失败
HEALTH CHECK
  • HEALTH CHECK [OPTIONS] CMD 定义一个CMD 指定一个命令 检查主进程是否正常,每隔一段时间检查一次

  • The options that can appear before CMD are:

    • –interval=DURATION (default:30s)
    • –timeout=DURATION(default:30s)
    • –start-period=DURATION(default:0s) #根据数字进程的速度设置秒数
    • –retries=N(default:3) #检查三次
  • 响应的返回值

    • 0:success
    • 1: ubhealthy
    • 2: reserverd
  • FOR example

    • HEALTHCHECK --interval=5m --timeout=3s \

      CMD curl -f http://localhost/ || exit 1

  • 为nginx做健康检查

FROM nginx:1.14-alpine
LABEL maintainer="ylm"
ENV NGX_DOC_ROOT="/data/web/html/"
ADD entrypoint.sh /bin/
ADD index.html ${NGX_DOC_ROOT}
EXPOSE 80/tcp 

HEALTHCHECK --start-period=3s CMD wget -O - -q  http://${IP:-0.0.0.0}:${PORT:-80}/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]


[root@ylm_aliyun nginx]# cat entrypoint.sh 
#!/bin/sh
#
cat > /etc/nginx/conf.d/www.conf << EOF
server {
	server_name $HOSTNAME;
	listen ${IP:-0.0.0.0}:${PORT:-80};
	root ${NGX_DOC_ROOT:-/usr/share/nginx/html};
}
EOF

exec "$@"


[root@ylm_aliyun nginx]# cat index.html 
<h1>this is nginx</h1>


[root@ylm_aliyun nginx]# docker build -t nginx:v2.5 ./

#健康检查已经开始了 每隔3秒一次
[root@ylm_aliyun nginx]# docker run --name myweb1 --rm -P -e "PORT=8
127.0.0.1 - - [27/Oct/2020:14:22:57 +0000] "GET / HTTP/1.1" 200 23 "
127.0.0.1 - - [27/Oct/2020:14:23:27 +0000] "GET / HTTP/1.1" 200 23 "
127.0.0.1 - - [27/Oct/2020:14:23:57 +0000] "GET / HTTP/1.1" 200 23 "
127.0.0.1 - - [27/Oct/2020:14:24:27 +0000] "GET / HTTP/1.1" 200 23 
SHELL
  • 默认LInux是["/bin/sh","-c"],在windows是[“cmd”,"/s","/C"]
STOPSIGNAL
  • Sntax
    • STOPSIGNAL 9
  • 默认是docker kill 15 可以改成9 默认不动
ARG
  • 变量 只在build过程中使用, --build-arg=flag
  • 在build过程中使用变量 使用 --build-arg 进行传值
  • 示例:
[root@ylm_aliyun nginx]# cat Dockerfile 
FROM nginx:1.14-alpine
ARG author="ylm"

LABEL maintainer="${author}"
ENV NGX_DOC_ROOT="/data/web/html/"
ADD entrypoint.sh /bin/
ADD index.html ${NGX_DOC_ROOT}
EXPOSE 80/tcp 
HEALTHCHECK --start-period=3s CMD wget -O - -q  http://${IP:-0.0.0.0}:${PORT:-80}/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]

#查看效果

docker inspect nginx:v4.0

            "OnBuild": null,
            "Labels": {
                "maintainer": "ylm"
            },




#赋予变量

[root@ylm_aliyun nginx]# docker build --build-arg author="ylm <ylmcr7@163.com>" -t nginx:v4.1 ./
#查看效果
[root@ylm_aliyun nginx]# docker inspect -f {{.Config.Labels}} nginx:v4.1
map[maintainer:ylm <ylmcr7@163.com>]
ONBUILD
  • 用于在Dockerfile中定义一个触发器
    · lDockerfile用于build映像文件,此映像文件亦可作为base image被另一个Dockerfile用作FROM指令的参数,并以之构建新的映像文件

  • 在后面的这个Dockerfile中的FROM指令在build过程中被执行时,将会“触发"创建其base image的Dockerfile文件中的ONBUILD指令定义的触发器

  • Syntax

    • ONBUILD
  • 尽管任何指令都可注册成为触发器指令,但ONBUILD不能自我嵌套,且不会触发FROM和 MAINTAINER指令

  • 使用包含ONBUILD指令的Dockerfilc构建的镜像应该使用特殊的标签,例如ruby:2.0-onbuild

  • 在ONBUILD指令中使用ADD或COPY指令应该格外小心,因为新构建过程的上下文在缺少指定的源文件时会失败

  • 示例:

[root@ylm_aliyun nginx]# cat Dockerfile 
FROM nginx:1.14-alpine
ARG author="ylm"

LABEL maintainer="${author}"
ENV NGX_DOC_ROOT="/data/web/html/"
ADD entrypoint.sh /bin/
ADD index.html ${NGX_DOC_ROOT}
EXPOSE 80/tcp 

HEALTHCHECK --start-period=3s CMD wget -O - -q  http://${IP:-0.0.0.0}:${PORT:-80}/
ONBUILD ADD http://nginx.org/download/nginx-1.19.4.tar.gz /usr/local/src/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]

在构建dockerfile时不会使用ONEBUILD 只有基于这个镜像去做的时才会触发ONEBUILD

[root@ylm_aliyun ima3]# cat Dockerfile
FROM nginx:v4.2
RUN mkdir /tmp/test

#在创建时 会触发器下载
[root@ylm_aliyun ima3]# docker build -t test:v1.1 ./
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM nginx:v4.2

# Executing 1 build trigger

Downloading  1.055MB/1.055MB
 ---> 433aaeb680fc
Step 2/2 : RUN mkdir /tmp/test
 ---> Running in 5aaec837d0c9
Removing intermediate container 5aaec837d0c9
 ---> 33811440e311
Successfully built 33811440e311
Successfully tagged test:v1.1

#验证是否下载
[root@ylm_aliyun ima3]# docker run --name test1 --rm test:v1.1 ls /usr/local/src 
nginx-1.19.4.tar.gz     #基础镜像ONEBUILD的触发器 已经被下载

12.Docker Registry

作用:托管镜像

定义个存储卷 网络存储。挂载地址为NFS

  • yum 安装
[root@ylm_aliyun ~]# yum info docker-registry
[root@ylm_aliyun ~]# yum install docker-registry
[root@ylm_aliyun ~]# rpm -ql docker-distribution
[root@ylm_aliyun registry]# cat /etc/docker-distribution/registry/config.yml
[root@ylm_aliyun registry]# systemctl start docker-distribution
[root@ylm_aliyun registry]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 :::5000                 :::*                    LISTEN      4164/registry
    
[root@ylm_aliyun registry]# docker push ylmcr7.com:5000/nginx:v2.4
The push refers to repository [ylmcr7.com:5000/nginx]
Get https://ylmcr7.com:5000/v2/: http: server gave HTTP response to HTTPS client   
#http是不安全的 ,我们要加参数 指定使用http
[root@ylm_aliyun ~]# cat /etc/docker/daemon.json
{
  "insecure-registries": [
    "ylmcr7.com:5000"
  ]
}

#history查找历史记录。!去调用就可以了
 1020  docker push ylmcr7.com:5000/nginx:v2.4
 1021  vim /etc/docker/daemon.json
 1022  systemctl restart docker
 1023  history
[root@ylm_aliyun registry]# !1020

#仓库的树杈树
[root@ylm_aliyun registry]# pwd
/var/lib/registry
[root@ylm_aliyun registry]# tree .
.
└── docker
    └── registry
        └── v2   #协议版本
            ├── blobs    #文件
            │   └── sha256  #sha256格式文件
            │       ├── 14
            │       │   └── 
            └── repositories   #文件
                └── nginx   #仓库
                    ├── _layers  #生成的镜像层次
                    │   └── sha256
                    │       ├── 15677010fe8e4d0cd131c1303d4b976602aff1f0c7aebce74e965258da3e5db2
                    │       │   └── link  #连接到blob中
                    │       ├── 

13.Docker资源限制

  • 容器能够实现,主要依赖于内核中的两个特性,namespaces control groups
  • 默认一个容器在资源中是没有任何资源限制的,几乎能够耗尽docker主机之上内核能分配给docker的所有资源。
  • Docker能控制内存(不可压缩)和cPU(可压缩),当一个容器内的进程耗尽他的内存,申请更多的时候,有可能会,OOM,被kill,
  • 这些资源的限制,依赖于Linux内核的capabilities支持才能工作,,
  • 我们的资源限制从namespace和control groups两个维度来定义

Resource allowances

  • Eight-sided container

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AvY8C8HA-1623723370208)(/assets/iShot2020-10-28-15.32.03.png)]

Memory

  • OOME
    • 在Linux 主机上,如果内核探测到宿主机没有足够的内存可用于执行某些重要的系统功能,就会抛出一个OOME异常,并且去杀死进程去释放某些内存资源
      • 一旦发现OOME,任何进程都有可能被杀死,包括docker daemon在内
      • 为此,Docker特地调整了docker daemon的OOM优先级,以避免它被内核“正法”,但容器的优选级并未被调整
      • 会吃掉内存最多的,会有一个算法计算谁会被干掉
      • 每一个进程我们可以分配一个OOMEDG,每个进程计算出一个OOM-SCORE(得分),得分越高,会被优先干掉,得分计算是根据内存资源申请,空间等一系列复杂计算方法计算出来的,例如docker daemon就算得分最高,也不应该被杀掉,调整优先级,每一个进程都有一个OOM.adj权重,优先级越低,得分越少,daocker daemon 的adj调低,那个进程不重要,就把adj调大点,一旦出现故障,就可以被优先杀死,一些重要的容器,在docker run启动时就定义oom.adj。
内存限制参数

在这里插入图片描述

  • 想要使用–memory-swap * 就必须设置物理内存大小-m参数
  • –memory-swappiness. 的值在0和100之间,0是能不用就不用,100是不得不用时 就用。
  • –oom-kill-disable. 禁止OOM被kill掉。跟-m一起使用
–memory-swap

在这里插入图片描述

CPU

  • 默认情况下,每一个容器可以没有限制的使用宿主机的CPU资源。
  • 你可以设置很多种设置,限制容器去访问主机的CPU
  • 大多数系统再调用时使用的CFS schedule
    • CPU核心数一般是小于进程数量的,一个系统上运行了很多进程,在某一时刻都需要运行,运心的进程数量大于核心数量的时候,调度进程运行在本地CPU核心数之上的,调度器决定谁先去运行,优先级在100-139. nice值是-20,19,实时优先级0-99(内核级),为了调用100-139之间的进程,我们有CFS(完全公平调度器),公平调度每一个资源。
    • 进程可以分为两类,一个是
      • CPU密集型的,对CPU资源占用量很大
      • IO密集型的,对IO资源找用
  • docker1.13版本以后,会有实时优先级调度器
Configure the default CFS scheduler

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GT9dhF4h-1623723370210)(/Users/yingliming/Nutstore Files/我的坚果云/github/clpe/docker/assets/iShot2020-10-28-15.32.27.png)]

  • –cpu-shares 按比例切分可用的CPU资源,需要就按比例分,不需要就分给有需求的,可压缩性资源通过比列来实现。
  • –cpus=限制CPU使用几核。可以使用小数,0.5最小
  • –cpuset-cpus 指定运行在那些cpu上。
  • –cpu-period=限制使用多少时间。
压测
  • 限制内存
[root@ylm_aliyun ~]# docker pull  lorel/docker-stress-ng

[root@ylm_aliyun ~]# docker run --name stress -it --rm lorel/docker-stress-ng:latest  stress --help
Example: stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10s

[root@ylm_aliyun ~]# docker run --name stress -it --rm -m 256m lorel/docker-stress-ng:latest --vm 2

#显示stress使用的资源
[root@ylm_aliyun ~]# docker top stress
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                2688                2653                0                   19:36               pts/0               00:00:00            /usr/bin/stress-ng stress --vm 2
root                2741                2688                0                   19:36               pts/0               00:00:00            /usr/bin/stress-ng stress --vm 2
root                2742                2688                0                   19:36               pts/0               00:00:00            /usr/bin/stress-ng stress --vm 2
root                3375                2742                0                   19:37               pts/0               00:00:00            /usr/bin/stress-ng stress --vm 2
root                3380                2741                0                   19:37               pts/0               00:00:00            /usr/bin/stress-ng stress --vm 2

#显示容器的状态
docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
e352557c07e3        stress              91.23%              243.8MiB / 256MiB   95.25%              0B / 0B             0B / 0B             5

#我们看到资源被限制在256m之下
  • 限制cpu
[root@ylm_aliyun ~]# docker run --name stress -it --rm --cpus 0.5 lorel/docker-stress-ng:latest --cpu 1
#因为我只有1个cpu。可以根据情况增改

#查看占用的资源
[root@ylm_aliyun ~]# docker top stress
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                5878                5855                0                   19:45               pts/0               00:00:00            /usr/bin/stress-ng --cpu 1
root                5932                5878                49                  19:45               pts/0               00:02:03            /usr/bin/stress-ng --cpu 1

#查看容器的状态

[root@ylm_aliyun ~]# docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
           BLOCK I/O           PIDS
8871328408b1        stress              49.88%              3.168MiB / 1.796GiB   0.17%               0B / 0B             0B / 0B             2

14.Docker跨宿主机通信MACVLAN

默认一个物理网卡,只有一个物理mac地址,虚拟多个mac地址

缺点是每次都要指定ip

1.创建macvlan网络

docker network create --driver macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=ens33 macvlan_1

ps:使用macvlan网络,可以虚拟出多个mac地址,相当于多了块网卡,类似于桥接的网络,网段和宿主机的网段一致,这样我们在宿主机上虚拟出一块mac地址,相当于虚拟出一块网卡 他的地址和宿主机一致,这样我们就饿可以实现跨宿主机进行通讯。

2.使用macvlan网络创建容器

[root@k8s-m01 ~]# docker run -it --network macvlan_1 --ip=10.0.0.201 busybox:latest
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0A:00:00:C9
          inet addr:10.0.0.201  Bcast:10.0.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # ping 10.0.0.202
PING 10.0.0.202 (10.0.0.202): 56 data bytes
64 bytes from 10.0.0.202: seq=0 ttl=64 time=0.678 ms
64 bytes from 10.0.0.202: seq=1 ttl=64 time=0.801 ms
^C
--- 10.0.0.202 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.678/0.739/0.801 ms
/ #
[root@k8s-m02 ~]# docker run -it --network macvlan_1 --ip=10.0.0.202 busybox:latest
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0A:00:00:CA
          inet addr:10.0.0.202  Bcast:10.0.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # ping 10.0.0.201
PING 10.0.0.201 (10.0.0.201): 56 data bytes
64 bytes from 10.0.0.201: seq=0 ttl=64 time=0.402 ms
64 bytes from 10.0.0.201: seq=1 ttl=64 time=0.406 ms

15.Docker跨宿主机通信OVERLAY

环境准备

原理是把ip地址存到数据库里面统一管理,统一分配地址,这样就不会出现ip地址冲突的情况。

63上的主机通过docker.sock去管理其他两个容器,所以开启docker.sock .

在这里插入图片描述

  1. 准备工作docker3上安装consul非关系型数据库
[root@c7-43 ~]# docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap

#-h 指定主机名
#consul是一个非关系性数据库

#查看容器
[root@c7-43 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                                            NAMES
fb494f49b917        progrium/consul     "/bin/start -server …"   2 minutes ago       Up 2 minutes        53/tcp, 53/udp, 8300-8302/tcp, 8400/tcp, 8301-8302/udp, 0.0.0.0:8500->8500/tcp   consul

#查看端口号
[root@c7-43 ~]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 :::8500                 :::*                    LISTEN      4506/docker-proxy

访问10.0.0.43:8500

在这里插入图片描述

  1. 在41\42机上开启docker.sock
#1.默认的sock和我们设置的有冲突,我们要先修改 
[root@c7-41 ~]# vim /usr/lib/systemd/system/docker.service
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock

#2.daeom.json写入配置开启sock

[root@c7-41 ~]# cat /etc/docker/daemon.json
{
  "hosts":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"],
  "cluster-store":"consul://10.0.0.43:8500",
  "cluster-advertise":"10.0.0.31:2376"
}

#3.重启docker
[root@c7-41 ~]# systemctl daemon-reload
[root@c7-41 ~]# systemctl restart docker

#4.查看端口

[root@docker01 ~]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 :::2376                 :::*                    LISTEN      4840/dockerd

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gsOTYBua-1623723370212)(assets/image-20201030191737922.png)]

看到这个说明环境已经准备好了

  1. 在41上创建全局网络 42自动生成同id的网络
[root@c7-41 ~]# docker network create -d overlay --subnet 172.16.1.0/24 --gateway 172.16.1.254 ol1
5c05ddafb7b83c5a6720f00694628b39786d3faf0985581b693ba41fe59e9142
[root@c7-41 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
5c05ddafb7b8        ol1                 overlay             global
#网络是global 

#42上自动创建了一个同姓名的全局网络
[root@c7-42 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
5c05ddafb7b8        ol1                 overlay             global

  1. 创建容器进行测试.
[root@c7-41 ~]# docker run -it --network ol1 --name oldboy1 busybox:latest /bin/sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:10:01:01  
          inet addr:172.16.1.1  Bcast:172.16.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

eth1      Link encap:Ethernet  HWaddr 02:42:AC:12:00:02  
          inet addr:172.18.0.2  Bcast:172.18.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:656 (656.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # ping 172.16.1.2
PING 172.16.1.2 (172.16.1.2): 56 data bytes
64 bytes from 172.16.1.2: seq=0 ttl=64 time=0.367 ms
64 bytes from 172.16.1.2: seq=1 ttl=64 time=0.261 ms
64 bytes from 172.16.1.2: seq=2 ttl=64 time=0.233 ms

[root@c7-42 ~]# docker run -it --network ol1 --name oldboy2 busybox:latest /bin/sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:10:01:02  
          inet addr:172.16.1.2  Bcast:172.16.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:574 (574.0 B)  TX bytes:574 (574.0 B)

eth1      Link encap:Ethernet  HWaddr 02:42:AC:12:00:02  
          inet addr:172.18.0.2  Bcast:172.18.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:14 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1356 (1.3 KiB)  TX bytes:400 (400.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:645 (645.0 B)  TX bytes:645 (645.0 B)

/ # ping oldboy1
PING oldboy1 (172.16.1.1): 56 data bytes
64 bytes from 172.16.1.1: seq=0 ttl=64 time=0.366 ms
64 bytes from 172.16.1.1: seq=1 ttl=64 time=0.261 ms
  1. 我们发现容器有两个网卡,他的网
/ # route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.18.0.1      0.0.0.0         UG    0      0        0 eth1
172.16.1.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth1

#上外网是172.18.0.0网段
#容器间通讯时172.16.1.0网段
  1. overlay的网络模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UJSTHy4g-1623723370212)(assets/image-20201030211652533.png)]

eth1通过网关连接到ens33网卡进行上网,eth0负责局域网之间的通讯,容器名字时依次排序的,比如41上起了name1容器,42上不可以使用name1了,所有eth0网卡通过隧道模式进行互通。

16.docker企业级镜像仓库harbor(vmware中国团队)

docker registry弊端

用户权限控制:不合理

界面丑陋 不方便管理

功能简单 ,删除镜像 比较麻烦

hrabor私有仓库

基于registry二次开发

1.安装harbor

下载地址https://github.com/goharbor/harbor/releases/download/v2.1.1/harbor-offline-installer-v2.1.1.tgz

[root@c7-41 ~]# cd /opt/
[root@c7-41 opt]# ls
containerd  harbor  harbor-offline-installer-v1.8.1.tgz
[root@c7-41 opt]# cd harbor/
[root@c7-41 harbor]# ls
harbor.v1.8.1.tar.gz  harbor.yml  install.sh  LICENSE  prepare
[root@c7-41 harbor]# docker load -i harbor.v1.8.1.tar.gz   #导入镜像

2.更改配置文件

[root@c7-41 harbor]# vim harbor.yml 
hostname: 10.0.0.41
harbor_admin_password: 123456

#老版改harbor.cfg

3.install

[root@c7-41 harbor]# ./install.sh 
Now you should be able to visit the admin portal at http://10.0.0.41. 
For more details, please visit https://github.com/goharbor/harbor .

在这里插入图片描述
在这里插入图片描述

4.客户端更改为41的仓库地址

[root@c7-42 ~]# vim /etc/docker/daemon.json 
{
  "hosts":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"],
  "cluster-store":"consul://10.0.0.43:8500",
  "cluster-advertise":"10.0.0.42:2376",
  "insecure-registries":["10.0.0.41"]
}
#设置支持http协议
[root@c7-42 ~]# systemctl daemon-reload 
[root@c7-42 ~]# systemctl restart docker

5.推送镜像

[root@c7-42 ~]# docker login 10.0.0.41
Username: admin
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[root@c7-42 ~]# docker push 10.0.0.41/library/busybox
The push refers to repository [10.0.0.41/library/busybox]
d2421964bad1: Pushed 
v10.30: digest: sha256:c9249fdf56138f0d929e2080ae98ee9cb2946f71498fc1484288e6a935b5e5bc size: 527

在这里插入图片描述

[root@c7-42 ~]# docker pull 10.0.0.41/library/busybox:v10.30
v10.30: Pulling from library/busybox
Digest: sha256:c9249fdf56138f0d929e2080ae98ee9cb2946f71498fc1484288e6a935b5e5bc
Status: Image is up to date for 10.0.0.41/library/busybox:v10.30
10.0.0.41/library/busybox:v10.30

在这里插入图片描述

17.docker-compose

单机编排之docker-Compose

1. docker 多容器管理提倡概念

docker 提倡理念是“一个容器及一个进程”,如果是LAMP的话就会分为apache、mysql,因为php相当
于是apache的一个子模块。也就意味着两个完全不同的进程。所以我们要把它放到两个不同的容器中
运行、这样是最好的而不是把他们两个放在同一个容器内部,也就意味着一个大型服务器可能需要多个
进程组成,也就会需要多个不同的容器组成。

举例:假如我有一个完整的LAMP环境我需要先创建一个mysql的一个容器,再创建一个apache的容
器。因为apache在启动的时候需要用到mysql,所以mysql需要先启动。

  • 启动组件1:mysql
  • 启动组件2:word press的 apache web服务
  • 因为他们启动的时候有对应的启动顺序的关系、先开启的应该是mysql、在开启apache。关
    闭的话应该先关apache,再关闭mysql。

所以这个时候我们就引入了一个服务叫做 docker-compose,这是一个编排工具,用户在我们的模板中
(YAML格式)中定义一组相关的容器,那这个docker-compose会根据我们定义的一层关系会对启动
优先就进行排序。也就意味着我们只需要去遵守他的格式书写对应的方案或叫做数据,他就会根据这些
数据自己去排序和启动以及关闭容器

2. docker-compose工作场景

当在宿主机启动较多的容器时候,如果都是手动操作会觉得比较麻烦而且容器出错,这个时候推荐使
用 docker 单机编排工具 docker-compose,docker-compose 是 docker 容器的一种单机编排服务,
docker-compose 是一个管理多个容器的工具,自动创建,自动映射包括自动挂载数据卷。比如可以解
决容器之间的依赖关系,就像启动一个 nginx 前端服务的时候会调用后端的 tomcat,那就得先启动
tomcat,但是启动 tomcat 容器还需要依赖数据库,那就还得先启动数据库,docker-compose 就可以
解决这样的嵌套依赖关系,其完全可以替代 docker run 对容器进行创建、启动和停止。
docker-compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排,
docker-compose 将所管理的容器分为三层,分别是工程(project),服务(service)以及容器
(container)。

3 docker-compose 工具下载,安装

github 地址 https://github.com/docker/compose/releases

在这里插入图片描述

1.将我们下载的docker-compose上传至服务器上。
2.移动至/usr/local/bin/
3.赋予执行权限
4.查看版本已显示、说明能够正常的工作了

1.常见的命令

-f             #指定使用的yam1文件位置
ps             #显示所有容器信昱
restart        #重新启动容器
1ogs           #查看日志信息
config -q      #验证yaml配置文件是否正确
stop           #停止容器
start          #启动容器、是已经把这个容器项目启动完成了已有在运行的容器了
up -d          #启动容器项目、这个是还没有在运行的容器,需要将镜像转换为容器。
pause          #暂停容器
unpause        #恢复暂停
rm             #珊邺除该项目中的所有容器

2.模板

version: '2'   #版本信息,当前我们使用的是第二个版本

services:     #services定义了一组服务
  db:             #第一个服务(容器)叫DB数据库服务
    image: mysql:5.7           #使用的镜像是mysql5.7
    restart: always             #相当于docker run --name db 命令
    environment:                #下面定义了一些变量
      MYSQL_ROOT_PASSWORD: 123456         #创建root用户登录密码
      MYSQL_DATABASE: wordpress           #创建数据库
      MYSQL_USER: wordpress               #创建用户
      MYSQL_PASSWORD: wordpress           #wordpress用户的密码为wordpress
  wordpress:              #第二个服务(容器)
    depends_on:           #相当于是--link选项          
      - db                #连接的是我们的db数据库容器
    image: wordpress:latest        #使用的是wordpress镜像
    restart: always               #运行wordpress镜像
    ports:                         #端口
      - "8000:80"                  #将容器80端口映射为宿主机的8000端口
    environment:                   #定义了一些变量
      WORDPRESS_DB_HOST: db:3306           #连接数据库服务端口3306
      WORDPRESS_DB_USER: wordpress           #通过wordpress数据库用户
      WORDPRESS_DB_PASSWORD: wordpress         #密码为wordpress
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云原生解决方案

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值