docker介绍

什么是docker

Docker使用Go语言开发,基于Linux内核的cgroupnamespace以及Unionfs等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术,由于隔离的进程独立于宿主和其它的进程,因此也称其为容器

表项 含义
cgroup 为每个进程容器分配不同的系统资源,例如CPU和内存
namespace 是linux内核隔离内核资源的方式
Unionfs 联合文件系统,把不同物理位置的目录合并mount到同一个目录中

https://www.cnblogs.com/architectforest/p/13131307.html【使用namespace做资源隔离】

特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为MB 一般为GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个

docker概念

(1)镜像

Docker镜像是特殊的文件系统,提供容器运行时所需的文件(程序、库、资源、配置等)和配置参数(如匿名卷、环境变量、用户等)

  • 分层存储
    各层通过联合文件系统做统一挂载,使镜像复用、定制更容易
  • 静态
    每层只能读,不能写

(2)容器

容器是镜像运行起来的实例

  • 动态
    有生命周期,创建、启动、暂停、停止、删除
  • 存在可写层
    容器运行后做的修改保存在了可写层

(3)镜像仓库

存储镜像

  • 镜像一次构建,处处使用
  • 分为公有仓库和私有仓库

docker存在的问题

(1)docker容器何如实现容灾
(2)docker容器的连通复杂

k8s —>docker容器容灾 故障切换,负载均衡
pod—>对于容器简单化

Docker安装部署

yum安装

[root@docker ~]# uname -r
4.4.223-1.el7.elrepo.x86_64
[root@docker ~]# yum repolist
!extras/7/x86_64    CentOS-7 - Extras - 163.com     323
[root@docker ~]# yum update
yum install -y yum-utils device-mapper-persistent-data lvm2
#设置yum源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#查看所有仓库中所有docker版本
yum list docker-ce --showduplicates | sort -r
#安装docker
yum install -y docker-ce[-17.12.0.ce]   #最新稳定版,可直接指定安装版本
#启动并加入开机启动
systemctl start docker && systemctl enable docker
[root@docker ~]# docker --version

脚本安装

[root@docker ~]# curl -sSL get.docker.com -o get-docker.sh
[root@docker ~]# sh get-docker.sh  --mirror Aliyun
systemctl start docker
systemctl enable docker
[root@docker ~]# docker version

Docker基本操作

配置镜像加速器

[root@docker ~]# vim /etc/docker/daemon.json
{"registry-mirrors": ["https://sopn42m9.mirror.aliyuncs.com"]
}
[root@docker ~]# systemctl daemon-reload && systemctl restart docker

“Hello world”

(1)获取镜像

[root@docker ~]# docker pull ubuntu:15.10
[root@docker ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              15.10               9b9cb95443b5        3 years ago         137MB

(2)在容器内运行应用程序

[root@docker ~]# docker run ubuntu:15.10 /bin/echo "Hello world"
Hello world
#Docker以ubuntu15.10镜像创建一个新容器,然后在容器里执行bin/echo "Hello world",输出结果(不指定版本号,会默认找最新版本)
#若镜像不存在,会从镜像仓库下载

(3)运行交互式的容器
-i: 以交互模式运行容器
-t: 为容器重新分配一个伪输入终端

[root@docker ~]# docker run ubuntu:15.10 /bin/echo "Hello world"
Hello world
[root@docker ~]# docker run -i -t ubuntu:15.10 /bin/bash
root@25177d9abcfb:/# uname -a
Linux 25177d9abcfb 4.4.223-1.el7.elrepo.x86_64 #1 SMP Sat May 9 08:36:51 EDT 2020 x86_64 x86_64 x86_64 GNU/Linux
root@25177d9abcfb:/# exit  #Ctrl+D
exit

(4)后台启动容器
-d: 后台运行容器,并返回容器ID

[root@docker ~]# docker run -d ubuntu:15.10
e6453eed8242e539c583573bab0409dc72807c1fcdf80c157b91114c26a5d62e    #容器ID
[root@docker ~]# docker ps -all
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
e6453eed8242        ubuntu:15.10        "/bin/bash"         59 seconds ago      Exited (0) 59 seconds ago                       condescending_raman
[root@docker ~]# docker run -d ubuntu:15.10 /bin/sh -c "while true;do echo hello world;sleep 1;done"
cc507d3ef326a228dc7d50a7fb8ffff3ac695569ad81f02aa79f026e27f54cd2
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
cc507d3ef326        ubuntu:15.10        "/bin/sh -c 'while t…"   10 seconds ago      Up 9 seconds                            goofy_shirley

查看容器内的标准输出

docker logs:获取容器的日志
-f:跟踪日志输出
–since=“2021-06-01”:显示某个开始时间的所有日志
-t:显示时间戳
–tail Num:仅列出最新N条容器日志

[root@docker ~]# docker logs goofy_shirley  #容器名称
[root@docker ~]# docker logs cc507d3ef326  #容器ID
docker logs -tf --since="2021-06-01" --tail 6 0314869a37f5

(5)停止容器

[root@docker ~]# docker stop cc507d3ef326
cc507d3ef326
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@docker ~]# docker ps -all
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS               NAMES
cc507d3ef326        ubuntu:15.10        "/bin/sh -c 'while t…"   4 minutes ago       Exited (137) 9 seconds ago                       goofy_shirley
[root@docker ~]# docker start cc507d3ef326
[root@docker ~]# docker stop goofy_shirley
goofy_shirley
[root@docker ~]# docker rm cc507d3ef326    #删除时容器必须是停止的
cc507d3ef326

