Docker基础篇

Docker基础篇

01 初识Docker

1.1 什么是Docker

1.1.1 官网首页

https://www.docker.com/

Modernize your applications, accelerate innovation
Securely build, share and run modern applications anywhere

1.1.2文档

https://docs.docker.com/get-started/

Docker is a platform for developers and sysadmins to develop, deploy, and
run applications with containers. The use of Linux containers to deploy
applications is called containerization. Containers are not new, but their
use for easily deploying applications is.

1.1.3 如何理解容器化

  • 远古时代

1572919863902.png

问题:成本高、部署慢、浪费资源、硬件限制、不利于迁移扩展

  • 虚拟化时代

1572919903763.png

优点 :相对利用好资源,相对容易扩展等

缺点 :虚拟机太重了,一上来占用较多物理资源,移植性差,资源利用率低等。

  • 容器时代

1572919942093.png

1.1.4 Docker应用场景

www.docker.com --->Solutions

(1)有助于Microservices的落地和部署
(2)充分利用物理机资源,同时能够整合服务器资源
(3)提高开发效率,测试效率,部署效率,有利于DevOps的落地,CICD
(4)云原生落地,应用更好地迁移
...

1.2 What is Image and Container?

1.2.1 What is Image?

Why is docker?->What is a container

A Docker container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code,runtime, system tools, system libraries and settings

1.2.2 What is Container?

Why is docker?->What is a container

A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another.

1.2.3 Relation between image and container

Container images become containers at runtime and in the case of Docker
containers- images become containers when they run on Docker Engine.

1.2.4 View from Docs

A container is launched by running an image. An image is an executable packagethat includes everything needed to run an application--the code, a runtime,libraries, environment variables, and configuration files.

A container is a runtime instance of an image--what the image becomes in memory when executed (that is, an image with state, or a user process). You can see a list of your running containers with the command, docker ps, just as you would in Linux.

1.3 容器和虚拟机

A container runs natively on Linux and shares the kernel of the host machinewith other containers. It runs a discrete process, taking no more memory thanany other executable, making it lightweight.

By contrast, a virtual machine (VM) runs a full-blown “guest” operating systemwith virtual access to host resources through a hypervisor. In general, VMs provide an environment with more resources than most applications need.

1572920129146

1.4 Docker引擎与架构

1.4.1 Docker Engine

Docker Engine is a client-server application with these major components:

  • A server which is a type of long-running program called a daemon process (the dockerd command).
  • A REST API which specifies interfaces that programs can use to talk to the daemon andinstruct it what to do.
  • A command line interface (CLI) client (the docker command).

1572920367957

1.4.2 Docker Architecture

Docker uses a client-server architecture. The Docker client talks to the Dockerdaemon, which does the heavy lifting of building, running, and distributing your Docker containers. The Docker client and daemon can run on the same system, or you can connect a Docker client to a remote Docker daemon. The Docker client and daemon communicate using a REST API, over UNIX sockets or a network interface.

1572920417931.png

1.5 安装和体验

1572920497164.png

1.5.1 在Windows上准备centos7

mac https://www.jianshu.com/p/f4936e306c19

Windows https://blog.csdn.net/babyxue/article/details/80970526

1.5.2 安装docker

https://docs.docker.com/install/linux/docker-ce/centos/

1.5.2.1 卸载之前的docker

sudo yum remove docker \
        docker-client \
        docker-client-latest \
        docker-common \
        docker-latest \
        docker-latest-logrotate \
        docker-logrotate \
        docker-engine

1.5.2.2 安装必要的依赖

sudo yum install -y yum-utils \
 device-mapper-persistent-data \
 lvm2

1.5.2.2 设置docker仓库

sudo yum-config-manager \
  --add-repo \
  https://download.docker.com/linux/centos/docker-ce.repo

设置阿里云镜像加速 https://cr.console.aliyun.com/cn-hangzhou/instances/repositories

1572920914221.png

1.5.2.2 安装docker

sudo yum install -y docker-ce docker-ce-cli containerd.io

1.5.2.2 启动docker

sudo systemctl start docker
#设置开机启动docker
sudo systemctl enable docker

1.5.3 docker基本体验

1.5.3.1 创建tomcat容器

docker pull tomcat
docker run -d --name my-tomcat -p 9090:8080 tomcat

