乐趣区

关于docker:Docker全轻量虚拟机

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
退出移动版