docker的使用

一,docker介绍使用

1.Docker 安装

windos安装

1
2
直接官网下载就可以了
https://download.docker.com/win/stable/Docker%20Desktop%20Installer.exe

Docker支持以下的CentOS版本:
CentOS 7 (64-bit)
CentOS 6.5 (64-bit) 或更高的版本
前提条件
目前,CentOS 仅发行版本中的内核支持 Docker。
Docker 运行在 CentOS 7 上,要求系统为64位、系统内核版本为 3.10 以上。
Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系统为64位、系统内核版本为 2.6.32-431 或者更高版本。

1.使用 yum 安装(CentOS 7下)

Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker 。
通过 uname -r 命令查看你当前的内核版本

1
[root@server1 ~]# uname -r

从 2017 年 3 月开始 docker 在原来的基础上分为两个分支版本: Docker CE 和 Docker EE。
Docker CE 即社区免费版,Docker EE 即企业版,强调安全,但需付费使用。
本文介绍 Docker CE 的安装使用。

docker的官方文档安装

1
https://docs.docker.com/engine/install/centos/

移除旧的版本:

1
2
3
4
5
6
7
8
9
10
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine

安装一些必要的系统依赖工具

1
yum install -y yum-utils device-mapper-persistent-data lvm2

添加软件源信息

1
2
3
4
5
6
7
8
9
阿里云的软件源:
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

官方的下载源:
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

更新 yum 缓存

1
yum makecache fast

列出Docker软件版本信息

1
yum list docker-ce --showduplicates | sort -r

安装 Docker-ce

1
2
3

yum -y install docker-ce //默认安装最新版本
yum -y install docker-ce-3:18.09.7-3.el7 //安装指定版本

支持端口转发

1
2
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf 
sysctl -p

重新加载systemctl配置

1
2
3
如果修改了systemctl edit docker.service 这个文件,就要执行这步操作

systemctl daemon-reload

启动 Docker 后台服务

1
2
3
systemctl start docker
systemctl status docker
systemctl enable docker

1.1docker疑难杂症:docker命令Tab无法自动补全

1.安装bash-complete

1
yum install -y bash-completion

2.刷新文件

1
2
source /usr/share/bash-completion/completions/docker
source /usr/share/bash-completion/bash_completion

查看版本信息

1
2
docker version
docker info

测试Docker安装

通过运行hello-world Docker映像来测试安装是否正常:

1
$ docker run hello-world

2.使用脚本安装 Docker

1、使用 sudo 或 root 权限登录 Centos。

2、确保 yum 包更新到最新

1
sudo yum update

3、执行 Docker 安装脚本。

1
2
3
curl -fsSL https://get.docker.com -o get-docker.sh

sudo sh get-docker.sh

执行这个脚本会添加 docker.repo 源并安装 Docker

4、启动 Docker 进程。

1
2
3
systemctl start docker
systemctl status docker
systemctl enable docker

5、查看版本信息

1
2
docker version
docker info

3,删除卸载Docker CE

执行以下命令来删除 Docker CE:

1
2
sudo yum remove docker-ce docker-ce-cli containerd.io -y
sudo rm -rf /var/lib/docker

2.Docker的使用

1.docker常用命令

1.镜像仓库

1
2
3
4
5
6
7
8
1.搜索镜像
docker search centos

2. 从镜像参数中拉取指定镜像
docker pull centos

docker官方镜像库
https://hub.docker.com/

2.镜像相关命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1.列出本地镜像
docker images
docker images -a
docker image ls

2.删除镜像
docker rmi 镜像名
docker rmi -f 镜像名 //强制删除镜像

3.查到指定镜像的创建历史
docker history 镜像名

4.将指定镜像保存为tar归档文件 -o 输出指定文件
docker save -o hello.tar hello-world //hello-world为镜像名。 hello.tar为指定输出的文件

5.由tar文档生成镜像
docker import -m "有本地保存的tar文件生成" ./hello.tar hello-world
参数说明: -m 为创建的镜像设置描述信息,可以通过docker history -H 查看。
./hello.tar 为tar文件的路径, hello-world 为镜像名字

6.使用dockerfile创建镜像
docker build [可选选项] 文件路径 . 当前目录
docker build -t look/centos7.3 .
参数说明:
-t :指定要创建的目标镜像名
.  :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径

7. 创建某个镜像的副本
docker tag src_image[:tag] tar_image[:tag]
docker tag centos:latest localhost:5000/centos #把本地的centos镜像复制一份,命名为localhost:5000/centos

3.容器操作常见命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
1.docker ps      列出容器 
docker ps -a -a 只显示正在运行的

2.docker inspect 7019f9fdf8ab 查看容器或镜像的元数据

3.docker top 容器名 查看指定容器中运行的进程

4.docker exec -it 容器名 /bin/bash //进入容器

5.docker logs -f 容器名 #查看容器的实时日志

6.docker cp // 容器与主机之间的文件复制
从容器中复制到主机
docker cp testtomcat:/usr/local/tomcat/webapps/test/js/test.js /opt

