序言
黄金指,一不小心就弄出一个故障。。。好可怕好可怕,我的小心脏。。。我的小心眼。。。
我这么信任你,你居然欺骗我。。。。fuck,这么大的坑,填不满啊。。。
生产变更,做再多的准备都不为过。。。double check。。。所谓的预期无影响都是骗人的。。。感觉很重要。。。内心是拒绝的。。。但是并不能拒绝。。。心魔啊、、、
为何要搭建私有仓库
在进行docker的时候,一般都是使用共有仓库来下载相关的镜像文件,然后运行一个镜像的实例也就是运行一个容器,如下:
在使用docker run的时候,首先查找的是本地仓库,如果本地没有,那么就会向公共仓库发起请求,找到对应的版本,然后下载,下载之后,运行这个镜像的实例,也就是dokcer images的结果是下载的镜像,而docker ps看到的是容器。
注册服务器(repository),仓库(registry),镜像(image),容器(container)之间的关系:注册服务器主要是用来存放仓库的服务器,在一个服务器上有多个仓库,而仓库又可以分为公共仓库和私有仓库,一个仓库里面有可以有多个镜像,而容器则是镜像的一个实例。
其实最简单的理解方式就是在使用linux系统的时候,我们会搭建yum源,而有公共的yum源epel,而总是喜欢搭建本地源,主要是为了应对内网环境。
在以上运行的registry容器其实就是一个私有仓库。在其中提供了监听的端口5000.
使用dockerfile来创建自己的镜像
在这里会使用dockerfile来创建自己的镜像,然后运行一个python程序,主要就是flask访问redis,dockerfile内容如下:
[root@docker-1 dockerfile]# cat Dockerfile
FROM python:2.7-slim
WORKDIR /app
ADD . /app
EXPOSE 80
ENV NAME World
CMD ["python","app.py"]
在写dockerfile的时候,第一行必须指定基础的镜像,此处的dockerfile就是以python-2.7-slim为基础镜像,当指定为基础镜像的时候使用的关键字为FROM。
WORKDIR表示指定工作目录,主要是为了在使用RUN,CMD,ENTRYPOINT指定工作目录,在指定目录的时候,如果没有以/开头那么表示为相对路径,如果指定了那么使用的是绝对路径。
ADD表示复制指定的源文件到容器的目录路径之中,在使用COPY的时候,也是复制,只是相对于dockerfile的相对路径。
RUN后面如果直接接的是命令,那么就是表示在shell中直接运行的命令,也就是使用/bin/sh -c 来直接运行这个命令;以上的RUN也可以修改为RUN [“executable”,"pip install --trusted-host pypi.python.org -r requirements.txt"],这步的主要目的就是安装相关的python模块文件redis和flask。
EXPOSE表示为容器对外的端口,在启动容器的时候,可以使用参数-P来指定容器的端口隐射关系。
ENV表示设定环境变量,会被RUN使用到,并且在容器运行的时候保持。
CMD表示指定容器启动时的命令,在上面的表示意思就是容器运行之后,运行python app.py。
dockerfile写完之后,那么就需要创建一个app依赖的模块文件,也就是requirements.txt,内容如下:
[root@docker-1 dockerfile]# cat requirements.txt
Flask
Redis
在根据flask写一个简单的程序,监听端口80:
[root@docker-1 dockerfile]# cat app.py (此处为官网实例)
from flask import Flask
from redis import Redis, RedisError
import os
import socket
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "cannot connect to Redis, counter disabled"
html = "Hello !" \
"Hostname:
" \
"Visits: "
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
所以一切准备完毕,那么开始编译镜像:
在编译镜像的时候,使用的参数未build,-t表示为这个镜像打上标签。
在进行push到私有仓库的时候,首先必须打tag,标记相关的ip和端口,如下:
在这个registry使用的是v2版本,从而和v1的api接口不一样,默认存储的路径为:
这个也就是刚刚上传的镜像文件,使用curl可以来进行检查查看(api文档路径https://docs.docker.com/registry/spec/api/):
看以上的ip地址问本宿主机的ip地址,查看本机的监听端口和容器的监听端口,如下:
其实。。。。docker的地址也是可以直接访问的,尼玛。。。
关键是这第二个报错,你TM为啥是V1的地址呢。。。为什么呢。百思不得骑姐。。。。
第二个报错需要修改启动文件,在启动docker的时候,注册这个服务器,然后使用http协议就好了,如下:
运行python程序
在上面创建一个python的程序,那么就运行一下:
当创建容器失败后,那么就会显示状态为创建中,但是并不能运行,需要删除,如下:
创建容器,并使用默认的CMD进行运行,然后使用curl进行访问:
冬。。微凉
这个冬天太冷了,手指都冻僵了,打个docker这个指令,都很多次出现dokcer。。。
dokcer的好处太多,照着目前看来,比虚拟机好无数倍,拿着镜像就可以到处浪了。。。虚拟机还需要修改各种配置。。。各种环境变量。。。
来。。。谁来送点温暖,你懂的。。。哈哈
领取专属 10元无门槛券
私享最新 技术干货