docker
底层技术是用的linux LXC容器技术。
为什么使用docker?
- 更高效的利用系统资源
- 更快的启动时间
- 一致的运行环境
- 持续交付和部署
- 更轻松的迁移
- 更轻松的维护和扩展
容器和虚拟机比较
1.docker三个概念
-
image 镜像
提供容器所需要使用到的资源,就相当于模板
-
仓库
仓库使Docker 用来集中存放镜像文件的地方,类似于我们之前常用的代码仓库
-
容器
容器就镜像·运行的实体,容器可以被创建、启动、停止、删除、暂停等。
docker | 面向对象 |
---|---|
镜像 | 类 |
容器 | 对象 |
2.镜像分层
假如有三个服务分别为nginx redis es 他们三个包中都有一个简化版的linux 。如果每个包都有linux,那么久会同时运行三个linux,就会产生冗余。
镜像分层就是,这几个服务共用一个简化版的linux,假如nginx,redis都需要用到c++的开发环境,那就会在Linux上多加一层,c++的开发环境,使他们共用,假如还有其他依赖,那么就会在分层。
2.1当容器启动时,一个新的可写层被加载到镜像的顶部。这一层就叫容器层,容器层之下的都叫镜像层。
Volume数据卷
宿主机的目录映射到容器中的目录,应用程序在容器汇中的目录读写数据会同步到宿主机上,这样容器产生的数据久可以持久化了,比如我们的数据库容器,就可以把数据存储到我们宿主机上的真实磁盘中。
注册中心
docker用
registry来保存 用户的镜像,registry有公共1和私有两种。
选择镜像原则,优先选择官方镜像,没有官方镜像,就是使用是星多的。
安装docker
配置docker需要的配置环境
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.re
yum-config-manager --enable docker-ce-nightly
安装docker
yum install docker-ce docker-ce-cli containerd.io ##检查一下密钥是不是060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35 如果不是则东西被篡改了
启动docker
systemctl start docker
查看docker版本
docker --version
Docker version 20.10.6, build 370c289
测试docker
docker run hello-world
查看docker容器的运行状态和简要信息
docker stats
docker info
查看容器详细信息
docker inspect [容器ID | 容器名]
配置docker加速
[root@master ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
镜像是什么:
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
联合文件系统UnionFS:
是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改,作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。union文件系统时Docker镜像的基础。镜像可以通过分层来进行继承、基于基础镜像(没有父镜像)、可以制作各种具体的应用镜像
特性:
一次同时加载多个文件系统、但是从外面看起来、只能看到一个文件系统、联合加载会把各层文件系统叠加起来,这样最终文件系统会包含所有底层和文件和目录
Docker镜像加载原理:
bootfs主要包含bootloader 和 kernel,boot loader 主要时引导加载kernel,linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs,在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同操作系统发行版。
对于一个精简的OS rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为最底层用Host和Kernal,自己只需要提供rootfs就行了。由此可见对于不同的linux发行班,bootfs基本是一致的,rootfs会有差别,因此不同的发现版可以共用bootfs。
docker镜像特点
只读,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作容器层。“容器层”指下的都叫"镜像层"。
多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份basw镜像,同时内存中也只需加载一份base镜像,就可以为所有同期服务了
搜索镜像
docker search centos
获取镜像,加入我们这里获取一个centos的镜像
docker pull centos
docker pull centos:lastest ##最新版本
docker pull centos:[版本号]
docker run的运行过程
docker run hello-world
Unable to find image 'hello-world:latest' locally ##提示本地找不到镜像
latest: Pulling from library/hello-world ##拉最新的镜像
b8dfde127a29: Pull complete
Digest: sha256:5122f6204b6a3596e048758cabba3c46b1c937a46b5be6225b835d091b90e46c
Status: Downloaded newer image for hello-world:latest ##拉取
Hello from Docker!
查看镜像
docker images
删除镜像
docker rmi centos
搜索镜像
docker search nginx
导出镜像
docker save -o centos.tar centos
docker save > centos.tar centos
导入镜像
docker load < centos.tar
docker load -i centos.tar
client客户端
容器相关命令
启动容器
docker run nginx ##这里会直接卡住
查看容器
docker ps ##查看运行的容器
docker ps -a ##查看所有容器
docker ps -l ##最后一次运行的容器
docker ps -f status=[状态] ##查看对应容器
docker ps -n ##查看几个
- -i 标识运行容器
- -t 标识启动容器后进入命令行
- -v 标识目录映射关系
- -d 后台
- -p 指定映射端口
- -P 随机映射端口
创建启动容器并进入
docker run --name mynginx -p 80:8080 nginx ##指定端口映射
docker run --name mynginx -P nginx ##随机映射
创建启动容器不进入
docker run -d --name mynginx -p 80:8080 nginx ##守护模式创建容器
进入守护进程容器
docker exec -it [容器ID | 容器名] /bin/bash
创建容器并进入容器
docker run -d --name mycentos centos /bin/bash
退出容器
exit
停止启动容器
docker stop [容器ID | 容器名]
docker start [容器ID | 容器名]
删除容器
docker rm [容器ID | 容器名] ##需要暂停容器
docker rm -f [容器ID | 容器名] ##删除运行中的容器
docker rm -f $(docker ps -a) ##删除所有容器
文件拷贝
文件拷贝到容器
docker cp [复制的文件] [容器名称]:[目的目录或者文件名]‘
容器文件拷贝到宿主机
docker cp [容器名|容器ID]:[容器内目录或者文件] [本机目录]
目录挂载
可以将容器挂载到本机的某个目录,从而可以通过修改挂载的本机目录来修改这个容器。
但是容器被删除的时候,宿主机内容不会被删除。如果多个容器挂载到同一个目录,其中一个容器被删除,其他容器的内容也不会受到影响。
匿名挂载
不指定本主机目录只指定容器目录,它会自动创建一个匿名卷在本主机的/var/lib/docker/vloumes
docker run -di --name nginx2 -p 81:80 -v [容器目录] nginx
具名挂载
目录也在/var/lib/docker/vloumes
docker run -di -d -p 8081:80 --name nginx4 -v [目录名字]:[容器目录] nginx
指定目录挂载
docker run -di --name nginx2 -p 81:80 -v [本机目录]:[容器目录] nginx ##容器目录指定了它会自动创建
查看目录挂载关系
docker inspect ##可以查看容器的所有信息包括ip地址什么的
docker volume inspect [卷名]
只读/只写
docker run -di -d -p 8082:80 --name nginx5 -v [容器目录]:[容器名]:[ro|rw] nginx ##只读
vloumes-from(继承)
docker run -di -d -p 81:80 --name nginx7 --volumes-from [被继承人容器]:ro nginx
构建镜像
通过centos7镜像,在里面安装jdk和redis,然后作为一个新的镜像。
创建容器
docker run -di --name mycentos centos:7
拷贝资源
先把redis和jdk的包上传到本主机
docker cp jdk-8u181-linux-x64.tar.gz mycentos:/
docker cp redis-4.0.8.tar.gz mycentos:/
安装资源
docker exec -it mycentos bash ##进入容器
mkdir /usr/local/jdk
mkdir /usr/local/redis
tar zvxf jdk-8u181-linux-x64.tar.gz -C /usr/local/jdk/
tar zvxf redis-4.0.8.tar.gz -C /usr/local/redis/
cat /etc/profile
export JAVA_HOME=/usr/local/jdk/jdk1.8.0_181
export PATH=$PATH:$JAVA_HOME/bin
java -version
构建镜像
docker commit [容器名|容器ID] [新镜像名]:[标签]
-a 镜像作者
-m 信息
docker commit -a='tanc' -m='redis and jdk ' mycentos mycentos:7
[root@master ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 7 01413e360209 8 seconds ago 593MB
docker stop mycentos
docker run -di --name mycentos7 mycentos:7
镜像就创建成功!
Dockerfile
Dockerfile 是创建镜像的所有命令的文本文档。
Dockerfile的运行规则
- 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 指令按照从上到下,顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层,并对镜像进行提交
Dockerfile执行的大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似docker commit的操作提交一个新的镜像层
- docker在基于刚提交的镜像运行一个新容器
- 执行dockerfile中的吓一跳指令知道所有指令都执行完成
从应用软件的角度来看Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段:
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Dokcer容器则可以认为是软件的运行态
Dockerfile面向开发,Docker镜像成为交付标准,Dokcer容器则涉及部署以合运维,三者缺一不可。
FROM
语法 FROM [image]:[tag]
构建来自于哪个基础镜像
有个镜像里面什么都没有只有基础的命令名字叫scratch
MAINTAINER
语法 MAINTAINER
指明镜像维护者及器联系方式,
LABEL
语法 LABEL [key]=[value]
指定镜像标签或者作者
RUN
语法 RUN [shell命令]
构建镜像运行的shell命令,比如构建的新镜像中我们想在/usr/local
ADD
语法 ADD [源文件] [目标文件]
拷贝文件,支持自动下载和解压
COPY
语法 COPY [源文件] [目标文件]
拷贝文件,不支持自动下载和解压
EXPOSE
语法 EXPORT [端口] [端口] / [协议]
暴露容器运行时监听端口给外部
ENV
语法 ENV [键] [值]
设置容器内环境变量
CMD
语法 CMD [命令]
启动容器时执行的shell命令,在Dockerfile中只能有一条CMD指令,有多条就只会最后一条生效。如果在创建容器时给定了shell命令,那么这个就会被覆盖掉
- shell格式 : CMD <命令>
- exec 格式:CMD ["可执行文件,“参数1”,“参数2”....]
- 参数列表格式:CMD[“参数1”,“参数2”....]在指定ENTPYPOINT指令后,用CMD指令具体参数。
ENTRYPOINT
语法 ENTRYPOINT [命令]
和cmd一样但是不会被覆盖掉,docker run之后的参数会被当做参数传递给ENTRYPOINT,之后形成新的命令组合
WORKDIR
语法 WORKDIR [目录]
为RUN、CMD、ENTRYPOINT以及COPY和AND设置工作目录,或者登录目录
VOLUME
指定容器挂载到宿主机
ONBUILD
当构建一个被继承的Dockerfile时运行命令父镜像的onbuild被触发
就是当他作为要被继承的主镜像的时候他就会触发的命令或者机制
创建Dockerfile
注意:Dockerfile可以创建有个文件夹在存放Dockerfile 也可以不用建议是用。
Dokcerfile 文件就以Dockerfile或者其他命名,没有任何后缀。
[root@master dockerfile]# cat /usr/local/dockerfile/Dockerfile
FROM centos:7
LABEL zuozhe='tanc'
WORKDIR /url/local
RUN mkdir -p /usr/local/jdk & mkdir -p /usr/local/redis
ADD jdk-8u181-linux-x64.tar.gz /usr/local/jdk
ADD redis-4.0.8.tar.gz /usr/local/redis
ENV JAVA_HOME=/usr/local/jdk/jdk1.8.0_181
ENV PATH=$PATH:JAVA_HOME/bin
CMD ['/url/local/root/redis-4.0.8/utils/install_server.sh','run']
使用Dockerfile
docker build -f Dockerfile -t mycentos:7 .
-f指定dockerfile文件
-t 创建的镜像名字
. 要调用的东西存在位置
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 7 2d0914b2ddf3 3 minutes ago 593MB
docker run -it mycentos:7
查看镜像变更历史
docker history [镜像名]
上传镜像到私有仓库
登录dockerhub
docker login
拉取私有仓库包
docker pull registry
修改配置文件daemon.json
添加
{
"insecure-registries":["192.168.137.10:5000"]
}
创建registry容器
docker run -di -p 5000:5000 -v /opt/registry/:/var/lib/registry --name registry registry
打开浏览器输入
http://192.168.137.10:5000/v2/_catalog ## 会显示 就表示成功
{"repositories":[]}
创建标签
docker tag hello-world:tag 192.168.137.10:5000/tanc-hello-world:1.1.1
##查看
docker images
busybox latest d3cd072556c2 6 days ago 1.24MB
192.168.137.10:5000/tanc-hello-world 1.1.1 d1165f221234 2 months ago 13.3kB
上传
docker push 192.168.137.10:5000/tanc-hello-world:1.1.1
在登录浏览器查看
http://192.168.137.10:5000/v2/_catalog
{"repositories":["tanc-hello-world"]}
拉取镜像
docker run -it --name hello2 192.168.137.10:5000/tanc-hello-world:1.1.1
配置个人仓库证书认证
创建放置密钥的文件
mkdir -p /usr/local/registry/certs
mkdir -p /usr/local/registry/auth
创建密钥
openssl req -newkey rsa:2048 -nodes -sha256 -keyout /usr/local/registry/certs/domia.key -x509 -days 365 -out /usr/local/registry/certs/domain.crt
Common Name (eg, your name or your server's hostname) []: ##在这个选项填仓库ip地址
openssl req | 创建证书签名请求等功能 |
-newkey | 创建CSR证书签名文件和RSA私钥文件; |
rsa:2048 | 指定创建RSA私钥长度为2048; |
-nodes | 对私钥不进行加密; |
-sha256 | 使用SHA256算法 |
-keyout | 创建的私钥文件名称及位置; |
-x509 | 自签发证书格式; |
-days | 证书有效期 |
-out | 指定CSR输出文件名称和位置 |
创建密码文件
htpasswd -Bbn root 1234 > /usr/local/registry/auth/htpasswd ##会自动生成文件
[root@master auth]# cat htpasswd
root:$2y$05$lUmu9uX5dgWaeeVho3YvYOWSfqtEA6ylMz3RMPfwG/aDfHokVcSd
htpasswd
参数 | 解释 |
---|---|
-c | 创建一个加密文件 |
-n | 不更新加密文件,只将apache htpsswd命令加密后的用户名密码显示在屏幕上 |
-m | 默认apache htpassswd命令采用MD5算法对密码进行加密 |
-d | apache htpassswd命令采用CRYPT算法对密码进行加密 |
-p | apache htpassswd命令不对密码进行进行加密,即明文密码 |
-s | apache htpassswd命令采用SHA算法对密码进行加密 |
-b | 在apache htpassswd命令行中一并输入用户名和密码而不是根据提示输入密码 |
-D | 删除指定的用户 |
-B | 强制对密码进行bcrypt加密(非常安全) |
创建容器,挂载和环境变量
docker run -di --name registry -p 5000:5000 \
-v /opt/registry/:/var/lib/registry \
-v /usr/local/registry/certs:/certs \
-v /usr/local/registry/auth/:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry
登录到仓库
[root@master certs]# docker login 192.168.137.10:5000
Username: root
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
上传容器
docker tag hello-world 192.168.137.10:5000/tc:1
docker push 192.168.137.10:5000/tc:1
退出账号
docker logout 192.168.137.10:5000
查看docker 网络
docker network ls
NETWORK ID NAME DRIVER SCOPE
41e3463787d8 bridge bridge local ##桥接
d6940070926d host host local ##使用主机模式
690f3fe16a1f none null local ##没有网络可以自己定义
网络模式 | 简介 |
---|---|
bridge | 为每一个容器分配,配置ip等,并将容器连接到一个docker0虚拟网桥,默认为改模式 |
host | 容器将不会虚拟出自己的网卡,配置直加到IP等,而是使用主机IP和端口 |
none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair和网桥连接,ip等 |
container | 新创建的容器不会创建自己的网卡和配置自己的IP,二十和一个指定的容器共享IP,端口范围等。 |
busybox是一个linux命令集成工具
bridge 网络模式
在桥接模式中,docker守护进程会自动你创建一个docker0,新建的容器会自动桥接到这个接口,附加在上面的任何网卡之间都可以自动转发数据包。
默认情况下,守护进程会创建一对对等的虚拟设备接口veth pair,将其中一个接口设置为容器的eth0接口,另一个阶段放在本主机的命令空间中,类似vethxxx这样的名字命名,从而将宿主机上所有容器都连接到这个内部网络上。
host网络模式
- host网络模式要在创建容器时通过参数 --net host 或者 --network host
- 采用host网络模式的docker容器,可以直接使用宿主机的IP地址与外界通信,若宿主机的网卡时应该公有ip,那么容器也拥有这个公有ip,同时容器内服务的端口也可以使用宿主机的端口,无需额外进行NAT转换
缺点就是容器缺少网络隔离
创建host网络容器
docker run -it --network host --name hostnet busybox
none网络模式
none模式就是禁止使用网络模式,只有本地回环口,通过--net none指定
创建none
docker run -it --net none --name nonenet busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
/ #
container网络模式
container网络模式是docker中特别的网络模式,在创建容器时通过参数 --net container:[已经运行的容器名|容器ID] 指定
处于这个模式下容器会共享一个网络线,这两个容器通过回环接口来通讯
创建container
docker run -di --name mycentos centos:7 ##创建一个容器
[root@master ~]# docker inspect mycentos ##查询这个容器的ip地址
Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
[root@master ~]# docker run -it --name container --net container:mycentos busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
92: eth0@if93: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
/ #
如果主容器停止或者删除了那么container的网卡也会销毁
[root@master ~]# docker stop mycentos
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
/ # ##这里可以看见一张网卡没有了
自定义网络
dokcer提供默认网络使用比较简单,但是为了保证容器中应用的安全性,在实际开发中更推荐使用自定义为了进行容器管理,以及启动容器名称到IP地址的自动DNS解析
docker1.10版本开始,docker daemon实现了一个内嵌的DNS服务,使容器可以直接通过容器名称进行通信,方法很简单,只要在创建容器时使用 --name 为容器命名即可
创建网络
[root@master ~]# docker network create network1
79a06fdc79ebfc9fc41050d7b606f2432df246e7bcac505192dfab218abd1a0e
[root@master ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
41e3463787d8 bridge bridge local
d6940070926d host host local
79a06fdc79eb network1 bridge local
690f3fe16a1f none null local
docker run -it --name zdynet --net network1 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
97: eth0@if98: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
/ #
将容器连接到网络命令
docker network connect [OPTIONS] NETWORK [容器名|容器ID]
命令 | 说明 |
---|---|
--alias | 为容器添加网络范围别名 |
--driver-opt | 网络驱动程序选项 |
--ip | ipv4地址 |
--ip6 | ipv6 |
--link | 将链接添加到另一个容器 |
--link-local-ip | 为容器添加本地链接地址 |
docker create
名称,简写 | 默认 | 描述 |
---|---|---|
--attachable |
API 1.25以上 启用手动容器附件 | |
--aux-address |
网络驱动程序使用的辅助IPv4或IPv6地址 | |
--config-from |
API 1.30+ 从中复制配置的网络 | |
--config-only |
API 1.30+ 创建仅配置网络 | |
--driver , -d |
bridge |
驱动程序来管理网络 |
--gateway |
主子网的IPv4或IPv6网关 | |
--ingress |
API 1.29+ 创建集群路由网状网络 | |
--internal |
限制对网络的外部访问 | |
--ip-range |
从子范围分配容器ip | |
--ipam-driver |
IP地址管理驱动程序 | |
--ipam-opt |
设置IPAM驱动程序特定选项 | |
--ipv6 |
启用IPv6网络 | |
--label |
在网络上设置元数据 | |
--opt , -o |
设置驱动程序特定选项 | |
--scope |
API 1.30+ 控制网络范围 | |
--subnet |
代表网段的CIDR格式的子网 |
自定义网络
默认的桥环模式在容器中只能通过来ip来ping,如果自己创建了个网络模式就可以依靠容器名来互相ping
创建网络
[root@master ~]# docker network create network1
创建network1模式容器
[root@master ~]# docker run -it --name tc2 --net network1 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
11: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@master ~]# docker run -it --name tc1 --net network1 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
9: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
使用容器名互ping就能通了
Compose简介
Dockerfile文件让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配好来完成某项任务的情况。
Docker Compose 恰好满足了这样的需求,它是用于定义和运行多容器Docker应用程序的工具,通过Compose,您可以使用YAML文件来配置程序所需要的服务。
docker compose 项目事Docker官方开源的项目,来源于之前的FIg项目,使用Python语言编写。负责实现2对Dokcer容器集群的快速编排。
使用Docker Compose使用的三个步骤为:
- 使用Dokcerfile文件定义应用程序的环境
- 使用doccker-compose.yml文件定义构成应用程序的服务,这样它们开源在隔离环境中一起运行;
- 执行docker-compose up 来创建并启动所有服务
安装compose
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
给与docker-compose文件可执行的限权
chmod +x /usr/local/bin/docker-compose
将docker-compose文件链接到/usr/bin、
ln -s /usr/local/bin/docker-compose /usr/bin/
查看docker-compose版本
docker-compose --version
docker-compose version 1.29.2, build 5becea4c
开始使用docker-compose!
创建一个用于存放compose文件的目录
[root@master ~]# mkdir composetest
在composetest文件里创建一个名为app.py的文件夹,并写入一下内容
[root@master composetest]# cat app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
在composetest文件夹中创建一个requirements.txt文件
容器的生命周期
如果这个容器里PID为1的进程结束了,那么容器内其就结束了
Docker运行参考
docker run [参数]
启动docker容器时,首先确定要在后台以分离模式还是默认的前台模式运行该容器,
-d=true 分离模式启动容器,以分离模式启动的容器会在用于运行容器的根进程退出时退出。可以与--rm一起使用,一起用则代表容器退出或者退出守护进程时将容器删除。
注意:不要将systemctl 和· service之类的命令传递给分离的容器
-d 不指定任何参数就是前台模式,可以在容器中启动进程并将控制台附加到进程的标准输入,输出和标准错误。
TTY :终端
-a=[ ] 附加到“STDIN(标准输出)”、“STDOUT(标准)”和/或“STDERR(标准错误)”
-t 分配给伪tty
--sig-proxy=true : 将所有接收到的信号代理给进程(仅限非TTY模式)
-i 即使未连接,也保持标准输入打开
如果 没有指定-a 则docker将同时附加到stdout和stderr
对于交互式shell,必须-i -t 一起使用才能为容器进程分配tty
集装箱标识
Name
可以通过三个来识别集装箱
UUID 长标识
UUID 短标识
集装箱名字
UUID标识符来之Docker守护程序。如果未使用--name 选项分配容器名称,则守护程序会生成一个随机的UUID。
[:tag]
可以通过添加image[:tag] 命令来指定要用于运行容器的映像版本。