从主机复制到容器中
docker cp /opt/test.js testtomcat:/usr/local/tomcat/webapps/test/js

选项:
-a 复制所有的gid/uid信息
-L Always follow symbol link in SRC_PATH 始终遵循原路径的符号信息

7.docker difff CONTAINER // 查看容器中被修改过的文件或目录

8.启动停止重启容器
docker stop hello-world
docker start hello-world
docker restart hello-world
docker kill hello-world #杀死一个容器

9.查看所有容器id
docker ps -aq

10.删除所有容器
docker rm $(docker ps -aq)

11.查看所有没有运行的容器id
docker ps -f "status=exited" -q

12. 删除所有没有运行的容器
docker rm $(docker ps -f "status=exited" -q)

4.运行容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
运行容器

docker run --name 容器名 -d -p 3306:3306 mysql docker 启动容器
docker run image_name
docker run -d -p 80:80 nginx:latest
run(创建并运行一个容器)
-d 放在后台
-p 端口映射 :docker的容器端口
-P 随机分配端口
-v 源地址(宿主机):目标地址(容器)

docker run -it --name centos6 centos:6.9 /bin/bash
-it 分配交互式的终端
--name 指定容器的名字
/bin/sh覆盖容器的初始命令

2,构建Dockerfile

编写一个go程序hello.go

1
2
3
4
5
6
7
8
package main

import "fmt"

func main(){
fmt.Println("hello world")

}

创建一个文件Dockerfile命名

1
2
3
4
5
6
7
8
9
#从头开始
FROM scratch

#加到根目录
ADD hello /

#运行hello

CMD ["/hello"]

开始构建

1
docker build  -t gohallo/hello .

把go程序跑起来

1
docker run gohello/hello

下载一个centos镜像并跑起来

1
2
3
4
5
6
7
8
docker run centos 

docker run -it --name centosl -d centos

拷贝hello文件到容器
docker cp hello centosl:/usr/local/
进入容器
docker exec -it centosl /bin/bash

2.1Dockerfile 详解

1.FROM

1
2
3
4
文件的开始
FROM scratch #从头开始制作一个最简单的
FROM centos #使用centos 为系统,本地若没有则拉取
FROM centos:7.0 #指定系统+ 版本号

2.LABEL

1
2
3
LABEL:相当于注释,或者说明信息。
LABEL version="1.0"
LABEL author="luke"

3.RUN

1
2
3
4
5
RUN :相当于执行命令,每执行一条RUN,就会多一层
RUN yum -y update && yum install -y lrzsz \
net-tools

\相当于连接线,如果一行写不完就可以这样做。

4.WORKDIR

1
2
3
4
5
WORKDIR   进入或创建目录
WORKDIR /root 进入/root目录
WORKDIR /test 自动创建目录
WORKDIR demo
RUN pwd # /test/demo 会打印这个路径

5.ADD and COPY

1
2
3
4
5
6
ADD and COPY  将本地文件添加到镜像里
ADD 可以解压文件
ADD hello / 将主机当前的hello文件 添加到 容器的/根目录下
ADD XXX.tar.gz / 添加到根目录,并解压文件

COPY hello / 直接复制一份到/目录下

6.ENV

1
2
3
4
5
6
7
8
功能为设置环境变量 
ENV MYSQL_VERSION 5.6 #设置常量
RUN yum install -y mysql-server="$(MYSQL_VERSION)" 等于下载mysql 5.6版本的
或者
设置了后,后续的 RUN 命令都可以使用,container 启动后,可以通过 docker inspect 查看这
个环境变量,也可以通过在 docker run --env key=value 时设置或修改环境变量。
假如你安装了 JAVA 程序,需要设置 JAVA_HOME,那么可以在 Dockerfile 中这样写:
ENV JAVA_HOME /usr/local/jdkxxxx/

7.EXPOSE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
EXPOSE 用于指定容器在运行时监听的端口: 
EXPOSE <port> [<port>...]

EXPOSE 并不会让容器的端口访问到主机。要使其可访问,需要在 docker run 运行容器时通过-p
来发布这些端口,或通过-P 参数来发布 EXPOSE 导出的所有端口。
映射一个端口
EXPOSE port1
# 相应的运行容器使用的命令
docker run -p port1 image

# 映射多个端口
EXPOSE port1 port2 port3
# 相应的运行容器使用的命令
docker run -p port1 -p port2 -p port3 image
# 还可以指定需要映射到宿主机器上的某个端口号
docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image

端口映射是 docker 比较重要的一个功能,原因在于我们每次运行容器的时候容器的 IP 地址不能
指定而是在桥接网卡的地址范围内随机生成的。
宿主机器的 IP 地址是固定的,我们可以将容器的端口的映射到宿主机器上的一个端口,免去每次
访问容器中的某个服务时都要查看容器的 IP 的地址。
对于一个运行的容器,可以使用 docker port 加上容器中需要映射的端口和容器的 ID 来查看该
端口号在宿主机器上的映射端口