1.5.3.2 创建mysql容器

docker pull mysql
docker run -d --name my-mysql -p 3301:3306 -e MYSQL_ROOT_PASSWORD=sunda123 --
privileged mysql

1.5.3.3 进入到容器里面

docker exec -it containerid /bin/bash

1.5.4 可能有的疑惑

(1)docker pull在哪拉取的镜像?
默认是在hub.docker.com
(2)docker pull tomcat拉取的版本是?
默认是最新的版本,可以在后面指定版本":"
(3)简单先说一下命令咯

docker pull    拉取镜像到本地
docker run     根据某个镜像创建容器
-d         让容器在后台运行,其实就是一个进程
--name       给容器指定一个名字
-p         将容器的端口映射到宿主机的端口
docker exec -it  进入到某个容器中并交互式运行

更为详细的命令

https://www.runoob.com/docker/docker-command-manual.html

02 Image and Container

2.1 深入探讨Image

1572921265539.png

说白了,image就是由一层一层的layer组成的。

2.1.1 官方image

https://github.com/docker-library

mysql

https://github.com/docker-library/tomcat/blob/master/8.5/jdk8/openjdk/Dockerfile

2.1.2 Dockerfile

2.1.2.1什么是dockerfile?

Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。Docker通过读取Dockerfile中的指令自动生成映像。

docker build命令用于从Dockerfile构建映像。可以在docker build命令中使用-f标志指向文件系统中任何位置的Dockerfile。
例:

docker build -f /path/to/a/Dockerfile
2.1.2.2 Dockerfile的基本结构

Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。

2.1.2.3 Dockerfile文件说明

Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以#字符开头则被视为注释。可以在Docker文件中使用RUN,CMD,FROM,EXPOSE,ENV等指令。

在这里列出了一些常用的指令。

格式:
  FROM <image>
  FROM <image>:<tag>
  FROM <image>@<digest>
示例:
  FROM mysql:5.6
注:
  tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像

MAINTAINER: 维护者信息

格式:
    MAINTAINER <name>
示例:
    MAINTAINER Jasper Xu
    MAINTAINER [email protected]
    MAINTAINER Jasper Xu <[email protected]>

RUN:构建镜像时执行的命令

RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:
shell执行
格式:
    RUN <command>
exec执行
格式:
    RUN ["executable", "param1", "param2"]
示例:
    RUN ["executable", "param1", "param2"]
    RUN apk update
    RUN ["/etc/execfile", "arg1", "arg1"]
注:
  RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache

ADD:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget

格式:
    ADD <src>... <dest>
    ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
示例:
    ADD hom* /mydir/          # 添加所有以"hom"开头的文件
    ADD hom?.txt /mydir/      # ? 替代一个单字符,例如:"home.txt"
    ADD test relativeDir/     # 添加 "test" 到 `WORKDIR`/relativeDir/
    ADD test /absoluteDir/    # 添加 "test" 到 /absoluteDir/

COPY:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源

CMD:构建容器后调用,也就是在容器启动时才进行调用。

格式:
    CMD ["executable","param1","param2"] (执行可执行文件,优先)
    CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
    CMD command param1 param2 (执行shell内部命令)
示例:
    CMD echo "This is a test." | wc -
    CMD ["/usr/bin/wc","--help"]
注:
   CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。

ENTRYPOINT:配置容器,使其可执行化。配合CMD可省去"application",只使用参数。

格式:
    ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
    ENTRYPOINT command param1 param2 (shell内部命令)
示例:
    FROM ubuntu
    ENTRYPOINT ["top", "-b"]
    CMD ["-c"]
注:
   ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。

LABEL:用于为镜像添加元数据

格式:
    LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:
  LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"
注:
  使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。

ENV:设置环境变量

格式:
    ENV <key> <value>  #<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
    ENV <key>=<value> ...  #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行
示例:
    ENV myName John Doe
    ENV myDog Rex The Dog
    ENV myCat=fluffy

EXPOSE:指定于外界交互的端口

格式:
    EXPOSE <port> [<port>...]
示例:
    EXPOSE 80 443
    EXPOSE 8080
    EXPOSE 11211/tcp 11211/udp
注:
  EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口

VOLUME:用于指定持久化目录

格式:
    VOLUME ["/path/to/dir"]
示例:
    VOLUME ["/data"]
    VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"
注:
  一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
卷可以容器间共享和重用
容器并不一定要和其它容器共享卷
修改卷后会立即生效
对卷的修改不会对镜像产生影响
卷会一直存在,直到没有任何容器在使用它

WORKDIR:工作目录,类似于cd命令

格式:
    WORKDIR /path/to/workdir
示例:
    WORKDIR /a  (这时工作目录为/a)
    WORKDIR b  (这时工作目录为/a/b)
    WORKDIR c  (这时工作目录为/a/b/c)
注:
  通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。

USER:指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户

格式:
  USER user
  USER user:group
  USER uid
  USER uid:gid
  USER user:gid
  USER uid:group
 示例:
      USER www
 注:
  使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。

ARG:用于指定传递给构建运行时的变量

格式:
    ARG <name>[=<default value>]
示例:
    ARG site
    ARG build_user=www

ONBUILD:用于设置镜像触发器

格式:
  ONBUILD [INSTRUCTION]
示例:
  ONBUILD ADD . /app/src
  ONBUILD RUN /usr/local/bin/python-build --dir /app/src
注:
  当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发

以下是一个小例子

# This my first nginx Dockerfile
# Version 1.0

# Base images 基础镜像
FROM centos

#MAINTAINER 维护者信息
MAINTAINER sunda 

#ENV 设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH

#ADD  文件放在当前目录下,拷过去会自动解压
ADD nginx-1.8.0.tar.gz /usr/local/  
ADD epel-release-latest-7.noarch.rpm /usr/local/  

#RUN 执行以下命令 
RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www

#WORKDIR 相当于cd
WORKDIR /usr/local/nginx-1.8.0 

RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install

RUN echo "daemon off;" >> /etc/nginx.conf

#EXPOSE 映射端口
EXPOSE 80

#CMD 运行以下命令
CMD ["nginx"]

最后用一张图解释常用指令的意义^-^
1572921791178.png

2.1.3 Dockerfile实战Spring Boot项目

2.1.3.1 创建一个Spring Boot项目

https://start.spring.io/

2.1.3.1 写一个controller
 @RestController
  public class DockerController {
    @GetMapping("/dockerfile")
    @ResponseBody
    String dockerfile() {
      return "hello docker" ;
   }
 }
2.1.3.1 打成jar包
mvn clean package打成一个jar包
在target下找到"dockerfile-demo-0.0.1-SNAPSHOT.jar
2.1.3.1 新建一个目录"dockerfile"
mkdir dockerfile
2.1.3.1 上传jar包

dockerfile-demo-0.0.1-SNAPSHOT.jar

2.1.3.1 创建Dockerfile并且编写
FROM openjdk:8
  MAINTAINER itcrazy2016
  LABEL name="dockerfile-demo" version="1.0" author="sunda"
  COPY dockerfile-demo-0.0.1-SNAPSHOT.jar dockerfile-image.jar
  CMD ["java","-jar","dockerfile-image.jar"]
2.1.3.1 基于Dockerfile构建镜像
docker build -t test-docker-image .
2.1.3.1 基于image创建container
docker run -d --name user01 -p 8081:8080 test-docker-image
2.1.3.1 查看启动日志
docker logs user01
2.1.3.1 访问
localhost:8081/dockerfile
2.1.3.1 还可以再次启动一个
docker run -d --name user02 -p 8082:8080 test-docker-image

2.1.4 镜像仓库

2.1.4.1 docker hub

hub.docker.com

sundablog登入

1)在docker机器上登录
docker login

(2)输入用户名和密码

(3)docker push sundablog/test-docker-image
[注意镜像名称要和docker id一致,不然push不成功]

(4)给image重命名,并删除掉原来的
docker tag test-docker-image sundablog/test-docker-image
docker rmi -f test-docker-image

(5)再次推送,刷新hub.docker.com后台,发现成功

(6)别人下载,并且运行
docker pull sundablog/test-docker-image
docker run -d --name user01 -p 6661:8080 sundablog/test-docker-image

2.1.4.2 阿里云docker hub

阿里云docker仓库
https://cr.console.aliyun.com/cn-hangzhou/instances/repositories
参考手册
https://cr.console.aliyun.com/repository/cn-hangzhou/dreamit/image-repo/details

