TOC
在面对复杂的分布式微服务应用时,传统的手工的基于物理机或虚拟机的部署方式效率低下且容易出错;Docker容器技术的出现,提供了一种可靠的打包和交付微服务的机制;另外向K8s这样的容器云平台的引入,可以进一步简化分布式微服务的部署和管理;通过K8s可以做到一键部署整个微服务应用,也可以一键扩容微服务应用;因此业界开始提出云原生Cloud Native架构理念,也就是说应用开发不仅要用微服务的方式组织架构,而且在架构上一开始就要考虑直接面向容器云环境部署。微服务架构和云原生架构相辅相成,微服务若离开了容器或容器云,部署和运维效率就会大打折扣
本地开发部署架构和需求
-
本地IDE部署架构
- 各服务对应不同端口
-
软件需求
- SwitchHosts
- SkyWalking 6.1.0:配置agent.service_name、collector.backend_service
- MySQL 5.7
- 阿里云邮箱账户:用于校验功能
手工服务部署和测试
-
部署步骤
-
清理释放内存
- 活动监控器
- 关闭Docker等大进程
-
部署数据库
- staffjoy_account
- staffjoy_company
-
部署SkyWalking
- bin/startup.sh(字节码注入的方式运行)
- IDE设置skywalking-agent
- VM options: -javaagent:D:\apache-skywalking-apm-bin\agent
- Environment variables: SW_AGENT_NAME:account-svc
-
部署服务
- 本地机密数据配置
- config/*.yml
- faraday网关配置review
mappings: - name: faraday_route host: faraday.staffjoy-v2.local destinations: httpbin.org - name: account_route host: account.staffjoy-v2.local destinations: localhost:8081 - name: company_route host: company.staffjoy-v2.local destinations: localhost:8082 - name: ical_route host: ical.staffjoy-v2.local destinations: localhost:8083 - name: whoami_route host: whoami.staffjoy-v2.local destinations: localhost:8084 timeout: connect: 10000 read: 10000 - name: superpowers_route host: superpowers.staffjoy-v2.local destinations: localhost:8085 - name: www_route host: www.staffjoy-v2.local destinations: localhost:8086 - name: myaccount_route host: myaccount.staffjoy-v2.local destinations: localhost:9000 - name: app_route host: app.staffjoy-v2.local destinations: localhost:9001
- 启动顺序:mail -> bot -> account -> company -> www -> whoami -> faraday
- 本地机密数据配置
-
部署单页应用(staffjoy/frontend下的app和myaccount)
- npm install
- npm start
-
启用SwitchHosts
- hosts文件是用于本地DNS服务的,采用 [ip 域名] 的格式卸载一个文本文档中,作用是将一些常用的网址域名与其对应的ip地址建立一个关联数据库:当用户在浏览器中输入一个网址时,系统会首先自动从hosts文件中寻找对应的ip地址,一旦找到会立即打开对应网页,若没找到则再会将网址提交DNS域名解析服务器进行ip地址的解析
127.0.0.1 account.staffjoy-v2.local 127.0.0.1 faraday.staffjoy-v2.local 127.0.0.1 myaccount.staffjoy-v2.local 127.0.0.1 whoami.staffjoy-v2.local 127.0.0.1 www.staffjoy-v2.local 127.0.0.1 ical.staffjoy-v2.local 127.0.0.1 staffjoy-v2.local 127.0.0.1 app.staffjoy-v2.local 127.0.0.1 company.staffjoy-v2.local
-
-
测试步骤
- 浏览器访问 www.staffjoy-v2.local
- 校验业务流程:注册管理员和公司,登录;注册雇员,登录;排班
- 输入邮箱->邮箱点击激活链接->设置密码、全名、手机号->设置公司名、地址->跳转到app.staffjoy-v2.local
- 创建雇员->设置雇员全名、邮箱、手机号->雇员到邮箱激活->雇员完善密码->跳转到myaccount.staffjoy-v2.local
- logout->管理员登录->SETTINGS->Add New Job->SCHEDULER->选择日期、时间、雇员和Job->Publish Week
- 校验cookie
- chrome dev tools->Application->Cookies
- name为staffjoy-faraday,value为JWT令牌
- 校验DB
SkyWalking调用链监控实验
- 测试步骤
- 浏览器访问dashboard
- http://localhost:8080
- admin/admin
- 校验拓扑图
- 校验仪表盘
- 校验追踪
- 结束清理
- 关闭服务
- 关闭单页应用
- 关闭SkyWalking(jps)
- 浏览器访问dashboard
Docker和Docker Compose简介
-
容器用途
- 标准化打包机制:由容器镜像技术实现
- 隔离:由linux control groups、namespace技术实现
- 标准化部署:容器在软件应用和操作系统之间引入一层抽象,一方面保证部署时环境的一致性,另一方面使大规模标准化部署称为可能。这就是为什么在docker容器技术出现之前很难做到标准化部署,发布平台一般和具体语言和技术栈绑定,如java的tomcat部署方式和python、ruby要开发不同的发布工具;容器技术出现后,像k8s这些和应用无关的标准化发布平台开始出现,发布可以统一,不需要为语言栈、框架开发单独的发布工具,可以用统一的平台来进行部署
-
OS & Kernel 操作系统和内核
- User Space:User Progress/Applications/Programs 用户空间,调用内核空间的功能
- Kernel Space:Operating System:Kernel 管理硬件,调度进程
- Hardware:Memory - Disk - Network Interface - CPU
-
虚拟机和容器
- 虚拟机:由硬件虚拟化和内核虚拟化共同实现,在宿主机操作系统或物理机硬件基础上,通过引入Hypervisor来创建一层虚拟化的硬件,可以虚拟出cpu、磁盘、网卡等,这之上再运行guest操作系统;隔离性较好,是一种强隔离性机制,但是比较重量,启动较慢,消耗资源多
- 容器:直接构建于宿主机操作系统之上,共享宿主机操作系统的内核,只引入了少量的guest os的部分,所以容器相对比较轻量;隔离性不如虚拟机,是一种软件隔离,但是轻量、启动快、消耗资源少;在同一个物理机上能启动的容器数量远远多于虚拟机数量
虚拟机 Application 容器 Bins/Libs Application Guest OS Bins/Libs Hypervisor Minimal Guest OS Container Engine Host OS Host OS Hardware Hardware
-
Docker容器核心技术
- 容器主要基于linux内核的一些机制实现
- Linux Kernel
- CGroups(控制容器对cpu和内存资源的使用量): cpu, cpuset, memory, device
- Networking(实现容器网络的底层技术,包括虚拟网卡、虚拟网桥、iptables这些技术): veth, bridge, iptables
- Namespaces(控制每个容器都有相互隔离的进程、文件系统、网络等空间): PID, MNT, IPC, UTS, NET
- Storage(存储驱动): Device Mapper, Btrfs, Aufs
-
容器镜像
- 可认为是一个固化的操作系统,不同于宿主机上的完整的操作系统(包括文件系统、二进制库、内核),容器的操作系统只包含文件系统和二进制库,是共享宿主机操作系统内核的
- 容器镜像采用分层的方式来组织
- 底层基础镜像Base Image,是容器所采用的操作系统,如Ubuntu,可以和宿主机的操作系统不一样,但是它们共享宿主机操作系统的内核
- 基础镜像之上可以有多层镜像,如JDK依赖层
- 之上可以包含Java应用程序的二进制文件的依赖层等
- 容器镜像的分层组织形式也被称为洋葱头文件系统,这种方式可以很方便的实现镜像层的重用:如果两个容器底层镜像相同,镜像层可以有一个唯一的hash值来标识,可以共用这个镜像层,大大节省存储和传输的开销
-
Docker架构
- Docker client
- 指挥docker执行操作的命令行工具,可在本地或远程操作
- docker build:可根据dockerfile构建镜像
- docker pull:从镜像仓库拉去镜像
- docker run:运行容器
- Docker host
- 驻有Docker daemon,接收docker client的指令,执行拉取镜像、缓存、启动、运行、管理容器、生成镜像这些操作
- Images
- Containers
- Docker registry
- 集中存储容器镜像的仓库,官方的就是dockerhub,也可自建私有的仓库
- 流程举例:
- 用户通过docker client运行docker run helloworld
- docker host上的daemon接收到运行命令会先到本地缓存查找helloworld镜像,若无则去docker registry拉取,然后做本地缓存;有了镜像后就会创建并启动容器,最后执行容器里面的命令
- Docker client
-
Docker Compose
- docker主要用于运行单容器应用,docker compose用于定义和运行多容器应用的工具
- 使用docker compose可以将多容器应用的部署架构规范在一个yml文件里面,如一个比较复杂的微服务依赖的整个依赖关系、部署架构规范在一个docker-compose.yml文件里面
- 通过docker-compose up一键的方式启动整个应用,也可通过docker-compose down一键销毁整个应用
- 主要适用于开发测试环境,可用来运行微服务快速部署和测试,对于生产环境则应该使用k8s这些生产级的容器云平台
容器镜像构建Dockerfile解析
-
Account服务Dockerfile
# 构建用基础镜像 FROM java:8-jdk-alpine # 将maven build生成的jar包拷贝到镜像的/usr/app/目录下 COPY ./target/account-svc-1.0.0.jar /usr/app/ # 设置工作目录 WORKDIR /usr/app RUN sh -c 'touch account-svc-1.0.0.jar' # 容器启动后,如何运行account service ENTRYPOINT ["java", "-jar", "account-svc-1.0.0.jar"]
-
MyAccount单页应用Dockerfile
- 两阶段构建:单页应用的构建先要生成静态资源,然后拷贝到nginx里
# 构建用的基础镜像 FROM node:alpine as builder # 设置工作目录 WORKDIR '/build' # 将单页应用源代码、构建需要的资源、第三方依赖拷贝到镜像中 COPY myaccount ./myaccount COPY resources ./resources COPY third_party ./third_party # 设置工作目录 WORKDIR '/build/myaccount' # 构建:安装reactJs需要的依赖 RUN npm install # 构建:构建node-sass RUN npm rebuild node-sass # 构建:生成静态html和js文件 RUN npm run build RUN ls /build/myaccount/dist # 换新的基础镜像 FROM nginx # 暴露80端口 EXPOSE 80 # 把生成的builder资源拷贝到nginx镜像里 COPY --from=builder /build/myaccount/dist /usr/share/nginx/html
Docker Compose部署文件解析
-
Docker Compose部署架构
- 用IDE时每个服务用不同的端口,如果用docker compose的方式:微服务、前端应用、网关都用的是80端口,因为docker compose环境内部有独立的网络,这些微服务可以认为是独立的小型虚拟环境,有自己的网络栈,所有每个都可以用相同的端口,不会有冲突
-
部署文件解析
- .env 放私密配置
SPRING_PROFILES_ACTIVE=test SERVER_PORT=80 EMAIL_SERVICE_ENDPOINT=http://email-service COMPANY_SERVICE_ENDPOINT=http://company-service ACCOUNT_SERVICE_ENDPOINT=http://account-service BOT_SERVICE_ENDPOINT=http://bot-service SMS_SERVICE_ENDPOINT=http://sms-service SENTRY_DSN=https://80aaf4ae889b414f9fe72e3904cd5246@sentry.io/1380198 SIGNING_SECRET=secret INTERCOM_ACCESS_TOKEN=YOUR_INTERCOM_ACCESS_TOKEN INTERCOM_APP_ID=TBD INTERCOM_SIGNING_SECRET=TBD ALIYUN_ACCESS_KEY=YOUR_ALIYUN_ACCESS_KEY ALIYUN_ACCESS_SECRET=YOUR_ALIYUN_ACCESS_SECRET RECAPTCHA_PUBLIC=test-recaptcha-public RECAPTCHA_PRIVATE=test-recaptcha-private ACCOUNT_DATASOURCE_URL=jdbc:mysql://host.docker.internal:3306/staffjoy_account?useUnicode=true&characterEncoding=utf-8 ACCOUNT_DATASOURCE_USERNAME=root ACCOUNT_DATASOURCE_PASSWORD=root COMPANY_DATASOURCE_URL=jdbc:mysql://host.docker.internal:3306/staffjoy_company?useUnicode=true&characterEncoding=utf-8 COMPANY_DATASOURCE_USERNAME=root COMPANY_DATASOURCE_PASSWORD=root
- docker-compose.yml
version: '3.7' services: account-service: build: ./account-svc # dockerfile路径,用于做构建 image: boboweike/account-svc # 构建产生的镜像名称 environment: # 环境变量 - SPRING_PROFILES_ACTIVE - SERVER_PORT - SIGNING_SECRET - SENTRY_DSN - EMAIL_SERVICE_ENDPOINT - COMPANY_SERVICE_ENDPOINT - BOT_SERVICE_ENDPOINT - INTERCOM_ACCESS_TOKEN - ACCOUNT_DATASOURCE_URL - ACCOUNT_DATASOURCE_USERNAME - ACCOUNT_DATASOURCE_PASSWORD depends_on: # 服务之间依赖的指定 - bot-service - email-service networks: # 网络配置 - internal_access - external_access # db access ... faraday-service: build: ./faraday image: boboweike/faraday-svc ports: - 80:80 # 不仅内部有80端口,还要向外暴露80端口 environment: - SPRING_PROFILES_ACTIVE - SERVER_PORT - SENTRY_DSN - SIGNING_SECRET depends_on: - account-service - company-service - www-service - whoami-service # - ical-service # commented for demo - myaccount-service - app-service networks: - internal_access - external_access myaccount-service: build: context: ./frontend dockerfile: myaccount/Dockerfile image: boboweike/myaccount-spa networks: - internal_access ... networks: internal_access: internal: true external_access:
将Staffjoy部署到本地Docker Compose环境
-
Docker Desktop for Mac/Win
-
download example
git clone https://github.com/docker/doodle.git
- Build & tag一个docker镜像
cd doodle\cheers2019 docker build -t wnzhong/cheers2019
- run container
docker run -it --rm wnzhong/cheers2019
- share image on Docker Hub
docker login docker push wnzhong/cheers2019
-
构建和部署
- 镜像构建
- mvn clean package -DskipTests
- docker-compose build
- docker images
- 部署MySQL数据库
- staffjoy_account
- staffjoy_company
- 部署Staffjoy
- docker-compose up
- docker-compose ps
- 启用SwitchHosts
- 校验Staffjoy
- 清理
- docker-compose down
- 镜像构建
「真诚赞赏,手留余香」
真诚赞赏,手留余香
使用微信扫描二维码完成支付