8.CMD and ENTRYPOINT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 #shell格式
RUN yum install -y lrzsz
CMD echo "hello docker "
ENTRYPONINT echo "hello docker"

#exec 格式
RUN ["yum","-y","install","lrzsz"]
CMD ["/bin/echo","hello Docker"]
ENTRYPONINT ["/bin/bash","-c","echo hello Docker"]

CMD 和ENTRYPOINT的区别

CMD
若docker指定了其他命令,CMD 会被忽略
若定义了多个CMD,只会执行最后一个

9.VOLUME

1
VOLUME ["/var/www/html","/data/mysql/data"]

3,搭建私有镜像仓库

1.直接执行一条命令搭建

1
2
3
4
5
6
官网地址: https://hub.docker.com/_/registry
docker run -d -p 5000:5000 --restart always --name registry registry:2
或者
docker run -d -p 5000:5000 --restart always --name registry -v /opt/reqistry:/var/lib/registry registry:2

/var/lib/registry是容器存放镜像的目录

2.构建自己的镜像

1
2
3
4
docker build -t 192.168.224.11:5000/centos2 .

或者复制一份本地的镜像
docker tag centos:latest localhost:5000/centos

3.上传到自己搭建的镜像仓库

1
2
3
4
5
6
7
8
9
10
11
12
 docker push  192.168.224.11:5000/centos2 

The push refers to repository [192.168.224.11:5000/centos2]
Get https://192.168.224.11:5000/v2/: http: server gave HTTP response to HTTPS client
如果报错:
echo '{ "insecure-registries":["192.168.224.11:5000"] }' > /etc/docker/daemon.json
重启docker

docker push localhost:5000/centos

去仓库看看。
http://192.168.224.11:5000/v2/_catalog

4.在本地删除构建的镜像

1
2
3
docker rmi 192.168.224.11:5000/centos2:latest

docker rmi localhost:5000/centos:latest

5.然后在去搭建的私有创库去下载镜像

1
2
3
4
docker pull 192.168.224.11:5000/centos2
docker pull localhost:5000/centos

也是很快就下载下来了

6.本地仓库加安全认证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1.生成密码:
yum install -y httpd-tools
mkdir /opt/registry-auth/ -p
htpasswd -Bbn luke 123 > /opt/registry-auth/htpasswd
多用户就追加
htpasswd -Bbn luke1 123 >> /opt/registry-auth/htpasswd
2.重新启动带有秘钥功能的registry容器
docker run -d -p 5000:5000 --restart always --name registry -v /opt/registry-auth/:/auth/ -v /opt/reqistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry:2

3.push镜像,需要进行login
docker login 192.168.224.11:5000

docker push 192.168.224.11:5000/centos2
上传成功

docker logout 192.168.224.11:5000
退出登录

7.docker-habor实现图形化镜像仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
1.安装docker-compose
yum install -y docker-compose

2.下载harbor离线安装包并解压
wget https://storage.googleapis.com/harbor-releases/release-1.7.0/harbor-offline-installer-v1.7.1.tgz

#解压harbor安装包:

tar xvf harbor-offline-installer-v1.7.1.tgz

3.修改harbor.cfg配置文件
3.1 修改如下参数
vim harbor/harbor.cfg

hostname = 192.168.224.11

barbor_admin_password = luke123

执行install.sh

3.2.修改docker配置文件
vim /etc/docker/daemon.json
#增加如下参数

["192.168.224.11"]

"live-restore":true
3.3重启docker
systemctl restart docker

4.测试harbor仓库
4.1 建立harbor项目
通过web访问harbor仓库

http://192.168.224.11/

输入用户名和密码:

默认用户admin

密码:luke123  #修改harbor.cfg时设置的密码
4.2建立项目,命名luke 设置公有
4.3 给镜像打标签
docker tag centos:latest 192.168.224.11/luke/centos_habor:v1

4.4 登录仓库
[root@instance-x0nj9foj harbor]# docker login 192.168.224.11

Username: admin

Password: luke123

Login Succeeded




4.5 上传镜像文件
docker push 192.168.224.11/luke/centos_habor:v1

4.6 web登录镜像仓库进行确认

4.Docker的网络

1.网络的分类

单机

1
2
3
4
5
Bridge Network 桥接网络

Host Network 公用主机网络和宿主机一个网络

None Network 本地网络,自己和自己玩

多机

1
2
Overlay Network 
做集群的时候用。

2.Linux 网络命名空间namespace

命名空间是docker底层重要的概念

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
列出网络名
ip netns list

增加一个网络名
ip netns add test1

删除一个网络
ip netns delete test1

查看新建的网络的状态 刚开始是DOWN
ip netns exec test1 ip a

设置test1网络的状态,现在变成了UNKNOWN
ip netns exec test1 ip link set dev lo up

命名空间至少需要两个以上才能连接起来
在添加一个
ip netns add test2

