Docker · Spring Boot · Kotlin · 微服务Docker容器

Docker基础

2020-05-12  本文已影响0人  左舷的风

本文本来是公司部门内部的技术分享,比较基础,特地再整理出来分享给大家。



第一章 容器技术前瞻

1.1 为什么要学习容器:
1.2 使用容器的优点:

第二章 容器技术的发展

2.1 容器与主机级虚拟化:

容器技术本身也是虚拟化的一种,只不过比起主机级虚拟化更轻量,每个容器不单独拥有操作系统,而是与宿主机共用内核

对比传统虚拟机总结:

特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为 MB 一般为 GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个
2.2 LXC:

<img src="http://cerberus43-md.oss-cn-beijing.aliyuncs.com/md/2020-04-22-083804.jpg" style="zoom: 150%;" />

LXC(LinuX Containers)Linux容器,一种操作系统层虚拟化技术,为Linux内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。透过统一的名字空间和共享API来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得Linux用户可以容易的创建和管理系统或应用容器。
Linux内核中,提供了cgroups功能,来达成资源的隔离(做资源限制)。它同时也提供了名称空间(NameSpaces隔离的功能,使应用程序看到的操作系统环境被区隔成独立区间,包括进程树,网络,用户id,以及挂载的文件系统。(ipc, network, user, pid, mount)

LXC利用cgroupsNameSpaces的功能,提供应用软件一个独立的操作系统环境。LXC不需要Hypervisor这个软件层,软件容器(Container)本身极为轻量化,提升了创建虚拟机的速度。

而Docker本质来说不是容器,而是容器的管理工具,最初的Docker也是基于LXC实现的。


第三章 Docker介绍

3.1 Docker简介:

Docker的英文翻译是“搬运工”的意思,他搬运的东西就是我们常说的集装箱ContainerContainer 里面装的是任意类型的 App,我们的开发人员可以通过 Docker 将App 变成一种标准化的、可移植的、自管理的组件,我们可以在任何主流的操作系统中开发、调试和运行。

Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 开放容器联盟(OCI)

Docker 自开源后受到广泛的关注和讨论,至今其 GitHub 项目 已经超过 5 万 4 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 DockerDocker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker

Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroupnamespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runCcontainerd

Docker Engine是一个C/S架构的应用程序,主要包含下面几个组件:

3.2 Docker安装:

官方安装文档:https://docs.docker.com/get-docker/

因国内访问DockerHub仓库比较慢,可以添加阿里云镜像加速配置。阿里云官方镜像加速

3.3 第一个容器:
#运行centos 6.7容器
  docker run -it --rm --name=demo01 centos:6.7 /bin/bash 

#当看到提示符改变时代表着我们已进入容器内部

#cat /etc/redhat-release 
CentOS release 6.7 (Final)

#uname -r
3.10.0-957.12.2.el7.x86_64

#ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:613 (613.0 b)  TX bytes:0 (0.0 b)
          
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

#hostname
ecb2a387e9c6

#ps axu
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.1  0.0  11488  1780 pts/0    Ss   07:06   0:00 /bin/bash
root        18  0.0  0.0  13372  1044 pts/0    R+   07:08   0:00 ps axu

第四章 Docker镜像

关键词:“分层构建,联合挂载”,“写时复制”

4.1 镜像的概念:

我们都知道,操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:18.04 就包含了完整的一套 Ubuntu 18.04 最小系统的 root 文件系统。

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变

4.2 镜像常用操作命令:
#查看本地镜像
docker image ls

#查找DockerHub上的镜像
docker search centos

-----
#docker pull [选项] [Docker Registry 地址[:端口]/]仓库名[:标签]

#从DockerHub获取centos 6.7的镜像(DockerHub默认仓库为library)
docker image pull centos:6.7

#从私有镜像仓库获取centos 6.6的镜像
docker image pull 10.1.129.123:81/base_image/centos:6.6

-----
#删除镜像
docker image rm centos:6.7

#描述centos:6.7镜像的详细信息
docker image inspect centos:6.7
#Layers处参数可以看出此镜像只有一层
docker image inspect nginx
#可以看出nginx镜像有三层

#查看centos:6.7镜像的历史
docker image history centos:6.7
4.3 使用Docker Commit定制镜像:

镜像是容器的基础,每次执行docker run的时候都会指定哪个镜像作为容器运行的基础。在之前的例子中,我们所使用的都是来自于 Docker Hub 的镜像。直接使用这些镜像是可以满足一定的需求,而当这些镜像无法直接满足需求时,我们就需要定制这些镜像。

现在我们以定制一个 Web 服务器为例子,来讲解镜像是如何构建的。

docker run --name webserver1 -d -p 80:80 nginx

这条命令会用 nginx 镜像启动一个容器,命名为 webserver,并且映射了 80 端口,这样我们可以用浏览器去访问http://10.1.129.122/这个 nginx 服务器,会看到默认的 Nginx 欢迎页面。

但是如果我们不喜欢这个欢迎页面,希望改成欢迎 Docker 的文字,我们就可以使用 docker exec命令进入容器,修改其内容。

docker exec -it webserver1 bash

#修改默认欢迎页面
echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

刷新下页面,就可以看到Hello,Docker!

我们修改了容器的文件,也就是改动了容器的存储层。我们可以通过docker diff命令看到具体的改动。

docker diff fccd0bf45940

C /run
A /run/nginx.pid
C /var
C /var/cache
C /var/cache/nginx
A /var/cache/nginx/proxy_temp
A /var/cache/nginx/scgi_temp
A /var/cache/nginx/uwsgi_temp
A /var/cache/nginx/client_temp
A /var/cache/nginx/fastcgi_temp
C /usr
C /usr/share
C /usr/share/nginx
C /usr/share/nginx/html
C /usr/share/nginx/html/index.html

当我们运行一个容器的时候(如果不使用卷的话),我们做的任何文件修改都会被记录于容器存储层里。而 Docker 提供了一个docker commit命令,可以将容器的存储层保存下来成为镜像。换句话说,就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。

我们可以用下面的命令将容器保存为镜像:

docker commit \
    --message "修改默认页面" \
    webserver1 \
    nginx-demo:v1

使用docker image ls查看刚才commit的镜像;

也可以使用docker image history 查看镜像历史:

docker image history nginx-demo:v1

docker commit 命令除了学习之外,还有一些特殊的应用场合,比如被入侵后保存现场等。但是,不要使用 docker commit 定制镜像,定制镜像应该使用Dockerfile来完成。

4.4 使用Dockerfile定制镜像:

我们还是以刚才的webserver为例子:

FROM nginx

RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

使用docker build构建:

docker build -t nginx-demo:v2 .
docker run -d -p 80:81 --name webserver2 nginx-demo:v2
4.5 理解镜像的构成原理:

使用docker image inspect对比下 nginx-demo:v2nginx:latest镜像,会发现多了一层:

docker image inspect nginx-demo:v2

docker image inspect nginx

镜像是多层存储,每一层是在前一层的基础上进行的修改;而容器同样也是多层存储,是在以镜像为基础层,在其基础上加一层作为容器运行时的存储层。

当 Docker 第一次启动一个容器时,初始的读写层是空的,当文件系统发生变化时,这些变化都会应用到这一层 之上。比如,如果想修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层。由此,该文件的只读版本依然存在于只读层,只是被读写层的该文件副本所隐藏。该机制则被称之为写时复制(Copy on write)


第五章 Docker容器

对于运维来说,容器与镜像的关系就像虚拟机与模板。对于开发来说,容器与镜像的关系就像类与实例

<img src="http://cerberus43-md.oss-cn-beijing.aliyuncs.com/md/2020-04-23-091849.jpg" style="zoom:200%;" />

5.1 容器常用操作命令:
#运行centos 6.7容器并打开一个交互终端
docker run -it centos:6.7 

#查看运行中的容器
docker container ps

#运行centos 6.7容器,打开一个交互终端,默认进去命令为/bin/bash,命名为centos6.7,并在退出后删除
docker run -it --rm --name=centos6.7 centos:6.7 /bin/bash

#查看所有容器(包括停止的)
docker container ps -a 

#进入id为177bb3ef28fe的容器
docker exec -it 177bb3ef28fe /bin/bash

#停止id为177bb3ef28fe的容器
docker stop 177bb3ef28fe

#删除id为177bb3ef28fe的容器
docker rm 177bb3ef28fe

关于后台运行:

#后台运行centos 6.7容器
docker run -d centos:6.7

docker ps -a 查看容器已经停止了,因为默认的centos 6.7镜像的命令是/bin/bash,命令执行完了,容器也就退出了
#后台运行centos 6.7容器,并运行shell命令 sleep 3600
docker run -d centos:6.7 sleep 3600

容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关!

容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关!

容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关!

5.2 容器存储与持久化:

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

创建一个数据卷:

  docker volume create nginx-demo-v4

查看所有的数据卷:

  docker volume ls

查看指定 数据卷 的信息:

  docker volume inspect nginx-demo-v4
  [
      {
          "CreatedAt": "2020-05-11T17:25:56+08:00",
          "Driver": "local",
          "Labels": {},
          "Mountpoint": "/var/lib/docker/volumes/nginx-demo-v4/_data",
          "Name": "nginx-demo-v4",
          "Options": {},
          "Scope": "local"
      }
  ]

启动一个挂载数据卷的nginx容器webserver4:

  docker run -d -p 81:80 \
    --name webserver4 \
    --mount source=nginx-demo-v4,target=/usr/share/nginx/html \
    nginx

再启动一个挂载数据卷的nginx容器webserver5:

  docker run -d -p 82:80 \
    --name webserver5 \
    --mount source=nginx-demo-v4,target=/usr/share/nginx/html \
    nginx

修改下webserver4的默认nginx页面:

  docker exec -it webserver4 bash
  
  echo '<h1>Hello,Docker!</h1>' > index.html

从浏览器查看两个容器的页面都会被修改,在宿主机上查看文件也会被修改:

  cd /var/lib/docker/volumes/nginx-demo-v4/_data 
  cat index.html
5.3 网络端口映射:

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P-p 参数来指定端口映射。

查看容器的端口映射:

docker port CONTAINER [PRIVATE_PORT[/PROTO]]

docker port webserver7

第六章 Docker仓库

默认镜像仓库是DockerHub:(https://hub.docker.com/

公有云镜像仓库:阿里云,腾讯云等等

私有镜像仓库:registry(官方的registry),Harbor

docker image pull <repository>:<tag>

#拉取最新的ubuntu镜像
docker image pull ubuntu:14.04

#把最新的ubuntu镜像重新打标签为my-ubuntu:v1
docker tag ubuntu:latest my-ubuntu:v1 

私有镜像仓库

因为 Docker 默认不允许非 HTTPS 方式推送镜像。我们可以通过 Docker 的配置选项来取消这个限制。

cat /etc/docker/daemon.json

{
  "insecure-registries": [
      "http://10.1.129.123:81"
  ]
}
上一篇 下一篇

猜你喜欢

热点阅读