Docker 学习笔记

第1章 docker简介

1.1 什么是docker

1.Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动开放容器联盟(OCI)。
2.Docker 使用 Google 公司推出的 Go 语言进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。
3.Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

1.2 为什么要用docker

1.2.1 docker的优势

更高效的利用系统资源
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。

更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。

一致的运行环境
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。

持续交付和部署
对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。

而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。

更轻松的迁移
由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。

更轻松的维护和扩展
Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。

1.2.2 docker与传统虚拟机的比较

Docker 学习笔记_第1张图片
Docker 学习笔记_第2张图片

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

第2章 docker的核心概念

Docker 包括三个基本概念

  1. 镜像(Image)
  2. 容器(Container)
  3. 仓库(Repository)

理解了这三个概念,就理解了 Docker 的整个生命周期。

2.1 镜像(Image)

Docker镜像类似于一个虚拟机镜像(xxx.iso), 可以将它理解为一个只读的模板!

例如, 一个镜像可以包含一个基本的操作系统环境, 里面仅安装了 Apache应用程序(或用户需要的其他软件). 可以把它称为Apache镜像.

镜像是创建Docker容器的基础.

通过版本管理和增量的文件系统, Docker提供了一套十分简单的机制来创建和更新现有的镜像, 用户甚至可以从网上下载一个已经做好的应用镜像, 并直接使用它.

2.2 容器(Container)

Docker 容器类似于一个轻量级的沙箱, Docker 利用容器来运行和隔离应用。 

容器是从镜像创建的应用运行实例。它可以启动、开始、停止、删除,而这些容器都是彼此相互隔离、互不可见的。 

可以把容器看作一个简易版的 Linux 系统环境(包括 root 用户权限、进程空间、用户空间和网络空间等)以及运行在其中的应用程序打包而成的盒子。

注意:
1.镜像自身是只读的。
2.容器从镜像启动的时候,会在镜像的最上层创建一个可写层。

2.3 仓库(Repository)

Docker 仓库类似于代码仓库,是 Docker 集中存放镜像文件的场所。

根据所存储的镜像公开分享与否, Docker 仓库可以分为公开仓库(Public)和私有仓库(Private)两种形式。

目前,最大的公开仓库是官方提供的 Docker Hub ,其中存放着数量庞大的镜像供用户下载。国内不少云服务提供商(如腾讯云 、 阿里云等)也提供了仓库的本地源,可以提供稳定的国内访问。

当然,用户如果不希望公开分享自己的镜像文件, Docker 也支持用户在本地网络内创建一个只能自己访问的私有仓库。

当用户创建了自己的镜像之后就可以使用 push 命令将它上传到指定的公有或者私有仓库。 这样用户下次在另外一台机器上使用该镜像时,只需要将其从仓库上 pull 下来就可以了。

第3章 Centos安装Docker引擎

Docker 目前支持 CentOS 7 及以后的版本, 内核版本必须是3.10.

查看操作系统版本:

cat /etc/redhat-release

查看内核版本:

uname -r

3.1 卸载旧版本

旧版本的 Docker 被叫做 docker 或 docker-engine,如果安装了旧版本的 Docker ,需要卸载掉它。

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

3.2 安装Docker

3.2.1 安装方法1: 手动安装

1.安装依赖的软件包

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

2.添加Docker文档版本的yum源,官方的yum源安装docker比较慢, 我们配置国内比较快的yum源(阿里云)

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

3.安装最新版本的docker引擎(社区版)

sudo yum -y install docker-ce docker-ce-cli containerd.io
3.2.2 安装方法2: 使用脚本自动安装
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

注意:

  1. 自动安装脚本会自动检测系统信息并进行相应配置
  2. 安装方法1和安装方法2二者选其一即可

3.3 启动Docker服务

sudo systemctl start docker

查看进程是否正常

[linux@node1 ~]$ ps -ef | grep docker
root       1716      1  0 22:36 ?        00:00:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
linux      1841   1418  0 22:36 pts/0    00:00:00 grep --color=auto docker

3.4 验证Docker是否可用

sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete 
Digest: sha256:bfea6278a0a267fad2634554f4f0c6f31981eea41c553fdf5a83e95a41d40c38
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

3.5 把普通用户添加到docker 组

每次使用docker的时候都需要使用root用户, 比较麻烦. 可用把普通用户添加到docker组, 避免每次都添加sudo.

 sudo usermod -aG docker linux

退出当前shell, 重新进入shell, 使刚才的配置生效

第4章 镜像基本操作

官方镜像地址:https://hub.docker.com/

镜像是 Docker 三大核心概念中最重要的,自 Docker 诞生之日起镜像就是相关社区最为热门的关键词。 Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在Docker 会尝试先从默认镜像仓库下载,用户也可以通过配置, 使用自定义的镜像仓库。

4.1 列出本机镜像

docker images

参数说明:

  1. REPOSITORY: 来源仓库
  2. TAG: 镜像的标签信息, 表示镜像的版本. 只是标记, 并不能表示镜像内容
  3. IMAGE ID: 镜像id, 唯一表示一个镜像. 如果两个镜像的 ID 相同, 说明它们实际上指向了同一个镜像,只是具有不同标签名称而已;
  4. CREATED: 镜像的最后更新时间.
  5. SIZE:镜像大小

4.2 获取一个新镜像

当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用 docker pull 命令来下载它。

docker pull hello-world

下载完成后, 可以使用这个镜像来运行容器

4.3 配置国内镜像源地址

下载镜像的时候, 默认是从官方地址下载, 服务器在国外, 速度比较慢, 可以换成国内镜像.
国内常用加速地址:

网易:http://hub-mirror.c.163.com
中国科技大学:https://docker.mirrors.ustc.edu.cn
阿里云容器服务:https://cr.console.aliyun.com/
首页点击“创建我的容器镜像”  得到一个专属的镜像加速地址,类似于https://abcdef.mirror.aliyuncs.com

配置方法:

sudo vim /etc/docker/daemon.json
{
    "registry-mirrors": [
                                "http://hub-mirror.c.163.com",
                                "https://docker.mirrors.ustc.edu.cn",
                                "https://813o9nus.mirror.aliyuncs.com"
                         ]
}

重启docker

sudo systemctl restart docker

查看是否配置成功

docker info
 Operating System: CentOS Linux 7 (Core)
 OSType: linux
 Architecture: x86_64
 CPUs: 4
 Total Memory: 3.84GiB
 Name: node1
 ID: 2WSC:CDIP:L7RV:75YL:GQAS:EUNX:PDE6:NYYD:6Z2W:NDLO:5COE:VOIF
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Registry Mirrors:
  http://hub-mirror.c.163.com/
  https://docker.mirrors.ustc.edu.cn/
  https://813o9nus.mirror.aliyuncs.com/
 Live Restore Enabled: false

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

说明:
关于阿里云地址,参考

https://help.aliyun.com/document_detail/60750.html?spm=a2c4g.11186623.6.550.469742c75wmmC8

4.4 搜索镜像

