docker 基础
一.docker 什么是 docker? Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux 或 Windows 操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
docker 基本组成 docker 的基本组成:客户端,服务器,镜像仓库。 镜像( image ): docker 镜像就好比是一个模板,可以通过这个模板来创建容器服务, 通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的),镜像没有启动,停止 这些操作 容器( container ): Docker 利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的。 启动,停止,刪除,基本命令! 目前就可以把这个容器理解为就是一个简易的 inux 系统 仓库( repository ): 仓库就是存放镜像的地方! 仓库分为公有仓库和私有仓库! Docker Hub(默认是国外的) 阿里云 腾讯云 …都有容器服务器(配置镜像加速!)
二.docker 安装 环境:CentOS Linux release 7.7.1908 (Core)/版本:3.10.0-1062.el7.x86_64
卸载旧的版本
1 2 3 4 5 6 7 8 yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
安装需要的包
1 yum install -y yum-utils
设置镜像仓库
1 2 3 4 5 yum -y install docker-ce docker-ce-cli containerd.io yum -y install docker-ce-20.10.* docker-ce-cli-20.10.* containerd.io docker-ce docker version
更新 yum 软件包索引
安装 docker
启动 docker
运行 hello-world 进行验证
查看运行的 hello-world
卸载 docker
1 2 3 4 1.删除安装包 yum remove docker-ce docker-ce-cli containerd.io 2.删除镜像、容器、配置文件等内容 rm -rf /var/lib/docker
阿里云镜像加速
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 mkdir -p /etc/dockertee /etc/docker/daemon.json <<-'EOF' { "exec-opts" : ["native.cgroupdriver=systemd" ], "registry-mirrors" : [ "http://hub-mirror.c.163.com" , "https://docker.m.daocloud.io" , "https://dockerproxy.com" , "https://docker.mirrors.ustc.edu.cn" , "https://docker.nju.edu.cn" , "https://docker.m.daocloud.io" , yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum makecache fast yum -y install docker-ce docker-ce-cli containerd.io yum -y install docker-ce-20.10.* docker-ce-cli-20.10.* containerd.io docker-ce docker version systemctl start docker docker run hello-world docker images "https://dockerproxy.com" , "https://docker.mirrors.ustc.edu.cn" , "https://docker.nju.edu.cn" ] } EOF systemctl daemon-reload systemctl restart docke
三.底层原理
Docker 是怎么工作的? Docker 是一个 Client-Server 结构的系统,Docker 的守护进程运行在主机上。通过 Socket 从客户端访问! DockerServer 接收到 Docker-Client 的指令,就会执行这个命令!
Docker 为什么比 VM 快?
1、Docker 有着比虚拟机更少的抽象层。
2、docker 利用的是宿主机的内核,vm 需要是 Guest OS。 所以说,新建一个容器的时候,docker 不需要像虚拟机一样重新加载一个操作系统内核,避免引导。 虚拟机是加载 GuestOS,分钟级别的,而 docker 是利用宿主机的操作系统,省略了这个复杂的过程,秒级!
四.Docker 常用命令
帮助命令
1 2 3 docker version docker info docker 命令 --help
列出 docker 下的镜像
1 2 3 4 5 6 7 8 9 10 11 12 testroot@heber ~# docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest feb5d9fea6a5 7 months ago 13.3kB REPOSITORY 镜像的仓库源 TAG 镜像的标签 IMAGE ID 镜像的id CREATED 镜像的创建时间 SIZE 镜像的大小 -a, --all -q, --quiet
在镜像仓库搜索某一个镜像
1 2 3 4 5 6 [root@heber ~]# docker search --limit 5 redis NAME DESCRIPTION STARS OFFICIAL AUTOMATED 镜像名称 镜像说明 点赞数量 是否为官方的 是否是自动构建的 --filter=STARS=3000 bash
docker 下载镜像
查看镜像所占空间
docker 删除镜像
1 2 3 4 docker rmi -f IMAGEID docker rmi -f 镜像 id docker rmi -f 镜像 id 镜像 id 镜像 id docker rmi -f $(docker images -aq)
导出导入镜像
1 2 3 4 5 6 docker save -o 要保存的文件名 要保存的镜像 docker save -o /opt/mysql.tar mysql:5.7 docker load --input 文件 docker load --input mysql.tar
五.docker 容器命令 1.新建+启动容器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 docker run [可选参数] image --name="name" 容器名字:用来区分容器 -d 后台方式运行:相当于 nohup -it 使用交互式运行:进入容器查看内容 -p 指定容器的端口(四种方式) -P 随机指定端口(大写字母 P) -p ip:主机端口:容器端口 -p 主机端口:容器端口(常用) -p 容器端口 docker run -it ubuntu /bin/bash for i in {1..4} ;do docker run -d --name=nginxtest$i nginx:1.18.0 ; done docker run -id --name=nginx1.18.0 -p 80:80 \ -v /docker_nginx/conf:/etc/nginx \ -v /docker_nginx/html:/usr/share/nginx/html \ -v /docker_nginx/logs:/var/log/nginx \ nginx:1.18.0
退出容器
列出正在运行的容器
1 2 3 4 5 6 7 8 9 10 docker ps -a -n=? -q [root@heber ~]# docker ps -alnq CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAME 容器 ID 镜像 命令 创建时间 状态 端口 容器新名字
删除容器
1 2 3 4 docker rm 容器 id docker rm -f $(docker ps -aq) docker ps -a -q|xargs docker rm for i in `docker ps -a|grep nginxtest|awk '{print $1}' `;do docker rm $i ;done
启动已停止运行的容器
1 2 3 4 docker start 容器 id docker restart 容器 id docker stop 容器 id docker kill 容器 id
后台启动容器
7.查看容器日志
1 2 3 4 5 docker logs -tf --tail 容器 id -tf --tail number
查看容器内的进程
查看容器内部细节
进入正在运行的容器
1 2 3 4 5 docker exec -it 容器 id /bin/bash docker attach 容器 id
从容器拷贝数据到主机
1 2 docker cp 容器 id :容器内路径 目标主机路径 docker cp 667fa4fec647:/tmp/1.txt /tmp
导入和导出容器 #导出
1 2 3 docker export 容器 id >文件名.tar cat 文件名.tar | docker import-镜像用户/镜像名:镜像版本号cat ubuntu.tar |docker import - ubuntu:18.0.0
六.小结练习 1.docker 安装 nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 1.搜索镜像: (建议去 dockerHub 上去搜索) [root@localhost ~]# docker search nginx 2.下载镜像:docker pull nginx [root@localhost ~]# docker pull nginx:1.8 3.启动 nginx: [root@localhost ~]# docker run -d --name nginxtest -p 80:80 nginx 4.查看进程 [root@localhost ~]# docker ps 5.测试 http://ip:80
2.docker 安装 tomcat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1.搜索 Tomcat [root@localhost ~]# docker search tomcat 2.下载镜像 docker pull tomcat:8 3.启动 docker run -d --name tomcattest -p 8080:8080 tomcat:8 4.查看进程 [root@localhost ~]# docker ps 5.进入容器 [root@localhost ~]# docker exec -it tomcattest /bin/bash 6.把 webapps.dist 文件夹下的文件复制到 webapps 文件夹下 root@6b278de8bce0:/usr/local/tomcat# cp -r webapps.dist/\* webapps/ 7.退出保持后台运行 ctrl+q+p 8.测试 http://ip:8080
七.可视化 portainer
portainer 是什么 是一款轻量级的应用,它提供了图形化界面,用于方便管理 docker 环境,包括单机环境和集群环境
安装
1 2 3 4 5 https://www.portainer.io/ docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
访问
1 2 http://192.168.0.119:9000/ admin/admin123.
八.docker 镜像详解
docker 镜像是什么 镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件 所需的所有内容,包括代码、运行时、库、环境变量和配置文件。 所有的应用,直接打包 docker 镜像,就可以直接跑起来! 如何得到镜像:
从远程仓库下载
朋友拷贝给你
自己制作一个镜像 DockerFile
commit 镜像 commit 提交容器副本使之成为一个新的镜像 docker commit -m=”提交的描述信息” -a=”作者” 容器 id 目标镜像名:[TAG] #案列演示 Ubuntu 安装 vim apt-get update #更新包 apt-get -y install vim #安装 vim docker commit -m=”Ubuntu_vim”-a”heber” a23fe6a14871 myubuntu:18.0.24
发布自己的镜像1.发布到 dockerhub 上 https://hub.docker.com/注册自己的账号,确定这个账号可以登录在我们服务器上提交自己的镜像
1 2 3 docker login -u username docker push 镜像名:[tag]
2.发布到阿里云上 登录阿里云账号,找到镜像容器服务,创建命名空间(一个账号只能创建 3 个命名空间),创建镜像仓库,浏览相关 操作命令。
1 2 3 docker login --username=username xxxxx docker tag imageid xxxxxx docker push 镜像名:[tag]
九.docker 容器数据卷 容器卷是什么? 将 docker 容器内的数据保存进宿主机的磁盘中 容器卷记得加入参数–privileged=true 表示开启权限
使用数据卷 直接使用命令来挂载:-v
1 2 3 docker run -it --privileged=true -v /宿主机绝对路径:/容器内目录 镜像名 docker inspect 容器 id
测试安装 MySQL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 docker search mysql docker pull mysql docker images mkdir /app/mysqldocker run -d -p 3306:3306 --privileged=true \ -v /app/mysql/log:/var/log/mysql \ -v /app/mysql/data:/var/lib/mysql \ -v /app/mysql/conf/:/etc/mysql/conf.d \ -e MYSQL_ROOT_PASSWORD=123456 \ --name mysql5.7 \ mysql:5.7 docker exec -it mysql /bin/bash mysql -uroot -p123456
匿名和具名挂载 如何确定是具名挂载,还是匿名挂载,还是指定路径挂载
1 2 3 -v 容器内的路径 -v 卷名:容器内的路径 -v /宿主机路径:容器内路径
拓展 通过 -v 容器内的路径:ro rw 改变读写权限
1 2 3 4 5 6 ro read only rw read write docker run -d -p 80:80 --name nginx -v my-nginx:/etc/nginx:ro nginx docker run -d -p 80:80 --name nginx -v my-nginx:/etc/nginx:rw nginx
十.dockerfile
dockerfile 是什么? dockerfile 是用来构建 docker 镜像的文本文件命令脚本!。 通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个一个的命令,每个命令都是一层! 基础知识
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序执行
3、# 表示注释
4、每一个指令都会创建 提交一个新的镜像层,并提交! 容器之间可以相互同步,几个容器共享时只要删除其他容器之后还有一个存在里面的数据都不会丢失
1 2 docker run -it --name nginx02 --volumes-from nginx01 nginx:1.8 nginx02 --volumes-from nginx01 两个容器之间相互同步
dockerfile 常用保留字指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 FROM MAINTAINER RUN EXPOSE WORKDIR USER ENV ADD COPY VOLUME CMD ENTRYPONIT ONBUILD COPY
实例 #创建 dockerfile 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 vim Dockerfile FROM centos MAINTAINER heber<heber@123.com> ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim RUN yum -y install net-tools RUN yum -y install glibc.i686 RUN mkdir /usr/local/java ADD Jdk-8u171-linux-x64.tar.gz /usr/local/java ENV JAVA_HOME /usr/local/java/jdk1.8.0_171 ENV JRE_HOME $JAVA_HOME /jre ENV CLASSPATH $JAVA_HOME /lib/dt.jar:$JAVA_HOME /lib/tools.jar:$JAVA_HOME /lib:$CLASSPATH ENV PATH $JAVA_HOME /bin:PATH EXPOSE 8080 CMD echo $MYPATH CMD echo 'success......ok' CMD /bin/bash
构建
1 docker build dockerfilename -t 镜像名字:tag .
查看已经构造的镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcat 8 2d2bccf89f53 13 months ago 678MB mysql 5.7 c20987f18b13 13 months ago 448MB portainer/portainer latest 580c0e4e98b0 22 months ago 79.1MB nginx 1.8 0d493297b409 6 years ago 133MB [root@localhost ~]# docker history 0d493297b409 IMAGE CREATED CREATED BY SIZE COMMENT 0d493297b409 6 years ago /bin/sh -c <missing> 6 years ago /bin/sh -c <missing> 6 years ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx… 22B <missing> 6 years ago /bin/sh -c apt-key adv --keyserver hkp://pgp… 8.19MB <missing> 6 years ago /bin/sh -c <missing> 6 years ago /bin/sh -c <missing> 6 years ago /bin/sh -c <missing> 6 years ago /bin/sh -c
实战 tomcat 镜像 准备镜像文件:tomcat 压缩包,jdk 的压缩包! 编写 dockerfile 文件,官方命名 Dockerfile ,build 会自动寻找这个文件,就不需要-f 指定文件名了!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 FROM centos:7 MAINTAINER heber<heber@163.com> COPY readme.txt /usr/local/readme.txt ADD jdk-8u271-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.5.tar.gz /usr/local/ RUN yum -y install vim RUN yum -y install net-tools ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_271 ENV CLASS_PATH $JAVA_HOME /lib/dt.jar:$JAVA_HOME /lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.5 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.5 ENV PATH $PATH :$JAVA_HOME /bin:$CATALINA_HOME /lib:$CATALINA_HOME /bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.5/bin/startup.sh && tail -F /usr/local/apache-tomcat- 9.0.5/bin/logs/catalina.out
十一. docker 网络 linux 是可以 ping 通容器的网络的。容器和容器之间也是可以相互 ping 通的。只要容器一删除,对应的一对网桥就一起被删除。 我们每启动一个 docker 容器,docker 就会给 docker 容器分配一个 ip,我们只要安装了 ddcker,就会有一个网卡 docker0(桥接模式,使用的技术是 veth-pair 技术)
查看容器的内部网络地址
1 docker exec -it 容器 id ip addr
容器互联 link 编写了一个微服务,database url=ip:,项目不重启,数据库 ip 换掉了,我们希望可以处理这个问题,可以用名字来进行访问容器
1 2 docker run -d -P --name tomcat03 --link tomcat02 tomcat:8.0
查看 docker 网络模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE dc2cbff90c52 bridge bridge local f3a59ab02850 host host local c130e4e8fe19 none null local bridge host none container [root@localhost ~]# docker network inspect dc2cbff90c52 |grep bridge "Name" : "bridge" , "Driver" : "bridge" , "com.docker.network.bridge.default_bridge" : "true" , "com.docker.network.bridge.enable_icc" : "true" , "com.docker.network.bridge.enable_ip_masquerade" : "true" , "com.docker.network.bridge.host_binding_ipv4" : "0.0.0.0" , "com.docker.network.bridge.name" : "docker0" , 容器间的互联和通信以及端口映射
自定义网络
1 2 3 4 5 6 7 docker run -d -P --name tomcato1 --het bridge tomcat docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet docker run -d -P --name tomcat-net-01 --net mynet tomcat:7.0 docker run -d -P --name tomcat-net-02 --net mynet tomcat:7.0
网络连通 tomcat01 在 docker0 网络下,tomcat-net-01 在 mynet 网络下; tomcat01 ping tomcat-net-01 是 ping 不通的
1 2 3 4 5 6 docker network connect mynet tomcat01
十二.docker_compose 容器编排
是什么 docker_compose 是 docker 官方开源项目,负责实现对 docker 容器集群的快速编排,多服务管理工具
能干嘛 用来管理容器实例 compose 允许用户通过一个单独的 docker_compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目
去哪里下
1 2 3 4 5 6 7 8 9 10 https://docs.docker.com/compose/install curl -L https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linuxx86_64 -o usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-composedocker-compose version rm -f /usr/local/bin/docker-compose
conpose 核心概念 #一个文件 docker-compose.yml # 两大要素 服务 #一个个应用容器实例 工程 #由一组关联的应用容器组成的完整业务单元,在 docker-compose.yml 文件中定义
compose 常用命令
1 2 3 4 5 6 7 8 9 10 11 12 13 docker-compose -h docker-compose up docker-compose up -d docker-compose down docker-compose exec yml 里面的服务 id docker-compose ps docker-compose top docker-compose logs yml 容器 id docker-compose config docker-compose config -q docker-compose start docker-compose restart docker-compose stop
conpose 编排微服务
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 56 57 58 59 60 61 62 63 vim docker-conpose.yml version:"3" servers: microSerice: image:heber_docker:1.8 container_name:ms01 ports: -"6001:6001" volumes: - /app/microSerice:/data networks: - heber_net depends_no: - redis - mysql redis: image:redis:6.0.8 ports: -"6379:6379" volumes: - /app/redis/redis.conf:/etc/redis/redis.conf - /app/redis/data:/data networks: - heber_net command :redis-server /etc/redis/redis.conf nginx: image: nginx:1.8 container_name: nginx restart: always ports: - "80:80" - "443:443" volumes: - /nginx/conf/nginx.conf:/etc/nginx/nginx.conf - /nginx/conf.d:/etc/nginx/conf.d - /nginx/html:/usr/share/nginx/html - /nginx/logs:/var/log/nginx networks: - heber_net networks: heber_net: mysql: image:mysql:5.7 environment: MYSQL_ROOT_PASSWORD:"123456" MYSQL_ALLOW_EMPTY_PASSWORD:"no" MYSQL_DATABASE:"db2022" MYSQL_USER:"heber" MYSQL_PASSWORD:"heber123" ports: -"3306:3306" volumes: - /app/mysql/db:/var/lib/mysql - /app/mysql/conf/my.cnf:/etc/my.cnf - /app/mysql/init:/docker-entrypoint-initdb.d networks: - heber_net command :--default-authentication-plugin=mysql_native_password networks: heber_net
nginx+tomcat+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 version: "3" services: nginx: image: nginx:1.8 container_name: nginx expose: - 80 - 443 ports: - 80:80 - 443:443 volumes: - /data/nginx/nginx.conf:/etc/nginx/nginx.conf - /data/nginx/html:/usr/share/nginx/html - /data/nginx/nginx/conf.d:/etc/nginx/conf.d - /data/nginx/logs:/var/log/nginx restart: always networks: - wd_net depends_on: - tomcat tomcat: image: tomcat:9.0.71 container_name: tomcat9 ports: - 8080:8080 volumes: - /data/tomcat/:/usr/local/tomcat/webapps networks: - wd_net links: - mysql mysql: image: mysql:5.7 container_name: mysql expose: - 3306 ports: - 3306:3306 environment: MYSQL_ROOT_PASSWORD: "123456" TZ: Asia/Shanghai" restart: always volumes: - /data/mysql/db:/var/lib/mysql - /data/mysql/init:/docker-entrypoint-initdb.d networks: - wd_net command: --character-set-server=utf8 --collation-server=utf8_general_ci networks: wd_net:
十三.docker swarm docker swarm 用来做集群使用,地址:https://docs.docker.com/engine/swarm/ 准备 2 台服务器,并且都安装上 docker 有两种类型的节点:管理节点,工作节点
swarm 集群搭建docker swarm --help 可以查看命令
1 2 3 4 5 6 7 8 9 10 11 12 docker swarm init --advertise-addr ip docker swarm join-token manager docker swarm join-token worker docker swarm leave docker node ls docker swarm leave --force
删除工作节点
1 2 3 docker swarm leave docker node rm docker-node1
查看集群中节点信息
1 docker node inspect docker-node1 --pretty
调度
1 2 3 4 5 6 docker node update --availability active docker-node1 docker node update --availability pause docker-node1 docker node update --availability drain docker-node1
标签
1 2 3 docker node update --label-add label1 docker-node1 docker node update --label-rm label1 docker-node1
manager 与 worker 互换
1 2 3 docker node promote docker-node1 docker node demote docker-node1
服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 docker service ls docker service ps my-test docker service create --name my-nginx nginx:1.18.0 docker service rm my-nginx docker service create --name my-nginx --replicas 2 -p 80:80 nginx:1.18.0 docker service update --publish-add 80:80 my-nginx docker service update --publish-rm 80:80 my-nginx docker service update --image redis:3.0.7 redis docker service create --name my-nginx --env MYVAR=myvalue --workdir /data/www --user my_user nginx docker service create --name my_nginx --reserve-cpu 2 --reserve-memory 512m --replicas 3 nginx docker service update --reserve-cpu 1 --reserve-memory 256m my_nginx