Docker容器安装及使用
Docker安装docker切记安装前需关闭NetworkManager直接使用网络安装wget https://download.docker.com/linux/centos/docker-ce.repo或自己打包安装这里使用网络安装及本地打包安装均出现container-selinux包版本低问题1、首先升级container-selinux包下载container-sel...
Docker安装
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
查看镜像 docker images
[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
启动容器镜像并进入busybox
[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 <src> <dest>
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
正确的Copy使用
[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 <src> <dest>
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
明显可以看到自动吧tar包进行解压.
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
查看镜像中data目录挂载点
[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
再次修改dockerfile
[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指令
- exec格式用法 (常用)
ENTRYPOINT [“top”,"-b", “-H”]
exec格式,也被称为JSON风格[“command”,“arg1”].
例:
[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
在修改dockerfile中测试
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 864066892@qq.com
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;"]
生成新镜像web1
[root@server2 docker]# docker build -t web1 .
启动镜像并命名为web
[root@server2 docker]# docker run -it --name web web1:latest
查看web所对应的IP是否生成
[root@server2 data]# docker inspect web
测试生成的IP是否启动nginx
[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 864066892@qq.com
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 864066892@qq.com
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
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
Registry数据存放点
[root@server2~]#cd /var/lib/docker/volumes/7c37e0e131e301fddc253827aa24406032e5e44bb18b011c3911302d8d6cc317/_data
[root@server2 _data]# ls
docker
[root@server2 _data]# cd docker/
[root@server2 docker]# tree
Docker私有仓库TSL加密
创建秘钥
[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
配置客户端key
[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
上传ubuntu镜像至镜像仓库
[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/ root@192.168.43.111:/etc/docker/
利用docker-registry-web制作web界显示上传后镜像
[root@server3 docker]# docker pull hyper/docker-registry-web
[root@server3 docker]# docker images
记录这个key值,并运行这个容器
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
会发现与主机共享网络
None模式禁用网络
例:
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
再次ping 测试通信成功
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
再次启动之前nginx容器IP更换为172.17.0.5
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
Docker容器访问外网
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
启动一个nginx服务做端口映射
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 <host path>:<contariner path>(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
如需挂载多个目录及文件只需要添加-v即可
例:
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
或自定义创建volume进行挂载
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
对容器进行CPU限额
例:
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 配置内存后显示问题
利用lxcfs 进行隔离
安装
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集群
在次新增一台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
访问web页面查看
更多推荐
所有评论(0)