Docker

一. Docker介绍

1.1 Docker是什么

Docker 是一个开源的应用容器引擎,基于 Go 语言并遵从 Apache2.0 协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

二. Docker的基本操作

2.1 Docker的安装

1
2
1.安装Docker依赖环境
yum -y install yum-utils device-mapper-persistent-data lvm2
1
2
2.下载Docker镜像源
yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
1
2
3
3.安装Docker
yum makecache fast
yum -y install docker-ce
1
2
3
4.启动Docker并设为开机自启
systemctl start docker
systemctl enable docker
1
2
3
4
5
5.测试运行hello world
docker run hello-world
...
Hello from Docker!
...

2.2 Docker的中央仓库

1、Docker官方(hub.docker.com):镜像最全,下载最慢

2、国内镜像网站:网易蜂巢(163yun.com)

​ daocloud(hub.daocloud.io)

3、公司内部私服拉取镜像:

1
2
3
4
5
6
7
8
1.配置/etc/docker/daemon.json
{
"registry-mirrors":["https://registry.docker-cn.com"],
"insecure-registries":["ip:port"]
}
2.重启两个服务
systemctl daemon-reload
systemctl restart docker

2.3 Docker镜像的操作

1
2
3
4
1.拉取镜像到本地
docker pull 镜像名称[:tag]
举个栗子
docker pull daocloud.io/library/nginx:1.18.0
1
2
2.查看本地镜像
docker images
1
2
3.删除本地镜像
docker rmi 镜像id(image id)
1
2
3
4.本地镜像的导入导出
docker save -o 导出路径 镜像id
docker load -i 镜像文件
1
2
5.给镜像添加标签
docker tag 镜像id repository:tag

2.4 Docker容器的操作

1
2
3
4
5
6
1.运行容器
docker run 镜像id/镜像名称[:tag]
docker run -d -p 宿主机端口:容器端口 --name 容器名称 镜像id/镜像名称[:tag]
-d:代表后台运行容器
-p:为了映射linux端口和容器端口
--name:指定容器名称
1
2
3
4
2.查看容器
docker ps -qa
-a:查看所有容器,包括没有运行的
-q:只看容器id
1
2
3
3.查看容器日志
docker logs -f 容器id
-f:可以滚动查看容器日志的最后几行
1
2
4.进入容器内部
docker exec -it 容器id bash
1
2
3
4
5
5.停止/删除容器
docker stop 容器id
docker stop $(docker ps -qa)
docker rm 容器id
docker rm $(docker ps -qa)
1
2
6.启动容器
docker start 容器id

三. Docker数据卷

3.1 数据卷操作

数据卷就是将宿主机的一个目录映射到容器的一个目录中

可以在宿主机的目录中直接操作,容器的目录和文件也会跟着改变

创建好的数据卷会存放在一个默认的目录下:/var/lib/docker/volumes/

1
2
1.创建数据卷
docker volume create 数据卷名称
1
2
3
4
2.查看数据卷详细信息
docker volume inspect 数据卷名称
查看全部数据卷
docker volume ls
1
2
3.删除数据卷
docker volume rm 数据卷名称
1
2
3
4
5
6
7
8
9
10
11
4.应用数据卷
#如果映射数据卷不存在,docker会自动创建,会将容器内部的文件存储在数据卷中
docker run -v 数据卷名称:容器内部路径 镜像id
#直接指定一个路径作为存放路径,建议使用这种
docker run -v 数据卷路径:容器内部路径 镜像id
-v:映射数据卷

#可以在指定路径后面加上权限,一旦设置权限就不可以改了,举个栗子
docker run -v /root/nginx:/etc/nginx:rw nginx
ro:只读
rw:可读可写

3.2 实现容器之间数据同步

–volumes-from可以实现容器之间的数据同步,即使有一台容器挂了也不会影响到数据,别的容器仍然会有数据在。

--volumes-from

举个栗子

1
2
#启动容器一,并创建测试目录
docker run -d -v /root/docker/test1:/test1 -v /root/docker/test2:/test2 --name nginx01 镜像id
1
2
3
#启动容器二,挂载容器一的目录
docker run -d --name nginx02 --volumes-from nginx01 镜像id
docker exec -it 容器二id bash

进入容器二内部后可以看见容器一的test1和test2,这时候无论在容器一还是容器二生成或删除文件都会进行同步

数据共享一

