Docker Dockerfile docker-compose

Docker

底层技术支持

  • Namespaces:做隔离pid,net,ipc,mnt,uts(这是都是linux底层)
  • Control groups:做资源限制
  • Union file systems:Container和image的分层

docker学习网站

https://yeasy.gitbooks.io/docker_practice/install/mirror.html

docker安装

# 检查内核版本,必须是3.10及以上
uname -r
# 安装docker
yum install docker* -y
# 查看docker软件是否安装
rpm -qa | grep docker
# 启动docker
systemctl start docker
# 开机启动
systemctl enable docker

docker命令

docker基本命令
# 搜索镜像
docker search tomcat
# 拉取镜像
docker pull tomcat
docker pull 镜像名:tag

# 加速registry.docker-cn.com/library/,后面跟上相对应的版本,去docker仓库里查看
docker pull registry.docker-cn.com/library/rabbitmq:3.7-management

3、根据镜像启动容器,mytomcat自己取名字 -d:后台运行,image-name:指定镜像模板
docker run --name mytomcat -d tomcat:latest
4、docker ps  
查看运行中的容器

5、 停止运行中的容器
docker stop  容器的id

6、查看所有的容器
docker ps -a

7、启动容器
docker start 容器id

8、删除一个容器
docker rm 容器id
docker rm -f 容器id  # 可以删除正在运行的容器
 
9、启动一个做了端口映射的tomcat
docker run -d -p 8888:8080 tomcat
-d:后台运行
-p: 将主机的端口映射到容器的一个端口    主机端口:容器内部的端口
-it:交互式运行

# 删除镜像
docker rmi image/id
docker命令
-i interactive 交互
-t tty 终端
-d daemon 后台运行
# 交互式运行
docker run -it centos  

# 显示所有的容器
docer ps -aq
docker container ls -aq 
docker container ls -a | awk {'print$1'}

# 删掉所有容器
docker rm $( docker container ls -aq )
docker rm -f flask  # 强制删除正在运行的容器

# 把状态为exited的容器查询出来
docker container ls -f "status=exited"
docker ps -f "status=exited" | awk {'print$1'}
# 删除状态为exited的容器,没有启动的容器
docker rm $( docker ps -f "status=exited" | awk {'print$1'} )

# 查看容器的ip
docker exec -it 容器id ip a
docker inspect 容器id | grep -i ipaddress

# 把主机的文件拷贝到容器
docker cp /Users/liheng/Desktop/iqiyi.zip 7ed9c6fbf986:/ 
进入运行环境
# 不用进入bash环境执行命令
docker exec 容器id 命令

# 进入bash环境
docker exec -it 容器id /bin/bash  # 执行命令,进入交互式环境

# 进入python环境
docker exec -it 容器id python

# 查看该容器的ip
docker exec -it 容器id ip a

# 查看容器的详细信息
docker inspect 容器id

# 查看容器的log
docker logs 容器id
docker 保存和加载
# 保存
docker save -o fedora-latest.tar fedora:latest
docer save 容器id > xxx.tar
# 加载
docker load < busybox.tar.gz
docker load --input fedora.tar
docker load -i fedora.tar

# 给镜像添加名称和标签
docker tag id号 zbyft/centos-vim:latest

# commit,生成镜像
docker commit id zbyft/centos-vim
docker 知识点
一台宿主机上的docker容器是相互通信

# 启动centos容器,--privileged:以超级权限启动,
docker run --privileged -itd -p 80:80 -p 6022:22 --name centos6 centos6

创建简单镜像

# 使用commit
# 拷贝镜像lucid_stonebraker,是容器停止后的names,docker ps -a
docker commit lucid_stonebraker zby/centos-vim

# 使用Dockerfile来创建(推荐)
# 在/tmp/docker_builder/下创建Dockerfile
# Dockerfile
FROM centos:latest  # 依赖的镜像,初始镜像
RUN yum install -y vim

# 执行命令
docker build -t zby/centos-vim /tmp/docker_builder/

# 生成自己的镜像
# Dockerfile
FROM python:3.7
CMD ["python","/data/www/hello.py"]
    
# 生成镜像,my-python-app生成的镜像名,指定Dockerfile的目录/tmp/docker_builder/
docker build -t my-python-app /tmp/docker_builder/

Dockerfile语法

FROM

FROM scratch  # 只做base image,不依赖任何镜像
FROM centos  # 使用base image
FROM ubuntu:14.04

LABLE 标签

LABEL maintainer="zby@qq.com"
LABEL version="1.0"
LABEL description="This is description"

RUN

RUN yum update && yum install -y vim \
	python-dev  # 反斜线换行

# 为了美观,复杂的RUN请用反斜线换行,避免无用分层,合并多条命令成一行

WORKDIR

# 类似如cd操作
WORKDIR /test  # 如果没有会自动创建test目录
WORKDIR demo
RUN pwd  # 输出结果应该是 /test/demo

# 用WORKDIR,不要用RUN cd,尽量使用绝对目录

ADD and COPY

ADD hello /
ADD test.tar.gz /  # 添加到根目录并解压