添加veth peer veth 对
ip link add veth-test1 type veth peer name veth-test2

查看veth对
ip link

把veth-test1 加入到 test1网络
ip link set veth-test1 netns test1

查看test1的link状态.
ip netns exec test1 ip link

把veth-test2加入到test2网络
ip link set veth-test2 netns test2

给test1网络添加ip
ip netns exec test1 ip addr add 172.17.0.2/24 dev veth-test1
给test2网络添加ip
ip netns exec test2 ip addr add 172.17.0.3/24 dev veth-test2

在查看状态test1命名空间的
ip netns exec test1 ip link

启动test1,指定veth对
ip netns exec test1 ip link set dev veth-test1 up
启动test2,指定veth对
ip netns exec test2 ip link set dev veth-test2 up

查看test1网络的IP
ip netns exec test1 ip a

test1网络去ping test2的ip
ip netns exec test1 ping 172.17.0.3

test2网络去ping test1的ip
ip netns exec test2 ping 172.17.0.2

3.Bridge 详解

进行多容器通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
查看支持的网络
docker network ls
查看网络id的数据信息
docker network inspect 6343c0e76790

查看registry容器的网络信息
docker exec registry ip a
eth0@if26 用ip a命令查看 26: vetha30904a@if25: 这个if25和if26就是veth对


yum install -y bridge-utils 下载这个工具
brctl show 查看桥接网络和容器的veth对
brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.02423025af29 no veth33d7deb
vetha30904a

4.容器通信

有时写代码时,并不知道要请求的IP地址

   其中,name和id是源容器的name和id,alias是源容器在link下的别名。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1.启动一个容器命名为mycentos2
docker run -it --name mycentos2 --restart=always -d centos

2.再启动一个容器mycentos3 --link 链接到mycentos2
docker run -it --name mycentos3 --restart=always --link mycentos2 -d centos

这时候进去mycentos3里面,docker exec -it mycentos3 /bin/bash
就可以直接ping mycentos2 可以直接ping通了。不用输入ip地址,但是进去mycentos2里面不能通过容器名ping通mycentos3这个容器,只能ip才可以ping

3.在启动一个容器,进行多个容器链接。
docker run -it --name mycentos4 --restart=always --link mycentos2:centos2 --link mycentos3:centos3 -d centos

进入容器 docker exec -it mycentos4 /bin/bash

ping mycentos2 或者ping centos2
ping mycentos3 或者ping centos3 都可以ping通
2.创建网络(推荐)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
docker network ls

创建网络

docker network create -d bridge my-bridge

-d 后面第一个bridge是网络的连接方式,第二个my-bridge是自己起的网络的名字

如何创建镜像同时连上主容器的某个网络上?

在镜像创建时指定network 的name ,可以通过docker network ls查看到所有的网络,如下面实例

docker run -it --name test1 --restart=always --network my-bridge -d centos

如何查看是否连上了呢?

docker network inspect+ 网络的名字 my-bridge

如何手动将网络和容器连接呢?

docker network connect my-bridage mycentos4
docker network connect my-bridge mycentos3
docker network connect my-bridge mycentos2
这时候进去test1 就可以ping mycentos4了。同时mycentos4里面也可以通过ping test1来ping通
docker exec -it test1 /bin/bash

这时他们几个容器都可以互相ping通

通过将test2和test3同时连上自己的创建的网络(注意是自己创建的网络,不是系统自己默认的网络),这样双方都可以通过名字互ping上

5.端口映射

实现外界访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1. -p 8080:80  把容器的80端口映射到主机的8080端口
docker run -it --name web --restart=always -p 8080:80 --network my-bridge -d nginx
这时候访问主机的8080端口就可以访问内部的80端口了。
http://192.168.224.11:8080/

2. -p ip:8081:80 把容器的80端口映射到主机指定的ip端口
docker run -it --name nginx2 --restart=always -p 192.168.224.11:8081:80 --network my-bridge -d nginx
这样就只能通过指定ip:端口才可以访问了,

3.随机端口映射(32768-60999)
-p 80 把容器的80端口映射到主机的随机端口
docker run -it --name web2 --restart=always -p 80 --network my-bridge -d nginx

4. udp端口映射 把容器的udp端口映射到主机端口
-p 82:53/udp

5. 多个端口映射 -p 8080:80 -p 33060:3306 -p 2222:22

aw6FwF.png

6.网络的none和host

none 应用场景:安全性要求极高,存储绝密数据等

1
2
3
4
指定网络模式为none 
docker run -it --name none1 --restart=always --network none -d centos

这里面只有127.0.0.1这个ip ,只能ping通自己,其他都不能ping通

host网络

1
2
3
docker run -it --name host1 --restart=always  --network host -d centos

网络和宿主机一样。

7.多容器部署和应用

flask 做web服务,redis做自增

8.多机器多容器通信

1.利用etcd实现多机的ip管理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
etcd
思路:
下载etcd
wget https://github.com/coreos/etcd/releases/download/v3.0.12/etcd-v3.0.12-linux-amd64.tar.gz


