1、Docker概述
为什么学习docker?
因为现在的技术越来越智能化,以前系统上线全部手动操作部署,过渡到现在的云原生一步到位完成部署。
docker为什么会出现?
开发和运维的协同
- 开发说:这个代码在我这里没有问题!
- 运维说:你的代码就是在服务器上跑不起来!
一款产品从开发到上线: 操作系统,运行环境,应用配置,都可能不同,开发和运维协同很麻烦!
很麻烦,原生的东西十分的麻烦,横向扩展,重新配置服务器,费时费力。
我们的应用能不能带上我们环境一起发布!使用docker,解决这个问题
上面的图所示把程序应用和所依赖的环境一起涵盖到项目中作为一个整体(镜像)打包发布,避免了程序放到服务器上后需要重新配置环境。就好像前面学习的active mq服务,使用broker 把mq服务集成到应用中,就不需要服务器开启mq服务了,因为项目内嵌了一个mq服务,随项目启动而启动。docker跟这个思想非常相似,它使用的是镜像容器的概念。
如果存在这样一个技术,我们以后打包上线一个人搞定!
开发/运维 DevOps
公司中职责分明:开发和运维的界限是越来越不清楚了!Docker加速了这个过程!
Docker的Logo : 一条鲸鱼载着很多个集装箱!
鲸鱼就相当于宿主机,集装箱就相当于装着应用的一个个容器,隔离。
比如一艘船:水果,生化武器(正常情况不能同时运输)如果需要运输,装箱隔离!
Docker的核心理念就是如此!
系统:10个应用, mysql,tomcat,redis(可能会公用或者混用!)单独配置! 把应用和它依赖的环境一起装箱打包成镜像,10个应用就打包10个镜像。每个镜像运行后都会创建一个容器,容器里运行的就是一个应用和它依赖 的mqsql,tomcat,redis等环境。容器都是相互隔离的,如下图:
虚拟机是这样隔离的,每个vm就相当于一个服务器(虚拟硬件):
Docker 就是更加细粒度的隔离,不需要模拟硬件,只需要服务运行的环境即可!
Docker 是 基于 Go 语言实现的云开源项目!
核心概念: 容器-镜像-仓库Docker的基本组成
客户机 + docker程序(docker_host)+ 仓库(本地和远程)
2、Docker安装
Linux的文档:https://docs.docker.com/engine/install/
基于CentOS的安装:https://docs.docker.com/engine/install/centos/
# 查看系统内核,3.10.0 以上才支持docker运行
[root@kuangshen ~]# uname -r
3.10.0-1062.12.1.el7.x86_64
# 查看系统版本
[root@kuangshen ~]# 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、卸载旧的版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2、环境需求,软件包,仓库
# gcc 环境
yum install -y gcc
yum install -y gcc-c++
#
$ sudo yum install -y yum-utils
# 国外的镜像地址
$ 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
3、更新软件索引包 yum makecache fast
4、安装docker引擎
# docker-ce 社区版本, docker-ee 企业版本
yum install docker-ce docker-ce-cli containerd.io
5、启动docker
systemctl start docker
# 停止docker
systemctl stop docker
6、运行helloworld镜像测试
docker run hello-world
出现以下效果:代表安装成功!
卸载docker
# 1、卸载docker引擎
[root@kuangshen ~]# sudo yum remove docker-ce docker-ce-cli containerd.io
# 2、删除相关文件
[root@kuangshen ~]# sudo rm -rf /var/lib/docker
# docker的默认目录
[root@kuangshen ~]# cd /var/lib/docker
[root@kuangshen docker]# ls
builder containers network plugins swarm trust
buildkit image overlay2 runtimes tmp volumes
3、阿里云镜像加速
登录阿里云,搜索容器镜像服务
进入管理控制台:
点击”镜像加速”,可以看到自己的镜像加速地址,选择Centos,修改配置/etc/docker/daemon.json来使用加速器
# 1、创建文件夹
[root@alibaba ~]# mkdir -p /etc/docker
# 2、配置自己的镜像加速地址
[root@alibaba ~]# tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://dyv68vb0.mirror.aliyuncs.com"]
}
EOF
# 3、重启daemon进程
[root@alibaba ~]# systemctl daemon-reload
# 4、重启docker
[root@alibaba ~]# systemctl restart docker
4、Docker是如何工作的
运行镜像
安装docker的时候我们运行了hello world镜像
docker run的原理
如果dockerhub上没有对应的镜像,会提示你登录自己的仓库获取镜像。
底层原理
镜像
Docker 中一个个的模板,Redis镜像(会包含这个服务需要的所有环境),一个镜像可以创建多个容器运行!
镜像就是一个模板而已,它包含服务本身和一套环境,比如
(shop.war + redis + mysql + tomcat) => myshop 镜像
容器
Docker 通过镜像来创建一个个的容器实例(run,运行产生的)
容器就是我们正真的服务。
(shop.war + redis + mysql + tomcat) => myshop 镜像
docker run myshop == > 容器 (暴露端口、数据需要同步到本地、配置网络)==> 访问服务即可!
容器(最终运行的项目),操作:开启、停止、重启、删除。。。。
容器之间是相互隔离的!
仓库
存放镜像的位置,DockerHub(最大的公有仓库)。
分为公有仓库、 私有仓库(比如自己在阿里云的镜像仓库)
大家可以先去DockerHub 注册一个账号,可以发布自己的镜像,就像github创建一个公有仓库,开源自己的项目一样。
底层原理
Docker C-S 结构!
Docker 和 VM的隔离比较
虚拟机:创建 guest os(虚拟的系统),和真实的一样,但比较耗资源,启动也慢,然后在guest os上运行我们的App应用程序
Docker:不需要再去虚拟化硬件资源,通过DOCKER DAEMON 直接运行我们的APP应用程序,资源开销共用宿主机(安装了Docker服务的主机)。
思想:**没有什么是加一层解决不了的**,一个架构的思想。
对比的优势:效率变高、速度变快、方便。
所有的Docker镜像的基础环境都是linux的!,镜像是有多层组成的,第一层都是linux的系统内核。
5、Docker基本使用
帮助命令
学习方式:对比 redis-tab 看到redis的一切命令,docker –help就可以看到所有命令帮助!
[root@kuangshen ~]# docker --help #看docker所有的命令,就亿点点
# 命令划分: 容器操作、镜像操作(crud)、系统命令:进入容器、创建、构建。。。。
Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
Run 'docker COMMAND --help' for more information on a command.
# 要查看任何命令帮助都可以这样使用
docker xxx --help
查看docker 版本信息
[root@kuangshen ~]# docker version
Client: Docker Engine - Community
Version: 19.03.11
API version: 1.40
Go version: go1.13.10
Git commit: 42e35e61f3
Built: Mon Jun 1 09:13:48 2020
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.11
API version: 1.40 (minimum version 1.12)
Go version: go1.13.10
Git commit: 42e35e61f3
Built: Mon Jun 1 09:12:26 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.2.13
GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc:
Version: 1.0.0-rc10
GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
docker-init:
Version: 0.18.0
GitCommit: fec3683
查看docker 具体运行信息,包括容器(运行中、暂停、已停止) 和 镜像信息等等
镜像命令
docker images
1、列出镜像
# 列出镜像,通过镜像id运行镜像
[root@kuangshen ~]# docker images
# 仓库源 # 版本 # 镜像id唯一的 # 创建时间 # 大小
REPOSITORY TAG IMAGE ID CREATED SIZE
composetest_web latest 9a309fa36afa 2 weeks ago 104MB
<none> <none> e244bf2f7f2c 2 weeks ago 96MB
python 3.6-alpine c937382ec98f 2 weeks ago 92.8MB
python 3.7-alpine 55312eb28831 2 weeks ago 96MB
redis alpine 29c713657d31 2 weeks ago 31.6MB
tomcat latest 1b6b1fe7261e 2 weeks ago 647MB
mysql latest 94dff5fab37f 2 weeks ago 541MB
hello-world latest bf756fb1ae65 5 months ago 13.3kB
webcenter/activemq latest 3af156432993 3 years ago 422MB
mysql 5.7 a4s5d465aw4e 5 months ago 500mb
# 可选项,通过help查看
[root@kuangshen ~]# docker images --help
Options:
-a, --all #查看所有的镜像,docker images 默认带上该选项
-f, --filter filter # 查询条件
-q, --quiet # 只显示镜像id
# 参数连起来使用
[root@kuangshen ~]# docker images -qa
2、搜索镜像 docker search –help
[root@kuangshen ~]# docker search mysql
# 名字 # 描述 # STARS
NAME DESCRIPTION STARS
mysql MySQL is a widely used, open-source relation… 9578
mariadb MariaDB is a community-developed fork of MyS… 3481
# 可以增加搜索条件
# 列出收藏不小于 5000 的镜像
[root@kuangshen ~]# docker search mysql --filter=stars=5000
# 我们搜素镜像直接去dockerhub!
# 我们搜素镜像直接去dockerhub!
# 我们搜素镜像直接去dockerhub!
点击镜像详细页面,会告诉你怎么下载镜像和运行镜像
3、下载镜像 docker pull –help
[root@kuangshen ~]# docker pull --help
# 下载指定版本,不指定就是最新版本
[root@kuangshen ~]# docker pull mysql
[root@kuangshen ~]# docker pull mysql:5.7
4、删除镜像
[root@kuangshen ~]# docker rmi -f 镜像id # 强制删除
[root@kuangshen ~]# docker rmi -f 镜像id 镜像id # 强制多个删除
# 删除全部,使用组合命令
docker images -aq # 获取全部镜像的id
docker rmi -f $(docker images -aq)
5、查看镜像的全部信息
[root@kuangshen ~]# docker image inspect 镜像id
容器命令
镜像一但运行就到容器了!
有了镜像才能创建容器!
1、新建并启动容器 docker run –help
# 查看run 帮助
docker run --help
# 常用参数
--name="MySQL" 给容器指定一个名字
-d 后台运行
-i 交互模式运行,进入容器
-t 交互模式运行,打开一个新的终端,进入容器
-P 随机暴露端口
-p 指定暴露的端口
-p 3306:3306 将容器内部的端口和内部端口做映射
# 这些镜像一般都是精简的!
# 以交互模式进入容器,
[root@kuangshen ~]# docker run --name=mylinux -it centos:7.8.2003 /bin/bash
[root@8731ed2f08d1 /]# ll
bash: ll: command not found
[root@8731ed2f08d1 /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@8731ed2f08d1 /]# vim
bash: vim: command not found
[root@8731ed2f08d1 /]# ifconfig
bash: ifconfig: command not found
[root@8731ed2f08d1 /]# exit # 退出容器
exit
[root@kuangshen ~]# ll
2、列出运行的容器
# 查看命令帮助
[root@kuangshen ~]# docker ps --help
# 显示正在运行的容器
[root@kuangshen ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
# 显示正在运行和历史运行的容器
[root@kuangshen ~]# docker ps -a
# 容器id # 创建容器的镜像 #
CONTAINER ID IMAGE COMMAND CREATED STATUS
8731ed2f08d1 centos "/bin/bash" 2 minutes ago Exited (127)
3、退出容器
exit # 容器停止退出
Ctrl+P+Q # 不停止容器,退出,查看正在运行的容器,status显示up
4、容器的启动停止
docker start 容器id # 启动
docker restart 容器id # 重启
docker stop 容器id # 正常停止
docker kill 容器id # 强制停止
[root@kuangshen ~]# docker stop a1e9f14fe46f
a1e9f14fe46f
5、删除容器
# 删除指定的
docker rm 容器id
# 强制删除指定的
docker rm -f 容器id
# 强制删除全部正在运行的容器
docker rm -f $(docker ps -qa)
小结:
-
docker stop rm start ps 对于容器的,容器是docker最小单元
-
镜像的命令都带 i,如docker images , docker rmi
其他命令(重要)
后台启动容器 docker run –help
# -d 后台运行容器
[root@kuangshen ~]# docker run -d centos
73c2b6182b79e07225f045be1fd5673b53b2953e0c02b7e0d47428eebaff4110
[root@kuangshen ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 发现这个容器停止了,
[root@kuangshen ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
73c2b6182b79 centos "/bin/bash" 19 seconds ago Exited (0) 19 seconds ago practical_hodgkin
# 注意点:docker 容器使用后台方式运行,必须要有一个前台进行,比如我们这里的centos,啥都没干,这个时候它就会自动停止,docker会认为没有程序的。没有对外提供服务!最好的情况,就是核心应用使用前台方式启动运行。
日志查看 docker logs –help
# 参数
-f -t --tail 行数
# 通过日志查看
# -t 时间戳显示
# -f 刷新最新的日志
# --tail n 指定显示最后的多少行
# 测试后台运行centos,写一个脚本让它有程序在运行,那样就不会停止了
[root@kuangshen ~]# docker run -d centos /bin/sh -c "while true;do echo icoding;sleep 1;done"
2b0b65a0733d8e801cb8788a68d84895676c6f626f2fab0e09ef990f317fa1ed
[root@kuangshen ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b0b65a0733d centos "/bin/sh -c 'while t…" 4 seconds ago Up 3 seconds beautiful_chaum
[root@kuangshen ~]# docker logs -tf --tail 10 2b0b65a0733d
2020-06-06T10:09:05.039165180Z icoding
2020-06-06T10:09:06.040633317Z icoding
2020-06-06T10:09:07.042213068Z icoding
2020-06-06T10:09:08.043662863Z icoding
2020-06-06T10:09:09.045180716Z icoding
查看容器进程信息
[root@kuangshen ~]# docker top 2b0b65a0733d
UID PID PPID C STIME
root 6905 6889 0 22:52
# 查看容器的CPU,内存,IO 等使用信息
# 不加容器名即查看所有
[root@localhost ~]# docker stats os1
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
f9420cbbd2a9 os1 45.94% 47.09MiB / 1GiB 4.60% 54.6MB / 352kB 0B / 21.1MB 3
查看容器和镜像的信息(研究本质常用)
[root@kuangshen ~]# docker inspect 2b0b65a0733d
进入正在运行的容器 会启动新的终端
# 常用的,进入正在运行的容器
# -it 创建一个新的端口,交互模式运行
docker exec -it 容器id 控制台
[root@kuangshen ~]# docker exec -it 2b0b65a0733d /bin/bash
[root@2b0b65a0733d /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@2b0b65a0733d /]# ll
bash: ll: command not found
进入正在运行的容器 不会启动新的终端
# 进入正在执行的终端!
docker attach 容器id
[root@kuangshen ~]# docker attach 2b0b65a0733d
icoding
icoding
icoding
拷贝文件,容器内的文件拷贝到容器外面(宿主机上)
[root@iZwz ~]# docker cp --help
Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
Copy files/folders between a container and the local filesystem
Options:
-a, --archive Archive mode (copy all uid/gid information)
-L, --follow-link Always follow symbol link in SRC_PATH
# 1、进入正在运行的容器
[root@iZwz99 ~]# docker exec -it 8b41850cad8c /bin/bash
[root@8b41850cad8c /]# cd home
# 2、在容器内创建一个文件
[root@8b41850cad8c home]# touch f1
[root@8b41850cad8c home]# ls
f1
# 3、退出容器,拷贝文件到宿主机
[root@iZwz996g ~]# docker cp 8b41850cad8c:/home/f1 /home
[root@iZwz996g ~]# cd /home
[root@iZwz996g home]# ls
coding esuser f1
# 测试:拷贝宿主机的文件到容器中
[root@iZwz99 home]# touch f2
[root@iZwz99 home]# docker cp f2 8b41850cad8c:/home
[root@iZwz99 ~]# docker exec -it 8b41850cad8c /bin/bash
[root@8b41850cad8c /]# cd home
[root@8b41850cad8c home]# ls
f1 f2
docker基本使用ok!
1、下载镜像
2、运行镜像
6、Docker全部的命令
官方文档查看更多使用命令:https://docs.docker.com/engine/reference/
7、作业
Docker 安装 Nginx
去docker hub搜索nginx
docker search nginx
docker pull nginx
docker run nginx 前面的两步可以不做,因为run的时候就会去docker hub搜索下载镜像
# --name 容器名, -d 后台运行, -p 端口映射暴露端口(宿主机端口:容器内端口)
# 防火墙,安全组一定要开放端口
docker run --name mynginx -d -p 3500:80 nginx
访问测试
我们访问nginx的流程是这样的: 外网访问阿里云服务器3500端口 -> 服务器内的Docker容器80端口 (-p 端口映射)
# 1、进入容器mynginx
[root@kuangshen ~]# docker exec -it mynginx /bin/bash
# 2、
root@4e6c81419f40:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
# 3、如何配置nginx 的反向代理路由,配置文件应该在/etc/nginx
root@640e0bff04d3:/# cd /etc/nginx
root@640e0bff04d3:/etc/nginx# ls
conf.d fastcgi_params koi-utf koi-win mime.types modules nginx.conf scgi_params uwsgi_params win-utf
# 不支持vim
root@640e0bff04d3:/etc/nginx# vim
bash: vim: command not found
# 解决方案:运行容器时通过目录挂载的方式把/etc/nginx挂到宿主机外,实现文件共享的方式修改配置。
docker run -d -p 3500:80 -v /etc/nginx:/etc/nginx --name mynginx nginx
Docker 安装 tomcat
–rm
# --rm 容器启动成功以后,然后退出,那么就自动移除容器(测试的时候使用!)
# docker ps -a 也不会记录容器的运行痕迹
docker run -it --rm tomcat:9.0
# 运行tomcat
[root@alibaba ~]# docker run -d -p 8080:8080 --name tomcat9 tomcat:9.0
[root@alibaba ~]# curl loalhost://8080
# 访问tomcat返回404,既然出现了404,说明服务启动成功!
# 进入容器tomcat9
[root@kuangshen ~]# docker exec -it tomcat9 /bin/bash
# 默认的tomcat,官方下载的,webapps 是空的!
# 我们每次假设要发布项目到 tomcat容器中,这个时候都需要进入容器!能不能可以直接在linux虚拟机上部署,就自动同步到容器中。
# 可以,docker run的时候通过目录挂载 -v(宿主机目录:容器内目录),把容器内/usr/local/tomcat/webapps目录挂载到宿主机外,实现文件数据同步,实现自动同步到容器中
[root@kuangshen ~]# docker run -d -p 8080:8080 -v /www/tomcat9/webapps:/usr/local/tomcat/webapps --name tomcat9 tomcat:9.0
Docker 安装 ES + Kibana
查看容器对cpu内存和网络资源的占用状况
docker stats 容器id
可以看出tomcat的cpu ,内存 占用都是比较小的,因为还没发布什么应用。
docker安装 es 需要解决的问题
- es占用资源很大,吃内存,修改es的config目录的jvm.options把内存改小,docker通过传环境参数的方式配置
- 端口暴露: 9200/9300
- 数据挂载问题!(docker容器内部! 删除docker容器, 删除跑路!=> 数据应该是持久化在本地的,不随容器销毁而消失)
docker hub搜索elasrticsearch
docker hub搜索kibana
docker run elasticsearch 访问
# 查看官网(docker hub搜索elasrticsearch)得知:
# 1、运行 elasticsearch:7.7.1
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.7.1
发现问题,占用运行内存大,调整变小
问题:整个Linux开始卡顿了!通过stats查看状态,ES占用了71%的内存,十分消耗资源!
[root@kuangshen ~]# docker stats af80e6966f24
docker es的更多配置 https://www.elastic.co/guide/en/elasticsearch/reference/7.7/docker.html
environment里配置的参数就是elasticsearch.yml配置文件里支持的参数,是一样的
而ES_JAVA_OPTS 就是Jim.options的参数,一般也就是修改内存,默认是占用1g
# 将es的运行内存变小!通过 -e 参数来改变环境配置!
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms64m -Xmx512m" elasticsearch:7.7.1
通过stats查看状态,发现占用内存明显变小,MEM: 20%
问题:es + kibana? 跨容器可以直接访问吗?!之后再Docker网络讲解!
了解下一节的docker网络,你会发现可以把ElasticSearch、Kibana放在同一组网络里,可以互相通信