docker,来自大佬分享,仅存档。 第一章 docker介绍 第二章 docker-ce安装 第三章 docker镜像常用命令 第五章 docker容器的常用命令 第六章 端口映射 第七章 docker数据卷 第八章 制作docker镜像 第九章 Dockerfile自动构建镜像 第十章 Docker-compose容器编排工具 第十一章 Docker网络模式 第十二章 Docker容器跨主机通信

docker,来自大佬分享,仅存档。
第一章 docker介绍
第二章 docker-ce安装
第三章 docker镜像常用命令
第五章 docker容器的常用命令
第六章 端口映射
第七章 docker数据卷
第八章 制作docker镜像
第九章 Dockerfile自动构建镜像
第十章 Docker-compose容器编排工具
第十一章 Docker网络模式
第十二章 Docker容器跨主机通信

官方镜像仓库

https://hub.docker.com/

docker官方仓库

https://www.docker.com/get-started

1.什么是容器

容器是隔离的环境中运行的一个进程,如果进程结束,容器就会停止,容器的隔离环境,拥有自己的ip地址,系统文件,主机名,进程管理

2:容器和虚拟机的区别

1.文字描述

虚拟机: 
硬件cpu支持(vt虚拟化),模拟计算硬件,走正常的开机启动
bios开机自检--根据bios启动项--读取硬盘第一个扇区grub,uefi, centos7, 加载内核,启动系统第一个进程/sbin/init systemd
容器:
不需要硬件cpu的支持,共用宿主机内核,启动容器的第一个进程
容器优势:
启动快,性能高,损耗少,轻量级
100虚拟机 100个服务     10宿主机
100容器     100个服务     6宿主机

2.图形描述

3.docker的三个主要概念

1.镜像

那么镜像到底是什么呢?Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程 序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户 等)。

2.容器

容器(Container)的定义和镜像(Image)几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的 最上面那一层是可读可写的。

3.仓库

镜像仓库是 Docker 用来集中存放镜像文件的地方,类似于我们之前常用的代码仓库。 通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。 我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 Latest 作为默认标签。

4.docker的组成部分

Docker是传统的CS架构分为docker client和docker server 
Docker客户端是 Docker 用户与 Docker 交互的主要方式。
当您使用 Docker 命令行运行命令时,Docker 客户端将这些命令发送给服务器端,服务端将执行这些 命令。 Docker 命令使用 Docker API 。
Docker 客户端可以与多个服务端进行通信。

docker是一个cs架构, docker主要:镜像 容器   仓库 网络 存储   监控
docker是一个软件的打包技术

第二章 docker-ce安装

1.环境准备

主机名 ip 内存
docker01 10.0.0.21 2G
docker02 10.0.0.22 2G

2.安装docker-ce

1.安装docker清华源

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

2.安装docker

[root@docker01 ~]# yum remove docker docker-common docker-selinux docker-engine
[root@docker01 ~]# yum -y install docker-ce

3.启动docker

[root@docker01 ~]# systemctl enable docker
[root@docker01 ~]# systemctl start docker

4.查看版本

[root@docker01 ~]# docker version 
Client: Docker Engine - Community
Version:           19.03.13
API version:       1.40
Go version:       go1.13.15

3.国内源镜像加速器

[root@docker01 ~]# cat> /etc/docker/daemon.json <<'EOF'
{
   "registry-mirrors": [
       "https://registry.docker-cn.com"
  ]
}
EOF

systemctl restart docker

第三章 docker镜像常用命令

1.搜索镜像

1.普通搜索

docker search  mirror-name      #优先选官方,好评多
NAME           DESCRIPTION     STARS       OFFICIAL   AUTOMATED
镜像名称       镜像描述       好评数量 官方的 是否自动构建

2.使用curl获取镜像版本号

yum -y install jq
curl -s https://registry.hub.docker.com/v1/repositories/镜像名称/tags|jq | grep name

2.拉取镜像

 docker  image pull   mirror-name           #默认最新版
docker image pull   mirror-name:版本号  #指定版本

3.推送镜像

docker image push 

4.导入镜像

docker image load -i 镜像包          #会导入标签和名字,推荐使用
docker image import 镜像包          #不会导入标签和名字

for i in `ls|xargs -n1`;do docker load -i $i;done    #批量导入镜像

5.导出镜像

1.导出一个镜像打包
两种方式
docker image save mirror-name:版本号 -o 名字.tar.gz
docker image save mirror-name:版本号 > 名字.tar.gz

