Docker入门
一、简介
1、简介
Docker是开发人员和系统管理员使用容器开发,部署和运行应用程序的平台。
使用Linux容器部署应用程序称为容器化,容器化逐渐变的流行是因为它有以下几个特点:
-
灵活性:即使是最复杂的应用也可以容器化
-
轻量性:容器使用并共享主机内核
-
互换性:可以即时部署更新和升级
-
便携性:可以在本地构建,云端部署,任何地方运行
-
扩展性:可以增加并自动分发容器的副本
-
堆叠性:可以即时地垂直堆叠(stack)各种服务(services)
2、相关概念
- 镜像和容器
镜像是一个包含程序运行时所需的所有内容:代码、运行时环境、库、环境变量和配置文件等的可执行包。
通过运行镜像可以启动容器,容器是镜像的运行时实例。
- 容器和虚拟机
容器在Linux上运行并与其他容器共享主机的内核,它运行一个独立的进程,不占用任何其他可执行的内存,因此它是轻量的。
相反,虚拟机运行一个完整的”客户端”操作系统,通过虚拟机管理程序对主机资源进行虚拟访问。通常情况下,虚拟机所使用的资源比大多数应用程序所需要的更多。
二、安装
1、安装Linux虚拟机
由于我之前安装的虚拟机是RedHat,但官网中并没有RedHat的安装介绍,因此需要先安装CentOS或Ubuntu。
此处选择Ubuntu Disco 19.04(操作系统要求是64位的)。
2、安装Docker
-
设置repository
- 更新软件源中的所有软件
sudo apt-get update
- 安装软件包,允许通过HTTPS使用库(repository)
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
- 添加Docker官方的GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
验证:
sudo apt-key fingerprint 0EBFCD88
- 设置稳定的库(repository)的地址
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
-
安装Docker引擎
- 更新软件源
sudo apt-get update
- 安装最新版Docker引擎
sudo apt-get install docker-ce docker-ce-cli containerd.io
- 验证是否安装成功
sudo docker version
或
sudo docker run hello-world
为了使用方便,直接将用户切换到root执行命令。
三、Docker基本命令
docker version
docker version [OPTIONS]
显示Docker的版本信息。
docker info
docker info [OPTIONS]
显示Docker的系统信息,包括镜像和容器的运行情况等。
1、镜像相关命令
docker pull
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
从镜像仓库中拉取或更新指定的镜像。
docker images
或docker image ls
docker images [OPTIONS] [REPOSITORY[:TAG]]
docker image ls
列出本地镜像列表。
docker rmi
docker rmi [OPTIONS] IMAGE [IMAGE...]
删除本地的一个或多个镜像,-f
:强制删除。
docker tag
docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
将镜像标记为某个库(REPOSITORY)下。
docker build
docker build [OPTIONS] PATH | URL | -
使用Dockerfile文件创建镜像。
docker history
docker history [OPTIONS] IMAGE
查看镜像的创建历史。
2、容器相关命令
docker container ls
docker container ls
列出所有容器信息。
docker run
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
创建一个新的容器并运行一个命令。
docker start
docker start [OPTIONS] CONTAINER [CONTAINER...]
启动一个或多个未启动的容器。
docker stop
docker stop [OPTIONS] CONTAINER [CONTAINER...]
停止一个或多运行中的容器。
docker restart
docker restart [OPTIONS] CONTAINER [CONTAINER...]
重启容器。
docker kill
docker kill [OPTIONS] CONTAINER [CONTAINER...]
杀掉一个运行中的容器。
docker rm
docker rm [OPTIONS] CONTAINER [CONTAINER...]
删除一个或多个容器。
docker exec
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
在运行的容器中执行命令,-i
:即时没有attach也保持输入有效;-t
:分配一个伪终端。
docker ps
docker ps [OPTIONS]
列出容器信息。
docker top
docker top [OPTIONS] CONTAINER [ps OPTIONS]
查看容器中运行的进程信息。
docker inspect
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
查看镜像/容器的元数据。
docker attach
docker attach [OPTIONS] CONTAINER
将本地标准输入,输出和错误流附加到正在运行的容器上。
docker port
docker port [OPTIONS] CONTAINER [PRIVATE_PORT[/PROTO]]
列出容器的端口映射。
docker cp
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
此命令用于在主机和容器之前拷贝数据。
四、运行镜像
此处以运行nginx镜像为例,具体如何使用此镜像可参考:NGINX - How to use this image。
1、从仓库中拉取镜像
之前运行docker run hello-world
时,由于在本地找不到hello-world
的镜像,因此自动从仓库中拉取。此处手动拉取nginx镜像:
docker pull nginx
2、运行镜像
以后台方式运行nginx:
docker run -d nginx
3、在容器中执行命令
查看容器信息:
docker ps
进入容器终端并执行命令:
docker exec -it e58ff9759645 bash
注:e58ff9759645 为容器ID。
4、端口映射
先停止容器:
docker stop e58ff9759645
重新运行,暴露外部端口:
docker run -d -p 8080:80 nginx
访问虚拟机8080端口:
五、制作镜像
1、编写Dockerfile
Dockerfile
定义了容器内部环境发生的事情,在此容器环境中访问网络接口、磁盘驱动器等资源都是虚拟化的,与系统的其他部分是隔离的,因此需要将端口映射到外部;并指定要拷贝到此环境中的文件。这样使用Dockerfile文件构建(build)出的应用程序在任何地方运行都会具有完全相同的行为。
- 创建目录和文件
创建一个新的目录:
mkdir hello
切换到该目录下,创建Dockerfile文件:
cd hello
mkdir Dockerfile
- 编辑Dockerfile
在Dockerfile中增加以下内容:
# Use an official Python runtime as a parent image
FROM python:3.6-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
2、编写应用程序
- 创建应用程序文件
创建Dockerfile中使用到的requirements.txt
和app.py
:
touch requirements.txt
touch app.py
- 编辑文件内容
requirements.txt
文件内容:
Flask
Redis
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)
3、构建
- 构建命令
docker build --tag=friendlyhello .
或
docker build -t=friendlyhello .
- 错误及解决方法
如果出现以下错误:
Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))
after connection broken by ProxyError('Cannot connect to proxy.', NewConnectionError(
'<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at xxxxxxxxxx>:
Failed to establish a new connection:,))':
则需要在/etc/docker/
目录下创建或编辑daemon.json
文件,增加dns
的配置:
{
"dns": ["your_dns_address", "8.8.8.8"]
}
之后重启docker服务:
service docker restart
然后再次构建即可成功。
4、运行及效果
运行镜像,并将容器暴露的80端口映射到主机的8080端口:
docker run -p 8080:80 friendlyhello
运行效果: