docker

Docker 是一个开源的应用容器引擎,主要利用 linux 内核 namespace 实现沙盒隔离,用cgroup 实现资源限制。
实验环境:rhel7.3

一.准备工作

1安装以下包:
yum  install  
container-selinux-2.21-1.el7.noarch.rpm
docker-ce-18.03.1.ce-1.el7.centos.x86_64.rpm
libsemanage-2.5-8.el7.x86_64.rpm
libsemanage-python-2.5-8.el7.x86_64.rpm
pigz-2.3.4-1.el7.x86_64.rpm
policycoreutils-2.5-17.1.el7.x86_64.rpm
policycoreutils-python-2.5-17.1.el7.x86_64.rpm

这里写图片描述

这里说一下yum源问题:https://www.docker.com/ 官网
https://mirrors.aliyun.com/centos/
www.pkgs.org

2.启动服务
systemctl start docker 

这里写图片描述

ip addr会发现多了个桥接网络
这里写图片描述

二.镜像管理,镜像tar包另行下载

镜像用来创建容器,是容器的只读模板,默认可以从 docker hub 上下载。docker 的镜像是增量修改,每次创建新的镜像都会在父镜像上构建一个增量的层,基于 AUFS 技术。

 docker search   查询镜像
docker pull   拉取镜像
docker push  推送镜像

镜像默认可以从 docker hub 上下载,这是 docker 官方的公共仓库,为我们免费提供了大量已经容器化的应用镜像,避免我们重复的去造轮子。但是官方并没有在国内部署服务器,如果你不走 vpn 的话真的是太慢了,报错和超时让人非常的郁闷。给大家介绍个可以快速下载镜像的好办法:www.daocloud.io 为我们提供了永久免费的加速器服务,相当于 docker hub 在国内的缓存服务器,我测试过真的是又快又爽。首先你需要在此网站上注册一个帐号,加速器需要和 Daocloud ID 绑定才能正常工作。注册后进入加速器页面,按照提示选择你的自有主机的系统类型,我使用的是 rhel7,直接选择了 centos 就可以。(rhel6 内核太旧不支持)

rhel7的镜像tar包,下载

https://dashboard.daocloud.io 百度daocloud.io就行

这里写图片描述
然后宿主机:(也可以是其他主机,下造后传给宿主机总之得能通网,按照提示,执行命令)

docker pull richxsl/rhel7:latest

这里写图片描述

三.容器的管理

 yum install bash-*

##安装后如果是ssh链接的话退出重新链接,可以tab出相关命令
载入本地镜像docker load -i /PATH/x.tar
载入 ubuntu镜像tar包

docker load -i  /root/ubuntu.tar

这里写图片描述
载入nginx镜像tar包

docker load -i  /root/nginx.tar

这里写图片描述

查看当前载入的镜像

docker images

这里写图片描述
把刚才下载的镜像导出为tar包方便后边使用

docker save richxsl/rhel7 > rhel7.tar

这里写图片描述

镜像信息的查看:以nginx为例,

 docker inspect nginx:latest

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

镜像历史版本的查看

docker history nginx:latest 

这里写图片描述

启用运行(容器)镜像,以nginx为例
docker run -d nginx    ##-d标识后台运行
docker ps -a         ##查看进程信息,启用了80(http)端口和443(https)

这里写图片描述

yum install bridge-utils    ##安装brctl命令
brctl show   ##会发现docker0桥接到了veth67bcb26上

这里写图片描述

ipaddr  查看多出了个 veth67bcb26@if4

这里写图片描述
此时nginx容器使用的172.17.0.2而网关再docker0上172.17.0.1
这里写图片描述
iptables -t nat -nL 查看多了个DOCKER链,事实上,宿主机此时充当了路由的作用,
这里写图片描述
sysctl -a | grep ipv4.ip_forward ##内核路由功能已经开启
这里写图片描述

关闭容器的nginx

查看id

docker ps -a
docker stop $id  ##id不一定要写全,开头一个能单独区分也可以,但良好的习惯是应该写全的
docker ps -a   ##载此查看发现还在只是状态不是up了
docker  rm  $id   ##删除,但并没有从载入的镜像库中删除,docker images 查看其实还在

这里写图片描述

docker images  ##还在

这里写图片描述

删除镜像

docker rmi nginx:latest  | 或者#id

这里写图片描述

赶紧载入回来,还要使用nginx

docker load -i nginx.tar

这里写图片描述
下边这条命令是后台运行nginx 端口影射80,命名为web,非必要,如果不给名字的话随机产生

docker run -d  -p 80:80 --name web nginx
docker stats web    ##查看web就是nginx状态

这里写图片描述

docker ps -a   ##查看进程信息正在启用

这里写图片描述

docker inspect web   ##查看nginx状态

这里写图片描述
这里写图片描述
此时客户端访问:172.25.51.1

docker inspect web
http://172.25.51.1/

这里写图片描述
这里写图片描述
这是服务的部署

下来看看gama2048:
docker load -i game2048.tar    ##载入包

这里写图片描述

docker run -d -p 8888:80 --name game game2048:latest   ##启动服务,这里端口映射8888,因为上边的nginx占用了80,避免端口冲突

这里写图片描述

docker inspect game   ##查看下信息,发现ip自增1,后边加的服务都是这样的,依次自增

这里写图片描述
这里写图片描述
浏览器查看:

http://172.25.51.1:8888

这里写图片描述

系统的的构建以ubuntu为例

docker  run -it --name vm-ubuntu  ubuntu bash    ##启用命名为vm-ubuntu
Shell行后查看ip

这里写图片描述
宿主机查看桥接网络
brctl show ##会发现docker0 分别桥接了三个interface,前两个是nginx和2048游戏的,最后一个自然是ubuntu系统的了172.17.0.4 (172.17.0.1是网关docker0)
这里写图片描述
测试:分别ping网关,dns114.114.114.114以及www.baidu.com,默认网络桥接模式是可以访问外网的,前提是宿主机对外联网
这里写图片描述
Ubuntu下时可以执行命令的,rhel7可能无法执行为正常现象

这是ubuntu
这里写图片描述

这是redhat7
这里写图片描述

呐,docker ps -a 查看对应的id
这里写图片描述

ctrl  +  p + q  ##打入后台运行,以rhel7为例
 docker attach redhat7    ##调回前台
Ctrl + z  退出

这里写图片描述

 docker logs redhat7  ##相当于实时录屏在redhat7上的操作都会被查除,exec除外

这里写图片描述

docker container exec web ls /usr/share/nginx/html  ##列出web(nginx)的发布页有哪些
docker container exec web ls /etc/nginx    ##查看web的配置文件信息

这里写图片描述

在宿主机家目录中写一个网页添加到nginx的默认发布目录中,这个时候查看容器是否被修改,当然修改了

echo "hello,nginx" >test.html
 echo "hello,nginx" >>test.html
 docker container cp test.html web:/usr/share/nginx/html/
 docker diff  web 

这里写图片描述
浏览器访问:

http://172.25.51.1/test.html
curl 172.25.51.1/test.html

这里写图片描述
这里写图片描述

docker container ps
docker  ps
两者效果其实一样,前者将不vfen命令归类了

这里写图片描述

docker top web
docker container top web

这里写图片描述

docker container stats vm1      ##动态监控
docker container top vm1        ##静态数据监控
docker container prune      ##删除所有关闭的容器
docker search nginx         ##查看nginx(默认联网搜索)
配置docker加速器,自己申请 加速器默认下载到这里cd /etc/docker/

docker run -it --name vm1 ubuntu bash   创建容器
docker ps -a                查看容器状态
docker attach vm1           连接容器
docker top vm1          查看容器进程

docker logs vm1             查看容器指令输出 -f 参数可以实时查看
docker inspect vm1          查看容器详情
docker stats vm1            查看容器资源使用率
docker diff vm1             查看容器修改
docker run -d --name vm1 ubuntu bash -c "while true; do echo westos; sleep 1; done" 后台运行
docker stop vm1             停止容器
docker start vm1            启动容器
docker kill vm1             强制干掉容器
docker restart vm1          重启容器
docker pause/unpause vm1        暂停/恢复容器
docker rm vm1               删除容器

docker export vm1 > vm1.tar     导出容器
docker import vm1.tar image     导入容器为镜像 image

docker search       查询镜像
docker pull     拉取镜像
docker push     推送镜像

四.数据卷管理

docker run 在创建容器时使用 -v 参数可以挂载一个或多个数据卷到当前运行的容器中,-v的作用是将宿主机上的目录作为容器的数据卷挂载到容器中,使宿主机和容器之间可以共享一个目录。
挂载数据卷到新创建的容器上:docker run -it –name westos -v /tmp/data1:/data1 -v /tmp/data2:/data2 rhel7 /bin/bash
-v 参数可以重复使用,挂载多个数据卷到容器中,冒号前面的是宿主机的目录(本地目录
不存在 docker 会自动创建),冒号后面的是容器中的挂载目录。
注:docker commit 时卷的数据不会被保存。
默认挂载可以读写数据卷,也可以只读挂载:docker run -it –name westos2 -v /tmp/data2:/data2:ro rhel /bin/bash

实例:

先关闭nginx服务

docker stop web  ##截图右半部分有省略
docker rm web   ##移除nginx
docker  ps -a    ##查看所有进程,一定加-a,否则只显示在线的服务

这里写图片描述
这里写图片描述
docker run -d -p 80:80 –name web -v /tmp/html/:/usr/share/nginx/html/ nginx ##重新挂载nginx服务的默认发布目录到/tmp/html下,默认可以写的,如果忘记写了很可能报错80端口被拒,采过坑的

ls /tmp/html/   ##空的
echo "nginx mount-point is /tmp/html" >/tmp/html/index.html 
echo "nginx mount-point page server/html" >/tmp/html/server.html

这里写图片描述
这里写图片描述
客户端测试:

curl 172.25.51.1
    --->>nginx mount-point is /tmp/html
curl 172.25.51.1/server.html
    --->>nginx mount-point page server/html

这里写图片描述
这里写图片描述
这里写图片描述
再回来查看nginx容器自身的数据

docker container exec web ls /usr/share/nginx/html/  ##查看

