Docker笔记

相关资料:

  1. Docker入门教程 http://dockone.io/article/111

  2. Docker_百度百科 http://baike.baidu.com/view/11854949.htm

  3. 史上最全Docker资料集粹 http://special.csdncms.csdn.net/BeDocker/

  4. Docker - 话题精华 - 知乎 http://www.zhihu.com/topic/19950993/top-answers

  5. docker 简明教程 | 简果网 http://www.simapple.com/docker-tutorial

  6. 如何使用Dockerfile构建镜像 http://blog.csdn.net/qinyushuang/article/details/43342553

  7. Dockerfile reference - Docker https://docs.docker.com/engine/reference/builder/

  8. dockers教程:https://yeasy.gitbooks.io/docker_practice/content/install/centos.html?q=

 

docker概述

docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可以移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器时完全使用沙盒机制,相互之间不会有任何接口。几乎没有性能开销,省略掉了开机流程,可以很容易地在机器和数据中新运行

Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。

docker与虚拟机的差异:

  docker 虚拟机
相同点 1.都可在不同的主机之间迁移 2.都具备root权限 3.都可以远程控制 4. 都有备份、回滚操作  
操作系统 在性能上有优势,可以轻易的运行多个操作系统 可以安装任何系统,但是性能不及容器
原理 和宿主机共享内核,所以容器运行在容器引擎之上,容器并非一个完整的操作系统,所有容器共享操作系统,在进程级进行隔离 每一个虚拟机都建立在虚拟的硬件之上,提供指令级的虚拟,具备一个完整的操作系统
优点 高效、集中。一个硬件节点可以运行数以百计的容器,非常节省资源,Qos会尽量满足,但不保证一定满足。内核有提供者升级,服务由服务提供者管理 对操作系统具有绝对权限,对系统版本和系统升级具有完全的管理权限。具有一整套的资源:cpu、RAM和磁盘。Qos是有保证的,每一个虚拟机就像一个真实的物理机一样,可以实现不同的操作系统运行在同一个物理节点上
资源管理 弹性资源分配:资源可以在没有关闭容器的情况下添加,数据卷也无需重新分配大小 虚拟机需要重启,虚拟机里边的操作系统需要处理新加入的资源,如磁盘等,都需要重新分区。
远程管理 根据操作系统的不同,可以通过 shell 或者远程桌面进行 远程控制由虚拟化平台提供,可以在虚拟机启动之前连接
缺点 对内核没有控制权限,只有容器的提供者具备升级权限。只有一个内核运行在物理节点上,几乎不能实现不同的操作系统混合。容器提供者一般仅提供少数的几个操作系统 每一台虚拟机都具有更大的负载,耗费更多的资源,用户需要全权维护和管理。一台物理机上能够运行的虚拟机非常有限
配置 快速,基本上是一键配置 配置时间长
启动时间 秒级 分钟级
硬盘使用 MB GB
性能 接近原生态 弱于原生态
系统支持数量 单机支持上千个 一般不多于几十个

 docker与基础架构的区别:

Docker系统架构

Docker使用客户端-服务端(C/S)架构模式,使用远程API来管理和创建Docker容器。

Docker容器通过Docker镜像来创建。

容器与镜像的关系类似于面向对象编程中的对象与类。

标题 说明
镜像(images) Docker 镜像是用于创建Docker 容器的模板
容器(Container) 容器是独立运行的一个或一组应用
客户端(Client) Docker客户端通过命令行或者其他工具使用Docker API 与 Docker 的守护进程通信。
主机(Host) 一个物理或者虚拟的机器用于执行Docker 守护进程和容器
仓库(Registry) Docker 仓库是用来保存镜像,可以理解为代码控制中的代码仓库。DockerHub提供了庞大的镜像集合供使用
DockerMachine Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、Digital Ocean、Microsoft Azure。

Docker-ce的安装

环境规划:

主机名 内存 ip
docker01 2G 10.0.0.11
docker02 2G 10.0.0.12

修改ip地址、主机和hosts解析:

10.0.0.11  docker01
10.0.0.12  docker02

ip转发功能开启:

注:这个很重要,如果不开启docker主机无法联网

vim /etc/sysctl.conf
net.ipv4.ip_forward=1

#重启network服务
systemctl restart network

#查看是否修改成功
sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

安装docker

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

systemctl enable docker
systemctl start docker

#验证
[root@docker01 yum.repos.d]# docker version 
Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea
 Built:             Wed Nov 13 07:25:41 2019
 OS/Arch:           linux/amd64
 Experimental:      false