(1)登录到阿里云docker仓库
sudo docker login [email protected] registry.cn-hangzhou.aliyuncs.com
(2)输入密码
(3)创建命名空间,比如sundablog
(4)给image打tag
sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/sundablog/test-docker-image:v1.0
(5)推送镜像到docker阿里云仓库
sudo docker push registry.cn-hangzhou.aliyuncs.com/sundablog/test-docker-image:v1.0
(6)别人下载,并且运行
docker pull registry.cn-hangzhou.aliyuncs.com/sundablog/test-docker-image:v1.0
docker run -d --name user01 -p 6661:8080 registry.cn-hangzhou.aliyuncs.com/itcrazy2016/test-docker-image:v1.0

2.1.4.3 搭建自己的Docker Harbor

https://www.jianshu.com/p/504326a6b4a4

2.2 深入探讨Container

既然container是由image运行起来的,那么是否可以理解为container和image有某种关系?

1572922704914

理解 :其实可以理解为container只是基于image之后的layer而已,也就是可以通过docker run image创建出一个container出来

2.2.1 container到image

既然container是基于image之上的,想想是否能够由一个container反推出image呢?
肯定是可以的,比如通过docker run运行起一个container出来,这时候对container对一些修
改,然后再生成一个新的image,这时候image的由来就不仅仅只能通过Dockerfile咯。

实验

(1)拉取一个centos image
docker pull centos

(2)根据centos镜像创建出一个container
docker run -d -it --name my-centos centos

(3)进入my-centos容器中
docker exec -it my-centos bash

(4)输入vim命令
bash: vim: command not found

(5)我们要做的是
对该container进行修改,也就是安装一下vim命令,然后将其生成一个新的centos

(6)在centos的container中安装vim
yum install -y vim

(7)退出容器,将其生成一个新的centos,名称为"vim-centos-image"
docker commit my-centos vim-centos-image

(8)查看镜像列表,并且基于"vim-centos-image"创建新的容器
docker run -d -it --name my-vim-centos vim-centos-image

(9)进入到my-vim-centos容器中,检查vim命令是否存在
docker exec -it my-vim-centos bash
vim

结论 :可以通过docker commit命令基于一个container重新生成一个image,但是一般得到image的
方式不建议这么做,不然image怎么来的就全然不知咯。

2.2.2 container资源限制

如果不对container的资源做限制,它就会无限制地使用物理机的资源,这样显然是不合适的。
查看资源情况 :docker stats

2.2.2.1 内存限制
--memory  Memory limit
如果不设置 --memory-swap,其大小和memory一样
docker run -d --memory 100M --name tomcat1 tomcat
2.2.2.2 CPU限制
--cpu-shares  权重
docker run -d --cpu-shares 10 --name tomcat2 tomcat

2.2.2.3 图形化资源监控

https://github.com/weaveworks/scope

sudo curl -L git.io/scope -o /usr/local/bin/scope
sudo chmod a+x /usr/local/bin/scope
scope launch 39.100.39.63
# 停止scope
scope stop
# 同时监控两台机器,在两台机器中分别执行如下命令
scope launch ip1 ip2

2.2.3 container常见操作

(1)根据镜像创建容器
docker run -d --name -p 9090:8080 my-tomcat tomcat

(2)查看运行中的container
docker ps

(3)查看所有的container[包含退出的]
docker ps -a

(4)删除container
docker rm containerid
docker rm -f $(docker ps -a)  删除所有container

(5)进入到一个container中
docker exec -it container bash

(6)根据container生成image
docker

(7)查看某个container的日志
docker logs container

(8)查看容器资源使用情况
docker stats

(9)查看容器详情信息
docker inspect container

(10)停止/启动容器
docker stop/start container

2.3 底层技术支持

Container是一种轻量级的虚拟化技术,不用模拟硬件创建虚拟机。

Docker是基于Linux Kernel的Namespace、CGroups、UnionFileSystem等技术封装成的一种自定义容器格式,从而提供一套虚拟运行环境。

Namespace:用来做隔离的,比如pid[进程]、net[网络]、mnt[挂载点]等
CGroups: Controller Groups用来做资源限制,比如内存和CPU等
Union file systems:用来做image和container分层

公众号

如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。
QQ图片20191012084332.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章