第二课 Docker践行DevOps理念 - 镜像和容器基本操作

第二课 Docker践行DevOps理念-镜像和容器基本操作

tags:

  • Docker
  • 慕课网

categories:

  • Docker
  • Devlop实践
  • Docker实验环境
  • Image
  • Container
  • Dockerfile
  • 上传容器
  • 实战服务容器和工具容器

第一节 Docker架构和实验环境

1.1 Docker Platform

  1. Docker提供了一个开发,打包,运行app的平台, 把app和底层infrastructure(可以直接物理,也可以虚拟机)隔离开来。
    在这里插入图片描述
  2. docker engine 使我们docker中核心的东西。它包括
    • 后台进程( dockerd ) ,用来维护后台常用的操作如:image,container容器管理,network网络,volume存储的管理
    • REST API Server
    • CLI接口( docker )
      在这里插入图片描述
  3. 展示版本变成18.01.0-ce。通过ps -ef | grep docker可以看到dockerd的进程。如果没有,sudo systemctl restart docker
  4. 然后执行sudo docker version。本质上是docker客户端。

1.2 Docker架构

在这里插入图片描述

  1. docker底层技术支持
    • Namespaces :做隔离pid, net, ipc, mnt, uts
    • Control groups :做资源限制
    • Union file systems : Container和image的分层

1.3 实验环境

  1. 提供dockerfile文件, shell自动执行脚本setup.sh和centos7的vagrant镜像。
  2. 插件用来共享数据到虚拟机(如果下不了,修改配置):
    • vagrant plugin install vagrant-vbguest
    • vagrant vbguest
  3. 如果安装插件后,启动一直卡在这Loading mirror speeds from cached hostfile。就不要同步文件夹啦,上面vbguest插件有问题。copy文件可以启动后使用vagrant-scp这个插件
  4. 安装: vagrant plugin install vagrant-scp
  5. 查看安装的插件:vagrant plugin list
  6. 加速插件安装:vagrant plugin install vagrant-scp --plugin-clean-sources --plugin-source https://gems.ruby-china.com/
  7. 使用vagrant global-status, 看下路径。
    在这里插入图片描述
  8. 开启vagrant, 直接使用vagrant scp labs ~
  9. 如果卡在 Presto metadata available for base。不要激动。。。不是错误,等待完成即可
# Dockerfile
Vagrant.require_version ">= 1.6.0"

boxes = [
    {
        :name => "docker-host",
        :eth1 => "192.168.205.10",
        :mem => "1024",
        :cpu => "1"
    }
]

Vagrant.configure(2) do |config|

  config.vm.box = "centos/7"
  boxes.each do |opts|
    config.vm.define opts[:name] do |config|
      config.vm.hostname = opts[:name]
      config.vm.provider "vmware_fusion" do |v|
        v.vmx["memsize"] = opts[:mem]
        v.vmx["numvcpus"] = opts[:cpu]
      end
      config.vm.provider "virtualbox" do |v|
        v.customize ["modifyvm", :id, "--memory", opts[:mem]]
        v.customize ["modifyvm", :id, "--cpus", opts[:cpu]]
      end
      config.vm.network :private_network, ip: opts[:eth1]
    end
  end
  # config.vm.synced_folder "./labs", "/home/vagrant/labs"
  config.vm.provision "shell", privileged: true, path: "./setup.sh"
end
# 配置阿里镜像
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://eyzd1v97.mirror.aliyuncs.com"]
}
EOF
# 更新源
sudo yum-config-manager \
  --add-repo \
  https://download.docker.com/linux/centos/docker-ce.repo
sudo yum clean all  
sudo yum makecache fast
sudo yum update
# 安装依赖包和docker
sudo yum install -y yum-utils device-mapper-persistent-data lvm2 git vim gcc glibc-static telnet bridge-utils net-tools
sudo yum install docker-ce-17.12.0.ce -y
sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker

# 添加vagrant到docker组中
sudo gpasswd -a vagrant docker # 把当前用户添加到docker组中
sudo systemctl restart docker.service # 重启docker服务

第二节 Docker Image初识

  1. 登录时vagrant使用docker都需要加上sudo,这样实在太麻烦啦。解决办法如下:
sudo groupadd docker # 默认已经有这个用户租了
sudo gpasswd -a vagrant docker # 把当前用户添加到docker组中
sudo systemctl restart docker # 重启docker服务
exit # 退出vagrant ssh 重新连接即可

2.1 Docker Image概述

  1. 文件和meta data的集合( root filesystem )
  2. 分层的,并且每一层都可以添加改变或删除文件,成为一个新的image
  3. 不同的image可以共享相同的layer
  4. Image本身是read-only的
    在这里插入图片描述

2.2 获取dokcer Image

  1. 查看当前所有的image: sudo docker image ls
  2. 查看当前所有的image简写: docker images
  3. 获取docker Image方式一: Dockerfile
    • docker build -t xiaopeng163/ redis: latest .
    • . 代表从当前目录的dockerfile构建,-t 表示仓库名
FROM ubuntu:14.04 # 选择基础image
LABEL maintainer="Peng Xiao <[email protected]>" # 作者信息
RUN apt-get update && apt-get install -y redis-server # 镜像上运行命令
EXPOSE 6379 # 暴露端口
ENTRYPOINT ["/usr/bin/redis-server"] # 启动入口
  1. 获取docker Image方式二:Pull from Registry(从网上拉取)
    • 例子:sudo docker pull ubuntu:14.04
    • 官方Registry(公开免费): https://hub.docker.com/
    • explore -> 镜像分为官方认证和个人的镜像。

2.3 构建自己的dokcer Image

  1. 通过c语言写一个hello-world程序,安装gcc
  2. docker image 可以看到一些常用命令。如:build pull history push rm ls
  3. docker image ls 简写 docker images
  4. docker image rm IMAGE ID简写 docker rmi IMAGE ID
mkdir hello-world
cd hello-world
vim hello.c
#include<stdio.h>

int main()
{
  printf("hello docker world\n");
}
# 编译成二进制文件
gcc -static hello.c -o hello

# 创建Dockerfile文件
FROM scratch
ADD hello /
CMD ["/hello"]

# 构建自己的镜像 最后的. 表示在当前目录中找Dockerfile
docker build -t qnhyn/hello-world .

# 查看自己构建的镜像
docker image ls
docker history  fce289e99eb9
# 执行镜像
docker run qnhyn/hello-world

第三节 Docker Container初识

3.1 Container简介

  1. Container通过Image创建( copy )
  2. 在Image layer之.上建立一个container layer (可读写)
  3. Image和Contaner的关系。类比面向对象:类和实例
  4. Image负责app的存储和分发, Container负责运行app
    在这里插入图片描述

3.2 Container基本操作

  1. 查看正在运行的Container: docker container ls
  2. 查看所有(正在运行和已经运行的)的Container: docker container ls -a
  3. 查看所有(正在运行和已经运行的)的Container简写方式:docker ps -a
  4. docker container rm + CONTAINER ID 简写 docker rm + CONTAINER ID
  5. docker container可以看到常用命令。
  6. 交互式运行 -i,–interactive
  7. 移除掉所有的container: docker rm $( docker container ls -aq)
  8. **移除掉所有的退出状态的container:**docker rm $(docker container ls -f “status=exited” -q)
# 运行一个container 这种方式运行完就退出啦
docker run centos
# 交互式运行 -i,--interactive
docker run -it centos
# 可以用yum安装软件 touch创建文件
# exit 退出
# 删除container  docker container rm + ContainerID(写全或者写一些都可以找到)
docker container rm b27fe3deb674 
docker container ls -a
docker rm 2be
docker ps -a
# 只查看container的ID
docker container ls -aq
docker container ls -a | awk {'print$1'}
# 移除所有的container
docker rm $( docker container ls -aq)
# 查看退出状态的所有容器
docker container ls -f "status=exited"
# 删除所欲退出状态的容器
docker container rm $(docker container ls -f "status=exited" -q)