用docker inspect 容器id可以看到两个容器映射的都是同一个目录

数据共享二

四. Dockerfile自定义镜像

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

4.1 创建自定义镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
1.创建一个Dockerfile文件,并指定自定义镜像信息
#Dockerfile中常用信息
FROM: 这个镜像的妈妈是谁?(指定基础镜像)
MAINTAINER: 告诉别人,谁负责养它?(指定维护者信息)
CMD: 你想让它干啥(指定容器run前要做什么,只有最后一个会生效)
ENTRYPOINT: 你想让它干啥(指定容器run前要做什么,可以追加命令)
RUN: 你想让它干啥(指定容器run后要做什么)
COPY: 给它点创业资金(拷贝文件到镜像内部)
ADD: 给它点创业资金(拷贝文件到镜像内部,如果是压缩包会解压了再就行拷贝)
WORKDIR: 我是cd(配置工作目录,栗子:如果WORKDIR配置了/home,那么COPY和ADD使用.作为拷贝路径的话都会拷贝到/home下)
VOLUME: 给一个存放行李的地方(设置数据卷,挂载到主机目录)
EXPOSE: 给一个门(指定对外开放的端口号)
ENV: 设置环境变量(environment,也就是参数-e)
1
2
2.在linux上通过docker指定镜像
docker build -t 镜像名称:[tag] .
1
2
3
4
3.举个nginx栗子
cat Dockerfile
FROM daocloud.io/library/nginx:1.18.0
COPY test.html /usr/share/nginx/html/test.html

4.2 CMD和ENTRYPOINT的区别

用CMD和ENTRYPOINT做同一个测试

CMD

1
2
1.创建Dockerfile文件
vim /root/docker/Dockerfile
1
2
3
2.编写
FROM daocloud.io/library/centos:latest
CMD ["ls","-a"]
1
2
3.生成镜像文件
docker build -f /root/docker/Dockerfile -t cmd_centos:1.0 .
1
2
4.启动容器,会发现执行了ls -a
docker run cmd_centos镜像id

cmd测试一

如果启动镜像的时候再加参数会报错,但完整的命令就可以

cmd测试二

cmd测试三

ENTRYPOINT

1
2
3
#除了Dockerfile中的CMD换成了ENTRYPOINT外其它都一样
FROM daocloud.io/library/centos:latest
ENTRYPOINT ["ls","-a"]

这时候我们再追加参数发现可以了,这就是ENTRYPOINT比起CMD有可以追加参数的不同

entrypoint测试一

4.3 制作Tomcat镜像

  1. 准备tomcat压缩包和jdk压缩包

    创建tomcat镜像一.png

  2. 编写Dockerfile文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FROM daocloud.io/library/centos:7
MAINTAINER cqm's diy tomcat<chenqiming13@qq.com>

ADD jdk-8u271-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.41.tar.gz /usr/local

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH #进入容器后就会进入MYPATH目录
ENV JAVA_HOME /usr/local/jdk1.8.0_271
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.41
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.41
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.41/bin/startup.sh && tailf /usr/local/apache-tomcat-9.0.41/bin/logs/catalina.out
  1. 生成tomcat镜像
1
docker build -t cqm_tomcat:1.0 .
  1. 启动容器
1
docker run -d -p 8080:8080 --name cqm_tomcat -v /root/tomcat/test:/usr/local/apache-tomcat-9.0.41/webapps/test -v /root/tomcat/logs:/usr/local/apache-tomcat-9.0.41/logs cqm_tomcat镜像id
  1. 访问测试

    创建tomcat镜像二

  2. 上传项目

    1
    2
    3
    cd /root/tomcat/test
    mkdir WEB-INF && cd WEB-INF
    vim web.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
    <display-name>db</display-name>
    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    </web-app>
    1
    vim ../index.hsp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>cqm's tomcat</title>
    </head>
    <body>
    this is cqm's tomcat web!!!<br/>
    <%
    System.out.println("-----this is cqm's tomcat web logs-----");
    %>
    </body>
    </html>
  3. 查看项目是否部署成功

创建tomcat镜像三

创建tomcat镜像四

4.4 上传自定义镜像到Docker Hub

1
2
3
4
5
6
7
1.登录docker账号
docker login -u docker用户名
...
Login Succeeded

#退出账号
docker logout
1
2
3
4
5
6
7
1.登录docker账号
docker login -u docker用户名
...
Login Succeeded