这里写图片描述
镜像数据卷挂载

docker run -it --name vm2 -v /tmp/data1:/data1 -v /tmp/data2:/data2 -v /etc/passwd:/passwd:ro ubuntu

运行ubuntu,把宿主机的/tmp/data1挂载到容器中的/data1,宿主机的/tmp/data2挂载到容器中的/data2,宿主机的/etc/passwd挂载到容器/paswwd,ro只读模式
这里写图片描述

Ctrl +c 退出后到宿主机查看

这里写图片描述
宿主机下在/tmp/data2中新建文件data2
这里写图片描述
容器同步了
这里写图片描述

docker create --name datavol -v /tmp/data:/data1 -v /tmp/data2:/data2 -v  /etc/passwd:/passwd:ro ubuntu   ##做虚拟封装,docker ps 查不到,默认为stop状态

这里写图片描述

docker run -it --volumes-from datavol  --name v-m1 ubuntu  ##可以拿虚拟封装直接启动

这里写图片描述
备份数据卷:

docker run --rm --volumes-from datavol -v /tmp/backup:/backup ubuntu tar cf /backup/data.tar /data2  

这里写图片描述

五.网络管理

实验前清清(非必要) 
docker kill `docker ps -aq`  ##批量停止,比stop快
 docker rm `docker ps -aq`  ##批量删除

这里写图片描述
Docker 在启动时会创建一个虚拟网桥 docker0,默认地址为 172.17.42.1/16, 容器启动后都会被桥接到 docker0 上,并自动分配到一个 IP 地址。容器的四种网络模式:
bridge 桥接模式、host 模式、container 模式和 none 模式
启动容器时可以使用 –net 参数指定,默认是桥接模式

Bridge 桥接模式的实现步骤主要如下:
(1) Docker Daemon 利用 veth pair 技术,在宿主机上创建两个虚拟网络接口设备,假设为veth0 和 veth1。而 veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方。
(2) Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0 网桥上。保证宿主机的网络报文可以发往 veth0;
(3) Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为 eth0。如此一来,保证宿主机的网络报文若发往 veth0,则立即会被 eth0 接收,实现宿主机到Docker Container 网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网络环境的隔离性。bridge 桥接模式下的 Docker Container 在使用时,并非为开发者包办了一切。最明显的是,该模式下 Docker Container 不具有一个公有 IP,即和宿主机的 eth0 不处于同一个网段。导致的结果是宿主机以外的世界不能直接和容器进行通信。虽然 NAT 模式经过中间处理实现了这一点,但是 NAT 模式仍然存在问题与不便,如:容器均需要在宿主机上竞争端口,容器内部服务的访问者需要使用服务发现获知服务的外部端口等。另外 NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。
这里写图片描述

docker network ls  ##显示网络信息

这里写图片描述

docker run -it  --name vm1 ubuntu  ##容器启动ubuntu
ip addr 

这里写图片描述
打开新的shellssh链接宿主机
查看ip
这里写图片描述

ping  www.baidu.com  ,可以ping通,

这里写图片描述

Host 网络模式:

host 模式是 bridge 桥接模式很好的补充。采用 host 模式的 Docker Container,可以直接使用宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。当然,有这样的方便,肯定会损失部分其他的特性,最明显的是 Docker Container 网络环境隔离性的弱化,即容器不再拥有隔离、独立的网络栈。另外,使用 host 模式的 Docker Container 虽然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱化,该容器会与宿主机共享竞争网络栈的使用;另外,容器内部将不再拥有所有的端口资源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以 bridge 网络模式容器的端口映射。

docker run -it --network host ubuntu
ip addr

这里写图片描述

None 网络模式:

网络环境为 none,即不为 Docker Container 任何的网络环境。一旦 Docker Container 采用了none 网络模式,那么容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。可以说 none 模式为 Docker Container 做了极少的网络设定,但是俗话说得好“少即是多”,在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制开发。这也恰巧体现了 Docker 设计理念的开放。
在 none 网络模式下分配固定 ip:
netns 是在 linux 中提供网络虚拟化的一个项目,使用 netns 网络空间虚拟化可以在本地虚拟化出多个网络环境,目前 netns 在 lxc 容器中被用来为容器提供网络。使用 netns 创建的网络空间独立于当前系统的网络空间,其中的网络设备以及 iptables 规则等都是独立的,就好像进入了另外一个网络一样。

docker run -it --name vm2 --network none ubuntu
ip addr

这里写图片描述
打开新shell链接上server1

ip link add name veth0 type veth peer name veth1
brctl addif docker0 veth1
brctl show

这里写图片描述

ip link set up veth1
ip link set up veth0
docker inspect vm2 | grep Pid   ##vm2哦,Pid,注意

这里写图片描述

cd /proc/1674/ns/

这里写图片描述

ln -s /proc/1674/ns/net  /var/run/netns/1674
ip netns list

这里写图片描述


 ip link set veth0 netns 1674
 ip netns exec 1674 ip link set veth0 name eth0
 ip netns exec 1674 ip addr add 172.17.0.10/24 dev eth0
 ip netns exec 1674 ip link set up eth0
 ip netns exec 1674 ip route add default via 172.17.0.1