etcd启动命令(node01) 注意修改ip
nohup ./etcd --name docker-node1 --initial-advertise-peer-urls http://192.168.224.11:2380 \
--listen-peer-urls http://192.168.224.11:2380 \
--listen-client-urls http://192.168.224.11:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://192.168.224.11:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster docker-node1=http://192.168.224.11:2380,docker-node2=http://192.168.224.12:2380 \
--initial-cluster-state new&

etcd启动命令(node02) 注意修改ip
nohup ./etcd --name docker-node2 --initial-advertise-peer-urls http://192.168.224.12:2380 \
--listen-peer-urls http://192.168.224.12:2380 \
--listen-client-urls http://192.168.224.12:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://192.168.224.12:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster docker-node1=http://192.168.224.11:2380,docker-node2=http://192.168.224.12:2380 \
--initial-cluster-state new&

参数说明:
● –data-dir 指定节点的数据存储目录,若不指定,则默认是当前目录。这些数据包括节点ID,集群ID,集群初始化配置,Snapshot文件,若未指 定–wal-dir,还会存储WAL文件
● –wal-dir 指定节点的was文件存储目录,若指定了该参数,wal文件会和其他数据文件分开存储
● –name 节点名称
● –initial-advertise-peer-urls 告知集群其他节点的URL,tcp2380端口用于集群通信
● –listen-peer-urls 监听URL,用于与其他节点通讯
● –advertise-client-urls 告知客户端的URL, 也就是服务的URL,tcp2379端口用于监听客户端请求
● –initial-cluster-token 集群的ID
● –initial-cluster 集群中所有节点
● –initial-cluster-state 集群状态,new为新创建集群,existing为已存在的集群

查看端口有没有正常起来
netstat -putnel
查看集群状态
./etcdctl cluster-health


docker启动命令(node01) 先停止下docker
/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://192.168.224.11:2379 --cluster-advertise=192.168.224.11:2375&

docker启动命令(node02) 先停止下docker
/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://192.168.224.12:2379 --cluster-advertise=192.168.224.12:2375&

测试下集群网络
在node01节点创建overlay网络,名为demo
docker network create -d overlay demo

这时候去node2节点看docker network ls 查看是否也有demo这个网络,有就说明可以了

开始在node01运行容器
docker run -it --name test1 --restart=always --net demo -d centos

在node02运行一台,容器名不要和node01的重复
docker run -it --name test2 --restart=always --net demo -d centos

这时候进去容器。两台机器上的容器都可以互相ping通了
docker exec -it test1 /bin/bash
ping test2
2.利用consul服务管理

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
1.启动 consul服务,实现网络的统一配置管理
docker run --name consul -p 8500:8500 -h consul -d progrium/consul -server -bootstrap

consul: kv类型的存储数据库(key:value)
docker01和docker02服务器上:
vim /etc/docker/daemon.json

{
"live-restore":true ,
"host":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"],
"cluster-store":"consul://192.168.224.11:8500",
"cluster-advertise":"ens33:2376"
}

cluster-store:配置的Consul的leader地址,单体直接写,其它软件注意协议
cluster-advertise: 指定监听的网卡和端口,也可以指定接收订阅消息的IP:PORT

systemctl daemon-reload
systemctl restart docker

2. 创建overlay网络
docker network create -d overlay --subnet 172.16.0.0/24 --gateway 172.16.0.254 over_1
docker network ls 会发现两台服务器上都多了一个网络over_1

3. 启动容器测试
docker run -it --name luke01 -h luke1 --network over_1 -d centos

docker run -it --name luke02 -h luke2 --network over_1 -d centos

进入容器测试
docker container exec -it luke01 /bin/bash
ping luke02 可以ping通 他们都可以互相ping通
每个容器有两块网卡,eth0实现容器间的通讯,eth1实现容器访问外网 容器默认路由是走eth1。docker会创建一个bridge网络“docker_gwbridge”,为所有连接到overlay网络的容器提供访问外网的能力 :

方法二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1.网卡名ens33
vim /etc/docker/daemon.json
{
"live-restore":true ,
"cluster-store":"consul://192.168.224.11:8500",
"cluster-advertise":"ens33:2376"
}

接着执行命令,重启docker服务,另一台服务器操作方式相同,注意网卡名称
sudo systemctl daemon-reload && sudo systemctl restart docker

2.在11上启动consul
docker run --name consul -p 8500:8500 -h consul -d consul:1.5.2

3.创建Docker overlay共享网络
$ docker network create -d overlay my_overlay

访问192.168.224.11:8500
key/value 会出现相关节点信息

4. 启动容器测试
docker run -it --name luke01 -h luke1 --network my_overlay -d centos

docker run -it --name luke02 -h luke2 --network my_overlay -d centos

进入容器测试
docker container exec -it luke01 /bin/bash
ping luke02 可以ping通 他们都可以互相ping通
每个容器有两块网卡,eth0实现容器间的通讯,eth1实现容器访问外网 容器默认路由是走eth1。docker会创建一个bridge网络“docker_gwbridge”,为所有连接到overlay网络的容器提供访问外网的能力 :

