docker
docker 学习笔记
单机版本docker 学习路径
Docker 概述
为什么出现?
一款产品 开发 上线 两套环境还要配置
开发人员 ----- 运维人员 问题我的电脑可以运行! 版本更新服务不可用
开发即运维
环境配置十分麻烦 如(redis es hadoop) 费时费力 jar(redis mysql jdk es)
项目能不能带着环境打包 有的环境不是跨平台的
传统 开发jar 运维来做
现在 开发打包部署上线 一套流程搞定
docker 给以上的问题提出了解决方案
虚拟机和容器的的区别
虚拟机 虚拟出一套硬件 运行一个完整的操作系统 在系统上安装和运行软还
容器 直接在宿主机里面运行 没有自己的内核 每个容器是相互隔离的 极大提高利用率
DevOps 开发 运维
传统 一堆文档 安装程序
docker 打包测试 一键运行
更加便捷升级和扩缩容
部署象搭积木一样
docker 内核级的虚拟化
物理机的性能可以压榨到极致
docker 安装
基本组成
镜像 -> 模版 要运行起来
容器(contatner) 理解为简单的linux系统 启动 停止 删除 基本命令;
仓库(repository) Docker Hub (默认国外) 使用国内镜像加速+
系统内核3.10以上
# linux uname -r cat /etc/os-release
docker run hello-world
底层原理
docker 是这么工作的
docker 是一个client-server 结构的系统 docker 守护进程运行在主机上 通过socket从客户端访问! DockerServer 收到docker-client的指令,执行指令;
为什么比虚拟机快
不用另外启动操作系统 省掉
docker 命令
常用命令
docker version | 显示版本信息 |
---|---|
diocker info | 当前信息 |
docker 命令 --help | 万能帮助 |
docker stats | 查看使用情况 |
镜像命令
docker images | 查看本机镜像 |
---|---|
docker search 镜像名 [mysql 等] | 搜索镜像 -f=start==100 |
docker pull 镜像名 [mysql 等 [: tag] ] | 下载镜像 会同步 |
docker rmi 镜像名/镜像id | 删除镜像 -f 强制删除 可以多个 |
docker rmi -f $(docker images -qa) | 删除全部 |
容器命令
有了镜像才有容器
-
docker run [参数] image
-
-
--name="name" 容器的名字
-
-d 后台方式运行
-
-it 使用交互方式运行,进容器查看内容 exit 退出
-
-p 指定容器端口 -p 8080:8080
-
- -p ip:主机端口:容器端口 (常用)
- -p 主机端口:容器端口
- -p 容器端口
-
-P 随机端口
-
-
docker ps 类似ps
-
- #正在运行的容器
- -a 历史运行的容器
- -n=? 列出最近创建的
- -q 只显示编号
-
exit 退出容器
-
ctrl + p + q #不停止退出
-
docker rm 容器id
-
- docker rm -f (docker ps -aq) 删除所有
- docker ps -a -q | xargs docker rm
启动和停止容器
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id
其他常用命令
后台启动容器
容器使用后台进程 必须有一个前台 否则自动停止
查看日志
docker logs [参数] 容器id
-tf 显示日志
--tail [条数]
查看进程
docker top 容器id /查看进程信息
查看镜像信息
docker inspect 容器id
进入正在运行的容器
通常使用后台运行 要进去修改容器配置
docker exec -it 容器id /bin/bash [一些命令的环境]
开启新的终端
docker attach 容器id /bin/bash
# 进入正在执行的
容器数据拷贝出来
docker cp 容器id:/home/test.java /home
命令非常多
初级体验 (可以跳过)
安装nginx 其他类似
docker pull nginx
docker run -d --name nginx01 -p 3344:80 nginxdocker run -d --name nginx01 -p 3344:80 nginx
进入
docker exec -it nginx01 /bin/bash
docker run -d -P -it tomcat --net redisnet --ip 172.38.0.5
用完即删 官方给的测试的用法
docker run -it --rm tomcat:9.0
问题 每次修改配置要进入容器十分麻烦 在容器外部提供一个路径映射,达到在容器修改文件的目的
答案 -v 数据卷;
es + kabanner
es 修改配置
大内存应用这么处理 限制内存 内存分配 -e 添加配置
docker run -d --name elasticsearch --net somenetwork -p 4346:9200 -p 4347:9300 -e "discovery.type=single-node" elasticsearch
docker run -d --name elasticsearch -p 4346:9200 -p 4347:9230 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch es
限制语句
linux 本地测试 curl localhost:端口
docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch
不同容器之间这么通讯 集群问题
可视化
portainer 面板
docker run -d -p 8090:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
Rancher
docker 镜像
镜像概述
所有的应用直接打包
如何得到镜像
docker hub 下载
联合文件系统 UnionFS
分层下载 有的可以复用
镜像默认都是只读 run 相当于加了一层 可以打包给别人
commit 镜像 打包自己的镜像
类似git
docker commit -a="作者" -m="提交信息" 容器id
保存自己的操作 类似于快照
下面是精髓
容器数据卷
什么是容器数据卷
数据在容器中 容器删除数据就会丢失 要求数据持久化
容器之间数据共享技术 容器产生的数据同步到本地
目录挂载
总结 容器的持久化和同步操作!容器间也可以数据共享
方式1 用命令挂载 -v
docker run -it -v 主机目录:容器目录 centos /bin/bash
内外文件会同步
安装mysql 将数据挂载出来
run 的参数
-d 后台启动
-p 端口映射
-v 数据卷挂载
-e 环境配置
--name 取名字
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=my-secret-pw -d mysql:tag
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 -d mysql:5.7
docker container run -it --detach --name mysql57 --network blog_network -p 3306:3306 -v $PWD/data/myscript/:/docker-entrypoint-initdb.d/ --env MYSQL_RANDOM_ROOT_PASSWORD=yes mysql:5.7
启动
docker exec -it some-mysql bash
查看日志
docker logs mysql57
docker logs mysql57 | grep 'GENERATED ROOT PASSWORD: ' | awk -F': ' '{print $2}'
具名挂载 匿名挂载
docker volume ls
查看所有的卷 默认卷名都在 /var/lib.docker/volumes/xxx/_data
-v 容器内路径
匿名
docker run -d -p --name nginx01 -v /etc/nginx nginx
具名
docker run -d -p 8080:8080 -v nginx:/nginx
如 只写了容器内的路径没有
local 5d62591dfceeb4664f776d74e12c671f47ad50a7fcf8acc23ce5981bdf5e7589
local 53af8a01718a4dfc648393282063ebd1cc04d78aba8083a5b515b32d792d113f
docker volume inspect 5d62591dfceeb4664f776d74e12c671f47ad50a7fcf8acc23ce5981bdf5e7589 [卷名]
可以查看详细信息
如何区分 匿名还是具名
-v 容器路口 #匿名
-v 卷名:容器路径 #具名
-v /宿主机路径::容器内路径 # 指定路径挂载
后面可以加参数【:ro/:rw
】 权限 ro 只能从外面改变 从宿主机操作 容器内无法操作
初识dockerfile
构建docker文件 就是命令脚本
构建命令
docker build -f dockerfile1 -t lmq/centos .
docker文件 镜像名:版本号
不给默认latest
指令(大写) 参数(小写)
FROM centos
VOLUME ["volume01","volume02"] # 匿名挂载 开启后有两个目录和本地对应
CMD echo "--END--"
CMD /bin/bash
VOLUME ["volume01","volume02"] # 匿名挂载 开启后有两个目录和本地对应
数据卷容器
可以理解为java的继承
数据复制拷贝 直到容器全部关闭
dockerfile
基础知识
- 每个保留关键字(指令)都必须大写
- 执行从上到下顺序执行
- #表示注释
- 每个指令都会创建提交一个新的镜像
dockerfile: 面相开发 我们的项目做成镜像 自己编写dockerfile文件
dockerFile: 构建文件,定义了一切步骤,源码
dockerimages: 通过dockerfile生成镜像,最终发布和运行的产品
docker容器: 容器就是镜像运行起来提供服务
dockerFile的指令
FROM # 基础镜像,一切从这里开始
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要的命令
ADD # 步骤tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载目录
EXPOST # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令 只有最后一个生效,可被替代
ENTRYPOINT # 指定这个容器启动时要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承的DockerFile 这个时候就会运行ONBUILD指令。触发指令
COPY # 类似ADD ,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量
构建自己的centos
编写dockerfile文件
FROM centos
MAINTAINER lmq<1435456124@qq.com>
ENV MYPATH /user/local
WORKDIR $MYPTH
RUN yum install -y vim
RUN yum install -y net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash
打包
docker build -f dockerfile -t mysentos:1.0 . # 后面有个点
centos 版本和主机不一致 可以选择 FROM centos:7
ERROR: failed to solve: process "/bin/sh -c yum -y install vim" did not complete successfully
查看镜像层数
docker history 镜像id
查看镜像制作过程
CMD 和 ENTRYPOINT
cmd-test
FROM centos
CMD ["ls","-a"]
直接执行
docker run cmd-test -l #直接报错 -l不是命令
发布自己的镜像 官方
- 有账号
- 登录
docker login -u username -p password
docker push 镜像名:版本
上传到阿里 1个账号只能创建3个命名空间
创建命名空间
保存
docker save -o aaa_v1.tar aaa:v1
导入
docker load -i aaa_v1.tar
docker 网络原理 --net
理解
- 测试
[root@hecs-397654 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether fa:16:3e:9a:f2:00 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.14/24 brd 192.168.0.255 scope global dynamic noprefixroute eth0
valid_lft 61205sec preferred_lft 61205sec
inet6 fe80::f816:3eff:fe9a:f200/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:bd:34:53:d8 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:bdff:fe34:53d8/64 scope link
valid_lft forever preferred_lft forever
怎么处理容器网络访问
linux 能不能直接ping到容器内的ip地址
可以 linux 可以ping通docker容器内部
-
原理
-
- 我们每启动一个docker就会个docker容器分配一个ip,
- 只要安装了docker就会有一个docker0网卡
- 桥接模式使用的技术是evth-pair技术
什么搜索evth-pair
evth-pair 就是一堆虚拟设备接口,他们都是成对出现的,一段链接协议 一段链接彼此
evth-pair 充当一个桥梁2
所有容器不指定默认就是
使用 linux 桥接
--link 目的可以直接诶ping他的name
docker run -d -P --name tomcat02 --link tonmcat01 tomcat
类似于host 添加 一条本地映射
探究 docker network inspect
网络模式
bridge : 桥接模式 docker(默认 自己使用也用bridge)
nbone : 不配做网络
host : 和宿主机共享网络
container : 容器网络连接通 (很少用)
docker network --help
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
直接启动的命令 默认 --net bridge docker0网卡
默认 docker0
域名不能访问--link
来处理
创建自己的网络
docker network create redis --subnet 172.38.0.0/16
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet # 65535个网络
查看已经拥有的网络配置
docker network ls
查看自己的网络配置
docker network inspect mynet
好处
不同的集群使用不同的网络
mysql redis 等 可以保证网络的安全和健康
连通网络
docker network connect [OPTIONS] NETWORK CONTAINER
docker network mynet tomcat01[容器名]
docker network connect --help
connect 链接一个容器到网络
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., "172.30.100.104")
--ip6 string IPv6 address (e.g., "2001:db8::33")
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container
联通之后
tomcat01 放到了mynet网络下
一个容器两个ip 直接解决相互访问问题
实战 查看redis
idea整合docker
docker compose
docker swarm
ci\cd jenkins