WORKDIR /root
ADD hello test/  # /root/test/hello

WORKDIR /root
COPY hello test/

# 大部分情况,COPY优于ADD!
# ADD处理COPY还有额外功能(解压)
# 添加远程文件/目录请使用curl或者wget
RUN wget ...

ENV

# 定义变量
ENV MYSQL_VERSION 5.6  # 设置常量
RUN apt-get install -y mysql-server= "${MYSQL_VERSION}" \
&& rm -rf /var/lib/apt/lists/*  # 引用常量

# 尽量使用ENV增加可维护性

VOLUME and EXPOSE

# 存储和网络
EXPOSE 5000  # 暴露端口

CMD and ENTRYPOINT

RUN:执行命令并创建新的Image Layer
CMD:设置容器启动后默认执行的命令和参数
ENTRYPOINT:设置容器启动时运行的命令

# Shell格式
RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"

# Exec格式
RUN ["apt-get", "install", "-y", "vim"]
CMD ["echo","hello docker"]
ENTRYPOINT ["echo","hello docker"]

# Dockerfile1
FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"

# Dockerfile2
FROM centos
ENV name Docker
# ENTRYPOINT ["echo","hello $name"]  # 此时打印不出来hello Docker
ENTRYPOINT ["bash", "-c", "echo hello $name"]

# CMD
容器启动时默认执行的命令
如果docker run指定了其它命令,CMD命令被忽略
如果定义了多个CMD,只有最后一个会执行

# ENTRYPOINT
让容器以应用程序或者服务的形式运行
不会被忽略,一定会执行
最佳时间:写一个shell脚本作为entrypoint
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 27017
CMD ["mongod"]

镜像的发布

镜像发布

# 登录
docker login
# push镜像,注意命令规范,前面必须是自己的docker ID
docker push zbyft/hello-world:latest

创建私有docker hub

# 在一台服务器上启动私有仓库,ip为192.168.220.130
docker run -d -p 5000:5000 --restart always --name registry registry:2

# 在另一台服务器,192.168.43.7
  # 创建镜像,命令规范
  docker build -t 192.168.220.130:5000/hello-docker:latest .
  # 在/etc/docker/daemon.json下添加以下内容
  {
    "insecure-registries":["192.168.220.130:5000"]
  }
  
  # 在修改docker的启动文件,/lib/systemd/system/docker.service
  vim /lib/systemd/system/docker.service
  # 添加
  EnvironmentFile=/etc/docker/daemon.json

  # 重启docker
  sudo systemctl daemon-reload
  sudo systemctl restart docker
  
  # 此时就可以push了
  docker push 192.168.220.130:5000/hello-docker:latest
  
  # 注意
  ping一下这祥两台服务器是否ping的通

部署flask应用

app.py

from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
    return "hello docker"

if __name__== "__main__":
    app.run(host="0.0.0.0")

Dockerfile

FROM python:3.7
LABEL maintainer="zby@qq.com"
RUN pip install flask
COPY ./app.py /app/
WORKDIR /app/
EXPOSE 5000  # 暴露端口
CMD ["python","app.py"]

调试Dockerfile

# 进入Dockerfile里的容器里
docker run -it 容器id /bin/bash  # 交互式

使用stress工具

Dockerfile

FROM ubuntu
RUN apt-get update && apt-get install -y stress
ENTRYPOINT ["/usr/bin/stress"]
CMD []  # []作用是用接收参数

# 制作镜像
docker build -t zbyft/ubuntu-stress .

执行stress镜像

docker run -it 40f52d6db972 --vm 1 --verbose

部署带redis的项目

构建flask-redis项目

# 先启动redis的镜像
docker run -d --name redis redis

# Dockerfile
FROM python:3.7
LABEL maintainer="zby@qq.com"
RUN pip install flask redis
COPY ./app.py /app/
WORKDIR /app/
EXPOSE 5000
CMD ["python", "app.py"]

# 构建镜像
docker build -t zbyft/flask-redis .

# -e 给该容器设置环境变量
# 启动,--link,镜像redis的名字,表示可以通过名字就可以连接redis镜像,设置环境变量REDIS_HOST=redis
docker run -d --name flask-redis -p 5000:5000 --link redis -e REDIS_HOST=redis zbyft/flask-redis

app.py

# -*- coding: utf-8 -*-
from flask import Flask
import redis
import os

app = Flask(__name__)

redis_conn = redis.Redis(host=os.environ.get("REDIS_HOST", "127.0.0.1"), port=6379)


@app.route("/")
def index():
    redis_conn.incr("num")
    return "hello redis: %s" % redis_conn.get("num")


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000, debug=True)

数据持久化

Data Volume

# 查看数据volume
docker volume ls
# 删除数据卷
docker volume rm 名字

# 在Dockerfile里添加,数据存储的路径,表示容器存储的数据在容器该路径下
VOLUME ["/var/lib/mysql"]

# 在启动容器时添加参数,volume的名字:容器的位置,数据库的密码为my-secret-pw
docker run --name mysql1 -v mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7
# 进入该容器
docker exec -it mysql1 /bin/sh
mysql -uroot -pmy-secret-pw
# 创建数据库docker
create databases docker;
# 停止容器

# 在启动一个新的容器,用该volume(mysql)
docker run --name mysql2 -v mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7
# 该数据库里有原来的数据,即有数据库docker

Bind Mouting

# 本机的数据位置:容器里的数据位置
docker run -v /home/aaa:/root/aaa

# 启动,当前的目录和容器的目录/usr/share/nginx/html,共享
docker run -d -p 80:80 --name nginx -v $(pwd):/usr/share/nginx/html zbyft/nginx-index

network

  • docker network create -d bridge my-bridge

安装wordpress

启动mysql容器

docker search mysql
# 下载5.7版本的mysql
docker pull docker.io/centos/mysql-57-centos7

docker run -d --name mysql -v /data/mysql:/usr/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw docker.io/centos/mysql-57-centos7

# 进入mysql容器中
docker exec -it mysql /bin/sh
mysql -uroot -p  # 不需要输入密码,直接回车进入
create database wordpress charset=utf8;

启动wordpress

# 下载wordpress
docker pull wordpress

docker run -d --name wordpress -e WORDPRESS_DB_HOST=mysql:3306 --link mysql -p 8080:80 wordpress

# 直接访问
ip:8080

docker compose

docker-compose.yml

# 三大概念
Services Networks Volumes

Services

  • 一个service代表一个container,这个container可以从dockerhub的image来创建,或者从本地的Dockerfile build出来的image来创建
  • Service的启动类似docker run,我们可以给其指定network和volume,所以可以给service指定network和Volume的引用

例如:

services:
  db:
    image: postgres:9.4
    volumes:
      - "db-data:/var/lib/postgresql/data"
    networks:
      - back-tier
# 就相当于
docker run -d --network back-tier -v db-data:/var/lib/postgresql/data postgres:9.4

完整的实例:

version: '3'

# docker run
services:
  # service的改名字,也可以理解成该容器的名字 --name,最后生成的名字确不是这个名字,但一样可以使用改名字,在docker-compose
  wordpress:
    image: wordpress
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_PASSWORD: root
    networks:
      - my-bridge
      
  # 可以理解成名字  --name
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - my-bridge

# docker volume create mysql-data
volumes:
  mysql-data:

# docker network create -d bridge my-bridge
networks:
  my-bridge:
    driver: bridge

安装

sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$( uname -s )-$( uname -m )" -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

# 如果下载不下来,就使用pip来装
https://blog.csdn.net/jojoy_tester/article/details/79182216

使用

docker-compose up  # 会自动从当前的路径找docker-compose.yml文件
docker-compose -f docker-compose.yml up  # 指定要启动的yml文件

# 后台启动
docker-compose up -d

# 停止
docker-compose stop

# 开始
docker-compose start

# 删除并重启
docker-compose down

# 进入到容器里exec
docker-compose exec mysql bash  # 进入到mysql的容器里

flask和redis的使用

Dockerfile

FROM python:3.7
LABEL maintainer="zby@qq.com"
RUN pip install flask redis
COPY ./app.py /app/
WORKDIR /app/
EXPOSE 5000
CMD ["python", "app.py"]

app.py

# -*- coding: utf-8 -*-
from flask import Flask
import redis
import os

app = Flask(__name__)

redis_conn = redis.Redis(host=os.environ.get("REDIS_HOST", "127.0.0.1"), port=6379)


@app.route("/")
def index():
    redis_conn.incr("num")
    return "hello redis: %s" % redis_conn.get("num")


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000, debug=True)

docker-compose.yml

version: "3"

services:
  redis:
    image: redis
  web:
    build:
      context: .  # 指定Dockerfile的位置
      dockerfile: Dockerfile  # 指定文件名
    ports:
      - 8080:5000
    environment:
      REDIS_HOST: redis

水平扩展和负载均衡

  • 启动多个web应用服务

docker-compose.yml

version: "3"

services:
  redis:
    image: redis
  web:
    build:
      context: .  # 指定Dockerfile的位置
      dockerfile: Dockerfile  # 指定文件名
    environment:
      REDIS_HOST: redis
  lb:  # 相当于是中间人,首先都访问它,然后由它分发到各个web服务上面
    image: dockercloud/haproxy
    links:
      - web
    ports:
      - 8080:80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

启动服务

docker-compose up -d

# 开启多个web服务,外界访问的话,会轮询各个服务器达到负载均衡
docker-compose up --scale web=3 -d  # scale:规模

# 访问
http://192.168.43.7:8080/

app.py

# 修改一点
if __name__ == '__main__':
    app.run(host="0.0.0.0", port=80, debug=True)

制作centos镜像

https://blog.csdn.net/liudian_cz/article/details/88850773

# 启动制作的镜像
docker run --privileged -d -it --name centos centos /usr/sbin/init

docker run --privileged -d -it -p 7000:6379 -p 4000:3306 --name centos 1316abe84234 /usr/sbin/init
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值