2.导出多个镜像打成一个包
docker image save 镜像名:版本号 镜像名:版本号 镜像名:版本号 -o 名字.tar.gz

6.查看镜像列表

docker image  ls
docker images

7.删除镜像

docker rmi 镜像:版本号
docker rmi 镜像ID

#批量删除镜像

8.给镜像打标签

docker image tag 镜像id  镜像名字:版本号           #(自己起名字和版本号)

9.查看镜像属性

docker inspect 镜像名字:版本号

第五章 docker容器的常用命令

1.创建并启动容器

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

2.创建容器

docker create   --name 自定义名字  镜像名:版本号

3.启动容器

docker start 容器ID
#批量启动容器
docker start $(docker ps -a)

4.停止容器

docker  stop  容器ID

5.重启容器

docker  restart  容器ID

6.强制停止容器

docker  kill

7.查看容器列表

docker  ps
参数:
-a 查看所有容器
-l 查看未启动的容器(好像不是,待修改)
-q 查看容器ID
不加 查看正在运行的容器

8. 删除容器

#单个删除容器
docker  rm

#批量删除容器
docker rm -f `docker ps -a -q`

9.进入正在运行的容器

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

docker  exec
例子: docker exec  -it 容器id/容器名字   /bin/bash(/bin/sh)

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

docker attach 容器ID
ctrl +p,ctrl +q           ##几个窗口会同步操作,使用同一个中端

10.自定义容器名字

docker run --name 名字  镜像名:版本号

11.查看容器属性

docker inspect 容器ID

12.前台运行

#启动的容器需要有一个PID为 1 的进程卡住,不然进程会关闭
#容器前台运行可以在起容器的时候加个命令杠住
#容器后面可以加查询,及其他命令
例:
docker run -it centos:7 /bin/bash
#nginx 卡进程的命令
nginx -g 'daemon off;'
/usr/sbin/php-fpm --nodaemonize

第六章 端口映射

1.指定端口映射

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

#指定端口映射
docker run -d -p 81:81 centos:7      #注意:-d 要放在端口前,不然报错

#多个容器使用8080端口
1.宿主机添加网卡
ifconfig eth0:1 10.0.0.23 up
#查看网卡是否创建成功
ifconfig eth0:1
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
      inet 10.0.0.23 netmask 255.0.0.0 broadcast 10.255.255.255
       
2.启容器并映射
docker run -d -p 10.0.0.21:8080:80 nginx:latest
docker run -d -p 10.0.0.23:8080:80 nginx:latest

2.随机端口映射

docker run  
-p 宿主机ip1::容器端口    #随机端口映射
-p 宿主机ip1::容器端口/udp      #使用udp协议做随机端口映射
-P 自动随机端口映射

3.范围端口映射

docker run
-p  1111-1119:1111-1119 #端口范围映射

第七章 docker数据卷

1.参数

docker run
-v 宿主机绝对目录:容器目录

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

2.举例

第八章 制作docker镜像

1.手动制作docker镜像

1.启动并进入容器

#以制作nginx镜像为例

docker run -it -d  --name nginx_mk centos:7
docker exec -it nginx_mk /bin/bash

2.安装nginx

1.安装nginx源
vi /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

2.安装nginx
yum makecache fast
yum -y install nginx

3.优化镜像

yum clean all

4.退出容器

exit

5.制作镜像

docker commit  nginx_mk nginx_cts:v1     #(nginx_cts是自己定义的)

6.查看

docker images | grep nginx_cts

7.启动制作的镜像并运行

docker run -it -d -p 80:80 nginx_cts:v1 nginx -g "daemon off;"
在浏览器测试:
10.0.0.21

8.将镜像导出

docker save nginx_cts:v1 -o nginx_v1.tar

2.自动制作docker镜像

需求:
1.访问宿主机的8080端口,跳转到小鸟游戏
2.访问宿主机的8090端口,跳转到神经猫
3.每个游戏单独的一个nginx配置文件
4.nginx记录的日志分开
5.小鸟的日志名为xiaoniao.access
6.神经猫的日志名为sjm.access
7.使用目录映射和配置文件把代码和配置文件映射到容器里
8.容器内日志持久化到宿主机的目录/opt/nginx/
9.nginx日志格式为json格式
10.不允许进入到容器里(允许调试进入)

1.创建代码目录、配置文件目录

mkdir -p /data/{conf..code}

2.配置游戏访问界面