3.3 Container构建image

  1. 基于image创建container, 在container里面做一些变化(比如:安装一些软件)。然后在把变化后的Containre重新commit成image.
  2. 上述过程:docker container commit 简写 docker commit
  3. 这种方式构建出的image,自己用没问题。如果是给别人用或者用别人的,可能镜像中可能安装一些不安全的软件,所以不推荐这种方式构建image.
# 交互式创建一个container容器
docker run -it centos
# 在centos中安装vim
yum -y install vim
# 退出container 
exit
# 把修改后的container commit 成image
# 用法:docker commit container名称 (库:版本) 
docker ps -a # 查看container名称
docker commit loving_swanson qnhyn/centos-vim
# 查看构建的image
docker image ls
# 查看共享层 b48是centos原来镜像id, 47是修改后镜像id
docker history b48
docker history 47

3.4 Dockfile构建image

  1. 我们一般推荐这种Dockfile的方式构建image镜像。(只需共享Dockerfile文件,就可以构建和我一样的环境)
  2. docker build -t hynqn/centos-vim-new .
  3. 这里需要说明一下,我们的镜像是只读的如何修改呢。
    • 通过上面构建过程可以看出,它其实在构建过程中生成了一个临时的container
    • 在临时的 container 运行yum安装
    • 然后临时container Commit成一个新的镜像
    • 删除临时container
  4. 过程如下
mkdir docker-centos-vim
cd docker-centos-vim

vim Dockerfile

FROM centos
RUN yum -y install vim

# 构建镜像
docker build -t hynqn/centos-vim-new .

第四节 Dockerfile语法梳理和最佳实践

  1. 官方文档: https://docs.docker.com/engine/reference/builder/

4.1 Dockerfile 常用关键字

  1. 关键字FROM。选择基础镜像(不需要镜像,选择scratch)
    • FROM scratch #制作base image
    • FROM centos #使用base image
    • FROM ubuntu:14.04
  2. 关键字:LABEL 。定义了image的Metadata(基础信息)
    • LABEL maintainer= " [email protected] # 作者
    • LABEL version= “1.0” # 版本
    • LABEL description= “This is description” # 描述
  3. 关键字:RUN 。用于临时容器运行命令,后打包生成到新容器
    • 一条RUN, 都会产生新的一层Image layer
    • 为了美观,复杂的RUN请用反斜线换行!
    • 避免无用分层,合并多条命令成一行
RUN yum update && yum install -y vim \
	python-dev #反斜线换行