5.docker容器数据持久化本地挂载

1.数据持久化引入

1
2
官方mysql数据存储文档
https://hub.docker.com/_/mysql
  1. 在主机系统上的适当卷上创建数据目录,例如/my/own/datadir

  2. mysql像这样启动容器:

    1
    docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql

-v /my/own/datadir:/var/lib/mysql命令的一部分/my/own/datadir从底层主机系统/var/lib/mysql在容器内部安装目录,默认情况下,MySQL将在该目录中写入其数据文件。

2.数据卷容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1.宿主机模拟数据目录
mkdir -p /opt/volume/a
mkdir -p /opt/volume/b
touch /opt/volume/a/a.txt
touch /opt/volume/b/b.txt

2.启动数据卷容器
docker container run -it --restart=always --name nginx_volumes -v /opt/volume/a:/opt/a -v /opt/volume/b:/opt/b -d centos

3.使用数据卷容器
docker run -d -p 8085:80 --volumes-from nginx_volumes --restart=always --name nginx_5 nginx

docker run -d -p 8086:80 --volumes-from nginx_volumes --restart=always --name nginx_6 nginx

这样有多个目录需要挂载就可以使用这种方式。
作用: 在集中管理集群中。大批量的容器都需要挂载相同的多个数据卷时,可以采用数据卷容器进行统一管理。

aw6nQx.png

6,volume卷管理

docker volume 可以理解成一个container中的磁盘,既可以跟随container的生命周期(在Dockerfile 中定义使用VOLUME关键字),也可以单独创建,永久存储,直到用docker volume rm 命令删除。

1.查看volume

1
docker volume ls

2.创建volume

1
2
3
4
5
6
7
8
9
docker volume create [options] 卷名 
options选项有两个参数
-d 指定存储设备,默认是local
-o 直接卷的存储路径 默认是 map[]
示例1:
docker volume create -d local-persist -o mountpoint=/data/nginx --name=nginxroot
示例2: 参数默认
docker volume create vo_logs
这时候卷的存放路径是/var/lib/docker/volumes/vo_logs/_data

3.查看volume的详细信息

1
docker volume inspect vo_logs

4.删除卷

1
2
3
4
5
6
7
docker volume rm -f vo_logs
-f 表示强制删除

docker volume prune [options]
删除未被任何容器使用的本地卷
--filter 提供过滤值
-f , --force 不提示确认信息,直接删除

5.卷的使用

1
2
3
4
5
6
7
docker run -t --name mysql --restart=always -p 3306:3306 -v myvoluem:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=mypassword -d mysql

这时候容器里的/var/lib/mysql的数据就存在myvoluem这个数据卷里了,

第二种是本地挂载
绑定宿主目录的概念很容易理解,就是将宿主目录绑定到容器中的某个目录位置。这样容器可以直接访问宿主目录的文件。其形式是
docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql

挂载nginx

1
2
3
4
5
6
7
8
9
1.创建nginx家目录存储卷
docker volume create -d local-persist -o mountpoint=/data/nginx --name=nginxroot
2.创建nginx配置目录存储卷
docker volume create -d local-persist -o mountpoint=/data/nginxconf --name=nginxconf

3.启动容器并挂载卷
docker run -it --name nginx1 --restart=always -p 8080:80 -v nginxroot:/usr/share/nginx/html -v nginxconf:/etc/nginx -d nginx

4.这时候修改配置文件就可以直接在物理机修改就可以了

6.卷和挂载目录有什么区别?

卷 (Docker Volume) 是受控存储,是由 Docker 引擎进行管理维护的。因此使用卷,你可以不必处理 uid、SELinux 等各种权限问题,Docker 引擎在建立卷时会自动添加安全规则,以及根据挂载点调整权限。并且可以统一列表、添加、删除。另外,除了本地卷外,还支持网络卷、分布式卷。

而挂载目录那就没人管了,属于用户自行维护。你就必须手动处理所有权限问题。特别是在 CentOS 上,很多人碰到 Permission Denied,就是因为没有使用卷,而是挂载目录,而且还对 SELinux 安全权限一无所知导致。

3,docker-compose 多容器部署

1.安装

1
2
3
4
5
6
7
方法一:
curl -L https://github.com/docker/compose/releases/download/1.26.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
或者:
curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose


chmod +x /usr/local/bin/docker-compose

查看版本信息

1
# docker-compose --version

但是此方法会经常因为网络的原因而无法安装

方法二:

1、安装python-pip

1
2
3
yum -y install epel-release

yum -y install python-pip

2、安装docker-compose

1
pip install docker-compose

待安装完成后,执行查询版本的命令,

1
docker-compose version

2.docker-compose用法

官方文档

1
https://docs.docker.com/compose/

常用选项:

–verbose:输出更多的调试信息

–version:查看compose的版本

