docker入门
一、镜像(images)
镜像是轻量的,独立的,可执行包,并且包含了软件运行需要的所有东西,包括代码、运行环境、库、环境变量,配置文件等
二、容器(container)
容器是镜像的一个运行实例——也就是镜像被加载到内存,并且真的被执行之后。默认情况下,容器和主机是完全隔离的,最多也会在配置了的情况下,使用主机的hosts文件和端口
容器使用的基本步骤
1、使用Dockerfile来定义一个容器
对于一些资源的访问,比如网卡、磁盘,在容器里都是虚拟化的,和主机是隔离的,因此,必须把容器内的资源和主机的资源做一个映射;还需要指定你想要把哪些文件copy到容器中(代码)
创建Dockerfile文件,并输入一下代码
# 使用python官方镜像作为镜像的基础 FROM python:2.7-slim # 设置工作空间为/app WORKDIR /app # 把当前目录下的文件拷贝到 容器/app里 ADD . /app # 安装requirements.txt中指定的依赖 RUN pip install -r requirements.txt # 开放80端口 EXPOSE 80 # 设置NAME环境变量 ENV NAME World # 当容器启动时,运行app.py CMD ["python","app.py"]
2、创建应用app
requirements.txt
Flask
Redis
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__) route("/") .def hello(): try: visits = redis.incr("counter") except RedisError: visits = "<h1>can not connect to Redis</h1>" 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、构建应用
不需要安装python,也不需要安装requirements.txt中的任何依赖包
执行构建命令,创建一个自己的dockerfile镜像
#将当前文件的所有文件构建成friendhello的镜像文件 docker build -t friendhello .
4、运行自定义应用
运行时需要映射端口号
#使用-p参数将容器内80端口映射到主机的5000端口 docker run -p 5000:80 friendhello #后台运行docker应用 docker run -d -p 5000:80 friendhello
5、结束应用进程
#查询容器ID docker ps #关闭docker docker stop id
6、登录docker
docker login #根据要求填写用户名和密码
7、给镜像打标签
docker tag friendhello smiletosunshine/test:hello docker images # 打标签语法格式: docker tag 镜像image名 用户名/仓库名:标签
注意:
如果给镜像打标签的时候,没有加 :tag,那么默认镜像的标签为 :latest
8、将镜像推送至远程终端
docker push smiletosunshine/test:hello # 语法格式 docker push 用户吗/仓库名:标签
9、执行远程应用
docker run -d -p 5000:80 smiletosunshine/test:hello # 语法格式 docker run -d -p 映射端口:应用端口 用户名/仓库名:标签
10、拉取远程镜像
docker pull smiletosunshine/test:hello
注意:
如果run的时候,没有找到image,会自动从官网pull
11、删除镜像
#删除镜像 docker rmi -f 镜像id #强制删除运行中容器 docker rm -f 容器id
三、服务(services)
服务就是一个应用中的容器。“一个服务只运行一个镜像,但是,他会编排镜像的运行方式——使用哪个端口,需要多少个实例才能满足需求”
伸缩一个服务就是改变这个服务的运行容器数量
1、使用docker-compose.yml文件控制docker容器的行为
# 只有version>=3.x才能使用docker stack deploy命令 version: "3" services: web: # 拉取镜像 image: smiletosunshine/test:part1 deploy: # 运行5个实例 replicas: 5 resources: # 限制CPU使用率 limits: cpus: "0.1" memory: 50M # 自动重启容器 restart_policy: condition: on-failure # 端口映射 ports: - "80:80" # 设置负载均衡网络 networks: - webnet networks: webnet: # 注意:缩进不能错
上述的docker-compose.yml定义了docker的行为:
1、从注册中心拉取镜像
2、运行5个实例作为服务web,并且限制每个实例都CPU使用率最多只能到10%,内存最多占用50M
3、容器启动失败则重启
4、把主机的80端口映射到web服务器的8000端口
5、指示web服务器的所有容器通过一个负载均衡的网络webnet来共享80端口
6、把webnet网络作为默认网络设置
2、运行负载均衡
docker swarm init docker stack deploy -c docker-compose.yml getstartedlab #语法格式 docker stack deploy -c yml文件 自定的应用名
注意:
在运行docker stack deploy之前,需要使用docker swarm init初始化,否则会报“this node is not a swarm manager”
3、伸缩应用
修改docker-compose.yml中的replicas数量,保存后,运行
docker stack deploy -c docker-compose.yml getstartedlab
注意:
docker是自动更新的,不需要手动kill
4、移除应用
#移除应用 docker stack rm getstartedlab #关闭swarm docker swarm leave --force
四、集群(swarm)
swarm就是一个运行docker的集群。可以使用docker来对swarm manager下命令,从而控制这个集群,集群中的机器可以是真实的物理机,也可以是虚拟机。
swarm manager策略:
在compose文件中指定swarm manager策略:
最空节点:选择使用率最低的节点来运行容器
全局策略:每个节点至少有一个镜像的容器
1、配置swarm
执行docker swarm init来开启一个swarm节点,并且把当前执行命令的节点作为管理节点,然后在其他机器上执行docker swarm join来加入这个swarm集群
2、使用虚拟机来完成swarm集群的配置
# 创建两个虚拟机,分别为myvm1和myvm2 docker-machine create --driver virtualbox myvm1 docker-machine create --driver virtualbox myvm2
3、设置管理节点和工作节点
# 把myvm1设为管理节点 docker-machine ssh myvm1 "docker swarm init"
注意:
执行失败,提示要加—advertise-addr
使用docker-machine ls查看虚拟机,然后拷贝myvm1的ip,指定端口2377
例如:
docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100:2377"
初始化成功之后会返回一个提示信息,拷贝命令,然后去myvm2中执行
docker-machine ssh myvm2 "docker swarm join \--token <token> \<ip>:<port>"
注意:
配置工作节点时的 \ 不能丢,必须加上,否则报错,且\前加空格,\后不可加空格
4、查看集群中的所有节点
# 登录管理节点之中,只有管理节点才可以执行docker命令 docker-machine ssh myvm1 docker node ls
5、退出,回到原机器
exit
6、部署应用
# 使用scp上传yml文件至管理节点 docker-machine scp docker-compose.yml myvm1:~ # 部署应用 docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"
7、查看部署后的应用容器
docker-machine ssh myvm1 "docker stack ps getstartedlab"
8、访问集群
# 查询ip docker-machine ls
通过myvm1和myvm2中的任意一个ip均可访问,因为整个集群内的网络是共享的
9、伸缩应用
# 修改docker-compose.yml文件 # 执行docker stack deploy
10、清除应用
# 清除应用 docker-machine ssh myvm1 "docker stack rm getstartedlab" # 让工作节点脱离swarm集群 docker-machine ssh myvm2 "docker swarm leave" # 关闭管理节点 docker-machine ssh myvm1 "docker swarm leave --force"
五、堆栈(stack)
1、在docker-compose.yml中添加可视化服务
version: "3" services: web: # replace username/repo:tag with your name and image details image: username/repo:tag deploy: replicas: 5 restart_policy: condition: on-failure resources: limits: cpus: "0.1" memory: 50M ports: - "80:80" networks: - webnet visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: [node.role == manager] networks: - webnet networks: webnet:
说明:
添加一个与web服务平级的服务visualizer。volumes,为可视化服务添加访问主机socket文件的权限;placement,确保服务只运行在swarm的管理节点上。
2、编辑docker-compose.yml,添加数据持久化服务
version: "3" services: web: # replace username/repo:tag with your name and image details image: username/repo:tag deploy: replicas: 5 restart_policy: condition: on-failure resources: limits: cpus: "0.1" memory: 50M ports: - "80:80" networks: - webnet visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: [node.role == manager] networks: - webnet redis: image: redis ports: - "6379:6379" volumes: - ./data:/data deploy: placement: constraints: [node.role == manager] networks: - webnet networks: webnet:
说明:
要保证redis只会运行在管理节点上,这样就可以让redis运行在同一个文件系统上
redis访问的文件路径时一样的,这样就可以从这个路径来读取和存储文件
3、在管理节点上创建redis的数据持久化路径
docker-machine ssh myvm1 "mkdir ./data"
3、上传新的docker-compose.yml文件
docker-machine scp docker-compose.yml myvm1:~
4、部署应用
docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"
5、查询结果
docker-machine ps
浏览器输入ip