RUN apt-get update && apt-get install -y perl \
	pwgen --no-install-recommends && rm -rf \
	/var/lib/apt/lists/* #注意清理cache
RUN /bin/bash -C 'source $HOME/.bashrc; echo $HOME'
  1. 关键字:WORKDIR。 设定当前工作目录 WORKDIR /root
    • 用WORKDIR,**不要用RUN cd **
    • 尽量使用绝对目录
WORKDIR /test #如果没有会自动创建test目录
WORKDIR demo
RUN pwd #输出结果应该是/test/demo
  1. 关键字: ADD and COPY
    • ADD 把本地文件添加到Docker Image中
    • ADD 不光可以拷贝文件到指定目录中,它还可以解压缩
    • 大部分情况, COPY优于ADD
    • ADD除了COPY还有额外功能(解压)
    • 添加远程文件/目录请使用curl或者wget
ADD hello / 
ADD test.tar.gz / #添加到根目录并解压
WORKDIR /root
ADD hello test/ # /root/test/hello
WORKDIR /root
COPY hello test/
  1. 关键字: ENV 通过设置环境变量设置常量
ENV MYSQL VERSION 5.6 # 设置常量
RUN apt-get install -y mysql-server= "${MYSQL_ _VERSION}” \
&& rm -rf /var/lib/apt/lists/* # 引用常量
  1. 关键字:VOLUME 和EXPOSE
    • (存储和网络) 看后面章节具体详讲。
  2. 关键字:CMD 和 ENTRYPOINT
    • 下面一下节细讲

4.2 CMD和ENTRYPOINT

  1. RUN :执行命令并创建新的Image Layer
  2. CMD :设置容器启动后默认执行的命令和参数
    • 容器启动时默认执行的命令
    • 如果docker run指定了其它命令, CMD命令被忽略
    • 如果定义了多个CMD ,只有最后一个会执行
# Dockerfile
FROM centos
ENV name Docker 
CMD echo "hello $name"

# /bin/bash 会把CMD的命令覆盖掉
docker run -it qnhyn/centos-cmd-shell /bin/bash
  1. ENTRYPOINT :设置容器启动时运行的命令(使用最多)
    • 让容器以应用程序或者服务的形式运行
    • 不会被忽略, 一定会执行
    • 最佳实践:写一个shell脚本作为entrypoint
# 写一个shell脚本作为entrypoint
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
  1. shell 格式
# Shell格式
RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"

# Dockerfile1例子 
FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name" #输出hello Docker
  1. EXEC格式
# Exec格式
RUN ["apt-get", "install", "-y", "vim"]
CMD ["/bin/echo", "hello docker"]
ENTRYPOINT ["/bin/echo", "hello docker"]

# Dockerfile2例子  docker build -t qnhyn/centos-entrypoint-exec-new .
FROM centos
ENV name Docker
# ENTRYPOINT ["/bin/echo", "hello $name"] # 输出hello $name
# 指明命令通过bash执行,才可以解析上面变量
ENTRYPOINT ["/bin/bash", "-c", "echo hello $name"]  #输出hello Docker

4.3 Dockerfile镜像的发布

  1. Docker官方仓库注册账号密码:https://hub.docker.com/
  2. 方式一:我们提交仓库的时候: 账号/image名字 — 直接提交镜像(不推荐,因为不安全呀)
# 登录docker仓库
docker login # 输入账号密码 返回success 表示登录成功
# docker image push 简写 docker push
docker push qnhyn/hello-world:latest
  1. 方式二:我们提交我们的Dockerfile文件,到Github或者是Bitbuacket。然后让Docker仓库网站帮我们构建镜像。(推荐这种方式,安全)

    • 绑定你Github账号到docker官网上
    • 我们只需要维护Dockerfile就可以啦
  2. 如果是公司使用,不想让自己的镜像公开。Docker官方也给我们提供了,建立私有Registery的镜像。用来搭建自己的仓库服务器

# 创建另一台网络可达的虚拟机
# 启动私有的Registry
docker run -d -p 5000: 5000 --restart always --name registry registry:2 

# 测试可达
telnet 服务器IP(10.75.44.222) 5000
docker build -t 服务器IP(10.75.44.222):5000/hello-world

# 配置可信信息
sudo ls /etc/docker
sudo more /etc/docker/daemon.json
vim /etc/docker/daemon.json
# 写入可信信息
{"insecure-registries":["10.75.44.222:5000"]}
sudo vim /lib/systemd/system/docker.service
# 加入一行
EnvironmentFile=-/etc/docker/daemon.json
sudo service docker restart

# 提交到服务器
docker push 服务器IP(10.75.44.222):5000/hello-world

# Registry服务器 验证提交是否成功 官方文档:https://docs.docker.com/registry/spec/api/
# 浏览器输入: 可以看到json数据
服务器IP 10.75.44.222:5000/v2/_catalog

第五节 Dockerfile实战

5.1 通过docker创建flask服务

  1. 创建app.py
  2. 安装pip:
    • sudo yum -y install epel-release
    • sudo yum -y install python-pip
    • sudo pip install flask -i https://pypi.douban.com/simple
from flask import Flask


app = Flask(__name__)

@app.route('/')
def hello():
    return "hello docker"


if __name__=='__main__' :
    app.run()
  1. 宿主机访问虚拟机的WEB服务。需要修改虚拟机网络为 public network, bridge(桥接模式),查看虚拟机的IP并访问(通过virtualbox登录查看),虚拟机的IP与宿主机的IP为同一网段。
  2. 也可以使用:curl http://172.0.0.1:5000 来访问服务
  3. 写Dockerfile。构建自己的镜像 docker build -t qnhyn/flask-hello-world .
    • 如果构建失败, 我们可以交互式进入到生成的临时容器中进行调试。
    • docker run -it 4320f8b526bc bin/bash
FROM python:2.7
LABEL maintainer="qnhyb<[email protected]>"
RUN pip install flask
COPY app.py /app/
WORKDIR /app
EXPOSE 5000
CMD ["python", "app.py"]
  1. 创建镜像,运行容器(后台运行 -d)
    • docker run -d qnhyn/flask-hello-world
    • 进入到容器中。docker exec -it 11a767d3a588 /bin/ bash
ps -ef | grep python
# 进入python交互界面
docker exec -it 11a767d3a588 python
docker exec -it 11a767d3a588 ip a
# 停止运行中的容器
docker container stop 11a767d3a588
docker stop 11a767d3a588
# 清理退出的所有容器
docker rm $(docker ps -aq)

# 给容器起一个名字并启动
docker run -d --name=demo  qnhyn/flask-hello-world 
docker stop demo

# 显示容器的详细信息
docker inspect 11a767d3a588

# 显示容器运行日志
docker logs 11a767d3a588

5.2 通过docker构建linux工具stress

  1. 工具stress 的使用
docker run -it ubuntu
#安装stress。
apt-get update && apt-get install -y  stress 
which stress 
stress --help
# --vm 创建几个worker(进程) verbose debug输出
stress --vm 1 --verbose # 创建一个进程,分配250M,在释放。一直循环
stress --vm 1 --vm-bytes 500000M --verbose # 最大不能超过宿主机的内存
  1. 写Dockerfile
FROM ubuntu
RUN apt-get update && apt-get install -y stress
ENTRYPOINT ["/usr/bin/stress"]
CMD [] # 用来接收docker run 后面的参数
  1. 构建镜像,运行容器
# 构建
docker build -t qnhyn/ubuntu-stress .
# 直接运行不加参数
docker run -it qnhyn/ubuntu-stress 
# 加参数运行
docker run -it qnhyn/ubuntu-stress --vm 1 --verbose
  1. 限制容器使用资源
# 限制内存
# 设置容器内存为200M 加上swap内存(不设置和memory一样) 共400M
docker run --memory=200M qnhyn/ubuntu-stress --vm 1 --verbose
# 500>400 报错内存不够
docker run --memory=200M xi qnhyn/ubuntu-stress --Vm 1 --verbose --Vm-bytes 500M

# 限制CPU --cpu-shares相对权重
# 假如连个容器,一个设置为10,一个设置为5。那么第一个容器就占用虚拟机内存的2/3
docker run --cpu-shares=10 --name=test1 qnhyn/ubuntu-stress --cpu 1
docker run --cpu-shares=5 --name=test2 qnhyn/ubuntu-stress --cpu 1

# top 查看资源占用
top
  1. 资源的限制源于底层的技术支持
    • Namespaces :做隔离pid, net, ipc, mnt, uts
    • Control groups :做资源限制
    • Union file systems : Container和image的分层
发布了61 篇原创文章 · 获赞 8 · 访问量 2801

猜你喜欢

转载自blog.csdn.net/aa18855953229/article/details/105177778