docker search hello-world
NAME                                       DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
hello-world                                Hello World! (an example of minimal Dockeriz…   1692      [OK]       
kitematic/hello-world-nginx                A light-weight nginx container that demonstr…   151                  
tutum/hello-world                          Image to test docker deployments. Has Apache…   88                   [OK]
dockercloud/hello-world                    Hello World!                                    19                   [OK]
crccheck/hello-world                       Hello World web server in under 2.5 MB          15                   [OK]
ppc64le/hello-world                        Hello World! (an example of minimal Dockeriz…   2                    
ansibleplaybookbundle/hello-world-db-apb   An APB which deploys a sample Hello World! a…   2                    [OK]
souravpatnaik/hello-world-go               hello-world in Golang                           1                    
thomaspoignant/hello-world-rest-json       This project is a REST hello-world API to bu…   1                    
rancher/hello-world                                                                        1                    
ansibleplaybookbundle/hello-world-apb      An APB which deploys a sample Hello World! a…   1                    [OK]
garystafford/hello-world                   Simple hello-world Spring Boot service for t…   0                    [OK]
armswdev/c-hello-world                     Simple hello-world C program on Alpine Linux…   0                    
businessgeeks00/hello-world-nodejs                                                         0                    
strimzi/hello-world-producer                                                               0                    
koudaiii/hello-world                                                                       0                    
strimzi/hello-world-consumer                                                               0                    
freddiedevops/hello-world-spring-boot                                                      0                    
strimzi/hello-world-streams                                                                0                    
tsepotesting123/hello-world                                                                0                    
uffizzicloud/hello-world                                                                   0                    
kevindockercompany/hello-world                                                             0                    
okteto/hello-world                                                                         0                    
dandando/hello-world-dotnet                                                                0                    
rsperling/hello-world3                                                                     0 

4.5 删除镜像

1.使用镜像名+版本号删除镜像

docker rmi hello-world:latest

2.使用id删除镜像

docker rmi feb5d9fea6a5

注意:

  1. 如果删除的时候报错: 有容器使用了该镜像, 则需要先删除使用过该镜像的容器, 才能删除该镜像.
 [linux@node1 ~]$ docker rmi hello-world:latest
Error response from daemon: conflict: unable to remove repository reference "hello-world:latest" (must force) - container 96c737393c57 is using its referenced image feb5d9fea6a5
[linux@node1 ~]$ docker rm 96c737393c57
  1. 删除容器, 再删镜像
[linux@node1 ~]$ docker rmi hello-world:latest
Untagged: hello-world:latest
Untagged: hello-world@sha256:bfea6278a0a267fad2634554f4f0c6f31981eea41c553fdf5a83e95a41d40c38
Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
Deleted: sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359

清理镜像
使用 Docker 一段时间后,系统中可能会遗留一些临时的镜像文件,以及一些没有被使用的镜像,可以通过以下命令来进行清理。

docker image prune -f

第5章 容器基本操作

容器是 Docker 的另一个核心概念。 简单来说,容器是镜像的一个运行实例。所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层,同时,容器中的应用进程处于运行状态。

如果认为虚拟机是模拟运行的一整套操作系统(包括内核、 应用运行态环境和其他系统环境)和跑在上面的应用。 那么 Docker 容器就是独立运行的一个(或一组)应用,以及它们必需的运行环境。

5.1 创建容器

5.1.1 获取centos:7.5.1804的镜像
docker pull centos:7.5.1804
5.1.2 创建容器
docker create -i -t centos:7.5.1804  /bin/bash

说明:
1.创建一个交互式的容器
3. -i: 允许你对容器内的标准输入 (STDIN) 进行交互
4. -t: 在新容器内指定一个伪终端或终端。

5.1.3 查看有哪些容器

1.查看启动的容器

docker ps

2.查看所有容器

docker ps -a
5.1.4 启动容器
docker start a365cb030dcf
5.1.5 新建并启动容器

前面的操作是先创建容器, 然后再启动容器. 也可以使用run来直接新建并启动容器

启动一个交互式的centos容器

docker run -it centos:7.5.1804 /bin/bash

说明:

  1. 检查本地是否存在指定的镜像,不存在就从公有仓库下载;
  2. 利用镜像创建一个容器,并启动该容器;
  3. 分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层 ;
5.1.6 启动后台进程
docker run -itd centos:7.5.1804 /bin/bash

5.2 进入容器

通过指定 -it参数来保持标准输入打开, 并且分配一个伪终端。可以看到会打开一个新的 bash 终端,在不影响容器内其他应用的前提下,用户可以与容器进行交互。

docker exec -i -t a365cb030dcf /bin/bash

在使用 -d 参数时,容器启动后会进入后台(有些容器默认就是后台, 比如centos容器)。

5.3 停止容器

[linux@node1 ~]$ docker ps 
CONTAINER ID   IMAGE             COMMAND       CREATED          STATUS              PORTS     NAMES
a365cb030dcf   centos:7.5.1804   "/bin/bash"   24 minutes ago   Up About a minute             trusting_fermat
[linux@node1 ~]$ docker stop a365cb030dcf
a365cb030dcf

5.4 删除容器

1.删除已经停止的容器

[linux@node1 ~]$ docker rm a365cb030dcf
a365cb030dcf

2.删除正在运行的容器,使用-f强制删除或者先停止再删除

docker rm -f a365cb030dcf

5.5 导入和导出容器

某些时候,需要将容器从一个系统迁移到另外一个系统,此时可以使用 Docker 的导人 和导出功能,这也是 Docker 自身提供的一个重要特性。

5.5.1 导出容器

导出容器是指,导出一个已经创建的容器到一个文件,不管此时这个容器是否处于运行状态.

docker export -o '/home/linux/yes.tar' 88e4853b27ce

可以把导出的tar文件, 传输到其他设备, 再通过导入命令导入, 实现容器的迁移.

5.5.2 导入容器

将上节导出的容器导入之后会成为镜像.

[linux@node1 ~]$ docker import yes.tar -- yescentos:1.1.1
sha256:8503e3daa5448422146f599c51c5b6b429db70c7cc7ca5a53a86dfd589b39202
[linux@node1 ~]$ docker images
REPOSITORY   TAG        IMAGE ID       CREATED         SIZE
yescentos    1.1.1      8503e3daa544   9 seconds ago   200MB
centos       7.5.1804   cf49811e3cdb   3 years ago     200MB

使用新的镜像启动容器:

[linux@node1 ~]$ docker run -i -t yescentos:1.1.1 /bin/bash
[root@6646bf6a1fbb /]# ll
total 0
lrwxrwxrwx.   1 root root   7 May 31  2018 bin -> usr/bin
drwxr-xr-x.   5 root root 360 Mar 31 03:30 dev
drwxr-xr-x.   1 root root  66 Mar 31 03:30 etc
drwxr-xr-x.   2 root root   6 Apr 11  2018 home
lrwxrwxrwx.   1 root root   7 May 31  2018 lib -> usr/lib
lrwxrwxrwx.   1 root root   9 May 31  2018 lib64 -> usr/lib64
drwxr-xr-x.   2 root root   6 Apr 11  2018 media
drwxr-xr-x.   2 root root   6 Apr 11  2018 mnt
drwxr-xr-x.   2 root root   6 Apr 11  2018 opt
dr-xr-xr-x. 138 root root   0 Mar 31 03:30 proc
dr-xr-x---.   2 root root 114 May 31  2018 root
drwxr-xr-x.  10 root root 130 May 31  2018 run
lrwxrwxrwx.   1 root root   8 May 31  2018 sbin -> usr/sbin
drwxr-xr-x.   2 root root   6 Apr 11  2018 srv
dr-xr-xr-x.  13 root root   0 Mar 31 02:12 sys
drwxrwxrwt.   7 root root 132 May 31  2018 tmp
drwxr-xr-x.  13 root root 155 May 31  2018 usr
drwxr-xr-x.  18 root root 238 May 31  2018 var

5.6 查看容器

5.6.1 查看容器详情

会以 json 格式返回包括容器 Id、创建时间、路径、状态、镜像、配置等在内的各项信息

docker container inspect 6646bf6a1fbb
5.6.2 查看容器内进程

这个子命令类似于 Linux 系统中的 top 命令, 会打印出容器内的进程信息, 包括 PID 、 用户、时间、命令等

[linux@node1 ~]$ docker top 6646bf6a1fbb  
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                2430                2411                0                   11:36               pts/0               00:00:00            /bin/bash
5.6.3 查看统计信息
[linux@node1 ~]$ docker stats --no-stream 6646bf6a1fbb
CONTAINER ID   NAME               CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O   PIDS
6646bf6a1fbb   pensive_torvalds   0.00%     376KiB / 3.84GiB    0.01%     656B / 0B   0B / 0B     1

5.7 容器和主机之间复制文件

注意:容器和主机之间进行文件复制的时候, 要保证容器已经启动
1.从主机复制到容器

[linux@node1 bin]$ docker cp cluster.sh 6646bf6a1fbb:/
[linux@node1 bin]$ docker exec -i -t 6646bf6a1fbb /bin/bash
[root@6646bf6a1fbb /]# ll
total 4
lrwxrwxrwx.   1 root root    7 May 31  2018 bin -> usr/bin
-rwxrwxrwx.   1 1000 1000 1105 Nov 25 14:06 cluster.sh
drwxr-xr-x.   5 root root  360 Mar 31 03:36 dev
drwxr-xr-x.   1 root root   66 Mar 31 03:30 etc
drwxr-xr-x.   2 root root    6 Apr 11  2018 home
lrwxrwxrwx.   1 root root    7 May 31  2018 lib -> usr/lib
lrwxrwxrwx.   1 root root    9 May 31  2018 lib64 -> usr/lib64
drwxr-xr-x.   2 root root    6 Apr 11  2018 media
drwxr-xr-x.   2 root root    6 Apr 11  2018 mnt
drwxr-xr-x.   2 root root    6 Apr 11  2018 opt
dr-xr-xr-x. 140 root root    0 Mar 31 03:36 proc
dr-xr-x---.   1 root root   27 Mar 31 03:31 root
drwxr-xr-x.  10 root root  130 May 31  2018 run
lrwxrwxrwx.   1 root root    8 May 31  2018 sbin -> usr/sbin
drwxr-xr-x.   2 root root    6 Apr 11  2018 srv
dr-xr-xr-x.  13 root root    0 Mar 31 02:12 sys
drwxrwxrwt.   7 root root  132 May 31  2018 tmp
drwxr-xr-x.  13 root root  155 May 31  2018 usr
drwxr-xr-x.  18 root root  238 May 31  2018 var

2.从容器复制到主机

[root@6646bf6a1fbb /]# echo 'hello world' > yes.txt
[root@6646bf6a1fbb /]# exit
exit
[linux@node1 bin]$ docker cp 6646bf6a1fbb:/yes.txt /home/linux/
[linux@node1 bin]$ cd /home/linux/
[linux@node1 ~]$ ll
总用量 202972
drwxrwxr-x. 2 linux linux      4096 12月 11 17:02 bin
-rw-------. 1 linux linux 207833088 3月  31 11:25 yes.tar
-rw-r--r--. 1 linux linux        12 3月  31 11:47 yes.txt

第6章 镜像高级操作

6.1 创建镜像

创建镜像的方法主要有2种:
1.基于已有容器创建。
2.基于Dockerfile文件创建

6.1.1 基于已有容器创建
docker commit -m 'add new file : yes.txt' -a 'linux'  6646bf6a1fbb new_centos:1.0.0

说明:
1.-m 提交信息
2.-a 作者
3.9fa 旧有的容器
4.new_centos:1.0 新的镜像

[linux@node1 ~]$ docker commit -m 'add new file : yes.txt' -a 'linux'  6646bf6a1fbb new_centos:1.0.0
sha256:5ef6d5a71ba8cbcf9b27b2652ac812b11e16ef46f8edd52ef90d2afeacdb949d
[linux@node1 ~]$ docker images
REPOSITORY   TAG        IMAGE ID       CREATED          SIZE
new_centos   1.0.0      5ef6d5a71ba8   7 seconds ago    200MB
yescentos    1.1.1      8503e3daa544   28 minutes ago   200MB
centos       7.5.1804   cf49811e3cdb   3 years ago      200MB
[linux@node1 ~]$ docker run -i -t 5ef6d5a71ba8 /bin/bash
6.1.2 基于Dockerfile 创建

基于 Dockerfile 创建是最常见的方式。 Dockerfile 是一个文本文件, 利用给定的指令描述基于某个父镜像创建新镜像的过程。

下面使用Dockerfile创建一个基于centos的java开发环境:

6.1.2.1 把jdk安装转包copy到 /home/linux 目录下
[linux@node1 ~]$ cd /home/linux/
[linux@node1 ~]$ cp /opt/software/jdk-8u212-linux-x64.tar.gz ./
6.1.2.2 在/home/linux上创建Dockerfile文件
vim Dockerfile

FROM centos:7.5.1804
RUN mkdir -p /opt/software
RUN mkdir -p /opt/module
COPY jdk-8u212-linux-x64.tar.gz /opt/software/
RUN tar -zxvf /opt/software/jdk-8u212-linux-x64.tar.gz -C /opt/module
RUN rm -rf /opt/software/jdk-8u212-linux-x64.tar.gz
ENV JAVA_HOME=/opt/module/jdk1.8.0_212
ENV PATH=$JAVA_HOME/bin:$PATH

说明:
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。
COPY 是把文件copy到镜像中. 源文件必须是相对路径不能是绝对路径
ENV 在镜像中设置环境变量

6.1.2.3 创建镜像, 并等待创建成功
docker build -t centos_java8:1.0 .

说明:
1 -t 指明镜像名字和标签
2 .表示Dockfile所在目录

6.1.2.4 测试镜像是否可以正常工作
[linux@node1 ~]$ docker run centos_java8:1.0 java -version
java version "1.8.0_212"
Java(TM) SE Runtime Environment (build 1.8.0_212-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)

6.2 保存和加载镜像

使用保存和加载功能可以把本机的镜像发给其他人使用

6.2.1 保存镜像
docker save -o centos_java8.tar centos_java8:1.0.0
6.2.2 加载镜像

把刚刚保存的镜像发给别人, 然后加载导入.

docker load -i centos_java8.tar

第7章 为镜像添加ssh服务

很多镜像是不带ssh服务的, 管理镜像非常的不方便, 本章介绍如何给镜像添加ssh服务,可以直接用xshell连接上

7.1 创建镜像

Dockerfile:

# 设置继承镜像
FROM centos_java8:1.0.0
# 提供作者信息
MAINTAINER linux ([email protected])

# 更换国内阿里云yum源
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
RUN yum makecache

# 安装sshd
RUN yum install -y openssh-server openssh-clients
RUN sed -i '/^HostKey/'d /etc/ssh/sshd_config
RUN echo 'HostKey /etc/ssh/ssh_host_rsa_key'>>/etc/ssh/sshd_config

# 生成 ssh-key
RUN ssh-keygen -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key

# 更改 root 用户登录密码为
RUN echo 'root:aaaaaa' | chpasswd

# 开发 22 端口
EXPOSE 22

# 镜像运行时启动sshd
RUN mkdir -p /opt
RUN echo '#!/bin/bash' >> /opt/run.sh
RUN echo '/usr/sbin/sshd -D' >> /opt/run.sh
RUN chmod +x /opt/run.sh
CMD ["/opt/run.sh"]

构建

docker build -t centos_java8_sshd:1.0.0 ./

7.2 运行容器, 测试镜像

docker run -d -p 2222:22 centos_java8_sshd:1.0.0

说明: 把容器的22端口映射到宿主机器的2222端口, 这样通过ssh连接宿主机器的2222端口就可以连接到容器了.

[linux@node1 yes]$ ssh [email protected] -p 2222              
The authenticity of host '[192.168.1.101]:2222 ([192.168.1.101]:2222)' can't be established.
RSA key fingerprint is SHA256:KMMId1OviSGgSMubkADSZ3T9LJPqN28qwds8e5i0trA.
RSA key fingerprint is MD5:dd:b0:5b:6d:37:b1:7c:cf:c3:ae:c1:e9:13:54:7f:63.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[192.168.1.101]:2222' (RSA) to the list of known hosts.
[email protected]'s password: 
[root@4f6ebb79172e ~]# ll
total 4
-rw-------. 1 root root 3302 May 31  2018 anaconda-ks.cfg

第8章 端口映射与容器互联

8.1 端口映射

在启动容器的时候,如果不指定对应参数,在容器外部是无法通过网络来访问容器内的 网络应用和服务的。

使用 -p 来指定映射规则: 3000:22 表示宿主的3000映射到容器的22端口, 使用多次 -p 可以映射多个端口.

docker run -d -p 2222:22 -p 8888:80 centos_java8_sshd:1.0

查看容器端口绑定情况:

docker port 4f6ebb79172e

8.2 容器互相访问

端口映射并不是唯一把 docker 连接到另一个容器的方法。

docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。

docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。

8.2.1 容器命名

创建容器的时候, Docker会自动为容器分配一个随机的名字.我们也可以指定一个好记的名字, 方便容器间的互联.

docker run -d --name node001 centos_java8_sshd:1.0

说明:
–name 参数给容器起一个名字

8.2.2 docker的网络

docker还会给我们创建三个网络:bridge/host/none。我们可以通过network ls命令查看当前宿主机中所有的docker网络。

[linux@node1 yes]$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
1d4d049b198d   bridge    bridge    local
7c66ef53a884   host      host      local
5cc0479f41ac   none      null      local

其中,网桥bridge模式是在实际项目中常用的。接下来,以交互模式启动两个centos_java8_sshd 容器。在没有指定相关网络的情况下,容器都会连接到默认的bridge网络.

创建两个容器: node001和node002, 检查bridge网络情况. 可以看到他们的ip地址.

docker run -d --name node001 centos_java8_sshd:1.0
docker run -d --name node002 centos_java8_sshd:1.0

docker network inspect bridge

 "Containers": {
            "4b0f93058fb187fd032c11b55dfc8cce34bc7e05568ace49189d75c222a4798c": {
                "Name": "node001",
                "EndpointID": "81a20c27bb61edb5dd4168d5f5e93f83aab3bdbe9a18e29adf5584dd40805b36",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",
                "IPv6Address": ""
            },
            "dee42587a057f9b17f57cdeb1b32bf1034e910e19985eebd253b637bc17b29e2": {
                "Name": "node002",
                "EndpointID": "cdd436252d55a8744894b3ab3c21e6ed0da766bdfde41130c0b1cd61954595da",
                "MacAddress": "02:42:ac:11:00:05",
                "IPv4Address": "172.17.0.5/16",
                "IPv6Address": ""
            }

注意:
1.通过ip地址我们在宿主机或者容器之间可以访问到对方

[linux@node1 yes]$ ping 172.17.0.5
PING 172.17.0.5 (172.17.0.5) 56(84) bytes of data.
64 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.160 ms
64 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.097 ms
64 bytes from 172.17.0.5: icmp_seq=3 ttl=64 time=0.074 ms

2.当是172.17.0.5 等这些ip地址不能固定, 每次启动容器的时候有可能会变化, 如果组建集群的话很不方便.

8.2.3 自定义bridge网络, 实现容器间通讯

docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过“容器名”通信。使用默认的bridge网络,不能通过DNS server实现通过容器名通信,但是使用自定义bridge网络可以做到通过容器名互相通信。

8.2.3.1 创建自定义bridge网络, 网络名yes
docker network create --driver bridge yes
8.2.3.2 删除node001和node002容器
docker rm -f node001
docker rm -f node002
8.2.3.3 新建并启动node001和node002容器, 并加入到yes网络
docker run -d --name node001 --network yes centos_java8_sshd:1.0
docker run -d --name node002 --network yes centos_java8_sshd:1.0
[linux@node1 yes]$ docker network inspect yes
[
    {
        "Name": "yes",
        "Id": "038665fdac23029a0758be9197dd4685b1882ce262b29a6a6638fd13d73fad14",
        "Created": "2022-03-31T16:20:51.333116309+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "0e6ab48e07fbd5949b931a36886e5742c925223f2b5f9a68bd3a94c1e766b6a5": {
                "Name": "node002",
                "EndpointID": "0b45230c8df2e3fad1b768c1ce46c804e667f301e9be436d7f79eaeb1da448b6",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "bfae4362da6740526c1978926722921660c19e560793a7b3b1f735b59216f729": {
                "Name": "node001",
                "EndpointID": "d293cb888ccd80a95111170e31e88770da8b8ab7d05ed07928920241f14cc7d0",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
8.2.3.4 进入node001, 测试是否可以ping通node002
[linux@node1 yes]$ ssh [email protected]
The authenticity of host '172.18.0.3 (172.18.0.3)' can't be established.
RSA key fingerprint is SHA256:KMMId1OviSGgSMubkADSZ3T9LJPqN28qwds8e5i0trA.
RSA key fingerprint is MD5:dd:b0:5b:6d:37:b1:7c:cf:c3:ae:c1:e9:13:54:7f:63.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.18.0.3' (RSA) to the list of known hosts.
[email protected]'s password: 
[root@0e6ab48e07fb ~]# ping node002
PING node002 (172.18.0.3) 56(84) bytes of data.
64 bytes from 0e6ab48e07fb (172.18.0.3): icmp_seq=1 ttl=64 time=0.015 ms
64 bytes from 0e6ab48e07fb (172.18.0.3): icmp_seq=2 ttl=64 time=0.043 ms
64 bytes from 0e6ab48e07fb (172.18.0.3): icmp_seq=3 ttl=64 time=0.082 ms

你可能感兴趣的:(运维监控组件,大数据,docker)