#退出账号
docker logout
1
2
2.给要上传的镜像添加标签
docker tag 镜像id docker用户名/镜像名称:版本号
1
2
3.上传镜像到Docker Hub
docker push 镜像id docker用户名/镜像名称:版本号

上传镜像到dockerhub

五. Docker网络

Docker使用桥接模式在Linux主机上添加一个docker0的网卡,而Docker每启动一个容器就会添加一个新的网卡,使用的是evth-pair技术。evth-pair就是一对虚拟设备接口,添加的网卡都是成对出现的,一段连接镜像,一段连接docker0,所以evth-pair就是一座桥梁,用来连接各种虚拟网络设备。

  1. 利用ip addr来查看Linux主机的网卡情况,可以看到docker0网卡

docker0

  1. 我们拉取一个镜像,并启动

docker网络一

  1. 我们在使用ip addr可以看到出现了对新的网卡

docker网络二

  1. 进入容器内部查看网卡可以看到是对应的

docker网络三

  1. 由此可知docker网络的架构

docker网络四

5.1创建自定义网络

  1. 创建自定义网络
1
2
3
4
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 cqmnet
--driver:网络类型,bridge为桥接
--subnet:配置子网
--gateway:配置网关地址

自定义网络一

  1. 启动两个tomcat容器并指定自定义网络
1
2
docker run -d -p 8081:8080 --net cqmnet --name tomcat01 镜像id
docker run -d -p 8082:8080 --net cqmnet --name tomcat02 镜像id

自定义网络二

  1. 测试两个容器之间是否连通

自定义网络二

5.2 实现docker0和自定义网络之间的连通

  1. 创建两个docker0网段的容器
1
2
docker run -d -p 8083:8080 --name tomcat03 镜像id
docker run -d -p 8084:8080 --name tomcat04 镜像id

自定义网络二

自定义网络二

  1. 利用coonnect进行连通
1
docker network connect cqmnet tomcat03
  1. 这时候再看自定义网络的信息,可以看到tomcat03被添加进来了

自定义网络六

  1. 测试

自定义网络六

  1. 结论,由此可知,connect是将一个网络中的容器添加到另一个网络中,通俗来讲就是该容器同时拥有两个网络的地址,就实现了两个网络之间的互通。

自定义网络六自定义网络九

5.3 不同主机之间容器的互联

方法一:静态路由

静态路由方法原理就是将容器的请求转发到指定的主机上,再由主机转发给容器。

  1. 修改 daemon.json 添加以下内容,使之每个主机的 docker 默认网段不同
1
2
3
4
# 主机一
"bip": "172.17.1.10/24"
# 主机二
"bip": "172.17.2.10/24"
  1. 添加路由规则
1
2
3
4
# 主机一,网关为主机二的IP地址,即访问172.17.2.0网段的数据包都会被转发到主机二上
route add -net 172.17.2.0 netmask 255.255.255.0 gw 192.168.88.130
# 主机二
route add -net 172.17.1.0 netmask 255.255.255.0 gw 192.168.88.135

方法二:Macvlan

Macvlan 原理是将一张物理网卡虚拟成多块虚拟网卡的技术,使得虚拟网卡与物理网卡的参数等都相同。

  1. 开启网卡的混杂模式
1
ip link set ens33 promisc [on/off] / ifconfig ens33 [-]promisc
  1. 创建 Macvlan 网络
1
2
# 子网和网关均和主机一致
docker network create --driver macvlan --subnet 192.168.88.0/24 --gateway 192.168.88.1 -o parent=ens33 [network_name]
  1. 创建容器需要指定网络
1
docker run -d -it --name centos --net [network_name] --ip 192.168.88.10 centos:7

5.4 Overlay

overlay 是一种在网络架构上进行叠加的虚拟化技术,即在原有的网络框架上叠加一层虚拟网络,从而实现应用在虚拟网络上承载,以及与其它网络业务分离。

在这个overlay网络模式里面,有一个类似于服务网关的地址,然后把这个包转发到物理服务器这个地址,最终通过路由和交换,到达另一个服务器的ip地址。

实现 overlay 网络需要有注册发现中心的键值数据库支持,可以用 consul、etcd、zookeeper 等。

区别:

  • consul:服务发现/全局的分布式 key-value 存储。自带 DNS 查询服务,可以跨数据中心。提供节点的健康检查,可以实现动态的 consul 节点增减,docker 官方的用例推荐。
  • etcd:服务发现/全局的分布式 key-value 存储。静态的服务发现,如果实现动态的新增etcd节点,需要依赖第三方组件。

