Docker
官网是这样介绍 docker 的:
Docker is an open platform for developers and sysadmins to build, ship, and run distributed applications…
其实看完这句话还是不明确 docker 到底是什么
咱们能够把他设想成是一个用了一种新鲜形式实现的超轻量虚拟机。当然在实现的原理和利用上还是和 VM 有微小差异的,并且业余的叫法是利用容器(Application Container)。
比方当初想用 MySQL, 那就找个装好并配置好的 MySQL 的容器(能够认为是非凡的, 轻量级的虚拟机), 运行起来, 那么就能够应用 MySQL 了。
那么为什么不间接在操作系统中装置一个 mysql, 而是用容器呢?
装置 MySql 过程并不简略, 要配置装置源, 装置依赖包, 对 mysql 进行配置…如果要在多台主机上安装, 每台主机都要进行这些繁琐的操作, 万一服务器挂了, 这一系列操作还要再重来一遍
但有了 docker, 一个装置配置好的 mysql 容器, 能够间接拿到另一台主机上启动, 而不用重新安装 mysql
另外,docker 还有一重要的用途, 就是能够保障开发, 测试和生产环境的统一.
docker 手册
中文收费手册 [Docker — 从入门到实际]
https://vuepress.mirror.docker-practice.com
docker 从入门到实际,离线版
docker pull dockerpracticecn/docker_practice
docker run -it --rm -p 4000:80 dockerpracticecn/docker_practice
centos7 装置 docker
离线安装包
下载离线安装包
https://download.csdn.net/download/weixin_38305440/12265961
上传离线安装包
docker-install
目录上传到/root
切换到 docker-install
目录
cd docker-install
装置
rpm -ivh *.rpm
设置零碎服务
systemctl enable docker
启动 docker 零碎服务
systemctl start docker
yum 在线装置 docker
官网装置手册
https://docs.docker.com/install/linux/docker-ce/centos/
卸载旧版
sudo yum remove docker-ce
docker-ce-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-engine
装置一组工具
sudo yum install -y yum-utils
device-mapper-persistent-data
lvm2
设置 yum 仓库地址
sudo yum-config-manager
--add-repo
https://download.docker.com/linux/centos/docker-ce.repo
sudo yum-config-manager
--add-repo
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新 yum 缓存
sudo yum makecache fast
装置新版 docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
启动 docker 零碎服务
启动 docker
sudo systemctl start docker
设置 docker 开机启动
sudo systemctl enable docker
镜像减速
因为国内网络问题,须要配置加速器来减速。
批改配置文件 /etc/docker/daemon.json
上面命令间接生成文件 daemon.json
cat <<EOF > /etc/docker/daemon.json
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://hub-mirror.c.163.com"
]
}
EOF
之后重新启动服务。
# 从新加载 docker 配置
sudo systemctl daemon-reload
#重启 docker 服务
sudo systemctl restart docker
查看镜像配置
docker info
运行 hello-world 镜像,验证 docker
sudo docker run hello-world
Docker
轻量的虚拟机
VMware
残缺虚构一台计算机,所有的应将、底层系统资源都须要虚构进去
Docker
充分利用宿主机的硬件和系统资源,本人虚构的货色非常少
Docker 是开发运维一体化(DevOps)的外围工具
基本概念
镜像
Docker 镜像是一个非凡的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还蕴含了一些为运行时筹备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不蕴含任何动态数据,其内容在构建之后也不会被扭转。
镜像只是一个虚构的概念,其理论体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联结组成。
镜像构建时,会一层层构建,前一层是后一层的根底。每一层构建完就不会再产生扭转,后一层上的任何扭转只产生在本人这一层。比方,删除前一层文件的操作,理论不是真的删除前一层的文件,而是仅在以后层标记为该文件已删除。在最终容器运行的时候,尽管不会看到这个文件,然而实际上该文件会始终追随镜像。因而,在构建镜像的时候,须要额定小心,每一层尽量只蕴含该层须要增加的货色,任何额定的货色应该在该层构建完结前清理掉。
分层存储的特色还使得镜像的复用、定制变的更为容易。甚至能够用之前构建好的镜像作为根底层,而后进一步增加新的层,以定制本人所需的内容,构建新的镜像。
容器
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是动态的定义,容器是镜像运行时的实体。容器能够被创立、启动、进行、删除、暂停等。
容器的本质是过程,但与间接在宿主执行的过程不同,容器过程运行于属于本人的独立的 命名空间。因而容器能够领有本人的 root 文件系统、本人的网络配置、本人的过程空间,甚至本人的用户 ID 空间。容器内的过程是运行在一个隔离的环境里,应用起来,就如同是在一个独立于宿主的零碎下操作一样。这种个性使得容器封装的利用比间接在宿主运行更加平安。
后面讲过镜像应用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为根底层,在其上创立一个以后容器的存储层,咱们能够称这个为容器运行时读写而筹备的存储层为容器存储层。
容器存储层的生存周期和容器一样,容器沦亡时,容器存储层也随之沦亡。因而,任何保留于容器存储层的信息都会随容器删除而失落。
依照 Docker 最佳实际的要求,容器不应该向其存储层内写入任何数据,容器存储层要放弃无状态化。所有的文件写入操作,都应该应用 数据卷(Volume)、或者绑定宿主目录,在这些地位的读写会跳过容器存储层,间接对宿主(或网络存储)产生读写,其性能和稳定性更高。
数据卷的生存周期独立于容器,容器沦亡,数据卷不会沦亡。因而,应用数据卷后,容器删除或者从新运行之后,数据却不会失落。
docker 镜像操作
下载 CentOS 镜像
docker pull centos:7
查看 centos7 镜
# 查看镜像列表
docker images
或
docker image ls
运行 centos7
# 从 tomcat 镜像,运行启动容器
# 参数 i: 交互 参数 t: 终端
docker run -it xxxx bash
- xxxx – 镜像名, 或 image id 的前几位
-it
这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。咱们这里打算进入 bash 执行一些命令并查看返回后果,因而咱们须要交互式终端。bash
放在镜像名后的是命令,这里咱们心愿有个交互式 Shell,因而用的是 bash。
删除镜像
501
镜像 id 前几位,个别三位以上,足够辨别即可
docker image rm 501
docker rmi hello-world
docker rmi aaaaa bbbbb cccccc dddd
docker rmi id1 id2 id3
# 如果存在容器,不能间接删除镜像,能够加 -f 参数强制删除镜像
docker rmi -f hello-world
- 删除指定仓库的镜像
docker image rm centos
镜像导出
docker save mysql:5.7 node:8 | gzip > app.tar.gz
镜像导入
docker load < apps.tar.gz
容器操作
启动容器
# 参数 i: 交互 参数 t: 终端
docker run -it centos:7 bash
# 查看正在运行的容器
docker ps
# 查看所有容器,包含已敞开的容器
docker ps -a
# 进行或重启容器
docker stop 0c6
docker start 0c6
docker restart 0c6
当利用 docker run 来创立容器时,Docker 在后盾运行的规范操作包含:
- 查看本地是否存在指定的镜像,不存在就从私有仓库下载
- 利用镜像创立并启动一个容器
- 调配一个文件系统,并在只读的镜像层里面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚构接口到容器中去
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行结束后容器被终止
容器启动后运行的利用
镜像中设置了默认启动的利用
# 查看镜像中设置的默认利用
docker history tomcat
docker history redis
docker history mariadb
如果不想执行镜像指定的默认命令,也能够本人指定任意命令
docker run -it tomcat ls
docker run -it tomcat top
docker run -it tomcat bash
docker ps -a
后盾运行
docker run -dit centos:7
-d
后盾运行容器- 容器是否会短暂运行,是和 docker run 指定的命令无关,和 -d 参数无关。
启动容器的参数:-d、–name、–rm、–restart=always
# -d 后盾运行,不占用控制台
# --name 给容器命名
docker run -d --name cat1 tomcat
docker ps
# 查看容器外部日志
docker logs cat1
# --rm 容器敞开时,主动删除容器
docker run -it --rm tomcat top
# ctrl+c 退出后,容器主动敞开,主动删除,查看容器列表是看不到容器的
docker ps -a
# --restart=always 容器总是主动启动
docker run -d --name cat2 --restart=always tomcat
docker ps
# 重启 docker 零碎服务,cat2 也会主动重启,cat1 不会主动启动
systemctl restart docker
docker ps
查看后盾运行的容器输入后果
docker container logs 802
查看容器
docker container ls -a
# 或
docker ps -a
-a
all, 全副
终止容器
docker container stop 802
重新启动容器
docker container restart 802
进入容器
在应用 -d 参数时,容器启动后会进入后盾。
某些时候须要进入容器进行操作,能够应用 docker exec
命令
docker exec -it 802 bash
docker exec -it cat2 pwd
docker exec -it cat2 ps
docker exec -it cat2 touch f1.txt
docker exec -it cat2 ls
docker exec -it cat2 bash
删除容器
docker container rm 802
docker rm 9aa f94
# 不能间接删除正在运行的容器,能够加 -f 强制删除
docker rm -f 0c6
# 清理所有曾经退出的容器
docker container prune
- 如果删除运行中的容器,须要增加
-f
参数
清理所有终止状态容器
docker container prune
数据管理
在容器中治理数据次要有两种形式:
- 数据卷(Volumes)
- 挂载主机目录 (Bind mounts)
数据卷
数据卷 是一个可供一个或多个容器应用的非凡目录
- 数据卷 能够在容器之间共享和重用
- 对 数据卷 的批改会立马失效
- 对 数据卷 的更新,不会影响镜像
- 数据卷 默认会始终存在,即便容器被删除
创立数据卷
# 创立数据卷
docker volume create my-vol
查看所有数据卷
# 查看数据卷
docker volume ls
查看指定 数据卷 的信息
# 查看数据卷详情 /var/lib/docker/volumes/my-vol/_data
docker volume inspect my-vol
查问的后果:
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]
启动挂载数据卷的容器
docker run -it --mount source=my-vol,target=/webapp centos:7 bash
# 或者:docker run -it -v my-vol:/webapp centos:7 bash
-v my-vol:/webapp
把数据卷 my-vol 挂载到容器的 /webapp 目录
删除数据卷
- 删除指定的数据卷,如果数据卷被容器应用则无奈删除
docker volume rm my-vol
- 清理无主数据卷
docker volume prune
数据卷挂载(施行)
# 创立数据卷
docker volume create my-vol
# 查看数据卷
docker volume ls
# 查看数据卷详情 /var/lib/docker/volumes/my-vol/_data
docker inspect my-vol
# 把 my-vol 数据卷挂载到容器
docker run \
-d --name cat2 \
--rm \
-v my-vol:/opt/app \
tomcat
# 在容器 cat2 的 /opt/app/ 下创立文件
docker exec -it cat2 touch /opt/app/f2.txt
docker exec -it cat2 ls /opt/app/
# 在宿主机 my-vol 数据卷的目录下查看文件
cd /var/lib/docker/volumes/my-vol/_data
ls
挂载主机目录
docker run -it --mount type=bind,source=/usr/app,target=/opt/app centos:7 bash
# 或
docker run -it -v /usr/app:/opt/app centos:7 bash
-v
如果本地目录不存在 Docker 会主动为你创立一个文件夹--mount
参数时如果本地目录不存在,Docker 会报错
查看挂载目录信息
docker inspect 91a
显示后果:
...
"Mounts": [
{
"Type": "bind",
"Source": "/usr/app",
"Destination": "/opt/app",
"Mode": "","RW": true,"Propagation":"rprivate"
}
],
...
目录挂载(施行)
# -v /usr/app:/opt/app
# -v 宿主机目录: 容器中的门路
# 宿主机目录不存在会主动创立
docker run \
-d \
--name cat1 \
-v /usr/app:/opt/app \
tomcat
# 进入 cat1 容器,在 /opt/app/ 目录下创立文件
docker exec -it cat1 bash
cd /opt/app/
echo 111111111111111 > f1.txt
ls
cat f1.txt
# 退回到宿主机,查看保留在宿主机的文件
exit
cd /usr/app/
ls
cat f1.txt
网络
主动调配映射端口
docker run -d -P tomcat
# 查看容器信息
docker container ls -a
显示后果:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d03480b1a781 tomcat "catalina.sh run" 3 minutes ago Up 3 minutes 0.0.0.0:32768->8080/tcp trusting_gagarin
映射指定端口
docker run -d -p 8080:8080 tomcat
8080:8080
本机端口: 容器端口
映射多个端口
docker run -d
-p 5000:5000
-p 80:8080 tomcat
映射指定端口(指定网卡)
docker run -d -p 192.168.64.150:8080:8080 tomcat
主动调配映射端口(指定网卡)
docker run -d -p 192.168.64.150::8080 tomcat
查看端口配置
docker port 8af
端口映射(施行)
# 清理容器
docker rm -f cat1 cat2
# 创立 tomcat 容器,映射到宿主机的 80 端口
docker run \
-d --name cat1 \
--restart=always \
-p 80:8080 \
tomcat
# 拜访 http://192.168.64.150
# 在宿主机创立 /opt/web/index.html
mkdir /opt/web/
cat <<EOF >/opt/web/index.html
<h1>Hello docker!!!</h1>
EOF
# 启动容器 cat2
docker run -d --name cat2 \
--restart=always \
-v /opt/web:/usr/local/tomcat/webapps/ROOT \
-p 8088:8080 \
tomcat
# 拜访 http://192.168.64.150:8088
容器互联
新建网络
docker network create -d bridge my-net
-d
driver, 网络类型,默认 bridge,也能够是 overlay(Swarm mode)
列出网络
docker network ls
查看网络信息
docker inspect 67d
连贯容器
docker run -it --name app1 --network my-net centos:7
新开终端执行:
docker run -it --name app2 --network my-net centos:7
在两个终端中别离执行:
ping app1
ping app2
显示如下:
[root@35569c623c4c /]# ping app1
PING app1 (172.18.0.2) 56(84) bytes of data.
64 bytes from 35569c623c4c (172.18.0.2): icmp_seq=1 ttl=64 time=0.577 ms
64 bytes from 35569c623c4c (172.18.0.2): icmp_seq=2 ttl=64 time=0.061 ms
64 bytes from 35569c623c4c (172.18.0.2): icmp_seq=3 ttl=64 time=0.066 ms
......
- 多个容器互联,举荐应用 Docker Compose
容器互联(施行)
# 创立网络
docker network create my-net
# 查看网络
docker network ls
# 查看网络详情
docker inspect my-net
# 查看宿主机上新建的虚构网卡
ifconfig
# 启动容器 app1,连贯到 my-net 网络
docker run -dit --name app1 \
--net my-net \
centos:7
# 启动容器 app2,连贯到 my-net 网络
docker run -dit --name app2 \
--net my-net \
centos:7
# 查看容器形容,能够看到取得的 ip 地址
docker inspect app1
docker inspect app2
# 从宿主机 ping app1 和 app2 的 ip
ping 172.18.0.2
ping 172.18.0.3
# 进入 app1,ping 宿主机和 app2
docker exec -it app1 ping 172.18.0.1
docker exec -it app1 ping 172.18.0.3
docker exec -it app1 ping app2
Dockerfile
筹备
- centos:7 镜像
- jdk 压缩包
jdk-8u212-linux-x64.tar.gz
- tomcat7 压缩包
apache-tomcat-7.0.96.tar.gz
Dockerfile 文件
# 以 centos7 为根底, 装置 oracle jdk8 和 tomcat7
FROM centos:7
#ADD 命令将压缩包传入镜像中的指定目录, 并同时解压缩
ADD jdk-8u212-linux-x64.tar.gz /opt/
ADD apache-tomcat-7.0.96.tar.gz /usr/
#为了不便, 把文件夹名称改得简略一点
RUN mv /usr/apache-tomcat-7.0.96 /usr/tomcat
#设置环境变量
ENV JAVA_HOME=/opt/jdk1.8.0_212
CATALINA_HOME=/usr/tomcat
PATH=$PATH:/opt/jdk1.8.0_212/bin:/usr/tomcat/bin
#裸露容器的 8080 端口
EXPOSE 8080
#设置启动容器时主动运行 tomcat
ENTRYPOINT /usr/tomcat/bin/startup.sh && tail -F /usr/tomcat/logs/catalina.out
FROM centos:7
ADD jdk-8u212-linux-x64.tar.gz /opt/
ADD apache-tomcat-7.0.96.tar.gz /usr/
RUN mv /usr/apache-tomcat-7.0.96 /usr/tomcat
ENV JAVA_HOME=/opt/jdk1.8.0_212 \
CATALINA_HOME=/usr/tomcat \
PATH=$PATH:/opt/jdk1.8.0_212/bin:/usr/tomcat/bin
EXPOSE 8080
ENTRYPOINT /usr/tomcat/bin/startup.sh && tail -F /usr/tomcat/logs/catalina.out
应用 Dockerfile 构建镜像
docker build -t tomcat:7 .
- 留神开端的点, 示意构建过程中从当前目录寻找文件
启动容器
筹备存储目录
- webapps 目录, 例如
/opt/webapps
- logs 目录, 例如
/var/lib/tomcat-logs
mkdir /opt/webapps
mkdir /opt/webapps/ROOT
mkdir /var/lib/tomcat-logs
# 增加欢送页
cat <<EOF > /opt/webapps/ROOT/index.html
<h1>Hello Docker!!!</h1>
EOF
启动容器, 挂载目录
docker run
-d
-p 8080:8080
--name tomcat7
-v /opt/webapps:/usr/tomcat/webapps
-v /var/lib/tomcat-logs:/usr/tomcat/logs
tomcat:7
构建 tomcat:7 镜像
# 新建文件夹 tomcat7
cd ~/
mkdir tomcat7
# 生成 Dockerfile 文件
cd tomcat7
cat <<EOF >Dockerfile
FROM centos:7
ADD jdk-8u212-linux-x64.tar.gz /opt/
ADD apache-tomcat-7.0.96.tar.gz /usr/
RUN mv /usr/apache-tomcat-7.0.96 /usr/tomcat
ENV JAVA_HOME=/opt/jdk1.8.0_212 \
CATALINA_HOME=/usr/tomcat \
PATH=$PATH:/opt/jdk1.8.0_212/bin:/usr/tomcat/bin
EXPOSE 8080
ENTRYPOINT /usr/tomcat/bin/startup.sh && tail -F /usr/tomcat/logs/catalina.out
EOF
# 上传 jdk 和 tomcat7 的压缩文件到 /root/tomcat7/
# 实现构建,开端的点,是当前目录(/root/tomcat7/)docker build -t tomcat:7 .
# 查看镜像列表
docker images
# 从 tomcat:7 镜像,运行启动容器
docker run -d --name cat3 \
-p 8089:8080 \
tomcat:7
docker logs cat3
http://192.168.64.150:8089
构建 eureka 镜像
# 筹备文件
cd ~/
mkdir eureka
cd eureka
# 上传文件 jdk 和 eureka 的 jar 文件到 /root/eureka/ 文件夹
# jdk 文件:课前材料 /docker/tomcat7/
# java -jar /opt/sp05-eureka-0.0.1-SNAPSHOT.jar
# --spring.profiles.active=eureka1 --server.port=2001
cat <<EOF >Dockerfile
FROM centos:7
ADD jdk-8u212-linux-x64.tar.gz /opt/
COPY sp05-eureka-0.0.1-SNAPSHOT.jar /opt/
ENV JAVA_HOME=/opt/jdk1.8.0_212 \
PATH=$PATH:/opt/jdk1.8.0_212/bin
ENTRYPOINT ["java", "-jar", "/opt/sp05-eureka-0.0.1-SNAPSHOT.jar"]
CMD ["--spring.profiles.active=eureka1", "--server.port=2001"]
EOF
docker build -t eureka:v1 .
# 启动 eureka 容器
docker run -d --name eureka1 \
--restart=always \
-p 2001:2001 \
eureka:v1
docker logs eureka1