docker attach vm2
ip addr

这里写图片描述
可以ping通宿主机,外网
这里写图片描述
查看路由表,自动添加nat策略

六.容器端口映射

docker run -p 8001:443 -it –name site1 nginx bash
docker run -it -P –name site2 nginx bash
大写 -P 参数表示宿主机随机分配端口

七.容器间互联:

–link 参数可以在不映射端口的前提下为两个容器间建立安全连接, –link 参数可以连接一个或多个容器到将要创建的容器。
–link 参数的格式为 –link name:alias,其中 name 是要链接的容器的名称,alias 是这个连接的别名。
清环境

docker kill `docker ps -aq`
docker rm `docker ps -aq`

添加nginx

 docker run -d --name web -P nginx:latest
 docker run -it --name vm1 ubuntu:latest

这里写图片描述
别急着退出,打开另一个shell(server1)

docker run -it --name vm2 --link vm1:web ubuntu
ping web

这里写图片描述
这里写图片描述

八.容器封装

docker kill `docker ps -aq`
docker rm `docker ps -aq`

Dockerfile 编写:

FROM rhel7:v1       指定基础镜像
MAINTAINER haitangyijiu@163.com   作者信息
ENV HOSTNAME server1  设置容器主机名
EXPOSE 80    暴露容器端口
RUN yum install -y httpd   镜像操作命令
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]  镜像启动命令,默认只能启动一
条

这里写图片描述

docker run --name v1 -it rhel7 bash
cd /etc/yum.repos.d/
vi  yum.repo
  [yum]
  name=rhel7.3
  baseurl=http://172.25.51.250/rhel7.3
  gpgcheck=0
rm -fr rhel7.repo 
rpmdb  --rebuilddb  ##直接在容器里边执行,ctrl + p+q 到外边执行貌似也行,可以试试看,总之不能ctrl + d | z

这里写图片描述
这里写图片描述


docker commit v1 rhel7:v1  ##提交镜像v1

这里写图片描述

docker build -t rhel7:web  /root/ 创建镜像 rhel7:web   ##后边根的Dockerfile文件路径

这里写图片描述
这里写图片描述
这里写图片描述
然后运行web就是装了httpd服务的容器

docker run -d --name apache -v /tmp/web/html:/var/www/html rhel7:web 

这里写图片描述

cd /tmp/web/html/
echo '<h1>www.westos.com</h1>'  >index.html

这里写图片描述

curl 172.17.0.3

这里写图片描述

基础服务封装

这里写图片描述

vim /mnt/Dockerfile
FROM rhel7:v1
MAINTAINER haitangyijiu@163.com
ENV HOSTNAME server2
EXPOSE 22
RUN yum install -y openssh-server openssh-clients && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:westos | chpasswd
CMD ["/usr/sbin/sshd","-D"]

这里写图片描述

docker build -t rhel7:v3 /mnt/

这里写图片描述
这里写图片描述
这里写图片描述
查看下地址
这里写图片描述

docker container start ssh
docker container attach ssh
echo root:westos | chpasswd

这里写图片描述

docker run -d --name ssh -p 2222:22 rhel7:v3

这里写图片描述
到此ok,客户机ssh宿主机2222端口,不是宿主机测试,

ssh -l root -p 2222 172.25.51.1

这里写图片描述

iptables -t nat -nL

这里写图片描述

多个容器服务的封装
docker run -it --name vm1 rhel7:v1

这里写图片描述
配置yum源

vi  /etc/yum.repos.d/yum.repo

[yum]
name=rhel7.3
baseurl=http://172.25.51.250/rhel7.3
gpgcheck=0

[docker]
name=docker
baseurl=http://172.25.51.250/docker
gpgcheck=0


yum repolist 查看下

这里写图片描述
打开另一个shell或者ctrl q+p后台运行容器

[root@server1 ~]# vim Dockerfile

FROM rhel7:v1
MAINTAINER  930372286@qq.com
ENV HOSTNAME server3
EXPOSE 22 80
COPY docker.repo /etc/yum.repos.d/docker.repo
RUN yum install -y openssh-server openssh-clients httpd supervisor && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:westos | chpasswd
VOLUME ["/var/www/html"]
COPY supervisord.conf /etc/supervisord.conf
CMD ["/usr/bin/supervisord"]

这里写图片描述

[root@server1 ~]# vim supervisord.conf