5.4.1 consul

consul 用于微服务下的服务治理,主要特点有:服务发现、服务配置、健康检查、键值存储、安全服务通信、多数据中心等。

注意:overlay 所需内核版本为 3.18+

consul实现overlay架构

  1. 安装 consul
1
2
curl -O https://releases.hashicorp.com/consul/1.10.3/consul_1.10.3_linux_amd64.zip
unzip consul_1.10.3_linux_amd64.zip
  1. 准备 config.json 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"advertise_addr": "192.168.88.130", # 更改我们向群集中其他节点通告的地址
"bind_addr": "192.168.88.130", # 内部群集通信绑定的地址,这是群集中所有其他节点都应该可以访问的IP地址
"data_dir": "/opt/consul", # 数据存放目录
"server": true, # 是否是server agent节点
"node_name": "server1", # 节点名称
"enable_syslog": true,
"enable_debug": true,
"log_level": "info", # 日志级别
"bootstrap_expect": 3, # 提供数据中心中预期服务器的数量,即需要3台consul server agent
"start_join": ["192.168.88.130", "192.168.88.135", "192.168.88.100"], # 启动时指定节点地址的字符串数组,指定是其他的consul server agent的地址
"retry_join": ["192.168.88.130", "192.168.88.135", "192.168.88.100"], # 允许start_join时失败时,继续重新连接
"ui": true, # 启动ui界面
"client_addr": "0.0.0.0" # Consul将绑定客户端接口的地址,包括HTTP和DNS服务器
}
  1. 启动 consul 查看状态
1
2
3
4
5
./consul agent -config-dir ./config.json
# 查看集群状态
./consul members
# 查看leader
./consul operator raft list-peers
  1. 访问 consul ui

consul_ui

  1. 配置 docker/daemon.json
1
2
3
# 虽然是consul集群,但只能填写一个consul节点的信息
"cluster-store": "consul://192.168.88.130:8500",
"cluster-advertise": "192.168.88.130:2376"
  1. 创建 docker 网络,去到其它主机查看 docker 网络可以看到是已经同步的
1
docker network create --driver overlay consulnet

docker_consul_overlay

  1. 在不同的主机创建容器测试是否能够互联
1
docker run -d --name centos1 --network consulnet centos:7

在容器内部可以看到有两张网卡,eth0 是 overlay 创建的,即一个 vxlan;eth1 则是服务网关的网卡

overlay中容器网卡

5.4.2 etcd

etcd 是一个高可以的键值存储系统,主要用于分享配置和服务发现。

  1. 安装 etcd
1
2
3
4
5
6
7
8
9
10
11
ETCD_VER=v3.5.1
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}

curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
tar -zvxf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz

/tmp/etcd-download-test/etcd --version
/tmp/etcd-download-test/etcdctl version
/tmp/etcd-download-test/etcdutl version
  1. 启动 etcd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HOST=192.168.88.130
CLUSTER_IPS=(192.168.88.130 192.168.88.135 192.168.88.136)
ETCD_DATADIR=/root/etcd/data
nohup ./etcd -name node1 \
-initial-advertise-peer-urls http://$HOST:2380 \
-listen-peer-urls http://$HOST:2380 \
-listen-client-urls http://$HOST:2379,http://127.0.0.1:2379 \
-advertise-client-urls http://$HOST:2379 \
-initial-cluster-token etcd-cluster \
-initial-cluster node1=http://${CLUSTER_IPS[0]}:2380,node2=http://${CLUSTER_IPS[1]}:2380,node3=http://${CLUSTER_IPS[2]}:2380 \
-initial-cluster-state new \
-data-dir $ETCD_DATADIR &
# listen-peer-urls:节点与节点之间数据交换, 因此需要监听在其他节点可以访问的IP地址上,默认端口2380
# listen-client-urls:用户客户机访问etcd数据, 一般监听在本地, 如果需要集中管理, 可以监听在管理服务器可以访问的IP地址上,默认端口2379
# initial-advertise-peer-urls:表示节点监听其他节点同步信号的地址,默认端口2380
# advertise-client-urls:在加入proxy节点后, 会使用该广播地址, 因此需要监听在一个proxy节点可以访问的IP地址上,默认端口2379
  1. 查看 etcd 集群信息和健康状态
