docker切记安装前需关闭NetworkManager
直接使用网络安装
wget https://download.docker.com/linux/centos/docker-ce.repo
或自己打包安装
这里使用网络安装及本地打包安装均出现container-selinux包版本低问题
1、首先升级container-selinux包
下载container-selinux包这里使用2.68版本即可
wget http://mirror.centos.org/centos/7/extras/x86_64/Packages/container-selinux-2.74-1.el7.noarch.rpm
wget http://mirror.centos.org/centos/7/extras/x86_64/Packages/container-selinux-2.68-1.el7.noarch.rp
解压container-selinux包发现需要依赖安装依赖后在进行继续解压
2、解压
3、解压完成在安装docker-ce 安装成功
yum install docker-ce -y
Docker使用tab补齐命令,需安装bash-completion
yum install install -y bash-completion -y
source /usr/share/bash-completion/bash_completion
Docker主配置文件
启动docker后会生成一个/etc/docker/key.json
这里测试拉取一个镜像发现出现错误
这个原因在网上找了很多资料发现大多是说因网络原因导致、书写镜像加速源即可但配置阿里镜像加速、中科大镜像加速依旧不行
原因:docker hub 中需创建本地用户作为认证,并本地登录后认证一次即可拉取镜像,拉取镜像时网络速率很慢,因为docker hub为国外网站,这时已经成功拉取镜像后在配置加速源即可;也可能是自己当时的网络不行哈哈.
配置阿里云docker镜像加速
注册并登录阿里云账号—>>进入产品选项中—>>点击容器镜像服务–>>选择镜像加速器—>>复制容器镜像加速地址至/etc/docker/daemon.json如果没有改文件创建即可
[root@server2 docker]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://wuuzskt1.mirror.aliyuncs.com"]
}
[root@server2 ~]# systemctl daemon-reload
[root@server2 ~]# systemctl restart docker
重启docker再次测试上传成功.配置完成.测试拉取镜像会发现变快了许多
查看docker版本,docker info发现出现一些报错,对bridge进行优化
[root@server2 ~]# cd /etc/sysctl.d/
[root@server2 sysctl.d]# vim docker.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
[root@server2 sysctl.d]# sysctl --system
[root@server2 sysctl.d]# docker info 发现报错已消失
Docker
共享宿主机的Kernel
Kernel Version: 3.10.0-862.el7.x86_64
Base镜像提供的是最小的linux发行版
同一docker主机支持多种linux系统
docker采用分层结构最大好处:共享资源
导入镜像 docker load -i 镜像包
[root@server2 ~]# docker load -i game2048.tar
[root@server2 ~]# docker images
启动一个容器 docker run -it --name vm1 镜像
[root@server2 ~]# docker run -it --name vm1 busybox
查看容器运行状态 docker ps -a
[root@server2 ~]# docker ps -a
[root@server2 ~]# docker start vm1
[root@server2 ~]# docker attach vm1
修改容器并保存容器数据
docker commit
把名称为vm1的容器镜像保存为buxybox:v1
[root@server2 ~]# docker commit vm1 buxybox:v1
强制删除vm1
[root@server2 ~]# docker rm -f vm1
启动保存后的buxybox:v1名称为vm1
[root@server2 ~]# docker run -it --name vm1 buxybox:v1
[root@server2 ~]# docker history buxybox:v1
[root@server2 ~]# docker history busybox:latest
明显可以看出是基于busybox:latest创建的新镜像,但里面执行的命令不能显示无法审计.
Docker镜像构建
docker commit构建新镜像
运行容器----->>修改容器------>>保存容器为新镜像
缺点:效率低、可重复性弱、易出错、使用中无法对镜像进行审计,存在安全隐患.
利用docker build构建镜像
利用docker build构建镜像
mkdir /root/docker
vim dockerfile
FROM busybox
RUN echo file1 > file1
RUN echo file2 > file2
[root@server2 docker]# cd /root/docker
[root@server2 docker]# docker build -t test:v1 .
[root@server2 docker]# docker history test:v1
查看新构建镜像
再次构建新镜像
再次构建一个名称为bosybox:v2的新镜像
[root@server2 docker]# vim dockerfile
FROM busybox
RUN echo file1 > file1
RUN echo file2 > file2
RUN echo file3 > file3
[root@server2 docker]# docker build -t bosybox:v2 .
这里发现前面执行过的任务时已cache形式执行,只有改变的会再次进行新建这样能更有效的提高效率、和安全审计.
[root@server2 docker]# docker history bosybox:v2
Dockerfile常用指令
FROM 指base镜像,如果镜像不存在则通过远程仓库进行下载.
MAINTAINER 设置镜像作者及邮箱等作者相关信息.
COPY 指令能够将构建命令所在的主机本地的文件或目录,复制到镜像文件系统.
COPY
Copy的文件必须和dockerfile同目录下不然会出息找不到目录
例:
[root@server2 ~]# echo hi > /root/file
[root@server2 ~]# cd docker
[root@server2 docker]# vim dockerfile
COPY /root/file /tmp
[root@server2 docker]# docker build -t bosybox:v3
[root@server2 docker]# echo lalala > file
[root@server2 docker]# docker build -t bosybox:v3 .
[root@server2 docker]# docker run -it --name vmm2 bosybox:v3
ADD 命令格式和copy相同用法类似.
除了不能用在 multistage 的场景下,ADD 命令可以完成 COPY 命令的所有功能,并且还可以完成两类超酷的功能:
解压压缩文件并把它们添加到镜像中;
从 url 拷贝文件到镜像中
当然,这些功能也让 ADD 命令用起来复杂一些,不如 COPY 命令那么直观.
ADD
ADD a.tar /root
ADD http://IP/.tar /root
测试ADD使用
首先在dockerfile目录中放置一个tar包,并修改dockerfile在进行docker build
[root@server2 ~]# cp nginx-1.17.1.tar docker
[root@server2 docker]# vim dockerfile
ADD nginx-1.17.1.tar /tmp
[root@server2 docker]# docker build -t bosybox:v4 .
[root@server2 docker]# docker run -it --name vm1 bosybox:v4
ENV 定义环境变量
ENV hostname
EXPOSTS 暴露的端口号
VOLUME 申明数据卷挂载点
[root@server2 docker]# vim dockerfile
VOLUME ["/data"]
[root@server2 docker]# docker build -t bosybox:v5 .
[root@server2 docker]# docker run -it --name vm1 bosybox
[root@server2 docker]# docker inspect vm2
“Source”: “/var/lib/docker/volumes/a3343980370e534e391dd9dd164c6c9db9d741146063f50d5ab30c6125d354df/_data”,
进入目录创建文件并查看是否数据同步
[root@server2 docker]# cd /var/lib/docker/volumes/a3343980370e534e391dd9dd164c6c9db9d741146063f50d5ab30c6125d354df/_data
[root@server2 _data]# ls
[root@server2 _data]# touch file1
[root@server2 _data]# echo hello > file1
[root@server2 _data]# docker attach vm2
明显可以看出挂载点与容器镜像是数据同步的.是一个地方的且如果没有这个目录自动创建.
如果需要手动设置挂载点不使用默认的/var/lib/docker/* 挂载点我们可以手动设置
例:
在重新启动一个vm3并加入-v参数冒号前面挂载点冒号后面容器镜像目录
[root@server2 _data]# docker run -it --name vm3 -v /tmp/data:/data bosybox:v5
WORKDIR
为RUN、CMD、ENTRYPOINT、ADD、COPY等指令设置镜像中当前工作目录,如果不存在则自动创建.
RUN
在容器中运行命令并创建新的镜像层,用于安装软件等服务.
RUN yum install bind-* -y
CMD、ENTRYPOINT
这两个指令都是用于容器启动后执行的命令,但CMD会被docker run后面的命令覆盖,而 ENTRYPOINT不会被忽略,一定会被执行.
docker run 后面的参数可以传递给ENTRYPOINT指令当做参数.
Dockerfile中只能指定一个ENTRYPOINT,如果指定了多个,只有最后一个有效,其他无效.
CMD指令
1)、exec格式用法 (常用)
exec格式,也被称为JSON风格[“command”,“arg1”].
CMD ["echo","hello", "world"]
CMD ["sh", "-c", "echo $HOME"]
2)、shell格式用法
CMD echo $HW
/bin/sh -c echo $HW
例:
[root@server2 docker]# vim dockerfile
CMD echo "This is a test."
[root@server2 docker]# docker build -t bosybox:v7 .
[root@server2 docker]# docker run --rm --name vm7 bosybox:v7
[root@server2 docker]# vim dockerfile
CMD echo "This is a test."
CMD ["echo" , "This is a test1"]
CMD ["echo" , "This is a test2"]
[root@server2 docker]# docker build -t bosybox:v8 .
[root@server2 docker]# docker run --rm --name vm8 bosybox:v8
可以明显看到CMD参数如果有只调用最后一个指令
ENTRYPOINT指令
例:
[root@server2 docker]# vim dockerfile
CMD echo "This is a test."
ENTRYPOINT ["echo", "hello"]
CMD ["echo" , "This is a test1"]
CMD ["echo" , "This is a test2"]
[root@server2 docker]# docker build -t bosybox:v9 .
[root@server2 docker]# docker run --rm --name v9 bosybox:v9
可以明显看到如果有ENTRYPOINT会先行调用ENTRYPOINT后在调用最后一个CMD且不会被执行,也就是说ENTRYPOINT是容器启动后真正要执行的命令,CMD则是容器默认执行命令,如果不额外指定就执行cmd如果额外指定则会被覆盖原数据.
3)shell格式用法
ENTRYPOINT exec echo “nihao”
ENTRYPOINT ps -aux
例:
[root@server2 docker]# vim dockerfile
ENTRYPOINT ["echo", "hello"]
ENTRYPOINT exec ps aux
CMD ["echo" , "This is a test1"]
CMD ["echo" , "This is a test2"]
[root@server2 docker]# docker build -t bosybox:v9 .
[root@server2 docker]# docker run --rm --name v9 bosybox:v9
ENTRYPOINT ["echo", "hello"]
CMD ["echo" , "This is a test1"]
CMD ["echo" , "This is a test2"]
CMD echo "This is a test."
可以明显看到如果dockerfile中ENTRYPOINT使用shell格式书写则只执行ENTRYPOINT中最后的指令,如果以exec格式书写则执行最后一个指令后执行CMD指令.
利用dockerfile安装nginx服务
首先下载centos镜像并在本地搭建yum源或利用外网yum源也行,这里在本地搭建http源安装
[root@server2 docker]# docker pull centos
[root@server2 docker]# vi /etc/yum.repos.d/yum.repo
[yum]
name=yum
baseurl=http://192.168.43.111:8080/rhel7.5
gpgcheck=0
在本地生成nginx主页面并拷贝安装nginx所需yum源
[root@server2 docker]# echo hello docker > /root/docker/index.html
[root@server2 docker]# cp /etc/yum.repos.d/yum.repo /root/docker/
配置dockerfile
[root@server2 docker]# vim dockerfile
FROM centos
EXPOSE 80
MAINTAINER [email protected]
COPY yum.repo /etc/yum.repos.d/
ADD nginx-1.17.1.tar /opt
WORKDIR /opt/nginx-1.17.1
#RUN rpmdb --rebuilddb && yum clean all && yum install -y gcc make pcre-devel zlib-devel
RUN rpmdb --rebuilddb && yum clean all && yum install -y gcc make pcre-devel zlib-devel && ./configure --prefix=/usr/local/nginx && make && make install
COPY index.html /usr/local/nginx/html/
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server2 docker]# docker build -t web1 .
[root@server2 docker]# docker run -it --name web web1:latest
查看web所对应的IP是否生成
[root@server2 data]# docker inspect web
[root@server2 data]# curl 172.17.0.4
hello docker
因为没有做端口映射所有只能访问docker内置Ip在进行映射
启动web2并进行映射 -p端口映射
[root@server2 data]# docker run -p 80:80 -it --name web2 web1:latest
[root@server2 data]# docker inspect web2
[root@server2 data]# curl 172.17.0.4
[root@server2 data]# curl 172.17.0.1
[root@server2 data]# netstat -antlp
[root@server2 data]# curl 192.168.43.111
Docker 多阶段构建镜像
对容器镜像进行精简.
例:对源码编译安装nginx进行精简
编辑dockerfile
[root@server2 docker]# vim dockerfile
FROM centos as build
EXPOSE 80
MAINTAINER [email protected]
COPY yum.repo /etc/yum.repos.d/
ADD nginx-1.17.1.tar /opt
WORKDIR /opt/nginx-1.17.1
#RUN rpmdb --rebuilddb && yum clean all && yum install -y gcc make pcre-devel zlib-devel
RUN rpmdb --rebuilddb && yum clean all && yum install -y gcc make pcre-devel zlib-devel && ./configure --prefix=/usr/local/nginx && make && make install
COPY index.html /usr/local/nginx/html/
FROM centos
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY --from=build /usr/local/nginx/ /usr/local/nginx/
COPY index.html /usr/local/nginx/html/
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server2 docker]# docker build -t nginx:web2 .
可以明显看到精简后nginx服务只有4M如果去除取消debug会发现只有nginx服务只有1M
[root@server2 docker]# vim dockerfile
FROM centos as build
EXPOSE 80
MAINTAINER [email protected]
COPY yum.repo /etc/yum.repos.d/
ADD nginx-1.17.1.tar /opt
WORKDIR /opt/nginx-1.17.1
RUN sed -i '172s/^/#/g' /opt/nginx-1.17.1/auto/cc/gcc
#RUN rpmdb --rebuilddb && yum clean all && yum install -y gcc make pcre-devel zlib-devel
RUN rpmdb --rebuilddb && yum clean all && yum install -y gcc make pcre-devel zlib-devel && ./configure --prefix=/usr/local/nginx && make && make install
COPY index.html /usr/local/nginx/html/
FROM centos
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY --from=build /usr/local/nginx/ /usr/local/nginx/
COPY index.html /usr/local/nginx/html/
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server2 docker]# docker build -t nginx:web4 .
[root@server2 docker]# docker run -d --name web3 nginx:web4
[root@server2 docker]# docker inspect web3
Registry 工作原理
一、用户拉取镜像
1.用户发送请求到index来下载镜像。
2.index 响应返回三个相关部分信息:
该镜像位于的registry
该镜像包括所有层的校验
以授权目的Token
3.用户通过响应中返回的Token和registry沟通,registry全权负责镜像,它存储基本的镜像和继承的层。
4.registry现在要与index证实该token是被授权的。
index会发送“true” 或者 “false”给registry,由此允许用户下载所需要的镜像。
二、用户推送镜像至Registry
1.用户发送带证书请求到index要求分配库名。
2.在成功认证,命名空间可用以及库名被分配之后。index响应返回临时的token。
3.镜像连带token,一起被推送到registry中。
4.registry与index证实token,然后在index验证之后开始读取推送流。
5.该index然后更新由Docker生成的镜像校验。
三、用户从index或Registry中删除镜像
1.index接收来自Docker一个删除库的信号。
2.如果index验证库成功,它将删除该库,并返回一个临时token。
3.registry现在接收到带有该token的删除信号。
4.registry与index核实该token,然后删除库以及所有相关信息。
Docker现在通知有关删除的index,然后index移除库的所有记录。
Docker私有仓库搭建
1、首先需下载registry
2、映射registry端口
3、修改push镜像名称为本地名称
4、Push镜像及pull镜像并查看镜像存放点.
[root@server2 docker]# docker pull registry
启动registry并打入后台运行并进行端口映射registry默认为5000端口
[root@server2 docker]# docker run -d --name registry -p 5000:5000 registry
查看数据卷
[root@server2 docker]# docker volume ls
修改nginx名称
[root@server2 ~]# docker tag nginx:latest localhost:5000/nginx:latest
上传至本地仓库
[root@server2 ~]# docker push localhost:5000/nginx:latest
[root@server2 docker]# curl localhost:5000/v2/_catalog
{"repositories":["nginx"]}
[root@server2 ~]# docker inspect registry
[root@server2~]#cd /var/lib/docker/volumes/7c37e0e131e301fddc253827aa24406032e5e44bb18b011c3911302d8d6cc317/_data
[root@server2 _data]# ls
docker
[root@server2 _data]# cd docker/
[root@server2 docker]# tree
[root@server2 ~]# mkdir -p certs
openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key \
-x509 -days 365 -out certs/westos.org.crt
[root@server3 ~]# vim /etc/hosts
192.168.43.112 westos.org
启动registry并设置为开机自启并配置key认证及端口映射
docker run -d \
--restart=always \
--name registry \
-v "$(pwd)"/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key \
-p 443:443 \
registry
[root@server3 ~]# netstat -antlp | grep 443
[root@server3 ~]# cd /etc/docker/
[root@server3 docker]# mkdir certs.d
[root@server3 docker]# cd certs.d/
[root@server3 certs.d]# mkdir westos.org
[root@server3 westos.org]# cp /root/certs/westos.org.crt ca.crt
[root@server3 /]# docker tag ubuntu:latest westos.org/ubuntu:latest
[root@server2 ~]# mkdir auth
[root@server2 ~]# docker run --rm --entrypoint htpasswd registry -Bbn admin lichen > auth/htpasswd
[root@server2 ~]# docker run --rm --entrypoint htpasswd registry -Bbn root redhat >> auth/htpasswd
[root@server2 ~]# docker rm -f registry
启动registry并加入用户认证功能
Registry默认为5000端口这里是改为443默认的不需要添加参数直接 -p就可以
docker run -d \
--restart=always \
--name registry \
-v "$(pwd)"/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key \
-p 443:443 \
-v "$(pwd)"/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry
登录测试
[root@server3 ~]# docker login westos.org
[root@server3 ~]# docker logout westos.org
[root@server3 ~]# docker push westos.org/ubuntu:latest
客户端连接私有仓库
再启动一台服务器并安装docker服务
首先在客户端启动docker配置hosts解析并添加客户端认证key
这里客户端为192.168.43.111服务器为192.168.43…112
在客户端配置hosts
[root@server2 ~]# vim /etc/hosts
192.168.43.112 westos.org
在服务端拷贝客户端认证key
[root@server3 ~]# scp -r /etc/docker/certs.d/ [email protected]:/etc/docker/
利用docker-registry-web制作web界显示上传后镜像
[root@server3 docker]# docker pull hyper/docker-registry-web
[root@server3 docker]# docker images
docker run -it -p 8080:8080 --name registry-web --link registry:westos.org \
-e REGISTRY_URL=https://westos.org/v2 \
-e REGISTRY_TRUST_ANY_SSL=true \
-e REGISTRY_BASIC_AUTH="eHR0OnJlZGhhdA==" \
-e REGISTRY_NAME=westos.org:443 hyper/docker-registry-web
等待启动成功后登录web页面查看所上传的镜像
Docker 网络
Docker原生网络
Docker安装完成后会自动创建三种网络: bridge host none
使用docker network ls查看
Bridge 模式下容器没有一个公有IP,只有宿主机可以直接访问,外部主机不可见
容器通过宿主机的NAT规则访问外网.
打开net.ipv4.ip_forward=1 内核路由转发功能启用
例:
docker run -it --name vm centos
docker inspect vm
Host网络模式需要在容器创建时指定 --network=host
Host模式可以让容器共享宿主机网络栈
好处:可以与主机直接通信.
坏处:容器确实隔离性.
例:
docker run -it --name vm1 --network=host centos
yum install net-tools -y
Ifconfig
docker run -it --name vm3 --network=none ubuntu
ip addr
Docker 自定义网络
Docker自定义网络模式提供了三种自定义网络驱动:
Bridge overlay macvlan
Bridge网络驱动类似bridge网络模式,但增加了新功能,overlay和macvlan用于创建跨主机网络
一般使用自定义网络来控制容器见项目通信,可自动进行DNS解析容器名称至IP地址
创建自定义网络网络名称为network1
创建自定义网络-d默认为bridge 如需更改模式只需修改-d后
docker network create -d bridge network1
docker run -it --name vm1 --network network1 ubuntu
查看network1IP地址bridge默认不指定IP会以单调递增方式进行添加IP
创建自定义网络指定IP为172.66.0.0/24 --subnet IP --gateway 网关
docker network create -d bridge --subnet 172.66.0.0/24 --gateway 172.66.0.1 network2
docker run -it --name vm2 --network network2 ubuntu
创建成果但容器内部IP也为单调递增方式如需指定IP地址需添加 --ip参数
使用–IP参数时必须使用指定网桥IP否则–ip不生效
docker run -it --name vm3 --network network2 --ip 172.66.0.55 ubuntu
Docker桥接在不同网桥上容器是无法通信的,因docker设计时就是要隔离不同的network
如需两个不同网桥上容器间要相互通信则需要添加一块网卡
docker network connect network2 vm1 在vm1中添加一个network2中IP
docker container attach vm1 或者 docker attach vm1 进入vm1查看ip
docker container attach vm1
ping 172.66.0.55
Ping vm2
Docker 自定义网络中自动会默认DNS解析IP地址 注意:必须是自定义网络模式
Joined 容器是一种特别的网络模式
在创建容器时添加 --network=conatiner:vm1(容器名称)
docker run -it --name vm4 --network container:vm1 ubuntu
可以发现这个模式下docker容器会共享同一个网络栈.此时vm4与vm1IP地址是相同的
链接两个容器 使用–link
–link < name or id >:alias
Name or id 是源容器名称
Alias源容器在link下的别名
docker run -d nginx
docker inspect pedantic_nightingale
docker run -it --name vm5 --link pedantic_nightingale:nginx1 ubuntu
ping nginx1
env
可以明显发现在link后docker会自动更新/etc/hosts及nginx中的变量传递至当前容器
停止nginx容器并再次创建一个容器后开启nginx容器再次查看
docker ps -a
docker stop pedantic_nightingale
docker run -d nginx
docker inspect focused_dubinsky 容器会默认单调递增增加IP
docker start pedantic_nightingale
docker inspect pedantic_nightingale
docker container attach vm5
cat /etc/hosts
可以发现–link会自动进行更新/etc/hosts文件
但vm5中nginx变量还未能传递更新过来,这时需要再次重启容器后就更新正常
docker stop vm5
docker start vm5
docker container attach vm5
Env
Iptables -t nat -S
-A POSTROUTING -s 172.66.0.0/24 ! -o br-f9a1366b62d0 -j MASQUERADE
-A POSTROUTING -s 172.18.0.0/16 ! -o br-6ffa5dfd2ab9 -j MASQUERADE
docker run -d --name vm6 -p 80:80 nginx
iptables -t nat -S
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.6:80
可以明显看到内部访问首先访问宿主机80端口并通过防火墙DNAT转换至容器内80端口
ps -aux | grep docker-proxy
Docker-proxy处理端口映射转发的数据包
而外部主机访问容器首先访问docker-proxy传入数据至docker0网关在通过docker0传入容器内
Docker跨主机容器网络
Docker 原生的网络overlay和macvlan
第三方:flannel、weave、calico
Docker跨主机容器通信
开启两台docker主机并在两台源主机中添加一块网卡并开启网卡混杂模式(promisc)
Docker network prune 清理网络模式 或docker network rm 网络名称
ip addr show ens34
ip link set ens34 promisc on
在两台docker中做同样步骤 创建一个macvlan 并制定网卡为ens34
docker network prune
docker network create -d macvlan --subnet 172.22.0.0/24 --gateway 172.22.0.1 -o parent=ens34 macvlan1
在docker1中启动ubuntu镜像并制定ip地址为172.22.0.12
docker run -it --name vm2 --network macvlan1 --ip 172.22.0.12 ubuntu
ping 172.22.0.13
在docker2中启动ubuntu镜像并制定ip地址为172.22.0.13
docker run -it --name vm2 --network macvlan1 --ip 172.22.0.13 ubuntu
ping 172.22.0.12
两台主机通讯正常
brctl show 查看网桥
Macvlan网络容器的接口直接与主机网卡连接,不需要NAT或端口映射,性能好
Macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络
Vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,vlan id 取值为1 ~ 4094
创建vlan子接口
在docker1中创建并启动新容器vm3
docker network create -d macvlan --subnet 172.23.0.0/24 --gateway 172.23.0.1 -o parent=ens34.1 macvlan2
docker run -it --name vm3 --network macvlan2 --ip 172.23.0.12 ubuntu
在docker2中创建并启动新容器vm3
docker network create -d macvlan --subnet 172.23.0.0/24 --gateway 172.23.0.1 -o parent=ens34.1 macvlan2
docker run -it --name vm3 --network macvlan2 --ip 172.23.0.13 ubuntu
查看通信情况
可以发现不同macvlan彼此之间相互隔离
Macvlan网络在二层上是隔离的,所以不同macvlan网络容器是不能通信的
可以通过三层网关将macvlan网络联通起来
Docker本身不做任何限制,与传统vlan网络管理相同.
Docker数据卷
Docker分层文件系统 性能差,生命周期与容器相同
Docker数据卷
Mount至主机,绕开分层文件系统;和主机磁盘性能相同,容器删除后依然保留;仅限本地磁盘不能随容器仅限迁移
Docker提供了两种卷
Bind mount docker managed volume
Bind mount 将主机上文件或目录直接以mount至容器中
格式 -v :(rwx)
例:
docker run -d --name web1 -v /opt/web:/usr/share/nginx/html -p 80:80 nginx
curl localhost
cd /opt/web/
echo web1 > index.html
curl localhost
容器目录挂载如没有此目录则新建目录,如容器挂载目录有文件则本地目录覆盖或替换容器挂载目录文件。
如需要登录进入如应用容器不能使用docker attach web1会发现卡住
再次启动后使用exec进入
docker exec -it web1 bash
cd /usr/share/nginx/html/
echo localhost >> index.html
curl localhost
docker run -it --name vm1 -v /opt/nihao:/nihao -v /etc/yum.repos.d/yum.repo:/etc/yum.repos.d/yum.repo:ro centos
Docker managed volum
Bind mount 必须制定host文件系统路径,限制了移植性
Docker managed volume 不需要制定mount源,docker自动为容器创建数据卷目录.
默认挂载位置/var/lib/docker/volumes如果挂载时指向容器内已有的目录,则原有目录中的数据会复制至volume中
例:
docker run -d --name nginx1 -v /usr/share/nginx/html -p 80:80 nginx
Docker 自动生成挂载地址 source
进入挂载目录并修改index页面
手动指定目录挂载名称,同个目录可进行多个挂载.
docker rm -f nginx1
docker run -d --name nginx1 -v web1:/usr/share/nginx/html -p 80:80 nginx
docker inspect nginx1
docker volume create web2
创建成功会在/var/lib/docker/volumes/生成目录
创建完成后在进行挂载
docker run -d --name nginx5 -v web2:/usr/share/nginx/html nginx
可以发现创建自定义volume挂载后可以自定义多个挂载,且用法简单
Bind mount 与docker managed volume区别
Bind mount 可任意指定volume位置
Bind mount 对容器挂载点隐藏并替换volume
Bind mount 支持单个文件如file、test等单个文件
Bind mount 权限 可设置读写只读等权限
Bind mount 移植性弱,与host path绑定
docker managed volume 挂载卷在/var/lib/docker/volumes/下
Docker managed volume 对容器挂载点原有数据复制至volume
Docker managed volume 只能为目录不支持文件形式
Docker managed volume 权限 无控制,均为读写权限
Docker managed volume 移植性强,无需指定host path目录
Docker volume插件 可根据官方插件进行配置
https://docs.docker.com/engine/extend/legacy_plugins
本地利用convoy插件配置卷
首先需要在两台docker中配置文件存储 这里利用nfs实验
在Docker1中
yum install nfs-utils -y
systemctl start rpcbind
mkdir /mnt/nfs
vim /etc/exports
/mnt/nfs *(rw,no_root_squash) 这里测试no_root_squash不建议使用
systemctl start nfs
在docker2配置
showmount -e 192.168.43.111
mkdir /opt/data
mount 192.168.43.111:/mnt/nfs /opt/data
挂载成功后安装convoy,两台docker都需要安装convoy
tar xf convoy.tar.gz
cp convoy/convoy convoy/convoy-pdata_tools /usr/local/bin/
注这里启动convoy服务path指定的是nfs挂载目录也就是docker1在/mnt/nfs中docker2在/opt/data中否则不能启动
convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs/ &
convoy daemon --drivers vfs --driver-opts vfs.path=/opt/data &
ll /var/run/convoy/convoy.sock
mkdir /etc/docker/plugins
echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
创建卷
convoy create volume1
convoy inspect volume1 查看卷详细信息
convoy list 列出所有卷
如需查看更多使用方法convoy --help
创建卷后在那台服务器创建就默认在哪个vfs.path下这里用docker2创建默认为/opt/data
docker run -it --name vm1 -v volume1:/data ubuntu
进入查看文件共享情况,共享成功.
删除后重新挂载数据依旧保存
docker rm -f vm1
docker run -it --name vm3 -v volume1:/nihao ubuntu
注:哪个docker创建的卷,启动docker镜像挂载卷时必须在哪个创建docker中
Docker容器资源控制
对CPU额度进行控制,利用cgroup进行限制
手动进行CPU限制
mount -t cgroup
进入/sys/fs/cgroup/cpu/下创建一个目录名字随意,创建完成会默认生成CPU控制文件
Docker 的限制在/sys/fs/cgroup/cpu(blkio、memory等等)/docker下自动生成
cd /sys/fs/cgroup/cpu/
mkdir xx
cpu.cfs_period_us 默认100毫秒
cpu.cfs_quota_us 控制CPU利用率
tasks 这个文件对应进程PID
修改CPU控制率为30%
例:
dd if=/dev/zero of=/dev/null &
echo 30000 > cpu.cfs_quota_us
echo 26528 > tasks
docker run -it --name vm5 --cpu-period 100000 --cpu-quota 20000 centos
dd if=/dev/zero of=/dev/null &
docker inspect vm5 | grep Pid
对内存的控制
/sys/fs/cgroup/memory
memory.limit_in_bytes 内存的限制
memory.memsw.limit_in_bytes 交换分区(本地磁盘不够用了会自动使用)
如需做限制可对两个同时做限制。
如需对docker内存进行配额
–memory 设置内存使用限制
–memory-swap 交换分区
例:
docker run -it --name vm6 --memory 300M --memory-swap 300M centos
对blkio限额
/sys/fs/cgroup/blkio/
blkio.throttle.read_bps_device 读数据
blkio.throttle.write_bps_device 写数据
例
1048576=1024*1024 写入速度为1M
cd
cgexec -g blkio:io dd if=/dev/zero of=lalala bs=1M count=15 oflag=direct (oflag当前目录下文件)
dd if=/dev/zero of=lalala bs=1M count=15
对比明显可以看出做了限额之后写入速度为1M
如对docker的blkio做写限制
docker run -it --name vm7 --device-write-bps /dev/sda:1MB centos
Docker 基于lxcfs增强docker隔离性
如
docker run -it --name vm7 -m 300M centos 配置内存后显示问题
yum install lxcfs-2.0.5-3.el7.centos.x86_64.rpm -y
systemctl start lxcfs 或lxcfs /var/lib/lxcfs/ &
/var/lib/lxcfs/proc 存放cpu、mem、swap等信息
docker run -it --name vm8 -m 300M -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo centos
如需对cpu、swap等进行限制直接-v挂载/var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo
systemctl enable lxcfs 开机自启
Docker 特权
Docker 镜像默认启动时显示root用户但无root用户的所有权限如需开发特权
例:
ifconfig eth0:1 172.16.0.5 netmask 255.255.255.0
可以发现不能正常添加一个临时IP
添加 --privileged 特权
docker run -it --rm --name vm9 --privileged centos
因–privileged 权限过大不安全所以docker提供白名单机制使用–cap-add添加所需权限
http://man7.org/linux/man-pages/man7/capabilities.7.html acp-add所需权限页面
例如添加网络权限
docker run -it --rm --name vm8 --cap-add=NET_ADMIN ubuntu
docker inspect vm8 | grep Pri
在次新增一台docker服务器
Server1
docker | IP |
---|---|
server1(master) | 10.217.135.35 |
server2 (node1) | 10.217.135.36 |
server3 (node2) | 10.217.135.37 |
在server1中
docker swarm init 执行记住token
在server2及server3中执行
这里执行报错需要清除记录
docker swarm leave --force 清除后再次执行
docker node ls 在master(server1)中查看
[root@server1 ~]# docker service create --name web --publish 80:80 --replicas 4 nginx 创建
[root@server1 ~]# docker service ps web
[root@server1 ~]#docker load -i visualizer.tar
[root@server1 ~]# docker service create --name=vi4 --publish=8282:8080/tcp --constraint=node.role==manager
[root@server1 ~]# docker service scale web=3
访问本地8282端口
因为node节点无nginx镜像所有全部节点都在mater中
在node节点导入nginx镜像再次查看
[root@server1 ~]# docker service scale web=15
[root@server2 ~]# docker load -i nginx.tar