[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D

[program:httpd]
command=/usr/sbin/httpd

这里写图片描述

vim docker.repo
[docker]
name=docker
baseurl=http://172.25.51.250/docker
gpgcheck=0

这里写图片描述

[root@server1 ~]# docker build -t rhel7:v4 .

这里写图片描述
这里写图片描述

[root@server1 ~]# docker images  ##查看下

这里写图片描述

[root@server1 ~]# docker history rhel7:v4

这里写图片描述

[root@server1 ~]# docker run -d --name apache -v /opt/web:/var/www/html rhel7:v4

这里写图片描述

测试:curl 172.17.0.3

这里写图片描述

ssh 172.17.0.3

这里写图片描述

九.docker私有仓库

[root@server1 ~]# docker load -i registry-2.3.1.tar

这里写图片描述

[root@server1 ~]# docker images

这里写图片描述

[root@server1 ~]# docker run -d --name registry -p 5000:5000 -v /opt/registry:/var/lib/registry registry:2.3.1  ##端口映射5000端口,后台运行
[root@server1 ~]# docker tag nginx localhost:5000/nginx:latest   ##命名

这里写图片描述

[root@server1 ~]# docker push localhost:5000/nginx:latest   ##推送

这里写图片描述

[root@server1 ~]# docker rmi localhost:5000/nginx:latest  ##删除ocalhost:5000/nginx:latest

这里写图片描述

[root@server1 ~]# docker rmi nginx  删除nginx

这里写图片描述

[root@server1 ~]# docker pull localhost:5000/nginx:latest   ##下载

这里写图片描述

[root@server1 ~]# docker tag localhost:5000/nginx:latest nginx ##重命名

这里写图片描述

[root@server1 ~]# docker rmi localhost:5000/nginx ##再次删除

这里写图片描述

仓库添加认证,证书自己的

解析

[root@server1 ~]# vim /etc/hosts
    172.25.51.1 server1 westos.org

这里写图片描述

[root@server1 ~]# mkdir certs
[root@server1 ~]# cd certs/
[root@server1 certs]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout westos.org.key -x509 -days 365 -out westos.org.crt

这里写图片描述
这里写图片描述
此时会在当前目录生成证书和钥匙
这里写图片描述
清空上个实验的数据

[root@server1 certs]# rm -fr /opt/registry/*
[root@server1 ~]# docker stop 6c7736f7eea0
[root@server1 ~]# docker rm 6c7736f7eea0

这里写图片描述

[root@server1 ~]# docker run -d --name registry --restart=always -v /root/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 /opt/registry/:/var/lib/registry  registry:2.3.1

[root@server1 ~]# docker ps -a  ##查看下,确保Up状态

这里写图片描述
剩下的操作如下:

[root@server1 ~]# cd /etc/docker/
[root@server1 docker]# mkdir -p certs.d/westos.org 
[root@server1 docker]# cd certs.d/westos.org/
[root@server1 westos.org]# cp ~/certs/westos.org.crt ca.crt
[root@server1 westos.org]# ls

这里写图片描述

[root@server1 westos.org]# docker tag ubuntu:latest westos.org/ubuntu
[root@server1 westos.org]# docker push westos.org/ubuntu  ##推送

这里写图片描述

[root@server1 westos.org]# docker rmi westos.org/ubuntu:latest ##删除镜像

这里写图片描述
另开一台虚拟机server2安装启动docker


[root@server2 ~]# cd /etc/docker/
[root@server2 docker]# mkdir -p certs.d/westos.org
[root@server2 docker]# cd certs.d/westos.org/

这里写图片描述

[root@server2 westos.org]# scp 172.25.51.1:/etc/docker/certs.d/westos.org/ca.crt  .   ##将server1的/etc/docker/certs.d/westos.org/ca.crt 复制到server2的/etc/docker/certs.d/westos.org/下边

这里写图片描述
Server2拉取试试:注意解析问题,否则报错

[root@server2 ~]# docker images   ##空的
[root@server2 ~]# docker pull westos.org/ubuntu  ##拉取

这里写图片描述
这里写图片描述

[root@server2 ~]# curl --cacert /etc/docker/certs.d/westos.org/ca.crt https://westos.org/v2/_catalog   ##查看信息
{"repositories":["ubuntu"]}

这里写图片描述

优化一下:不需要证书添加浏览器:
[root@server2 ~]# cd /etc/pki/ca-trust/source/anchors/
[root@server2 anchors]# ls
[root@server2 anchors]# cp /etc/docker/certs.d/westos.org/ca.crt /etc/pki/ca-trust/source/anchors/
[root@server2 anchors]# ls
ca.crt
[root@server2 anchors]# mv ca.crt westos.org.crt
[root@server2 anchors]# ls
westos.org.crt

这里写图片描述

[root@server2 anchors]# update-ca-trust  ##更新信任证书
[root@server2 anchors]# curl https://westos.org/v2/_catalog
{"repositories":["ubuntu"]}

这里写图片描述

##curl验证
[root@server1 ~]# mkdir auth
[root@server1 ~]# cd auth/
[root@server1 auth]# docker run --entrypoint htpasswd registry:2.3.1 -Bbn admin westos >htpasswd  ##添加人证名和密码,多个追加
[root@server1 auth]# cat htpasswd 
admin:$2y$05$Js9sBiZYlzMLCV5HzyqRP.n1Y5KO/fd4XCoHC8ofNq1l/KsTPqgCC

这里写图片描述

清下环境,删除上个实验的镜像:
[root@server1 auth]# docker stop 184
[root@server1 auth]# docker rm 184

这里写图片描述

[root@server1 ~]# docker run -d --name registry --restart=always -v /root/certs:/certs -v /root/auth:/auth  -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 -e REGISTRY_AUTH=htpasswd -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -p 443:443 -v /opt/registry/:/var/lib/registry registry:2.3.16557d24432b8c2f5fe09ed9b5b46fec952d64d98c5e4435abca24bc3de459c89

[root@server1 auth]# pwd
/root/auth

这里写图片描述

测试:
[root@server2 ~]# curl -u admin:westos https://westos.org/v2/_catalog
{"repositories":["ubuntu"]}

[root@server2 ~]# docker login westos.org
Username: admin
Password: westos    ##隐藏
Login Succeeded

这里写图片描述

登陆成功就可以pull拉取镜像了
[root@server2 ~]# docker pull westos.org/ubuntu

这里写图片描述

密码文件在家目录下
/root/.docker

这里写图片描述

十.cgroup管理


新开一个rhel6.5的虚拟机host4 
[root@host4 ~]# yum install libcgroup.x86_64 -y  ##安装这个,人生苦短,不要追问这是什么
[root@host4 ~]#  /etc/init.d/cgconfig start  ##安装完成后启动

这里写图片描述
这个时候cd /cgroup/ ,ls查看会有些目录文件
这里写图片描述

内存的控制
[root@host4 cgroup]# vim /etc/cgconfig.conf 

 27 group x1 {
 28         memory {
 29                 memory.limit_in_bytes = 104857600;
 30         }
 31 }

[root@host4 cgroup]# /etc/init.d/cgconfig restart

这里写图片描述
实验:

cd /dev/shm/   进入内存
dd if=/dev/zero of=bigfile bs=1M count=200   ##截取200M全在内存里

这里写图片描述

rm  -fr bigfile
cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=200
这个时候会先内存大概用了100M其他由swap去存了

这里写图片描述

[root@host4 shm]# vim /etc/cgconfig.conf 

 27 group x1 {
 28         memory {
 29                 memory.limit_in_bytes = 104857600;
 30                 memory.memsw.limit_in_bytes = 104857600;  内存和交换分区总共的限制
 31         }
 32 }

这里写图片描述

重启/etc/init.d/cgconfig restart
cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=200
会发现写不进去

这里写图片描述
限制用户lel

[root@host4 shm]# vim /etc/cgrules.conf 
         lel             memory          x1/
[root@host4 shm]# /etc/init.d/cgred restart

这里写图片描述
对于lel用户来说内存和swap只能用100M多了不行


[lel@host4 shm]$ dd if=/dev/zero of=bigfile bs=1M count=200
Killed
[lel@host4 shm]$ dd if=/dev/zero of=bigfile bs=1M count=50
50+0 records in
50+0 records out
52428800 bytes (52 MB) copied, 0.035936 s, 1.5 GB/s

这里写图片描述

cpu管理工具
[root@server1 x2]# cd /sys/devices/system/cpu/
[root@server1 cpu]# ls
cpu0   cpu1  cpufreq  cpuidle  kernel_max  offline  online  possible  present
[root@server1 cpu]# cd cpu1     ##cpu0是默认的,无法更改
[root@server1 cpu1]# ls
cache  online  crash_notes  node0  topology
[root@server1 cpu1]# cat online     ##显示cpu信息
1
[root@server1 cpu1]# echo 0 > online    ##更改0挂掉,1上线

[root@server1 ~]# killall dd       ##删除所有dd进程

cpu1再打开,top查看
blkio
[root@server1 blkio]# ll /dev/vda
brw-rw---- 1 root disk 252, 0 May  8 15:11 /dev/vda     ##252,0 是vda的信息

[root@server1 blkio]# vim /etc/cgconfig.conf
group x3 {
        blkio {
                blkio.throttle.read_bps_device = "252:0 1000000";   ##限速1000k
        }
}

[root@server1 ~]# yum install iotop -y     ##查看速度的软件

[root@server1 ~]# cgexec -g blkio:x3 dd if=/dev/vda of=/dev/null & ##执行
[1] 1306
[root@server1 ~]# iotop        ##查看
freezer
[root@server1 freezer]# vim /etc/cgconfig.conf 
group x4 {
        freezer {}      ##冻结
}



[root@server1 freezer]# cd  
[root@server1 ~]# /etc/init.d/cgconfig restart
Stopping cgconfig service:                                 [  OK  ]
Starting cgconfig service:                                 [  OK  ]
[root@server1 ~]# cd -
/cgroup/freezer
[root@server1 freezer]# cd x4/


[root@server1 x4]# cat tasks        ##管理进程的文件
[root@server1 x4]# cgexec -g blkio:x3 dd if=/dev/vda of=/dev/null &
[1] 1336
[root@server1 x4]# echo 1336 > tasks    ##导入(用的是速度查询的进程)
[root@server1 x4]# cat freezer.state    ##运行状态
THAWED
[root@server1 x4]# echo FROZEN > freezer.state  ##冻结状态
[root@server1 x4]# iotop
[root@server1 x4]# echo THAWED > freezer.state  ##正常运行
[root@server1 x4]# iotop

十一.docker的安全

[root@server1 ~]#docker run -it --name  vm1 ubuntu bash
root@6d24f44bd014:/# ip addr del 172.17.0.2/16 dev eth0

如下图,操作被禁止

这里写图片描述

放权docker run -it –privileged=true –name vm1 ubuntu bash
[root@server1 ~]# docker stop vm1
[root@server1 ~]# docker rm vm1
[root@server1 ~]# docker run -it --privileged=true --name vm1 ubuntu bash
root@ebd5e1aaa795:/# ip addr del 172.17.0.2/16 dev eth0

这里写图片描述

设置容器白名单:–cap-add

–privileged=true 的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供给容器必须的权限。此时 Docker 提供了权限白名单的机制,使用–cap-add 添加必要的权限。

docker run -it --cap-add=NET_ADMIN --name vm1 ubuntu
bash
docker inspect -f {{.HostConfig.Privileged}} vm1
false
docker inspect -f {{.HostConfig.CapAdd}} vm1
{[NET_ADMIN]}

这里写图片描述

十二.docker+apache+nginx+haproxy实际上compose实现负载均衡,docker自身就可以负载均衡,最后一个实验说明

如果你没有母镜像需要先封装一个apache镜像,方法如下

docker run --name [name] -it rhel7 bash 
cd /etc/yum.repos.d/
vim yum .repo
[yum]
name=rhel7.3
baseurl=http://172.25.10.250/rhel7.3
gpgcheck=0
rm -fr redhat.repo

ctrl  p + q

rpmdb --rebuilddb

删除所有正在运行的容器

[root@server1 ~]# docker  kill `docker ps -aq`
[root@server1 ~]# docker  rm `docker ps -aq`
[root@server1 ~]# docker ps -a

这里写图片描述
这里需要一个二进制可执行命令,如下图
这里写图片描述

[root@server1 ~]# mv docker-compose-Linux-x86_64  /usr/local/bin/
[root@server1 ~]# ln -s /usr/local/bin/docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
[root@server1 ~]# chmod +x /usr/local/bin/docker-compose

配置文件

[root@server1 ~]# mkdir compose
[root@server1 ~]# cd compose/
[root@server1 compose]# vim docker-compose.yml
 apache:
    build: ./web
    expose:
        - 80
nginx:
    image: nginx
    expose:
        - 80
haproxy:
    image: haproxy
    volumes:
        - ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
    links:
        - apache
        - nginx
    ports:
        - "80:80"
    expose:
        - "80"

这里写图片描述

[root@server1 compose]# mkdir web
[root@server1 compose]# cd web/
[root@server1 web]# pwd
/root/compose/web
[root@server1 web]# vim Dockerfile

FROM rhel7:v1                              ##确保有rhel7:v1  
MAINTAINER 1904168391@qq.com
ENV HOSTNAME apache
EXPOSE 80
RUN  yum -y install httpd
COPY index.html /var/www/html/index.html
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]

