Docker
镜像(Image) :
docker镜像好比是一个模板,可以通过这个模板创建容器服务 tomcat镜像==>run==>tomcat01容器(提供服务器)
容器(Contaniner) :
Docker利用容器技术,独立运行一个或一个组应用。可以理解位一个简易的linux系统
仓库(Repository) :
仓库就是存放容器的地方!分为公有仓库和私有仓库
安装docker (centos7为例) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine # sudo yum install -y yum-utils # sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # yum makecache fast # sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # sudo systemctl start docker # docker version # sudo docker run hello-world
卸载docker 1 2 3 sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd
底层原理 Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问。 Docker-Server接收到Docker-Client的指令,就会执行这个命令!
Docker 常用命令 帮助命令 1 2 3 docker version # 显示docker的版本信息 docker info # 显示docker的系统信息 包括镜像和容器数量 docker 命令 --help # 帮助命令
镜像命令 1 2 3 4 docker images # 查看本地主机上的镜像 docker search # 搜索镜像 docker pull[:tag] # 下载镜像 不注明tag即最新 docker rmi # 删除镜像
容器命令 下载centos镜像作为测试学习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 docker pull centos # docker run[可选参数] image 参数说明 --name="Name" 容器名字 用于区分容器 --d 后台运行 --it 交互方式运行 进入容器查看内容 --P 随机指定端口 --p 指定容器端口 docker run -it centos exit # 停止容器退回主机 docker ps # 所有运行的容器 Ctrl + q + p # 退回主机不停止容器 docker rm 容器id # 删除指定容器 docker rm -rf $(docker ps -aq) #删除所有容器 docker start 容器id docker restart 容器id docker stop 容器id docker kill 容器id # 强制停止
常用其他命令
常见的坑:
docker 容器使用后台运行 必须要有一个前台进程
nginx,容器启动后,发现没有提供服务,就会立刻停止
查看日志 1 docker logs -f -t --tail 容器id
查看镜像源数据
进入当前正在运行的容器 1 2 3 docker exec -it 容器id /bin/bash #开启新的终端,可以在里面操作 # **OR** docker attach 容器id #进入容器正在执行的终端
拷贝容器内的数据至主机 1 docker cp 容器id:路径内路径 目的主机路径
commit镜像 1 2 docker commit # 提交容器成为一个新的副本 docker commit -m="提交的描述信息" -a="作者" 容器ID 目标镜像名:[TAG]
Docker-Nginx 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 docker pull nginx docker run -d --name nginx01 -p:3344:80 nginx #3344为linux端口 80为容器端口 curl localhost:3344 ====================================== [root@localhost elijah]# curl localhost:3344 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } 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> ======================================
Docker-TomCat 1 2 3 4 5 6 7 docker run -d -p 3355:8080 --name tomcat01 tomcat:9.0 curl localhost:3355 ====================================== [root@localhost elijah]# curl localhost:3355 # <!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/9.0.75</h3></body></html> ======================================
Docker-ES
Elasticsearch 暴露的端口很多!
Elasticsearch 十分得耗内存 1.xG
Elasticsearch 的数据一般需要挂载到安全目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.5.2 docker run -p 9200:9200 -p 9300:9300 -d -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.5.2 ====================================== [root@localhost elijah]# curl localhost:9200 { "name" : "c876dcd60451", "cluster_name" : "docker-cluster", "cluster_uuid" : "QhjzNz7JRiSSRzZqVT_PRw", "version" : { "number" : "7.5.2", "build_flavor" : "default", "build_type" : "docker", "build_hash" : "8bec50e1e0ad29dad5653712cf3bb580cd1afcdf", "build_date" : "2020-01-15T12:11:52.313576Z", "build_snapshot" : false, "lucene_version" : "8.3.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" } ======================================
可视化 portainer 1 2 3 4 5 6 7 8 docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer # 测试 curl localhost:8088 <!DOCTYPE html > <html lang="en" ng-app="portainer" > # 外网访问 http://ip:8088
容器数据卷 目的 为了数据持久化和同步操作,将容器内的数据挂载出来 容器与容器也可以数据共享
使用数据卷 1 2 3 4 5 6 # -v docker run -it -v 主机目录,容器内目录 # docker run -it -v /home/ceshi:/home centos /bin/bash docker inspect 容器id
Mysql
运行数据库需要数据挂载
1 2 docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
具名和匿名挂载 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 # 匿名挂载 -v 容器内路径 docker run -d -P --name nginx01 -v /etc/nginx nginx # -P 随机指定端口 # 查看所有volume的情况 docker volume ls DRIVER VOLUME NAME local 561b81a03506f31d45ada3f9fb7bd8d7c9b5e0f826c877221a17e45d4c80e096 local 36083fb6ca083005094cbd49572a0bffeec6daadfbc5ce772909bb00be760882 # 这里发现,这种情况就是匿名挂载,我们在-v 后面只写了容器内的路径,没有写容器外的路径! # 具名挂载 docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx 26da1ec7d4994c76e80134d24d82403a254a4e1d84ec65d5f286000105c3da17 docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 26da1ec7d499 nginx "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 0.0.0.0:32769->80/tcp nginx02 486de1da03cb nginx "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 0.0.0.0:32768->80/tcp nginx01 docker volume ls DRIVER VOLUME NAME local 561b81a03506f31d45ada3f9fb7bd8d7c9b5e0f826c877221a17e45d4c80e096 local 36083fb6ca083005094cbd49572a0bffeec6daadfbc5ce772909bb00be760882 local juming-nginx # 通过-v 卷名:容器内的路径 # 查看一下这个卷 # docker volume inspect juming-nginx docker volume inspect juming-nginx [ { "CreatedAt": "2020-08-12T18:15:21+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data", "Name": "juming-nginx", "Options": null, "Scope": "local" } ] # 所有docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxxx/_data # 我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用的是具名挂载 # 如何确定是具名挂载还是匿名挂载,还是指定路径挂载! -v 容器内路径 # 匿名挂载 -v 卷名:容器内路径 # 具名挂载 -v /主机路径:容器内路径 # 指定路径挂载 # 通过 -v 容器内容路径 ro rw 改变读写权限 ro readonly # 只读 rw readwrite # 可读可写 docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx # ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内容无法操作
数据卷容器 多个mysql同步数据!
1 2 3 docker run -d -p 3344:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 docker run -d -p 3344:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
DockerFile
dockerfile 就是用来构建docker镜像的构建文件!
构建步骤
1 2 3 4 >>1.编写一个dockerFile文件 >>2.docker build 构建成为一个镜像 >>3.docker run 运行镜像 >>4.docker push 发布镜像(DockerHub、阿里云镜像)
1 2 3 4 5 6 7 8 9 10 11 mkdir dockerfile vim dockerfile01 FROM centos ============ VOLUME ["volume01","volume02"] CMD echo "-----end-----" CMD /bin/bash ============ docker build -f dockerfile1 -t xiaowo/centos:1.0 . docker images
指令 # 每行都会提交一个新的镜像层
FROM # 基础镜像,一切从这里开始构建 MAINTAINER # 镜像是谁写的, 姓名+邮箱 RUN # 镜像构建的时候需要运行的命令 ADD # 步骤, tomcat镜像, 这个tomcat压缩包!添加内容 WORKDIR # 镜像的工作目录 VOLUME # 挂载的目录 EXPOSE # 保留端口配置 CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效可被替代 ENTRYPOINT # 指定这个容器启动的时候要运行的命令, 可以追加命令 ONBUILD # 当构建一个被继承DockerFile 这个时候就会运行 ONBUILD 的指令,触发指令 COPY # 类似ADD, 将我们文件拷贝到镜像中 ENV # 构建的时候设置环境变量!
实战测试
创建一个自己的centos
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@localhost docker-test-volume]# vim mycentos [root@localhost docker-test-volume]# cat mycentos FROM centos:centos7 MAINTAINER XIAOWO<19857178394@163.com> ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "---end---" CMD /bin/bash [root@localhost docker-test-volume]# docker build -f mycentos -t mycentos:0.1 .
Tomcat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 FROM centos MAINTAINER xiaowo<19857178394@163.com> COPY readme.txt /usr/local/readme.txt ADD jdk-8u73-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.37.tar.gz /usr/local/ RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_73 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.37 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.37 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.37/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.37/bin/logs/catalina.out
Docker网络
理解docker0 -Link 思考一个场景,我们编写了一个微服务,database url =ip; 项目不重启,数据ip换掉了,我们希望可以处理这个问题,可以按名字来进行访问容器
1 2 docker run -d -P --name tomcat03 --link tomcat02 tomcat # 3可ping2 2不可ping3
-自定义网络 网络模式 1 2 3 4 5 [root@localhost docker-test-volume]# docker network ls NETWORK ID NAME DRIVER SCOPE dda70ac5191c bridge bridge local 00d9897200c1 host host local 34a89431ba8e none null local
bridge 网络模式 在该模式中,Docker 守护进程创建了一个虚拟以太网桥 docker0
,新建的容器会自动桥接到这个接口,附加在其上的任何网卡之间都能自动转发数据包。
默认情况下,守护进程会创建一对对等虚拟设备接口 veth pair
,将其中一个接口设置为容器的 eth0
接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似 vethxxx
这样的名字命名,从而将宿主机上的所有容器都连接到这个内部网络上。
host 网络模式 host 网络模式需要在创建容器时通过参数 --net host
或者 --network host
指定;
采用 host 网络模式的 Docker Container,可以直接使用宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换;
host 网络模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。
none 网络模式 none 网络模式是指禁用网络功能,只有 lo 接口 local 的简写,代表 127.0.0.1,即 localhost 本地环回接口。在创建容器时通过参数 --net none
或者 --network none
指定;
none 网络模式即不为 Docker Container 创建任何的网络环境,容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。可以说 none 模式为 Docke Container 做了极少的网络设定,但是俗话说得好“少即是多”,在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制开发。这也恰巧体现了 Docker 设计理念的开放。
container 网络模式
Container 网络模式是 Docker 中一种较为特别的网络的模式。在创建容器时通过参数 --net container:已运行的容器名称|ID
或者 --network container:已运行的容器名称|ID
指定;
处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用 localhost 高效快速通信。
Container 网络模式即新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等 。同样两个容器除了网络方面相同之外,其他的如文件系统、进程列表等还是隔离的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # 我们直接启动的命令默认有一个 --net bridge,而这个就是我们的docker0 docker run -d -P --name tomcat01 tomcat docker run -d -P --name tomcat01 --net bridge tomcat # docker0特点,默认,容器名不能访问, --link 可以打通连接! # 我们可以自定义一个网络! # --driver bridge # --subnet 192.168.0.0/16 可以支持255*255个网络 192.168.0.2 ~ 192.168.255.254 65535 # --gateway 192.168.0.1 网关 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 26a5afdf4805d7ee0a660b82244929a4226470d99a179355558dca35a2b983ec [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 30d601788862 bridge bridge local 226019b14d91 host host local 26a5afdf4805 mynet bridge local 7496c014f74b none null local