Docker
部署流程繁琐环境不一致资源隔离问题交付流程复杂Java Web 项日Spring Boot 一体式项目Spring Cloud 微服务项目r:是一个容器引擎,用于管理容器的生命周期(安装成功后的软件):用于运行一个软件的容器,这个容器里面准备了软件运行所需的一系列依赖(软件安装包):容器的安装包,容器中西药哪些内容,以及对应的配置信息,全部打包在这里面,要运行一个容器,必须要先有一个镜像(应用商店
认识Docker
没有docker 存在的问题
部署流程繁琐
环境不一致
资源隔离问题
交付流程复杂
Docker容器化部署演示
Java Web 项日
Spring Boot 一体式项目
Spring Cloud 微服务项目
Docker发展史
容器、镜像以及仓库
Docker:是一个容器引擎,用于管理容器的生命周期
--容器 (安装成功后的软件):用于运行一个软件的容器,这个容器里面准备了软件运行所需的一系列依赖
--镜像(软件安装包):容器的安装包,容器中西药哪些内容,以及对应的配置信息,全部打包在这里面,要运行一个容器,必须要先有一个镜像
--仓库 (应用商店):用于存放各个镜像,对镜像进行统一管理
Docker 架构
Docker Client客户端 向服务端发起请求 比如下载镜像,管理容器生命周期操作
Docker Daemon 守护程序
--Docker Server 服务端,接收请求
--Engine 容器引擎 ,真正负责执行对应任务
Docker Registry 镜像仓库 存储镜像用户信息 Docker Hub
Docker入门
安装docker
内核版本>=3.10 uname -a #查看内核版本
Docker 阿里云镜像加速配置 镜像服务
systemctl enable docker 开机自启
基础命令操作
--镜像
查找 docker search jdk 全文
拉取 docker pull openjdk:11版本号
查看本地 docker images
删除 docker rmi 镜像id
--容器
创建并运行一个容器 docker run 容器名
--端口映射 docker run -d(daemon守护) -p 80(主机端口):80(容器内端口) nginx容器名
docker run -d(daemon守护) -P(暴露容器中端口在主机中映射) nginx容器名
--指定容器名字 docker run –name 容器名nginx
--退出时删除容器 docker run --rm 容器id(CONTAINER ID)
--重启策略:
内存溢出导致容器挂掉 立马恢复
容器关闭时重启 --restart
no 不重启
on-failure :重启次数
always:挂掉即重启
--环境变量
echo $PATH
docker run -d -P --name 容器名 --env JAVA=env --env JAVA_HOME=env nginx
docker run -d -P --name 容器名 -e JAVA_HOME=env nginx
查看容器信息 docker inspect 容器名/容器id
docker exec -it 容器名 env(命令)
--限制容器资源
docker -h 查看命令
针对内存 CPU
docker run -d --rm -m 8m --cpus 0.5 nginx
查看容器状态 docker stats 容器id
查看容器 docker ps运行中 docker ps -a 全部
删除容器 docker rm -f(强制删除) 容器id(CONTAINER ID)
停止容器 docker stop 容器id(CONTAINER ID)
启动容器 docker start 容器id(CONTAINER ID)
进入容器内部 docker exec -it 容器名 /bin/bash
查看容器日志 docker logs -f -n 20容器id
数据卷
volume的作用
查看数据卷 docker volume ls
volume作用 容器内的文件夹和容器外部的文件夹打通 部分共享 持久保存
绑定方式
--匿名绑定
docker run -d -P --rm --name nginx-volume -v /usr/share/ngnix/html nginx
在启动容器时直接使用-v /container dir 即可完成匿名绑定,匿名绑定的方式将在Docker的 volumes 目录下生成一个sha256的字符串作为目录名,且指定的 /container dir 中的文件或目录会被保存在该处,匿名绑定的 volume 在容器被删除的时候,数据卷也会被删除
docker run --rm -d -p 80:80 -v /www/test nginx
匿名绑定方式由于不知道名称,因此如果需要查看数据卷在主机的哪个位置,需要使用docker inspect container_id 来查看
--具名绑定
同样是启动容器时绑定一个数据卷,不同的是可以为该数据卷起个名字-v volume-name:container_dir,通过名字你可以快速的定位并管理这些 volume
docker run --rm -d -p 80:80 -v nginx-www: /www/test nginx
持久化容器目录 不能自由指定目录
--Bind Mount
绑定并加载主机的某个文件目录到容器中,这种方式是平常最常用的。
这种绑定方式与前面两种一样,也是在容器启动时使用 -v host_dir:container _dir 的格式来完成映射
docker run --rm -d -p 80:80 -v /www/wolfcode:/www/wolfcode -v /etc/nginx/ nginx.conf:/etc/nginx/ nginx.conf nginx
管理命令
Docker为我们提供了一些专门用于管理数据卷的命令docker volume,通过下面的Usage来查看相关命令的使用
docker volume COMMAND
Usage:
Manage volumes
Commands:
create 创建一个数据卷
inspect 显示一个或多个数据卷的详细信息
ls 查看目前已有的数据卷列表
prune 删除所有本地没有被使用的数据卷
rm 删除一个或多个数据卷
网络 network
微服务部署 注册中心将服务调用信息收集形成调用网络 路由
基本概念
是docker对容器网络隔离的一项技术,提供了多种不同的模式供用户使用,选择不同的模式实现了容器之间的网络互通以及彻底隔离
容器间的网络隔离
实现部分容器间的网络共享
管理多个子网下的容器ip
网络模式
bridge桥接:
在主机中创建docker0的虚拟网桥,在docker0创建一对网卡,一半在主机上vethxxx, 一半在容器内eth0
docker run -d -P --rm --name 容器名 --net briage --link 要连接的容器名
host主机:
容器不再有自己的网络空间,而是直接与主机共享网络空间,那么基于该模式创建的容 器对应的ip实际上与主机同一个子网
none:
Docker会拥有自己的主机空间,不会跟主机共享,在这个模式下的容器不会被分配网卡 路由,ip等相关信息
container:
基于另一个容器 跟容器共享
自定义:
docker network
docker network create --help
docker network create --driver birdge --subnet 192.168.1.0/24 --gateway 192.168.1.1 网络名
Dockerfile
基本概念
自定义构建镜像的配置文件 描述如何构建一个对象
利用build命令
需要:
作为开发者需要将想不打包成docker镜像,便于后面直接作为 docker容器运行
作为运维人员需要构建更精简的基础设施服务镜像,满足公司的需求以及减少冗余的功能占用过多的资源
作用:
可以自定义镜像内容
构建公共镜像减少其他镜像配置
开源程序快速部署
常用指令
FROM 指定基础镜像,用于后续的指令构建。
MAINTAINER 指定Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令)
LABEL 添加镜像的元数据,使用键值对的形式。
ENV 在容器内部设置环境变量。
RUN 在构建过程中在镜像中执行命令。
CMD 指定容器创建时的默认命令。(可以被覆盖)
ENTRYPOINT 设置容器创建时的主要命令。(不可被覆盖)
EXPOSE 声明容器运行时监听的特定网络端口。
ADD 将文件、目录或远程URL复制到镜像中。
COPY 将文件或目录复制到镜像中。
VOLUME 为容器创建挂载点或声明卷。
WORKDIR 设置后续指令的工作目录。
USER 指定后续指令的用户上下文。
ARG 定义在构建过程中传递给构建器的变量,可使用 "docker build" 命令设置。
ONBUILD 当该镜像被用作另一个构建过程的基础时,添加触发器。
STOPSIGNAL 设置发送给容器以退出的系统调用信号。
HEALTHCHECK 定义周期性检查容器健康状态的命令。
SHELL 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。
# 1.先指定当前镜像的基础镜像是什么
ARG jdk-8
FROM openjdk:$jdk 例: docker build -t --build-arg jdk=11
FROM openjdk:8
#提前添加好用户
RUN useradd wolfcode
# 拓展:表示后续容器中所有执行命令的操作都是以 wolfcode 这个用户操作的
USER wolfcode
# 2.描述这个镜像的作者,以及联系方式(可选)
MAINTAINER wolfcode<liugangawolfcode.cn>
# 3.镜像的标签信息 (可选 )
LABEL version="1.0"LABEL description="这是我的第一个 Dockerfile"
# 4.环境变量配置
ENV JAVA ENV=dev
ENV APP NAME=test-dockerfile
# ENV JAVA ENV=dev APP NAME=test-dockerfile
# 5.在构建镜像时,需要执行的 shell 命令
RUN Is -al
RUN mkdir /www/dockerfile/test
# 6.将主机中的指定文件复制到容器的目标位置,可以简单理解为cp命令
# ADD /www/wolfcode.cn/index.html /www/server
ADD ["/www/wolfcode.cn/index.html","/www/server"]
# 7,设置容器中的工作目录,如果该目录不存在,那么会自己创建
WORKDIR /app
# 在设置完工作目录后,执行 pwd 命令,打印的目录就是 /app
RUN pwd
# 8.镜像数据卷绑定,将主机中的指定目录挂载到容器中
VOLUME ["/www/wolfcode .cn"]
# 9.设置突器启动后要暴露的端口
EXPOSE 8080/tcp
# CMD 和 ENTRYPOINT 选择其一即可,作用是描述镜像构建完成后,启动容器时默认执行的脚木
# CMD ping 127..0.1
# CMD ["sh","-c","ping 127.0.0.1"]
# ENTRYPONINT ping 127.0..1
ENTRYPOINT ["sh""-c","ping 127.0.0.1"]
# 拓展:健康检查,每各10s检查容器是否正常,每次不超过35,并且如果失败了,最多不能超过5次
HEALTHCHECK --interval-10 --timeout=3 --retries=5 CMD ps -ef | grep java exit 1
返回参数:
0: success =>成功
1: unhealthy =>健康监测失败
2: reserved手>保留值
构建镜像
commit 基于一个现有的容器,构建一个新的镜像
docker commit -a 镜像作者 -m 提交时的描述 容器名 新容器名:版本号
Build
Spring Boot 镜像
[root@k8s-node1 spring-boot-docker-demo]# touch Dockerfile
[root@k8s-node1 spring-boot-docker-demo]# ls
Dockerfile sprineboot-docker.-demo-1.0.0.jar
Dockerfile内容
#关联基础镜像 => jdk
FROM openjdk:8
#将项目 jar 包拷贝到容器中
ADD *.jar app.jar
#配置项目环境变量
ENV APP OPTS=“”
#JVM 环境变量
ENV JVM_OPTS="-Duser.timezone=Asia/Shanghai -Xms128m -mx128m"
#暴露端口
EXPOSE 8888
# 设置启动时的命令
ENTRYPOINT ["sh","java $JVM_OPTS -jar /app.jar $APP_OPTS"]
[rootek8s-nodel spring-boot-docker-demo]# vim Dockerfile
[root@k8s-nodel spring-boot-docker-demo] docker build -t springboot-docker:1.0.0 .
Sending build context to Docker daemon 17.57MB
Step 1/6 : FROM openjdk:8
---> e24ac15e052e
Step 2/6 : ADD *.jar app.jar
---> 406416869333
Step 3/6 : ENV APP_OPTS=”"
---> Running in 96365f41201e
Removing intermediate container 96365f41201e
---> f8c68d88ed57
Step 4/6 : ENV JVM_OPTS="-Duser.timezone-Asia/shanghai -Xms128m -Xmx128m"--> Running in b328aa085ef0
Removing intermediate container b328aa085efo
---> 2653985ae585
step 5/6 : EXPOSE 8888
---> Running in b036a780eeca
Removing intermediate container bo36a780eeca
---> ala1002d20c4
Step 6/6 : ENTRYPOINT ["sh","-c","java SJVM_OPTS -jar /app.jar SAPP_OPTS"]
Running in abd76dfc2e7c
Removing intermediate container abd76dfc2e7c
---> 8a63460d3752
Successfully built 8a63460d3752
Successfully tagged springboot-docker:1.0.0
[root@k8s-nodel spring-boot-docker-demo] # docker images
[root@k8s-nodel spring-boot-docker-demo] # docker run --rm -P springboot-docker:1.0.0
Tomcat 镜像
FROM tomcat:9.0
WORKDIR /usr/local/tomcat/webapps
ADD *.war ROOT.war
ENTRYPOINT ["sh",-c","../bin/catalina.sh run"]
Nginx镜像
[rootek8s-nodel nginx-demo]# ls
nginx-1.14.2.tar.gz pcre-8.38.tar.gz
[root@k8s-nodel nginx-demo]# vim Dockerfile
# 设置基础镜像
FROM centos:7
# 维护者信息
MAINTAINER liugang<liugang@wolfcode.cn>
# 加入构建镜像所需的文件
ADD pcre-8.38.tar.gz /usr/local/src
ADD nginx-1.14.2.tar.gz /usr/local/src
# 安装 c++ 源码编译的基础工具
RUN yum install -y wget gcc gcc-c++ make openssl-devel
# 创建 ww 用户作为 nginx 启动用户
RUN useradd -s /sbin/nologin -M www
# 进入 nginx 解压后的源码目录
WORKDIR /usr/local/src/nginx-1.14.2
# nginx 编译安装
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www with-http_ssl_ module --with-http_stub_status_module --with-pcre=/usr/local/src/pcre-8.38
RUN make && make install
# 关闭 nginx 后台运行
RUN echo 'daemon off;' >> /usr/local/nginx/conf/nginx.conf
# 创建 inginx 命令快速访问的环境变量
# In -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
ENV PATH /usr/local/nginx/sbin:$PATH
# 用自己自定义的首页模板替换 nginx 原本的首页模板
ADD index.html /usr/local/nginx/html
# 暴露端口
EXPOSE 80
# 容器启动命令
CMD ["nginx"]
Registry仓库
基本概念
用于管理docker的镜像 快速交付打包镜像上传仓库 可在任何机器下载 运行为一个容器 便于镜像重复利用
可以存储内部私有镜像,避免暴露外网
常见的仓库
Docker hub
Aliyun
1.登录阿里云Docker Registry
$ docker login --username=leon****@sinacom registry.cn-hangzhou.aliyuncs.com
用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码
2.从Registry中拉取镜像
$docker pull registry.cn-hangzhou.aliyuncs.com/wolfcode_liug/wolfcode_nginx:[镜像版本号]
3.将镜像推送到Registry
$ docker login --username=leon****@sina,com registry.cn-hangzhou.aliyuncs.com
$ docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/wolfcode_liug/wolfcode_nginx:[镜像版本号]
$ docker push registry.cn-hangzhou.aliyuncs.com/wolfcode_liug/wolfcode_nginx:[镜像版本号]
自主搭建(私服)
一、Nexus镜像仓库搭建与配置:
#创建持久化目录
mkdir -p /opt/docker/nexus
#开放权限
chmod 777 -R /opt/docker
#启动nexus容器
docker run -d --restart=always -p 8868:8081 -p 5000:5000 -p 5001:5001 --name nexus -v /opt/docker/nexus:/nexus-datasonatvpe/nexus3
#查看默认密码
docker exec -it nexus /nexus-data/admin.password
二、创建私有镜像仓库
1、repository的类型
hosted,本地仓库,通常我们会部署自己的构件到这一类型的仓库。比如公司的第二方库。
proxy,代理仓库,它们被用来代理远程的公共仓库,如maven中央仓库。
group,仓库组,用来合并多个hosted/proxy仓库,当你的项目希望在多个repository使用资源时就不需要多次引用了,只需要引用一个group即可。
2、创建 docker(hosted) 类型的仓库
在创建镜像仓库的页面中,设置镜像仓库的相关信息,包括名称、HTTP端口、是否允许匿名拉取镜像等信息。这里需要注意的是,此处的HTTP端口(此处的值为8082)很重要,后续拉取和推送进行是使用此端口进行的,而不是nexus本身对外暴露的端口。
3、修改docker配置 安全访问
在/etc/docker/daemon.json文件中添加下面的内容:
[root@localhost ~]# cat /etc/docker/daemon.json
{
"insecure-registries":["192.168.100.163:5000","192.168.100.163:5001"]
}
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# docker info
Insecure Registries:
192.168.100.163:5000 #生效了
127.0.0.0/8
4、上传、拉取镜像
[root@localhost ~]# docker login 192.168.100.163: 5000
Username: admin
Password: admin123
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded #登录成功
注意:登录时,需要提供用户名和密码。认证的信息会被保存在~/.docker/config.json文件,在后续与私有镜像仓库交互时就可以被重用,而不需要每次都进行登录认证。
[root@localhost ~]# docker pull hello-world
[root@localhost ~]# docker tag hello-world 192.168.100.163:5000/helloworld:1.0
[root@localhost ~]# docker push 192.168.100.163: 5000/helloworld:1.0
[root@localhost ~]# docker pull 192.168.100.163: 5000/helloworld:1.0 #拉取镜像
1.0: Pulling from helloworld
1b930d010525: Pull complete
Digest: sha256:92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a
Status: Downloaded newer image for 192.168.100.163:8082/helloworld:1.0
192.168.100.163:8082/helloworld:1.0
一、Harbor
除了Docker Hub以外最早的一个比较受欢迎的Docker企业级Registry 服务器。
docker-compose
使用 Harbor必须要先安装docker 以及 docker-compose
1.安装:
下载后将压缩包上传到服务器使用命令tar -zxf harbor-offline-installer-v2.4.2.tgz
解压
解压后在当前的解压路径可以得到文件夹harbor
,cd harbor
进文件夹:
可以看到文件夹有一堆文件,其中最主要的是 harbor.yml.tmpl
和 install.sh
,他们分别是配置文件和安装执行文件。
# 复制并重命名一份新的配置文件
cp harbor.yml.tmpl harbor.yml
# 使用 vim 编辑配置文件
vim harbor.yml
编辑完成后按ESC
,然后使用命令:wq
保存并推出。
然后继续用命令执行安装./install.sh
。
2、创建项目 用户(开发 管理 访客)
重复上3,4
容器编排
基本概念
就是针对容器生命周期的管理,对容器的生命周期进行更快速方便的方式进行管理
依赖管理,当一个容器必须在另一个容器运行完成后,才能运行时,就需要进行依赖管理
副本数控制,容器有时候也需要集群,快速的对容器集群进行弹性伸缩
配置共享,通过配置文件统一描述需要运行的服务相关信息,自动化的解析配置内容,并构建对应的服务
Docker Compose(单机)
Compose 简介:
Compose 是用于定义和运行多容器 Docker 应用程序的工具,通过 Compose,您可以使用YML 文件来配置应用程序需要的所有服务,然后使用一个命令,就可以从 YML文件配置中创建并启动所有服务。
一、Compose 安装: *注意与docker版本一致
sudo curl -L "http://mirrors.aliyun.com/docker-toolbox/linux/compose/1.21.2/docker-compose-$(uname -s)- $ (uname -m)" -o /usr/local/bin/docker-compose
将可执行权限应用于二进制文件:
sudo chmod +x /usr/local/bin/docker-compose
创建软链:
sudo In -s /usr/local/bin/docker-compose /usr/bin/docker-compose
测试是否安装成功:
docker-compose --version
注意: 对于 alpine,需要以下依赖包: py-pip,python-dev, libffi-dev, openssldev,gcc, libc-dev,和make
二、配置文件案例
服务services
需要运行的容器配置,可以理解为原先用 docker run 命令后面跟的一系列配置信息,都配在这个下面
网络networks
docker-compose 公共自定义网络管理,配置好以后,可以直接在services中引用该网络配置,这个配置可以多个service 使用
数据卷volumes
docker-compose 下的统一数据卷管理,可以给多个service 使用
[root@k8s-node1 wolfcode .cn]# docker run -d --restart=always --net xxxx www/wolfcode .cn:/usr share/nginx/html -e APP_ENV=dev nginx
[root@k8s-nodel docker]# mkdir nginx
[root@k8s-node1 docker]# ls
nexus nginx
[rootak8s-nodel docker]# cd nginx/
[root@k8s-nodel nginx]# Is
[rootak8s-nodel nginx]# touch docker-compose.yml
[root@k8s-nodel nginx]# vim docker-compose.yml
version: "2 .1"
services:
# 其中的一个service 配置
nginx-demo:
image : "nginx"
container_name : "nginx_compose
restart : "always"
netowrks:
- wolfcode_net
volumes :
- wolfcode_volume
eviorment:
APP_ENV: dev
dns :
- 114.114.115.115
ports:
-80:80
netowrks:
wolfcode_net:
driver: bridge
pam :
driver: default
config:
- subnet: 188.18.0.0/16
gateway: 188.18.0.1
volumes :
wolfcode_volume:
- nginx_volume:/usr/share/nginx/html
三、常用命令
[root@k8s-nodel nginx]# docker-compose config opt/docker/nginx/docker-compose.yml
[root@k8s-nodel nginx]# docker-compose create nginx-demo
[root@k8s-nodel nginx]# docker-compose up -d 运行/重新读取配置命令
[root@k8s-nodel nginx]# docker-compose scale nginx-demo=3 不要配置容器名 端口映射ports:
-80
Swarm(分布式集群)
关键概念
Swarm
Node
Task
Service
可视化
一、安装portainer
docker search portainer 搜索portainer,选择自己需要的版本进行下载
#基于docker 运行
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
#基于swarm运行
docker service create -p 9000:9000 --replicas 1 –mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock --mount type=volume,src=portainer_datadst=/data
微服务部署
微服务架构下部署的问题:
1.由于服务+中间件的复杂度,导致部署复杂度也呈指数级上升
2.服务与服务之间的依赖关系
3.服务之间的网络共享问题
4.考虑有状态服务的数据持久化问题
问题一:利用 docker-compose的服务编排能力,来实现对多服务的批量化处理
问题二:利用docker-compose的 depens_on 属性,来设置依赖服务, 必须被依赖服务先启动,当前服务才能启动
问题三:利用自定义网络,或者links属性来连接需要通信的服务
问题四:使用数据卷来进行持久化的数据管理
部署流程:
- 容器编排
- Dockerfile文件编写
针对每一个服务都需要编写自定义的Dockerfile,需要对所有服务的Dockerfile文件进行一个统一的管理。
- 网络问题
自定义网络,或者利用links属性,将两个容器连接起来,以上两种方案都可以实现基于容器名称的访问
- 日志收集问题
ELK:利用Logstash或FileBeat进行数据收集,将数据存入ES通过Kibana进行统一的数据可视化展示
- 监控问题
应用/容器监控,健康状况、资源使用情况都需要进行监控,基于普罗米修斯实现各个类型的监控
Docker构建项目结构规划解析
更多推荐
所有评论(0)