Docker
Docker概述
Docker为什么出现
一款产品:开发--上线 两套环境 应用环境,应用配置
开发----运维
环境配置是十分的麻烦,每一个机器都要部署环境(集群Redis,ES,Hadoop。。。。)!费时费力
发布项目jar+(Redis,MySQL,jdk,ES...),项目能不能带上环境安装打包!
之前在服务器配置一个应用的环境Redis,MySQL,jdk,ES,Hadoop,配置超麻烦,不能跨平台
Windows,最后发布到Linux
传统:开发jar,运维来做部署的事情
现在:开发打包部署上线,一套流程做完
java--jar(环境)---打包项目带上环境(形成镜像)---(Docker仓库:商店)--下载我们发布的镜像--直接运行
Docker给以上的问题,提出了解决方案
docker的思想就来自集装箱
JRE--多个应用(端口冲突)--原来是交叉的
隔离:Docker的核心思想,打包装箱!每个箱子是互相隔离。
Docker通过隔离限制,可以将服务器利用到极致。
Docker历史
2010年,几个年轻人在美国成立了一家公司dotcloud
做一些pass的云计算服务,LXC有关的容器技术!
他们将自己的技术 容器化技术 命名为Docker
Docker刚刚创建时,没有引起行业的注意,dotCloud就活不下去
开源
开发源代码
2013年,Docker开源
Docker越来越火,Docker每个月都或更新一个版本
2014年4月9日。Docker1.0发布
Doker为什么这么火,十分轻巧
在容器技术出来之前,都是使用虚拟机技术
虚拟机:在windows中装一个Vmware,通过这个软件可以虚拟出一台或者多台电脑!非常笨重
虚拟机也是属于虚拟化技术,Docker容器技术,也是一种虚拟化技术
vm:linux centOS原生镜像(一台电脑) 隔离:需要开启多个虚拟机 几个G 几分钟
docker:隔离,镜像(最核心的环境 4m + jdk +mysql) 十分轻巧,运行镜像即可!小巧 几个m kb 秒级启动
到现在,多有开发人员都必须会Docker
Docker是基于GO语言开发!开源项目
文档地址:https://docs.docker.com/,Docker的文档是超级详细的
Docker能做什么
-
之前的虚拟机技术
-
资源占用十分多
-
冗余步骤多
-
启动很慢
-
容器化技术
容器化技术不是模拟的一个完整的操作系统
比较Docker和虚拟机技术的区别:
-
传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
-
容器内应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
-
每个容器是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响
-
DevOps(开发,运维)
应用更快速的交付和部署
传统:一堆文档,安装程序
Docker:打包镜像发布测试,一键运行。
更便捷的升级和扩缩容
使用了Docker之后,我们部署应用就和搭积木一样
项目打包为一个镜像,扩展 服务器A!服务器B
更简单的系统运维
在容器化之后,我们的开发,测试环境都是高度一致的
更高效的计算资源的利用
Docker是内核级别的虚拟化,可以在一个物理机上运行很多容器实例!服务器性能可以被压榨到极致。
Docker安装
Docker基本组成
镜像(image):
docker镜像就好比是一个模板,通过这个模板来创建容器服务,tomcat镜像--->run-->tomcat01容器(提供服务)
通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)
容器(containers):
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的
启动,停止,删除,基本命令
目前就可以把这个容器理解为就是一个简易的linux系统
仓库(repository):
仓库就是存放镜像的地方!
仓库分为私有和共有仓库
Docker Hub(默认是国外的)
阿里云。。。都有容器服务(配置镜像加速)
Docker安装
环境安装
-
需要一些linux的基础
-
CentOS7
-
我们使用Xshell连接远程服务器进行操作
环境查看
#系统内核是3.10
[zhoudelin@localhost ~]$ uname -r
3.10.0-1127.el7.x86_64
#系统版本
[zhoudelin@localhost ~]$ cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
安装
帮助文档
#1.卸载旧的版本
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
#2.需要的安装包
$ sudo yum install -y yum-utils
#3.设置镜像的仓库
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo #国外的地址,非常慢
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #推荐使用阿里云
#先更新yum软件包索引
yum makecache fast
#4.安装docker docker-ce社区版 ee 企业版
$ sudo yum install docker-ce docker-ce-cli containerd.io
#5.启动docker
$ sudo systemctl start docker
#6.判断是否成功
[zhoudelin@localhost ~]$ docker version
#7.hello-world
$ sudo docker run hello-world
结果显示:
[zhoudelin@localhost ~]$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:7f0a9f93b4aa3022c3a4c147a449bf11e0941a1fd0bf4a8e6c9408b2600777c5
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/
#8.查看一下下载的这个hello-world镜像
$ sudo docker images
[zhoudelin@localhost ~]$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 8 months ago 13.3kB
了解卸载docker
#卸载依赖
$ sudo yum remove docker-ce docker-ce-cli containerd.io
#删除目录
$ sudo rm -rf /var/lib/docker #docker默认工作路径:/var/lib/docker
阿里云镜像加速
回顾HelloWorld流程
底层原理
Docker是干什么工作的?
docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过socket从客户端访问
DockerServer接收到Docker-Client的指令,就会执行这个命令!
Docker为什么比VM快
-
Docker有着比虚拟机更少的抽象层
-
Docker利用的是宿主机的内核,vm更需要的是Guest OS
所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机是加载Guest OS,分钟级别,而Docker是利用宿主机的操作系统,省略了这个复杂的过程。
Docker常用命令
帮助命令
docker version # 显示docker版本
docker info # 显示docker系统信息,包括镜像和容器
docker command --help # 帮助命令
systemctl start docker # 启动docker服务
帮助文档:https://docs.docker.com/reference/
镜像命令
docker images 查看本机上的所有镜像
[root@localhost ~]$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 8 months ago 13.3kB
#解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小
Options: #可选项
-a, --all Show all images (default hides intermediate images)#列出所有的镜像
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output
-q, --quiet Only show numeric IDs #只显示镜像的ID
docker search 搜索镜像
[root@localhost ~]$ sudo docker search mysql
[sudo] root 的密码:
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9934 [OK]
#可选项
[root@localhost ~]$ sudo docker search --help
Usage: docker search [OPTIONS] TERM
Search the Docker Hub for images
Options:
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print search using a Go template
--limit int Max number of search results (default 25)
--no-trunc Don't truncate output
#通过收藏来过滤
--filter-STARTS-3000 #搜索出来的镜像就是STARTS大于3000的
docker pull 下载镜像
#下载镜像 docker pull 镜像名[:tag]
[root@localhost ~]$ sudo docker pull mysql
[sudo] root 的密码:
Using default tag: latest #如果不写tag,默认就是latest
latest: Pulling from library/mysql
bf5952930446: Pull complete #分层下载,docker images的核心 联合文件系统
8254623a9871: Pull complete
938e3e06dac4: Pull complete
ea28ebf28884: Pull complete
f3cef38785c2: Pull complete
894f9792565a: Pull complete
1d8a57523420: Pull complete
6c676912929f: Pull complete
3cdd8ff735c9: Pull complete
4c70cbe51682: Pull complete
e21cf0cb4dc3: Pull complete
28c36cd3abcc: Pull complete
Digest: sha256:6ded54eb1e5d048d8310321ba7b92587e9eadc83b519165b70bbe47e4046e76a #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实的
#两者等价
docker pull mysql
docker.io/library/mysql:latest
docker rmi 删除镜像
[root@localhost ~]$ sudo docker rmi -f 容器id #删除指定内容 [root@localhost ~]$ sudo docker rmi -f 容器id 容器id 容器id #删除多个容器 [root@localhost ~]$ sudo docker rmi -f $(docker images -aq)#删除全部的容器
容器命令
说明:我们有了镜像才可以创建容器,Linux,下载一个CentOS镜像来测试学习
docker pull centos
新建容器,并启动
docker run [可选参数] image #参数说明 --name="Name" 容器名字 tomcat01 tomcat02,用来区分容器 -d 后台方式运行 -it 使用交互方式运行,进入容器查看内容 -p 指定容器的端口 -p 8080:8080 -p ip:主机端口:容器端口 -p 主机端口:容器端口(常用) -p 容器端口 容器端口 -p 随机指定端口 #测试,启动并进入容器 [root@localhost ~]$ sudo docker run -it centos /bin/bash [sudo] root 的密码: [root@a4533364bee2 /]# ls #查看容器内的centos,基础版本,很多命令都是不完善的! bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var #从容器中退回主机 [root@a4533364bee2 /]# exit
列出运行中的容器
#docker ps命令 #列出当前正在运行的容器 -a #列出当前正在运行的容器+带出历史运行过的容器 -n=? #显示最近创建的容器 -q #只显示容器的编号 [root@localhost ~]$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@localhost ~]$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a4533364bee2 centos "/bin/bash" 9 minutes ago Exited (127) 3 minutes ago upbeat_keller 2a726ed3ab4b bf756fb1ae65 "/hello" 2 hours ago Exited (0) 2 hours ago blissful_maxwell
退出容器
exit #直接容器停止并退出 Ctrl+P+Q #容器不停止退出
删除容器
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,想要强制删除 rm -f docker rm -f $ (docker ps -aq) #删除所有的容器 docker ps -q|xargs docker rm #删除所有的容器
启动和停止容器操作
docker start 容器id #启动容器 docker restart 容器id #重启容器 docker stop 容器id # docker kill 容器id
常用其他命令
后台启动容器
#命令 docker run -d 镜像名 [root@localhost ~]$ sudo docker run -d centos #问题docker ps 发现centos停止了 #常见的坑,docker容器使用后台运行,就必须有一个前台进程,docker发现没有前台进程,就会自动把后台停止 #nginx 容器启动之后,发现自己没有提供服务,就会立即停止,就是没有程序了
查看日志
docker logs -f -t --tail 容器,没有日志
查看容器中进程信息
# 命令 docker top 容器id
镜像元数据
# 命令 docker inspect 容器id [root@localhost ~]$ sudo docker inspect b4af22c18647 [sudo] root 的密码: [ { "Id": "b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8", "Created": "2020-09-08T02:02:35.268831886Z", "Path": "/bin/bash", "Args": [], "State": { "Status": "exited", "Running": false, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 0, "ExitCode": 0, "Error": "", "StartedAt": "2020-09-08T02:04:58.767625388Z", "FinishedAt": "2020-09-08T02:04:58.778547336Z" }, "Image": "sha256:0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566", "ResolvConfPath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/resolv.conf", "HostnamePath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/hostname", "HostsPath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/hosts", "LogPath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8-json.log", "Name": "/nervous_gates", "RestartCount": 0, "Driver": "overlay2", "Platform": "linux", "MountLabel": "", "ProcessLabel": "", "AppArmorProfile": "", "ExecIDs": null, "HostConfig": { "Binds": null, "ContainerIDFile": "", "LogConfig": { "Type": "json-file", "Config": {} }, "NetworkMode": "default", "PortBindings": {}, "RestartPolicy": { "Name": "no", "MaximumRetryCount": 0 }, "AutoRemove": false, "VolumeDriver": "", "VolumesFrom": null, "CapAdd": null, "CapDrop": null, "Capabilities": null, "Dns": [], "DnsOptions": [], "DnsSearch": [], "ExtraHosts": null, "GroupAdd": null, "IpcMode": "private", "Cgroup": "", "Links": null, "OomScoreAdj": 0, "PidMode": "", "Privileged": false, "PublishAllPorts": false, "ReadonlyRootfs": false, "SecurityOpt": null, "UTSMode": "", "UsernsMode": "", "ShmSize": 67108864, "Runtime": "runc", "ConsoleSize": [ 0, 0 ], "Isolation": "", "CpuShares": 0, "Memory": 0, "NanoCpus": 0, "CgroupParent": "", "BlkioWeight": 0, "BlkioWeightDevice": [], "BlkioDeviceReadBps": null, "BlkioDeviceWriteBps": null, "BlkioDeviceReadIOps": null, "BlkioDeviceWriteIOps": null, "CpuPeriod": 0, "CpuQuota": 0, "CpuRealtimePeriod": 0, "CpuRealtimeRuntime": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": [], "DeviceCgroupRules": null, "DeviceRequests": null, "KernelMemory": 0, "KernelMemoryTCP": 0, "MemoryReservation": 0, "MemorySwap": 0, "MemorySwappiness": null, "OomKillDisable": false, "PidsLimit": null, "Ulimits": null, "CpuCount": 0, "CpuPercent": 0, "IOMaximumIOps": 0, "IOMaximumBandwidth": 0, "MaskedPaths": [ "/proc/asound", "/proc/acpi", "/proc/kcore", "/proc/keys", "/proc/latency_stats", "/proc/timer_list", "/proc/timer_stats", "/proc/sched_debug", "/proc/scsi", "/sys/firmware" ], "ReadonlyPaths": [ "/proc/bus", "/proc/fs", "/proc/irq", "/proc/sys", "/proc/sysrq-trigger" ] }, "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337-init/diff:/var/lib/docker/overlay2/f75740f43db3aa996a6f4b57893c909b313d94f1e2f2aff368ffe5532c3078d9/diff", "MergedDir": "/var/lib/docker/overlay2/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337/merged", "UpperDir": "/var/lib/docker/overlay2/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337/diff", "WorkDir": "/var/lib/docker/overlay2/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337/work" }, "Name": "overlay2" }, "Mounts": [], "Config": { "Hostname": "b4af22c18647", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/bash" ], "Image": "centos", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "org.label-schema.build-date": "20200809", "org.label-schema.license": "GPLv2", "org.label-schema.name": "CentOS Base Image", "org.label-schema.schema-version": "1.0", "org.label-schema.vendor": "CentOS" } }, "NetworkSettings": { "Bridge": "", "SandboxID": "1b993ccc98a55b6da5c5db799f1d8c5273d72810a3357b51ce776faa2bec96fc", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/1b993ccc98a5", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "", "Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "MacAddress": "", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "b1923d034b83452efca1c670efe2357579bdd03170647fa6f70761d46c5e9eb0", "EndpointID": "", "Gateway": "", "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "", "DriverOpts": null } } } } ]
进入当前正在运行的容器
# 我们通常容器都是使用后台的方式运行的,需要进入容器,修改一些配置 # 命令 docker exec -it 容器id #方式二:docker attach 容器id # docker exec # 进入容器后开启一个新的终端,可以在里面操作(常用) # docker attach # 进入容器正在执行的终端,不会启动新的进程
从容器内拷贝到主机上
#命令 docker cp 容器id:容器内路径 目的的主机路径 [root@localhost ~]$ sudo docker run -it centos /bin/bash [sudo] root 的密码: [root@7222c4dfd973 /]# [root@localhost ~]$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7222c4dfd973 centos "/bin/bash" 46 seconds ago Up 45 seconds vigilant_blackburn # 查看当前主机目录下的文件 [root@localhost ~]$ cd /home [root@localhost home]$ ls root [root@localhost home]$ sudo touch antia.java [root@localhost home]$ ls antia.java root [root@localhost home]$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7222c4dfd973 centos "/bin/bash" 2 minutes ago Up 2 minutes vigilant_blackburn # 进入容器内部 [root@localhost home]$ sudo docker attach 7222c4dfd973 [root@7222c4dfd973 /]# cd /home # 在容器内新建一个文件 [root@7222c4dfd973 home]# touch test.java [root@7222c4dfd973 home]# ls test.java [root@7222c4dfd973 home]# exit exit [root@localhost home]$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # 将文件拷贝到主机中 [root@localhost home]$ sudo docker cp 7222c4dfd973:/home/test.java /home [root@localhost home]$ ls antia.java test.java root # 拷贝是一个手动过程,未来我们使用-v卷的技术,可以实现,自动同步 容器/home 到 主机/home
docker命令是十分多的。
作业练习
-
nginx安装
# 1. 搜索镜像 search # 2. 下载镜像 pull # 3. 运行测试 # -d 后台运行 # --name 给容器命名 # -p 宿主机端口:容器内部端口 [root@localhost home]$ sudo docker run -d --name nginx01 -p 3344:80 nginx 6259fe2d44a41272eebd4719ac6fd18c088baf811a692db5f665faff5106cb5b [root@localhost home]$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6259fe2d44a4 nginx "/docker-entrypoint.…" 17 seconds ago Up 16 seconds 0.0.0.0:3344->80/tcp nginx01
[root@localhost home]$ curl localhost:3344 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
思考问题:
我们每次改动nginx配置文件,都需要进入容器内部?
十分麻烦,我要是在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改?-v 数据卷
-
docker来装一个tomcat
# 官方的使用 docker run -it --rm tomcat:9.0 # 我们之前的启动都是后台,停止容器之后,容器还是可以查到 一般用来测试,用完即删 # 一般下载再启动 docker pull tomcat # 启动运行 docker run -d -p 3355:8080 --name tomcat01 tomcat # 测试访问没有问题 192.168.72.129:3355 # 进入容器 docker exec -it tomcat01 /bin/bash # 发现问题 1. linux命令少了 2. 没有webapps 如果是的话,可能是阿里云的原因,默认是最小镜像,所有不必要的都剔除。 仅保证最小启动。
思考问题:我们以后要部署项目,如果每一次都要进入容器是不是十分麻烦?我要是在容器外部提供一个映射的路径,webapps,我们在外部放置项目,就自动同步到内部就好了。
-
部署es+kabana
# es 暴露端口很多 # es 耗内存 # 版本配置 7.6.2 # --net somenetwork 网络配置 docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag # 启动 elasticsearch docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2 # 测试es是否成功了 curl localhost:9200 # 启动 linux就很卡 docker stats 查看 cpu的状态 # es 是十分耗内存的,占用1.XG, 服务器不行 # 查看CPU状态 docker stats # 赶紧关闭,增加内存限制,修改配置文件 -e 环境配置修改 docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
使用kabana连接elasticsearch
-
可视化
-
portainer(先用这个)
docker run -d -p 8088:9000 \ --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
-
Rancher(CI/CD再用)
什么是portainer?
Docker图形化界面工具!提供一个后台面板供我们操作!
Docker镜像讲解
镜像是什么?
镜像是一种轻量级,可执行的的独立软件包,用来打包软件运行环境和基于环境运行的软件,它包含了某个软件所需的所有内容,包括代码,运行时,库,环境变量和配置文件。
所有的应用,直接打成docker镜像,就可以直接跑起来!
如何得到镜像:
-
从远程仓库下载
-
别人拷贝给你
-
自己制作一个镜像DockerFile
Docker镜像加载原理
UnionFS(联合文件系统)
联合文件系统(
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker分层理解
我们看到CentOS的镜像大小不到200MB,平时我们安装一个CentOS至少是几个GB,怎么可能才 200MB !
下面我们来解释这个问题,Linux 操作系统由内核空间和用户空间组成。
典型的Linux启动到运行需要两个FS,bootfs + rootfs,如下图:
rootf
内核空间是 kernel,Linux 刚启动时会加载 bootfs 文件系统,之后 bootfs 会被卸载掉。用户空间的文件系统是 rootfs,包含我们熟悉的 /dev, /proc, /bin 等目录。
对于 base 镜像来说,底层直接用 Host 的 kernel,自己只需要提供 rootfs 就行了。
而对于一个精简的 OS,rootfs 可以很小,只需要包括最基本的命令、工具和程序库就可以了。相比其他 Linux 发行版,CentOS 的 rootfs 已经算臃肿的了,alpine 还不到 10MB。
我们平时安装的 CentOS 除了 rootfs 还会选装很多软件、服务、图形桌面等,需要好几个 GB 就不足为奇了。
可以看到,新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。
问什么 Docker 镜像要采用这种分层结构呢?
最大的一个好处就是 - 共享资源。
比如:有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享,我们将在后面更深入地讨论这个特性。
这时可能就有人会问了:如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如 /etc 下的文件,这时其他容器的 /etc 是否也会被修改?
答案是不会! 修改会被限制在单个容器内。 这就是我们接下来要说的容器 Copy-on-Write 特性。
-
新数据会直接存放在最上面的容器层。
-
修改现有数据会先从镜像层将数据复制到容器层,修改后的数据直接保存在容器层中,镜像层保持不变。
-
如果多个层中有命名相同的文件,用户只能看到最上面那层中的文件。
Docker镜像
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层
如何提交一个自己的镜像
commit镜像
docker commit 提交容器成为一个新的副本 # 命令和git差不多 docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
实战测试
Dockerfile、Image、Container
Dockerfile Image Container 的关系.png
-
Dockerfile: 用于描述镜像的生成规则。 Dockerfile中的每一条命令,都在Docker镜像中以一个独立镜像层的形式存在。
-
Image: 由Dockerfile生成, 呈现层级结构, 每层镜像包含:镜像文件以及镜像json元数据信息。
-
Container: Container 是Image 的动态运行结果,概括而言,就是在Docker镜像之上,运行进程。
-