Docker容器使用

(1)在docker容器中运行一个Python Flask应用来运行一个web应用

[root@docker ~]# docker pull training/webapp
[root@docker ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
training/webapp     latest              6fae60ef3446        5 years ago         349MB
[root@docker ~]# docker run -d -P training/webapp python app.py    #-P 将容器内部使用的网络端口映射到主机的随机端口
1ac039180e5fec2556b220697a4066f530785659743ae2d4448bb39d7bfa9e35
[root@docker ~]# docker ps
CONTAINER ID   IMAGE             COMMAND           CREATED         STATUS         PORTS                                         NAMES
136912052c36   training/webapp   "python app.py"   3 minutes ago   Up 3 minutes   0.0.0.0:49153->5000/tcp, :::49153->5000/tcp   hungry_bardeen
#49153->5000表示主机中使用的端口是41593,容器中的网络端口是5000
[root@docker ~]# curl 192.168.213.131:49153
Hello world![root@docker ~]# docker run -d -p 80:5000 training/webapp python app.py
[root@docker ~]# docker ps
CONTAINER ID   IMAGE             COMMAND           CREATED         STATUS         PORTS                                         NAMES
1db1f9f2e614   training/webapp   "python app.py"   3 seconds ago   Up 2 seconds   0.0.0.0:80->5000/tcp, :::80->5000/tcp         crazy_wescoff
[root@docker ~]# docker logs 1db1f9f2e614* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.213.1 - - [15/May/2020 07:57:05] "GET / HTTP/1.1" 200 -
192.168.213.1 - - [15/May/2020 07:57:05] "GET /favicon.ico HTTP/1.1" 404 -
[root@docker ~]# docker logs -f 1f839cb8906f   #动态打印日志
[root@docker ~]# docker top 1f839cb8906f   #查看容器内部运行的进程
[root@docker ~]# docker inspect 1f839cb8906f   #查看docker的底层信息
[root@docker ~]# docker ps -l  #查看最后一次创建的容器

(2)进入正在运行的Docker容器

[root@docker ~]# docker exec -it 136912052c36 /bin/bash

(3)删除所有停止的docker容器
docker ps -a|awk '$1 != "CONTAINER" {print $1}'|while read line;do docker rm $line;done

Docker镜像使用

当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从docker镜像仓库中下载,默认是从Docker Hub公共镜像源下载
(1)管理和使用本地Docker主机镜像

命令 含义
docker images 列出本地主机上的镜像
docker pull ubuntu:15.10 获取一个新的镜像
docker search nginx 查找镜像

(2)创建镜像

  1. 从已经创建的容器中更新镜像,并且提交这个镜像
[root@docker ~]# docker run -t -i ubuntu:15.10 /bin/bash
root@34596cb30007:/# apt-get update
  1. 使用Dockerfile指令来创建一个新的镜像
[root@docker ~]# cat Dockerfile
FROM    centos:6.7  #指定镜像源
MAINTAINER      Fisher "fisher@sudops.com"RUN     /bin/echo 'root:123456' |chpasswd
RUN     useradd zhao
RUN     /bin/echo 'zhao:123456' |chpasswd
RUN     /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE  22
EXPOSE  80
CMD     /usr/sbin/sshd -D
#每一个指令都会在镜像上创建一个新的层,指令的前缀必须大写
#RUN指令告诉docker在镜像内执行命令,安装了什么
[root@docker ~]# docker build -t zhao/centos6.7 .  #-t 指定要创建的目标镜像名,. Dockerfile文件所在目录
  1. 更新镜像
[root@f4a95aa4fb3d ~]# yum update
[root@docker ~]# docker commit -m="has update" -a="zhao" f4a95aa4fb3d zhao/centos-ansible:v1.0   #容器ID通过docker ps查看
  1. 设置镜像标签
[root@docker ~]# docker tag 9e528daf9660 zhao/centos6.7:v1.1

Docker镜像连接

[root@docker ~]# ip a |grep docker
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group defaultinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
[root@docker ~]# yum install bridge-utils
[root@docker ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.02425763b98b       no
#可以对docker0进行修改,使之成为我们希望的网段
[root@docker ~]# ifconfig dockerO IP netmask NATMASK

docker守护进程就是通过docker0为docker容器提供网络连接的各种服务,docker0实质是Linux的虚拟网桥,可以设置IP地址,相当于拥有一个隐藏的虚拟网卡

[root@docker ~]# docker run -it --name container1 centos:6.7 /bin/bash
[root@docker ~]# docker run -it --link container1:container1 --name container2 ansible/centos7-ansible /bin/bash

docker网络

https://www.jianshu.com/p/22a7032bb7bd

[root@docker ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
1cd999ea03e9   bridge    bridge    local
751b96291cb7   host      host      local
87521c37e4f8   none      null      local

bridge模式

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以veth27f3ec4@if20这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。

[root@docker ~]# ip a s docker0;ip a s veth27f3ec4
[root@docker ~]# docker exec -it 4d6316c37128 /bin/bash
root@4d6316c37128:/opt/webapp# ip a s eth0

使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能,可以使用iptables -t nat -vnL查看

host模式

和宿主机共用一个Network Namespace,容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

[root@docker ~]# docker run -d --net=host training/webapp python app.py

mac系统无法使用host网络模式

none模式

使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

[root@docker ~]# docker run -itd --net=none centos
[root@docker ~]# docker exec -it 26898b692720 /bin/bash
[root@26898b692720 /]# ip a

none模式有网卡模块但没有给其配置IP,使用pipework工具可以给虚拟机容器配置IP(企业常用)
https://blog.csdn.net/qq_34556414/article/details/107922570

应用场景

封闭意味着隔离,适用于对安全性要求高并且不需要联网的应用
例如:某个容器的唯一用途是生成随机密码,就可以放到none网络中避免密码被窃取

container模式

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

[root@docker ~]# docker run -d -p 80:5000 --name a0 training/webapp python app.py
#容器a1共享已存在的容器a0的网络,container模式下运行的容器端口转发不生效
[root@docker ~]# docker run -d -t --network container:a0 --name a1 centos
[root@docker ~]# docker exec a0 ip a
[root@docker ~]# docker exec a1 ip a

应用场景

nginx 镜像自带的网络命令非常少,查看网络不方便,而 busybox 的网络命令比较齐全,使用 container 模式,可以快速解决这个问题
https://www.wenjiangs.com/doc/docker-container

新运行一个名为 n0 的 nginx 容器,再将它的网络共享给 busybox 容器 n0-net:

docker run -d -t --name n0 nginx
docker run -d -t --network container:n0 --name n0-net busybox

使用 n0-net 容器,执行docker exec n0-net ip a进行网络状态查看自身网络信息,也就是 nginx 的网络信息

dockerfile操作

dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本

每条保留字指令都必须为大写字母且后面要跟随至少一个参数指令按照从上到下,顺序执行
#表示注释。
每条指令都会创建一个新的镜像层,并对镜像进行提交

Docker执行Dockerfile的大致流程

  • docker从基础镜像运行一个容器
  • 执行一条指令并对容器作出修改
  • 执行类似docker commit的操作提交一个新的镜像层
  • docker再基于刚提交的镜像运行一个新容器
  • 执行dockerfile中的下一条指令直到所有指令都执行完成

Dockerfile命令语法

https://docs.docker.com/engine/reference/builder/#user
(1)FROM
指定基础镜像,必须是第一条指令

FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>
#三种写法,其中<tag>和<digest>是可选项,如果没有选择,那么默认值为latest
#不以任何镜像为基础:FROM scratch

(2)RUN
运行指定的命令

RUN <command>  #在linux操作系统上默认/bin/sh -C,在windows操作系统上默认cmd /S /C
RUN ["executable","param1","param2"]  #executable可执行文件,两个参数

RUN yum install httpd -y #/bin/bash -c yum install httpd -y
RUN ["/bin/bash","-c","yum install vim -y"]

1.多行命令不要写多个RUN,因为Dockerfile中每一个指令都会建立一层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错
2.RUN书写时的换行符是\

RUN tar && mkdir && cd && prefix && make && make install

(3)CMD
容器启动时要运行的命令

CMD ["executable", "param1"," param2"]
CMD ["param1","param2"]
CMD command param1 param2

注意:包括参数的一定要用双引号, 原因是参数传递后,docker解析的是一个JSON array

RUN & CMD对比
RUN是构件容器时就运行的命令以及提交运行结果;CMD是容器启动时执行的命令,在构件时并不运行,构件时仅仅指定了这个命令到底是个什么样子

(4)LABEL
为镜像指定标签

LABEL <key>=<value> <key>=<value> <key>=<value>
一个Dockerfile种可以有多个LABEL,如下:
LABEL version="test_v1.0" \
description="This is a test v1.0.." \
author="zhao"
#LABEL会继承基础镜像的LABEL,如遇到key相同,则值覆盖

(5)MAINTAINER
指定作者

MAINTAINER <name>

(6)EXPOSE
暴露容器运行时的监听端口给外部
但是EXPOSE并不会使容器访问主机的端口,如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上-P参数

EXPOSE 111
EXPOSE 4096
[root@docker ~]# docker run -it -d fa90e483fb82 /bin/bash
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
6d1cb3992267        fa90e483fb82        "/bin/bash"         7 seconds ago       Up 6 seconds        111/tcp, 4096/tcp   agitated_hamilton

(7)ENV
设置环境变量

ENV <key> <value>    #一次设置一个
ENV <key>=<value>  #一次设置多个

(8)ADD
复制命令,把文件复制到镜像中(类似于scp,但不需密码)

ADD <src>. .. <dest>
ADD ["<src>",... "<dest>"]
ADD http://example.com/foobar /usr/local
ADD *.txt /usr/local

工作路径: 进入到镜像所对应的容器后的当前路径

1.dest路径可以是容器内的绝对路径,也可以是相对于工作目录的相对路径
2.src可以是本地文件,也可以是一个url(类似于wget命令)
3.尽量不要把src写成一个文件夹,否则会复制整个目录的内容,包括文件系统元数据
4.add命令可以自解压
5.add上传目录时只上传其中的文件,不上传目录;可在dest中加上目录名称已达到有目录的效果
6.add添加文件时,按照build上下文查找

build上下文:docker build命令的PATH或URL指定的路径中的文件的集合,如.当前路径,在指向ADD命令时,将当前路径下的文件传递到server
(9)COPY
复制命令

COPY <src>... <dest>
COPY ["<src>",..."<dest>"]

COPY&&ADD对比
(1) ADD的两大特性:拷贝时可自动解压文件;可传递url
(2) copy应用于multistage场景下,只能是本地文件
(3) ADD和copy都能支持go语言风格的正则,都将传递Build上下文,只复制目录下的内容不包含目录本身

Dockerfile中的multi-stage(多阶段构建)

  1. 在容器化技术的软件开发过程中,不得不考虑如何控制容器镜像的大小,若构建的镜像既是编译软件的环境,又是软件最终的运行环境,那是很难控制大小的
  2. 一般思路是分别为软件的编译环境和运行环境提供不同的容器镜像,这种情况被称为构建者模式

(10) ENTRYPOINT
启动时的默认命令

ENTRYPOINT ["executable","param1","param2"]    #可执行文件加参数
ENTRYPOINT command param1 param2    #shell命令

(11)VOLUME
可实现挂载功能,可以将本地文件夹或者其他容器中得文件夹挂在到这个容器

VOLUME ["/data"]
#["/data"]可以是一个JsonArray,也可以是多个值
VOLUME ["/var/log/"]
VOLUME /var/log
VOLUME /var/log /var/db

一般的使用场景为需要持久化存储数据时,容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失,所以当数据需要持久化时用这个命令

(12)USER
设置启动容器的用户,可以是用户名或UID

USER daemon
USER UID

注意:如果设置了容器以daemon用户去运行,那么RUN,CMD 和ENTRYPOINT 都会以这个用户去运行

(13)WORKDIR
设置工作目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效,如果不存在则会创建,也可以设置多次

WORKDIR /path/to/workdir

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
#pwd执行的结果是/a/b/c

WORKDIR也可以解析环境变量

ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
#pwd的执行结果是/path/$DIRNAME

(14)ARG
设置变量

ARG <name> [=<default value>]

ARG命令定义了一个变量,在docker build创建镜像的时候,使用--build-arg<varname>=<value>来指定参数

如果用户在build镜像时指定了一个参数没有定义在Dockerfile中,那么将有一个警告[Warning] one or more build-args [foo] were not consumed.

我们可以定义一个或多个参数,如下:
FROM busybox
ARG user1
ARG buildno也可以给参数一个默认值:
FROM busybox
ARG user1=someuser
ARG buildno=1

如果给了ARG定义的参数默认值,那么当build镜像时没有指定参数值,将会使用这个默认值

例1

ARG name=vim
RUN ["/bin/bash","-c","yum install $name -y"]
[root@docker ~]# docker build -t zhao/centos_test:v6.0 --build-arg name=net-tools .
Step 7/7 : RUN ["/bin/bash","-c","yum install $name -y"]


例2

ARG path=/usr/local
WORKDIR $path
[root@docker ~]# docker build -t zhao/centos_test:v7.0 --build-arg path=/var .
[root@docker ~]# docker run -it zhao/centos_test:v7.0 /bin/bash
[root@569886c09a13 var]# pwd
/var

(15)ONBUILD
这个命令只对当前镜像的子镜像生效

ONBUILD [INSTRUCTION]

ONBUILD RUN yum install net-tools -y
[root@docker ~]# docker build -t zhao/centos_test:v8.0 .
[root@docker ~]# cat Dockerfile
FROM zhao/centos_test:v8.0
[root@docker ~]# docker build -t zhao/centos_test:v8.1 .


(16)STOPSIGNAL
当容器退出时给系统发送什么样的指令

STOPSIGNAL signal

(17)HEALTHCHECK
容器健康状况检查命令

HEALTHCHECK [OPTIONS] CMD command    #在容器内部运行一个命令来检查容器的健康状况
HEALTHCHECK NONE    #在基础镜像中取消健康检查命令[OPTIONS]选项:
--interval=DURATION #两次检查默认的时间间隔为30秒
--timeout=DURATION #健康检查命令运行超时时长,默认30秒
--retries=N #当连续失败指定次数后,则容器被认为是不健康的,状态为unhealthy,默认次数是3

HEALTHCHECK命令只能出现一次,如果出现了多次,只有最后一个生效
CMD后边的命令的返回值决定了本次健康检查是否成功,具体的返回值如下:
0 success-表示容器是健康的
1 unhealthy-表示容器已经不能工作了
2 reserved-保留值

dockerfile总结

https://docs.docker.com/develop/develop-images/multistage-build/

dockerfile实例解析

构建镜像三步骤

  • 编写dockerfile文件
  • docker build
  • docker run

自定义mycentos

(1)编写dockerfile文件

from centos
env mypath /usr/local
workdir $mypath
run yum -y install vim
run yum -y install net-tools
expose 80
cmd echo "=======SUCCeSS---"
cmd /bin/bash

(2)构建镜像

docker build -t新镜像名字:TAG

(3)列出镜像变更历史

docker history 镜像名

自定义tomcat

FROM centos
MAINTAINER zhao
#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
#把java与tomcat添加到容器中
ADD jdk-8u842-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.53.tar.gz /usr/local/
#安装vim编辑器
RUN yum -y install vim
#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_242
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.53
ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.53
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
/#启动时运行tomcat
# ENTRYPOINT ["/usr/1ocal/apache-tomcat-9.0.8/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh", "run"]
CMD /usr/local/apache-tomcat-8.5.53/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.53/bin/logs/catalina.out

build一个新镜像

[root@docker ~]# docker build -t zhao/centos_test:v11.0 .

运行

[root@docker ~]# mkdir -p /zyuse/mydockerfile/tomcat8/test
[root@docker ~]# mkdir -p /zyuse/mydockerfile/tomcat8/tomcat8logs
[root@docker ~]# docker run -d -p 9080:8080 --name mytomcat -v /zyuse/mydockerfile/tomcat8/test:/usr/local/apache-tomcat-8.5.53/webapps/test -v /zyuse/mydockerfile/tomcat8/tomcat8logs:/usr/local/apache-tomcat-8.5.53/logs --privileged=true zhao/centos_test:v11.0
84304bea9769e87b0bd638f7356ce624bfafc4af3eb746e63544c8aae74738e2
[root@docker ~]# docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                    NAMES
84304bea9769        zhao/centos_test:v11.0   "/bin/sh -c '/usr/lo…"   17 seconds ago      Up 16 seconds       0.0.0.0:9080->8080/tcp   mytomcat

自定义nginx

#wget http://mirrors.sohu.com/nginx/nginx-1.17.9.tar.gz
[root@k8s-node1 docker]# cat Dockerfile
###
FROM centos
RUN yum -y install gcc make pcre-devel zlib-devel tar zlib
ADD nginx-1.17.9.tar.gz /usr/src/
RUN cd /usr/src/nginx-1.17.9 \&& mkdir /usr/local/nginx \&& ./configure --prefix=/usr/local/nginx \&& make \&& make install \&& ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ \&& nginx
RUN echo "This is a test from myapp:v1.0" > /usr/local/nginx/html/index.html
RUN rm -rf /usr/src/nginx-1.17.9
EXPOSE 80WORKDIR /
CMD nginx && tail -F /var/log/nginx/access.log
[root@k8s-node1 docker]# docker build -t reg.zhao.com/zhao/myapp:v1.0 .
[root@k8s-node1 docker]# docker run -dit -p 9999:80 --name myapp1.0 reg.zhao.com/zhao/myapp:v1.0

[root@k8s-node1 ~]# docker push reg.zhao.com/zhao/myapp:v1.0

Docker生产环境部署和实践

Docker安装Nginx

[root@docker ~]# docker pull nginx
[root@docker ~]# docker run --name nginx -p 8081:80 -d nginx

Nginx部署

#创建目录nginx
[root@docker ~]# mkdir -p ~/nginx/{www,logs,conf}
#拷贝容器内Nginx默认配置文件到本地当前目录下的conf目录
[root@docker ~]# docker cp b2c013828445:/etc/nginx/nginx.conf ~/nginx/conf/
#编辑网页
[root@docker ~]# cat ~/nginx/www/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>恨君不似江楼月</title>
</head>
<body><h1>只有相随</h1><p>无别离。</p>
</body>
</html>
#映射挂载
[root@docker ~]# docker run -d -p 8082:80 --name nginx-test-web -v ~/nginx/www/:/usr/share/nginx/html -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v ~/nginx/log:/var/log/nginx 602e111c06b6  #镜像ID

Docker安装PHP

#拉取官方镜像
[root@docker ~]# docker pull php:5.6-fpm
#启动php
[root@docker ~]# docker run --name myphp-fpm -v ~/nginx/www:/www -d php:5.6-fpm
#修改配置
[root@docker ~]# mkdir nginx/conf/conf.d
[root@docker ~]# vim nginx/conf/conf.d/test-php.conf
server {listen          80;server_name     localhost;location / {root    /usr/share/nginx/html;index index.html index.htm index.php;}error_page  500 502 503 504 /50x.html;location = /50x.html {root /usr/share/nginx/html;}location ~ \.php$ {fastcgi_pass    php:9000;fastcgi_index   index.php;fastcgi_param   SCRIPT_FILENAME /www/$fastcgi_script_name;include         fastcgi_params;}
}
#启动服务
[root@docker ~]# docker run --name runoob-php-nginx -p 8083:80 -d -v ~/nginx/www:/usr/share/nginx/html:ro -v ~/nginx/conf/conf.d:/etc/nginx/conf.d:ro --link myphp-fpm:php nginx
#-p 8083:80 端口映射,把nginx中的80映射到本地的8083端口
#~/nginx/www是本地html文件的存储目录,/usr/share/nginx/html是容器内html文件的存储目录
#~/nginx/conf/conf.d是本地nginx配置文件的存储目录,/etc/nginx/conf.d是容器内nginx配置文件的存储目录
#--link myphp-fpm:php 把myphp-fpm的网络并入nginx,并通过修改nginx的/etc/hosts,把域名php映射成127.0.0.1,让nginx通过php:9000访问php-fpm #编辑测试页面
[root@docker ~]# vim nginx/www/index.php
<?phpecho phpinfo();
?>

自建私有仓库

本地镜像服务器

仓库配置

[root@dockerhub ~]# docker pull registry
[root@dockerhub ~]# docker run -d -v /registry:/var/lib/registry -p 5000:5000 --restart=always --privileged=true --name registry registry:latest
#--restart=always docker服务重启时容器会随之启动
#--privileged=true 扩展权限
#目录映射的目的是防止docker私有仓库这个容器被删除时,仓库里的镜像也会被删除

配置支持http方式推送镜像

docker私有仓库服务器默认是基于https传输,需要在客户端做相关设置,不使用https传输
每一个要使用http方式访问私有镜像仓库的机器上的docker都要配置insecure-registries

[root@docker ~]# vim /etc/docker/daemon.json
{"registry-mirrors": ["https://sopn42m9.mirror.aliyuncs.com"],"insecure-registries":["192.168.213.129:5000"]
}
[root@docker ~]# systemctl restart docker

上传镜像到镜像仓库

#给hello-world镜像打个tag,表示新的版本
[root@docker ~]# docker tag hello-world 192.168.213.129:5000/hello-world:latest
#将新的hello-world镜像上传到私有仓库
[root@docker ~]# docker push 192.168.213.129:5000/hello-world:latest
The push refers to repository [192.168.213.129:5000/hello-world]
9c27e219663c: Pushed
[root@docker ~]# docker pull 192.168.213.129:5000/hello-world

在私有仓库192.168.42.141查看上传的镜像

[root@dockerhub ~]# ls /registry/docker/registry/v2/repositories/
hello-world

harbor GUI

(1)给每个docker节点安装一个ce认证信赖

[root@dockerhub ~]# vim /etc/docker/daemon.json
{"exec-opts": ["native.cgroupdriver=systemd"],"log-driver": "json-file","log-opts": {"max-size": "100m"},"insecure-registries": ["https://hub.zhao.com"]
}
[root@dockerhub ~]# yum install lrzsz

(2)导入包docker-compose

[root@dockerhub ~]# chmod a+x /usr/local/bin/docker-compose
#http://harbor.orientsoft.cn/
[root@dockerhub ~]# tar xf harbor-offline-installer-v1.2.0.tgz
[root@dockerhub ~]# mv harbor /usr/local/
[root@dockerhub ~]# cd /usr/local/harbor/
[root@dockerhub harbor]# vim harbor.cfg
hostname = hub.zhao.com
ui_url_protocol = https

(3)创建HTTPS证书

[root@docker ~]# mkdir -p /data/cert
[root@dockerhub cert]# openssl genrsa -des3 -out server.key 2048   #创建私钥
[root@dockerhub cert]# #发起请求
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HB
Locality Name (eg, city) [Default City]:SJZ
Organization Name (eg, company) [Default Company Ltd]:xingyun
Organizational Unit Name (eg, section) []:xingyun
Common Name (eg, your name or your server's hostname) []:hub.zhao.com
Email Address []:zhao@163.comPlease enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@dockerhub cert]# cp server.key server.key.org    #备份私钥
[root@dockerhub cert]# openssl rsa -in server.key.org -out server.key  #转化证书
Enter pass phrase for server.key.org:
writing RSA key
[root@dockerhub cert]# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt  #签名
Signature ok
[root@dockerhub ~]# chmod -R 777 /data/cert

(4)执行安装

[root@dockerhub ~]# cd /usr/local/harbor
[root@dockerhub harbor]# ./install.sh

(5)在hosts中配置域名解析
(6)查看镜像
(7)登录Web界面访问 https://192.168.213.129/harbor
账号admin,密码在配置文件中,默认Harbor12345
(8)docker测试

登录仓库

[root@master01 ~]# docker login https://reg.zhao.com

推送镜像

[root@docker ~]# docker tag hello-world hub.zhao.com/library/nginx:v1.0
[root@docker ~]# docker push hub.zhao.com/library/nginx:v1.0
The push refers to repository [hub.zhao.com/library/nginx]
9c27e219663c: Pushed
v1.0: digest: sha256:90659bf80b44ce6be8234e6ff90a1ac34acbeb826903b02cfa0da11c82cbc04                                                                      2 size: 525

拉取镜像

[root@k8s-node2 ~]# docker pull reg.zhao.com/zhao/myapp:v2.0
[root@k8s-node2 ~]# docker run -dit -p 10000:80 --name myapp2.0 reg.zhao.com/zhao/myapp:v2.0

harbor故障处理

[root@docker ~]# docker stop $(docker ps -a -q)
[root@docker ~]# docker rm $(docker ps -aq)
[root@docker ~]# cd /usr/local/harbor
[root@docker harbor]# ./install.sh

docker总结

  1. docker build的执行过程是什么?
  • Docker采用C/S架构,客户端向服务器发送请求,服务器负责构建、运行和分发容器
  • build上下文
    docker build 命令的 PATH 或 URL 指定的路径中的文件的集合
    解决docker客户端和docker daemon不在同一台机器上的情况

docker client将docker build指令发送到docker server的daemon程序,并同时拷贝build context到docker server产生JOB,由daemon解析Dockerfile,完成JOB,构建容器

  1. 什么是多阶段构建,此构建方法解决了什么问题?

对于多阶段构建,可以在Dockerfile中使用多个FROM语句,每个FROM指令可以使用不同的基础,并且每个指令都开始一个新的构建。您可以选择性地将工件从一个阶段复制到另一个阶段,从而在最终image中只留下您想要的内容。
https://docs.docker.com/develop/develop-images/multistage-build/

Docker多阶段构建旨在解决编译和构建复杂的问题,减小镜像大小
下一步的运行可使用上一步的结果

在多阶段构建中,每次 FROM 都会开启一个新的 Stage(阶段),可以看作一个新的 Image(不够准确、来源请求),与其它阶段隔离(甚至包括环境变量)。只有最后的 FROM才会被纳入 Image 中。
https://www.codercto.com/a/44975.html

docker容器企业级实战——docker部署与操作实践相关推荐

  1. Docker容器虚拟化技术---Docker高级实战(DockerFile)2

    Docker容器虚拟化技术-Docker高级实战(DockerFile) DockerFile是一个文本格式的配置文件,用户可以使用DockerFile来快速创建自定义的镜像. 1. DockerFi ...

  2. docker 容器 exited_Docker实战006:docker容器使用详解

    Docker容器也是docker的核心成员,是docker镜像的一个运行实例.一个镜像可以创建多个容器,多个容器也可以在同一台机器上运行并与其他容器共享操作系统内核同时将应用程序与系统其它周围环境隔离 ...

  3. docker容器互联实战

    2019独角兽企业重金招聘Python工程师标准>>> docker容器互联实战 转载于:https://my.oschina.net/xiejunbo/blog/811768

  4. 【云原生】第十二篇--docker容器镜像仓库Harbor部署

    docker容器镜像仓库Harbor部署 一.容器镜像加速器 1.1 获取阿里云容器镜像加速地址 1.2 配置docker daemon使用加速器 二.容器镜像仓库 2.1 docker hub 2. ...

  5. 如何在Docker容器中运行Docker [3种方法]

    在本博客中,我将向您介绍在docker中运行docker所需的三种不同方法. Docker In Docker的用处 dockerIndocker的一个潜在用处是CI管道,在代码成功构建后,您需要在其 ...

  6. Docker容器虚拟化技术---Docker运维管理(Docker Compose)4

    Docker容器虚拟化技术-Docker运维管理(Docker Compose)4 Docker Compose 通过前面的讲解我们知道使用一个Dockerfile模板文件,可以很方便地定义一个单独的 ...

  7. 【转载】从Docker容器漏洞谈Docker安全

    近日,一篇在Docker博客上发表的文章显示,Docker的容器已经被突破,并且能够遍历宿主机的文件了.由于Docker的轻量,快速等等优点,让Docker在PaaS[注]领域愈发火热,自然也就吸引了 ...

  8. Docker容器虚拟化技术---Docker运维管理(Swarm集群管理)3

    Docker容器虚拟化技术-Docker运维管理(Swarm集群管理)3 Swarm集群管理 docker swarm是docker官方提供的一套容器编排系统,是Docker公司推出的官方容器集群平台 ...

  9. 如何从Docker容器内部获取Docker主机的IP地址

    本文翻译自:How to get the IP address of the docker host from inside a docker container As the title says. ...

最新文章

  1. 如何在多Node版本的情况下公用一个npm
  2. 自习室网上预约系统设计_港澳居民“回乡证”出新规啦!新系统网上预约更方便!...
  3. 《转》 ImportError: No module named caffe 的解决方案
  4. 机器学习笔记:FLOPs
  5. linux c嵌入汇编语言,Linux 下的C和Intel 汇编语言混用
  6. Oracle统计信息的导出、导入
  7. redis 分布式锁 看门狗_分布式锁Redisson的使用,看门狗机制
  8. 蓝桥杯2020年第十一届C++省赛第六题-成绩统计
  9. RDMA的原理、传输与Verbs
  10. 微信公众号定位显示EC-01G模组+STM32F103
  11. LeetCode-Python-1386. 安排电影院座位(数组)
  12. 计算机显卡型号中数字含义详解,显卡型号中字母和数字所代表的含义
  13. 求有10个整型元素的数组中最大元素及其下标。
  14. 教程篇(7.0) 05. FortiGate基础架构 IPsec安全隧道 ❀ Fortinet 网络安全专家 NSE 4
  15. 流程控制之if...elif...else和流程控制之while循环
  16. 加密解密技术基础及用OpenSSL创建私有CA
  17. python3 zlib 实现压缩与解压字符串与文件数据流
  18. 大学计算机word图文混排,WORD图文混排教学设计
  19. css 一行超出显示省略号 多行超出显示省略号
  20. StartDT Hackathon | 技术小白独立部署DataSimba,需要多久?

热门文章

  1. Hbuilder真机运行显示空白的问题
  2. C#日期时间的格式化输出
  3. 禹司凤扛鸿蒙炉,《琉璃美人煞》还有第二季?副宫主没死,无支祁和紫狐未能圆满...
  4. CNKI E-Study系统崩溃问题:
  5. 关于SGM8903YTS14G/TR
  6. 使用forEach添加序号
  7. EXCEL移动单元格时,出现信息检索怎么办
  8. 详述机器人的5种定位技术
  9. python npv 计算公式_8种相似度度量方式的原理及实现
  10. 今日头条适配方案使用