[root@server1 web]# echo "hello,world" >index.html
[root@server1 web]# ls
   Dockerfile  index.html
[root@server1 web]# cd ..
[root@server1 compose]# pwd
/root/compose
[root@server1 compose]# mkdir haproxy
[root@server1 compose]# cd haproxy/
[root@server1 haproxy]# vim haproxy.cfg
global
    log 127.0.0.1 local0
defaults
    log global
    mode http
    option httplog
    option dontlognull
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    stats uri /status
frontend balancer
    bind 0.0.0.0:80
    default_backend web_backends
backend web_backends
    balance roundrobin
    server web1 apache:80 check
    server web2 nginx:80 check

这里写图片描述

[root@server1 compose]# mkdir web
[root@server1 compose]# cd web/
[root@server1 web]# pwd
/root/compose/web
[root@server1 web]# vim Dockerfile
[root@server1 web]# 

这里写图片描述

[root@server1 compose]#  docker-compose up  ##注意工作目录在那,重要

这里写图片描述
报错了,docker仓库没有haproxy镜像会去外网找,而网不通,我们需要把haproxy.tar上传仓库

[root@server1 ~]# docker load -i haproxy.tar 

这里写图片描述
再次执行

[root@server1 compose]#  docker-compose up

这里写图片描述
这里写图片描述