1
2
./etcdctl member list
./etcdctl cluster-health
  1. 修改 docker/daemon.json
1
2
"cluster-store": "etcd://192.168.88.130:2379",
"cluster-advertise": "192.168.88.130:2376"
  1. 查看是否注册到 etcd
1
2
./etcdctl ls /
/docker
  1. 创建 docker 网络
1
docker network create --driver overlay etcdnet
  1. 创建容器测试是否互通
1
docker run -d -it --name centos1 --network etcdnet centos:7

5.5 Flannel与Calico

在 Kubernetes 中,使用的网络组件主要为 Flannel 和 Calico 两种,都可以实现不同主机之间容器的通信,使用前提是要有 etcd。

5.5.1 Flannel

Flannel 网络架构如下

flannel

  1. 添加网络配置到 etcd
1
2
3
# Network:flannel网段
# Type:网络类型
./etcdctl set /coreos.com/network/config '{ "Network": "10.0.0.0/24", "Backend": {"Type": "vxlan"} }'
  1. 安装 Flannel
1
curl -O https://github.com/flannel-io/flannel/releases/download/v0.15.0/flannel-v0.15.0-linux-amd64.tar.gz
  1. 启动 Flannel,会生成 /run/flannel/subnet.env,路由表也会加上新规则
1
2
# -etcd-endpoints:etcd地址
./flanneld -etcd-endpoints "http://192.168.88.30:2379"

flannel路由

  1. 生成 docker 参数信息
1
./mk-docker-opts.sh -d /root/etcd/docker -c
  1. 修改 /usr/lib/systemd/system/docker.service
1
2
3
4
5
vim /usr/lib/systemd/system/docker.service
# 添加
EnvironmentFile=/root/etcd/docker
# 在ExecStart后加上
ExecStart=/usr/bin/dockerd $DOCKER_OPTS
  1. 重启 docker 后测试容器是否能够互联

flannel测试

5.5.2 Calico

Calico 是目前企业在 k8s 集群上使用的最多的容器互通网络方案,比起 Flannel 能够实现更过复杂的需求。

Calico 是一种纯三层的解决方案,因此避免了与二层方案相关的数据包封装操作,中间没有任何 NAT 和 overlay,直接走 TCP/IP 协议栈,通过 iptables 实现复杂的网络规则。

calico架构

Calico 组件如下:

  • Felix:运行在每一台主机中,主要负责网络接口管理和监听、路由、ARP 管理、ACL 管理和同步、状态上报等。
  • etcd:分布式键值存储,保证网络数据的一致性。
  • BIDR(BGP Client):每一个主机都会有个 BIDR,用来实现不同的路由协议,Calico 监听主机上 Felix 注入的信息,然后通过 BGP 协议告诉其它节点,从而实现互联。
  • BGP Route Reflector:用于解决网络规模过大的组件。

Calico 工作模式:

  • IPIP:将 IP 数据包再次封装到一个 IP 包里,相当于一个基于网络层的网桥,普通的网桥是基于 Mac 地址的,而 IPIP 能将两端的路由做成一个 tunnel,将其连接。
  • BGP:即边界网关协议。
  1. 在所有主机上下载 Calico Controller
1
curl -o calicoctl -O -L  "https://github.com/projectcalico/calicoctl/releases/download/v3.21.0/calicoctl"
  1. 配置 calicoctl.cfg
1
2
3
4
5
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
etcdEndpoints: http://192.168.88.30:2379
  1. 初始化 Calico
1
2
# ip:宿主机ip
./calicoctl node run --ip=192.168.88.30 -c ./calicoctl.cfg
  1. 查看 Calico 状态
1
./calicoctl node status
  1. 由于新版本的 Calico 不再支持 docker 单独使用,但通过插件可以实现
1
2
3
4
git clone https://github.com/projectcalico/libnetwork-plugin.git
cd libnetwork-plugin
# 下载插件镜像
make image
  1. 运行 libnetwork 容器
1
docker run -d --privileged --name calico-docker-network-plugin --net host --restart always -v /run/docker/plugins:/run/docker/plugins -e ETCD_ENDPOINTS=http://192.168.88.30:2379 calico/libnetwork-plugin
  1. 创建 ippool
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看calico目前地址池
./calicoctl get ippools
# 创建地址池yaml文件
cat ip.yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: ippool-test
spec:
cidr: 10.0.0.0/24
ipipMode: Nerver
natOutgoing: true
disabled: false
nodeSelector: all()
./calicoctl apply -f ip.yaml
  1. 创建 GlobalNetworkPolicy
