docker容器
容器介绍
容器其实是一种沙盒技术。沙盒就是能够像一个集装箱一样,把你的应用"装"起来的技术。这样,应用与应用之间,就因为有了边界而不至于相互干扰;(隔离性)
而被装进集装箱的应用,也可以被方便地搬来搬去。(移植性)
容器的本质到底是什么?
容器的本质是进程。(在宿主机上被隔离的进程)容器镜像就是这个wind系统里的".exe"安装包.
Docker介绍:
Docker是Docker.Inc公司开源的一个基于轻量级虚拟化技术的容器引擎项目,整个项目基于Go语言开发,并遵从Apache 2.0协议。Docker使得应用开发者和运维工程师可以以统一的方式跨平台发布应用,并且以几乎没有额外开销的情况下提供资源隔离的应用运行环境。 Docker 是一个开源工具,它可以让创建和管理 Linux 容器变得简单。容器就像是轻量级的虚拟机,并且可以以秒级的速度来启动或停止。 官网:docker.com https://hub.docker.com/ ---docker官方库--(存镜像)也叫docker-hub
没有容器的时候:
1.rd开发产品(需要配置开发环境)
2.测试(需要配置测试环境)
3.op上线(需要部署上线环境)
开发 测试 运维
有容器之后:
-
rd开发产品(开发过程中就做成镜像,在docker容器里配置环境)
-
测试(直接测试)
-
把容器打包成镜像交给运维,运维上线
Docker 优势
1、交付物标准化 Docker的标准化交付物称为"镜像",它包含了应用程序及其所依赖的运行环境,大大简化了应用交付的模式。 2、应用隔离 Docker可以隔离不同应用程序之间的相互影响,----容器之间相互独立互不影响。容器技术部署速度快,开发、测试更敏捷; 3、移植性:一次构建,多次交付 类似于集装箱的"一次装箱,多次运输",Docker镜像可以做到"一次构建,多次交付"。 Docker是利用容器来实现的一种轻量级的虚拟技术,从而在保证隔离性的同时达到节省资源的目的。Docker的可移植性可以让它一次建立,到处运行。Docker的度量可以从以下几个方面进行: 4、隔离性通过内核的命名空间来实现的,将容器的进程、网络、消息、文件系统和主机名进行隔离。(当然磁盘、内存仍然没有隔离) 5、可度量性Docker主要通过cgroups控制组来控制资源的度量和分配,提高系统利用率,降低资源成本. 6、轻量级:与传统的虚拟机相比,容器共享主机操作系统的内核,而不是携带一个完整的操作系统副本。这意味着容器启动速度非常快,资源消耗也相对较少。
容器技术主要依赖于操作系统提供的功能,特别是Linux内核中的以下特性:
-
命名空间(Namespaces):为容器提供隔离的视图,使得每个容器看起来像是在自己的系统中运行。
-
控制组(Control Groups, cgroups):用来限制、记录和隔离容器使用的物理资源(CPU、内存、磁盘I/O等)。
容器和 VM 的主要区别
1.表面区别: 容器占用体积小,虚拟机占用体积大 隔离性:虚拟机隔离性好,容器的隔离性差。容器提供了基于进程的隔离,而虚拟机提供了资源的完全隔离,虚拟机比容器安全. 启动速度:虚拟机可能需要一分钟来启动,而容器只需要一秒钟或更短。 容器共享宿主机操作系统的内核,而虚拟机使用独立的内核。Docker 的局限性之一是,它只能用在64位的操作系统上。 2.本质区别: 容器是隔离的进程,共享宿主机操作系统内核,启动速度快,占用资源少; 虚拟机是完整的虚拟计算机,具有较好的隔离性,但需要较长的启动时间和较大的资源占用。
常见的容器技术
- Docker:目前最流行的容器平台之一,提供了一整套工具和服务来构建、部署和管理容器化应用程序。
- Kubernetes(K8s):一个开源平台,用于自动化容器化应用的部署、扩展和管理。
- LXC (Linux Containers):一个更底层的技术,直接使用Linux内核特性来创建和管理容器。
docker安装
CentOS 7 中 Docker 的安装:
Docker 软件包已经包括在默认的 CentOS-Extras 软件源(联网使用centos7u2自带网络Yum源)里。因此想要安装 docker,只需要运行下面的 yum 命令:
# yum install -y epel*
# yum install docker
启动 Docker 服务:
# service docker start
# chkconfig docker on
CentOS 7
# systemctl start docker.service
# systemctl enable docker.service
确定docker服务在运行:结果会显示服务端和客户端的版本,如果只显示客户端版本说明服务没有启动
# docker version
Client:Version: 1.13.1API version: 1.26
...
Server:Version: 1.13.1API version: 1.26 (minimum version 1.12)
···
docker版本与官方安装方式
moby、docker-ce与docker-ee
最早时docker是一个开源项目,主要由docker公司维护。2017年3月1日起,docker公司将原先的docker项目改名为moby,并创建了docker-ce和docker-ee。
三者关系:
moby是继承了原先的docker的项目,是社区维护的的开源项目,谁都可以在moby的基础打造自己的容器产品 docker-ce是docker公司维护的开源项目,是一个基于moby项目的免费的容器产品 docker-ee是docker公司维护的闭源产品,是docker公司的商业产品
moby project由社区维护,docker-ce project是docker公司维护,docker-ee是闭源的docker公司维护。
CentOS--官方安装
如果是centos,上面的安装命令会在系统上添加yum源:/etc/yum.repos.d/docker-ce.repo
# wget https://download.docker.com/linux/centos/docker-ce.repo
# mv docker-ce.repo /etc/yum.repos.d/
# yum install -y docker-ce
或者直接下载rpm安装
# wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-17.09.0.ce-1.el7.centos.x86_64.rpm
# yum localinstall docker-ce-17.09.0.ce-1.el7.centos.x86_64.rpm
国内源安装新版docker
使用aliyun docker yum源安装新版docker
删除已安装的Docker
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
配置阿里云Docker Yum源
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
列出所有可用的 Docker 软件包版本
用于安装或更新 Docker
yum list docker-ce --showduplicates
安装Docker新版本
制定版本,比如Docker 18.03.0,加上rpm包名的版本号部分或不加都可以
# 安装最新版本
yum install -y docker-ce
# 安装制定版本
yum install docker-ce-18.03.0.ce -y
启动Docker服务
systemctl enable docker
systemctl start docker
查看Docker版本和当前版本状态
# 检查 Docker 客户端的版本
docker -v
# 提供详细的客户端和服务端版本信息
docker version
查看Docker运行状态
docker info报错1:
docker info的时候报如下错误:bridge-nf-call-iptables is disabled
解决1:
追加如下配置,然后重启系统
# vim /etc/sysctl.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-arptables = 1
问题2:
虚拟机ping百度也能ping通,但是需要等好几秒才出结果,关键是下载镜像一直报错如下
# docker pull daocloud.io/library/nginx
Using default tag: latest
Error response from daemon: Get https://daocloud.io/v2/: dial tcp: lookup daocloud.io on 192.168.1.2:53: read udp 192.168.1.189:41335->192.168.1.2:53: i/o timeout
解决2:
我的虚拟机用的网关和dns都是虚拟机自己的.1或者.2,把DNS改成8.8.8.8问题就解决了,ping百度也秒出结果
# vim /etc/resolv.conf
nameserver 8.8.8.8
简单测试
运行一个容器
# docker run -itd daocloud.io/library/ubuntu #放后台运行
# docker run -it daocloud.io/library/ubuntu /bin/bash #下载并运行容器
(/bin/bash、/bin/sh都是登录shell,/bin/bash有环境变量)
Unable to find image 'daocloud.io/library/ubuntu:latest' locally
latest: Pulling from library/ubuntu
5c939e3a4d10: Pull complete
c63719cdbe7a: Pull complete
19a861ea6baf: Pull complete
651c9d2d6c4f: Pull complete
Digest: sha256:bc025862c3e8ec4a8754ea4756e33da6c41cba38330d7e324abd25c8e0b93300
Status: Downloaded newer image for daocloud.io/library/ubuntu:latest
如果自动进入下面的容器环境,说明•ubuntu镜像运行成功,Docker的安装也没有问题:可以操作容器了
root@db8e84e2ea96:/#
国内镜像源
去查看如何使用aliyun的docker镜像库
Docker 加速器
使用 Docker 的时候,需要经常从官方获取镜像,但是由于显而易见的网络原因,拉取镜像的过程非常耗时,严重影响使用 Docker 的体验。因此 DaoCloud 推出了加速器工具解决这个难题,通过智能路由和缓存机制,极大提升了国内网络访问 Docker Hub 的速度。 Docker 加速器对 Docker 的版本有要求吗? 需要 Docker 1.8 或更高版本才能使用。 Docker 加速器支持什么系统? Linux, MacOS 以及 Windows 平台。 Docker 加速器是否收费? 提供永久免费的加速器服务,请放心使用。
国内比较好的镜像源:aliyun和daocloud
daocloud.io--官网
配置道客的镜像
进入网站:DaoCloud 道客 – 云原生领域的创新领导者/
注册帐号:soso666
进入镜像市场
随便选择一个,选择mysql
上面有详细的使用命令。但是每个镜像的命令不一样,在选择一个:
[root@docker-server ~]# docker pull daocloud.io/library/nginx #下载镜像
Using default tag: latest
latest: Pulling from library/nginx
0a4690c5d889: Pull complete
9719afee3eb7: Pull complete
44446b456159: Pull complete
Digest: sha256:f83b2ffd963ac911f9e638184c8d580cc1f3139d5c8c33c87c3fb90aebdebf76
Status: Downloaded newer image for daocloud.io/library/nginx:latest
daocloud.io/library/nginx:latest
配置阿里云的镜像仓库
创建阿里云的私有仓库
使用自己的私有仓库
登录:
[root@docker-server ~]# docker login --username=aliyun1308451786 crpi-bi3swcirbp9a2x5x.cn-hangzhou.personal.cr.aliyuncs.com
Password: Yunjisuan666@
...
Login Succeeded
重新打标记
[root@yixuan ~]# docker tag daocloud.io/library/nginx:latest registry.cn-shanghai.aliyuncs.com/testpm/nginx:1.18
上传到自己的仓库
[root@yixuan ~]# docker push registry.cn-shanghai.aliyuncs.com/testpm/nginx:1.18
查看上传的镜像
自己的nginx:1.1版本已经上传成功!
使用自己的仓库
配置加速器
配置阿里加速器:
如果这个目录/etc/docker/不存在就创建
[root@yixuan ~]# vim /etc/docker/daemon.json
{"registry-mirrors": ["https://br003st4.mirror.aliyuncs.com"]
}
[root@yixuan ~]# systemctl daemon-reload
[root@yixuan ~]# systemctl restart docker
docker基本概念
Docker系统
Docker系统有两个程序:docker服务端和docker客户端 docker服务端:是一个服务进程,管理着所有的容器。也叫docker engine。 docker客户端:扮演着docker服务端的远程控制器,可以用来控制docker的服务端进程。 大部分情况下,docker服务端和客户端运行在一台机器上
Docker三大核心组件:
Docker 镜像 - Docker images Docker 仓库 - Docker registeries Docker 容器 - Docker containers
容器的三大组成要素:
名称空间 namespace 容器隔离(pid,net,mnt,user,) 资源限制 cgroups 资源(内存,cpu) 文件系统 overlay2(UnionFS) (镜像分层)
docker 仓库:用来保存镜像,可以理解为代码控制中的代码仓库。同样的,Docker 仓库也有公有和私有的概念。这些镜像可以是自己创建,或者在别人的镜像基础上创建。
docker 国内仓库
ali
网易蜂巢
daocloud
=========================
docker公有仓库
docker.io -------docker官方库也叫docker-hub
类似于github一样,面向全球的一个docker镜像的公共仓库。如果在国内使用速度太慢。
===============================
docker私有仓库
个人或者公司部署的非公开库
阿里、harbor、腾讯、华为
docker镜像命名解析
Docker 镜像是 Docker 容器运行时的只读模板,每一个镜像由一系列的层组成。Docker 使用 UnionFS 来将这些层联合到单独的镜像中。当你改变了一个 Docker 镜像,比如升级到某个程序到新的版本,一个新的层会被创建。
在 Docker 的术语里,一个只读层被称为镜像,一个镜像是永久不会变的。由于镜像不可写,所以镜像是无状态的。
镜像是Docker最核心的技术之一,也是应用发布的标准格式。那么docker镜像是如何命名的,这也是Docker里面比较容易令人混淆的一块概念:Registry,Repository, Tag and Image。
那么Registry又是什么呢?Registry存储镜像数据,并且提供拉取和上传镜像的功能。Registry中镜像是通过Repository来组织的,而每个Repository又包含了若干个Image。下面是在本地机器运行docker images的输出结果:
常说的"ubuntu"镜像其实不是一个镜像名称,而是代表了一个名为ubuntu的Repository,同时在这个Repository下面有一系列打了tag的Image,Image的标记是一个GUID,为了方便也可以通过Repository:tag来引用。
镜像由三部分组成:
镜像名称:仓库名称+镜像分类+tag名称(镜像版本)
1.存储对象:images
2.格式:库名/分类:tag
3.tag:表示镜像版本
镜像的大体分类方式:这不是规定
1.以操作系统名字
centos的docker镜像:
centos5
centos6
centos7
-----------------
2.以应用的名字
nginx的docker镜像
tomcat的docker镜像
mysql的docker镜像
镜像名字:
完整镜像名称示例:
docker.io/library/nginx:v1
docker.io/library/nginx:latest
daocloud.io/library/nginx
镜像ID:
所有镜像都是通过一个 64 位十六进制字符串来标识的。 为简化使用,前 12 个字符可以组成一个短ID,一般我们看到的是12位的我们称之为短ID,只要我们每个ID号不冲突就可以了,可以在命令行中使用。
镜像本身:是由一层一层的镜像合在一起的,最底层的镜像我们称为基础镜像,在这个基础镜像的基础上还可以在做镜像,在做的镜像称为子镜像,对于子镜像来讲在谁的基础之上做的谁就是父镜像。 基础镜像:一个没有任何父镜像的镜像,谓之基础镜像。 centos7 镜像 centos7+nginx 镜像
Docker 容器
Docker 容器和文件夹很类似,一个Docker容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台,Docker 容器是 Docker 的运行部分。
docker镜像和容器的区别
一、Docker镜像
要理解Docker镜像和docker容器之间的区别,确实不容易。。
一个Docker镜像可以构建于另一个Docker镜像之上,这种层叠关系可以是多层的。第1层的镜像层我们称之为基础镜像(Base Image),其他层的镜像(除了最顶层)我们称之为父层镜像(Parent Image)。这些镜像继承了他们的父层镜像的所有属性和设置。
Docker镜像通过镜像ID进行识别。镜像ID是一个64字符的十六进制的字符串。但是当我们运行镜像时,通常我们不会使用镜像ID来引用镜像,而是使用镜像名来引用。
镜像可以发布为不同的版本,这种机制我们称之为标签(Tag)。
二、Docker容器
Docker容器可以使用命令创建:
docker run -it imagename /bin/bash
它会在所有的镜像层之上增加一个可写层。这个可写层有运行在CPU上的进程,而且有两个不同的状态:运行态(Running)和退出态 (Exited)。这就是Docker容器。当我们使用docker run启动容器,Docker容器就进入运行态,当我们停止Docker容器时,它就进入退出态。
当我们有一个正在运行的Docker容器时,从运行态到停止态,我们对它所做的一切变更都会永久地写到容器的文件系统中。要切记,对容器的变更是写入到容器的文件系统的,而不是写入到Docker镜像中的。我们可以用同一个镜像启动多个Docker容器,这些容器启动后都是活动的,彼此还是相互隔离的。我们对其中一个容器所做的变更只会局限于那个容器本身。如果对容器的底层镜像进行修改,那么当前正在运行的容器是不受影响的,不会发生自动更新现象。
名字空间--namespace
namespace 名字空间隔离
cgroup 资源限制
名字空间是 Linux 内核一个强大的特性。每个容器都有自己单独的名字空间,运行在其中的应用都像是在独立的操作系统中运行一样。名字空间保证了容器之间彼此互不影响。
Docker名称空间分类
- pid 名字空间--进程的隔离。不同用户的进程就是通过 pid 名字空间隔离开的,且不同名字空间中可以有相同 pid。所有的 LXC 进程在 Docker中的父进程为Docker进程,每个 LXC 进程具有不同的名字空间。同时由于允许嵌套,因此可以很方便的实现嵌套的 Docker 容器。
- net 名字空间 ----做网络接口隔离的。有 了 pid 名字空间, 每个名字空间中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net 名字空间实现的, 每个 net 名字空间有独立的 网络设备, IP 地址, 路由表, /proc/net 目录。这样每个容器的网络就能隔离开来。
- ipc 名字空间。容器中进程交互还是采用了 Linux 常见的进程间交互方法(interprocess communication - IPC), 包括信号、消息队列和共享内存、socket、管道等。
- mnt名字空间。专门处理每一个容器的目录,每一个容器里面都有相同的目录,这些名字都会重名。
- uts 名字空间。UTS("UNIX Time-sharing System") 名字空间允许每个容器拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非主机上的一个进程。--用来存放每一个容器的主机名和域名。
- user 名字空间。用来隔离每一个容器的用户和组的,你上面有,我上面也有。所以需要给他隔离。
面试题:
linux系统里面ipc通信有几种方式
socket套接字:网络进程间的通信
管道:本地进程间的通信:echo hello | grep e
信号: kill -9 PID 这种我们叫信号量级,也是本地进程间的通信
共享内存:每个操作系统里面共享内存多大,是物理内存的一半
消息队列
镜像管理
基础命令
搜索镜像
这种方法只能用于官方镜像库。搜索基于 centos 操作系统的镜像
docker search centos
按星级搜索镜像
查找 star 数至少为 100 的镜像:
docker search ubuntu -f stars=100
# -f:filter
拉取镜像
# docker pull centos
注:没有加registry,默认是从docker.io下载的
# docker pull daocloud.io/library/tomcat:7
# docker pull daocloud.io/library/centos:6
查看本地镜像
docker image list
或者
docker images
查看镜像详情
docker image inspect 镜像id
删除镜像
删除一个或多个,多个之间用空格隔开,可以使用镜像名称或id
docker rmi daocloud.io/library/mysql
或者
docker rmi 81debc
参数解释:
rm Remove one or more containers ---移除一个或多个容器
rmi Remove one or more images ---删除一个或多个镜像
强制删除:--force
如果镜像正在被使用中可以使用--force强制删除
# docker rmi docker.io/ubuntu:latest --force
-f, --force Force removal of the image
注意: 容器运行中不能删除,将容器停止后,删除容器在删除镜像。
只查看所有镜像的id:
docker images -q
# -q, --quiet
删除所有镜像:
docker rmi $(docker images -q)
查看镜像制作的过程
相当于dockfile
使用镜像名或者镜像ID都可以
docker history daocloud.io/library/nginx
容器管理
基础命令
创建新容器但不启动
docker create -it daocloud.io/library/centos:5 /bin/bash
创建并运行一个新Docker 容器
同一个镜像可以启动多个容器,每次执行run子命令都会运行一个全新的容器
docker run -itd --restart=always daocloud.io/library/centos:7 /bin/bash
#最常用
-i:标准输入输出,以交互模式运行容器
-t:分配一个伪输入终端或控制台
--restart=always:容器随docker engine自启动,因为在重启docker的时候默认容器都会被关闭
也适用于create选项
-d 后台运行容器,并返回容器ID;
如果执行成功,说明CentOS 容器已经被启动,并且应该已经得到了 bash 提示符。
--rm:默认情况下,每个容器在退出时是可以保存容器所产生的数据。但是当你仅仅需要短暂
的运行一个容器用于测试,并且这些数据不需要保存,当你退出容器之后,这个容器就不用了。
这个时候就需要--rm参数了。
注意:--rm 和 -d不能共用
容器名称
启动容器时,可以使用--name参数为容器分配一个自定义的名字。
如果不指定--name参数,Docker会自动为容器分配一个随机的名称。
# docker run -it --name 名字 daocloud.io/centos:6 /bin/bash #名字自定义# docker run -it --name tomcat_1 50fc2d0 /bin/bash #不加-d,exit会关闭容器
# 一般不加/bin/bash,就需要加-d。这时exit退出,容器不会关闭
# docker run -itd --name tomcat_2 50fc2d0
如果你在执行docker run时没有指定--name,那么自动生成一个随机字符串UUID。这个UUID标识是由Docker deamon生成的。但是对于一个容器来说有个name会非常方便,当你需要连接其它容器时或者类似需要区分其它容器时,使用容器名称可以简化操作。无论容器运行在前台或者后台,这个名字都是有效的。
rename ---修改容器名称
# docker rename命令来修改容器的名称
docker rename old_name new_name[root@yixuan ~]# docker rename mytest testmy
[root@yixuan ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
774c02898fb1 daocloud.io/library/nginx "/bin/bash -c 'while…" 5 minutes ago Up About a minute 80/tcp testmy
stats
断开连接并关闭容器
exit
断开连接而不关闭容器
快捷键:ctrl+p+q
查看容器
语法:docker ps [options]
[options]
-a 列出当前所有正在运行的容器+历史上运行过的
-l 显示最近创建的容器
-n 显示最近n个创建的容器
-q 静默模式,只显示容器编号
1. 列出运行状态的容器: # docker ps
2. -a 列出所有容器 # docker ps -a
3. 只查看所有容器id: # docker ps -a -q
查看容器详细信息
inspect :用于查看容器的配置信息,包含容器名、环境变量、运行命令、主机配置、网络配置和数据卷配置等。目标:查找某一个运行中容器的id,然后使用docker inspect命令查看容器的信息。提示:可以使用容器id的前面部分,不需要完整的id。
docker inspect 容器名
docker inspect 容器ID
启动容器
docker start name #容器ID也可以
这里的名字是状态里面NAMES列列出的名字,这种方式同样会让容器运行在后台
#启动所有容器
docker start $(docker ps -aq)
关闭容器
docker stop 容器ID或容器名
docker kill 容器ID或容器名 --强制终止容器
# 杀死所有running状态的容器
docker kill $(docker ps -q) stop和kill的区别
docker stop命令给容器中的进程发送SIGTERM信号,默认行为是会导致容器退出,当然,
容器内程序可以捕获该信号并自行处理,例如可以选择忽略。而docker kill则是给容器的进程发送
SIGKILL信号,该信号将会使容器必然退出。
删除容器
docker stop <容器ID或名称> # 先停止容器
docker rm <容器ID或名称> # 再删除容器
docker rm -f <容器ID或名称> #强制删除正在运行的容器,慎用,会直接终止容器的运行。
#删除所有已退出的容器
docker rm $(docker ps -qf status=exited)
docker ps -a -q | xargs docker rm
暂停容器进程
pause :暂停容器中所有的进程
unpause:恢复容器内暂停的进程,与pause对应
[root@yixuan ~]# docker pause c7
[root@yixuan ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3c0e0f43807d 98ebf73aba "/bin/bash" 7 minutes ago Up 7 minutes (Paused) 80/tcp c7
[root@yixuan ~]# docker unpause c7 #恢复
重启容器
docker restart name
让容器运行在后台
docker run -itd 镜像ID /bin/bash
-d后台运行必须要加-it
如果在docker run后面追加-d=true或者-d,那么容器将会运行在后台模式。此时所有I/O数据只能通过网络资源或者共享卷组来进行交互。因为容器不再监听你执行docker run的这个终端命令行窗口。但你可以通过执行docker attach来重新附着到该容器的会话中。
[root@yixuan ~]# docker attach 容器ID/容器名字
显示容器资源使用统计信息的实时流
docker stats
# 实时显示正在运行的容器的资源消耗情况,包括CPU使用率、内存使用量、网络I/O等。
连接容器(进入容器)
前提是容器在运行状态中
docker attach 命令用于附加到正在运行的容器的标准输入、输出和错误流。
前提是容器创建时必须指定了交互式shell。
docker attach 容器ID或名称可以将当前的终端连接到容器中,并与容器进行交互。docker exec 命令用于在正在运行的容器中执行命令。有两种任务类型可以创建:
1. 交互型任务:
docker exec -it 容器ID或名称 /bin/bash
# 可以进入并与容器进行交互,并在容器中执行命令。
2. 后台型任务:
docker exec 容器ID或名称 命令 # 在容器中执行指定的命令
# 不会与容器进行交互,只是在容器内部执行命令。
监控容器的运行
可以使用logs、top、wait这些子命令
使用docker logs命令查看容器的运行日志
--tail选项可以指定查看最后几条日志,使用-f选项可以跟踪日志的输出,直到手动停止。
[root@yixuan ~]# docker pull daocloud.io/library/nginx
[root@yixuan ~]# docker images
[root@yixuan ~]# docker run -it --name nginx1 98ebf73 /bin/bash
root@8459191dbe7c:/# /usr/sbin/nginx #启动nginx
ctrl+p+q --- 退出
[root@yixuan ~]# docker inspect nginx1 #找到ip地址
[root@yixuan ~]# curl -I http://172.17.0.3 #宿主机访问容器可以访问成功
HTTP/1.1 200 OK
Server: nginx/1.17.1
Date: Mon, 09 Mar 2020 14:49:40 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 25 Jun 2019 12:19:45 GMT
Connection: keep-alive
ETag: "5d121161-264"
Accept-Ranges: bytes
[root@yixuan ~]# curl -I http://172.17.0.3 #继续测试访问
在开启一个终端:
[root@yixuan ~]# docker logs -f nginx1 #动态查看容器日志
root@8459191dbe7c:/# /usr/sbin/nginx
root@8459191dbe7c:/# 172.17.0.1 - - [09/Mar/2020:14:49:33 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
172.17.0.1 - - [09/Mar/2020:14:49:40 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
# docker logs --tail=2 App_Conainer 查看倒数2行的容器日志
top:显示一个运行的容器里面的进程信息
[root@yixuan ~]# docker top nginx #容器ID也可以
wait :--捕捉容器停止时的退出码
执行此命令后,该命令会"hang"在当前终端,直到容器停止,此时,会打印出容器的退出码
在第一个终端执行停止容器命令
[root@yixuan ~]# docker stop nginx1
===============================
[root@yixuan ~]# docker wait 01d8aa #第二个终端操作
0
docker run 之后容器退出的状态码:
0,表示正常退出
非0,表示异常退出
宿主机和容器之间相互COPY文件
cp的用法如下:
docker cp CONTAINER:PATH LOCALPATH --从容器拷贝到本机
docker cp LOCALPATH CONTAINER:PATH --从本机拷贝到容器
如:容器nginx中/usr/local/bin/存在test.sh文件,可如下方式copy到宿主机
[root@yixuan ~]# docker exec -it nginx /bin/bash
root@2a9a18b4a485:/# cd /usr/local/bin/
root@2a9a18b4a485:/usr/local/bin# touch test.sh
ctrl+p+q 退出
[root@yixuan ~]# docker cp mytest:/usr/local/bin/test.sh /root/
修改完毕后,将该文件重新copy回容器
[root@yixuan ~]# ls
anaconda-ks.cfg test.sh
[root@yixuan ~]# echo "123" >> test.sh
[root@yixuan ~]# docker cp /root/test.sh mytest:/usr/local/bin/
docker容器镜像制作
一、容器文件系统打包
制作个人的镜像需要的步骤:
1.先有一个基础镜像,下载------>2.把镜像运行起来----->3.进入容器做你的修改-------4.将这个容器打包成一个新镜像。
将容器的文件系统打包成tar文件,也就是把正在运行的容器直接导出为tar包的镜像文件
export
有两种方式:
第一种:在运行容器内导出为tar包,把容器做成镜像
[root@yixuan ~]# docker ps #运行一个容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
96e2b7265d93 daocloud.io/library/centos:6 "/bin/bash" About an hour ago Up About an hour c6
[root@yixuan ~]# docker exec -it c6 /bin/bash
[root@96e2b7265d93 /]# vi a.txt #编辑一个文件
123
[root@96e2b7265d93 /]# yum install -y vim wget #安装一个软件
[root@yixuan ~]# docker export -o centos6-1.tar 96e2b726 #容器ID
-o, --output
[root@yixuan ~]# ls #保存到当前目录下
anaconda-ks.cfg centos6-1.tar
第二种:在宿主机上将指定容器导出为镜像
[root@yixuan ~]# docker export 容器名称 > 镜像.tar
导入镜像归档文件到其他宿主机:
import
[root@yixuan ~]# docker import centos6-1.tar centos6-1:v1 # 自定义名字和版本sha256:b8414448c913259a28d623643a7b67a6c13da9b3259e70ee5febb16c2b0b1095[root@yixuan ~]# docker images[root@yixuan ~]# docker run -it --name c6.1 centos6-1:v1 /bin/bash
[root@4a29d58d3bd2 /]# ls
a.txt bin dev etc home lib lib64 lost+found media mnt opt proc root sbin selinux srv sys tmp usr var
[root@4a29d58d3bd2 /]# cat a.txt
123123
二、通过容器创建本地镜像
背景:容器运行起来后,又在里面做了一些操作,并且要把操作结果保存到镜像里
方案:使用 docker commit 指令,把一个正在运行的容器,直接提交为一个镜像。
commit 是提交的意思,类似告诉svn服务器我要生成一个新的版本。
例子:
在容器内部新建了一个文件
[root@yixuan ~]# docker run -it --name c7 daocloud.io/library/centos:7 /bin/bash
[root@2e8f79cb5922 /]# touch test.txt
将这个新建的文件提交到镜像中保存
[root@yixuan ~]# docker commit 2e8f79cb5922 soso/test:v2
sha256:2214bad66e9b1c2079dc89a2e14e997604237cd49a6dc6c29d84e915fbbeb5bd
[root@yixuan ~]# docker images
也可以这样例子:
# docker commit -m "my images version1" -a "soso" 108a85b1ed99 daocloud.io/ubuntu:v2
sha256:ffa8a185ee526a9b0d8772740231448a25855031f25c61c1b63077220469b057
-m 添加注释
-a 作者
108a85b1ed99 容器环境id
daocloud.io/ubuntu:v2 镜像名称:hub的名称/镜像名称:tag
-p,–pause=true 提交时暂停容器运行
镜像迁移
保存一台宿主机上的镜像为tar文件,然后可以导入到其他的宿主机上:
save打包
将镜像打包,与下面的load命令相对应
语法:docker save -o xxx.tar 容器名
[root@yixuan ~]# docker save -o nginx.tar daocloud.io/library/nginx
load导入
与上面的save命令相对应,将上面sava命令打包的镜像通过load命令导入,(实验环境中原来机器上面有镜像可以先删除掉。)
语法:docker load < xxx.tar
[root@yixuan ~]# docker load < nginx.tar
[root@yixuan ~]# docker images
#把容器导出成tar包 export import
#把容器做成镜像 commit -a "" -m ""
#把镜像保存为tar包 save load
部署私有仓库应用
私有仓库镜像:
registry --官方出品, 没有图形界面.Docker hub官方已提供容器镜像registry,用于搭建私有仓库
拉取镜像
docker pull daocloud.io/library/registry:latest
docker images #查看拉取的镜像
#在daemon.json文件中添加私有镜像仓库地址
vim /etc/docker/daemon.json
{"insecure-registries":["http://192.168.145.15:5000"], #添加,注意用逗号结尾"registry-mirrors":["https://00ub0bmk.mirror.aliyuncs.com"]
}#添加完记得重启
systemctl restart docker
#若重启docker,容器状态不全是up状态,可以执行docker-compose restart
systemctl status docker
目录映射
运行容器:会自动创建
docker run -d -v /home/dockerdata/registry:/var/lib/registry --name "pri_registry" --restart=always -p 5000:5000 daocloud.io/library/registry
参数解释:
/home/dockerdata/registry表示为宿主机的目录,如果不存在自动创建
-v 目录映射(容器卷) 宿主机的目录:容器目录
把宿主机的目录挂载到容器中,将数据目录挂载出来就是为了防止docker私有仓库这个容器
被删除的时候,仓库里面的镜像也被删除。
-p 端口映射:本地端口:容器端口 (容器端口固定,本地端口可以自定义)
注:如果创建容器不成功,报错防火墙,解决方案如下
#systemctl stop firewalld
#yum install iptaqbles*
#systemctl start iptables
#iptables -F
#systemctl restart docker
[root@yixuan ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0823df72b160 daocloud.io/library/registry "/entrypoint.sh /etc…" About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp pri_registry
连接容器查看端口状态
[root@yixuan ~]# docker exec -it 0823df7 /bin/sh# 注意这里未安装 bash,需要使用/bin/sh
/ # netstat -lntp #查看5000端口是否开启
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::5000 :::* LISTEN 1/registry
/ #
测试
在本机查看能否访问该私有仓库, 看看状态码是不是200
[root@yixuan ~]# curl -I http://127.0.0.1:5000
HTTP/1.1 200 OK
为了测试,下载1个比较小的镜像buysbox:
docker pull daocloud.io/library/busybox上传前必须给镜像打tag 注明ip和端口:
docker tag daocloud.io/library/busybox 192.168.157.141:5000/busybox下面这个Mysql是测试的第二个镜像,从daocloud拉取的:
docker pull daocloud.io/library/mysql
docker tag daocloud.io/library/mysql 192.168.157.141:5000/daocloud.io/library/mysql
docker images注:tag后面可以使用镜像名称也可以使用id,我这里使用的镜像名称,如果使用官方的镜像,
不需要加前缀,但是daocloud.io的得加前缀。
客户端修改请求方式为http
默认为https,不改会报以下错误:
Get https://master.up.com:5000/v1/_ping: http: server gave HTTP response to HTTPS client
[root@yixuan ~]# vim /etc/docker/daemon.json #不存在则创建
{ "insecure-registries":["192.168.246.141:5000"] }
重启docker:
[root@yixuan ~]# systemctl daemon-reload
[root@yixuan ~]# systemctl restart docker
上传镜像到私有仓库
[root@yixuan ~]# docker push 192.168.157.141:5000/busybox
[root@yixuan ~]# docker push 192.168.157.141:5000/daocloud.io/library/mysql
宿主机查看存放镜像目录
ls /home/dockerdata/registry/docker/registry/v2/repositories/
查看私有仓库里的所有镜像
语法: # curl http://ip:port/v2/repo名字/tags/list~]# curl http://192.168.157.141:5000/v2/busybox/tags/list
{"name":"busybox","tags":["latest"]}~]# curl http://192.168.157.141:5000/v2/daocloud.io/library/mysql/tags/list
{"name":"daocloud.io/library/mysql","tags":["latest"]} 这条命令会查看仓库下面所有的镜像:
~]# curl http://192.168.157.141:5000/v2/_catalog
{"repositories":["busybox","daocloud.io/library/mysql","mysql"]}
拉取镜像测试:
1.先将刚才打了tags的镜像删掉
[root@yixuan ~]# docker rmi 192.168.157.141:5000/busybox
2.拉取镜像:
[root@yixuan ~]# docker pull 192.168.157.141:5000/busybox
[root@yixuan ~]# docker images
部署docker web ui应用
下载并运行容器:
docker pull uifd/ui-for-docker #拉取
docker run -it -d --name docker-web -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock docker.io/uifd/ui-for-docker# 如果本地有压缩包,可以本地上传
docker load < web-ui.tar
docker run -itd --name docker-web -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock 965940f98fa5
浏览器访问测试
http://192.168.157.141:9000/
容器管理
镜像下载
部署私有仓库harbor
[root@harbor ~]# wget https://storage.googleapis.com/harbor-releases/release-1.8.0/harbor-offline-installer-v1.8.0.tgz
下载docker-compose
[root@harbor ~]# curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
或者本地上传
[root@harbor ~]# rz -y
[root@harbor ~]# cp docker-compose-Linux-x86_64 /usr/bin/docker-compose
[root@harbor ~]# chmod +x /usr/local/bin/docker-compose
http访问方式的配置:
[root@kub-k8s-master harbor]# vim harbor.yml #使用IP地址,需要修改的内容如下
hostname: 192.168.157.129 #改成自己的ip
解压harbor仓库
[root@harbor ~]# tar xf harbor-offline-installer-v1.8.0.tgz
[root@harbor ~]# vim load .sh
#!/bin/bash
cd /root/myharbor
for i in `ls /root/myharbor`
do#echo $idocker load < $i
done
[root@harbor ~]# sh load.sh
[root@kub-k8s-master ~]# cd harbor
[root@kub-k8s-master harbor]# ./install.sh #需要等待下载镜像
可以看到
docker-compose 使用
[root@harbor harbor]# docker-compose down #停止服务
[root@harbor harbor]# docker-compose up -d #放后台
浏览器访问测试:
http://192.168.157.129
然后在界面新建项目
客户端配置连接仓库地址
[root@docker-server ~]# vim /etc/docker/daemon.json
{
"insecure-registries": ["192.168.157.141"] #仓库的ip地址,配置http方式连接
}
[root@docker-server ~]# systemctl daemon-reload
[root@docker-server ~]# systemctl restart docker
[root@harbor harbor]#docker-compose up -d #启动harbor仓库
登陆仓库
#可以指定用户名
[root@docker-server ~]# docker login -u admin 192.168.157.129
#也可以不指定
[root@docker-server ~]# docker login 192.168.157.129
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
将生成的jspgou镜像上传到仓库中
[root@harbor harbor]# docker tag test/jspgou:1.1 192.168.157.129/pm-server/jspgou:1.1
[root@harbor harbor]# docker push 192.168.157.129/pm-server/jspgou:1.1
登陆仓库界面查看
通过Dockerfile创建镜像
Docker 提供了一种更便捷的方式,叫作 Dockerfile,Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
docker build命令用于根据给定的Dockerfile构建Docker镜像。
docker build语法
docker build [OPTIONS] <PATH | URL | ->
1. 常用选项说明
--build-arg,设置构建时的变量
--no-cache,默认false。设置该选项,将不使用Build Cache构建镜像
--pull,默认false。设置该选项,总是尝试pull镜像的最新版本
--compress,默认false。设置该选项,将使用gzip压缩构建的上下文
--disable-content-trust,默认true。设置该选项,将对镜像进行验证
--file, -f,Dockerfile的完整路径,默认值为‘PATH/Dockerfile’
--isolation,默认--isolation="default",即Linux命名空间;其他还有process或hyperv
--label,为生成的镜像设置metadata
--squash,默认false。设置该选项,将新构建出的多个层压缩为一个新层,但是将无法在多个镜像之间共享新层;设置该选项,实际上是创建了新image,同时保留原有image。
--tag, -t,镜像的名字及tag,通常name:tag或者name格式;可以在一次构建中为一个镜像设置多个tag
--network,默认default。设置该选项,Set the networking mode for the RUN instructions during build
--quiet, -q ,默认false。设置该选项,Suppress the build output and print image ID on success
--force-rm,默认false。设置该选项,总是删除掉中间环节的容器
--rm,默认--rm=true,即整个构建过程成功后删除中间环节的容器
示例:
docker build -t soso/nginx:v2.1 .
docker build 是docker创建镜像的命令
-t 是标识新建的镜像属于soso的nginx镜像
:v2.1 是tag
"."是用来指明 我们使用的Dockerfile文件当前目录
2.1、 创建镜像所在的文件夹和Dockerfile文件
[root@yixuan ~]# mkdir sinatra
[root@yixuan ~]# cd sinatra/
[root@yixuan sinatra]# touch Dockerfile
2.2、 在Dockerfile文件中写入指令
每一条指令都会更新镜像的信息
[root@yixuan sinatra]# vim Dockerfile
#This is a comment
FROM daocloud.io/library/centos:7
MAINTAINER soso soso@yixuan
RUN touch a.txt
RUN mkdir /test
格式说明:
指令要大写,"#"是注解。
每一个指令后面需要跟空格
FROM 命令是告诉docker 我们的镜像什么从哪里下载。一般选择比较小的系统镜像
MAINTAINER 是描述 镜像的创建人。
RUN 命令是在镜像内部执行的命令。
2.3、创建镜像
命令:注意此时在Dockerfile目录
[root@yixuan sinatra]# docker build -t soso/centso:7 .
docker build 是docker创建镜像的命令
打的tag一般就是私有仓库的地址和版本
.或者Dockerfile的目录
详细执行过程:
[root@yixuan sinatra]# docker build -t soso/centos:7 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM daocloud.io/library/centos
latest: Pulling from library/centos
d8d02d457314: Pull complete
Digest: sha256:a36b9e68613d07eec4ef553da84d0012a5ca5ae4a830cf825bb68b929475c869
Status: Downloaded newer image for daocloud.io/library/centos:latest---> 67fa590cfc1c
Step 2/4 : MAINTAINER soso soso@yixuan---> Running in aab3d80939d8
Removing intermediate container aab3d80939d8---> 12bae7d75a23
....
2.4、创建完成后,从镜像创建容器
Dockerfile实例:容器化python的flask应用
目标: 用 Docker 部署一个用 Python 编写的 Web 应用。
首先部署整个流程:
基础镜像(python)-->flask-->部署python应用----->打包成镜像
web框架 flask django
代码功能:
如果当前环境中有"NAME"这个环境变量,就把它打印在"Hello"后,否则就打印"Hello world",最后再打印出当前环境的 hostname。
[root@yixuan ~]# mkdir python_app
[root@yixuan ~]# cd python_app/
[root@yixuan python_ app]# vim app.py
from flask import Flask
import socket
import os
app = Flask(__name__)
@app.route('/')
def hello():html = "<h3>Hello {name}!</h3>" \"<b>Hostname:</b> {hostname}<br/>"return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())
if __name__ == "__main__":app.run(host='0.0.0.0', port=80)
应用依赖:
定义在同目录下的 requirements.txt 文件里,内容如下:
[root@yixuan python_app]# vim requirements.txt
Flask
Dockerfile制作容器镜像:
# vim Dockerfile
FROM daocloud.io/library/python:2.7-slim
WORKDIR /app
ADD . /app
RUN pip install --trusted-host pypi.python.org -r requirements.txt
EXPOSE 80
ENV NAME World
CMD ["python", "app.py"]
Dockerfile文件说明:
FROM python:2.7-slim
# 使用官方提供的 Python 开发镜像作为基础镜像
# 指定"python:2.7-slim"这个官方维护的基础镜像,从而免去安装 Python 等语言环境的操作。
WORKDIR /app ---cd /app
# 将工作目录切换为 /app,意思是在这一句之后,Dockerfile 后面的操作都以这一句指定的 /app 目录作为当前目录。
ADD . /app
# 将当前目录下的所有内容复制到 /app 下 Dockerfile 里的原语并不都是指对容器内部的操作。比如 ADD,指的是把当前目录(即 Dockerfile 所在的目录)里的文件,复制到指定容器内的目录当中。
COPY ./a.txt /app
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# 使用 pip 命令安装这个应用所需要的依赖
EXPOSE 80 # 允许外界访问容器的 80 端口
ENV NAME World # 设置环境变量
VOLUME ["/data"]
# 定义匿名数据卷挂载点。通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,而是自动生成的。需要通过inspect去查看对应宿主机上面的目录。
CMD ["python", "app.py"]
# CMD给出的是一个容器启动以后,默认的容器启动后的执行命令。
这里命令为 python app.py
app.py的实际路径是 /app/app.py。CMD ["python", "app.py"]
等价于 "docker run python app.py"。
现在目录结构
[root@yixuan python_app]# ls
Dockerfile app.py requirements.txt
构建镜像:
[root@yixuan python_app]# docker build -t testpython .
-t 给这个镜像加一个 Tag
Dockerfile 中的每个原语执行后,都会生成一个对应的镜像层。即使原语本身并没有明显地修改文件的操作(比如,ENV 原语),它对应的层也会存在。只不过在外界看来,这个层是空的。
查看结果:
[root@yixuan python_app]# docker images
REPOSITORY TAG IMAGE ID ...
testpython latest 16bc21f3eea3
启动容器:
[root@yixuan python_app]# docker run -itd -p 4000:80 testpython
-p 端口映射:本地端口:容器端口
查看容器:
[root@yixuan python_app]# docker ps
CONTAINER ID IMAGE COMMAND CREATED
ce02568e64ce testpython "python app.py" About a minute ago
访问容器内应用:
[root@yixuan ~]# curl http://localhost:4000
<h3>Hello World!</h3><b>Hostname:</b> f201f6855136<br/>
实战练习
1.创建一个jenkins的Dockerfile
[root@yixuan ~]# mkdir tomcat
[root@yixuan ~]# cd tomcat/
[root@yixuan tomcat]# vim Dockerfile
# This my first jenkins Dockerfile
# Version 1.0
FROM daocloud.io/library/centos:7
MAINTAINER yixuan
ENV JAVA_HOME /usr/local/jdk1.8.0_211
ENV PATH=$JAVA_HOME/bin:$PATH
ENV TOMCAT_HOME /usr/local/apache-tomcat-8.5.47
#老版本的配置方式:
#ENV PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
#ENV CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jarADD apache-tomcat-8.5.47.tar.gz /usr/local/
ADD jdk-8u211-linux-x64.tar.gz /usr/local/
RUN rm -rf /usr/local/apache-tomcat-8.5.47/webapps/*
ADD jenkins.war /usr/local/apache-tomcat-8.5.47/webapps
RUN rm -rf apache-tomcat-8.5.47.tar.gz apache-tomcat-8.5.47.tar.gz
EXPOSE 8080
ENTRYPOINT ["/usr/local/apache-tomcat-8.5.47/bin/catalina.sh","run"] #运行的命令
[root@yixuan tomcat]# pwd
/root/tomcat
[root@yixuan tomcat]# ls #将jdk与tomcat还有jenkins的包上传到tomcat目录中
apache-tomcat-8.5.47.tar.gz Dockerfile jdk-8u211-linux-x64.tar.gz jenkins.war
[root@yixuan tomcat]# docker build -t jenkins:v1 .
[root@yixuan tomcat]# docker run -itd --name jenkins1 -p 8081:8080 jenkins:v1
扩展----CMD与ENTRYPOINT区别
一、dockerfile中的 CMD
1、每个dockerfile中只能有一个CMD,如果有多个那么只执行最后一个。
2、CMD 相当于启动docker时候后面添加的参数看,举个简单例子:
# docker run -itd --name test image(镜像) /bin/bash -c
a、镜像名称后面跟了一个/bin/bash -c ,其实等价于在dockerfile中的CMD ["/bin/bash","-c"]。
b、如果dockerfile中的CMD中有了CMD["/bin/bash","-c"],那么就不用在执行的时候再添加了,
如果添加了参数的话那么就相当于要执行你添加的参数,默认的CMD中的参数就无效了。
二、dockerfile中的ENTRYPOINT
1、一个dockerfile中ENTRYPOINT也只能存在一个,若存在多个那么只执行最后一个,你可以理解
为开机启动的意思,和CMD有点像,不过还是有区别。
2、举个简单例子:
a、dockerfile中有ENTRYPOINT ["tail","-f","/var/log/nginx/access.log"],那么启动的
时候镜像就执行了这个里面的内容,如果你像上面带参数的话就相当于在这个执行的内容后面再加入参数。
案例:
如果我们的dockerfile中有a中的这句话然后我们启动我们的docker:
#docker run -itd --name test image(镜像名) /bin/bash -c
此时就相当于我们启动docker的时候执行了:
tail -f /var/log/nginx/access.log /bin/bash -c
这个命令明显就不对.
dockerfile优化
编译一个简单的nginx成功以后发现好几百M。
1、RUN 命令要尽量写在一条里,每次 RUN 命令都是在之前的镜像上封装,只会增大不会减小
2、每次进行依赖安装后,记得yum clean all【centos】 # yum clean all 清除缓存
3、选择比较小的基础镜像。Alpine Linux
Alpine linux系统:
1、小巧:和busybox一样小巧,最小的Docker镜像只有5MB;
2、简单:软件的搜索、安装、删除、升级都非常方便。
3、适合容器使用:由于小巧、功能完备,非常适合作为容器的基础镜像。
编写带有中文环境的centos7系统镜像
现在从公共仓库下载下来的ceonos7镜像默认是没有中文字符的,有时候由于业务时需要支持中文的。所以我们需要先构建一个带有中文的centos7镜像,在将该镜像作为基础镜像去使用。
编写带有中文包的基础镜像
[root@iZ8vb3lp570ckxi53yb66gZ ~]# cat Dockerfile
FROM daocloud.io/library/centos:7
# 基于官方centos7精简版基础镜像,添加中文支持
# 替换yum源
#COPY CentOS-Base.repo /etc/yum.repos.d/
# 更新软件
RUN yum -y upgrade
# 安装中文包
RUN yum install -y kde-l10n-Chinese
# 重新安装glibc-common
RUN yum -y reinstall glibc-common
# 编译生成语言库
RUN localedef -c -f UTF-8 -i zh_CN zh_CN.utf8
# 设置语言默认值为中文,时区改为东八区
RUN echo 'LANG="zh_CN.UTF-8"' > /etc/locale.conf
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
ENV LANG zh_CN.UTF-8
ENV LC_ALL zh_CN.UTF-8
[root@iZ8vb3lp570ckxi53yb66gZ ~]# docker build -t my/c7:1.1 .
端口转发
使用端口转发解决容器端口访问问题
-p
-p:创建应用容器的时候,一般会做端口映射,这样是为了让外部能够访问这些容器里的应用。
可以用多个-p指定多个端口映射关系。
mysql应用端口转发:
查看本地地址:
[root@yixuan ~]# ip a
...
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000link/ether 00:0c:29:9c:bf:66 brd ff:ff:ff:ff:ff:ffinet 192.168.246.141/24 brd 192.168.246.255 scope global dynamic ens33valid_lft 5217593sec preferred_lft 5217593secinet6 fe80::a541:d470:4d9a:bc29/64 scope link valid_lft forever preferred_lft forever
运行容器:使用-p作端口转发,把本地3307转发到容器的3306,其他参数需要查看发布容器的页面提示
[root@yixuan ~]# docker pull daocloud.io/library/mysql:5.7
[root@yixuan ~]# docker run -itd --name mysql1 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=Qf@123! daocloud.io/library/mysql:5.7
a4327dbddf665b4302c549320bff869b8a027c2e1eead363d84ce5d06acf2698
-e MYSQL_ROOT_PASSWORD= 设置root密码。
-e MYSQL_DATABASE= 设置要创建的库
通过本地IP:192.168.246.141的3307端口访问容器mysql1内的数据库,出现如下提示恭喜你
1.安装一个mysql客户端
[root@yixuan ~]# yum install -y mysql
2.登录
[root@yixuan ~]# mysql -uroot -p'Qf@123!' -h 192.168.246.141 -P3307
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.26 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
-P(大P)
当使用-P标记时,Docker 会随机映射一个 32768~49900 的端口到内部容器开放
的网络端口,无需手动指定端口。
[root@yixuan ~]# docker pull daocloud.io/library/redis
[root@yixuan ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/library/redis latest 598a6f110d01 2months ago 118MB
[root@yixuan ~]# docker run --name myredis -P -d daocloud.io/library/redis
ca06a026d84a0605d9a9ce6975389a79f4ab9a9a043a03f088cd909c1fe52e29
[root@yixuan ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ca06a026d84a daocloud.io/library/redis "docker-entrypoint.s…" 22 seconds ago Up 21 seconds 0.0.0.0:32768->6379/tcp myredis
从上面的结果中可以看出,本地主机的32768端口被映射到了redis容器的6379端口上,也就是说访问本机的32768端口即可访问容器内redis端口。
在别的机器上通过上面映射的端口32768连接这个容器的redis
[root@docker-server2 ~]# yum install -y redis
[root@docker-server2 ~]# redis-cli -h 192.168.246.141 -p 32768
192.168.246.141:32768> ping
PONG
192.168.246.141:32768>
容器卷
把本地宿主机上面的某一个目录挂载到容器里面的目录去。这两个目录都不用提前存在,会自动创建 本质上是一个目录挂载,将容器内的目录挂载到虚拟机上
新卷只能在容器创建过程当中挂载
[root@yixuan ~]# docker run -it --name testnginx -v /test:/test2 daocloud.io/library/nginx /bin/bash
root@86320e734cd1:/# ls
root@86320e734cd1:/# ctrl+p+q #退出
测试:
[root@yixuan ~]# cd /test/
[root@yixuan test]# ls
[root@yixuan test]# touch a.txt
[root@yixuan test]# cd
[root@yixuan ~]# docker exec -it testnginx /bin/bash
root@86320e734cd1:/# cd test2/
root@86320e734cd1:/test2# ls
a.txt
共享文件:
[root@yixuan ~]# mkdir /dir
[root@yixuan ~]# vim /dir/a.txt
123
[root@yixuan ~]# docker run -it --name testnginx2 -v /dir/a.txt:/dir1/a.txt daocloud.io/library/nginx /bin/bash
root@f899be627552:/# cat dir1/a.txt
123
root@f899be627552:/#
共享其他容器的卷(与其他容器用同一个卷):
[root@yixuan ~]# docker run -it --name testnginx1 --volumes-from testnginx daocloud.io/library/nginx /bin/bash
root@50e6f726335c:/# ls
bin dev home lib64 mnt proc run srv test2 usr
boot etc lib media opt root sbin sys tmp var
root@50e6f726335c:/# cd test2/
root@50e6f726335c:/test2# ls
a.txt
实际应用中可以利用多个-v选项把宿主机上的多个目录同时共享给新建容器:
比如:
# docker run -it -v /abc:/abc -v /def:/def 1ae9
#当前目录$PWD
# docker run -it --name testnginx4 -v $PWD:/test3 -v /abc:/abc daocloud.io/library/nginx /bin/bash
docker数据存储位置
查看存储路径
[root@yixuan ~]# docker info | grep RootDocker Root Dir: /var/lib/docker修改默认存储位置:
在dockerd的启动命令后面追加--data-root参数指定新的位置
[root@yixuan ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --data-root=/data
[root@yixuan ~]# systemctl daemon-reload
[root@yixuan ~]# systemctl restart docker
查看是否生效:
[root@yixuan ~]# docker info | grep RootDocker Root Dir: /data
Docker --link实现容器互联
1.1、容器间通过IP进行网络访问
1.2、容器间通过容器名或容器id进行网络访问
容器互联
--link可以通过容器名互相通信,容器间共享环境变量。
--link主要用来解决两个容器通过ip地址连接时容器ip地址会变的问题.
语法:
--link 源容器名:连接别名 #连接别名可以和容器名一致,也可以不指定先创建mysql容器
[root@docker-server ~]# docker run -dti --name db-server --restart=always -e MYSQL_ROOT_PASSWORD=QianFeng@123! -e MYSQL_DATABASE=blog mysql:5.7在创建wordpress容器
[root@docker-server ~]# docker run -dti --name blog --restart=always -v /web:/var/www/html -p 80:80 --link db-server:mysql wordpress--link db:mysql:将容器与另一个名为db-server的容器连接起来,并设置别名为 mysql,以便在后续操作中引用该容器。
docker网络
容器网络分类
注:
面试用,用了编排之后就没有用了
查看当前网络:
[root@yixuan ~]# docker network list NETWORK ID NAME DRIVER SCOPE 9b902ee3eafb bridge bridge local 140a9ff4bb94 host host local d1210426b3b0 none null local
docker安装后,默认会创建三种网络类型,bridge、host和none
1、bridge:网络桥接
默认情况下启动、创建容器都是用该模式,所以每次docker容器重启时会按照顺序获取对应ip地址。
2、none:无指定网络
启动容器时,可以通过--network=none,docker容器不会分配局域网ip
3、host:主机网络
docker容器和主机共用一个ip地址。使用host网络创建容器: [root@yixuan ~]# docker run -it --name testnginx2 --net host 98ebf73ab [root@yixuan ~]# netstat -lntp | grep 80 tcp6 0 0 :::80 :::* LISTEN 3237/docker-proxy 浏览器访问宿主ip地址
4、固定ip:
创建固定Ip的容器:
4.1、创建自定义网络类型,并且指定网段
[root@yixuan ~]# docker network create --subnet=192.168.0.0/24 staticnet
4efd309244c6ad70eda2d047a818a3aec5b162f5ca29fb6024c09a5efbf15854通过docker network ls可以查看到网络类型中多了一个staticnet:
[root@yixuan ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
9b902ee3eafb bridge bridge local
140a9ff4bb94 host host local
d1210426b3b0 none null local
4efd309244c6 staticnet bridge local
4.2、使用新的网络类型创建并启动容器[root@yixuan ~]# docker run -itd --name userserver --net staticnet --ip 192.168.0.2 daocloud.io/library/centos:7通过docker inspect可以查看容器ip为192.168.0.2:[root@yixuan ~]# docker inspect userserver | grep -i ipaddress"SecondaryIPAddresses": null,"IPAddress": "","IPAddress": "192.168.0.2",关闭容器并重启,发现容器ip并未发生改变