最近心血来潮大概的学了一下docker,docker和虚拟机相比,虚拟机占资源多,冗余步骤多,启动慢,容器恰恰相反,启动快,占资源,体积小,启三个KVM和启三个容器,三个KVM的占用会是三个docker的N倍数。烦求子的,最懒的写这种废话,直接开撸吧,从安装开始。
docker安装
docker现在分为两个版本,分别是docker-ee及docker-ce,ee是企业版,ce是社区版,我们用社区版本就够了,开始添加yum源。
先说一下我用的环境吧,其实我打算用本地的测试服务器,但是公司的网络貌似有点不太好,yum直接安装不上docker,不是安装不上,是直接无法下载,炸了,没办法,只好用自己的鸡儿了,腾讯云,系统CentOS-7.4-3.10.0-693.el7.x86_64,建议在开始前安装一下bash-completion
,命令补全参数的包,Debian/Ubuntu自带,CentOS没有,需要自己装一下,装完之后需要断开重新连一下服务器。
添加docker源
[root@rj-bai ~]# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
修改下载源为中科大源
[root@rj-bai ~]# sed -i 's#download.docker.com#mirrors.ustc.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
安装docker&更换源
[root@rj-bai ~]# yum -y install docker-ce
输出,看到Complete即可。
Dependency Installed:
audit-libs-python.x86_64 0:2.7.6-3.el7 checkpolicy.x86_64 0:2.5-4.el7 container-selinux.noarch 2:2.42-1.gitad8f0f7.el7 libcgroup.x86_64 0:0.41-13.el7
libsemanage-python.x86_64 0:2.5-8.el7 pigz.x86_64 0:2.3.4-1.el7 policycoreutils-python.x86_64 0:2.5-17.1.el7 python-IPy.noarch 0:0.75-6.el7
setools-libs.x86_64 0:3.3.8-1.1.el7
Complete!
更换源
顺便把docker源也换一下吧,免得一会还的重启
[root@rj-bai~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
启动docker,查看版本号
[root@VM_0_11_centos ~]# systemctl start docker.service
[root@VM_0_11_centos ~]# docker version
Client:
Version: 18.03.0-ce
API version: 1.37
Go version: go1.9.4
Git commit: 0520e24
Built: Wed Mar 21 23:09:15 2018
OS/Arch: linux/amd64
Experimental: false
Orchestrator: swarm
Server:
Engine:
Version: 18.03.0-ce
API version: 1.37 (minimum version 1.12)
Go version: go1.9.4
Git commit: 0520e24
Built: Wed Mar 21 23:13:03 2018
OS/Arch: linux/amd64
Experimental: false
docker是传统的CS架构,分为docker client&docker server,主要组价包括镜像、容器,仓库。到此,安装结束。
docker基本命令
docker搜索镜像
实例,搜索一个镜像,名为centos
[root@VM_0_11_centos ~]# docker search centos
输出结果
如下,取第一行,分别是什么意思解释一下。
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 4213 [OK]
参数 | 含义 |
---|---|
NAME | 镜像的名字 |
DESCRIPTION | 描述 |
STARS | 点赞次数, |
OFFICIAL | 是否为官方,建议使用官方镜像。 |
AUTOMATED | 是否自动构建 |
下载docker镜像
实例,下载centos镜像
[root@VM_0_11_centos ~]# docker pull centos
不指定版本号默认下载最新版,也就是centos7.4
输出结果
Using default tag: latest
latest: Pulling from library/centos
469cfcc7a4b3: Pull complete
Digest: sha256:989b936d56b1ace20ddf855a301741e52abca38286382cba7f44443210e96d16
Status: Downloaded newer image for centos:latest
查看镜像列表
[root@VM_0_11_centos ~]# docker images
输出结果
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest e934aafc2206 2 weeks ago 199MB
可以看到刚刚下载的centos镜像
镜像的导入导出删除
导出镜像
[root@VM_0_11_centos ~]# docker image save centos > docker-centos7.tar.gz
[root@VM_0_11_centos ~]# ll docker-centos7.tar.gz
-rw-r--r-- 1 root root 207187968 Apr 24 12:46 docker-centos7.tar.gz
删除镜像
[root@VM_0_11_centos ~]# docker rmi centos:latest
输出,如果出现none的镜像,需要通过docker images
获取到镜像的ID,使用rmi -f
进行删除即可。
Untagged: centos:latest
Untagged: centos@sha256:989b936d56b1ace20ddf855a301741e52abca38286382cba7f44443210e96d16
Deleted: sha256:e934aafc22064b7322c0250f1e32e5ce93b2d19b356f4537f5864bd102e8531f
Deleted: sha256:43e653f84b79ba52711b0f726ff5a7fd1162ae9df4be76ca1de8370b8bbf9bb0
[root@VM_0_11_centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
导入镜像
[root@VM_0_11_centos ~]# docker image load -i docker-centos7.tar.gz
输出
43e653f84b79: Loading layer [==================================================>] 207.2MB/207.2MB
Loaded image: centos:latest
[root@VM_0_11_centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest e934aafc2206 2 weeks ago 199MB
镜像管理就到这里,下面开始玩容器。
容器管理
emmmmm,既然是容器管理了,那就得先得启个容器才可以,先来玩一个简单的吧,使用docker跑一个nginx,就这么愉快的决定了,先搜索一下名为nginx的镜像。
搜索nginx镜像
[root@VM_0_11_centos ~]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 8341 [OK]
就用第一个吧,官方的。
下载nginx镜像。
[root@VM_0_11_centos ~]# docker pull nginx #下载nginx镜像
Using default tag: latest
latest: Pulling from library/nginx
2a72cbf407d6: Already exists
04b2d3302d48: Pull complete
e7f619103861: Pull complete
Digest: sha256:18156dcd747677b03968621b2729d46021ce83a5bc15118e5bcced925fb4ebb9
Status: Downloaded newer image for nginx:latest
[root@VM_0_11_centos ~]# docker images #查看镜像,加上之前的centos一共是两个。
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest b175e7467d66 13 days ago 109MB
centos latest e934aafc2206 2 weeks ago 199MB
云服务器的速度就是快,有点心疼我的流量费,哈哈。
启动一个nginx容器。
[root@VM_0_11_centos ~]# docker run -d -p 80:80 nginx
8a6d19263aeb08e60414403a61adb5c01076a562e41036653a8db5a7d9772102
参数
参数 | 含义 |
---|---|
-d | 后台运行 |
-p | 端口映射 |
主要说一下-p参数,上面的-p 80:80就是将本机的80端口映射到刚刚启动容器的80端口。他转发的原理是用了iptables的DNAT,现在查看iptables的NAT会看到将80端口的请求全部转发到了容器上,顺便看一下刚刚创建的那个容器的IP地址。
首先看一下正在运行的容器,获取到它的名称
[root@VM_0_11_centos ~]# docker ps
查看正在运行的容器,输入结果。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0f950bc96127 nginx "nginx -g 'daemon of…" 4 minutes ago Up 4 minutes 0.0.0.0:80->80/tcp heuristic_allen
参数 | 含义 |
---|---|
CONTAINER ID | docker容器的ID |
IMAGE | 所使用的镜像 |
COMMAND | 默认命令,这个一会再解释 |
CREATED | 创建时间 |
STATUS | 状态,显示的是启动时长 |
PORTS | 端口映射信息 |
NAMES | 该容器的名称 |
获取到镜像的名称了,先看一下iptables的NAT,再看一下容器的地址就知道了。
[root@VM_0_11_centos ~]# iptables -t nat -L -n
[root@VM_0_11_centos ~]# docker container inspect heuristic_allen | grep -i ipaddress
最后测试一下能不能访问到。
[root@VM_0_11_centos ~]# curl -I 140.143.143.136
HTTP/1.1 200 OK
实时证明可以访问到
登陆到容器
就是进入到容器内进行一些操作,进入容器有两种方法,不建议使用docker attach
,如果用这个登陆会和之前使用一样的终端,下面的方法是使用不同的终端。
先把这个容器停掉删掉吧,下次启动时候指定点参数,再指定一下容器的名字,删除容器不会影响到镜像,镜像和容器的概念一定要搞清楚。
[root@VM_0_11_centos ~]# docker stop `docker ps -q`
这个命令是停掉全部的容器,ps
是显示正在运行的容器,-q
就是输镜像ID,要查看全部的镜像,包括不在运行的请加上-a
删除容器
[root@VM_0_11_centos ~]# docker rm `docker ps -a -q`
启动并登录容器
还是先玩玩nginx的容器,先启动,指定名字
[root@VM_0_11_centos ~]# docker run -d --name nginx -p 80:80 nginx:latest
93375710e47db5b5ffcf78b75e3e8447db9980e95c8524024620f646446db182
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
93375710e47d nginx:latest "nginx -g 'daemon of…" 31 seconds ago Up 30 seconds 0.0.0.0:80->80/tcp nginx
登陆到容器
[root@VM_0_11_centos ~]# docker exec -it nginx /bin/bash
root@efb439ea4cae:/#
参数 | 含义 |
---|---|
-it | 打开交互式终端 |
/bin/bash | 所执行的命令 |
在这里解释一下为什么我在第一步启动容器的时候没有打开终端,因为酱紫是不是行的,我是想在启动容器时也运行起nginx,并能正常提供服务,docker容器启动后想要坚挺住不退出的条件,就是在容器里执行的最后一条命令的时候,需要把容器夯住,也就是前台运行。卡住,类似你执行tailf /var/log/messages
,想要停掉需要Ctrl+C
的那种。
这个nginx的容器启动的默认命令是nginx -g 'daemon off;'
,有兴趣的可以docker image history --no-trunc nginx:latest
看一下最上面CDM的那一行,直接执行nginx -g 'daemon off;'
不是以守护进程模式启动nginx,会夯住在前台。我如果在启动时候-it
指定了/bin/bash登陆到容器,登陆是能登陆进去,但是我一旦退出,容器马上就会关闭,nginx服务也没有启动,如果我使用了-it
不加/bin/bash使用默认的命令,nginx启动了,但是还是夯在前台,访问还有log输出出来,哈哈。
[root@VM_0_11_centos ~]# docker run -it --name nginx -p 80:80 nginx:latest
172.17.0.1 - - [24/Apr/2018:06:31:51 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
现在登录上来了,随便看看吧,这是一个以Debian9做的nginx镜像,执行命令cat /etc/os-release
查看,特别纯净的系统,常用的命令都没有,就给你装了一个nginx,想装东西?apt-update && apt-get install
去装吧,我记得好久之前也装过这个镜像,当时根本不知道这是个什么系统,登陆上来了,ifconfig没有,ps没有,netstat没有,yum安装一个吧,yum也没有,绝望了,感觉这docker太难了,进到容器里什么命令都没有,还不让我用yum,都快哭了,直到现在我才知道这特么是Debian的系统,而且绝大部分的镜像都是基于Debian/Ubuntu去做的,我个人不是很喜欢Debian/Ubuntu系列的系统,所以,一会基于CentOS镜像去自动构建一个nginx的镜像,一会再说,先把这个容器关掉吧,用centos的镜像启容器搞点事情吧。
关闭nginx容器
[root@VM_0_11_centos ~]# docker stop nginx
nginx
后台运行容器
就是将运行的容器挂到后台,不退出,先启动一个CentOS的容器,顺便搞点事情,装个ssh&nginx,并把端口映射做了,然后启动容器。
[root@VM_0_11_centos ~]# docker run --name centos7-ssh-nginx --privileged -d -p 122:22 -p 80:80 -e "container=docker" -v /sys/fs/cgroup:/sys/fs/cgroup centos:latest /usr/sbin/init
5cbaa000fa1b2be325f502644ba33876fc248f410bf2ae6744f8b6db6ea92096
[root@VM_0_11_centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5cbaa000fa1b centos:latest "/usr/sbin/init" 4 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:122->22/tcp centos7-ssh-nginx
[root@VM_0_11_centos ~]# docker exec -it centos7-ssh-nginx /bin/bash
[root@5cbaa000fa1b /]#
简单说一下-v
是挂载宿主的文件到容器,-e
是一个变量,一会会细说。这算是docker的一个BUG吧,Centos7想要使用systemctl命令启动服务就得加上这个,否则会抛出Failed to get D-Bus connection: Operation not permitted
的错误,相信现在看那个启动命令应该能看懂了吧,不多说了。
现在登录上来了安装一下ssh和nginx,需要添加一下nginx的源。
[root@5cbaa000fa1b /]# cat >>/etc/yum.repos.d/nginx.repo<<OEF
> [nginx]
> name=nginx repo
> baseurl=http://nginx.org/packages/centos/7/x86_64/
> gpgcheck=0
> enabled=1
> OEF
[root@5cbaa000fa1b /]# yum -y install openssh-server nginx net-tools
自己玩的话装ssh可以,如果真的用来跑东西,就不要装了,装完了使用netstat -lntp
来看一下占用
[root@5cbaa000fa1b /]# systemctl start nginx
[root@5cbaa000fa1b /]# systemctl start sshd
[root@5cbaa000fa1b /]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 202/nginx: master p
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 228/sshd
tcp6 0 0 :::22 :::* LISTEN 228/sshd
占用是有了,再设置一下root密码
[root@5cbaa000fa1b /]# echo Sowhat? | passwd --stdin root
Changing password for user root.
passwd: all authentication tokens updated successfully.
挂起容器,开始测试连接。
挂起的快捷键为Ctrl+P松开Ctrl+Q
,按完了会提示read escape sequence
就退回到你的宿主机了。
测试nginx,没问题。
[root@VM_0_11_centos ~]# curl -I 140.143.143.136
HTTP/1.1 200 OK
Server: nginx/1.14.0
测试ssh,可阔以连接上。
[root@VM_0_11_centos ~]# ssh root@140.143.143.136 -p122
The authenticity of host '[140.143.143.136]:122 ([140.143.143.136]:122)' can't be established.
ECDSA key fingerprint is SHA256:427vgrnOjde6RQsAV8LaPDTdwkzi5Fd9+WZB/bzIpe4.
ECDSA key fingerprint is MD5:57:e4:a6:88:7c:84:9f:e6:51:a9:70:9f:88:2f:c8:85.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[140.143.143.136]:122' (ECDSA) to the list of known hosts.
root@140.143.143.136's password:
[root@5cbaa000fa1b ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
然后,基于这个容器去做一个镜像,能提供ssh和nginx服务的镜像,但是有个问题摆在了这里,docker再启动的时候只允许指定一条默认命令,而且让容器坚挺的条件是还得有一个服务器在前台夯住,下次容器启动的时候需要启动nginx&ssh服务,所以,写个脚本吧,替换默认命令执行脚本即可。
[root@VM_0_11_centos ~]# docker exec -it centos7-ssh-nginx /bin/bash
[root@5cbaa000fa1b /]# vi init.sh
#!/bin/bash
/usr/sbin/nginx
/usr/sbin/sshd -D
基于容器制作镜像
[root@VM_0_11_centos ~]# docker commit centos7-ssh-nginx centos7-ssh-nginx
sha256:72cd93fd19021360894351da6669fc0619f3a5b9b55c9f7cd92d89582deeedab
第一个centos7-ssh-nginx
为容器的名字,第二个centos7-ssh-nginx
为镜像的名字,然后查看镜像。
[root@VM_0_11_centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7-ssh-nginx latest 72cd93fd1902 22 seconds ago 309MB
然后开始启动测试,默认命令要执行init.sh,宿主机22&80端口已被占用,启动容器时需要改一下。
docker run --privileged -d -p 1122:22 -p 81:80 -e "container=docker" -v /sys/fs/cgroup:/sys/fs/cgroup centos7-ssh-nginx:latest /init.sh
[root@VM_0_11_centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
468539b9b595 centos7-ssh-nginx:latest "/init.sh" 3 hours ago Up 3 hours 0.0.0.0:1122->22/tcp, 0.0.0.0:81->80/tcp determined_allen
换了一下,也就是吧宿主机的81&1122端口转发到容器的80&22端口,这次没有指定名字,最后开始测试。
nginx测试
[root@VM_0_11_centos ~]# curl -I 140.143.143.136:81
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Tue, 24 Apr 2018 13:20:25 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 17 Apr 2018 15:48:00 GMT
Connection: keep-alive
ETag: "5ad61730-264"
Accept-Ranges: bytes
木有问题,下面看一下SSH
[root@VM_0_11_centos ~]# ssh 140.143.143.136 -p1122
The authenticity of host '[140.143.143.136]:1122 ([140.143.143.136]:1122)' can't be established.
ECDSA key fingerprint is SHA256:ihAznbL3wYQ2XhJ1QvuEHS0wQ/GdvcOJCE23ZpweEcM.
ECDSA key fingerprint is MD5:f3:e1:d0:7c:66:5b:27:83:a4:69:64:89:41:81:c4:c3.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[140.143.143.136]:1122' (ECDSA) to the list of known hosts.
root@140.143.143.136's password:
Last login: Tue Apr 24 13:17:46 2018 from gateway
[root@468539b9b595 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
最后看一下容器的IP地址,没有错,这个最基本的景象就算是完成了,要改配置直接登录到容器去改就行了。
[root@VM_0_11_centos ~]# docker exec -it determined_allen /bin/bash
[root@468539b9b595 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
容器数据卷&Dockerfile
这俩东西放一起因为下午出了点事情,之前的服务器要新上一个H5的页面,和现有的一套H5几乎一致,阿里云服务器,现有的跑在80口,新的这个就是有几个文件不同,少了点东西,需求是要加上nginx的验证登陆,然后我开始忙这个,其实很简单,有已经装好的nginx,把代码传上去新加一个server
就行了,使用81端口,但是出了一个很奇怪的问题。
特么的访问新的H5页面不知道是怎么搞的,一个json文件返回的数据,一直是返回跑在80口json数据,而不是81端口的json数据,他俩不一样,调了好长时间就是不行,而且我把新的H5页面的里的json删掉还能访问到,看地址也是走的81端口,我和我的前端同事一脸懵逼,确认不是代码问题,而是我这里的问题,但是我也查不到是哪里的原因,绝望了。
在想特么的要不用docker跑个nginx试试?实在是找不到问题所在了,我还在找机会在正式环境实践一下,然而现在机会来了,说搞就搞,需求上面也说了,nginx跑一个H5,然后添加验证访问,想了一下会用到两个点,一个是编写Dockerfile,一个是使用容器最基本的数据券,由于当时着急看效果,我就把docker环境搭了起来,然后下了一个nginx的镜像,起了个容器,挂上H5页面就跑起来了,具体命令如下
[root@iZhp37ot8ujc37b0bgvwxzZ ~]# docker pull nginx
[root@iZhp37ot8ujc37b0bgvwxzZ ~]# docker run -d -p 81:80 -v /www/html:/usr/share/nginx/html nginx
数据卷
现在说一下docker数据卷,也就是-v
参数,现在我的测试云服务器启了两个nginx,分别占用80&81端口,都是nginx默认的欢迎页,但这是不是我想要的,我想放一些我自己的东西进去。
先以80口的为例,譬如我的网页在宿主机的/www/html
目录下,我现在要通过容器去访问,就需要使用-v
去挂载一下,需要把现有的容器停掉。
[root@VM_0_11_centos ~]# docker run -d -p 80:80 -v /data/html/:/usr/share/nginx/html:ro centos7-ssh-nginx:latest /init.sh
-v
后面的/data/html/
为宿主机目录,挂载到容器的/usr/share/nginx/html
目录,以只读的方式挂载,如果不指定,默认是rw,看需求,要访问到ro就够了。
看一下容器有没有启动。
[root@VM_0_11_centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
53322e217369 centos7-ssh-nginx:latest "/init.sh" 4 seconds ago Up 2 seconds 22/tcp, 0.0.0.0:80->80/tcp vigilant_tereshkova
新建一个html页面加点内容。
[root@VM_0_11_centos ~]# echo docker-nginx-80 > /data/html/index.html
[root@VM_0_11_centos ~]# curl 140.143.143.136
docker-nginx-80
说明没问题,还有一个--volumes-from
的挂载方式,做集群的话可能用的多,现在都是单机-v
就够了,再看一下--volumes-from
挂载方式,我再启一个容器,使用81端口,以--volumes-from
的方式去挂载数据卷。
[root@VM_0_11_centos ~]# docker run -d -p 81:80 --volumes-from vigilant_tereshkova centos7-ssh-nginx:latest /init.sh
f878e9f7d871b661b01b7ea8ff3da9d7e382bebd00b56f2946cfa7369003105c
[root@VM_0_11_centos ~]# curl 140.143.143.136:81
docker-nginx-80
这个可以在--volumes-from
参数后面指定一个容器,我指定的是80端口的容器,意思也就是我指定的容器挂载源和目标原封不动的挂在到了这个新容器,80端口挂载的位置就是nginx的网页根目录,所以81端口的容器也挂在了那里,改一下内容看一下就懂了。
[root@VM_0_11_centos ~]# echo rj-bai > /data/html/index.html
[root@VM_0_11_centos ~]# curl 140.143.143.136
rj-bai
[root@VM_0_11_centos ~]# curl 140.143.143.136:81
rj-bai
Dockerfile自动构建
之前做的那些都算是手动构建,像是上面做的那个基于CentOS的镜像去手动安装nginx服务&SSH服务,下面通过编写Dockerfile文件去自动完成这些事情,emmmm,刚刚好现在就有这么个事情,安装一个nginx,需要支持验证登陆,下面来介绍一下dockerfile的常用指令。
指令 | 含义 |
---|---|
FROM | 指定基础镜像 |
LABEL | 维护者信息 |
RUN | 构建过程中执行的命令 |
ADD | 复制文件,会自动解压 |
COPY | 复制文件,不会自动解压 |
ENV | 环境变量 |
WORKDIR | 设置当前工作目录 |
VOLUME | 设置挂载目录 |
EXPOSE | 端口映射 |
CDM | 执行的默认命令 |
ENTRYPOINT | 默认命令,与CMD不同的是他无法被替换,指定的命令会被当为参数。 |
栗子,通过Dockerfile自动构建nginx+验证登陆
直接在正式服务器上搞吧,现有的nginx是基于Debian9来做的,现在要基于CentOS去做,还要安装点别的东西,行了,开撸。
首先创建一个目录
[root@iZhp37ot8ujc37b0bgvwxzZ ~]# mkdir /data/docker/centos7-nginx && cd /data/docker/centos7-nginx
编写Dockerfile文件
名字不能改,文件必须得叫Dockerfile,还需要向容器传几个文件,Dockerfile内容如下。
FROM centos:latest
ADD nginx.repo /etc/yum.repos.d/
RUN yum -y install nginx net-tools httpd-tools
ADD init.sh /init.sh
ADD default.conf /etc/nginx/conf.d/default.conf
CMD ["/bin/bash","/init.sh"]
基于CentOS最新版本来做,之前没提过,latest
表示最新版本,添加nginx的epel源到镜像,然后安装nginx及生成密码文件的httpd-tools
,添加脚本init.sh
到镜像的根目录,CDM镜像执行的默认命令,建议不要在文件里设置挂载目录和端口映射,启容器时候在设置就好,我的当前目录存在的文件如下,要传到镜像的文件一定要与Dockerfile放在同一级目录。default.conf
文家只是加了两行关于nginx验证的东西,不会的百度一下吧。
[root@iZhp37ot8ujc37b0bgvwxzZ centos7-nginx]# ls
Dockerfile init.sh nginx.repo default.conf
Dockerfile内容已经贴出来了,nginx的epel源怎么写应该都会,贴一下init.sh的内容吧。
[root@iZhp37ot8ujc37b0bgvwxzZ centos7-nginx]# cat init.sh
#!/bin/bash
/usr/bin/htpasswd -b -c /etc/nginx/passwd.db "$http_user" "$http_pass"
nginx -g 'daemon off;'
里面有两个变量,马上就要用到-e
参数了,先把镜像正常构建了再说。
[root@iZhp37ot8ujc37b0bgvwxzZ centos7-nginx]# docker build -t centos7-nginx-verification .
[root@iZhp37ot8ujc37b0bgvwxzZ centos7-nginx]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7-nginx-verification latest bbb41c7875ac 8 seconds ago 307MB
构建的镜像名为centos7-nginx-verification
,最终的效果,看上图,通过命令也能看到刚刚创建的镜像,下面开始启动测试。
启动测试
[root@iZhp37ot8ujc37b0bgvwxzZ ~]# docker run -d -p 8088:80 \
> -v /www/html:/usr/share/nginx/html \
> -e "http_user=dalin" \
> -e "http_pass=123456" \
> centos7-nginx-verification
1dd9f6c930563c7eba01784d894a3544baac3ca287cfd52b857e329e25d635ad
[root@iZhp37ot8ujc37b0bgvwxzZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1dd9f6c93056 centos7-nginx-verification "/bin/bash /init.sh" 5 seconds ago Up 4 seconds 0.0.0.0:8088->80/tcp amazing_meninsky
52bb615b6e2a nginx-h5:latest "/init.sh" 5 hours ago Up 5 hours 0.0.0.0:81->80/tcp nginx
现在是一共启动了两个容器,一个是在跑那个新的H5,昨天弄得,刚刚有启动了一个,所以是两个,使用curl
命令测试一下,返回的应该是401就对了
[root@iZhp37ot8ujc37b0bgvwxzZ ~]# curl -I 39.104.0.0:8088
HTTP/1.1 401 Unauthorized
使用curl进行一下验证登陆,返回200,成功,一个基于CentOS自动构建nginx+验证登陆的镜像就完成了,下次如果还有需求要用,直接以这个镜像启个容器就可以了。
[root@iZhp37ot8ujc37b0bgvwxzZ ~]# curl -I -u dalin:123456 39.104.0.0:8088
HTTP/1.1 200 OK
下面说说那个传变量的参数-e
,也都看到了,我是在Dockerfile里面指定了默认命令,就是执行init.sh
这个脚本,在这个脚本里有两个变量,分别是http_user&http_pass,我们在启动的时候指定了如下两个参数。
-e "http_user=dalin" \
-e "http_pass=123456" \
这两个变量是在容器启动的时候传进来的,说白了上面两个启动参数就是给你的容器增加了两个全局变量,全局变量是啥就不用说了吧,现在登录到容器看一下,可以找到。
[root@iZhp37ot8ujc37b0bgvwxzZ ~]# docker exec -it ecstatic_northcutt /bin/bash
[root@d685b08b7d91 /]# env | grep http
http_pass=123456
http_user=dalin
用这个传参可以搞很多事情,譬如配合sed去动态替换nginx配置文件的server_name
,或是安装了ssh,解决了容器密码都是一样的尴尬局面,使用传参就可以自己定义了,如果没有传参这些东西都是写死的,需要登录到容器去改,用传参就不用了,总之用处很大,自行琢磨吧,下面大概的说一下仓库。
docker仓库
安装启动仓库服务
这个用本地的测试服务器去演示了。我服务器小水管传镜像估计会很慢,流量费是小事,需要先去pull一下仓库的镜像。
[root@localhost ~]# docker pull registry
[root@localhost ~]# yum install httpd-tools -y
会用到httpd-tools,也是用来加验证,顺便把容器也启动了吧。
[root@localhost ~]# htpasswd -Bbn docker docker >> /opt/registry-var/auth/htpasswd
[root@localhost ~]# docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -v /opt/myregistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry
dbc09df757e05ff0159e7fbfa1734c8ca57afae1eeadeff5da72137e2745db60
结果。
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dbc09df757e0 registry "/entrypoint.sh /etc…" 2 seconds ago Up 1 second 0.0.0.0:5000->5000/tcp heuristic_lichterman
打标签
我现在给一个centos的镜像打一个标签,还要加上docker仓库的地址,也就是本机的IP
[root@localhost ~]# docker image tag centos:latest 192.168.1.8:5000/entos7-nginx:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.1.8:5000/centos7-nginx latest e934aafc2206 2 weeks ago 199MB
打标签的镜像为centos:latest
,在仓库看到的名字是entos7-nginx:latest
,然后就可以开始上传了,但是docker仓库默认只支持https的环境,需要改一下docker配置文件,把仓库的地址加进去,然后重启一下docker,重启docker全部容器都会被关闭。
[root@localhost ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["192.168.1.8:5000"]
}
[root@localhost ~]# systemctl restart docker.service
启动镜像服务
[root@localhost ~]# docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -v /opt/myregistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry
上传镜像
因为启用了密码登陆,上传或是下载镜像的时候需要登陆一下。
[root@localhost ~]# docker login 192.168.1.8:5000
Username: docker
Password:
Login Succeeded
开始上传
[root@localhost ~]# docker push 192.168.1.8:5000/entos7-nginx:latest
输出结果
The push refers to repository [192.168.1.8:5000/entos7-nginx]
43e653f84b79: Pushed
latest: digest: sha256:191c883e479a7da2362b2d54c0840b2e8981e5ab62e11ab925abf8808d3d5d44 size: 529
看一下在不在
[root@localhost ~]# curl -u docker:docker 192.168.1.8:5000/v2/_catalog
{"repositories":["entos7-nginx"]}
下载镜像直接pull就可以了,也需要登陆一下,暂时就到这里吧
docker pull 192.168.1.8:5000/centos7-nginx