Docker学习笔记-理论篇

1、疑问和困惑

随着初步了解,有一些疑问和困惑,这些问题及回答的准确性,本人完全不能保证,只是一个小白学习和使用时产生的问题以及自己理解后的猜想。

1、单个docker类似一个linux虚拟机,那么集群时是不是要开多个docker,相当于开多个虚拟机?
经过多方查阅资料,docker并不是开多个操作系统。docker有image,这个image就相当于android的APK安装文件,运行时系统把APK拷贝到虚拟机生成一个实例,docker中把这个实例叫做 Container,每个Container之间几乎没有任何联系,相当于沙盒。这个image目前我理解的是,image可以被运行为多个实例(Container),会生成多个ID,但是需要配置一些文件防止冲突,比如命名空间、端口号、配置文件等等。

2、docker的image中有nginx、tomcat等镜像,他们是安装软件吗?他们和原生软件有什么关系?
他们不是原生软件,当用docker run一个image后,用docker exec -it指令进去用shell交互时,用ls查看当前目录,发现这个image就是个独立的操作系统,拿nginx的image来说,这个image被运行起来后,整个操作系统基本上就运行了一个nginx的软件。所以完全可以同时运行多个nginx的image,因为他们之间是操作系统级别的隔离。但是docker的image被运行起来后,只是个进程(Container),不是虚拟机的整个系统。
简单粗暴的理解就是:虚拟机可以装多个软件和操作系统一样,docker的image就只装一个软件。

Docker学习笔记-理论篇_第1张图片
关系示意图

3、docker的image运行起来后(Container),如何在后台执行?
Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 systemd 去启动后台服务,容器内没有后台服务的概念。

4、docker运行数据库时,数据都存储在哪里,以<关系示意图>为例,是存储在"linux操作系统"这一层吗?
不是,docker的Container运行起来后,也可以存储数据,但是一旦停止或者被rm掉,数据就消失了,相当于是运行时数据。一般是通过挂载“云服务器”的硬盘数据来做存储,在容器中管理数据主要有两种方式:数据卷(Volumes)、挂载主机目录 (Bind mounts)

2、安装

docker分ce社区免费版和ee企业版,这里介绍的是免费版的安装,参考官方文档。

卸载旧版本

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

安装工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

添加yum信息源
sudo yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo

更新yum缓存
sudo yum makecache fast

安装 docker ce
sudo yum install docker-ce docker-ce-cli containerd.io

使用脚本自动安装

curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun

启动docker
systemctl start docker

开机启动
systemctl enable docker

验证是否正确安装
docker run hello-world

添加内核参数

如果在 CentOS 使用 Docker CE 看到下面的这些警告信息:

WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled

添加内核配置参数以启用这些功能。
sudo tee -a /etc/sysctl.conf <<-EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF
然后重新加载 sysctl.conf
sudo sysctl -p

3、Dockerfile

创建Dockerfile文件
vim /home/server/Dockerfile
写入以下内容

FROM nginx 
RUN echo '

Hello, Docker!

' > /usr/share/nginx/html/index.html

FROM 指定基础镜像
RUN 执行命令行命令,多行操作用&&连接,千万不要写多个RUN指令,正确写法如:

FROM nginx 
RUN echo '

Hello, Docker!

' > /usr/share/nginx/html/index.html \ && cd /root \ && ls

进入Dockerfile所在目录构建新的nginx image
docker build -t nginx:v1 .
这个.实际上是在指定上下文的目录, docker build 命令会将该目录下的内容打包交给 Docker 引擎以帮助构建镜像,所以在Dockerfile脚本所在目录尽量不要放置其他无关内容,如果文件繁多,可以用.dockerignore来忽略无关文件。

启动nginx,映射真实服务器端口的10001端口到docker的80端口
docker run --name nginx1 -d -p 10001:80 nginx:v1

3.1、Dockerfile指令详解

COPY

从当前构建文件夹下复制数据到image里。
COPY [--chown=:] <源路径>... <目标路径>
COPY package.json /usr/src/app/
通配符*,占位符?
COPY hom* /mydir/
COPY hom?.txt /mydir/
改变文件的所 属用户及所属组
COPY --chown=user1:mygroup files* /mydir/

ENV定义环境变量

ENV = =

ENV VERSION=1.0 DEBUG=on \ 
    NAME="Happy Feet"

可以命名多个,后面用$VERSION来引用,空格内容需要加双引号

ARG定义临时参数

ARG <参数名>[=<默认值>]

构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是, ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用 ARG 保存密码之类的信息,因为 docker history 还是可以看到所有值。

VOLUME 定义匿名卷

VOLUME ["<路径1>", "<路径2>"...]

VOLUME /data
容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中。

EXPOSE 声明端口

EXPOSE <端口1> [<端口2>...]

要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口> 区分开来。 -p ,是 映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访 问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行 端口映射。