离线下载

rpm包下载地址:https://pan.baidu.com/s/1V0tb9opVXpjEeJvQ98Jo_Q

tar xf docker_rpm.tar.gz
yum localinstall docker_rpm/*.rpm -y
#验证
docker version 
.....此处省略

 

Docker主要内容

docker是一个cs架构, docker主要:镜像 容器 仓库 网络 存储 监控

docker是一个软件的打包技术.

# run等于创建容器和启动容器
docker  run -d  -p 80:80  nginx:latest 
run 创建并启动一个容器
-d  放后台启动
-p  端口映射
nginx:latest docker镜像名称

 

docker镜像常用命令

1. docker search 搜索镜像, 优先选官方,stars数量多

# 在官方仓库搜索nginx镜像
docker search nginx 

2. docker pull 拉取镜像(下载镜像)

注:拉去官方镜像需要访问国外仓库很可能显示timeout,拉去失败

# 拉去官方镜像
docker  image pull  itsthenetework/nfs-server-alpine 

3. docker push 推送镜像(上传镜像)

# 上传本地镜像alpine:v1到镜像仓库
docker push  10.0.0.11/library/alpine:latest

4. docker load 导入镜像

# 导入nginx镜像(推荐使用)
docker load  -i  docker_nginx.tar.gz
# 导入镜像没有镜像名称和版本 会多一个无名镜像
docker image import  docker_alpine.tar.gz  

5. docker save 导出镜像

# 将centos:7 的镜像打包成docker_centos7.tar.gz压缩包 导出镜像就不显示
docker save centos:7 -o docker_centos7.tar.gz

6. docker images 查看镜像列表

# 查看镜像列表
docker images (别名)  或者 docker image ls 

7. docker rmi 删除镜像

#删除 alpine镜像
docker rmi alpine:latest

8. docker tag 给镜像打标签

# 给无名镜像贴标签
 docker  image tag   <容器ID>  alpine:latest

 

Docker容器常用命令

1. docker run 创建并启动容器

# 后台运行
docker run  -d -it -p 80:80  nginx:latest
run 创建并启动一个容器
-d  放后台启动
-p  端口映射
nginx:latest docker镜像名称

run参数

-i: 直接运行容器,通常与 -t 同时使用;

#使用命令/bin/bash直接前台进入centos:7 版本虚拟机
docker run -it -p 80:80 centos:7  /bin/bash 

-P:随机端口映射,Docker会随机映射一个49000~49900的端口发哦内部容器开放的网络端口

# 将容器暴露的所有端口,都随机映射到宿主机上 (不推荐)
docker run -P -it alpine /bin/sh 
# 将容器指定端口随机映射到宿主机一个端口上
docker run  -d -p :80  alpine_kod:v3

-p: 容器指定端口随机映射到宿主机指定端口

注:命令只能指定一次,否侧会显示指定端口冲突

# 指定容器80端口映射到宿主机80端口在后台运行
docker run -d -p 80:80 nginx:latest
# 指定端口在前台运行
docker run -it -p 80:80 centos:6.9

2. docker create 创建容器 --name

注:建议直接使用 run 直接创建和开启容器

#创建一个以alpine为镜像名字为nginx的容器 docker  create  <iso镜像版本>  <容器名>
docker create  --name nginx nginx:latest 
4ce0b66cb8492c7f8571a26d6bb14ae7ee593b01fd4c06e61b5a4c374af176f4

3. docker start 启动容器

# 启动未开启的容器 格式:docker <容器ID>   
 docker start <容器ID>

4. docker stop 停止容器

# 将创建的容器给停止 格式:docker stop  <容器ID>或者<容器名>
docker stop nginx
docker stop 4ce0b66cb849 

5. docker restart 重启容器

# 将创建的容器重启 格式:docker restart  <容器ID>或<name>
docker restart nginx
docker restart 4ce0b66cb849 

6. docker kill 强制停止容器

# 强制关闭nginx 格式:docker kill <容器ID>或<name>
docker kill 4ce0b66cb849
docker kill nginx

7. docker ps 查看容器列表

  • -a 查看所有容器

  • -f 根据条件显示的内容

  • --format 指定返回值的模板文件

  • -l 显示最近创建的容器

  • -n 列出最近创建的n个容器

  • --no-trune 不截断输出

  • -q 静默模式,只显示容器编号

  • -s 显示总的文件大小

#列出所有容器
docker ps -a 

#列出最近创建的5个容器信息
docker ps -n 5

#列出所有创建的容器ID
docker ps -a -q

#列出最后一个容器
docker ps -l

输出详情介绍:

  • CONTAINER ID: 容器 ID。
  • IMAGE: 使用的镜像。
  • COMMAND: 启动容器时运行的命令。
  • CREATED: 容器的创建时间。
  • STATUS: 容器状态。

状态有7种:

  • created(已创建)
  • restarting(重启中)
  • running(运行中)
  • removing(迁移中)
  • paused(暂停)
  • exited(停止)
  • dead(死亡)

PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。

NAMES: 自动分配的容器名称。

 

8. docker rm 删除所有容器

#删除单个容器
docker rm  <容器ID>或<容器名字>
#删除所有已经停止的容器
docker rm $(docker ps -a -q)

  -f 通过 SIGKILL 信号强制删除一个运行的容器

#强制删除所有容器 
docker rm -f `docker ps -a -q`

  -v 删除与容器关联的卷

#删除容器nginx01,并删除容器挂载的数据卷
docker rm -v nginx01

  -l 移除容器间的网络连接,而非容器本身

#移除容器nginx01对容器db01的连接,连接名db:
docker rm -l db

9. docker exec 进入正在运行的容器(分配一个新终端)

#分配一个交互式的终端
docker exec -it  <容器ID>或<容器名字>  /bin/bash(/bin/sh)

10. docker attach 进入正在运行的容器(使用相同的终端)

注:偷偷离开的快捷键ctrl+p,ctrl +q

#进入相同的终端
docker attach <容器ID>

容器想要放后台一直运行的话,那么容器的初始命令,必须夯住(前台运行),否则容器就会退出。

#前台运行
nginx -g 'daemon off;'
/usr/sbin/php-fpm --nodaemonize

 

Docker端口映射

docker run
-p  宿主机端口:容器端口
-p  宿主机ip1:宿主机端口:容器端口 (多个容器同时使用80端口)
-p  宿主机ip1::容器端口   随机端口映射
-p  宿主机ip1::容器端口/udp   使用udp协议做随机端口映射
-p 80:80  -p 3306:3306
-p 1111-1119:1111-1119  端口范围映射

-P 自动随机端口映射  

宿主机80端口映射到容器80端口

注:命令只能执行一次,因为端口唯一

docker run -d -p 80:80 nginx:latest

多个ip地址映射到容器指定端口

#添加网卡
ifconfig eth0:1 10.0.0.10/24 up
#指定网卡端口映射到容器端口
docker run -d -p 10.0.0.10:80:80 nginx:latest

多个ip地址端口随机映射到容器指定80端口

docker run -d -p 10.0.0.10::80 nginx:latest
#查看端口映射
docker ps -a 

#指定udp协议--默认tcp协议
docker run -d -p 10.0.0.10::80/udp nginx:latest

多个端口进行映射

注:比如一个容器运行了多个服务,就需要指定映射多个端口

#指定映射宿主机与容器的80,3306端口
docker run -d -p 80:80 -p 3306:3306 nginx:latest

指定端口范围进行映射

注:范围可以不一样,但是数量要一致

#指定宿主机的90到99端口映射到容器100到109端口
docker run -d -p  90-99:100:109 nginx:latest

-P 随机指定端口

#随机映射端口
docker run -d -P  nginx:latest

docker ps -a 查看21    1

 

Docker数据卷

数据卷的创建:

官方的解释是:数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS.

UFS即UNIX文件系统的简称

  1. 数据卷可以在容器之间共享和重用

  2. 对数据卷的修改会立马生效

  3. 对数据卷的更新,不会影响镜像

  4. 数据卷默认会一直存在,即使容器被删除

  5. 数据卷的使用,类似于Linux下对目录或文件进行mount,镜像中的被指定为挂载点的目录中的文件会被隐藏掉,能显示看的是挂载的数据卷

docker run 
-v 宿主机绝对目录:容器目录
-v 容器目录    #创建一个随机卷,来持久化容器的目录下的数据
-v 卷名:容器目录   #创建一个固定名字的卷,来持久化容器的目录下的数据
--volumes-from 跟某一个容器挂载所有的卷

1. 实现网页小鸟飞飞

小鸟飞飞 nginx镜像 --Debian系统

#宿主机操作 创建目录并进入
mkdir /opt/xiaoniaofeifei
cd /opt/xiaoniaofeifei
unzip xiaoniaofeifei.zip 

#容器目录挂载容器目录
docker run -d -p 80:80 -v /opt/xiaoniaofeifei:/usr/share/nginx/html nginx:latest  

注:如果挂载的数据卷不存在,Docker会自动创建该目录 ·

网站登录到宿主机的80端口:10.0.0.12:80

 

 

 小练习:只启动一个nginx容器,要求访问80端口,出现nginx默认欢迎首页,访问81端口,出现小飞飞。

方式一:在容器里面创建配置文件

mkdir /opt/xiaoniao
cd /opt/xiaoniaofeifei  --解压html文件

docker run -d -p 80-81:80-81 -v /opt/xiaoniao:/opt nginx:latest

#进入容器进行创建
echo 'server {
        listen       81;
        server_name  localhost;
        location / {
            root   /opt;
            index  index.html index.htm;
        }
    }' >/etc/nginx/conf.d/xiaoniao.conf
    
#重启容器
docker restart  容器ID/容器名

方式二:在宿主机里创建配置文件在复制到容器

#配置文件
echo 'server {
        listen       81;
        server_name  localhost;
        location / {
            root   /opt;
            index  index.html index.htm;
        }
    }' >xiaoniao.conf


docker run -d  -p 84-85:80-81  -v /opt/xiaoniao:/opt nginx:latest
#将配置文件复制到容器内
docker container  cp   xiaoniao.conf  34e0fbe5d88e:/etc/nginx/conf.d/xiaoniao.conf 

方式三:目录挂载目录,文件挂载文件

docker run -d -p 90-91:80-81 -v /opt/xiaoniaofeifei:/opt -v /opt/xiaoniao.conf:/etc/nginx/conf.d/xiaoniao.conf nginx:latest    --一步到位

扩展更新Debian源为清华源

清华源:https://mirrors.tuna.tsinghua.edu.cn/help/debian/

echo '# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free
# deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free
# deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free
# deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free
deb http://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free
# deb-src http://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free ' >/etc/apt/sources.list

#更新源
apt-get update

2. 建随即卷,持久化数据

#创建一个随机卷
docker run  -d -p 82:80 -v /usr/share/nginx/html nginx:latest

#查看创建的卷--宿主机上的一个容器
docker volume ls
DRIVER              VOLUME NAME
local               14f20e31f213497d336e06fa5b85702e2601d9755f6043c44cb6f9e384cfcc07

#查看卷的属性
docker volume  inspect 14f20e31f213497d336e06fa5b85702e2601d9755f6043c44cb6f9e384cfcc07
[
    {
        "CreatedAt": "2020-01-24T21:15:24+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": 
# -- 宿主机上卷的位置       "/var/lib/docker/volumes/14f20e31f213497d336e06fa5b85702e2601d9755f6043c44cb6f9e384cfcc07/_data",
        "Name": "14f20e31f213497d336e06fa5b85702e2601d9755f6043c44cb6f9e384cfcc07",
        "Options": null,
        "Scope": "local"
    }
]
[root@docker02 _data]# ls
50x.html  index.html

3. 创建一个有名字的数据卷 --推荐

#创建容器 挂载到有名字的数据卷
方式一:docker run -d -p 80:80  -v  nginx:/usr/share/nginx/html nginx:latest
方式二:docker run -d -p 82:80 --volume nginx:/usr/share/nginx/html nginx:latest
#查看卷
docker volume ls
DRIVER              VOLUME NAME
local               nginx

4. 挂载相同的目录

#挂载到之前容器相同目录
docker run -d -p 83:80 --volume-from 容器ID nginx:latest

 

手动制作docker镜像

基于centos6系统的nginx镜像(单服务)

centos6.9镜像https://pan.baidu.com/s/12Qk0Dya7hfpwLJjtD3Ex4Q

1:启动一个纯净的centos:6.9容器,安装nginx
docker run -it -p 80:80 centos:6.9 
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
yum install nginx -y
2:把安装好服务的容器,提交为镜像
docker container commit 容器ID/容器名 centos6.9_nginx:v1
3:测试镜像的功能
docker run -d  -p 82:80 centos6.9_nginx:v1 nginx -g 'daemon off;'

制作一个基于centos6系统的kod网盘的镜像(多服务)

可道云:https://pan.baidu.com/s/1yIKYHk3JaRUfJnbeGjSTVQ

在线下载

wget http://static.kodcloud.com/update/download/kodexplorer4.40.zip
unzip kodexplorer4.40.zip
chown -R nginx:nginx .

安装可道云

1:启动一个centos6.9_nginx:v1,再安装php
docker  run -it  -p 80:80  centos:6.9   /bin/bash 
yum install php-fpm php-gd php-mbstring -y
vi /etc/php-fpm.d/www.conf
--修改用户、组为nginx
service php-fpm start
cd /etc/nginx/conf.d/
vim default.conf
# The default server
server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  _;
    root         /html;
    index index.php index.html;

    # Load configuration files for the default server block.
    #连接php
    include /etc/nginx/default.d/*.conf;
    location ~ \.php$ {
        root        /html;
          fastcgi_pass    127.0.0.1:9000;
    fastcgi_index    index.php;
    fastcgi_param    SCRIPT_FILENAME    /html$fastcgi_script_name;
    include        fastcgi_params;
    }
}

mkdir /html
--解压kod文件到/html
chown -R nginx:nginx .
service nginx restart 

#创建一个可以夯住容器的脚本
vi /init.sh
#!/bin/bash
service php-fpm restart
service nginx restart
tail -f /etc/hosts
注:nginx -g 'deamon off;' 无法夯住....

#提交镜像
docker commit 8436ff4a76b8 kod:v1
#验证镜像
docker run -d -p 80:80 kod:v1 /bin/bash /init.sh

登录:10.0.0.12:80/index.php

 

 

自动制作docker镜像

镜像: 中药

dockerfile: 配方

dockerfile常用指令

FROM  基础镜像
RUN   制作镜像过程中需要的执行命令(安装服务)
CMD   容器启动的时候执行的初始命令,容易被替换(启动服务)
ENTRYPOINT  容器启动的时候执行的初始命令,不能被替换,如果同时使用CMD和ENTRYPOINT,cmd命令将作为ENTRYPOINT命令的参数
ADD   把dockerfile当前目录下的文件拷贝到容器中(自动解压tar包)
COPY  把dockerfile当前目录下的文件拷贝到容器中(不解压tar包)
WORKDIR 指定容器的默认工作目录
EXPOSE  镜像要暴露的端口
VOLUME  持久化卷
ENV     环境变量(ssh的密码,数据库的密码)
LABEL       镜像的属性标签
MAINTAINER  管理者标识

dockerfile的通俗理解:

据dockerfile自动构建镜像思路

a: 手动制作docker镜像,记录历史命令
b:根据历史命令编写dockerfile文件
c:docker build构建docker镜像
d:测试镜像的功能

dockerfile单服务例子

dockerfile创建一个nginx服务镜像 /opt/dockerfile/centos_nginx/

FROM centos:6.9
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
RUN curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
RUN yum install nginx -y
CMD ["nginx","-g","daemon off;"]

进行创建镜像

[root@docker02 centos_nginx]# docker image build -t centos6.9_nginx:v2  --network=host  .
--network=host #直接使用宿主机网络

dockerfile多服务例子

#提前开启一个kod容器,将创建kod容器的文件复制到kod目录下
docker cp  friendly_davinci:/etc/php-fpm.d/www.conf   .
docker cp  friendly_davinci:/etc/nginx/conf.d/default.conf  . 

#夯住容器脚本
vim init.sh
#!/bin/bash

service php-fpm start
nginx -g 'daemon off;'

[root@docker02 kod]# ls
default.conf  www.conf  init.sh 

default.conf文件内容

[root@docker02 kod]# cat default.conf  
server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  _;
    root         /html;
    index index.php index.html;
    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
    location ~ \.php$ {
        root        /html;
          fastcgi_pass    127.0.0.1:9000;
    fastcgi_index    index.php;
    fastcgi_param    SCRIPT_FILENAME    /html$fastcgi_script_name;
    include        fastcgi_params;
    }
    error_page 404 /404.html;
        location = /40x.html {
    }
    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}

www.conf文件:php目录下修改www.conf用户和组为nginx

创建dockerfile文件 kod在线下载

#vim dockerfile
FROM centos6.9_nginx:v1
RUN yum install php-fpm php-gd php-mbstring -y
ADD www.conf /etc/php-fpm.d/www.conf
ADD default.conf /etc/nginx/conf.d/default.conf 
RUN mkdir /html
WORKDIR /html
RUN curl -o kodexplorer4.40.zip http://static.kodcloud.com/update/download/kodexplorer4.40.zip
RUN yum install unzip -y
RUN unzip kodexplorer4.40.zip 
RUN chown -R nginx:nginx .
ADD init.sh   /init.sh

CMD ["/bin/bash","/init.sh"]

报错处理centos6.9系统没有curl命令,需要在dockerfile文件内加上RUN yum install curl -y

创建kod容器

docker build -t kod:v2 . 
docker run -d -p 80:80  kod:v2  
--打开网页验证 10.0.0.12:80

容器加入sshd服务

加入ssh服务可以远程连接容器

dockerfile文件

#在docker文件内加入一下内容
RUN yum install openssh-server -y 
RUN service sshd start 
ADD init.sh /init.sh 
#重设密码
RUN echo "123456" | passwd --stdin root
#初始化命令,夯住容器
CMD ["/bin/bash","/init.sh"] 

init.sh脚本

#/bin/bash 

service sshd start
service php-fpm start
nginx -g "daemon off;"

测试服务

docker run -d -p 80:80 -p 1023:22 kod:v3 /bin/bash /init.sh
docker exec -it <容器ID>
ssh root@10.0.0.12 -p 1023  --登录宿主机的1023端口就是登录容器的22端口

dockerfile使用环境变量的例子

使用环境变量设置root密码

1. dockersfile文件

FROM kod:v2
RUN yum install openssh-server -y
RUN service sshd start
ADD init.sh /init.sh
EXPOSE 22 #开启22端口

CMD ["/bin/bash","/init.sh"]
或者 ENTRYPOINT ["/bin/bash","/init.sh"]  
#容器启动的时候执行的初始命令,不能被替换,如果同时使用CMD和ENTRYPOINT,cmd命令将作为ENTRYPOINT命令的参数

注: dockerfile参数VOLUME /html 创建随机的卷挂载到html 名字只能随机,因为卷名唯一

2. init.sh 脚本

#/bin/bash 
#将密码加入脚本
echo "$SSH_PWD" | passwd --stdin root
#密码可以命令参数 -e "SSH_PWD=123456" 传输进去

service sshd start 
service php-fpm start 
nginx -g 'daemon off;'

注:只要可以夯住容器启动tail -f /etc/hosts也可以使用

3. 设置方式

方式一:

#命令行 -e 参数
docker  run  -d -P  --env "SSH_PWD=654321" kod_ssh:v3   -e参数会写到全局环境变量

#容器env查看
SSH_PWD=654321

#远程登录,-P随机映射到了宿主机的32787端口
ssh root@10.0.0.12 -p 32787

方式二:

#在dockerfile加上ENV环境变量
ENV SSH_PWD 654321

 

docker镜像的分层(复用,节省空间)

docker分层结构图

 

 docker里的镜像绝大部分都是在别的镜像的基础上去进行创建的,也就是使用镜像的分层结构。

镜像和分层

docker镜像由一些松耦合的只读镜像组成。如图所示。

docker 负责堆叠这些镜像层,并且将它们表示为统一的对象。

查看镜像分层的方式可以通过 docker image inspect命令

# docker  image inspect centos:6.9 
          "Type": "layers",
            "Layers": [
                "sha256:b5e11aae8a8e8fab750bd384393aafa379e21c57c398f5dd4980cd01fcf55b9e"
            ]

docker history查看centos镜像构建历史

# docker history centos:6.9
IMAGE               CREATED              CREATED BY        SIZE                         COMMENT
adf829198a7f        18 months ago       /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>           18 months ago       /bin/sh -c #(nop)  LABEL name=CentOS Base Im…   0B   
<missing>           18 months ago       /bin/sh -c #(nop)  ADD file:b99efdfca7b4df4ef…  195MB

有些dockerfile 中的指令并不会创建新的镜像层。比如ENV、EXPOSE、CMD以及ENTRY-POINT。不过,这些命令会在镜像中添加元数据。

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

:基于Ubuntu Linux 16.0.4创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加python包,就会在基础镜像层之上创建第二层镜像层层;如果继续添加一个安全补丁,就会添加第三个镜像层。

该镜像当前已经包含3个镜像层,如图所示

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含 3 个文件,而镜像包含了来自两个镜像层的 6 个文件。

上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。

下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有 6 个文件,这是因为最上层中的文件 7 是文件 5 的一个更新版本。

这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。

Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顾名思义,每种存储引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。

Docker 在 Windows 上仅支持 windowsfilter 一种存储引擎,该引擎基于 NTFS 文件系统之上实现了分层和 CoW[1]。

下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。

分层的优点

  1. 基本上每个软件都是基于某个镜像运行的,因此一但某个底层环境出了问题,就不需要去修改全部基于该镜像的软件的镜像,只需要修改底层环境的镜像

  2. 最大好处是可以共享资源,其他相同环境的软件镜像都共同去使用同一个环境镜像,而不需要每个软件镜像去创建一个底层镜像

 

dockerfile的优化

a: 使用体积小的linux镜像alpine
b:尽可能的清理无用的缓存文件
c:修改dockerfile的时候,尽可能把修改的内容放在最后
d:使用.dockerignore忽略构建docker镜像时,不需要的文件

alpine系统

官方网站:https://www.alpinelinux.org/

Alpine Linux是基于musl libc和busybox的面向安全的轻量级Linux发行版,大小只有5M。

使用alpine手动制作kod镜像

docker pull alpine
docker run -it alpine:latest
# sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories 
# apk update
# apk add nginx
# mkdir /run/nginx
# nginx
# nginx -v
# apk add php7 php7-fpm php7-opcache php7-curl php7-gd php7-mbstring php7-mysqli php7-json php7-iconv php7-exif php7-ldap php7-pdo php7-session php7-xml
# apk add openrc --no-cache
# mkdir -p /run/openrc
# touch /run/openrc/softlevel
# service php-fpm7 start
# rc-update add nginx default
# rc-upfate add php-fpm7 default
# vim  /etc/nginx/conf.d/default.conf  
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    location / {
        root /html;
        index index.php  index.html;
    include /etc/nginx/conf.d./*.conf;
    location ~ \.php$ {
        root        /html;
          fastcgi_pass    127.0.0.1:9000;
    fastcgi_index    index.php;
    fastcgi_param    SCRIPT_FILENAME    /html$fastcgi_script_name;
    include        fastcgi_params;
    }
    }
    # You may need this to prevent return 404 recursion.
    location = /404.html {
        internal;
    }
}

# nginx -t
# mkdir /html
# cd /html
# wget http://static.kodcloud.com/update/download/kodexplorer4.40.zip
# unzip kodexplorer4.40.zip
# chown -R nginx:nginx . 

#启动脚本文件编写
vim  /etc/init.sh
nginx
php-fpm7 -D
tail -f /etc/hosts

构建镜像:

docker commit <容器名称> alpine_kod:v1
docker run -d -p 80:80 alpine_kod:v1 /bin/sh /init.sh

使用dockerfile制作镜像

  • 准备nginx配置文件

  • 准备启动init.sh文件

  • 编写dockerfile文件

FROM alpine:latest
RUN  sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
RUN  apk update
RUN  apk add nginx php7 php7-fpm php7-opcache php7-curl php7-gd php7-mbstring php7-mysqli php7-json php7-iconv php7-exif php7-ldap php7-pdo php7-session php7-xml openrc --no-cache 
RUN  mkdir /run/nginx &&  mkdir /run/openrc  && touch /run/openrc/softlevel &&  mkdir /html
RUN  cd /html && wget http://static.kodcloud.com/update/download/kodexplorer4.40.zip  && unzip kodexplorer4.40.zip
RUN  chmod -R 777 /html
WORKDIR /html
COPY init.sh /init.sh
COPY default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD  ["/bin/sh","/init.sh"]

构建:

docker bulid -t alpine_kod:v2   --> 构建
docker run -d -p 81:80 alpine_kod:v2   --> 后台启动测试
docker exec -it alpine_kod:v2 /bin/sh  --> 前台进入

 

容器之间的互联

容器互联介绍

因为容器ip地址是随机创建的,在内部建立连接只用名称会更好一些,容器互联适合此场景。

核心:容器之间的互联使用了--link 参数将需要互联的容器ip地址和容器id写入hosts文件内

容器互联实例

#创建一个容器名字问web的容器
docker run  -d -p 80:80 --name web01 alpine:v1  /bin/sh /init.sh

#alpine_kod:v2进行互联
[root@docker01 ~]# docker run -it --link web01  alpine_kod:v2  /bin/sh
/html # 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.2    web01 ff5b38ba60a5
172.17.0.3    f77cd0a895aa

docker部署zabbix集群

zabbix官网文档docker介绍:https://www.zabbix.com/documentation/4.0/zh/manual/installation/containers

zabbix-github地址:https://github.com/zabbix/zabbix-docker

拉取镜像:

docker pull mysql:5.7
docker pull zabbix-java-gateway:latest
docker pull zabbix-server-mysql:latest
docker pull zabbix-web-nginx-mysql:latest
#导入
for n in `ls ./*.tar.gz` ;do docker load -i $n ;done

容器启动:

# 首先,启动空的 MySQL 服务器实例
docker run --name mysql-server -t \
      -e MYSQL_DATABASE="zabbix" \
      -e MYSQL_USER="zabbix" \
      -e MYSQL_PASSWORD="zabbix_pwd" \
      -e MYSQL_ROOT_PASSWORD="root_pwd" \
      -d mysql:5.7 \
      --character-set-server=utf8 --collation-server=utf8_bin

# 其次,启动 Zabbix Java gateway 实例   
docker run --name zabbix-java-gateway -t \
      -d zabbix/zabbix-java-gateway:latest

# 然后,启动 Zabbix server 实例,并将其关联到已创建的 MySQL server 实例。
docker run --name zabbix-server-mysql -t \
      -e DB_SERVER_HOST="mysql-server" \
      -e MYSQL_DATABASE="zabbix" \
      -e MYSQL_USER="zabbix" \
      -e MYSQL_PASSWORD="zabbix_pwd" \
      -e MYSQL_ROOT_PASSWORD="root_pwd" \
      -e ZBX_JAVAGATEWAY="zabbix-java-gateway" \
      --link mysql-server:mysql \
      --link zabbix-java-gateway:zabbix-java-gateway \
      -p 10051:10051 \
      -d zabbix/zabbix-server-mysql:latest

# 最后,启动 Zabbix Web 界面,并将其关联到已创建的 MySQL server 和 Zabbix server 实例。
docker run --name zabbix-web-nginx-mysql -t \
      -e DB_SERVER_HOST="mysql-server" \
      -e MYSQL_DATABASE="zabbix" \
      -e MYSQL_USER="zabbix" \
      -e MYSQL_PASSWORD="zabbix_pwd" \
      -e MYSQL_ROOT_PASSWORD="root_pwd" \
      --link mysql-server:mysql \
      --link zabbix-server-mysql:zabbix-server \
      -p 80:80 \
      -d zabbix/zabbix-web-nginx-mysql:latest

登录:

10.0.0.11
登录名:Admin 密码:zabbix

 

单机版容器编排

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

安装docker-compose

#需要扩展源
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
#下载
yum install docker-compose -y

官方下载方式:

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
#如果安装失败可以指向/usr/bin
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose --version

docker-compose命令使用

docker-compose --help

#常用命令
up(创建并启动服务)
down(停止服务,并删除)
stop(停止服务)
start -d (启动服务,-d后台启动服务)
restart(重启服务)

#其他命令
exec(登录容器)
ps(显示所有容器)
build(构建镜像)
build(不带缓存的构建)
rm(删除容器)
pause(暂停nginx容器)
unpause(恢复容器)
kill(停止指定服务的容器)

使用docker-compose

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

  1. 使用定义您的应用环境,Dockerfile以便可以在任何地方复制。

  2. 定义组成应用程序的服务,docker-compose.yml 以便它们可以在隔离的环境中一起运行。

  3. Run docker-compose upand Compose启动并运行您的整个应用程序。

mkdir -p /opt/dock-compose/zabbix
cat /opt/docker-compose/zabbix/docker-compose.yml
version: '3'

services:
   mysql-server:
     image: mysql:5.7
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: root_pwd
       MYSQL_DATABASE: zabbix
       MYSQL_USER: zabbix
       MYSQL_PASSWORD: zabbix_pwd
     command: --character-set-server=utf8 --collation-server=utf8_bin
     
   zabbix-java-gateway:
     image: zabbix/zabbix-java-gateway:latest
     restart: always
     
   zabbix-server:
     depends_on:
       - mysql-server
     image: zabbix/zabbix-server-mysql:latest
     restart: always
     environment:
       DB_SERVER_HOST: mysql-server
       MYSQL_DATABASE: zabbix
       MYSQL_USER: zabbix
       MYSQL_PASSWORD: zabbix_pwd
       MYSQL_ROOT_PASSWORD: root_pwd
       ZBX_JAVAGATEWAY: zabbix-java-gateway
     ports:
       - "10051:10051"
       
   zabbix-web-nginx-mysql:
     depends_on:
       - zabbix-server
     image: zabbix/zabbix-web-nginx-mysql:latest
     ports:
       - "80:80"
     restart: always
     environment:
       DB_SERVER_HOST: mysql-server
       MYSQL_DATABASE: zabbix
       MYSQL_USER: zabbix
       MYSQL_PASSWORD: zabbix_pwd
       MYSQL_ROOT_PASSWORD: root_pwd
       
#构建
[root@docker01 zabbix]# docker-compose up
访问:10.0.0.11

注:docker-compose版本v1 v2 v3, 每一一个版本语法,功能不一样 docker- compose中不需要link,↓docker- compose内部提供dns功能,通过service的名字来通信,双向通讯

 

posted @ 2020-04-18 11:07  kerwin-  阅读(416)  评论(0编辑  收藏  举报