docker 官方文档 https://docs.docker.com/engine/install/
Docker的镜像称为image,容器称为container。对于Docker来说,image是静态的,类似于操作系统快照,而container则是动态的,是image的运行实例。
有了镜像才能创建容器,如果数据在容器里,删除容器会丢失数据,数据持久化请看数据卷
安装gcc
卸载旧版本
安装所需软件
设置仓库
国外
国内
更新yum
安装docker
配置阿里云镜像加速
找到 “容器镜像服务”–>“镜像加速器” 菜单
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
启动docker
开机自启动docker
基础命令
查看本地镜像 docker images
删除镜像 docker rmi -f(rm代表remove,i代表image,-f代表force强制) 可以通过ID删,也可以通过名称删
通过ID删除镜像 docker rmi -f c8562eaf9d81
通过名称删除镜像 docker rmi -f mysql:latest
删除全部镜像 docker rmi -f $(docker images -aq)
运行容器 docker run -it REPOSITORY(-it交互执行,没加 -it ,进入不了。)
查看运行容器 docker ps
查看所有容器 docker ps -a
重新进入容器 docker attach ConTAINER ID
重新进入容器2 docker exec -it NAMES /bin/bash (加-it,才有终端)
启动容器 docker start ConTAINER ID
重启容器 docker restart ConTAINER ID
终止容器 docker stop ConTAINER ID
强制终止容器 docker kill ConTAINER ID
删除容器 docker rm ConTAINER ID
强制删除容器(-f 强制删除,包括运行中的) docker rm -f container-name
删除全部容器 docker rm $(docker ps -a)
强制删除所有容器(-f 强制删除,包括运行中的) docker rm -f $(docker ps -a)
创建容器时设置名称 docker run -d --name hadoop_master ubuntu:hadoop
重命名容器 docker rename peaceful_gould hadoop_slave1
退出容器并停止 exit
退出容器不停止 ctrl+p+q
退出输入状态 ctrl+c
拷贝容器文件到主机 docker cp ConTAINER ID 容器路径 主机路径
查看是否挂载成功 docker inspect ConTAINER ID
查看日志 docker logs -f redis
设置redis自启动 docker update redis --restart=always
https://hub.docker.com/search?q=mysql&type=image
或用命令 docker search mysql 搜索,得到如下图,两个结果是对应的
docker pull mysql:5.7
指定下载 docker pull 镜像名[:tag],不写tag默认最新版,版本号一定要在dockerhub里面有,如下图
另外:以下一条一条下载称为分层下载,是docker核心 联合文件系统
启动mysql
docker run -d 后台运行
-p 3306:3306 主机端口:容器端口,将容器端口映射到主机端口
-e MYSQL_ROOT_PASSWORD=密码 初始化root用户的密码,-e为配置环境
-v /mydata/mysql/conf:/etc/mysql 主机目录:容器目录,将配置文件夹挂载到主机
-v /mydata/mysql/log:/var/log/mysql 主机目录:容器目录,将日志文件夹挂载到主机
-v /mydata/mysql/data:/var/lib/mysql 主机目录:容器目录,将数据文件夹挂载到主机
设置mysql自启动
修改配置文件 vi /mydata/mysql/conf/my.cnf
先创建redis目录与redis文件,防止挂载时把redis.conf当成目录
设置持久化与密码,vi /mydata/redis/conf/redis.conf 在redis.conf中加入
启动docker
设置redis自启动
进入redis
输入密码
退出
redis获取数据库个数
查看redis当前所有的key
查看redis当前的配置信息
docker run -d --name ngnix01 -p 3344:80 nginx【-d 后台运行 --name 命名容器 -p 宿主端口:内部端口(端口暴露)】
主机内部测试 curl localhost:3344
docker run -d --name tomcat01 -p 8081:8080 tomcat:9.0
主机内部测试 curl localhost:8081
运行portainer
docker pull portainer/portainer-ce
docker run -d -p 8088:9000 --restart always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
提交镜像
docker commit -a=“chen” -m=“my docker” 【container-name】tomcatchen:1.0 (-a为author,-m为message,tomcatchen为自定义名称 要求小写字母,1.0为自定义版本)
指定路径挂载
使用命令挂载 -v ,docker run -it -v 主机目录:容器目录,例如 docker run -it -v /home/ceshi:/home centos
查看是否挂载成功, docker inspect ConTAINER ID,成功会显示如下挂载代码
测试:touch testshujujuan.txt ,查看主机目录与容器目录是否都有
在关闭容器的情况下,在主机目录 vim testshujujuan.txt 编辑文件,再重启容器 cat testshujujuan.txt,如下图可看到也是可以成功同步到主机,所以无论容器是否启动,挂载完都可以自动同步
优势是修改文件只到主机修改即可,不用每次都进入容器
匿名挂载
docker run -d -P --name nginx01 -v /etc/nginx nginx (P为随机端口)
docker volume ls 查看所有卷的情况,如下图就是匿名卷,匿名挂载(-v 只写容器内路径,没有写容器外路径)
具名挂载
docker run -d -P --name nginx02 -v chen-nginx:/etc/nginx nginx (P为随机端口)
注意:chen-ngin没有加/是名字不是路径
docker volume ls 查看所有卷的情况,如下图名称
docker volume inspect chen-nginx 查看卷路径
没有指定路径的情况 卷都会在/www/server/docker/volumes/chen-nginx/_data
docker run -d -P --name nginx02 -v chen-nginx:/etc/nginx:ro nginx 【ro为readonly设为只读,设置为只读,挂载出来的内容就有相应约束,,ro只能通过宿主机来操作,不能通过容器操作】
docker run -d -P --name nginx02 -v chen-nginx:/etc/nginx:rw nginx 【rw为readwrite设为可读写】
mkdir docker-test-volume 创建目录
cd docker-test-volume 进入目录
vim dockerfile1 新建docker文件
dockerfile1内容:(注意:指令都是大写,每个指令都是一层镜像,镜像是一层一层的,下面#部分记得去掉)
docker build -f dockerfile1 -t chen/centos . (-f为force强制,-t为target目标,.为当前目录)
如图为挂载的,和外部目录有同步
cd volume01 进入volume01
touch inner.txt 在容器内创建inner.txt
docker ps 得到ConTAINER ID
docker inspect 【ConTAINER ID】,可以看到容器路径
用FTP链接可以看到如下
docker run -it --name centos01 chen/centos 启动第一个容器
docker run -it --name centos02 --volumes-from centos01 chen/centos 通过–volumes-from相当于继承son extend father,绑定上数据同步
ctrl+p+q 退出容器不停止
docker attach fae490bc72b5 进入容器
cd volume01 进入数据卷
touch centos01.txt
ctrl+p+q 退出容器不停止
docker attach 5d13641c890f 进入容器2
cd volume01 进入数据卷
如下图,文件已同步到centos02容器的卷中
删除其中一个容器,并不影响其他容器,数据不会丢失
同步多个mysql
dockerhub中99%镜像都是从FROM scratch过来的,然后配置需要的软件
创建dockerfile
cd /home
mkdir dockerfile
cd dockerfile
vim mydockerfile
按i键 插入内容
dockerfile1内容:(注意:指令都是大写,每个指令都是一层镜像,镜像是一层一层的)
Esc
:wq 保存退出
cat mydockerfile 查看文件内容是否编写成功
执行dockerfile
docker build -f mydockerfile -t mycentos . (-f为force强制,-t为target目标,. 为当前目录)
docker history 【REPOSITORY】查看镜像历史变更
到dockerhub注册账户 https://hub.docker.com/
docker login -u 用户名
再输入密码
docker tag local-image:tagname new-repo:tagname (local-image:tagname为本地镜像和版本号,也可以用ID,new-repo:tagname为dockerhub中的用户名加名称)
docker push new-repo:tagname
创建命名空间
创建容器镜像
仓库,进去可以看到具体教程
三个网络
查看容器内部网络地址
docker exec -it tomcat01 ip addr
注意:
每启动一个docker容器,就会给docker分配一个ip;
只要安装docker,就会有一个网卡 docker0;
桥接模式,使用的技术是evth-pair。
启动tomcat
docker run -d --name tomcat01 -p 8081:8080 tomcat:9.0
在查看ip
ip addr
如下,多了一个277
再启动一个tomcat
docker run -d --name tomcat02 -P tomcat:9.0 (大写P表示随机端口)
在查看ip
ip addr
如下,又多了一个279
查看linux的ip
ip addr
查看容器内ip
docker exec -it tomcat02 ip addr
如上图,网卡是一对一对,并且宿主主机与容器是对应的。
这就是evth-pair技术,evth-pair就是一对虚拟设备接口,他们都是成对出现的,一端连着协议,一端相互相连。
正因为有这个特性,所以用evth-pair充当桥梁,连接各种虚拟网络设备
容器之间是可以互相ping通的
docker exec -it tomcat02 ping
结论:tomcat01 与 tomcat02 公用一个路由器docker0,所有容器不指定网络,都是docker0路由的,docker会给容器分配一个默认可用 IP 255.255.0.1/16 (16代表前面16位)
二进制 00000000.00000000.00000000.00000000
十进制 255.255.255.255
docker 网络
docker 中所有网络接口都是虚拟的,虚拟的转发效率高
只要删除容器,对应的网桥也没了
启动tomcat03用–link连接tomcat02
docker run -d -P --name tomcat03 --link tomcat02 tomcat:9.0
用tomcat03 ping tomcat02
docker exec -it tomcat03 ping tomcat02
如下,可ping得通,可以实现高可用,也就是IP换了不影响,用名称直接可以访问
docker exec -it tomcat03 cat /etc/hosts
–link 就是我们在hosts配置中增加了一个tomcat02的映射
docker exec -it tomcat02 cat /etc/hosts 而反过来,查看 tomcat02并没有映射,–link并不是双向绑定
注意:现在已经不使用–link,一般使用自定义网络,docker0不支持容器名访问
docker network ls 查看docker网络
网络模式
bridge: 桥连(默认)
none: 不配置网络
host: 与宿主共享网络
container: 容器内网络连通(用的少,局限性很大)
创建一个网络,名叫mynet
–driver bridge
–subnet 192.168.0.0/16(192.168.0.2 - 192.168.255.255)
–gateway 192.168.0.1(默认的路由网关)
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
查看网络 docker network inspect mynet
常规默认启动 bridge
docker run -d -P --name tomcat01 --net bridge tomcat
改为我们自定义的网络启动
docker run -d -P --name tomcat01 --net mynet tomcat
再启动 tomcat02
docker run -d -P --name tomcat02 --net mynet tomcat
再查看网络 docker network inspect mynet ,如下有两个容器
用tomcat01去ping tomcat02的IP,可以ping通
docker exec -it tomcat01 ping 192.168.0.3
PING名字,也可以ping通
docker exec -it tomcat01 ping tomcat02
我们自定义的网络已经帮我们维护好对应的关系,包括双向连接。docker0(–link)并没有,所以自定义网络
优点:
redis mysql 不同的集群使用不同的网络,保证集群安全与健康
连通
再启动一个容器 docker run -d -P --name tomcat03 tomcat
连通 docker network connect mynet tomcat03
查看自定义网络 docker network inspect mynet 已直接加入容器
创建redis网络
docker network create redis --subnet 172.38.0.0/16
查看是否存在
docker inspect redis
通过shell脚本创建六个redis配置
进入
cd /mydata/redis
可以看到6个节点
进入
cd node-1/conf
查看
cat redis.conf
redis-1
redis-2
redis-3
redis-4
redis-5
redis-6
redis只有 /bin/sh 没有 /bin/bash
docker exec -it redis-1 /bin/sh
创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
进入集群
redis-cli -c
查看集群信息
cluster info
查看节点
cluster nodes
设置一个值
set a b
如下,说明第三台在处理
再查看a
get a
然后停止第三台,再查看a还能不能获取到,判断高可用
docker stop redis-3
ctrl p+q 退出
再进入其中一台
docker exec -it redis-1 /bin/sh
进入集群
redis-cli -c
get a 如下可以看到在第四台出现a
建一个springboot项目,写个简单的controller 输出hello world
Maven package
在target目录可以看jar包
在jar包目录下打开cmd 执行 java -jar demo-0.0.1-SNAPSHOT.jar,如下图成功,说明项目没问题
新建Dockerfile (注意: FROM adoptopenjdk/openjdk11程序框架要用java11 , java8请用java:8)
在home下新建目录
mkdir
用FTP上传 Dockerfile和jar包 demo-0.0.1-SNAPSHOT.jar 到 目录里,然后把他们打个包
docker build -t chenxb . (-t为target目标,. 为当前目录)
镜像创建成功,docker images 查看镜像,如下图
启动chenxb镜像命名chenxb666
docker run -d -P --name chenxb666 chenxb
curl localhost:49168/hello 测试返回hello world
官网安装地址
curl -L “https://github.com/docker/compose/releases/download/1.28.5/docker-compose- ( u n a m e − s ) − (uname -s)- (uname−s)−(uname -m)” -o /usr/local/bin/docker-compose
国内安装地址
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-- > /usr/local/bin/docker-compose
授权
chmod +x /usr/local/bin/docker-compose
查看版本,能看到版本号说明成功
docker-compose version
跟着官网Getting started一步步做下来
https://docs.docker.com/compose/gettingstarted/
建项目目录,并进入
mkdir composetest
cd composetest
创建app.py文件,并把以下代码黏贴进去
创建requirements.txt文件,并把以下代码黏贴进去
创建Dockerfile文件,并把以下代码黏贴进去
创建docker-compose.yml文件,并把以下代码黏贴进去(定义两个服务web和redis)
docker-compose.yml 核心就三层,官网 https://docs.docker.com/compose/compose-file/compose-file-v3/
第一层,版本 version
第二层,服务 services
第三层,其他配置 volumes , networks , configs 等等
创建启动compose
获取如下地址时,可能超时
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
解决方案,使用国内的alpine源,在Dockerfile中增加下面两行,cat /etc/apk/repositories 输出资源路径,记得把原来的image都先删掉
如下,成功
再另外打开客户端docker ps 查看有两个容器
查看网络
docker network ls
查看网络详情,如下同一个网段,所以可以通过上面app.py文件里面定义的host='redis’去访问
docker inspect composetest_default
官方地址
https://docs.docker.com/compose/wordpress
创建目录
mkdir my_wordpress
cd my_wordpress/
vim docker-compose.yml
编写文件,黏贴如下代码
运行
1,编写项目
2,dokerfile 构建镜像
3,docker-compose.yml 容器编排
4,打jar包
5,上传到服务器 docker-compose up -d
6,打开另外窗口 curl 成功
先查看docker swarm有什么命令
再查看init命令
查看ip
配置主节点
加入节点
获取令牌