第1章 Docker容器介绍

1.docker是什么

 Docker是Docker.Inc公司开源的一个基于LXC技术之上构建的Container容器引擎,源代码托管在GitHub 上,基于Go语言并遵从Apache2.0协议开源。
 Docker是通过内核虚拟化技术(namespaces及cgroups等)来提供容器的资源隔离与安全保障等。
 由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机(VM)额外的操作系统开销,提高资源利用率。

2.容器与虚拟机对比

传统虚拟化和Docker分层对比:

docker笔记_nginx

VM虚拟化和Docker特性对比

docker笔记_mysql_02

3.docker的三个重要概念

Image(镜像):

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

Container(容器):

 镜像(image)和容器(container)的关系,就像是面向对象程序设计中的类和对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

Repository(仓库):

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

镜像和容器图解:

docker笔记_php_03

4.docker的组成部分

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

docker笔记_docker_04

第2章 Docker安装部署

1.国内源安装docker-ce

yum安装gcc相关

yum -y install gcc gcc-c++

卸载旧版本

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

这里使用清华源:

https://mirrors.tuna.tsinghua.edu.cn/help/docker-ce/

操作步骤:

yum remove docker docker-common docker-selinux docker-engine
yum install -y yum-utils device-mapper-persistent-data lvm2

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 makecache fast
yum install docker-ce -y
systemctl start docker

2.国内远镜像加速配置

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

3.运行第一个容器

运行一个Hello world

docker run alpine /bin/echo "Hello world"
第3章 Docker镜像和容器管理

1.Docker进程相关命令

1.1 启动Docker服务

systemctl start docker

1.2 停止Docker服务

systemctl stop docker

1.3 重启Docker服务

systemctl restart docker

1.4 查看Docker服务状态

systemctl status docker

1.5 开机自启动Docker服务

systemctl enable docker

2 镜像相关命令

2.1 搜索镜像

选择镜像建议:

1.优先选择官方的
2.选择星星多的
# 从网络上查找需要的镜像
docker search 镜像名称

使用curl命令获取镜像版本号:

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

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

2.2 拉取镜像

# 从Docker的仓库下载镜像到本地,镜像名称格式为名称:版本号,如果版本号不指定则是最新的版本。如果不知道镜像版本,可以去Docker Hub搜索对应镜像查看即可。
docker pull 镜像名称

docker pull centos
docker pull busybox
docker pull busybox:1.29

2.3 查看镜像

# 查看本地镜像
docker images
# 查看本地所有镜像
docker images -a
# 查看本地镜像的id
docker images -q

2.4 删除镜像

# 删除镜像 -f表示强制删除
docker rmi [-f] 镜像id[镜像名称]
# 删除所有镜像
docker rmi -f $(docker images -qa)

2.5 导出镜像

docker save -o centos.tar centos:latest
docker save  centos:latest > centos.tar 
docker save  本地镜像:版本 > 导出镜像名称

2.6 导入镜像

docker load -i centos.tar
docker load < centos.tar

2.7 镜像打标签

​ 注意:打完 标签后,要删除镜像,只能通过镜像名删除

docker tag centos:7 centos:7.1

docker tag 本地镜像名/ID centos:7.1

3 容器相关命令

3.1 查看运行的容器

# 查看正在执行的容器
docker ps
# 查看所有的容器
docker ps -a
# 查看所有容器的id号
docker ps -qa

3.2 创建并启动容器

docker run 参数

参数说明:
-i:保持容器运行。通过和-t同时使用。加入-it这两个参数以后,容器创建后会自动进入容器中,退出容器后,容器会自动关闭。
-t:为容器重新分配一个伪输入终端,通常和-i同时使用。
-d:以守护(后台)模式运行容器。创建一个容器在后台运行,需要使用docker exec 进入容器。
-it:创建的容器一般称为交互式容器。
-id:创建的容器一般称为守护式容器、
--name:为创建的容器命名。
-p:映射端口 外部端口:容器内部暴露的端口
docker run --name centos7 -it -d centos:7 /bin/bash

3.3 进入容器

docker exec -it 容器id[容器名称] /bin/bash

3.4 查看容器信息

docker inspect 容器id[容器名称]

3.5 停止容器

docker stop 容器id[容器名称]
批量停止容器
docker stop $(docker ps -q)

3.6 启动容器

docker start 容器id[容器名称]

3.7 重启容器

docker restart 容器id[容器名称]

3.8 强制停止容器

docker kill 容器id[容器名称]

3.9 删除容器

# 需要先停止容器,然后再删除
docker rm 容器id[容器名称]
# 强制删除容器
docker rm -f 容器id[容器名称]
# 强制删除所有容器
docker rm -f $(docker ps -qa)

3.10 查看容器日志

docker logs -f 容器id[容器名称]

3.11 文件传递

docker cp 宿主机文件 容器ID:容器内目录路径    #发送到容器内

docker cp 容器ID:容器内文件 宿主机目录路径    #拉取到宿主机中

3.12 host解析

#link 链接 可以使两个容器之间,通过容器名连接
1.容器命令
docker run --name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123 \
-e MYSQL_DATABASE=zabbix \
-e MYSQL_USER=zabbix \
-e MYSQL_PASSWORD=zabbix \
-v /data/docker_mysql:/var/lib/mysql \
-d mysql:5.7 \
--character-set-server=utf8 --collation-server=utf8_bin

docker run --name zabbix-server-mysql \
--link mysql \
-e DB_SERVER_HOST="mysql" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-p 10051:10051 \
-d zabbix/zabbix-server-mysql


容器一可以通过容器名解析到容器二

4 常用命令

attach    Attach to a running container                 # 当前 shell 下 attach 连接指定运行镜像
build     Build an im from a Docker registry server     # 从当前 Docker registry 退出
logs      Fetch the logs of a container                 # 输出当前容器日志信息
port      Lookup the public-facing port which is NAT-ed to PRIVATE_PORT    # 查看映射端口对应的容器内部源端口
pause     Pause all processes within a container        # 暂停容器
ps        List containers                               # 列出容器列表
pull      Pull an image or a repository from the docker registry server   # 从docker镜像源服务器拉取指定镜像或者库镜像
push      Push an image or a repository to the docker registry server    # 推送指定镜像或者库镜像至docker源服务器
restart   Restart a running container                   # 重启运行的容器
rm        Remove one or more containers                 # 移除一个或者多个容器
rmi       Remove one or more images             # 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]
run       Run a command in a new container              # 创建一个新的容器并运行一个命令
save      Save an image to a tar archive                # 保存一个镜像为一个 tar 包[对应 load]
search    Search for an image on the Docker Hub         # 在 docker hub 中搜索镜像
start     Start a stopped containers                    # 启动容器
stop      Stop a running containers                     # 停止容器
tag       Tag an image into a repository                # 给源中镜像打标签
top       Lookup the running processes of a container   # 查看容器中运行的进程信息
unpause   Unpause a paused container                    # 取消暂停容器
version   Show the docker version information           # 查看 docker 版本号
wait      Block until a container stops, then print its exit code   # 截取容器停止时的退出状态值age from a Dockerfile              # 通过 Dockerfile 定制镜像
commit    Create a new image from a container changes   # 提交当前容器为新的镜像
cp        Copy files/folders from the containers filesystem to the host path   #从容器中拷贝指定文件或者目录到宿主机中
create    Create a new container                        # 创建一个新的容器,同 run,但不启动容器
diff      Inspect changes on a container's filesystem   # 查看 docker 容器变化
events    Get real time events from the server          # 从 docker 服务获取容器实时事件
exec      Run a command in an existing container        # 在已存在的容器上运行命令
export    Stream the contents of a container as a tar archive   # 导出容器的内容流作为一个 tar 归档文件[对应 import ]
history   Show the history of an image                  # 展示一个镜像形成历史
images    List images                                   # 列出系统当前镜像
import    Create a new filesystem image from the contents of a tarball # 从tar包中的内容创建一个新的文件系统映像[对应export]
info      Display system-wide information               # 显示系统相关信息
inspect   Return low-level information on a container   # 查看容器详细信息
kill      Kill a running container                      # kill 指定 docker 容器
load      Load an image from a tar archive              # 从一个 tar 包中加载一个镜像[对应 save]
login     Register or Login to the docker registry server    # 注册或者登陆一个 docker 源服务器
logout    Log out
第4章 Docker网络管理

1.随机映射端口

docker run -P

2.指定映射端口

-p 宿主机端口:容器端口

-p 80:80 -p 443:443
-p 宿主机IP:宿主机端口:容器端口

如果想多个容器使用8080端口,可以通过添加多个IP地址实现

ifconfig eth0:1 10.0.0.13 up
docker run -d -p 10.0.0.11:8080:80 nginx:latest
docker run -d -p 10.0.0.13:8080:80 nginx:latest

进入容器里修改站点目录,然后访问测试

docker exec -it bdb2a4e7e24d /bin/bash
echo "web01" > /usr/share/nginx/html/index.html
docker exec -it 31c1de138dda /bin/bash
echo "web02" > /usr/share/nginx/html/index.html

访问测试:

[root@docker01 ~]# curl 10.0.0.11:8080
web02
[root@docker01 ~]# curl 10.0.0.13:8080
web01
第5章 Docker容器的数据卷--数据映射

1 数据卷

1.1 思考

  • Docker容器删除后,在容器中产生的数据还在吗?

    docker笔记_docker_05

  • Docker容器和外部机器可以直接交换文件吗?

    docker笔记_git_06

  • 容器之间能进行数据交互?

    docker笔记_mysql_07

1.2 数据卷概念

  • 数据卷是宿主机中的一个目录或文件。

  • 当容器目录和数据卷目录绑定后,对方修改会立即同步

  • 一个数据卷可以同时被多个容器同时挂载。

  • 一个容器也可以被挂载多个数据卷。

    docker笔记_docker_08

1.3 数据卷作用

  • 容器数据持久化
  • 外部机器和容器间接通信。
  • 容器之间数据交换

1.4 配置数据卷

1.4.1 命令
docker run ... -v 宿主机目录(文件):容器内目录(文件) ...

注意事项:

①目录必须是绝对路径。

②如果目录不存在,则会自动创建

③可以挂载多个数据卷

1.4.2 应用示例

1.4.2.1 一个容器挂载一个数据卷

docker run -id --name c1 -v /root/data:/root/data_container centos:7

1.4.2.2 两个容器挂载同一个数据卷

docker run -id --name c1 -v /root/data:/root/data_container centos:7
docker run -id --name c2 -v /root/data:/root/data_container centos:7

1.5 数据卷的分类

1.5.1 指定目录挂载
  • 命令:

    # 宿主名目录(文件)的路径为绝对路径
    docker run ... -v 宿主机目录(文件):容器内目录(文件) ...
    
  • 示例:

    docker run -d -v /var/log/nginx:/var/log/nginx/ --name nginx nginx
    
1.5.2 匿名目录挂载
  • 命令:

    # 可以在宿主机的/var/lib/docker/volumes目录中找到容器挂载的目录,但是目录的名称是随机的
    docker run ... -v 容器内目录(文件) ...
    
  • 示例:

    docker run -d -v /var/log/nginx/ --name nginx nginx
    
1.5.3 具名目录挂载
  • 命令:

    #可以在宿主机的/var/lib/docker/volumes目录中找到容器挂载的目录,但是目录的名称是自己指定的
    docker run ... -v 名称:容器内目录(文件) ...
    
  • 示例:

    docker run -d -v nginx80:/var/log/ --name nginx nginx
    

2 数据卷容器

2.1 概念

  • 多容器进行数据交换
    • 多个容器挂载同一个数据卷
    • 数据卷容器

docker笔记_nginx_09

2.2 配置数据卷容器

  • 创建启动c3数据卷容器,使用-v参数设置数据卷

    docker run -id -v /volume --name c3 centos:7
    
  • 创建启动c1、c2容器,使用--volumes-from参数设置数据卷。

    docker run -id --volumes-from c3 --name c1 centos:7
    docker run -id --volumes-from c3 --name c2 centos:7
    
第5章 Docker数据映射

1.映射容器目录

-v 宿主机目录:容器内目录

1.1 创建游戏代码目录

mkdir /data/xiaoniao -p
cd /data/
unzip xiaoniaofeifei.zip  -d xiaoniao /

1.2 创建容器并映射数据目录

docker run -d  -p 80:80 -v /data/xiaoniao:/usr/share/nginx/html nginx:latest
docker ps

1.3 访问游戏页面

10.0.0.11

2.实验-访问不同端口展示不同页面

需求:

访问8080端口,展示xiaoniao首页
访问8090端口,展示shenjingmao的首页

2.1 准备nginx配置文件

[root@docker01 ~]# cat /data/game.conf 
server {
    listen       8080;
    server_name  localhost;
    location / {
        root   /opt/game/;
        index  index.html index.htm;
    }
}

server {
    listen       8090;
    server_name  localhost;
    location / {
        root   /opt/xiaoniao/;
        index  index.html index.htm;
    }
}

2.2 上传代码目录

[root@docker01 /data]# ll 
总用量 18896
drwxr-xr-x 5 root root       73 9月   7 23:03 game
-rw-r--r-- 1 root root      309 9月   7 22:57 game.conf
-rw-r--r-- 1 root root 19248295 8月  28 09:48 html5.zip
drwxr-xr-x 3 root root       92 9月   7 22:15 xiaoniao
-rw-r--r-- 1 root root    91014 9月   7 22:11 xiaoniaofeifei.zip

2.3 创建容器并挂载

需要挂载的内容:

1.nginx配置文件
2.游戏目录

创建容器命令:

docker run  
-p 8080:8080 \
-p 8090:8090 \
-v /data/game:/opt/game \
-v /data/xiaoniao:/opt/xiaoniao \
-v /data/game.conf:/etc/nginx/conf.d/game.conf \
-d nginx:latest   

2.4 访问测试

10.0.0.11:8080
10.0.0.11:8090
第6章 Docker镜像手动构建

1.手动制作游戏镜像

下面我们基于centos容器制作一个新镜像,并安装nginx服务

1.1 启动一个容器并安装nginx

[root@docker01 ~]# docker run -it centos /bin/bash
[root@0ede2760ba65 /]# yum install wget install openssh-clients -y 
[root@0ede2760ba65 /]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@0ede2760ba65 /]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
[root@0ede2760ba65 /]# sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
[root@0ede2760ba65 /]# cat /etc/yum.repos.d/nginx.repo  
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
[root@0ede2760ba65 /]# yum makecache fast
[root@0ede2760ba65 /]# yum install nginx -y

1.2 上传代码目录并配置nginx配置文件

[root@0ede2760ba65 /]# scp -r 10.0.0.11:/data/* /opt/
[root@0ede2760ba65 /]# ll /opt/
total 18896
drwxr-xr-x 5 root root       73 Sep  7 16:02 game
-rw-r--r-- 1 root root      303 Sep  7 16:02 game.conf
-rw-r--r-- 1 root root 19248295 Sep  7 16:02 html5.zip
drwxr-xr-x 3 root root       92 Sep  7 16:02 xiaoniao
-rw-r--r-- 1 root root    91014 Sep  7 16:02 xiaoniaofeifei.zip
[root@0ede2760ba65 /]# cp /opt/game.conf /etc/nginx/conf.d/

1.3 将容器提交为新的镜像

[root@docker01 ~]# docker ps -aq
0ede2760ba65
[root@docker01 ~]# docker commit 0ede2760ba65 game:v1
sha256:a61d28fbfe27ebe36d4b73825b55e5f94097083273ab56dccce0453ce2bd6d38

1.4 测试镜像功能是否可用

[root@docker01 ~]# docker run -d -p 8080:8080 -p 8090:8090 game:v1  nginx -g 'daemon off;'
f58f209d4761c4bdd9bb164c0050a94a3273b1ee0e57eafe29e48b1517c72950

1.5 将新镜像导出

docker save -o game_v1.tar game:v1

2.手动制作云盘镜像

2.1 创建容器

docker run -d -p 80:80 --name clould game:v1  nginx -g 'daemon off;'

2.2 进入容器安装php并求改运行用户

[root@d0c987bcefa2 /]# yum install php-fpm -y
[root@d0c987bcefa2 /]# php-fpm -v
PHP 5.4.16 (fpm-fcgi) (built: Oct 30 2018 19:32:20)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
[root@d0c987bcefa2 /]# sed -i '/^user/c user = nginx' /etc/php-fpm.d/www.conf
[root@d0c987bcefa2 /]# sed -i '/^group/c group = nginx' /etc/php-fpm.d/www.conf
[root@d0c987bcefa2 /]# sed -i '/daemonize/s#no#yes#g' /etc/php-fpm.conf     
[root@d0c987bcefa2 /]# php-fpm -c /etc/php.ini -y /etc/php-fpm.conf
[root@d0c987bcefa2 /]# php-fpm -c /etc/php.ini -y /etc/php-fpm.conf                                   
[root@d0c987bcefa2 /]# ps -ef|grep php
root         77      0  0 21:43 ?        00:00:00 php-fpm: master process (/etc/php-fpm.conf)
nginx        78     77  0 21:43 ?        00:00:00 php-fpm: pool www
nginx        79     77  0 21:43 ?        00:00:00 php-fpm: pool www
nginx        80     77  0 21:43 ?        00:00:00 php-fpm: pool www
nginx        81     77  0 21:43 ?        00:00:00 php-fpm: pool www
nginx        82     77  0 21:43 ?        00:00:00 php-fpm: pool www

2.3 配置nginx

[root@d0c987bcefa2 /]# cat /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;
    }
}
[root@d0c987bcefa2 /]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@d0c987bcefa2 /]# nginx -s reload

2.4 下载代码目录

[root@d0c987bcefa2 /]# mkdir /code
[root@d0c987bcefa2 /]# cd /code/
[root@d0c987bcefa2 code]# scp -r 10.0.0.11:/data/kod/* /code/
[root@d0c987bcefa2 code]# ls
ChangeLog.md  README.MD  app  config  data  index.php  plugins  static
[root@d0c987bcefa2 code]# chown -R nginx:nginx /code/

2.5 测试

[root@d0c987bcefa2 code]# curl -I 127.0.0.1
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.16.1
Date: Sat, 07 Sep 2019 21:53:17 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
X-Powered-By: PHP/5.4.16
Set-Cookie: KOD_SESSION_ID_9d6d9=ljq63o0tmcscon6eb3gdpqscf4; path=/
Set-Cookie: KOD_SESSION_ID_9d6d9=ljq63o0tmcscon6eb3gdpqscf4; path=/
Set-Cookie: KOD_SESSION_ID_9d6d9=ljq63o0tmcscon6eb3gdpqscf4; path=/
Set-Cookie: KOD_SESSION_SSO=bboh1p0h1uc50tfibrg67dnra7; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: KOD_SESSION_ID_9d6d9=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/
Set-Cookie: kod_name=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT
Set-Cookie: kodToken=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT
Set-Cookie: X-CSRF-TOKEN=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT
Location: ./index.php?user/login

2.6 提交新的镜像

[root@docker01 ~]# docker commit d0c987bcefa2 kod:v1
sha256:169df6e8db11bd044e3e05237f2947783f9cc7a65b643dc9206ecf05fdc4a3ea

2.7 编写启动脚本并提交新镜像

[root@docker01 ~]# docker exec -it c14835183fb5 /bin/bash
[root@c14835183fb5 /]# cat init.sh     
#!/bin/bash
php-fpm -c /etc/php.ini -y /etc/php-fpm.conf
nginx -g 'daemon off;'
[root@c14835183fb5 /]# chmod +x init.sh 
[root@docker01 ~]# docker commit c14835183fb5 kod:v2
sha256:c05ebdf400aa7f7a27aa857df0d9c75c42943db89abca66f79101771db8e9585

2.8 启动测试

[root@docker01 ~]# docker stop $(docker ps -qa)
[root@docker01 ~]# docker run -d -p 80:80 kod:v2 /bin/bash /init.sh
dccf4aea5471713872e4fefaca45f7fac3bffec8f5f602570863ed14231dea1a
[root@docker01 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                            NAMES
dccf4aea5471        kod:v2              "/bin/bash /init.sh"     36 seconds ago      Up 35 seconds       0.0.0.0:80->80/tcp                               magical_napier

2.9 添加GD库

此时打开页面提示缺少GD库,进入容器内安装php支持插件
[root@dccf4aea5471 /]yum install php-mbstring php-gd -y
然后重启容器
[root@docker01 ~]# docker restart dccf4aea5471

2.10 访问测试没问题后提交新镜像

[root@docker01 ~]# docker commit dccf4aea5471 kod:v2
sha256:23051ce545a2eb6bb50bb2307bd9cfbaf6139e52f205a4126fb1d8d974c417f4
第7章 Dockerfile自动构建Docker镜像

1.Dockerfile操作命令说明

Docker通过对于在Dockerfile中的一系列指令的顺序解析实现自动的image的构建
  通过使用build命令,根据Dockerfiel的描述来构建镜像
  通过源代码路径的方式
  通过标准输入流的方式
Dockerfile指令:
  只支持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指令

构建思路流程:

1.先不要着急写Dockerfile,首先手动进入容器,然后正常执行安装步骤。并确保运行正常
2.收集好安装步骤的命令以及正确的配置文件
3.将收集的配置文件按照一定规范保存在相应的目录下
4.根据收集到的安装步骤编写Dockerfile
5.构建镜像并启动测试

2.基于Dockerfile制作nginx镜像

1.创建目录
[root@docker-11 ~]# mkdir dockerfile
[root@docker-11 ~]# cd dockerfile/
[root@docker-11 ~/dockerfile]# mkdir nginx_base
[root@docker-11 ~/dockerfile]# cd nginx_base/

2.准备文件
[root@docker-11 ~/dockerfile/nginx_base]# cat > local.repo << 'EOF'
[local]
name=local
enable=1
gpgcheck=0
baseurl=http://10.0.0.100
EOF
[root@docker-11 ~/dockerfile/nginx_base]# ll
total 8
-rw-r--r-- 1 root root 292 Jul 22 15:01 Dockerfile
-rw-r--r-- 1 root root  65 Jul 22 15:47 local.repo

3.编写Dockerfile
[root@docker-11 ~/dockerfile/nginx_base]# cat > Dockerfile << 'EOF'
FROM centos:7
RUN rm -rf /etc/yum.repos.d/*
ADD local.repo /etc/yum.repos.d/local.repo
RUN yum makecache fast
RUN yum install nginx -y
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
EOF

4.构建镜像
[root@docker-11 ~/dockerfile/nginx_base]# cat build.sh 
#!/bin/bash
docker build -t centos7_nginx:1.20 .
[root@docker-11 ~/dockerfile/nginx_base]# bash build.sh 

5.启动测试
[root@docker-11 ~/dockerfile/nginx_base]# docker run -d -p 10.0.0.11:80:80 centos7_nginx:1.20
[root@docker-11 ~/dockerfile/nginx_base]# curl -I 10.0.0.11

3.Dockerfile分段构建的最佳实践

避免安装不必要的软件包

只安装容器必须的软件,不是必须要的不要安装,比如一些工具类的命令,wget net-tools等

安装完成后清除缓存

安装完成后我们可以把不用的压缩包以及软件缓存等文件删除掉,以减少镜像的体积

一个容器内不要跑太多的应用

Docker倡导一个容器应该只关注一件事,应该保证一个容器只有一个进程。
但是这也不是硬性要求,比如nginx+php+mysql的应用,那么我们也可以将nginx+php放在一个容器里,mysql单独放一个容器。
但是我们还是希望一个容器专注干一件事,尽量保持干净和模块化。

最小化镜像层数

Dockerfile里每条RUN,COPY,ADD指令都会创建指令层,所以我们可以将多条RUN命令尽可能的合并成一个RUN指令,这样就减少了构建镜像的层数。

增加可读性

我们刚才说了可以讲多个RUN指令合并成一个RUN指令,但是这样做可能会导致RUN指令很长很长,那么我们可以像shell命令那样使用\来换行,增加可读性,例如:
RUN yum install git \
    wget \
    net-tools \
    tree

4.私有仓库的构建

1.创建第二IP
ifconfig eth0:1 10.0.0.100 up

2.创建目录准备配置文件
mkdir /data/yum/ -p
cat >/data/yum/yum.conf <<'EOF'
server {
    listen       80;
    server_name  localhost;
    location / {
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
        autoindex_format html;
        charset utf-8,gbk;
        root   /data/yum;
        index  index.html index.htm;
    }
}
EOF

1.使用第二个IP启动容器
docker run -d \
-p 10.0.0.100:80:80 \
-v /data/yum/yum.conf:/etc/nginx/conf.d/yum.conf \
-v /data/yum:/data/yum \
nginx:latest

2.在容器里配置源缓存
[root@docker-11 ~]# docker exec -it $(docker ps |grep nginx|awk '{print $1}') /bin/bash
root@a0bcaa499211:/# rm -rf /etc/nginx/conf.d/default.conf
root@a0bcaa499211:/# exit
[root@docker-11 ~]# docker restart $(docker ps |grep nginx|awk '{print $1}')

3.启动centos7容器
[root@docker-11 ~]# docker run -it centos:7 /bin/bash 
[root@d3625c77ea89 ~]# cd /etc/yum.repos.d/
[root@d3625c77ea89 yum.repos.d]# rm -rf *

4.将repo文件发送到容器里
[root@docker-11 ~]# docker cp repos d3625c77ea89:/etc/yum.repos.d/

5.容器内查看
[root@d3625c77ea89 yum.repos.d]# ll
total 12
-rw-r--r-- 1 root root 1712 Jul 22 02:46 CentOS-Base.repo
-rw-r--r-- 1 root root  652 Jul 22 02:48 epel.repo
-rw-r--r-- 1 root root  398 Jul 22 02:49 nginx.repo

6.容器内修改yum配置文件
[root@d3625c77ea89 yum.repos.d]# vi /etc/yum.conf 
keepcache=1

7.容器更新缓存并安装软件
[root@d3625c77ea89 ~]# yum makecache fast
[root@d3625c77ea89 ~]# yum install nginx php-fpm net-tools wget git vim supervisor java -y

8.将rpm文件复制到宿主机
[root@d3625c77ea89 ~]# mkdir rpm
[root@d3625c77ea89 ~]# cd rpm
[root@d3625c77ea89 rpm]# find / -type f -name "*.rpm"|xargs mv -t /root/rpm/
[root@d3625c77ea89 rpm]# ll |wc -l
138

#宿主机操作
[root@docker-11 ~]# cd /data/yum/
[root@docker-11 /data/yum]# docker cp d3625c77ea89:/root/rpm/ .
[root@docker-11 /data/yum]# mv rpm/* .

9.更新私有仓库yum源
[root@docker-11 /data/yum]# yum install nginx createrepo -y
[root@docker-11 /data/yum]# createrepo /data/yum

5.使用Dockerfile创建云盘镜像

基于Dockerfile构建云盘镜像

1.先创建目录
[root@docker-11 ~]# cd dockerfile/
[root@docker-11 ~/dockerfile]# ls
nginx_base
[root@docker-11 ~/dockerfile]# mkdir kod
[root@docker-11 ~/dockerfile]# cd kod/
[root@docker-11 ~/dockerfile/kod]# 

2.收集配置文件
mkdir conf
cd conf
cat > local.repo << EOF
[local]
name=local
enable=1
gpgcheck=0
baseurl=http://10.0.0.100
EOF
docker cp b7757c17bf36:/etc/php-fpm.d/www.conf  .
docker cp b7757c17bf36:/etc/nginx/conf.d/cloud.conf  .
docker cp b7757c17bf36:/etc/supervisord.conf  .
docker cp b7757c17bf36:/etc/supervisord.d/nginx_php.ini  .

3.准备代码目录
mkdir code/
cd code
docker cp b7757c17bf36:/code/ .
tar zcvf code.tar.gz code

4.编写Dockerfile
FROM centos:7
RUN rm -rf /etc/yum.repos.d/*
ADD conf/local.repo /etc/yum.repos.d/local.repo
RUN yum install nginx php-fpm php-mbstring php-gd supervisor -y
ADD conf/www.conf /etc/php-fpm.d/www.conf
ADD conf/cloud.conf /etc/nginx/conf.d/cloud.conf
ADD conf/supervisord.conf /etc/supervisord.conf
ADD conf/nginx_php.ini /etc/supervisord.d/nginx_php.ini
ADD code/code.tar.gz /
RUN chown -R nginx:nginx /code/
EXPOSE 80
CMD ["supervisord","-c","/etc/supervisord.conf"]

5.构建镜像
docker build -t kod:v2 .

6.启动容器测试
docker run -d --name kod_v1 -p 8080:80 kod:v1 

6.使用Dockerfile创建wordpress博客镜像

#注意数据库的数据
#注意执行的顺序

7.使用Dockerfile创建KVM图形化管理工具镜像


supervisor的控制多个进程使用

1.安装软件
yum -y install supervisor

2.编写进程配置文件
[root@b7757c17bf36 ~]# cat /etc/supervisord.d/nginx_php.ini 
[program:nginx]
command=nginx -g 'daemon off;'
autostart=true
startsecs = 5
redirect_stderr = true
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 20
stdout_logfile = /var/log/supervisor/nginx.log

[program:php-fpm]
command=php-fpm -c /etc/php.ini -y /etc/php-fpm.conf
autostart=true
startsecs = 5
redirect_stderr = true
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 20
stdout_logfile = /var/log/supervisor/php-fpm.log

3.修改supervisord配置文件放在前台启动
sed -i "s#nodaemon=false#nodaemon=true#g" /etc/supervisord.conf

4.启动supervisord程序
supervisord -c /etc/supervisord.conf 

5.使用命令
supervisorctl update
supervisorctl status
supervisorctl start nginx
supervisorctl restart nginx
supervisorctl stop nginx

7.构建Tomcat镜像

过程思路

先搭建基础镜像
搭建有JDK的镜像
一层一层的搭建,有微服务的项目,只需要jdk镜像即可

jpress.war项目
Dockerfile
-------------------------------------------------
FROM tomcat_jdk8:8.5
ADD jpress.war /opt/tomcat/webapps/jpress.war
CMD ["/opt/tomcat/bin/catalina.sh","run"]
-------------------------------------------------

halo.jar项目
Dockerfile
-------------------------------------------------
FROM openjdk:latest
ADD halo.jar /opt/halo.jar
CMD ["java","-jar","/opt/halo.jar"]
-------------------------------------------------


docker笔记_git_10

7.1 构建基础CentOS7镜像

#1.基础镜像需要的操作
安装网络工具包
配置yum源
更改时区

#2.创建目录
mkdir centos7
cd centos7/

#3.准备配置文件
[root@docker-11 centos7]# ll
总用量 16
-rw-r--r-- 1 root root 1759 7月  22 21:02 CentOS-Base.repo
-rw-r--r-- 1 root root  664 7月  22 21:02 epel.repo

#4.编写dockerfile
FROM centos:7
RUN rm -f /etc/yum.repos.d/*
ADD CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo
ADD epel.repo /etc/yum.repos.d/epel.repo
ADD supervisord.conf /etc/supervisord.conf
RUN yum install net-tools bash-completion supervisor -y \
    && yum clean all \
    && rm -f /etc/localtime \
    && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && groupadd -g 1000 www \
    && useradd -u 1000 -g 1000 www -M -s /sbin/nologin
    
#5.构建命令
docker build -t centos7_base:v1 .

7.2 构建基础JDK镜像

#1.创建目录
mkdir dockerfile/jdk/

#2.准备配置文件
[root@docker-11 ~]# cd dockerfile/jdk/
[root@docker-11 jdk]# docker cp 28e7ff621f8c:/etc/profile .
[root@docker-11 jdk]# vim profile 
[root@docker-11 jdk]# tail -4 dockerfile/jdk/profile  
export JAVA_HOME=/opt/jdk
export TOMCAT_HOME=/opt/tomcat
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$TOMCAT_HOME/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar

#3.将jdk上传到指定目录
[root@docker-11 ~]# tree dockerfile/
dockerfile/
└── jdk
    ├── jdk-8u60-linux-x64.tar.gz
    └── profile

#4.编写Dockerfile
[root@docker-11 jdk]# cat Dockerfile 
FROM centos7_base:v1
ADD jdk-8u60-linux-x64.tar.gz /opt/ 
ADD profile /etc/profile
RUN ln -s /opt/jdk1.8.0_60 /opt/jdk
ENV JAVA_HOME /opt/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin

#5.编写构建命令脚本
[root@docker-11 jdk]#  cat > /root/dockerfile/jdk/build.sh << 'EOF' 
#!/bin/bash
docker build -t centos7_jdk:8u60 .
EOF
[root@docker-11 jdk]# bash build.sh 

#6.查看构建后的镜像
[root@docker-11 jdk]# docker images|grep jdk
centos7_jdk   8u60      58a880ff9253   19 seconds ago   569MB

#7.使用jdk镜像启动容器测试
[root@docker-11 jdk]# docker run -it --rm centos7_jdk:8u60 java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

7.3 构建Tomcat镜像

#1.创建目录
[root@docker-11 ~]# mkdir dockerfile/tomcat

#2.上传压缩包
[root@docker-11 ~]# cd dockerfile/tomcat
[root@docker-11 tomcat]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.69/bin/apache-tomcat-8.5.69.tar.gz

#3.编写Dockerfile
[root@docker-11 tomcat]# cat > Dockerfile << 'EOF'
FROM centos7_jdk:8u60
ADD apache-tomcat-8.5.69.tar.gz /opt/
RUN ln -s /opt/apache-tomcat-8.5.69 /opt/tomcat
EOF

#4.编写构建命令脚本
[root@docker-11 jdk]#  cat > /root/dockerfile/jdk/build.sh << 'EOF' 
#!/bin/bash
docker build -t tomcat_base:8.5.69 .
EOF
[root@docker-11 tomcat]# tree
.
├── apache-tomcat-8.5.69.tar.gz
├── build.sh
└── Dockerfile

#5.构建镜像
[root@docker-11 tomcat]# bash build.sh 

#6.测试访问
[root@docker-11 tomcat]# docker run -d -it tomcat_base:8.5.69 /bin/bash
[root@docker-11 tomcat]# docker exec -it b2011b0b3eb3 /bin/bash
[root@b2011b0b3eb3 /]# /opt/tomcat/bin/catalina.sh start

7.4 构建业务镜像

#1.创建目录
[root@docker-11 ~]# mkdir dockerfile/webapp1

#2.编写业务文件
[root@docker-11 ~]# cd dockerfile/webapp1
[root@docker-11 webapp1]# mkdir app
[root@docker-11 webapp1]# echo "V1" > app/index.jsp
[root@docker-11 webapp1]# tar zcf app.tar.gz app/

#3.修改tomcat配置文件
[root@docker-11 webapp1]# docker cp b2011b0b3eb3:/opt/tomcat/conf/server.xml .
[root@docker-11 webapp1]# vim server.xml
 <Host name="localhost"  appBase="/opt/tomcat/webapps"

#4.编写supervisor配置文件
[root@docker-11 webapp1]# cat tomcat.ini 
[program:tomcat]
command=/opt/tomcat/bin/catalina.sh run
autostart=true
autorestart=true
startsecs = 5
redirect_stderr = true
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 20
stdout_logfile = /var/log/supervisor/tomcat.log

#5.编写Dockerfile文件
[root@docker-11 webapp1]# cat Dockerfile 
FROM tomcat_base:8.5.69
ADD tomcat.ini /etc/supervisord.d/tomcat.ini
ADD server.xml /opt/tomcat/conf/server.xml
ADD app.tar.gz /opt/tomcat/webapps/
EXPOSE 8080
CMD ["supervisord","-c","/etc/supervisord.conf"]

#6.编写构建脚本
[root@docker-11 webapp1]# cat > build.sh << 'EOF'
#!/bin/bash
docker build -t tomcat_app:v1 .
EOF

#7.运行容器测试
docker run -d -it -p 8080:8080 tomcat_app:v1
使用官方镜像搭建zabbix服务端
zabbix容器化

1.容器命令
docker run --name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123 \
-e MYSQL_DATABASE=zabbix \
-e MYSQL_USER=zabbix \
-e MYSQL_PASSWORD=zabbix \
-v /data/docker_mysql:/var/lib/mysql \
-d mysql:5.7 \
--character-set-server=utf8 --collation-server=utf8_bin

docker run --name zabbix-server-mysql \
--link mysql \
-e DB_SERVER_HOST="mysql" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-p 10051:10051 \
-d zabbix/zabbix-server-mysql

docker run --name zabbix-web-nginx-mysql \
--link mysql \
--link zabbix-server-mysql \
-e DB_SERVER_HOST="mysql" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e ZBX_SERVER_HOST="zabbix-server-mysql" \
-e PHP_TZ="Asia/Shanghai" \
-p 80:8080 \
-d zabbix/zabbix-web-nginx-mysql

===================================================

2.注释
docker run \
#mysql服务
--name mysql \

#映射端口 宿主机端口:容器内端口	
-p 3306:3306 \	

#启动Mysql初始化的时候设置root的密码			
-e MYSQL_ROOT_PASSWORD=123 \

#初始化时创建的数据库名称		
-e MYSQL_DATABASE=zabbix \

#初始化时创建的的普通用户,此用户对刚才创建的数据库拥有所有权限			
-e MYSQL_USER=zabbix \	

#普通用户的密码			
-e MYSQL_PASSWORD=zabbix \			

#将容器内的数据持久化到宿主机,如果已经有数据了,用户传递的变量就失效了
-v /data/docker_mysql:/var/lib/mysql \	

#后台启动,使用镜像名称
-d mysql:5.7 \

#设置数据库的字符集
--character-set-server=utf8 --collation-server=utf8_bin

--------------------------------------------------------------------
docker run \
#给zabbix服务端容器起个名字
--name zabbix-server-mysql \

#连接到mysql容器,连接后可以直接使用容器名进行通讯
--link mysql \

#后端mysql的连接地址,这里因为Link了mysql容器,所以可以直接使用容器名通讯
-e DB_SERVER_HOST="mysql" \

#告诉zabbix-server连接mysql使用什么用户
-e MYSQL_USER="zabbix" \

#告诉zabbix-server连接mysql的用户的密码
-e MYSQL_PASSWORD="zabbix" \

#将zabbix-server的服务端口暴露出来,方便客户端连接
-p 10051:10051 \

#使用镜像名称
-d zabbix/zabbix-server-mysql

--------------------------------------------------------------------

docker run \
--name zabbix-web-nginx-mysql \
--link mysql \
--link zabbix-server-mysql \

#连接数据库的地址,因为link了mysql容器,所以可以直接使用容器名通讯
-e DB_SERVER_HOST="mysql" \

#mysql连接的用户
-e MYSQL_USER="zabbix" \

#mysql连接的用户密码
-e MYSQL_PASSWORD="zabbix" \

#zabbix-server的地址,因为link了zabbix-server的容器,所以可以直接使用容器名通讯
-e ZBX_SERVER_HOST="zabbix-server-mysql" \

#修改php的时区为上海
-e PHP_TZ="Asia/Shanghai" \

#映射web网页端口,通过查看镜像信息得知容器内是8080
-p 80:8080 \

#镜像名称
-d zabbix/zabbix-web-nginx-mysql

第8章 企业级私有仓库Docker-harbor

1.部署步骤

第一步:安装docker和docker-compose
第二步:下载harbor-offline-installer-v1.9.0-rc1.tgz
第三步:上传到/opt,并解压
第四步:修改harbor.yml配置文件 hostname = 10.0.0.11 harbor_admin_password = 123456
第五步:执行install.sh

2.安装docker-compose

1.安装docker-compose

yum install -y docker-compose

2.检查

docker-compose version

3.上传解压docker-harbor

[root@docker01 ~]# cd /opt/
[root@docker01 /opt]# ls
harbor-offline-installer-v1.9.0-rc1.tgz
[root@docker01 /opt]# tar zxf harbor-offline-installer-v1.9.0-rc1.tgz 
[root@docker01 /opt]# ls
harbor  harbor-offline-installer-v1.9.0-rc1.tgz
[root@docker01 /opt]# cd harbor/

4.修改配置文件

修改2个地方:

[root@docker01 /opt/harbor]# egrep "10.0.0.11|123456" harbor.yml 
hostname: 10.0.0.11
harbor_admin_password: 123456

5.安装

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

6.修改docker信任仓库

[root@docker01 /opt/harbor]# cat /etc/docker/daemon.json    
{
      "registry-mirrors": ["https://ig2l319y.mirror.aliyuncs.com"],
      "insecure-registries": ["http://10.0.0.11"] 
}

7.重启docker

systemctl restart docker  

#如果启动不了就用
docker start $(docker ps -qa)

8.给镜像打标签并提交到harbor

docker登陆harbor

[root@docker01 /opt/harbor]# docker login 10.0.0.11           
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@docker01 ~]# docker run -d -p 8080:80 centos_kod:v1          
78be80f7c2029b68e8943e38fa99131ec6709f798e63c94afb5a7fdfa4a8047c

查看容器ID:

[root@docker01 ~]# docker ps|grep kod
78be80f7c202        centos_kod:v1                                       "/bin/bash /init.sh"     15 seconds ago      Up 13 seconds            0.0.0.0:8080->80/tcp        tender_dirac

将容器提交为新镜像并且更改为harbor仓库的地址

[root@docker01 ~]# docker commit 78be80f7c202 10.0.0.11/linux/centos_kod:v1
sha256:6bf1e1eef1969bcd4c82472aed945d4dda74a923c0d7dae91e38539676f8c240

查看镜像

[root@docker01 ~/dockerfile/kod]# docker images
REPOSITORY                      TAG                        IMAGE ID            CREATED             SIZE
10.0.0.11/linux/centos_kod      v1                         6bf1e1eef196        13 minutes ago      465MB

将新镜像推送到harbor上

[root@docker01 /opt/harbor]# docker push 10.0.0.11/linux/centos_kod:v1

9.在docker-harbor上查看

10.0.0.11
账号:admin
密码:123456

10.其他主机上下载镜像

配置docker信任仓库

[root@docker02 ~]# cat /etc/docker/daemon.json 
{
      "insecure-registries": ["http://10.0.0.11"],
      "insecure-registries": ["https://10.0.0.11"] 
}

从Harbor仓库拉取镜像

[root@docker02 ~]# docker pull 10.0.0.11/linux/centos_kod:v1
第9章 Docker容器编排工具

1.docker-compose介绍

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

Compose 使用的三个步骤:

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

官方版本说明:

 https://docs.docker.com/compose/compose-file/compose-versioning/

2.安装docker-compose

方法1:直接yum安装

yum install docker-compose

方法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
chmod +x /usr/local/bin/docker-compose
docker-compose --version

3.docker-compose命令格式

build 			#构建镜像
bundle 			#从当前docker compose 文件生成一个以<当前目录>为名称的json格式的Docker
Bundle 			#备 份文件
config -q 		#查看当前配置,没有错误不输出任何信息
create 			#创建服务,较少使用
down 			#停止和删除所有容器、网络、镜像和卷
events 			#从容器接收实时事件,可以指定json 日志格式,较少使用
exec 			#进入指定容器进行操作
help 			#显示帮助细信息
images 			#显示镜像信息
kill			#强制终止运行中的容器
logs 			#查看容器的日志
pause 			#暂停服务
port 			#查看端口
ps 				#列出容器
pull 			#重新拉取镜像,镜像发生变化后,需要重新拉取镜像,较少使用
push 			#上传镜像
restart 		#重启服务
rm 			    #删除已经停止的服务
run 			#一次性运行容器
scale 			#设置指定服务运行的容器个数
start 			#启动服务
stop 			#停止服务
top 			#显示容器运行状态
unpause 		#取消暂定
up 				#创建并启动容器

4.docker-compose语法介绍

官方英文参考文档:

https://github.com/compose-spec/compose-spec/blob/master/spec.md

菜鸟教程翻译文档:

https://www.runoob.com/docker/docker-compose.html

5.docker-compose模板案例

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

6.使用docker-compose部署zabbix

官方文档:

https://www.zabbix.com/documentation/5.0/zh/manual/installation/containers

docker-compose文件:

version: '3'
services:
  mysql:
    image: mysql:5.7
    container_name: mysql
    user: 2000:2000
    environment:
      - "MYSQL_ROOT_PASSWORD=123"
      - "MYSQL_DATABASE=zabbix"
      - "MYSQL_USER=zabbix"
      - "MYSQL_PASSWORD=zabbix"
    volumes:
      - "/data/docker_mysql:/var/lib/mysql"
    ports:
      - "3306:3306"
    command:
      --character-set-server=utf8 
      --collation-server=utf8_bin
          
  zabbix-server-mysql:
    image: zabbix/zabbix-server-mysql
    container_name: zabbix-server-mysql
    environment:
      - "DB_SERVER_HOST=mysql"
      - "MYSQL_USER=zabbix"
      - "MYSQL_PASSWORD=zabbix"
    ports:
      - "10051:10051"
    links:
      - mysql 
          
  zabbix-web-nginx-mysql:
    image: zabbix/zabbix-web-nginx-mysql
    container_name: zabbix-web-nginx-mysql
    environment:
      - "DB_SERVER_HOST=mysql"
      - "MYSQL_USER=zabbix"
      - "MYSQL_PASSWORD=zabbix"
      - "ZBX_SERVER_HOST=zabbix-server-mysql"
      - "PHP_TZ=Asia/Shanghai"
    ports:
      - "80:8080"
    links:
      - mysql
      - zabbix-server-mysql

7.使用自定义网段

#创建网段
docker network create -d bridge --subnet 192.168.200.0/24 --gateway 192.168.200.1 zabbix-net

#docker-compose文件
version: '3'
services:
  mysql:
    image: mysql:5.7
    container_name: mysql
	user: 2000:2000
    environment:
      - "MYSQL_ROOT_PASSWORD=123"
      - "MYSQL_DATABASE=zabbix"
	  - "MYSQL_USER=zabbix"
	  - "MYSQL_PASSWORD=zabbix"
    volumes:
      - "/data/docker_mysql:/var/lib/mysql"
    ports:
      - "3306:3306"
    command:
      --character-set-server=utf8 
      --collation-server=utf8_bin
	networks:
      - zabbix-net 
	 
  zabbix-server-mysql:
    image: zabbix/zabbix-server-mysql
    container_name: zabbix-server-mysql
    environment:
      - "DB_SERVER_HOST=mysql"
      - "MYSQL_USER=zabbix"
      - "MYSQL_PASSWORD=zabbix"
    ports:
      - "10051:10051"
    depends_on:
      - mysql
	networks:
      - zabbix-net 
	  
  zabbix-web-nginx-mysql:
    image: zabbix/zabbix-web-nginx-mysql
    container_name: zabbix-web-nginx-mysql
    environment:
      - "DB_SERVER_HOST=mysql"
      - "MYSQL_USER=zabbix"
      - "MYSQL_PASSWORD=zabbix"
      - "ZBX_SERVER_HOST=zabbix-server-mysql"
      - "PHP_TZ=Asia/Shanghai"
    ports:
      - "80:8080"
	networks:
      - zabbix-net 
	  
networks:
  default:
    external: true
    name: zabbix-net

8.使用docker-compose部署wordpress

version: '3'
services:
  mysql:
    image: mysql:5.7
    container_name: mysql
	user: 2000:2000
    environment:
      - "MYSQL_ROOT_PASSWORD=123"
      - "MYSQL_DATABASE=wordpress"
	  - "MYSQL_USER=wordpress"
	  - "MYSQL_PASSWORD=wordpress"
    volumes:
      - "/data/wordpress:/var/lib/mysql"
    ports:
      - "3306:3306"
    command:
      --character-set-server=utf8 
      --collation-server=utf8_bin
	  
  nginx_php:
    image: nginx_php:v1
    container_name: nginx_php
    ports:
      - "80:80"
	  
networks:
  default:
    external: true
    name: wordpress	  

6.使用docker-compose部署EBK

version: '2.2'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.13.4
    container_name: es01
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es02
      - cluster.initial_master_nodes=es01,es02
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - /data/es_01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - elastic
  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.13.4
    container_name: es02
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01
      - cluster.initial_master_nodes=es01,es02
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - /data/es_02:/usr/share/elasticsearch/data
    networks:
      - elastic

  kibana:
    image: docker.elastic.co/kibana/kibana:7.13.4
    container_name: kibana 
    environment:
      SERVER_NAME: 10.0.0.12
      ELASTICSEARCH_HOSTS: http://es01
    ports:
      - 5601:5601
    networks:
      - elastic

networks:
  elastic:
    driver: bridge

9.使用docker-compose部署gitlab

version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    restart: always
    hostname: 'gitlab.example.com'
	container_name: gitlab 
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://10.0.0.11'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
	    alertmanager['enable'] = false
        grafana['enable'] = false
        prometheus['enable'] = false
        node_exporter['enable'] = false
        redis_exporter['enable'] = false
        postgres_exporter['enable'] = false
        pgbouncer_exporter['enable'] = false
        gitlab_exporter['enable'] = false
    ports:
      - '9090:80'
      - '2222:22'
    volumes:
      - '/data/gitlab/config:/etc/gitlab'
      - '/data/gitlab/logs:/var/log/gitlab'
      - '/data/gitlab/data:/var/opt/gitlab'

10.docker-compose部署jenkins

version: '3'
services:
  jenkins:
    image: 'jenkins/jenkins:latest'
    container_name: jenkins 
    restart: always
    privileged: true
    user: root
    ports:
      - '8080:8080'
      - '50000:50000'
    volumes:
      - '/data/jenkins:/var/jenkins_home'
      - '/var/run/docker.sock:/var/run/docker.sock'
      - '/usr/bin/docker:/usr/bin/docker'
      - '/root/.ssh:/root/.ssh'
      - '/root/.docker/:/root/.docker/'
第10章 Docker网络模式

1.Docker网络的四种模式

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

查看网络模式命令:

[root@node-51 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
3791e4fc9c18        bridge              bridge              local
b494337929ef        host                host                local
a153ac0003e3        none                null                local

查看网卡命令:

[root@node-51 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:11:6b:18 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe11:6b18/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:bb:96:63:c7 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

查看桥接网卡命令

yum install bridge-utils -y
brctl show

2.Bridge模式

2.1 Bridge模式介绍

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

网络模式特点:

1.同一宿主机的容器之间可以互相通信,不同宿主机之间不能互相通信
2.桥接模式的容器可以自动获取172.17.0.0/16网段的IP地址
3.其他机器不能直接访问容器,可以通过映射端口的形式访问
4.每个容器映射到宿主机的端口不能重复
5.容器可以借助宿主机的网络访问其他机器

2.2 Bridge模式示意图:

docker笔记_nginx_11

2.3 查看Bridge的详细信息

查看桥接模式的详细信息:

[root@docker-11 ~]# docker network inspect bridge

容器内查看:

[root@docker-11 ~]# docker run -it busybox /bin/sh
/ # cd
~ # 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
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
	link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff
	inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0
	valid_lft forever preferred_lft forever
	
~ #
~ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0

~ # ping 10.0.0.12 -c 1
PING 10.0.0.12 (10.0.0.12): 56 data bytes
64 bytes from 10.0.0.12: seq=0 ttl=63 time=0.471 ms

--- 10.0.0.12 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.471/0.471/0.471 ms

~ # traceroute 10.0.0.12
traceroute to 10.0.0.12 (10.0.0.12), 30 hops max, 46 byte packets
1 172.17.0.1 (172.17.0.1) 0.010 ms 0.005 ms 0.005 ms
2 10.0.0.12 (10.0.0.12) 0.257 ms 0.246 ms 0.192 ms

2.4 修改桥接模式默认的网络配置

方法1:修改systemd文件添加bip参数

[root@docker-11 ~]# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --
containerd=/run/containerd/containerd.sock --bip=192.168.1.1/24

[root@docker-11 ~]# systemctl daemon-reload
[root@docker-11 ~]# systemctl restart docker.service
[root@docker-11 ~]# ip a

[root@docker-11 ~]# docker run -it busybox /bin/sh
/ # ip a

方法2:修改daemon.json文件

[root@docker-11 ~]# cat /etc/docker/daemon.json
{
"bip": "192.168.2.1/24",
"registry-mirrors": ["https://ig2l319y.mirror.aliyuncs.com"]
}

3.Host模式

3.1 Host模式说明

1.Host模式启动的容器不会虚拟出自己的网卡和IP,而是使用宿主机的IP和端口。
2.但是其他的资源比如文件系统和进程列表还是和宿主机隔离的。
3.启动容器需要使用指定的参数 --network host
4.Host模式不支持端口映射
5.因为直接使用宿主机的网络资源,所以性能较好

3.2 Host模式示意图

docker笔记_git_12

3.3 Host模式演示

#查看当前宿主机的端口和容器运行情况
[root@docker-11 ~]# netstat -lntup|grep 80
[root@docker-11 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

#运行一个nginx容器
[root@docker-11 ~]# docker run -d --network host nginx
f6f44b316317f1727d648801836653866fe25f2ad8c24bf6fe9e7e2e8ee1b6ea
[root@docker-11 ~]# docker ps
CONTAINER ID IMAGE 	COMMAND CREATED STATUS PORTS NAMES
f6f44b316317 nginx "/docker-entrypoint.…" 5 seconds ago Up 4 seconds charming_blackwell


#再次查看宿主机端口情况
[root@docker-11 ~]# netstat -lntup|grep 80

#进入容器后配置源信息
[root@docker-11 ~]# docker exec -it f6f44b316317 /bin/bash
root@docker-11:/# cat >/etc/apt/sources.list << 'EOF'
> deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free
> deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free
> deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free
> deb https://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free
> EOF

root@docker-11:/# apt update

#在容器内安装网络命令
root@docker-11:/# apt install iproute2 net-tools -y

#查看网络信息
root@docker-11:/# ifconfig

3.4 Host模式注意

不能端口映射

host模式下端口不能重复.如果再次启动相同端口的虚拟机就会失败

  • #启动多个host模式的容器
  • #查看容器发现并没有启动成功
  • #通过查看失败的容器日志发现是端口冲突了

4.Container模式

4.1 Container模式说明

1.Container模式创建的容器不会创建自己的网卡和IP,而是和一个已经存在的容器共享同一个网络空间
2.Container模式的容器和宿主机网络空间互相隔离。

4.2 Container模式示意图

docker笔记_docker_13

4.3 Container模式演示

#运行第一个容器没有nginx服务
docker run -it --name web1 -p 80:80 nginx
docker exec -it web1 /bin/bash
curl 127.0.0.1

#运行第二个容器拥有nginx服务
docker run -d --name web2 --network container:web1 nginx
curl 127.0.0.1

5.None模式

5.1 None模式介绍

如果使用None模式,则容器不会创建任何网络配置,没有网卡也没有IP地址,因此机会不会使用这种模式

5.2 使用None模式

[root@docker-11 ~]# docker run --network none -it busybox:latest /bin/sh
/ #
/ # ip a
/ # ping 10.0.0.11
PING 10.0.0.11 (10.0.0.11): 56 data bytes
ping: sendto: Network is unreachable
/ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface

6.自定义网络模式

docker笔记_mysql_14

6.1 自定义网络模式特点

自定义网络可以独立设置容器的使用的网段,而且在同一网络里的虚拟机不需要link就可以直接使用容器名进行互相访问

6.2 自定义网络模式语法

#创建自定义网络
docker network create -d <mode> --subnet <CIDR> --gateway <网关> <自定义网络名称>

#引用自定义网络
docker run --network <自定义网络名称> <镜像名称>

#删除自定义网络
doccker network rm <自定义网络名称或网络ID>

6.3 自定义网络模式实验

#创建自定义网络
docker network create -d bridge --subnet 192.168.100.0/24 --gateway 192.168.100.1 sz-net

#查看信息
docker inspect my-net

#查看网卡
ip a

#查看网桥
brctl show

#利用自定义的网络创建容器
##运行第一个容器
docker run --name busybox_1 -it --network my-net busybox /bin/sh
ip a
route -n

##运行第二个容器
docker run --name busybox_2 -it --network my-net busybox /bin/sh
ip a
route -n
ping busybox_1

第11章 Docker容器夸主机通信

1.Docker跨主机网络类型

静态路由
Overlay
macvlan
flannel
calico

2.静态路由模式

2.1 静态路由模式说明

docker笔记_docker_15

配置说明:

1.两台宿主机的容器IP处于不同的网段
2.两台宿主机都配置了静态路由,发给对方的网段的数据包通过eth0网卡,网关指向对方的eth0地址
3.防火墙开发内网转发规则

2.2 两台主机创建不同的docker0网段

docker-11配置

cat > /etc/docker/daemon.json << 'EOF'
{
	"bip": "192.168.100.1/24",
	"registry-mirrors": ["https://ig2l319y.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
ip a|grep 192.168.100

docker-12配置

cat > /etc/docker/daemon.json << 'EOF'
{
	"bip": "192.168.200.1/24",
	"registry-mirrors": ["https://ig2l319y.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
ip a|grep 192.168.200

2.3 添加静态路由和iptables规则

docker-11配置

route add -net 192.168.200.0/24 gw 10.0.0.12
iptables -A FORWARD -s 10.0.0.0/24 -j ACCEPT

docker-12配置

route add -net 192.168.100.0/24 gw 10.0.0.11
iptables -A FORWARD -s 10.0.0.0/24 -j ACCEPT

2.4 跨主机容器通信测试

docker-11启动容器

[root@docker-11 ~]# docker run -it busybox /bin/sh
/ # ip a

docker-12启动容器

[root@docker-12 ~]# docker run -it busybox /bin/sh
/ # ip a

docker-11启动容器访问docker-12容器测试

/ # ping -c 1 192.168.200.2
PING 192.168.200.2 (192.168.200.2): 56 data bytes
64 bytes from 192.168.200.2: seq=0 ttl=62 time=0.531 ms

docker-12启动容器访问docker-11容器测试

/ # ping -c 1 192.168.100.2
PING 192.168.100.2 (192.168.100.2): 56 data bytes
64 bytes from 192.168.100.2: seq=0 ttl=62 time=0.631 ms

2.5 抓包查看

docker-11抓包

[root@docker-11 ~]# yum install tcpdump -y
[root@docker-11 ~]# tcpdump -i eth0 -nn icmp

docker-12抓包

[root@docker-12 ~]# yum install tcpdump -y
[root@docker-12 ~]# tcpdump -i eth0 -nn icmp

3.macvlan模式

3.1 创建网络

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

3.2 启动容器

docker01启动容器

docker run -it --network macvlan_1 --ip 10.0.0.100 alpine

docker02启动容器

docker run -it --network macvlan_1 --ip 10.0.0.200 alpine

启动后互相ping发现可以正常通讯

ping 10.0.0.100
ping 10.0.0.200

4.跨主机通信-Consul实现

4.1 Consul介绍

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

4.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

4.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.4 重启docker01

systemctl daemon-reload     
systemctl restart docker.service

4.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

4.6 重启docker2

systemctl daemon-reload     
systemctl restart docker.service

4.7 在docker主机上创建overlay网络

在docker1上创建网络,然后会自动同步到docker2上

docker network create -d overlay overlay_net

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

docker1上运行命令

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

docker2上运行命令

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

4.9 测试联通性

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

5.跨主机通信-flannel实现

5.1 flannel介绍

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

5.2 flannel通信原理

流程图解

docker笔记_git_16

文字说明

1.数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡。

2.源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达目标主机后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一样由docker0路由到达目标容器。 

3.使每个结点上的容器分配的地址不冲突。Flannel通过Etcd分配了每个节点可用的IP地址段后,再修改Docker的启动参数。“--bip=X.X.X.X/X”这个参数,它限制了所在节点容器获得的IP范围。

5.3 实验环境

10.0.0.11  etcd,flannel,docker
10.0.0.12  flannel,docker

5.2 安装配置etcd

安装etc:

yum install etcd -y

编辑配置文件:

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

启动etcd

systemctl start etcd
systemctl enable etcd

测试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

防火墙

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

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

安装Flannel

yum install flannel -y

配置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.11: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

配置etcd数据库--在etcd主机上执行

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

启动docker

systemctl start flanneld.service
systemctl enable flanneld.service

检查端口

netstat -lntup|grep flannel

5.4 配置Docker关联Flannel网络

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

systemctl restart docker

5.5 创建容器测--网络地址没变

docker01创建容器:

docker run -it busybox /bin/sh

查看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
223: eth0@if224: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:c0:a8:64:02 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.2/24 brd 192.168.100.255 scope global eth0
       valid_lft forever preferred_lft forever

Docker02创建容器:

docker run -it busybox /bin/sh

查看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
223: eth0@if224: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:c0:a8:64:02 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.2/24 brd 192.168.100.255 scope global eth0
       valid_lft forever preferred_lft forever

测试容器间可否通讯:

ping 192.168.72.2
ping 192.168.58.3

5.6 网卡地址没变的处理方法

修改docker配置文件:

vim /usr/lib/systemd/system/docker.service

.................
[Service]
.................
EnvironmentFile=/run/flannel/docker
ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_NETWORK_OPTIONS
.................
systemctl daemon-reload 
systemctl restart docker

5.7 容器间网络不通的解决方法

iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT #使用这个规则即可
第12章 搭建代码上线

docker笔记_mysql_17

宿主机先配备好密钥

#jenkins做远程控制的时候要用到
ssh-keygen

#做好harbor后登录宿主机登录完,将 /root/.docker/ 映射到容器内

#jenkins使用参数化构建,注意参数的字符

#要执行的脚本要记得放到jenkins容器内部

docker笔记_php_18

docker笔记_mysql_19

docker笔记_nginx_20

docker笔记_git_21

搭建镜像仓库

第一步:安装docker和docker-compose
第二步:下载harbor-offline-installer-v1.9.0-rc1.tgz
第三步:上传到/opt,并解压
第四步:修改harbor.yml配置文件 hostname = 10.0.0.11 harbor_admin_password = 123456
第五步:执行install.sh


修改docker信任仓库
cat > /etc/docker/daemon.json << 'eof'
{
      "registry-mirrors": ["https://ig2l319y.mirror.aliyuncs.com"],
      "insecure-registries": ["http://10.0.0.11"] 
}
eof

#重启docker
systemctl restart docker

docker登陆harbor
docker login 10.0.0.11
user:admin
pass:123456

给镜像打标签
docker tag centos:latest 10.0.0.11/linux6/nginx:v1

上传镜像
docker push 10.0.0.11/linux6/nginx:v1

拉取镜像
docker pull 10.0.0.11/linux6/nginx:v1

搭建jenkins

docker-compose文件

version: '3'
services:
  jenkins:
    image: 'jenkins/jenkins:latest'
    container_name: jenkins 
    restart: always
    privileged: true
    user: root
    ports:
      - '8080:8080'
      - '50000:50000'
    volumes:
      - '/data/jenkins:/var/jenkins_home'
      - '/var/run/docker.sock:/var/run/docker.sock'
      - '/usr/bin/docker:/usr/bin/docker'
      - '/root/.ssh:/root/.ssh'
      - '/root/.docker/:/root/.docker/'
      - '/etc/docker/daemon.json:/etc/docker/daemon.json'

搭建步骤及问题

jenkins容器化

1.下载镜像
docker pull jenkins/jenkins

2.创建用户和数据目录并授权
useradd -u 1000 jenkins -M -s /sbin/nologin
mkdir /data/jenkins/
chown -R jenkins:jenkins /data/jenkins/

3.运行镜像
docker run \
--name jenkins \
-p 8080:8080 -p 50000:50000 \
-v /data/jenkins:/var/jenkins_home \
-d jenkins/jenkins

4.安装插件
tar zxf plugins.tar.gz 
mv plugins /data/jenkins/
ll /data/jenkins/plugins/
chown -R jenkins:jenkins /data/jenkins/
docker restart jenkins

5.查看默认登录密码
cat /data/jenkins/secrets/initialAdminPassword

6.如何指定root用户运行jenkins容器
--privileged=true --user root


docker run \
--name jenkins \
-p 8080:8080 -p 50000:50000 \
--privileged=true \
--user root \
-v /data/jenkins:/var/jenkins_home \
-d jenkins/jenkins

7.如何在jenkins容器里里运行docker命令?
方法1:更新源并安装docker-ce
#更新源 
cat > /etc/apt/sources.list << 'EOF'
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free
EOF
apt update

#安装docker
apt -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg |apt-key add -
add-apt-repository \
   "deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian \
   $(lsb_release -cs) \
   stable"
apt update
apt install docker-ce -y

#启动docker
/usr/bin/dockerd

#检查结果
docker version 

方法2:映射宿主机的docker
docker run \
--name jenkins \
-p 8080:8080 -p 50000:50000 \
--privileged=true \
--user root \
-v /data/jenkins:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v /etc/docker/daemon.json:/etc/docker/daemon.json \
-v /root/.ssh:/root/.ssh \
-d jenkins/jenkins

搭建gitlab

docker-compose文件

version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    restart: always
    hostname: 'gitlab.example.com'
	container_name: gitlab 
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://10.0.0.11'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
	    alertmanager['enable'] = false
        grafana['enable'] = false
        prometheus['enable'] = false
        node_exporter['enable'] = false
        redis_exporter['enable'] = false
        postgres_exporter['enable'] = false
        pgbouncer_exporter['enable'] = false
        gitlab_exporter['enable'] = false
    ports:
      - '9090:80'
      - '2222:22'
    volumes:
      - '/data/gitlab/config:/etc/gitlab'
      - '/data/gitlab/logs:/var/log/gitlab'
      - '/data/gitlab/data:/var/opt/gitlab'

搭建步骤及问题

0.部署gitlab命令
version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    restart: always
    hostname: 'gitlab.example.com'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://10.0.0.11'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
	    alertmanager['enable'] = false
        grafana['enable'] = false
        prometheus['enable'] = false
        node_exporter['enable'] = false
        redis_exporter['enable'] = false
        postgres_exporter['enable'] = false
        pgbouncer_exporter['enable'] = false
        gitlab_exporter['enable'] = false
    ports:
      - '9090:80'
      - '2222:22'
    volumes:
      - '/data/gitlab/config:/etc/gitlab'
      - '/data/gitlab/logs:/var/log/gitlab'
      - '/data/gitlab/data:/var/opt/gitlab'

容器化gitlab遇到的坑

1.默认密码不知道,进入容器修改root密码
docker exec -it gitlab-ce /bin/bash
gitlab-rails console
user = User.where(username: 'root').first
user.password = 'admin-123'
user.save!
exit

2.即使添加了公钥,克隆代码需要密码,需要修改配置文件
解决方法1:直接修改配置文件然后重新启动
external_url 'http://10.0.0.11'
gitlab_rails['gitlab_shell_ssh_port'] = 2222
alertmanager['enable'] = false
grafana['enable'] = false
prometheus['enable'] = false
node_exporter['enable'] = false
redis_exporter['enable'] = false
postgres_exporter['enable'] = false
pgbouncer_exporter['enable'] = false
gitlab_exporter['enable'] = false


解决方法2:docker-compose文件直接添加变量
version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    restart: always
    hostname: 'gitlab.example.com'
	container_name: gitlab 
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://10.0.0.11'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
	    alertmanager['enable'] = false
        grafana['enable'] = false
        prometheus['enable'] = false
        node_exporter['enable'] = false
        redis_exporter['enable'] = false
        postgres_exporter['enable'] = false
        pgbouncer_exporter['enable'] = false
        gitlab_exporter['enable'] = false
    ports:
      - '9090:80'
      - '2222:22'
    volumes:
      - '/data/gitlab/config:/etc/gitlab'
      - '/data/gitlab/logs:/var/log/gitlab'
      - '/data/gitlab/data:/var/opt/gitlab'

3.优化不需要的启动服务,需要修改配置文件
参考上面的docker-compose

4.公钥key写谁的?
直接映射宿主机的
version: '3'
services:
  jenkins:
    image: 'jenkins/jenkins:latest'
    container_name: jenkins 
    restart: always
    privileged: true
    user: root
    ports:
      - '8080:8080'
      - '50000:50000'
    volumes:
      - '/data/jenkins:/var/jenkins_home'
      - '/var/run/docker.sock:/var/run/docker.sock'
      - '/usr/bin/docker:/usr/bin/docker'
      - '/root/.ssh:/root/.ssh'
      - '/root/.docker/:/root/.docker/'

docker-compose文件

version: '3'
services:
  jenkins:
    image: 'jenkins/jenkins:latest'
    container_name: jenkins 
    restart: always
    privileged: true
    user: root
    ports:
      - '8080:8080'
      - '50000:50000'
    volumes:
      - '/data/jenkins:/var/jenkins_home'
      - '/var/run/docker.sock:/var/run/docker.sock'
      - '/usr/bin/docker:/usr/bin/docker'
      - '/root/.ssh:/root/.ssh'
      - '/root/.docker/:/root/.docker'
      - '/etc/docker/daemon.json:/etc/docker/daemon.json'
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    restart: always
    hostname: 'gitlab.example.com'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://10.0.0.11'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
        alertmanager['enable'] = false
        grafana['enable'] = false
        prometheus['enable'] = false
        node_exporter['enable'] = false
        redis_exporter['enable'] = false
        postgres_exporter['enable'] = false
        pgbouncer_exporter['enable'] = false
        gitlab_exporter['enable'] = false
    ports:
      - '9090:80'
      - '2222:22'
    volumes:
      - '/data/gitlab/config:/etc/gitlab'
      - '/data/gitlab/logs:/var/log/gitlab'
      - '/data/gitlab/data:/var/opt/gitlab'  

脚本

#1.打包代码
code_tar(){
  tar zcvf code.tar.gz *
}

#2.编写dockerfile
docker_file(){
cat > Dockerfile << EOF
FROM nginx:latest
ADD code.tar.gz /usr/share/nginx/html/
EOF
}


#3.构建镜像
docker_build(){
  docker build -t 10.0.0.11/linux6/nginx:$git_version .
}

#4.推送镜像
docker_push(){
  docker push 10.0.0.11/linux6/nginx:$git_version
}

#5.远程拉取镜像
docker_pull(){
  ssh 10.0.0.12 docker pull 10.0.0.11/linux6/nginx:$git_version
}

#6.停止容器
docker_stop(){
  ssh 10.0.0.12 docker stop app
}

#7.删除容器
docker_rm(){
  ssh 10.0.0.12 docker rm app
}

#9.启动新容器
docker_run(){
  ssh 10.0.0.12 docker run --name app -it -p 80:80 -d 10.0.0.11/linux6/nginx:$git_version
}

#发布逻辑
if [ "$deploy_env" == "deploy" ]
then
  code_tar
  docker_file
  docker_build
  docker_push
  docker_pull
  docker_stop
  docker_rm
  docker_run
else
  docker_stop
  docker_rm
  docker_run
fi

第13章 Docker资源限制

1.Docker资源限制说明


2.容器的内存限制

官方文档:

 https://docs.docker.com/config/containers/resource_constraints/

Docker限制内存相关参数:

-m 允许容器使用的最大内存,单位有k,m,g
--oom-kill-disable

下载压测工具镜像:

docker pull lorel/docker-stress-ng

压测工具参数说明:

#查看帮助说明
docker run --name mem_test -it --rm lorel/docker-stress-ng

#常用参数
-m N, --vm N 启动N个workers,默认一个256M内

创建一个没有内存限制的容器:

#启动一个前台窗口任务
docker run --rm --name mem_test -it lorel/docker-stress-ng --vm 2

#另开一个窗口查看
docker stats

CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O   PIDS
5438f8d29413   mem_test   99.26%    514.2MiB / 1.934GiB   25.96%    516B / 0B   0B / 0B     5

创建一个限制了内存大小的容器

#启动一个前台窗口任务
docker run --rm --name mem_test --rm -m 300m -it lorel/docker-stress-ng --vm 2

#新开窗口查看
docker stats
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O   PIDS
90f6273fba09   mem_test   97.66%    119.5MiB / 300MiB   39.82%    656B / 0B   0B / 0B     5

3.容器的CPU限制

官方文档:

https://docs.docker.com/config/containers/resource_constraints/

Docker限制CPU相关参数:

 --cpus=<value>

查看宿主机CPU核数:

[root@docker-11 ~]# lscpu
Architecture: 			x86_64
CPU op-mode(s): 		32-bit, 64-bit
Byte Order: 			Little Endian
CPU(s): 				4

压测工具命令:

#不限制容器的CPU使用,压测工具开启4个CPU
docker run --rm --name cpu_test -it --rm lorel/docker-stress-ng --cpu 4

#新开窗口查看CPU占用情况
docker stats

CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O   PIDS
a15914a949ad   cpu_test   98.88%    14.18MiB / 1.934GiB   0.72%     516B / 0B   0B / 0B     5


#限制容器只能使用1.5个CPU
docker run  --rm --cpus 1.5 --name cpu_test -it --rm lorel/docker-stress-ng --cpu 4


#查看容器运行状态
docker stats

CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O   PIDS
b504d2d4a6be   cpu_test   98.70%    14.75MiB / 1.934GiB   0.75%     516B / 0B   0B / 0B     5

第14章 Docker监控

1.docker自带的监控命令

docker container ps  :查看正在运行的容器
docker container top  :知道某个容器运行了哪些进程
docker container stats :显示每个容器各种资源使用情况 

2.cAdvisor+ prometheus+ grafana组件介绍

2.1 cAdvisor介绍

1.cAdvisor是google开发的容器监控工具,cAdvisor会显示当前host的资源使用情况,包括CPU,内存,网络,文件系统。
2.不过cAdvisor提供的操作界面略显简陋,而且需要在不同页面之间跳转,并且只能监控一个host,这不免让人质疑他的实用性,但cAdvisor有一个亮点是可以将监控到的数据导出给第三方工具,有这些工具进一步加工处理。
3.所以我们可以把cAdvisor定位为一个监控数据收集器,收集和导出数据是他的强项,而非展示数据。
cAdvisor支持很多第三方工具,其中就包含prometheus

2.2 prometheus

Prometheus是一个非常优秀的监控工具。提供了监控数据搜集,存储,处理,可视化和告警一系列完整的解决方案。
包含组件:
Node Exporter :负责收集host硬件和操作系统数据,以容器的形式运行在所有host上
cAdvisor :负责收集容器数据,以容器的形式运行在所有host上

2.3 grafana

grafana是一款支持多种数据源的图形展示工具

3.使用docker-compose部署

3.1 地址规划

10.0.0.11   cAdvisor+ Node Exporter +prometheus+ grafana
10.0.0.12   cAdvisor+ Node Exporter

3.2 编写prometheus配置文件

cat > prometheus.yml << 'EOF'
scrape_configs:
- job_name: cadvisor
  scrape_interval: 5s
  static_configs:
  - targets:
    - 10.0.0.11:8080
    - 10.0.0.12:8080

- job_name: prometheus
  scrape_interval: 5s
  static_configs:
  - targets: 
    - 10.0.0.11:9090

- job_name: node_exporter
  scrape_interval: 5s
  static_configs:
  - targets: 
    - 10.0.0.11:9100
    - 10.0.0.12:9100
EOF

3.2 编写docker-compose文件

docker01配置

cat >docker-compose.yml<<EOF
version: '3.2'
services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
    - 9090:9090
    command:
    - --config.file=/etc/prometheus/prometheus.yml
    volumes:
    - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
    depends_on:
    - cadvisor

  node-exporter:
    image: prom/node-exporter:latest
    container_name: node_exporter
    ports:
    - 9100:9100

  cadvisor:
    image: google/cadvisor:latest
    container_name: cadvisor
    ports:
    - 8080:8080
    volumes:
    - /:/rootfs:ro
    - /var/run:/var/run:rw
    - /sys:/sys:ro
    - /var/lib/docker/:/var/lib/docker:ro

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
    - 3000:3000
EOF

docker02配置:

cat >docker-compose.yml<<EOF
version: '3.2'
services:
  node-exporter:
    image: prom/node-exporter:latest
    container_name: node_exporter
    ports:
    - 9100:9100

  cadvisor:
    image: google/cadvisor:latest
    container_name: cadvisor
    ports:
    - 8080:8080
    volumes:
    - /:/rootfs:ro
    - /var/run:/var/run:rw
    - /sys:/sys:ro
    - /var/lib/docker/:/var/lib/docker:ro
EOF

运行命令:

docker-compose -f docker-compose.yml up -d

4.web页面操作

访问地址:

10.0.0.11:3000
admin admin

添加数据源:

DataSources
Name:Prometheus
URL:http://10.0.0.11:9090

下载监控面板文件:

https://grafana.com/api/dashboards/10619/revisions/1/download

查看执行效果:


第15章 Jenkins自动化部署Docker

1.部署流程

部署流程:

1.下载代码
2.编译镜像
3.推送镜像
4.停止正在运行的容器
5.启动新容器
6.清理jenkins主机上的镜像

回滚流程:

1.选择需要回滚的版本
2.停止正在运行的容器
3.启动新容器

2.jenkins Docker in Docker

docker run -p 8888:8080 -p 50000:50000 \
-v /data/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v '/root/.ssh:/root/.ssh' \
--name jenkins \
--privileged=true  \
-u root \
-d jenkins/jenkins:latest

3.编写dockerfile

还需要做什么?

设置容器内的时区
将创建的ssh私钥加入(使用git拉代码是要用,配对的公钥配置在gitlab中)
加入了登陆自建harbor仓库的config文件
修改了ssh客户端的配置,不做指纹验证

4.登陆docker

cat > /etc/docker/daemon.json << 'EOF'
{
  "registry-mirrors": ["https://ig2l319y.mirror.aliyuncs.com"],
  "insecure-registries": ["http://10.0.0.11"]
}
EOF
docker login 10.0.0.11

5.准备文件

在harbor中创建基础镜像的仓库源

给镜像进行打标签

cd /data/dockerfile/jenkins/
cp /root/.ssh/id_rsa .
cp /root/.docker/config.json .
wget get.docker.com -O get-docker.sh
chmod +x get-docker.sh 

6.构建镜像

cd /data/dockerfile/jenkins/
docker build . -t 10.0.0.11/linux6/jenkins:latest

7.上传镜像

docker push 10.0.0.11/linux6/jenkins:latest

8.准备docker-compose文件

version: '3'
services:
  jenkins:
    image: jenkins/jenkins:latest
    container_name: jenkins
    restart: always
    privileged: true
    user: root
    ports:
      - '8888:8080'
      - '50000:50000'
    volumes:
      - '/etc/localtime:/etc/localtime'
      - '/data/jenkins_home:/var/jenkins_home'
      - '/var/run/docker.sock:/var/run/docker.sock'
      - '/usr/bin/docker:/usr/bin/docker'
      - '/root/.ssh:/root/.ssh'

9.安装插件

docker笔记_git_22

10.jenkins配置

docker笔记_mysql_23

11.流程问题

部署容器的时候,要对容器进行判断
1.判断是否有game项目的容器开启着
2.如果没有,判断容器有没有删除

解决方案:
使用docker-compose管理

在宿主机的家目录中创建一个环境变量的文件 /root/.env
启动容器使用docker-compose来启动管理

-------------------------------------------------
version: '3'
services:
  game:
    image: 10.0.0.11/image/game:${git_version}
    container_name: game
    volumes:
      - "/data/docker_mysql:/var/lib/mysql"
    ports:
      - "80:80"
-------------------------------------------------

docker笔记_docker_24

12.pipeline脚本

新版本

pipeline{ 
    agent any 
    parameters {
        gitParameter name: 'git_version', 
                     type: 'PT_TAG',
                     defaultValue: 'main'
        choice(name: 'base_image', choices: ['nginx:1.17','nginx:1.18'],description: '请选择基础镜像版本')
        choice(name: 'deploy_env', choices: ['deploy','rollback'],description: 'deploy: 发布版本\nrollback: 回滚版本') 
    }

    stages{
        stage("拉取代码") {
            steps {
			    dir('game'){
                    checkout([$class: 'GitSCM', 
                              branches: [[name: "${params.git_version}"]], 
                              doGenerateSubmoduleConfigurations: false, 
                              extensions: [], 
                              gitTool: 'Default', 
                              submoduleCfg: [], 
                              userRemoteConfigs: [[url: 'ssh://git@10.0.0.11:2222/root/docker.git']]
                            ])
			    }
            }
        }

        stage("编译镜像"){
            when {
                environment name: 'deploy_env', value: 'deploy'
            }
            steps{
                writeFile file: "Dockerfile", text: """FROM 10.0.0.11/base_image/${params.base_image}\nADD game /usr/share/nginx/html/"""
                sh "docker build -t 10.0.0.11/image/game:${params.git_version} . && docker push 10.0.0.11/image/game:${params.git_version}"               
            } 
        }

        stage("推送镜像"){
            when {
                environment name: 'deploy_env', value: 'deploy'
            }
            steps{
                sh "docker build -t 10.0.0.11/image/game:${params.git_version} . && docker push 10.0.0.11/image/game:${params.git_version}"               
            }         
        }

        stage("部署容器"){
            when {
                environment name: 'deploy_env', value: 'deploy'
            }         
            steps{
                sh 'ssh 10.0.0.12 "echo git_version=${git_version} > /root/.env"'
                sh 'ssh 10.0.0.12 "docker-compose -f /root/docker-compose.yml up -d"'
            }
        } 

        stage("清理构建镜像"){
            when {
                environment name: 'deploy_env', value: 'deploy'
            }        
            steps{
                sh "docker rmi 10.0.0.11/image/game:${params.git_version}"
            }
        }

        stage("回滚容器"){
            when {
                environment name: 'deploy_env', value: 'rollback'
            }

            steps{
                sh 'ssh 10.0.0.12 "docker stop game && docker rm game && docker run --name game -p 80:80 -d 10.0.0.11/image/game:${git_version} && docker ps"'
            }         
        }
    }  
}

旧版本

pipeline{ 
    agent any 

    parameters {
        gitParameter name: 'git_version', 
                     branchFilter: 'origin/(.*)',
                     type: 'PT_TAG',
                     defaultValue: 'v1.0',
                     description: '发布新版本'
        choice(name: 'base_image', choices: ['nginx:1.17','nginx:1.18'],description: '请选择基础镜像版本')
        choice(name: 'deploy_env', choices: ['deploy','rollback'],description: 'deploy: 发布版本\nrollback: 回滚版本')               
             
    }

    stages{
        stage("下载代码"){ 
            steps{
                  checkout([$class: 'GitSCM', 
                                     branches: [[name: '*/master']], 
                                     doGenerateSubmoduleConfigurations: false, 
                                     extensions: [[$class: 'RelativeTargetDirectory', 
                                     relativeTargetDir: 'game']], 
                                     submoduleCfg: [], 
                                     userRemoteConfigs: [[credentialsId: '9a68705c-be54-4579-8814-69e132a3ee9d', 
                                     url: 'ssh://git@10.0.0.11:2222/root/game.git']]])
            }
        } 

        stage("编译镜像"){
            when {
                environment name: 'deploy_env', value: 'deploy'
            }
            steps{
                writeFile file: "Dockerfile", text: """FROM 10.0.0.11/base_image/${params.base_image}\nADD game /usr/share/nginx/html/"""
                sh "docker build -t 10.0.0.11/image/game:${params.git_version} . && docker push 10.0.0.11/image/game:${params.git_version}"               
            } 
        }

        stage("推送镜像"){
            when {
                environment name: 'deploy_env', value: 'deploy'
            }
            steps{
                sh "docker build -t 10.0.0.11/image/game:${params.git_version} . && docker push 10.0.0.11/image/game:${params.git_version}"               
            }         
        }

        stage("部署容器"){
            when {
                environment name: 'deploy_env', value: 'deploy'
            }         
            steps{
                sh 'ssh 10.0.0.12 "docker stop game && docker rm game && docker run --name game -p 80:80 -d 10.0.0.11/image/game:${git_version} && docker ps"'
            }
        } 

        stage("清理构建镜像"){
            when {
                environment name: 'deploy_env', value: 'deploy'
            }        
            steps{
                sh "docker rmi 10.0.0.11/image/game:${params.git_version}"
            }
        }

        stage("回滚容器"){
            when {
                environment name: 'deploy_env', value: 'rollback'
            }

            steps{
                sh 'ssh 10.0.0.12 "docker stop game && docker rm game && docker run --name game -p 80:80 -d 10.0.0.11/image/game:${git_version} && docker ps"'
            }         
        }         
    }
}