Ctrl +c 

[root@server1 compose]# docker-compose start

这里写图片描述
这个时候,浏览器可以查看了

http://172.25.51.1/status   ##查看haproxy的状态
http://172.25.51.1/    ##apache和nginx轮询
或者curl  172.25.51.1

这里写图片描述
这里写图片描述
这里写图片描述

十四.swarm 高可用

准备两台7.3docker 开启,时间同步 server2,server3
load nginx镜像

leader 为server1
[root@server2 ~]#  docker load -i nginx.tar 

这里写图片描述
时间是一样的,不一样的话需要时间同步

[root@server1 ~]# docker swarm init  ##初始化

复制图中黑色代码去server2和server3执行,另外注意,如果server1 eth0多个ip的话可能报错
这里写图片描述

Server2:

这里写图片描述

Server3:

这里写图片描述

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=viz --publish=8080:8080/tcp --constraint=node.role==manager --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock dockersamples/visualizer

这里写图片描述
实验效果是某一个坏了,转移其他

浏览器:
http://172.25.51.1:8080/

这里写图片描述

多开几个:
[root@server1 ~]# docker service scale web=9  ##9个

这里写图片描述
这里写图片描述

十五.flask框架,需要python环境

封装一个apache
更新httpd
封装一个apache
方法如下:

