Docker
desktop23.example.com 172.25.254.23
Selinx iptables disabled rhel7.2版本
1.安装
yum install -y docker-engine-1.10.3-1.el7.centos.x86_64.rpm
docker-engine-selinux-1.10.3-1.el7.centos.noarch.rpm
systemctl start docker
2.简单命令
docker version# 查看版本信息
docker info# 显示docker系统的信息
(1) 容器管理
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 # 查看容器修改
A:增加的, D:删除的,C:改变的
docker run -d --name vm2 ubuntu bash# 后台运行容器
docker run -d --name vm1 ubuntu bash -c "while true; do echo westos; sleep 1; done"
docker stop vm1 # 停止容器
docker start `docker ps -qa`# 启动所有容器
docker start vm1 # 启动容器
docker kill vm1 # 强制干掉容器
docker restart vm1 # 重启容器
docker pause vm1# 暂停容器
docker unpause vm1# 恢复容器
docker rm vm1# 删除容器
docker export vm1 > vm1.tar# 导出容器
docker import vm1.tar p_w_picpath# 导入容器为镜像 p_w_picpath
(2) 镜像管理
镜像用来创建容器,是容器的只读模板,默认可以从 docker hub 上下载。docker 的镜像是增量修改,每次创建新的镜像都会在父镜像上构建一个增量的层,基于 AUFS 技术。
docker search# 查询镜像
docker pull# 拉取镜像
docker push# 推送镜像
docker p_w_picpaths # 查看本地镜像
docker inspect # 查看镜像详情
docker save ubuntu > ubuntu.tar# 导出镜像
docker load -i ubuntu.tar# 导入镜像
docker rmi# 删除镜像
docker commit# 更新镜像
eg:
a)docker commit vm1 test 会多出一个test的p_w_picpath,内容=vm1
b)端口映射
docker run -d --name vm2 -p 8080:80 nginx 8080--->80
docker run -d -P --name vm3 nginx -P宿主机随机分配端口
3.逻辑卷
docker run -it --name vm4 -v /tmp/data1:/data1 -v /tmp/data2:/data2:ro rhel7 bash
# 建立一个vm4容器,将物理机上的/tmp/data1映射到容器中的/data1,/tmp/data2映射到容器中的/data2,并且/data2属于只读。
-v 参数可以重复使用,挂载多个数据卷到容器中,冒号前面的是宿主机的目录(本地目录不存在 docker 会自动创建),冒号后面的是容器中的挂载目录。docker commit 时卷的数据不会被保存。
(1)数据卷容器:
docker create --name data -v /tmp/data:/data rhel7 bash
docker run -it --name vm1 --volumes-from=data rhel7 bash
docker run -it --name vm2 --volumes-from=data rhel7 bash
eg:
docker attach vm1
bash-4.2# cd /data
bash-4.2# touch 111
docker attach vm2
bash-4.2# cd /data
bash-4.2# ls
111
bash-4.2# touch 222
[root@desktop23 ~]# ls /tmp/data
111 222
(2) 先执行命令,执行完后会自动释放容器
docker run --rm rhel7 cat /etc/hosts
(3) 备份数据卷:
docker run --rm --volumes-from data -v /tmp/backup:/backup ubuntu tar cf /backup/test.tar /data
docker run --rm --volumes-from data -v /tmp/backup:/backup rhel7 tar cf /backup/test.tar /data1
# 失败,因为rhel7中没有打包命令
4. 重新设置docker0的网络
Docker 在启动时会创建一个虚拟网桥 docker0, 容器启动后都会被桥接到 docker0 上,并自动分配到一个 IP 地址
systemctl start docker
ip addr show docker0
(1)先删除掉原有docker0
systemctl stop docker
ip link set dev docker0 down
ip addr del 172.17.0.1/16 dev docker0
(2)添加新的docker0
ip addr add 172.17.23.0/24 dev docker0
ip link set dev docker0 up
cd /usr/lib/systemd/system
# /usr/lib/systemd/system上的文件一般不做修改,先进行复制
cp docker.service /etc/systemd/system
cd /etc/systemd/system
vim docker.service
添加 --bip 172.17.23.1/24
systemctl daemon-reload #修改配置文件后,需要重新加载
systemctl start docker
ip addr show docker0
5.网络类型
(1) bridge ---- 桥接模式 (默认配置方式)
docker run -it --name vm1 ubuntu bash
(2) host ---- 共享物理机上网络的设置 可以直接分享,不用映射,但会有资源抢夺
docker run -it --net=host --name vm2 ubuntu bash
(3) container 使用其他容器的namespace
docker run -it --net=container:vm1 --name vm3 ubuntu bash
(4) none 容器内部只能使用loopback,没有其他网络资源
可用 --net 指定
docker run -it --net=none --name vm4 ubuntu bash
6.自定义网络(在 none 网络模式下分配固定 ip)
netns 是在 linux 中提供网络虚拟化的一个项目,使用 netns 网络空间虚拟化可以在本地虚拟化出多个网络环境,目前 netns 在 lxc 容器中被用来为容器提供网络。
使用 netns 创建的网络空间独立于当前系统的网络空间,其中的网络设备以及 iptables 规则等都是独立的,就好像进入了另外一个网络一样。
(1) 运行一个新容器
docker stop `docker ps -aq`
docker rm `docker ps -aq`
docker run -it --net=none --name vm1 ubuntu bash
(2) 加一对接口,并启动
ip link add name veth0 type veth peer name veth1
ip link set dev veth0 up
ip link set dev veth1 up
(3) 将veth0加入docker0上
brctl addif docker0 veth0
(4) 查看PID,进入该namespace做链接
docker inspect -f '``.`State`.`Pid`' vm1
cd /proc/18366/ns
ln -s /proc/18366/ns/net /var/run/netns/18366
mkdir /var/run/netns
ln -s /proc/18366/ns/net /var/run/netns/18366
ip netns list#查看所有的network namespace
(5) 将另外一个接口添加到容器那端
ip link set veth1 netns 18366
ip netns exec 18366 ip link set veth1 name eth0
ip netns exec 18366 ip link set eth0 up
ip netns exec 18366 ip addr add 172.17.23.10/24 dev eth0
(6) 添加路由
ip netns exec 18366 ip route add default via 172.17.23.1
(7) 测试
brctl show
ip addr show docker0
docker attach vm1
ping 172.25.254.0/24 可以ping 通
常用的 namespace 的命令:
1.) 添加一个 namespace
ip netns add [name]
2.) 在 namespace 中启用一个设备
ip netns exec [name] ip link set lo up
3.) 在 namespace 中新加一个设备
ip link set [dev-name] netns [name]
启用:
ip netns exec [name] ip link set [dev-name] up
4.) 查看指定 namespace 中指定设备的参数信息
ip netns exec [name] ip addr show [dev-name] permanent scope global
5.) 为 namespace 中指定设备设置 ip
ip netns exec [name] ip addr add 172.17.23.20/24 dev eth0
6.) 查看所有 network namespace
ip netns list
7.) ping 虚拟机实例
ip netns exec [name] ping 172.17.23.2
7.两个container进行访问 (容器间互联)
--link 参数可以在不映射端口的前提下为两个容器间建立安全连接, --link 参数可以连接一个或多个容器到将要创建的容器。
--link 参数的格式为 --link name:alias,其中 name 是要链接的容器的名称,alias 是这个连接的别名。
docker load -i redis.tar
docker run -d --name redis redis
docker run -it --name redisclient --link redis:db redis bash
docker attach redisclient
8.安全权限问题 (eg:修改容器网络)
设置特权级运行的容器:--privileged=true
设置容器白名单:--cap-add
--privileged=true 的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供给容器必须的权限。此时 Docker 提供了权限白名单的机制,使用--cap-add 添加必要的权限。
(1) 默认无权限
docker inspect vm1
可看到:
a) privileged = false
b) capadd = null
(2) 满权限,可以执行任意操作,但不安全
docker inspect vm2
可看到:
a) privileged = true
b) capadd = null
(3) 白名单,添加必要的服务权限
docker inspect vm1
可看到:
a) privileged = false
b) capadd = NET_ADMIN
9.设置自己的镜像 Dockerfile的编写
用已经封装好的镜像修改
构建apache
(1) 封装一个已配置好yum源的镜像 test
docker run -it --name vm1 rhel7 bash
#在vm1上配好yum源
docker commit vm1 test
(2) vim /mnt/test/apache/Dockerfile
--->
FROM test# 基础镜像
MAINTAINER wj# 作者信息
ENV HOSTNAME server1# 主机名
EXPOSE 80# 对外链接端口号
RUN yum install -y httpd && yum clean all# 镜像操作命令
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]# 启动命令,默认只能启动一条,启动httpd并打入后台运行
(3) docker build -t rhel7:apache .# 创建镜像rhel7:apache
(4) docker history rhel7:apache
(5) 创建容器
a) 编写测试页
vim /mnt/test/apache/index.html
---> hello
b) 创建apache容器,映射端口,测试页
docker run -d --name apache -p 8000:80 -v /mnt/test/apache/index.html:/var/www/html/index.html
rhel7:apache
c) 访问
curl 172.25.254.23:8000
用基础镜像修改
构建apache
(1)vim /mnt/test/apache/Dockerfile
--->
FROM rhel7
MAINTAINER wj
ENV HOSTNAME server1
EXPOSE 80
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN yum install -y httpd && yum clean all
ADD index.html /var/www/html
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
注意:向镜像中添加文件有两种命令:COPY 和 ADD。
COPY 命令可以复制本地文件夹到镜像中;ADD 命令支持添加本地的 tar 压缩包到容器中指定目录,压缩包会被自动解压为目录,也可以自动下载 URL 并拷贝到镜像
(2)vim /mnt/test/dvd.repo
--->
[dvd]
name=rhel7.0
baseurl=http://172.17.23.1/rhel7.0
gpgcheck=0
enabled=1
(3)vim /mnt/test/index.html
--->
Hello,world
(4)创建镜像rhel7.0:apache
docker build -t rhel7.0:apache .
...
(5) 创建容器
(6) 查看测试页
(7) 查看历史
构建sshd
(1)vim /mnt/test/sshd/Dockerfile
--->
FROM rhel7
MAINTAINER wj
ENV HOSTNAME server2
EXPOSE 22
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN echo root:westos | chpasswd
RUN yum install -y openssh-server && yum clean all
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -q -N ""
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_ecdsa_key -q -N ""
CMD ["/usr/sbin/sshd","-D"]
注意:可以有多条RUN,但只能有一条CMD
(2)vim /mnt/test/sshd/dvd.repo
--->
[dvd]
name=rhel7.0
baseurl=http://172.17.23.1/rhel7.0
gpgcheck=0
enabled=1
(3)创建镜像 (注意路径)
docker build -t rhel7:sshd .
(4) 创建容器 (注意映射端口,我们只测连接容器,可以先不用)
(5)测试
(6)查看历史
启动多个服务
CMD 如果只有一个命令,那如果我们需要运行多个服务怎么办呢?最好的办法是分别在不同的容器中运行,通过 link 进行连接
如果一定要在一个容器中运行多个服务可以考虑用 Supervisord 来进行进程管理,方式就是将多个启动命令放入到一个启动脚本中
首先安装 Supervisord
(1) vim /mnt/test/super/Dockerfile
--->
FROM rhel7
MAINTAINER wj
ENV HOSTNAME server1
EXPOSE 22 80
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN echo root:westos | chpasswd
RUN yum install -y openssh-server httpd supervisor && yum clean all
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -q -N ""
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_ecdsa_key -q -N ""
ADD index.html /var/www/html/
COPY supervisord.conf /etc/supervisord.conf
CMD ["/usr/bin/supervisord"]
(2) vim /mnt/test/super/dvd.repo
--->
[dvd]
name=rhel7.0
baseurl=http://172.17.23.1/rhel7.0
gpgcheck=0
[docker]
name=docker
baseurl=ftp://172.17.23.1/docker
gpgcheck=0
(3) vim /mnt/test/super/supervisord.conf
--->
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
[program:httpd]
command=/usr/sbin/httpd -D FOREGROUND
注意:如果有多个服务需要启动可以在文件后继续添 [program:xxx]
(4) vim /mnt/test/super/index.html
--->
Hello,world
(5) 创建镜像
docker build -t rhel7:super
(6) 创建容器并测试
docker run -d --name vm1 rhel7:super
(6) 查看历史
10.Docker仓库
无认证方式
(1) 默认 docker 仓库远程推送拉取需要 TLS 加密支持,走的是https 协议,如需开启 http 方式,需要做如下修改
vim /etc/systemd/system/docker.service
添加:
--insecure-registry 172.25.254.23:5000
systemctl daemon-reload
systemctl restart docker.service
(2) 导入镜像
docker load -i registry:2.3.1
(3) 创建容器
docker run -d --name registry -p 5000:5000 -v /opt/registry:/var/lib/registry registry:2.3.1
目录 /var/lib/registry 是仓库存放镜像的位置。
(4) 推送镜像
docker tag nginx 172.25.254.23:5000/redis:latest 改标签
# docker 镜像的命名规则 172.25.254.23:5000/redis:latest 中,172.25.254.23:5000 表示 Registry 的地址和端口。
docker push 172.25.254.23:5000/redis
# 推送镜像到 172.25.254.23:5000 仓库
docker rmi 172.25.254.23:5000/redis
# 删除本地 nginx 镜像的 TAG
docker pull 172.25.254.23:5000/redis
# 拉取镜像到本地
认证机制
(1) 创建密码
docker run --entrypoint htpasswd registry:2.3.1 -Bbn wj westos > /opt/auth/htpasswd
追加一个用户密码
docker run --entrypoint htpasswd registry:2.3.1 -Bbn admin westos >> /opt/auth/htpasswd
cat /opt/auth/htpasswd
(2) 创建镜像
docker run -d -p 5000:5000 --name registry-auth -v /opt/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry:2.3.1
(3) 推送镜像
docker tag nginx 172.25.254.23:500/nginx
docker push 172.25.254.23:500/nginx
# 推送失败,没有密码验证
docker login 172.25.254.23:5000 #进行密码验证即可
再次推送
# 再次推送成功
Registry 的配置信息都存储在 Registry 中的/etc/docker/registry/config.yml 文件。最简单的配置方法是直接将修改好的 YAML 配置文件挂载到 Registry 容器中。
如果只修改少数几个配置信息,可以通过设置环境变量来改变,比如修改storage/filesystem/rootdirectory , 只 需 要 使 用 docker run 的 -e 参 数 设 置 相 应 的REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY 变量。
以上操作均来自老师课上所讲