MENU

docker入门及实践

2018 年 04 月 23 日 • 应用服务器

最近心血来潮 (xian de dan teng) 大概的学了一下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 IDdocker容器的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仓库

安装启动仓库服务

这个用本地的测试服务器去演示了。我服务器小水管传镜像估计会很慢,流量费是小事 (you dian gui) ,需要先去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
最后编辑于: 2018 年 12 月 10 日
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码