vim /mnt/Dockerfile
    FROM rhel7:v1
    MAINTAINER 1904168391@qq.com
    ENV HOSTNAME apache
    EXPOSE 80
    RUN  yum -y install httpd
    CMD ["/usr/sbin/httpd","-D","FOREGROUND"]

docker build -t rhel7:v2 /mnt/
docker save rhel7:v2 >rhel7.tar
scp rhel7.tar root@172.25.51.2:~
scp rhel7.tar root@172.25.51.3:~

这里写图片描述

[root@server1 ~]# docker save rhel:v2 >/opt/rhel7.tar ##导出来分发server2和server3
scp rhel7.tar root@172.25.51.2:~
scp rhel7.tar root@172.25.51.3:~

这里写图片描述
这里写图片描述

[root@server1 compose]# docker service update --update-parallelism 2  --update-delay 2s --update-failure-action rollback --image  rhel7:v2 web
##--update-parallelism 2 (同一时刻)更新的数量默认0,--update-delay 2s更新时间间隔默认0s,--update-failure-action rollback 更新失败从头再来,回滚,还有其他模式参考docker service update --help

这里写图片描述

[root@server1 ~]# docker load -i flask.tar

这里写图片描述

[root@server1 ~]# vim test.py
[root@server1 ~]# cat -n test.py 
     1  from flask import Flask
     2  
     3  import os
     4  
     5  app = Flask(__name__)
     6  
     7  @app.route("/")
     8  
     9  def env():
    10     return os.environ["HOSTNAME"]
    11  
12  app.run(host="0.0.0.0")

这里写图片描述

[root@server1 ~]# docker run  -d --name test -v /root/test.py:/test.py python:flask  python /test.py

这里写图片描述

[root@server1 ~]# curl 172.17.0.6:5000  ##会显示主机id

这里写图片描述

当出现这个错误多半是test.py文件有错
May 11 08:51:56 server1 dockerd: time=”2018-05-11T08:51:56.064730380-04:00” level=error msg=”Error in responding to bulk sync from node 172.25.51.2: failed to send a TCP message during bulk sync: dial tcp 172.25.51.2:7946: getsockopt: no route to host”

关闭删除test容器
[root@server1 ~]# docker stop test
[root@server1 ~]# docker rm test

这里写图片描述

[root@server1 ~]# docker run -it --name test python:flask
Python 2.7.11 (default, Mar 24 2016, 09:47:20) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> ctrl + p +q 
[root@server1 ~]# docker container  cp test.py test:/   ##把/root/test.py复制到容器的根目录下
[root@server1 ~]# docker container exec test ls /    ##非必要步骤,查看容器test根下是否有test.py肯定有的
[root@server1 ~]# docker container commit test python:demo  ##提交test容器重命名
[root@server1 ~]# docker save python:demo  > demo.tar  ##导出容器test命名后的容器
[root@server1 ~]# scp demo.tar root@172.25.51.2:~  ##分发给server2

[root@server1 ~]# scp demo.tar root@172.25.51.3:~  ##分发给server3

这里写图片描述

[root@server1 ~]# docker load -i demo.tar
[root@server2 ~]# docker load -i demo.tar
[root@server3 ~]# docker load -i demo.tar
这个过程中可能存在存储不足或者没有这个文件/var/lib/docker/tmp/docker-import-376966965/repositories,清理下挂载的容器,du -sh /* 可用空间可能过少,鄙人把所有的都干掉了docker kill | rm`docker ps -aq`,当然剩下的高可用你也可以干掉(docker service  rm  [id] )

这里写图片描述
其他两个就不截图了

[root@server1 compose]# docker service create --replicas 3 --publish 80:5000  --name web python:demo python /test.py

这里写图片描述

实验:
[kiosk@foundation51 Desktop]$ for i in {1..6}; do curl -w "\n" 172.25.51.1; done

这里写图片描述
已经实现了负载均衡8eaf5ddfdc80 对应的172.25.51.1,efd6def70def 对应172.25.51.2, 3f7da2e20bfb 对应172.25.51.3

换种方式

[root@server1 ~]# docker service rm web   ##删除上边实验的web
[root@server1 ~]# docker service rm viz 
[root@server1 ~]# docker service  ls   ##空的
[root@server1 ~]# docker service create --name www -p 80:80 --replicas 3 nginx
[root@server1 ~]# docker service ls  ##只有一个容器www
[root@server1 ~]# docker service ps www   ###在三台主机上都有nginx

这里写图片描述
这里写图片描述
curl 172.25.51.1

访问都是nginx默认页,挂载让实验更明显些
在server1 root家目录下新建web 
[root@server1 ~]# mkdir web
[root@server1 ~]# echo server1 > web/index.html
在server2 root家目录下新建web 
[root@server2 ~]# mkdir web
[root@server2 ~]# echo server2 > web/index.html

在server3 root家目录下新建web 
[root@server3 ~]# mkdir web
[root@server2 ~]# echo server3 > web/index.html

[root@server1 ~]# docker service update --mount-add type=bind,source=/root/web,target=/usr/share/nginx/html www   ##更新,你也可以删除重建

实验测试:

curl 172.25.51.1

这里写图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值