HEALTHCHECK 健康检查

HEALTHCHECK [选项] CMD <命令> :设置检查容器健康状况的命令

假设我们有个镜像是个最简单的 Web 服务,我们希望增加健康检查来判断其 Web 服务是否在正常工作,我们可以用 curl 来帮助判断,其 Dockerfile 的 HEALTHCHECK 可以这么写:

FROM nginx 
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib /apt/lists/* 
HEALTHCHECK --interval=5s --timeout=3s \ 
  CMD curl -fs http://localhost/ || exit 1

设置了每 5 秒检查一次(这里为了试验所以间隔非常短,实际应该相对较长),如果健康检查命令超过 3 秒没响应就视为失败,并且使用 curl -fs http://localhost/ || exit 1 作为健康检查命令。

查看运行状态
docker container ls

WORKDIR定义工作空间

相当于shell里的cd,但是由于进程的问题,导致cd后和后续要执行的指令不在一个会话里

FROM node:slim 
RUN mkdir /app 
WORKDIR /app 
COPY ./package.json /app 
RUN [ "npm", "install" ] 
COPY . /app/ 
CMD [ "npm", "start" ]

.dockerignore忽略文件

项目根目录下新建.dockerignore文件,用于忽略上传文件,和git忽略文件语法一致。

4、操作指令

docker run

用image启动Container
docker run --name web1 -d -p 8088:80 nginx
这条命令会用 nginx 镜像启动一个容器,命名为 web1,并且映射了真实物理机的 8088端口,这样我们可以用浏览器带8088端口去访问这个 nginx 服务器。

交互式终端方式进入web1
docker exec -it web1 bash
-t —— 分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上
-i —— 让容器的标准输入保持打开

docker container

启动、停止、重启
docker container start
docker container stop
docker container restart

正在运行的容器信息
docker container ls
所有容器的信息包括已停止的
docker container ls -a

删除一个处于终止状态的容器
docker container rm web1
删除一个运行中的容器,可以添加 -f 参数
docker container rm -f web1
清理所有处于终止状态的容器
docker container prune

获取容器的输出信息
docker container logs [container ID or NAMES]

image

导出镜像
docker export 7691a814370e > ubuntu.tar
导入
cat ubuntu.tar | docker import - test/ubuntu:v1.0
从url导入
docker import http://example.com/exampleimage.tgz example/imagerepo

查找
docker search centos
下载
docker pull centos

上传
docker tag ubuntu:18.04 username/ubuntu:18.04
docker image ls
docker push username/ubuntu:18.04
docker search username

删除image
docker image rm web1

5、数据存储

数据卷(Volumes)

数据卷,类似于Linux下对目录或文件进行mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的数据卷。

创建一个名字叫my-vol的数据卷
docker volume create my-vol
查看所有的 数据卷
docker volume ls
查看指定数据卷
docker volume inspect my-vol
利用--mount来挂载数据到container里的/webapp目录下
docker run --name web1 -d -p 8088:80 nginx --mount source=my-vol,target=/webapp

删除数据卷
docker volume rm my-vol
清理无主的数据卷
docker volume prune

挂载主机目录 (Bind mounts)

docker run --name web1 -d -p 8088:80 nginx --mount type=bind,source=/src/webapp,target=/webapp
加载主机的 /src/webapp 目录到容器的 /webapp 目录
Docker 挂载主机目录的默认权限是 读写 ,用户也可以通过增加 readonly指定为只读
--mount type=bind,source=/src/webapp,target=/webapp,read only
挂载单个文件
--mount type=bind,source=/src/webapp/web.war,target=/webapp/web.war,read only

6、扩展

6.1 Docker Compose

使用一个 Dockerfile 模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。 Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker- compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目 (project)。

6.2 Docker Machine

在多种平台 上快速安装 Docker 环境,如果要给100台阿里云ECS安装上docker,传统方式就是你一台一台ssh上去安装,但是有了docker-machine,可以快速给100台ecs安装上docker。还有在本地快创建docker集群环境,总不能一台一台创建虚拟机吧,所以docker-machine可以解决这个问题。

6.3 Docker Swarm

Swarm 是使用 SwarmKit 构建的 Docker 引擎内置(原生)的集群管理和编排工具。如果在100台云服务器上安装了docker这时候难道要一个一个进如dokcer的客户端去管理,有了Swarm,你可以在一台叫做manager的节点上去管理集群。

6.4 Kubernetes

Kubernetes 是 Google 团队发起的开源项目,它的目标是管理跨多个主机的容器, 提供基本的部署,维护以及运用伸缩。功能应该是比Swarm要强大一些,但维护难度比Swarm要高一些,根据查阅的资料,如果是新手建议先搞懂Swarm,再来用k8s。

你可能感兴趣的:(Docker学习笔记-理论篇)