0. docker镜像加速器
# 编辑配置文件 /etc/docker/daemon.json
{
"registry-mirrors": [
"https://97tnx9lz.mirror.aliyuncs.com"(需要自己注册),
"https://docker.mirrors.ustc.edu.cn",
"http://f1361db2.m.daocloud.io",
"https://registry.docker-cn.com",
]
}
1. pull环境
docker pull centos:tag-name
docker pull nginx
- 测试启动
docker run -ti --rm centos:latest bash
docker run -ti --rm -p 81:80 nginx bash
2. yum配置
- EPEL (Extra Packages for Enterprise Linux)
yum -y install epel-release
yum -y insatll vim
yum -y install python36
Part1 Orientation
1. Test Docker version
# 查看当前docker版本号
~ docker --version / -v
# 输出
Docker version 18.09.2, build 6247962
- Run
docker info
(ordocker version
without--
) to view even more details about your Docker installation - docker version:信息较少
~ docker info
Containers: 2
Running: 1
Paused: 0
Stopped: 1
Images: 3
Server Version: 18.09.2
Storage Driver: overlay2
Backing Filesystem: extfs
...
# 查看镜像信息
docker inspect 镜像名
2. Recap and cheat sheet
1. 查看命令
# 查看本机所有镜像
docker image ls
docker images
# 只显示 images 的 id
docker images -q
# List Docker containers (running, all, all in quiet mode)
docker container ls
docker container ls --all
docker container ls -aq
# offical 表示是否是docker的官方镜像
docker search mysql
# 查看容器启动后的logs
options:
-f:实时查看日志
docker logs 容器ID
# 查看容器的资源占用率
docker stats 容器id
# 实时查看日志
docker logs -f 容器id/name
2. 删除
# 删除镜像,只要 run 过就需要先删除 对应的容器,如果tag为none则是其他镜像的依赖
docker rmi 镜像id
# 强制删除image
docker rmi -f 镜像id
# 删除容器
options:
-f:强制删除
docker rm 容器id/别名
docker rm -f 容器id/别名
# 删除所有 stopped 的容器
docker container prune
# 删除所有容器和镜像
docker rm -f `docker ps -qa`
docker rmi -f `docker images -q`
3. 启动
- docker容器进程,如果没有在后台运行的话,就会立即挂掉(容器中必须有正在工作的进程)
# 启动容器
格式:docker run [选项] 镜像 [执行的命令]
-d:表示后台启动,如果启动失败则需要与-it连用
-it: 交互式终端
--name:指定启动后的容器名称
--rm:用于测试使用,退出容器后自动删除
-v:宿主机目录:容器使用的目录,把容器目录挂载到宿主机
-p:宿主机port:容器使用的port,把容器使用的port映射到宿主机的port
-P:宿主机的port是随机的,自动指定端口
docker run -d -P redis
4.备份
- 注意导出的文件是压缩文件, xxx.tar.gz
# 导出镜像
docker save -o redis.tar.gz redis
docker save redis > redis.tar.gz
# 导入镜像
docker load -i redis.tar.gz
docker load < redis.tar.gz
# push镜像
docker commit 容器id # 生成镜像
docker tag 镜像id mycentos # 给镜像加上tag,没有tag则添加,有怎复制一份
docker push repositoryname:tagname
Part2 Containers
1. 进入容器
docker ps -a
# 进入后台启动过的容器
docker exec -it d1fe90d74edc /bin/bash
sudo docker attach 容器ID
- 删除镜像先删除container
# 删除一个image
docker rmi <image id>
# 删除所有image
docker rmi $(docker images -q)
2. 把容器打包成镜像
# 二次修改容器并打包
# 进入纯净的容器
docker run -it centos /bin/bash
# 安装vim
yum install vim -y
# 退出容器
exit
# 提交容器文件
docker commit 容器id centos-vim
3. Dockerfile
- 一般使用 乌班图 (较小)
- 作为基础镜像
3.1 创建dockerfile文件
-
对于复杂的RUN命令,避免无用的分层,多条命令用反斜线换行,合成一条命令
-
ADD存在压缩文件解压的功能,因此,仅仅添加文件到容器内,用COPY而不是ADD
-
添加远程文件/目录使用curl或wget
-
ENV,环境变量,尽可能使用ENV增加可维护性
ENV MYSQL_VERSION 5.6
,设置一个mysql常量RUN yum install -y mysql-server="${MYSQL_VERSION}"
-
参数注释
- 如果复制目录则需要在后面加上目录名称,只复制目录中的文件
# 创建dockerfile文件
vim DockerFile
1. 指定基础镜像
FROM 镜像名
2. 构建执行的命令
RUN yum install -y wget
RUN mkdir /mydata
3. 添加文件到 /mydata,如果是压缩包则自动解压
ADD etc.tar.gz /mydata
4. 本地文件copy到镜像中
COPY test.txt /mydata
5. 切换工作目录,启动后的目(默认根目录),需要使用绝对路径,没有则创建
WORKDIR /mydata
6.ENV设置变量
ENV name=henry
7. VOLUME,指定当前的数据卷
VOLUME ["/data"]
8. EXPOSE,指定 image 的端口,必须声明
EXPOSE 5900
9. LABEL指定标签,容器元信息,帮助信息
LABEL version="1.0"
10. 执行的命令,只执行最后一个CMD
CMD echo $HOME >> home.txt
CMD ['nginx', 'g', 'daemon off;']
- flask示例
- 注意需要修改
/etc/redis.conf
,关闭保护模式,并更换bind 的ip
- 注意需要修改
# Use an official Python runtime as a parent image
FROM python
# 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 -i https://pypi.douban.com/simple -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 build -t myimage -f 文件名 .
# 执行,通过浏览器访问测试
docker run -it -P myimage
3.2 创建app和requirements.txt
1. requirements.txt
Flask
Redis
2. app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="172.16.44.142", port=6379, 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. build app
- Here's what ls should show
$ ls
Dokerfile app.py requirements.txt
- 创建镜像,存储到本机Docker image registry
- -t:指定tag
- .:表示当前Dockerfile文件所在目录
docker build --tag/-t=friendlyhello .
# 查看镜像
$ docker images
- tag默认是
latest
,完整语法
--tag=friendlyhello:v0.0.1
Note for Linux
- Linux 用户proxy server settings
- ENV command 指定host 和 port
# set proxy server, replace host:port with values for your servers
ENV http_proxy host:port
ENV http_proxy host:port
- DNS settings:DNS设置不当
pip
不能正常使用,需要设置DNS server使 pip 正常使用,为Docker daemon设置DNS编辑/etc/docker/daemon.json
{
'dns':['your_dns_address', '8.8.8.8']
}
- 本机的dns不可用时,使用goole的dns,保存后重启docker service
sudo service docker restart
4. Run the app
- 运行app,mapping 主机port 4000 端口和 80 使用
-p
docker run -p 4000:80 friendlyhello
- 使用
http://0.0.0.0:80
查看或curl http://localhost:4000
- 后台运行app
docker run -d -p 4000:80 friendlyhello
5. Log in with your Docker ID
docker login
# 或者
docker login -u 用户名 -p 密码
- 推送image到Docker Hub
# 添加tag标dock
docker tag image username/repository:tag
# For example
docker tag friendlyhello henrywzh/get-started:part2
- Publish the image
docker push henry/repository:tag
- 先在其他终端上登录:再运行app
docker run -p 4000:80 hernywzh/test:friendlyhello
Part3 Services
1. docker-compose.yml
- 定义docker容器的参数
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: henrywzh/test:hello
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- "4000:80"
networks:
- webnet
networks:
webnet:
2. Run new load-balanced app
1. docker stack deploy
命令
- 需要执行如下命令
docker swarm init
2. 为app命名
- A single container running in a service is called a task
- web服务的名称为 app名称_web
docker stack deploy -c docker-compose.yml app名称(如:mytest)
# 获取service ID
docker service ls
# 查看所有服务with stack
docker stack services mytest
# 展示服务的所有task
docker service ps mytest_web
# 展示所有容器的id
docker container ls -q
3. Scale the app
# 修改docker-compose.yml中的replicas=3参数
# 重新部署即可
docker stack deploy -c docker-compose.yml mytest_web
docker stack service ps mytest_web
# 显示如下
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
o8fq9vr1lt04 mytest_web.1 henrywzh/test:hello linuxkit-025000000001 Running Running 11 minutes ago
z5cyi8z0xrje mytest_web.2 henrywzh/test:hello linuxkit-025000000001 Running Running 11 minutes ago
cjsancy3bgpv mytest_web.3 henrywzh/test:hello linuxkit-025000000001 Running Running 11 minutes ago
k1ogibpmrnn2 mytest_web.4 henrywzh/test:hello linuxkit-025000000001 Remove Running 14 seconds ago
sgddt44fe5aw mytest_web.5 henrywzh/test:hello linuxkit-025000000001 Remove Running 14 seconds ago
4. take down the app and the swarm
1. Take the app down
docker stack rm mytest_web
2. Take down the swarm
docker swarm leave --force