1
2
3
4
5
6
7
8
9
10
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: gnp-test
spec:
selector: all
ingress:
- action: Allow
egress:
- action: Allow
  1. 创建 docker 网络
1
docker create network -d calico --ipam-driver calico-ipam --subnet 10.0.0.0/24 caliconet
  1. 关闭 ipv6 内核
1
echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6
  1. 创建容器测试
1
docker run -d -it --name centos1 --network caliconet centos:7

六. Docker-Compose

Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

6.1 Docker-Compose使用步骤

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

6.2 安装Docker-Compose

1
2
1.下载
curl -L https://get.daocloud.io/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
1
2
2.赋权
chmod +x /usr/local/bin/docker-compose

6.3 编写Docker-Compose管理MySQL和Nginx容器

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
1.创建数据卷目录
mkdir /root/docker_mysql_nginx/docker_mysql/mysql_data
mkdir /root/docker_mysql_nginx/docker_nginx/nginx_conf
mkdir /root/docker_mysql_nginx/docker_nginx/nginx_html

2.编写
vim /root/docker_mysql_nginx/docker-compose.yml

version: '3.8' #指定本 yml 依从的 compose 哪个版本制定的
#可参考https://docs.docker.com/compose/compose-file/
services:
mysql: #指定服务的名称
restart: always #只要docker启动,这个容器就一起启动
image: daocloud.io/library/mysql:5.7.4 #指定镜像路径
container_name: mysql #指定容器名称
ports:
- 3306:3306 #指定端口号的映射
environment:
MYSQL_ROOT_PASSWORD: toortoor #指定mysql的root用户登录密码
TZ: Asia/Shanghai #指定时区
volumes:
- /root/docker_mysql_nginx/docker_mysql/mysql_data:/var/lib/mysql #映射数据卷

nginx:
restart: always
image: daocloud.io/library/nginx:1.18.0
container_name: nginx
ports:
- 80:80
environment:
TZ: Asia/Shanghai
volumes:
- /root/docker_mysql_nginx/docker_nginx/nginx_conf:/etc/nginx
- /root/docker_mysql_nginx/docker_nginx/nginx_html:/usr/share/nginx/html

6.4 使用Docker-Compose命令

在使用Docker-Compose命令时,系统会在当前目录下寻找yml文件

1
2
3
1.应用Docker-Compose启动容器
docker-compose up -d
-d:在后台运行容器
1
2
2.关闭并删除容器
docker-compose down
1
2
3.开启|关闭|重启已由docker-compose管理的容器
docker-compose start | stop | restart
1
2
4.查看由docker-compose管理的容器
docker-compose ps
1
2
3
5.查看docker-compose日志
docker-compose logs -f
-f:可以滚动查看

6.5 Docker-Compose配合Dockerfile使用

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
version: '3.8'
services:
nginx:
build:
context: ./ #指定在当前目录下寻找dockerfile
dockerfile: Dockerfile #指定dockerfile文件名
image: nginx:1.18.0 #使用上边制作好的镜像
container_name: nginx
ports:
- 8080:80
environment:
TZ: Asia/Shanghai

Dockerfile

1
2
from daocloud.io/library/nginx:1.18.0
copy test.html /usr/share/nginx/html/test.html

遇到的错误

1
2
3
4
5
6
7
8
9
10
11
1.
ERROR: yaml.scanner.ScannerError: while scanning for the next token
found character '\t' that cannot start any token
#是因为yml文件里使用了tab,yml文件格式不允许使用,全部换成空格

2.
WARNING: Image for service nginx was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
#是因为运行docker-compose时自定义镜像不存在,会帮助生成自定义镜像
#提供两种构建方法:
#docker-compose build
#docker-compose up --build

6.6 Docker-Compose部署wordpress

  1. 编写docker-compose.yml
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
version: '3.8'
services:
db:
container_name: mysql
image: daocloud.io/library/mysql:latest
volumes:
- db_data:/var/lib/mysql
restart: always
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: toortoor
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: toortoor

wordpress:
container_name: wordpress
image: wordpress:latest
ports:
- 80:80
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: toortoor
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
  1. 启动
1
docker-compose up -d