vim /data/conf/sjm.conf
server {
  listen       8090;
  server_name localhost;
  access_log /var/log/nginx/sjm.log json;

  location / {
      root   /usr/share/nginx/html/sjm;
      index index.html index.htm;
  }
}

vim /data/conf/xiaoniao.conf
server {
  listen       8080;
  server_name localhost;
  access_log /var/log/nginx/xiaoniao.log json;

  location / {
      root   /usr/share/nginx/html/xiaoniao;
      index index.html index.htm;
  }
}

3.配置nginx.conf日志格式为 json

vim /data/conf/nginx.conf
user nginx;
worker_processes  1;

error_log /var/log/nginx/error.log warn;
pid       /var/run/nginx.pid;

events {
  worker_connections  1024;
}

http {
  include       /etc/nginx/mime.types;
  default_type application/octet-stream;

  log_format main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

log_format json '{ "time_local": "$time_local", '
                         '"remote_addr": "$remote_addr", '
                         '"referer": "$http_referer", '
                         '"request": "$request", '
                         '"status": $status, '
                         '"bytes": $body_bytes_sent, '
                         '"agent": "$http_user_agent", '
                         '"x_forwarded": "$http_x_forwarded_for", '
                         '"up_addr": "$upstream_addr",'
                         '"up_host": "$upstream_http_host",'
                         '"upstream_time": "$upstream_response_time",'
                         '"request_time": "$request_time"'
   ' }';
#   access_log /var/log/nginx/access.log json;
#   access_log /var/log/nginx/access.log main;

  sendfile       on;
   #tcp_nopush     on;

  keepalive_timeout  65;

   #gzip on;

  include /etc/nginx/conf.d/*.conf;
}

4.拉取代码

上传代码
cd /data/code
rz sjm.zip xiaoniaofeifei.zip

解压代码
unzip sjm.zip
unzip xiaoniaofeifei.zip -d xiaoniao

5.自动启动容器

docker run 
-p 8080:8080
-p 8090:8090
-v /data/conf/sjm.conf:/etc/nginx/conf.d/sjm.conf
-v /data/conf/xiaoniao.conf:/etc/nginx/conf.d/xiaoniao.conf
-v /data/conf/nginx.conf:/etc/nginx/nginx.conf
-v /data/code/sjm:/usr/share/nginx/html/sjm
-v /data/code/xiaoniao:/usr/share/nginx/html/xiaoniao
-v /opt/nginx/:/var/log/nginx/
-d nginx:latest

###注意路径,搞错了容器起不来

6.启动代码测试

浏览器:
http://10.0.0.21:8080
http://10.0.0.21:8090

3.制作kod云盘镜像站

1.创建容器

docker run -it -d -p 80:80 --name kod_cts centos:7  

2.进入容器

docker exec -it kod_cts /bin/bash

3.创建www用户

容器:
groupadd -g 1000 www
  useradd -u1000 -g1000 -M -s /sbin/nologin www
宿主机:
groupadd -g 1000 www
useradd -u1000 -g1000 -M -s /sbin/nologin          ##容器跟宿主机用户id最好一致

4.创建代码目录

mkdir /code

5.安装nginx

1.配置Nginx源

 vi /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

2.下载Nginx

yum -y install nginx

3.配置Nginx配置文件

vi /etc/nginx/conf.d/cloud.conf
server {
listen 80;
server_name localhost;
root /code;
index index.php index.html;
location ~ .php$ {
root /code;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

4.修改nginx.conf

#修改nginx启动用户为www
user www;
worker_processes  1;

error_log /var/log/nginx/error.log warn;
pid       /var/run/nginx.pid;


events {
  worker_connections  1024;
}

http {
  include       /etc/nginx/mime.types;
  default_type application/octet-stream;

  log_format main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

  access_log /var/log/nginx/access.log main;

  sendfile       on;
   #tcp_nopush     on;

  keepalive_timeout  65;

   #gzip on;

  include /etc/nginx/conf.d/*.conf;
}

6.安装PHP

1.安装php-fpm

yum -y install php-fpm
php-fpm -v

2.修改php-fpm配置文件

sed -i '/^user/c user = www' /etc/php-fpm.d/www.conf 
sed -i '/^group/c group = www' /etc/php-fpm.d/www.conf

7.下载代码到宿主机/code

cd /code
rz D:kodexplorer4.40.zip
unzip kodexplorer4.40.zip -d kod

8.将kod软件cp到容器

docker cp /code/kod kod_cts:/code

9.添加GD库

yum install php-mbstring php-gd -y

10.授权/code

chown -R www.www /code

11.编写启动脚本并授权

1.写启动脚本
vi /code/init.sh
#!/bin/bash
nginx
php-fpm

2.添加执行权限
chmod +x /code/init.sh

12.提交镜像

 docker commit kod_cts kod:v1

13.启动测试

 docker stop $(docker ps -qa)
docker run -d -p 80:80 kod:v1
docker ps

浏览器
http://10.0.0.21
跳出来界面即可

14.导出镜像

docker save kod:v1 -o kod_v1.tar.gz

第九章 Dockerfile自动构建镜像

1.Dockfile 操作说明

Docker通过对于在Dockerfile中的一系列指令的顺序解析实现自动的image的构建
通过使用build命令,根据Dockerfiel的描述来构建镜像
通过源代码路径的方式
通过标准输入流的方式
   
指令:
只支持Docker自己定义的一套指令,不支持自定义
大小写不敏感,但是建议全部使用大写
根据Dockerfile的内容顺序执行
   
FROM:
FROM {base镜像}
必须放在DOckerfile的第一行,表示从哪个baseimage开始构建

MAINTAINER:
可选的,用来标识image作者的地方

RUN:
每一个RUN指令都会是在一个新的container里面运行,并提交为一个image作为下一个RUN的
base
一个Dockerfile中可以包含多个RUN,按定义顺序执行
RUN支持两种运行方式:
RUN <cmd> 这个会当作/bin/sh -c “cmd” 运行 RUN [“executable”,“arg1”,。。],Docker把他当作json的顺序来解析,因此必须使用双引号,而且executable需要是完整路径
RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。第一层 RUN command1 的执行仅
仅是当前进程,一个内存上的变化而已,其结果不会造成任何文件。而到第二层的时候,启动的是一个全
新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。而如果需要将两条命令或者多条命令联合起来执行需要加上&&。
如:cd /usr/local/src && wget xxxxxxx
       
CMD:
CMD的作用是作为执行container时候的默认行为(容器默认的启动命令)
当运行container的时候声明了command,则不再用image中的CMD默认所定义的命令
一个Dockerfile中只能有一个有效的CMD,当定义多个CMD的时候,只有最后一个才会起作用

CMD定义的三种方式:
CMD <cmd> 这个会当作/bin/sh -c "cmd"来执行
CMD ["executable","arg1",....]
CMD ["arg1","arg2"],这个时候CMD作为ENTRYPOINT的参数

EXPOSE 声明端口
格式为 EXPOSE <端口1> [<端口2>...]。
  EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明,应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者 理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
   
ENTRYPOINT:
  entrypoint的作用是,把整个container变成了一个可执行的文件,这样不能够通过替换CMD的方法来改变创建container的方式。但是可以通过参数传递的方法影响到container内部
  每个Dockerfile只能够包含一个entrypoint,多个entrypoint只有最后一个有效 当定义了entrypoint以后,CMD只能够作为参数进行传递
   
  entrypoint定义方式:
  entrypoint ["executable","arg1","arg2"]
  这种定义方式下,CMD可以通过json的方式来定义entrypoint的参数,可以通过在运行container的时候通过指定command的方式传递参数
  entrypoint <cmd>,当作/bin/bash -c "cmd"运行命令
  ADD & COPY: 当在源代码构建的方式下,可以通过ADD和COPY的方式,把host上的文件或者目录复制到image中 ADD和COPY的源必须在context路径下
  当src为网络URL的情况下,ADD指令可以把它下载到dest的指定位置,这个在任何build的方式下,都可以work
  ADD相对COPY还有一个多的功能,能够进行自动解压压缩包
   
ENV:
ENV key value 用来设置环境变量,后续的RUN可以使用它所创建的环境变量
当创建基于该镜像的container的时候,会自动拥有设置的环境变量

WORKDIR:
用来指定当前工作目录(或者称为当前目录)
当使用相对目录的情况下,采用上一个WORKDIR指定的目录作为基准
   
USER:
指定UID或者username,来决定运行RUN指令的用户

ONBUILD:
ONBUILD作为一个trigger(触发)的标记,可以用来trigger(触发)任何Dockerfile中的指令
可以定义多个ONBUILD指令
当下一个镜像B使用镜像A作为base的时候,在FROM A指令前,会先按照顺序执行在构建A时候定义 的ONBUILD指令 ONBUILD <DOCKERFILE 指令> <content>

VOLUME:
用来创建一个在image之外的mount point,用来在多个container之间实现数据共享
运行使用json array的方式定义多个volume
VOLUME ["/var/data1","/var/data2"]
或者plain text的情况下定义多个VOLUME指令

2.dockerfile自动部署kod容器

1.kod需要的配置文件及代码

tree /data/ -L 2
/data
├── code
│   └── nginx-1.18.0-1.el7.ngx.x86_64.rpm
├── conf
│   ├── cloud.conf
│   ├── nginx.conf
│   └── www.conf
├── Dockerfile
├── init.sh
├── kod
│   ├── kod.tar.gz
└── kodexplorer4.40.zip

2.启动kod容器dockerfile文件

#安装基础镜像
FROM centos:7

#创建用户
RUN groupadd -g 1000 www
RUN useradd -u 1000 -g 1000 www

#安装php
RUN yum -y install php-fpm

#修改php配置文件
COPY conf/www.conf /etc/php-fpm.d/www.conf

#创建代码目录
RUN mkdir /code

#安装nginx依赖
RUN yum install openssl -y

#安装nginx
COPY code/nginx-1.18.0-1.el7.ngx.x86_64.rpm /code
RUN rpm -ivh /code/nginx-1.18.0-1.el7.ngx.x86_64.rpm

#修改配置文件
COPY conf/cloud.conf /etc/nginx/conf.d/cloud.conf
COPY conf/nginx.conf /etc/nginx/nginx.conf

#将kod代码拉取到溶器
ADD kod/kod.tar.gz /code

#添加GD库
RUN yum install php-mbstring php-gd -y

#写启动脚本并授权
COPY init.sh /code/
RUN chmod +x /code/init.sh

#给/code目录授权
RUN chown -R www.www /code

#启动命令
CMD ["/bin/bash","/code/init.sh"]

3.构建容器

cd /code
docker build -t kod:v1 .

3.Dockerfile自动构建小游戏

 

4.Dockerfile自动构建 wordpress

 

第十章 Docker-compose容器编排工具

1.docker-compose介绍

Compose 是用于定义和运行多容器 Docker 应用程序的工具。
通过Compose,您可以使用YML文件来配置应用程序需要的所有服务。
写好yaml文件之后,只需要运行一条命令,就会按照资源清单里的配置运行相应的容器服务。

Compose 使用的三个步骤

1.使用 Dockerfile 定义应用程序的环境。
2.使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
3.最后,执行 docker-compose up 命令来启动并运行整个应用程序。

2.安装docker-compose

1.方法1:直接yum安装

yum install docker-compose

2.方法2:使用官方脚本安装

curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

3.docker-compose语法介绍

1.语法

version: '2.2'
services:
服务名称:
  image: 容器镜像
  container_name: 容器名称
  environment:
    - 环境变量1=值1
    - 环境变量2=值2
  volumes:
    - 存储驱动1:容器内的数据目录路径
    - 宿主机目录路径:容器内的数据目录路径
  ports:
    - 宿主机端口:映射到容器内的端口
  networks:
    - 自定义网络的名称
服务名称:
  image: 容器镜像
  container_name: 容器名称
  environment:
    - 环境变量1=值1
    - 环境变量2=值2
  volumes:
    - 存储驱动2:对应容器内的数据目录路径
  ports:
    - 宿主机端口:映射到容器内的端口
  networks:
    - 自定义网络的名称

volumes:
  存储驱动1:
  driver: local
  存储驱动2:
  driver: local

networks:
自定义网络名称:
  driver: bridge

2.参数解释

1.为什么要做link
centos7-1 ping 172.17.0.2 ping centos7-2
centos7-2 ping 172.17.0.3 ping centos7-1

zabbix-mysql      
- mysql

zabbix-server    
--link mysql
配置数据库IP地址:
DBHOSt: mysql

zabbix-web
DBHOSt: mysql


2.用户参数
user: 2000:2000
2000:999
    mysql:mysql
-v /data/mysql:/var/lib/mysql

3.参数哪里找/环境变量哪里找
官网找:https://hub.docker.com/_/mysql
--character-set-server=utf8
--collation-server=utf8_bin

4.服务启动顺序控制
depends_on:
- mysql

1 mysql

2 zabbix-server
depends_on:
  - mysql

3 zabbix-web
depends_on:
  - zabbix-server

5.版本号

4.参数的含义不理解
environment:
MYSQL_DATABASE: zabbix #启动mysql容器的时候创建的新数据库名称
MYSQL_USER: zabbix #启动mysql容器的时候创建的新数据库的管理用户
MYSQL_PASSWORD: zabbix #启动mysql容器的时候创建的新数据库的管理用户的密码
MYSQL_ROOT_PASSWORD: zabbix   #启动mysql容器的时候root账户的密码
volumes:
- /data/mysql:/var/lib/mysql #把容器里的数据目录挂载到宿主机的目录
 
5.参数作用
services:
mysql:  

1.可以自定义
2.docker-compose里links连接时候用的
3.docker-compose想单独停止或启动某个服务时候用的名字

6.参数的意义
user: 2000:2000

如果不添加这个参数的结果:
1.容器内mysql用户是999
2.挂载之后,宿主机目录显示的也是999
3.要求你宿主机的mysql和容器内的mysql用户的UID和GID保持完全一致

但是假如我宿主机的UID和GID为999的已经被占用了怎么?
那么就添加user: 2000:2000参数,可以达到什么效果呢?
1.宿主机显示的是2000用户,容器内依然是999用户
2.但是两边可以互相写入
3.前提是你宿主机提前创建好目录并且更改好授权为2000用户

7.环境变量意义
environment:
MYSQL_DATABASE: zabbix #作用是,启动mysql容器的时候自动创建一个数据库
MYSQL_USER: zabbix       #作用是,给刚才创建的新的数据库授权用户
MYSQL_PASSWORD: zabbix   #作用是,给刚才创建的普通用户赋予一个密码
MYSQL_ROOT_PASSWORD: zabbix #作用是,给root账户创建一个密码叫zabbix

前三个参数的作用:
启动容器的时候
1.自动创建一个用户名字叫zabbix
2.给zabbix用户创建个密码
3.创建数据库叫zabbix
4.赋权zabbix用户对zabbix数据库拥有所有的权限

8.links作用
links:    
- mysql

为什么要用links???
如果不用的话,两个容器互相通讯必须通过IP地址
那么为配置文件就不能提前配了


如果用了Links呢?
两个容器互相通讯,只需要知道对方的容器名称即可,不需要知道IP地址


9.mysql变量从哪里获取的?
docker-hub是什么?
docker-hub是docker官方的镜像仓库地址,全球都可以访问,朝鲜除外
大家都会把官方镜像放在docker-hub上

来源地址:
https://hub.docker.com/_/mysql


10.依靠什么名字来通讯

依靠的是容器之间的名字
不是docker-compose里的service名称

如果使用的是docker-compose启动的,并且配置文件里加了网卡的bridge,可以通过service名称
如果只是用run启动,则必须是容器的name名称

links:    
- mysql

4.使用docker-compose部署zabbix

1.docker-run命令

docker run --name mysql-server -t 
    -e MYSQL_DATABASE="zabbix"
    -e MYSQL_USER="zabbix"
    -e MYSQL_PASSWORD="zabbix"
    -e MYSQL_ROOT_PASSWORD="zabbix"
    -d mysql:5.7
    --character-set-server=utf8 --collation-server=utf8_bin
 
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"
    -e MYSQL_ROOT_PASSWORD="zabbix"
    --link mysql-server:mysql
    -p 10051:10051
    -d zabbix/zabbix-server-mysql:latest

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"
    -e MYSQL_ROOT_PASSWORD="zabbix"
    --link mysql-server:mysql
    --link zabbix-server-mysql:zabbix-server
    -p 80:8080
    -d zabbix/zabbix-web-nginx-mysql:latest

2.docker-compose

version: '2.2'
services:
mysql:
  image: mysql:5.7
  container_name: mysql-server
  user: 2000:2000
  environment:
    MYSQL_DATABASE: zabbix
    MYSQL_USER: zabbix
    MYSQL_PASSWORD: zabbix
    MYSQL_ROOT_PASSWORD: zabbix
  volumes:
    - /data/mysql:/var/lib/mysql
  command:
    --character-set-server=utf8
    --collation-server=utf8_bin      
         
zabbix-server-mysql:
  image: zabbix/zabbix-server-mysql:latest
  container_name: zabbix-server-mysql
  environment:
    DB_SERVER_HOST: mysql-server
    MYSQL_DATABASE: zabbix
    MYSQL_USER: zabbix
    MYSQL_PASSWORD: zabbix
    MYSQL_ROOT_PASSWORD: zabbix
  ports:
    - 10051:10051
  links:
    - mysql
  depends_on:
    - mysql
 
zabbix-server-web:
  image: zabbix/zabbix-web-nginx-mysql:latest
  container_name: zabbix-web-nginx-mysql
  environment:
    DB_SERVER_HOST: mysql-server
    MYSQL_DATABASE: zabbix
    MYSQL_USER: zabbix
    MYSQL_PASSWORD: zabbix
    MYSQL_ROOT_PASSWORD: zabbix
  ports:
    - 80:8080
  links:
    - mysql
    - zabbix-server-mysql
  depends_on:
    - zabbix-server-mysql

5.使用docker-compose部署jenkins+gitlab

docker-compose

version: '2.2'
services:
gitlab:
  image: 'gitlab/gitlab-ce:latest'
  restart: always
  hostname: '10.0.0.11'
  environment:
    GITLAB_OMNIBUS_CONFIG: |
      external_url 'http://10.0.0.11'
  ports:
    - '8000:80'
    - '443:443'
    - '2222:22'
  volumes:
    - '/data/gitlab/config:/etc/gitlab'
    - '/data/gitlab/logs:/var/log/gitlab'
    - '/data/gitlab/data:/var/opt/gitlab'
 
jenkins:
  image: 'jenkins/jenkins:lts'
  restart: always
  hostname: '10.0.0.11'
  user: root
  ports:
    - '8080:8080'
    - '50000:50000'
  volumes:
    - /data/jenkins/:/var/jenkins_home

第十一章 Docker网络模式

1.Docker网络的四种模式

1.四种模式

Host        容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
Bridge     此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。
None 此模式关闭了容器的网络功能。
Container 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。

2.查看网络模式命令

    docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
3791e4fc9c18        bridge              bridge              local
b494337929ef        host                host                local
a153ac0003e3        none                null                local

3.查看网卡命令

ip a

4.查看桥接网卡命令

yum install bridge-utils -y
brctl show

2.bridge模式介绍

1.当Docker Daemon第一次启动时会创建一个虚拟的网桥,默认名称是Docker0
2.创建完后会给这个网桥分配一个子网,默认是172.17.0.1/16
3.由Docker创建的每一个容器,都会创建一个Veth设备对,其中一端关联到网桥上,另一端放在容器里映射为eth0,然后从网桥的地址段内给容器内的eth0分配一个IP地址,这样容器之间就可以互通了。

流程图:

docker,来自大佬分享,仅存档。
第一章 docker介绍
第二章 docker-ce安装
第三章 docker镜像常用命令
第五章 docker容器的常用命令
第六章 端口映射
第七章 docker数据卷
第八章 制作docker镜像
第九章 Dockerfile自动构建镜像
第十章 Docker-compose容器编排工具
第十一章 Docker网络模式
第十二章 Docker容器跨主机通信

第十二章 Docker容器跨主机通信

1.Docker跨主机网络类型

自带:
macvlan

第三方:
flannel
Consul
calico

2.macvlan模式

1.创建网络

docker network 
create -d macvlan
--subnet 10.0.0.0/24
--gateway 10.0.0.2
-o parent=eth0 macvlan_1

2.启动容器

1.docker01启动容器
docker run -it --network macvlan_1 --ip 10.0.0.100 alpine

2.docker02启动容器
docker run -it --network macvlan_1 --ip 10.0.0.200 alpine

3.启动后进入容器测试IP通讯

docker01容器  ping 10.0.0.100
docker02容器 ping 10.0.0.200

3.跨主机通信-Consul实现

1. Consul介绍

Consul是一个服务网格(微服务间的 TCP/IP,负责服务之间的网络调用、限流、熔断和监控)解决方案,它是一个分布式的,高度可用的系统,而且开发使用都很简便。
它提供了一个功能齐全的控制平面,主要特点是:服务发现、健康检查、键值存储、安全服务通信、多数据中心。

2. 二进制安装步骤

wget https://releases.hashicorp.com/consul/1.4.4/consul_1.4.4_linux_amd64.zip 
unzip consul_1.4.4_linux_amd64.zip
mv consul /usr/bin/
chmod +x /usr/bin/consul
nohup consul agent -server -bootstrap -ui -data-dir /var/lib/consul -client=10.0.0.11 -bind=10.0.0.11 &>/var/log/consul.log &
tail -f /var/log/consul.log

3.修改docker01启动文件

[root@docker01 ~]# vim /lib/systemd/system/docker.service
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store consul://10.0.0.11:8500 --cluster-advertise 10.0.0.11:2375

4.重启docker01

systemctl daemon-reload     
systemctl restart docker.service

5.同样方法修改docker02的配置

[root@docker02 ~]# vim /lib/systemd/system/docker.service
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store consul://10.0.0.11:8500 --cluster-advertise 10.0.0.12:2375

6.重启docker2

systemctl daemon-reload     
systemctl restart docker.service

7.在docker主机上创建overlay网络

在docker1上创建网络,然后会自动同步到docker2上
docker network create -d overlay overlay_net

8.分别在两个节点上创建容器

1.docker01运行命令

docker run -it --net=overlay_net --name busybox01 busybox:latest

2.docker02运行命令

docker run -it --net=overlay_net --name busybox02 busybox:latest

9.测试联通性

docker run -it --net=overlay_net --name busybox01 busybox:latest
#ping 10.0.0.3

4.跨主机通信-flannel实现

1.flannel介绍

Flannel是一种基于overlay网络的跨主机容器网络解决方案,即将TCP数据包封装在另一种网络包里面进行路由转发和通信,Flannel是CoreOS开发,专门用于docker多机互联的一个工具,让集群中的不同节点主机创建的容器都具有全集群唯一的虚拟ip地址

2. flannel通信原理

流程图解

 

文字说明

3.实验环境

10.0.0.11  etcd,flannel,docker
10.0.0.12 flannel,docker

4. 安装配置etcd

1.安装etd:

yum install etcd -y

2.编辑配置文件

cat > /etc/etcd/etcd.conf << 'EOF'
# [member]
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://10.0.0.11:2379,http://127.0.0.1:2379"

# #[cluster]
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://10.0.0.11:2379"
EOF

3.启动etcd

systemctl start etcd
systemctl enable etcd

4.测试etcd功能

etcdctl -C http://10.0.0.11:2379 cluster-health
etcdctl -C http://10.0.0.11:2379 set /testdir/testkey "Hello world"   
etcdctl -C http://10.0.0.11:2379 get /testdir/testkey

5.防火墙

iptables -A INPUT -p tcp -m tcp --dport 2379 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 2380 -m state --state NEW,ESTABLISHED -j ACCEPT

5.安装配置Flannel-两台机器都操作

1.安装Flannel

yum install flannel

2.配置Flannel

cp /etc/sysconfig/flanneld /opt/flanneld.bak
cat > /etc/sysconfig/flanneld << 'EOF'
# Flanneld configuration options  

# etcd url location. Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://10.0.0.21:2379"

# etcd config key. This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/atomic.io/network"

# Any additional options that you want to pass
#FLANNEL_OPTIONS=""
EOF

3.配置etcd数据库

etcdctl mk /atomic.io/network/config '{ "Network": "192.168.10.0/16" }'

4.启动flannel

systemctl start flanneld.service
systemctl enable flanneld.service

5.检查端口

[root@docker01 ~]#netstat -lntup|grep flannel
udp        0      0 10.0.0.21:8285          0.0.0.0:*                           2202/flanneld
[root@docker02 ~]#netstat -lntup|grep flannel
udp        0      0 10.0.0.22:8285          0.0.0.0:*                           1963/flanneld

6. 配置Docker关联Flannel网络

#配置好flannel之后,我们只需要重启docker即可,然后查看网卡会发现docker0变成了我们配置的flannel网段。
systemctl restart docker

7. 创建容器测试

1.docker01创建容器
docker run -it busybox /bin/sh
2.查看IP地址
/ # ip a
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
17: eth0@if18: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
  link/ether 02:42:c0:a8:3a:03 brd ff:ff:ff:ff:ff:ff
  inet 192.168.58.3/24 brd 192.168.58.255 scope global eth0
      valid_lft forever preferred_lft forever
3.Docker02创建容器
docker run -it busybox /bin/sh
4.查看IP地址
/ # ip a
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
13: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1472 qdisc noqueue
  link/ether 02:42:c0:a8:48:02 brd ff:ff:ff:ff:ff:ff
  inet 192.168.72.2/24 brd 192.168.72.255 scope global eth0
      valid_lft forever preferred_lft forever  
5.测试容器间可否通讯
ping 192.168.72.2
ping 192.168.58.3
6.docker地址没变处理方法

修改docker配置文件

vim /usr/lib/systemd/system/docker.service
.................
EnvironmentFile=/run/flannel/docker
ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_NETWORK_OPTIONS
.................
systemctl daemon-reload
systemctl restart docker
7. 修改防火墙
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT