docker部署实战

 

检查docker镜像

$ ps -aux | grep -v grep | grep docker-proxy

查看被docker-proxy占用的端口

停止 doker 进程,删除所有容器,然后删除 local-kv.db 这个文件,再启动 docker 就可以了。

$ sudo service docker stop
$ docker rm $(docker ps -aq)
$ sudo rm /var/lib/docker/network/files/local-kv.db
$ sudo service docker start

这个应用的代码部分(app.py)非常简单:

from flask import Flask
import socket
import os

app = Flask(__name__)

@app.route('/')
def hello():
    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>"           
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())
    
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

在这段代码中,我使用 Flask 框架启动了一个 Web 服务器,而它唯一的功能是:如果当前环境中有“NAME”这个环境变量,就把它打印在“Hello”之后,否则就打印“Hello world”,最后再打印出当前环境的 hostname。这个应用的依赖,则被定义在了同目录下的 requirements.txt 文件里,内容如下所示:

$ cat requirements.txt
Flask

而将这样一个应用容器化的第一步,是制作容器镜像。不过,相较于我之前介绍的制作 rootfs 的过程,Docker 为你提供了一种更便捷的方式,叫作 Dockerfile,如下所示。

 

# 使用官方提供的Python开发镜像作为基础镜像
FROM python:2.7-slim

# 将工作目录切换为/app
WORKDIR /app

# 将当前目录下的所有内容复制到/app下
ADD . /app

# 使用pip命令安装这个应用所需要的依赖
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# 允许外界访问容器的80端口
EXPOSE 80

# 设置环境变量
ENV NAME World

# 设置容器进程为:python app.py,即:这个Python应用的启动命令
CMD ["python", "app.py"]

通过这个文件的内容,你可以看到 Dockerfile 的设计思想,是使用一些标准的原语(即大写高亮的词语),描述我们所要构建的 Docker 镜像。并且这些原语,都是按顺序处理的。比如 FROM 原语,指定了“python:2.7-slim”这个官方维护的基础镜像,从而免去了安装 Python 等语言环境的操作。否则,这一段我们就得这么写了:

FROM ubuntu:latest
RUN apt-get update -yRUN apt-get install -y python-pip python-dev build-essential
...

 

其中,RUN 原语就是在容器里执行 shell 命令的意思。而 WORKDIR,意思是在这一句之后,Dockerfile 后面的操作都以这一句指定的 /app 目录作为当前目录。所以,到了最后的 CMD,意思是 Dockerfile 指定 python app.py 为这个容器的进程。这里,app.py 的实际路径是 /app/app.py。所以,CMD ["python", "app.py"]等价于"docker run <image> python app.py"。另外,在使用 Dockerfile 时,你可能还会看到一个叫作 ENTRYPOINT 的原语。实际上,它和 CMD 都是 Docker 容器进程启动所必需的参数,完整执行格式是:“ENTRYPOINT CMD”。但是,默认情况下,Docker 会为你提供一个隐含的 ENTRYPOINT,即:/bin/sh -c。所以,在不指定 ENTRYPOINT 时,比如在我们这个例子里,实际上运行在容器里的完整进程是:/bin/sh -c "python app.py",即 CMD 的内容就是 ENTRYPOINT 的参数。备注:基于以上原因,我们后面会统一称 Docker 容器的启动进程为 ENTRYPOINT,而不是 CMD。需要注意的是,Dockerfile 里的原语并不都是指对容器内部的操作。就比如 ADD,它指的是把当前目录(即 Dockerfile 所在的目录)里的文件,复制到指定容器内的目录当中。读懂这个 Dockerfile 之后,我再把上述内容,保存到当前目录里一个名叫“Dockerfile”的文件中:

$ ls
Dockerfile  app.py   requirements.txt

接下来,我就可以让 Docker 制作这个镜像了,在当前目录执行:

$ docker build -t helloworld .

 

其中,-t 的作用是给这个镜像加一个 Tag,即:起一个好听的名字。docker build 会自动加载当前目录下的 Dockerfile 文件,然后按照顺序,执行文件中的原语。而这个过程,实际上可以等同于 Docker 使用基础镜像启动了一个容器,然后在容器中依次执行 Dockerfile 中的原语。需要注意的是,Dockerfile 中的每个原语执行后,都会生成一个对应的镜像层。即使原语本身并没有明显地修改文件的操作(比如,ENV 原语),它对应的层也会存在。只不过在外界看来,这个层是空的。docker build 操作完成后,我可以通过 docker images 命令查看结果:

$ docker image ls

REPOSITORY            TAG                 IMAGE ID
helloworld         latest              653287cdf998

接下来,我使用这个镜像,通过 docker run 命令启动容器:

 

$ docker run -p 4000:80 helloworld

在这一句命令中,镜像名 helloworld 后面,我什么都不用写,因为在 Dockerfile 中已经指定了 CMD

同时,我已经通过 -p 4000:80 告诉了 Docker,请把容器内的 80 端口映射在宿主机的 4000 端口上。这样做的目的是,只要访问宿主机的 4000 端口,我就可以看到容器里应用返回的结果:

 

$ curl http://localhost:4000
<h3>Hello World!</h3><b>Hostname:</b> 4ddf4638572d<br/>

 

上传到dockerhub

我们可以将image上传到dockerhub中,从而能够在任何地方运行image。
首先我们需要先注册一个账号,然后输入docker login在本地登录账号

使用镜像加速器
直接访问dockerhub时,访问速度会较慢,这时候可以采用镜像加速器。国内的镜像加速器有

Azure 中国镜像 https://dockerhub.azk8s.cn
七牛云加速器 https://reg-mirror.qiniu.com
阿里云加速器(需登录账号获取)
在/etc/docker/daemon.json中写入以下内容

{
  "registry-mirrors": [
    "https://dockerhub.azk8s.cn",
    "https://reg-mirror.qiniu.com"
  ]
}
之后重启服务

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
执行docker info可以查看镜像是否添加成功

$ docker info
   ...
 Registry Mirrors:
  https://dockerhub.azk8s.cn/
  https://reg-mirror.qiniu.com/
 Live Restore Enabled: false
关联仓库
使用username/repository:tag可已将本地image和远程仓库关联到一起,其中tag是可选的,当tag时,仓库会为相应的image打上标签。其完整的指令是

docker tag image username/repository:tag
例如

docker tag friendlyhello   yezh01/getstart:v1.0

$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
friendlyhello       latest              7ecc82fd960a        23 hours ago        148MB
yezh01/getstart     v1.0                7ecc82fd960a        23 hours ago        148MB
python              2.7-slim            5f759d36aead        30 hours ago        137MB
hello-world         latest              fce289e99eb9        7 months ago        1.84kB
检查image可以发现其中多了一个yezh01/getstart

 上推image
我们需要先将image上传到dockerhub中,才能在不同机器上运行image,上传指令为:

$ docker push yezh01/getstart:v1.0 
上传完成后,,我们可以通过在任何机器上通过以下命令运行image

docker run -p 4000:80 username/repository:tag

 docker常规---启动停止关闭重启

一、启动一个已经停止的容器实例

docker start 容器ID或容器名,建议使用容器ID,容器ID支持模糊查询而容器名称不支持
1. 先查看已经暂停的容器实例信息
2. 通过docker start 067启动容器
3. 通过docker ps 查看当前启动的容器
具体操作如下图



 

docker start 还有两个参数
-it:以 交互模式启动  

 sudo docker run -it  -p 8009:80  apinetcoredocker:1.0.0
-p 8009:80指将外部访问8009映射到内部的80端口,apinetcoredocker:1.0.0指镜像名称

因为是交互模式所以当前会话不支持继续输入命令工作,如果想看主机上的其他信息,可以考虑重新开启一个会话 




-d:以 附加进程方式启动  

 sudo docker run -d  -p 8009:80  apinetcoredocker:1.0.0
-d参数指用附加进程方式启动容器,上面的方法如不指定容器名称,系统会默认创建,如需要指定容器名称,添加--name 参数

sudo docker run -d  -p 8009:80  --name testcore apinetcoredocker:1.0.0
执行命令界面



测试结果页面

 

进入docker容器里面,本人环境为ubuntu环境

 sudo docker exec -it 067 /bin/bash
  067指的是容器ID前3位,这里是模糊查询

执行后会显示/app#,这时我们通过curl 127.0.0.1:80/api/values ,查看显示运行是否正常,退出直接输入exit



二、停止一个正在运行的容器
1、docker stop 此方式常常被翻译为优雅的停止容器

docker stop 容器ID或容器名
参数 -t:关闭容器的限时,如果超时未能关闭则用kill强制关闭,默认值10s,这个时间用于容器的自己保存状态
docker stop -t=60 容器ID或容器名

2、docker kill

docker kill 容器ID或容器名 :直接关闭容器

由此可见stop和kill的主要区别:stop给与一定的关闭时间交由容器自己保存状态,kill直接关闭容器
想更进一步了解处理机制的可以看下面这篇文章,比较详细但是需要其他方面的
https://www.jb51.net/article/96617.htm

三、重启一个容器

docker restart 容器ID或容器名 :不管容器是否启动,直接重启容器
1. 首先 docker ps 查看正在运行的容器信息,显示2分钟前启动运行
2. docker restart 59ec 重启容器
3. 再次 docker ps 查看容器信息 显示 2秒前启动运行

docker restart 参数
-t:关闭容器的限时,如果超时未能关闭则用kill强制关闭,默认值10s,这个时间用于容器的自己保存状态
 

原文地址:https://blog.csdn.net/Michel4Liu/article/details/80889977
启停重开

 

posted @ 2020-03-19 22:51  AnthonyWang  阅读(446)  评论(0)    收藏  举报