-f –file FILE:使用特定的compose模板文件,默认为docker-compose.yml。

-p –project-name NAME 指定项目名称,默认使用目录名称。

常用命令:

down: 停止并删除容器、网络、镜像和卷

build:构建或重建服务

ps:查看已经启动的服务状态

kill:停止某个服务、杀掉容器

logs:可以查看某个服务的log、显示容器的输出内容

port:打印绑定的public port(开放端口)

pull:拉取服务镜像

up:启动yml定义的所有服务

stop:停止yml中定义的所有服务

start:启动被停止的yml中的所有服务

kill:强行停止yml中定义的所有服务

rm:删除yml中定义的所有服务

restart:重启yml中定义的所有服务

scale:设置服务的容器数目

run:运行一个一次性命令

docker-compose up -d nginx 构建建启动nignx容器 在后台运行

docker-compose exec nginx bash 登录到nginx容器中

docker-compose down 删除所有容器,镜像

docker-compose ps 显示所有容器

docker-compose restart nginx 重新启动nginx容器

docker-compose run –no-deps –rm php-fpm php -v 在php-fpm中不启动关联容器,并容器执行php -v 执行完成后删除容器

docker-compose build nginx 构建镜像 。

docker-compose build –no-cache nginx 不带缓存的构建。

docker-compose logs nginx 查看nginx的日志

docker-compose logs -f nginx 查看nginx的实时日志

3.YAML简介

​ Yaml简介.YAML是一种标记语言,可读性很强。类似于XML数据描述语言,语法比XML简单的多。YAML数据结构通过缩进来表示,连续的项目通过减号来表示,键值对用冒号分割,数组用括号括起来, hash用花括号括起来。

YAML文件格式注意事项:

在缩排中空白字符的数目并不是非常重要,只要相同阶层的元素左侧对齐就可以了(不过不能使用TAB字符);

通常开头缩进2个空格;字符的后面缩进1个空格,比如冒号、逗号、横杆;

支持#注释;

允许在文件中加入选择性的空行,以增加可读性;

可以看到一份标准配置文件应该包含 version、services、networks、volumes 四大部分,其中最关键的就是 services 和 networks 两个部分,下面先来看 services 的书写规则。

示例:创建4台centos容器。在同一个网络,有挂载。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
version: '3'
services:
centos:
image: centos
restart: always
hostname: centos
container_name: centos
ports:
- 80:80
networks:
- nginx
centos1:
image: centos
restart: always
hostname: centos1
container_name: centos1
networks:
- nginx
command:
- yum install -y epel-release && yum install -y nginx
volumes:
- nginx:/usr/share/nginx/html
- nginx:/etc/nginx
centos2:
image: centos
restart: always
hostname: centos2
container_name: centos2
networks:
- nginx
centos3:
image: centos
restart: always
hostname: centos3
container_name: centos3
networks:
- nginx
networks:
nginx:
driver: bridge
volumes:
nginx:
driver: local-persist
driver_opts:
mountpoint: /data/nginx

4.docker-compose中YAML常用的字段:

字段 描述
version: ‘3’ 表示当前yaml文件版本
build dockerfile context 指定dockerfile文件名构建镜像上下文路径
services 相当于容器服务
image 指定镜像
restart 重启策略,默认no,always|on-failurel|unless-stopped
hostname 容器主机名
command 执行命令,覆盖默认命令
container_name 指定容器名称,由于容器名称是唯一的,如果指定自定义名称,则无法scale
ports 暴漏端口,与-p相同,但端口不能低于60
environment 添加环境变量
networks 加入网络,引用顶级networks下条目
extra_hosts 添加主机名的标签,就是往/etc/hosts文件中添加一些记录,与Docker client的–add-host类似:
volumes 挂载宿主机路径或命名卷在顶级volumes定义卷名称
deploy 指定部署和运行服务相关配置,只能在Swarm模式使用
depends_on 这个标签解决了容器的依赖、启动先后的问题。
1
2
3
4
5
6
7
Docker容器的重启策略如下:
restart
no,默认策略,在容器退出时不重启容器
on-failure,在容器非正常退出时(退出状态非0),才会重启容器
on-failure:3,在容器非正常退出时重启容器,最多重启3次
always,在容器退出时总是重启容器
unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器

关于networks

1
2
3
4
5
6
    networks:
- my-bridge #此容器用的my-bridge网络

networks:
my-bridge: #创建的网络名称
driver: bridge #网络模式为桥接

关于volumes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
使用卷:
volumes:
- data01:/var/lib/mysql

创建卷:
volumes:
data01:
driver: local-persist
driver_opts:
mountpoint: /data/a
data10:
driver: local-persist
driver_opts:
mountpoint: /data/b

data01为卷的名字。 /data/a为卷的物理路径。

示列 docker-compose -f docker-compose.yml up 启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
version: '3'
services:
zoo1:
image: zookeeper
restart: unless-stopped
hostname: zoo1
ports:
- "2181:2181"
- "2881:2888"
- "3881:3888"
container_name: zookeeper
networks:
zoo_net:
ipv4_address: 172.18.0.2
extra_hosts:
- "zoo1:172.18.0.2"
- "zoo2:172.18.0.3"
- "zoo3:172.18.0.4"
volumes:
- "/root/kafka/zoo1data:/data"
- "/root/kafka/zoo1data_log:/datalog"
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=zoo1:2881:3881;2181 server.2=zoo2:2882:3882;2181 server.3=zoo3:2883:3883;2181

zoo2:
image: zookeeper
restart: unless-stopped
hostname: zoo2
container_name: zookeeper2
networks:
zoo_net:
ipv4_address: 172.18.0.3
extra_hosts:
- "zoo1:172.18.0.2"
- "zoo2:172.18.0.3"
- "zoo3:172.18.0.4"
ports:
- "2182:2181"
- "2882:2888"
- "3882:3888"
volumes:
- "/root/kafka/zoo2data:/data"
- "/root/kafka/zoo2data_log:/datalog"

environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2881:3881;2181 server.2=zoo2:2882:3882;2181 server.3=zoo3:2883:3883;2181

zoo3:
image: zookeeper
restart: unless-stopped
hostname: zoo3
container_name: zookeeper3
networks:
zoo_net:
ipv4_address: 172.18.0.4
extra_hosts:
- "zoo1:172.18.0.2"
- "zoo2:172.18.0.3"
- "zoo3:172.18.0.4"
ports:
- "2183:2181"
- "2883:2888"
- "3883:3888"
volumes:
- "/root/kafka/zoo3data:/data"
- "/root/kafka/zoo3data_log:/datalog"

environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2881:3881;2181 server.2=zoo2:2882:3882;2181 server.3=zoo3:2883:3883;2181

kafka1:
image: wurstmeister/kafka
ports:
- "9092:9092"
extra_hosts:
- "zoo1:172.18.0.2"
- "zoo2:172.18.0.3"
- "zoo3:172.18.0.4"
networks:
- zoo_net
restart: always

environment:
KAFKA_ADVERTISED_HOST_NAME: 192.161.87.218 ## 修改:宿主机IP
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.161.87.218:9092 ## 修改:宿主机IP
KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181"
KAFKA_ADVERTISED_PORT: 9092
KAFKA_BROKER_ID: 1
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
volumes:
- "/root/kafka/kafka1-data:/kafka"
depends_on:
- zoo1
container_name: kafka1
kafka2:
image: wurstmeister/kafka
networks:
- zoo_net
restart: always
ports:
- "9093:9092"
extra_hosts:
- "zoo1:172.18.0.2"
- "zoo2:172.18.0.3"
- "zoo3:172.18.0.4"
volumes:
- "/root/kafka/kafka2-data:/kafka"
environment:
KAFKA_ADVERTISED_HOST_NAME: 192.161.87.218 ## 修改:宿主机IP
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.161.87.218:9093 ## 修改:宿主机IP
KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181"
KAFKA_ADVERTISED_PORT: 9093
KAFKA_BROKER_ID: 2
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
depends_on:
- zoo1
container_name: kafka2
kafka3:
image: wurstmeister/kafka
ports:
- "9094:9092"
restart: always
extra_hosts:
- "zoo1:172.18.0.2"
- "zoo2:172.18.0.3"
- "zoo3:172.18.0.4"
volumes:
- "/root/kafka/kafka3-data:/kafka"

networks:
- zoo_net
environment:
KAFKA_ADVERTISED_HOST_NAME: 192.161.87.218 ## 修改:宿主机IP
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.161.87.218:9094 ## 修改:宿主机IP
KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181"
KAFKA_ADVERTISED_PORT: 9094
KAFKA_BROKER_ID: 3
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
depends_on:
- zoo1
container_name: kafka3
kafka4:
image: wurstmeister/kafka
ports:
- "9095:9092"
restart: always
extra_hosts:
- "zoo1:172.18.0.2"
- "zoo2:172.18.0.3"
- "zoo3:172.18.0.4"
volumes:
- "/root/kafka/kafka4-data:/kafka"

networks:
- zoo_net
environment:
KAFKA_ADVERTISED_HOST_NAME: 192.161.87.218 ## 修改:宿主机IP
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.161.87.218:9095 ## 修改:宿主机IP
KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181"
KAFKA_ADVERTISED_PORT: 9095
KAFKA_BROKER_ID: 4
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
depends_on:
- zoo1
container_name: kafka4



kafka-manager:
image: sheepkiller/kafka-manager ## 镜像:开源的web管理kafka集群的界面
networks:
- zoo_net
environment:
ZK_HOSTS: 192.161.87.218 ## 修改:宿主机IP
ports:
- "9000:9000" ## 暴露端口
depends_on:
- kafka3

networks:
zoo_net:
ipam:
config:
- subnet: 172.18.0.0/16

评论


:D 一言句子获取中...

加载中,最新评论有1分钟缓存...