1. 构建你的Docker环境(最复杂的问题要用最简单的方式来解决)
Docker是一个对于开发者和系统管理员用容器去开发,部署和运行应用程序的一个平台。
-
Docker非常流行的几个因素
- Flexible(灵活的)
- Lightweight(轻量级的)
- Interchangeable(可互换的,可交替的)
- Portable(便携的)
- Scalable(可扩展的)
- Stackable(易叠起堆放的;可叠起堆放的)
-
镜像和容器
- 镜像
A container is launched by running an image.镜像就是一个可执行的包,这个包中有程序运行的所有条件,代码,依赖的jar包,环境变量,配置文件。 - 容器
容器是一个运行的镜像实例。你可以使用命令docker ps
去查看正在运行的容器。 -
容器和虚拟机的差别
- 较虚拟机而言,Docker将会更加省内存基于上图。因为虚拟机是逻辑上的一台机器,它共享宿主机器的硬件资源。
- 镜像
-
Docker的Cli命令简介
[root~]# docker Usage: docker COMMAND A self-sufficient runtime for containers Options: --config string Location of client config files (default "/root/.docker") -D, --debug Enable debug mode -H, --host list Daemon socket(s) to connect to -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") --tls Use TLS; implied by --tlsverify --tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem") --tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem") --tlskey string Path to TLS key file (default "/root/.docker/key.pem") --tlsverify Use TLS and verify the remote -v, --version Print version information and quit Management Commands: config Manage Docker configs container Manage containers image Manage images network Manage networks node Manage Swarm nodes plugin Manage plugins secret Manage Docker secrets service Manage services swarm Manage Swarm system Manage Docker trust Manage trust on Docker images volume Manage volumes Commands: attach Attach local standard input, output, and error streams to a running container build Build an image from a Dockerfile commit Create a new image from a container's changes cp Copy files/folders between a container and the local filesystem create Create a new container diff Inspect changes to files or directories on a container's filesystem events Get real time events from the server exec Run a command in a running container export Export a container's filesystem as a tar archive history Show the history of an image images List images import Import the contents from a tarball to create a filesystem image info Display system-wide information inspect Return low-level information on Docker objects kill Kill one or more running containers load Load an image from a tar archive or STDIN login Log in to a Docker registry logout Log out from a Docker registry logs Fetch the logs of a container pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container ps List containers pull Pull an image or a repository from a registry push Push an image or a repository to a registry rename Rename a container restart Restart one or more containers rm Remove one or more containers rmi Remove one or more images run Run a command in a new container save Save one or more images to a tar archive (streamed to STDOUT by default) search Search the Docker Hub for images start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers version Show the Docker version information wait Block until one or more containers stop, then print their exit codes Run 'docker COMMAND --help' for more information on a command.
小结
以上是通过运行docker
打印出来的所有有关docker
的命令。如果想了解具体某部分的命令,比如,我现在想了解镜像相关的命令,可以输入docker image
,这样在命令行中就会输出与镜像相关的命令。如果对于某个命令有疑问,可以使用docker image build --help
进行命令的查询,在Linux世界中,对于不会的命令,或第一次遇到的命令,可以找man
,在Docker中就可以找help
了,一切help
。
-
Docker的版本等相关命令
#查看Docker的版本 docker --version Docker version 18.03.1-ce, build 9ee9f40 #查看跟多的信息 docker version Client: Version: 18.03.1-ce API version: 1.37 Go version: go1.9.5 Git commit: 9ee9f40 Built: Thu Apr 26 07:20:16 2018 OS/Arch: linux/amd64 Experimental: false Orchestrator: swarm Server: Engine: Version: 18.03.1-ce API version: 1.37 (minimum version 1.12) Go version: go1.9.5 Git commit: 9ee9f40 Built: Thu Apr 26 07:23:58 2018 OS/Arch: linux/amd64 Experimental: false #查看Docker一些详细信息 docker info Containers: 3 Running: 0 Paused: 0 Stopped: 3 Images: 2 Server Version: 18.03.1-ce Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog Swarm: inactive Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: 773c489c9c1b21a6d78b5c538cd395416ec50f88 runc version: 4fc53a81fb7c994640722ac585fa9ca548971871 init version: 949e6fa Security Options: seccomp Profile: default Kernel Version: 3.10.0-693.2.2.el7.x86_64 Operating System: CentOS Linux 7 (Core) OSType: linux Architecture: x86_64 CPUs: 1 Total Memory: 992.3MiB Name: iz2ze6jeqopgq9yoosls6dz ID:UIVR:2YDB:XRFJ:PUFM:WFJH:NZVN:LCSM:W7AI:BNLA:RBED:T7RJ:I22F Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false #Docker hello world docker run hello-world #列出下载到本机上的所有镜像文件 docker image ls #遇到不会的命令怎么办呢? docker container --help
2. 构建一个镜像并且作为容器运行
方便携带的镜像是由一个叫做
Dockerfile
这个文件定义的。-
创建一个
Dockerfile
文件首先创建一个路径
containers
cd
进入这个路径cd containers
-
创建一个
Dockerfile
文件# Use an official Python runtime as a parent image # 从python:2.7-slim这个镜像基础之上创建的镜像, FROM命令可以多次使用 FROM python:2.7-slim # Set the working directory to /app WORKDIR /app # Copy the current directory contents into the container at /app ADD . /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"]
-
Docker提供一种自动化的方式来创建镜像--
Dockerfile
。Dockerfile
包含了创建镜像所需要的全部命令。Docker支持如下语法命令:# 指令要大写根据命名规约 INSTRUCTION argument
-
有趣的
Dockerfile命令
-
FROM
:基于某个镜像去构建FROM ubuntu //基于ubuntu的镜像来构建。
-
MAINTAINER
:镜像的维护者MAINTAINER mark // 镜像的作者mark
-
RUN
:在Shell或exec环境下执行命令。这个命令会在新创建的镜像上添加新的层面(layer), RUN指令会在shell里使用命令包装器/bin/sh -c
来执行。RUN pip install --trusted-host pypi.python.org -r requirements.txt
-
ADD
:复制文件指令。有两个参数src和destinction。destinction是容器内的路径。src是URL或启动配置上下文的一个文件。ADD . /app
-
CMD
:提供容器默认的执行命令。只允许使用一次。CMD ["python", "app.py"]
-
EXPOSE
:暴露容器在Docker虚拟机内部运行时的监听端口。EXPOSE 8080
-
ENTRYPOINT
:配置给容器一个可执行的命令。这意味着在每次使用镜像创建一个容器时一个特定的应用程序可以被设置成默认程序。同时也意味着该镜像被调用时只能运行指定的程序。类似CMD
,只允许一个ENTRYPOINT
,如果多个出现,以最后一个命令为准。ENTRYPOINT ['executable', 'param1', 'param2']
-
WORKDIR
:指命令RUN
,CMD
和ENTRYPOINT
的工作目录。WORKDIR /app
-
ENV
:设置环境变量,使用key-value
的方式ENV NAME World
-
USER
:镜像运行时设置一个UID.USER mark
-
VOLUME
:授权访问容器内到主机上的目录。VOLUME ['/data']
-
-
在同一路径下创建另外两个文件,
requirements.txt
和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)
-
-
构建应用
docker build -t friendlyhello .
查看本地镜像文件
docker image ls
-
运行自己制作的docker镜像
docker run friendlyhello
/docker run -p 4000:80 friendlyhello
运行结果如图所示
将镜像起个别名,准备上传到Docker Hub上
docker tag friendlyhello gordon/get-started:part2
docker push username/repository:tag
-
本小节常用的命令
docker build -t friendlyhello . # Create image using this directory's Dockerfile docker run -p 4000:80 friendlyhello # Run "friendlyname" mapping port 4000 to 80 docker run -d -p 4000:80 friendlyhello # Same thing, but in detached mode docker container ls # List all running containers docker container ls -a # List all containers, even those not running docker container stop <hash> # Gracefully stop the specified container docker container kill <hash> # Force shutdown of the specified container docker container rm <hash> # Remove specified container from this machine docker container rm $(docker container ls -a -q) # Remove all containers docker image ls -a # List all images on this machine docker image rm <image id> # Remove specified image from this machine docker image rm $(docker image ls -a -q) # Remove all images from this machine docker login # Log in this CLI session using your Docker credentials docker tag <image> username/repository:tag # Tag <image> for upload to registry docker push username/repository:tag # Upload tagged image to registry docker run username/repository:tag # Run image from a registry
3. 扩展您的应用程序以运行多个容器
拆分应用并实现负载均衡,我们必须在分布式应用程序的层次结构中提升一个级别:服务。
在分布式应用中, 会根据不同的业务划分不同的模块,实现不同的功能。拆分服务比较容易,通过写
docker-compose.yml
文件来实现。docker-compose.yml
是一个YAML文件,定义了Docker容器在生产中的表现。-
docker-compose.yml
version: "3" services: web: # replace username/repo:tag with your name and image details image: username/repo:tag deploy: replicas: 5 resources: limits: cpus: "0.1" memory: 50M restart_policy: condition: on-failure ports: - "4000:80" networks: - webnet networks: webnet:
-
这个文件告诉Docker要做下面的事情。
- 在Docker Hub上面拉取镜像
- 运行5个从Docker Hub上面下载下来的镜像实例作为一个web服务。限制每个都要被用到,最多10%的CPU资源和50M的内存资源。
- 如果一个停止或者
fail
掉的话,立即重新启动。 - 通过主机上的
4000
端口和Docker中容器container
进行绑定。 - 通知
web
容器共享端口80
通过负载均衡网络被称为webnet
。 - 用默认的方式定义
webnet
网络(负载均衡的覆盖网络)。
-
运行负载均衡
app
- 第一步首先运行
docker swarm init
- 第二步运行
docker stack deploy -c docker-compose.yml getstartedlab
- 第三步
docker service ls
- 第四步
docker service ps helloworld_web
- 第五步
docker container ls -q
- 第六步
curl http://localhost:4000
- 第一步首先运行
扩展你的应用
通过修改docker-compose.yml
文件中replicas
值来扩展你的应用,然后运行命令docker stack deploy -c docker-compose.yml getstartedlab
4. 在群集中分发您的应用
你部署一个应用到一个集群,在多台机器上运行。多容器,多机器的应用通过加入更多的机器来进行
Dockerized
集群的制作,被称为Swarm
。一个
swarm
是一群运行在Docker
上机器成为一个集群。一个swarm
开始后,你可以运行你熟悉的Docker命令。但他们现在被一个swarm manager
在一个集群上执行。在swarm
中的机器可以是物理机器也可以是虚拟机。加入swarm
后,他们被称为节点。-
swarm manager
运行集群的两种策略:emptiest node
global
swarm manager
是唯一一台可以执行命令,授权其他机器一worker
的角色加入swarm
。worker
仅仅可以提供容量并且没有权限告诉其他机器,他们能做或不能做什么。直到现在,你一直用你的Docker以单主机的模式在本地运行。Docker也可以切换到
swarm mode
模式。-
建立你的
swarm
- 一个
swarm
有多个节点构成。节点可以是物理节点,也可以是虚拟节点。可以使用命令docker swarm init
开启swarm
模式并且是自己的机器成为swarm manager
。然后运行命令docker swarm join
在其他的机器上,使其加入swarm成为worker
。现在我们使用虚拟机创建两台机器的集群,然后创建好的两台机器添加到swarm中。虚拟机可以使用win10的Hyper-v
或者使用VirtualBox来搭建。在使用Docker Toolbox前,一定要保证VirtualBox已经安装了。
- 一个
-
现在用命令
docker-machine
和VirtualBox driver
来创建一对虚拟机。docker-machine create --driver virtualbox myvm1 docker-machine create --driver virtualbox myvm2
列出虚拟机并且得到他们的IP地址,使用命令
docker-machine ls
。