基本信息
- 容器和镜像
镜像中包括运行应用程序所需的所有内容的代码,运行时,库,环境变量,和配置文件
通过运行镜像得到一个容器,容器是镜像运行时的一个实例
- 容器和虚拟机
容器运行在原生的linux中,与其他容器共享主机内核,它运行在独立的线程上,相比于其他可执行文件,它也不会占用更多内存,这使得它比较轻量级
相比之下,虚拟机(VM)运行一个完整的“客户”操作系统,通过虚拟机管理程序对主机资源进行虚拟访问。通常,VM提供的环境比大多数应用程序需要的资源更多。
基本命令
- docker --version 查看docker版本
- docker info 查看docker信息
- docker image ls 列出本地镜像
- docker run hello-world 一个测试用的镜像
- docker ps 查看所有运行着的容器
- 列出所有的容器 (running, all, all in quiet mode)
docker container ls
docker container ls --all
docker container ls -aq
- docker search 镜像名称关键字 搜索可用镜像,搜索结果会显示镜像全称
- docker pull 镜像全称 下载容器镜像
- docker rmi -f 镜像全称 删除镜像
- docker run learn/tutorial echo "hello word" 打印hello world
容器定义文件Dockerfile
- 为了演示,我们将在一个容器中运行一个python web 程序:
在本地计算机上创建一个空目录。cd到新目录,创建一个名为Dockerfile的文件,将以下内容复制并粘贴到该文件中,然后保存。记下Dockerfile中每个语句的注释。 - Dockerfile
# Use an official Python runtime as a parent image
# 用一个官方的python运行时作为父镜像
FROM python:2.7-slim
# Set the working directory to /app
# 工作空间设置为/app
WORKDIR /app
# Copy the current directory contents into the container at /app
# 拷贝当前路径下的所有内容到容器的/app目录
COPY . /app
# Install any needed packages specified in requirements.txt
# 执行pip安装必要的依赖
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Make port 80 available to the world outside this container
# 容器将80端口暴露到容器之外
EXPOSE 80
# Define environment variable
# 定义环境变量
ENV NAME World
# Run app.py when the container launches
# 容器载入时,运行app.py
CMD ["python", "app.py"]
这个Dockefile关联了另外2个文件app.py和requirements.txt,接下来继续创建这俩文件
- app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
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 = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {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)
这是个Flask框架的web程序
- requirements.txt
Flask
Redis
- 如果你操作正确,那么你的命令行大概像下面这样(windows)
F:\>mkdir dockerExample
F:\>cd dockerExample
# 创建文件
F:\dockerExample>fsutil file createnew Dockerfile 0
已创建文件 F:\dockerExample\Dockerfile
# notepad 打开记事本,将对应文件的内容填充进去
F:\dockerExample>notepad Dockerfile
F:\dockerExample>notepad requirements.txt
F:\dockerExample>notepad app.py
F:\dockerExample 的目录
2019/05/13 20:40 <DIR> .
2019/05/13 20:40 <DIR> ..
2019/05/13 20:33 687 app.py
2019/05/13 20:31 531 Dockerfile
2019/05/13 20:32 12 requirements.txt
3 个文件 1,230 字节
2 个目录 40,458,706,944 可用字节
- 构建镜像
现在运行build命令。将创建一个Docker镜像,我们将使用该--tag选项命名。如果你想用较短的选项,
请使用-t
F:\dockerExample>docker build -t=friendlyhello .
Sending build context to Docker daemon 5.12kB
Step 1/7 : FROM python:2.7-slim
2.7-slim: Pulling from library/python
743f2d6c1f65: Pull complete 9bfbedfce8de: Pull complete 7f4da2474cef: Pull complete ffc893575679: Pull complete Digest: sha256:686bc67cbebf4c4fb0d96d55650d8704d00ccb6b9c6bdd0bee5fad48b827a6cb
Status: Downloaded newer image for python:2.7-slim
---> eb40dcfcbc42
Step 2/7 : WORKDIR /app
---> Running in ba0963035cc4
Removing intermediate container ba0963035cc4
---> 63275e530678
Step 3/7 : COPY . /app
---> 4d8013198979
Step 4/7 : RUN pip install --trusted-host pypi.python.org -r requirements.txt
---> Running in 2596525388cd
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Collecting Flask (from -r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB)
Collecting Redis (from -r requirements.txt (line 2))
Downloading https://files.pythonhosted.org/packages/ac/a7/cff10cc5f1180834a3ed564d148fb4329c989cbb1f2e196fc9a10fa07072/redis-3.2.1-py2.py3-none-any.whl (65kB)
Collecting itsdangerous>=0.24 (from Flask->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl
Collecting Jinja2>=2.10 (from Flask->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/1d/e7/fd8b501e7a6dfe492a433deb7b9d833d39ca74916fa8bc63dd1a4947a671/Jinja2-2.10.1-py2.py3-none-any.whl (124kB)
Collecting Werkzeug>=0.14 (from Flask->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/18/79/84f02539cc181cdbf5ff5a41b9f52cae870b6f632767e43ba6ac70132e92/Werkzeug-0.15.2-py2.py3-none-any.whl (328kB)
Collecting click>=5.1 (from Flask->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->Flask->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/fb/40/f3adb7cf24a8012813c5edb20329eb22d5d8e2a0ecf73d21d6b85865da11/MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl
Installing collected packages: itsdangerous, MarkupSafe, Jinja2, Werkzeug, click, Flask, Redis
Successfully installed Flask-1.0.2 Jinja2-2.10.1 MarkupSafe-1.1.1 Redis-3.2.1 Werkzeug-0.15.2 click-7.0 itsdangerous-1.1.0
Removing intermediate container 2596525388cd
---> dd688a3fe448
Step 5/7 : EXPOSE 80
---> Running in 48b8f0a03c46
Removing intermediate container 48b8f0a03c46
---> 056afc3d12ad
Step 6/7 : ENV NAME World
---> Running in f7d23f8273e4
Removing intermediate container f7d23f8273e4
---> 4eb46b07a490
Step 7/7 : CMD ["python", "app.py"]
---> Running in f7b483731c3c
Removing intermediate container f7b483731c3c
---> ff5d8601fdda
Successfully built ff5d8601fdda
Successfully tagged friendlyhello:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
- 那么构建的镜像在哪里呢?它位于本地Docker镜像注册表中:
F:\dockerExample>docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
friendlyhello latest ff5d8601fdda 54 seconds ago 131MB
python 2.7-slim eb40dcfcbc42 5 days ago 120MB
hello-world latest fce289e99eb9 4 months ago 1.84kB
注意friendlyhello的标签,默认是latest。标签选项的完整语法类似于--tag=friendlyhello:v0.0.1。
- 如何运行friendlyhello作为一个web程序?
使用以下方法将计算机的端口4000映射到容器的已发布端口80(-p选项):
F:\dockerExample>docker run -p 4000:80 friendlyhello
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
应该看到Python正在为应用提供服务的信息提示http://0.0.0.0:80。但是该消息来自容器内部,容器不知道你将该容器的端口80映射到物理机器的4000端口,从而生成正确的URL http://localhost:4000。
在Web浏览器中转到该URL以查看在网页上提供的显示内容。
在Windows上,显式停止容器
在Windows系统上,CTRL+C不会停止容器。因此,首先键入CTRL+C以获取提示(或打开另一个shell),然后键入 docker container ls以列出正在运行的容器,然后 docker container stop <Container NAME or ID>停止容器。否则,当您尝试在下一步中重新运行容器时,会从守护程序收到错误响应:F:\dockerExample>docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 18830b8b16ed friendlyhello "python app.py" 2 hours ago Up 2 hours 0.0.0.0:4000->80/tcp clever_burnell F:\dockerExample>docker container stop clever_burnell clever_burnell F:\dockerExample>docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES F:\dockerExample>
- 使容器在后台运行(detached mode):
docker run -d -p 4000:80 friendlyhello
执行之后会获得一个container id,当然,docker container ls能找到它缩写的container id:
F:\dockerExample>docker run -d -p 4000:80 friendlyhello
478d81f54f03635e116e3fae3a1b32f7ec8a40d1f4bb178cd87fe0138db69e58
F:\dockerExample>docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
478d81f54f03 friendlyhello "python app.py" About a minute ago Up About a minute 0.0.0.0:4000->80/tcp cranky_antonelli
F:\dockerExample>
接下来试着用这个缩写的container id停止这个正在运行的容器
F:\dockerExample>docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
478d81f54f03 friendlyhello "python app.py" About a minute ago Up About a minute 0.0.0.0:4000->80/tcp cranky_antonelli
F:\dockerExample>docker container stop 478d81f54f03
478d81f54f03
F:\dockerExample>docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
F:\dockerExample>
- 将镜像推送到dockerhub,你可以将它理解为docker版本的github,只不过里面存储的时docker的镜像,而不是代码,在此之前,你需要登录,如果没有,请执行以下指令:
F:\dockerExample>docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: micoldd
Password:
Login Succeeded
-
在推送之前还有一个重要步骤是给镜像打标签
将本地镜像与镜像仓库上的镜像相关联的表示法是username/repository:tag
。标签是可选的,但建议使用,因为它是注册管理机构用来为Docker镜像提供版本管理的机制。为存储库提供存储库和标记有意义的名称,例如get-started:part2
。这会将图像放入get-started
存储库并将其标记为part2
。
docker tag image
加上用户名 存储库名称和标记名称运行,以便将图像上传到所需的目标位置。该命令的语法是:docker tag image username/repository:tag
例如:
F:\dockerExample>docker tag friendlyhello micoldd/test:friendlyhello
运行docker image ls以查看新标记的图像。
F:\dockerExample>docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE micoldd/test friendlyhello ff5d8601fdda 2 hours ago 131MB friendlyhello latest ff5d8601fdda 2 hours ago 131MB python 2.7-slim eb40dcfcbc42 5 days ago 120MB hello-world latest fce289e99eb9 4 months ago 1.84kB
-
发布镜像到dockerhub
将标记的图像上传到存储库:docker push username/repository:tag
比如(如果出现 net/http: TLS handshake timeout多试几次,dockerhub网络抽风,GFW):
F:\dockerExample>docker push micoldd/test:friendlyhello The push refers to repository [docker.io/micoldd/test] 2322d80cba28: Layer already exists 20be5d221cc2: Layer already exists 59fe83a10910: Layer already exists 0ec0d723449a: Layer already exists 5c78e81a8fd9: Mounted from library/python 7b6b548a54d0: Layer already exists 6270adb5794c: Layer already exists friendlyhello: digest: sha256:8a2967f700be25f0e89dcc39cf97a2de3f7b842615f68bf5a622bf36aa91903f size: 1787
完成后,此上传的结果将公开发布。如果您登录到Docker Hub,则会看到其中的新镜像。
dockerhub
-
从远程存储库中拉出并运行映像
从现在开始,您可以使用docker run
命令在任何计算机上使用和运行您的应用程序:
docker run -p 4000:80 username/repository:tag
如果镜像在本地不可用,则Docker会从存储库(docker)中提取镜像。
docker run -d -p 4000:80 micoldd/test:friendlyhello
Unable to find image 'micoldd/test:friendlyhello' locally
part2: Pulling from gordon/get-started
10a267c67f42: Already exists
f68a39a6a5e4: Already exists
9beaffc0cf19: Already exists
3c1fe835fb6b: Already exists
4c9f1fa8fcb8: Already exists
ee7d8f576a14: Already exists
fbccdcced46e: Already exists
Digest: sha256:0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068
Status: Downloaded newer image for micoldd/test:friendlyhello
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
无论在哪里执行上面的docker run
命令,只要本地仓库中没有,它都会拉取你的镜像,以及Python和所有依赖项requirements.txt
,并运行你的代码。它们都在一个容器中一起运行,你不需要在主机上安装任何东西让Docker运行它。
导入导出操作
-
【docker】离线环境导入镜像
docker save image > /root/image.tar 导出镜像
docker load < /root/image.tar 导出镜像
错误集锦
dial tcp: lookup index.docker.io on read udp : i/o timeout
或
dial tcp: lookup index.docker.io: no such host
DockerHub 加速:
查询DNS记录
| => dig @114.114.114.114 index.docker.io
; <<>> DiG 9.9.7-P3 <<>> @114.114.114.114 index.docker.io
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60071
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;index.docker.io. IN A
;; ANSWER SECTION:
index.docker.io. 300 IN CNAME elb-io.us-east-1.aws.dckr.io.
elb-io.us-east-1.aws.dckr.io. 900 IN CNAME us-east-1-elbio-rm5bon1qaeo4-623296237.us-east-1.elb.amazonaws.com.
us-east-1-elbio-rm5bon1qaeo4-623296237.us-east-1.elb.amazonaws.com. 60 IN A 3.91.211.1
us-east-1-elbio-rm5bon1qaeo4-623296237.us-east-1.elb.amazonaws.com. 60 IN A 52.207.42.240
us-east-1-elbio-rm5bon1qaeo4-623296237.us-east-1.elb.amazonaws.com. 60 IN A 52.54.178.62
可以看到index.docker.io的延迟是300,选个响应时间短的us-east-1-elbio-rm5bon1qaeo4-623296237.us-east-1.elb.amazonaws.com
:52.54.178.62
52.54.178.62 index.docker.io
加入到hosts文件中接着修改代理
Linux
:
将下面的代码加入到你的 Docker 配置文件 /etc/docker/daemon.json 中。适用于 Ubuntu14.04、Debian、CentOS6 、CentOS7、Fedora、Arch Linux、openSUSE Leap 42.1,其他版本可能有细微不同:{ "registry-mirrors": ["https://registry.docker-cn.com"] }
dockerhub加速
MacOS
:
右键点击桌面顶栏的 docker 图标,选择 Preferences ,在 Daemon 标签(Docker 17.03 之前版本为 Advanced 标签)下的 Registry mirrors 列表中加入下面的镜像地址:
https://registry.docker-cn.com
Windows:
配置文件在~/.docker/daemon.json,更便捷的方式是
在桌面右下角状态栏中右键 docker 图标,修改在 Docker Daemon 标签页中的 json ,填入下面的地址:
https://registry.docker-cn.com
网友评论