本文依然是通过 staffjoy 来学习和实践微服务和云原生相关内容。上篇文章着重于学习微服务相关的概念、原理,各个中间件的知识以及具体的代码实现。承接上文,本文重点学习云原生部分的内容,以及如何将项目正确部署。
微服务+云原生实践(Spring + K8s)
本地开发环境部署
本地开发环境部署时,要给每个服务开放一个端口,在 IDEA 里启动后都是一个个进程
软件安装
SwitchHosts
因为整个服务都是通过域名访问的,所以需要一个域名解析工具,下载地址:
https://github.com/oldj/SwitchHosts/releases
SkyWalking
用于数据监控,下载 6. 1.0 版本,下载地址:
http://archive.apache.org/dist/skywalking/
文档地址为:
https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/readme/
MySQL
本来是想下载经典的 5.7 版本,但是由于电脑是 M1 芯片的 Mac,为了防止有适配问题,直接下载了 M1 的适配版本
https://dev.mysql.com/downloads/mysql/
安装之后需要配置环境变量:
在 ~/.bash_profile 文件中添加
export PATH=$PATH:/usr/local/mysql/bin
export PATH=$PATH:/usr/local/mysql/support-files
在从命令行输入 mysql -u root -p 指令时,可能会出现报错信息:
zsh: command not found: mysql
这时修改 ~/.bashrc 文件,在其中添加
alias mysql=/usr/local/mysql/bin/mysql
本地部署(IDEA 环境)
清理内存
部署 MySQL 数据库
本项目主要用到两个数据库,一个是 account,另外一个是 company。它们的 sql 文件分别在 account-svc 和 company-svc 的 resources 中。
account 有一个表:
CREATE TABLE IF NOT EXISTS account (
id VARCHAR(255),
email VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL default '',
phone_number VARCHAR(255) NOT NULL,
confirmed_and_active BOOLEAN NOT NULL DEFAULT false,
member_since TIMESTAMP NOT NULL default current_timestamp,
password_hash VARCHAR(100) default '',
photo_url VARCHAR(255) NOT NULL,
support BOOLEAN NOT NULL DEFAULT false,
PRIMARY KEY (id),
key ix_account_email (email), -- TODO use unique key
key ix_account_phone_number (phone_number) -- TODO use unique key
) ENGINE=InnoDB;
company 有七个表:
CREATE TABLE IF NOT EXISTS company (
id VARCHAR(255),
name VARCHAR(255) NOT NULL DEFAULT '',
archived boolean DEFAULT false,
default_timezone VARCHAR(255) NOT NULL DEFAULT '',
default_day_week_starts VARCHAR(20) NOT NULL DEFAULT 'Monday',
PRIMARY KEY (id)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS directory (
id VARCHAR(255),
company_id VARCHAR(255) NOT NULL,
user_id VARCHAR(255) NOT NULL,
internal_id VARCHAR(255) NOT NULL,
PRIMARY KEY (id),
key ix_directory_company_id (company_id),
key ix_directory_user_id (user_id),
key ix_directory_internal_id (internal_id),
UNIQUE key ix_directory_company_user_internal_id (company_id, user_id, internal_id)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS admin (
id VARCHAR(255),
company_id VARCHAR(255) NOT NULL,
user_id VARCHAR(255) NOT NULL,
PRIMARY KEY (id),
KEY ix_admin_company_id (company_id),
KEY ix_admin_user_id (user_id),
UNIQUE KEY ix_admin_company_user_id (company_id, user_id)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS team (
id VARCHAR(255) NOT NULL,
company_id VARCHAR(255) NOT NULL DEFAULT '',
name VARCHAR(255) NOT NULL DEFAULT '',
archived boolean NOT NULL DEFAULT false,
timezone VARCHAR(255) NOT NULL DEFAULT '',
day_week_starts VARCHAR(20) NOT NULL DEFAULT 'Monday',
color VARCHAR(10) NOT NULL DEFAULT '#48B7AB',
PRIMARY KEY (`id`),
KEY ix_team_company_id (company_id)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS worker (
id VARCHAR(255),
team_id VARCHAR(255) NOT NULL,
user_id VARCHAR(255) NOT NULL,
PRIMARY KEY (id),
KEY ix_team_team_id (team_id),
KEY ix_team_user_id (user_id),
UNIQUE KEY ix_worker_team_user_id (team_id, user_id)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS job (
id VARCHAR(255) NOT NULL,
team_id VARCHAR(255) NOT NULL DEFAULT '',
name VARCHAR(255) NOT NULL DEFAULT '',
archived boolean NOT NULL DEFAULT false,
color VARCHAR(10) NOT NULL DEFAULT '#48B7AB',
PRIMARY KEY (id),
KEY ix_job_team_id (team_id)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS shift (
id VARCHAR(255) NOT NULL,
team_id VARCHAR(255) NOT NULL DEFAULT '',
job_id VARCHAR(255) NOT NULL DEFAULT '',
user_id VARCHAR(255) NOT NULL DEFAULT '',
published boolean NOT NULL DEFAULT false,
start TIMESTAMP NOT NULL DEFAULT current_timestamp,
stop TIMESTAMP NOT NULL DEFAULT current_timestamp,
PRIMARY KEY (id),
KEY ix_job_shift_id (`job_id`),
KEY ix_job_user_id (`user_id`)
) ENGINE=InnoDB;
SkyWalking
将下载好的 SkyWalking 解压到合适的位置,从终端中进入对应的目录,执行以下指令:
macos@macosdeMacBook-Pro apache-skywalking-apm-bin % bin/startup.sh
SkyWalking OAP started successfully!
SkyWalking Web Application started successfully!
这样买点程序以及 web 端的 dashboard 都已经启动成功。
因为 SkyWalking 是通过字节码注入的方式运行的,所以微服务要使用这些功能在 IDEA 中也要进行一些相应的配置:
在 Run > Edit Configurations 中进行配置虚拟机选项,以及给每个服务通过环境变量的方式传入服务名。
其中的 SW_AGENT_NAME 对应的 SkyWalking 源文件中 /agent/config/agent.config 中的相应变量。
部署服务
1. 本机机密数据配置
在目录 /config/application.yml 文件中,因为涉密所以不能上传到 github 上,在 .gitignore
# store your development credentials for spring app here
# this file should and will not be checked into version control
staffjoy:
common:
sentry-dsn: https://80bbf4ae778b525f9fe72e2813cd5246@sentry.io/1271087
signing-secret: YOUR-SIGNING-SECRET
intercom-access-token: YOUR-INTERCOM-ACCESS-TOKEN
aliyun-access-key: YOUR-ALIYUN-ACCESS-KEY
aliyun-access-secret: YOUR-ALIYUN-ACCESS-SECRET
aliyun-sms-sign-name: YOUR-ALIYUN-SMS-SIGN-NAME
intercom-app-id: YOUR-INTERCOM-APP-ID
intercom-signing-secret: YOUR-INTERCOM-SIGNING-SECRET
recaptcha-public: YOUR-RECAPTCHA-PUBLIC
recaptcha-private: YOUR-RECAPTCHA-PRIVATE
需要将真实数据填入后将 .example 后缀去掉。在根目录下的 /config 目录下的文件,Spring 会认出来是配置文件
2. Faraday 配置 Review
Faraday 的配置文件在对应模块的 resources/application-dev.yml 文件中。包含的路由映射表为:
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
3. 启动服务
启动顺序为:
mail-svc -> bot-svc -> account-svc -> company-svc -> whoami-svc -> www-svc -> faraday-svc
接下来是两个单页应用,通过终端去运行:
首先进入目录 /frontend/myaccount,然后输入指令
// 加载依赖
macos@macosdeMacBook-Pro myaccount % npm install
// 启动服务
macos@macosdeMacBook-Pro myaccount % npm start
然后是目录 /frontend/app, 输入同样的指令
// 加载依赖
macos@macosdeMacBook-Pro myaccount % npm install
// 启动服务
macos@macosdeMacBook-Pro myaccount % npm start
配置 StructHosts
# My hosts
127.0.0.1 account.staffjoy-v2.local
127.0.0.1 faraday.staffjoy-v2.local
127.0.0.1 company.staffjoy-v2.local
127.0.0.1 ical.staffjoy-v2.local
127.0.0.1 whoami.staffjoy-v2.local
127.0.0.1 www.staffjoy-v2.local
127.0.0.1 app.staffjoy-v2.local
127.0.0.1 myaccount.staffjoy-v2.local
127.0.0.1 staffjoy-v2.local
至此,前后端服务都已经启动完成,可以通过浏览器输入网址进行访问了。
4. skywalking dashboard
Docker 部署
容器概念
虚拟机通过引入 Hypervisor 层来做硬件的虚拟映射,在此基础上再运行 Guest OS。虚拟机具有强隔离性,但是重量级比较大,容器是软件级别的隔离,能够达到秒级的启动。
容器的镜像可以理解成为固化的操作系统,容器的操作系统只包含文件系统和二进制库,跟虚拟机的完整操作系统相比缺少内核,因为容器共享宿主机操作系统的内核。容器镜像采用分层的机制,好处就是能够做到镜像的重用。如果两个镜像的底层环境相同,那么可以公用底层镜像层。
Docker Compose 用于本地开发或者测试环境,可以进行容器的编排,提供一键部署和一键销毁应用的功能。
镜像构建 & Dockerfile 剖析
服务端以 bot-svc
为例,dockerfile 为:
FROM java:8-jdk-alpine
COPY ./target/bot-svc-1.0.0.jar /usr/app/
WORKDIR /usr/app
RUN sh -c 'touch bot-svc-1.0.0.jar'
ENTRYPOINT ["java", "-jar", "bot-svc-1.0.0.jar"]
单页应用的 dockerfile 内容为:
FROM node:alpine as builder
WORKDIR '/build'
COPY myaccount ./myaccount
COPY resources ./resources
COPY third_party ./third_party
WORKDIR '/build/myaccount'
RUN npm install
RUN npm rebuild node-sass
RUN npm run build
RUN ls /build/myaccount/dist
FROM nginx
EXPOSE 80
COPY --from=builder /build/myaccount/dist /usr/share/nginx/html
每一个 springboot 服务以及每一个单页应用都需要编写一个 dockerfile。
Docker Compose File 剖析
需要注意的是不同于本地开发环境部署,这里每个服务的端口号都是 80。这是因为容器中的网络是公用的,只需要一个容器入口端口即可。
在 staffjoy 根目录下有 docker compose 文件:
version: '3.7'
services:
account-service:
build: ./account-svc
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
company-service:
build: ./company-svc
image: boboweike/company-svc
environment:
- SPRING_PROFILES_ACTIVE
- SERVER_PORT
- SIGNING_SECRET
- SENTRY_DSN
- EMAIL_SERVICE_ENDPOINT
- ACCOUNT_SERVICE_ENDPOINT
- BOT_SERVICE_ENDPOINT
- COMPANY_DATASOURCE_URL
- COMPANY_DATASOURCE_USERNAME
- COMPANY_DATASOURCE_PASSWORD
depends_on:
- bot-service
- email-service
networks:
- internal_access
- external_access # db access
bot-service:
build: ./bot-svc
image: boboweike/bot-svc
environment:
- SPRING_PROFILES_ACTIVE
- SERVER_PORT
- SENTRY_DSN
- EMAIL_SERVICE_ENDPOINT
- ACCOUNT_SERVICE_ENDPOINT
- COMPANY_SERVICE_ENDPOINT
- SMS_SERVICE_ENDPOINT
depends_on:
- email-service
# - sms-svc # commented for demo
networks:
- internal_access
email-service:
build: ./mail-svc
image: boboweike/mail-svc
environment:
- SPRING_PROFILES_ACTIVE
- SERVER_PORT
- SENTRY_DSN
- ALIYUN_ACCESS_KEY
- ALIYUN_ACCESS_SECRET
networks:
- internal_access
- external_access # aliyun access
# commented for demo
# sms-service:
# build: ./sms-svc
# image: sms-svc
# environment:
# - SPRING_PROFILES_ACTIVE=test
whoami-service:
build: ./whoami-svc
image: boboweike/whoami-svc
environment:
- SPRING_PROFILES_ACTIVE
- SERVER_PORT
- SENTRY_DSN
- INTERCOM_APP_ID
- INTERCOM_SIGNING_SECRET
- ACCOUNT_SERVICE_ENDPOINT
- COMPANY_SERVICE_ENDPOINT
depends_on:
- account-service
- company-service
networks:
- internal_access
# commented for demo
# ical-service:
# build: ./ical-svc
# image: ical-svc
# environment:
# - SPRING_PROFILES_ACTIVE=test
# depends_on:
# - company-service
www-service:
build: ./web-app
image: boboweike/www-svc
environment:
- SPRING_PROFILES_ACTIVE
- SERVER_PORT
- SENTRY_DSN
- SIGNING_SECRET
- ACCOUNT_SERVICE_ENDPOINT
- COMPANY_SERVICE_ENDPOINT
- EMAIL_SERVICE_ENDPOINT
- RECAPTCHA_PUBLIC
- RECAPTCHA_PRIVATE
depends_on:
- account-service
- company-service
- email-service
networks:
- internal_access
faraday-service:
build: ./faraday
image: boboweike/faraday-svc
ports:
- 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
app-service:
build:
context: ./frontend
dockerfile: app/Dockerfile
image: boboweike/app-spa
networks:
- internal_access
networks:
internal_access:
internal: true
external_access:
因为具体的配置数据涉密,所以将具体的配置值写在另外一个 .env 文件中:
当然在根目录的 .gitignore 文件中要明确该文件不能上传
docker-compose.yml 文件的具体结构主要分为三部分:
- version
- services
- networks
对于每个 service 要配置一下内容:
- build: 服务 dockerfile 的路径
- image: 用户名/镜像名称
- environment: 传入所需的环境变量
- depends_on: 服务关系的指定,决定了启动服务的顺序
- networks: 网络配置
镜像构建
在根目录下执行打包指令:
执行 docker compose 指令:mvn clean package -DskipTests
构建好之后通过 docker images 指令可以查看镜像情况,也可以通过 docker desktop 查看:docker-compose build
macos@macosdeMBP staffjoy % docker images REPOSITORY TAG IMAGE ID CREATED SIZE boboweike/faraday-svc latest cf0bd503a720 11 seconds ago 227MB boboweike/app-spa latest 7dcc1d2696f0 15 seconds ago 141MB boboweike/myaccount-spa latest c00841ffd14b 2 minutes ago 139MB boboweike/www-svc latest 5818df8564c6 44 minutes ago 249MB boboweike/whoami-svc latest a246411a7f5d 44 minutes ago 220MB boboweike/account-svc latest 4f5e959b8936 44 minutes ago 263MB boboweike/company-svc latest 9172bfeadfb8 44 minutes ago 262MB boboweike/bot-svc latest 7b6e24081427 44 minutes ago 220MB boboweike/mail-svc latest 594794ff2e36 44 minutes ago 220MB docker/getting-started latest 720f449e5af2 2 weeks ago 27.2MB
部署 MySQL
因为在之前的本地开发环境部署过程中已经起过 MySQL 服务,这里略过,只需要让 docker 环境中的服务连接到数据库即可部署 staffjoy 服务
在 staffjoy 根目录下使用指令:
查看服务运行情况: ```bash macos@macosdeMBP staffjoy % docker-compose psdocker-compose up
Name Command State Ports
staffjoy_account-service_1 java -jar account-svc-1.0. … Up
staffjoy_app-service_1 /docker-entrypoint.sh ngin … Up
staffjoy_bot-service_1 java -jar bot-svc-1.0.0.jar Up
staffjoy_company-service_1 java -jar company-svc-1.0. … Up
staffjoy_email-service_1 java -jar mail-svc-1.0.0.jar Up
staffjoy_faraday-service_1 java -jar faraday-1.0.0.jar Up 0.0.0.0:80->80/tcp
staffjoy_myaccount-service_1 /docker-entrypoint.sh ngin … Up
staffjoy_whoami-service_1 java -jar whoami-svc-1.0.0.jar Up
staffjoy_www-service_1 java -jar web-app-1.0.0.jar Up
<a name="d7dMq"></a>
### 启用 SwitchHosts
![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640080636461-d72759b2-7ee1-475d-b258-1f1a031a8a76.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=480&id=ucf988359&margin=%5Bobject%20Object%5D&name=image.png&originHeight=960&originWidth=1600&originalType=binary&ratio=1&rotation=0&showTitle=false&size=151380&status=done&style=none&taskId=ue64d337b-0264-4160-a9e1-c6765c78621&title=&width=800)<br />之后就可以通过 web 验证
<a name="JjqAg"></a>
# 阿里云环境部署
<a name="a1Trf"></a>
## 云原生
定义为:基于微服务原理而开发的应用,以容器方式打包。在运行时,容器由运行于云基础设施之上的平台进行调度。应用开发采用持续交付和 DevOps 实践。
<a name="SJJeJ"></a>
## K8s
![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640095481723-08a1a1f1-f910-49e5-a9cc-157dbbc5ae75.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=554&id=u541f579e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1108&originWidth=1862&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1324949&status=done&style=none&taskId=ufeaa5ba3-2344-40a5-ad9e-3410f0a2043&title=&width=931)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640101343822-d35534e0-e6db-4364-b2a9-884ae034ee7d.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=650&id=u25064e37&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1300&originWidth=2362&originalType=binary&ratio=1&rotation=0&showTitle=false&size=999368&status=done&style=none&taskId=ud24c177c-c8a9-487f-a6b4-52a41a22ace&title=&width=1181)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640101665557-b98421cb-98f2-45d5-9ce0-3e5af8e54a27.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=580&id=u3ec6f307&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1160&originWidth=2054&originalType=binary&ratio=1&rotation=0&showTitle=false&size=378626&status=done&style=none&taskId=ue6126db4-1590-4aa0-8911-11ea5209526&title=&width=1027)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640101730845-11d2d7d5-fd57-4908-b3c6-98ef47a8d215.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=579&id=u5404c388&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1158&originWidth=2086&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1648635&status=done&style=none&taskId=u21c0738a-54ad-4b10-9e2c-c1c52e29ebd&title=&width=1043)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640101783214-92f04ad0-8af6-47a0-86b4-595b7118d88a.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=572&id=ueaa5671a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1144&originWidth=2110&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1304661&status=done&style=none&taskId=u94f7627a-e183-4bfa-97ec-c1fd0e077de&title=&width=1055)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640102255657-a9ceea03-a22e-4554-a49b-fea4a825b0ff.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=590&id=u30008271&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1180&originWidth=1796&originalType=binary&ratio=1&rotation=0&showTitle=false&size=444616&status=done&style=none&taskId=ue956fadb-63ea-49e1-947f-36997200073&title=&width=898)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640102327742-7ebcc90c-3000-447b-aabe-c7897c11df57.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=573&id=uf302e5a8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1146&originWidth=1940&originalType=binary&ratio=1&rotation=0&showTitle=false&size=481806&status=done&style=none&taskId=u5bf6da6a-5cf4-4fce-ba89-fa084159f80&title=&width=970)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640102570912-6cc93d78-624d-44c7-af45-0630691b1655.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=597&id=u8e3b727d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1194&originWidth=1728&originalType=binary&ratio=1&rotation=0&showTitle=false&size=484858&status=done&style=none&taskId=ubfd42ad9-ba42-4dcb-b73f-1ad9294240b&title=&width=864)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640102695812-dc3a9a7f-eda5-4fa6-96e0-ac1b98eebf35.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=562&id=u8e8bce5c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1124&originWidth=2250&originalType=binary&ratio=1&rotation=0&showTitle=false&size=495839&status=done&style=none&taskId=u1472debd-137c-4dc1-acd4-99cda31bed6&title=&width=1125)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640102749063-a67109b2-1a58-4d5b-8b17-1557ae403a0b.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=504&id=ud07f64d2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1008&originWidth=2286&originalType=binary&ratio=1&rotation=0&showTitle=false&size=454122&status=done&style=none&taskId=u84814dd1-8860-474c-b006-3622407efe6&title=&width=1143)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640103104615-1a78459f-9f6b-4d65-81b9-b588e3fae538.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=556&id=u14491f88&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1112&originWidth=1948&originalType=binary&ratio=1&rotation=0&showTitle=false&size=714230&status=done&style=none&taskId=u9d1815a9-0b27-438c-96fe-e6a2bb712e5&title=&width=974)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640103205784-9a007fa7-db16-4a9c-b04e-5409124d3364.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=529&id=u5e2f4590&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1058&originWidth=2062&originalType=binary&ratio=1&rotation=0&showTitle=false&size=302385&status=done&style=none&taskId=u3dd210fa-073f-4aef-b857-fb597356323&title=&width=1031)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640151463295-ac4a8045-a57e-4c2d-8124-6d02e47705b9.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=581&id=u12e52fda&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1162&originWidth=2164&originalType=binary&ratio=1&rotation=0&showTitle=false&size=477085&status=done&style=none&taskId=ua0b2d672-e21c-4425-b734-e68b4c9e71b&title=&width=1082)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640155173750-eaadc58e-b764-4a13-87ab-fdf2f5fddf2e.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=619&id=ubfe50e73&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1238&originWidth=1786&originalType=binary&ratio=1&rotation=0&showTitle=false&size=478012&status=done&style=none&taskId=u07cc802f-9d2f-4dee-b31b-924f18915e1&title=&width=893)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640155381648-12612b52-987c-4fcd-96b6-81cf993bc637.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=566&id=u1646e3ae&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1132&originWidth=1926&originalType=binary&ratio=1&rotation=0&showTitle=false&size=354702&status=done&style=none&taskId=u15a92f71-a38f-4c11-80d2-35a7cddfe24&title=&width=963)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640155399969-7515e657-1f24-4630-85d0-b135081df5e1.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=534&id=u6921ecd2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1068&originWidth=1874&originalType=binary&ratio=1&rotation=0&showTitle=false&size=315725&status=done&style=none&taskId=u237cf21b-c932-41e2-94f6-4d60920127a&title=&width=937)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640155622257-d18a8125-fd84-4f5e-8e56-ddbe83702d5a.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=594&id=u95157c87&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1188&originWidth=1958&originalType=binary&ratio=1&rotation=0&showTitle=false&size=394860&status=done&style=none&taskId=ud5290b08-a1b6-44f3-a712-506387a223d&title=&width=979)<br />k8s 给每个 Node 都搭建一个虚拟网桥(图中红色显示),然后给每个 pod 分配一个 ip 地址,同个 pod 内的容器之间通过 Localhost 就可以访问,添加 pod 以后会自动分配新的 ip 地址。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640160659003-577898d3-c69b-4582-810b-ab73b4265c62.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=614&id=u6c7a88f8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1228&originWidth=2196&originalType=binary&ratio=1&rotation=0&showTitle=false&size=621536&status=done&style=none&taskId=u0587f367-8fe0-4d9b-a930-346dff5dfa9&title=&width=1098)<br />引入 service 来解决以下问题:
1. 各个 pod 是动态变化的,所以 ip 地址也是变化的,如何正确寻址?
1. 如何做负载均衡?
Service 可以屏蔽 pod 的地址变化,同时实现对目标 pod 的负载均衡和访问。客户端只需要访问 service,通过 service name 即可访问到目标服务。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640161059938-c3dfbc10-bc86-42f0-b73b-b3d72d46f060.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=652&id=ucf5ae100&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1304&originWidth=1882&originalType=binary&ratio=1&rotation=0&showTitle=false&size=471538&status=done&style=none&taskId=uc11e3550-b005-4011-9a31-215c56b8976&title=&width=941)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640162053740-dbf132f2-8659-42d2-9d8a-5086580bad43.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=671&id=u4eecddb0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1342&originWidth=1888&originalType=binary&ratio=1&rotation=0&showTitle=false&size=409390&status=done&style=none&taskId=u55081ce8-8b94-4e29-a0fb-cd60c9abf59&title=&width=944)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640162223701-50fe25a3-1218-4739-a434-aecd4f2a022a.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=627&id=u8c6d35ed&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1254&originWidth=1928&originalType=binary&ratio=1&rotation=0&showTitle=false&size=584041&status=done&style=none&taskId=ub5fdd824-6a4f-4110-afd8-68451389b36&title=&width=964)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640162461655-2ae37ebd-bfd5-4499-b1b9-fb6152e4c31d.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=608&id=ub35c441d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1216&originWidth=1654&originalType=binary&ratio=1&rotation=0&showTitle=false&size=507515&status=done&style=none&taskId=ue796abff-29b1-4dc6-8aea-0def4b1ed42&title=&width=827)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640162503650-d77423ef-3c3a-4397-aafb-7e44921767b1.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=669&id=u462edc00&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1338&originWidth=1664&originalType=binary&ratio=1&rotation=0&showTitle=false&size=555354&status=done&style=none&taskId=u555ca2e1-1fb0-4fef-9fa6-5f9c99cffc5&title=&width=832)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640162572560-7447ce7f-c850-4900-b0a5-5910b1103473.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=603&id=ueafa523e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1206&originWidth=1728&originalType=binary&ratio=1&rotation=0&showTitle=false&size=483875&status=done&style=none&taskId=u25dc7833-ece7-4559-bd9f-03910d39a7b&title=&width=864)
<a name="Yc3oL"></a>
## 本地 k8s 部署
![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640162973950-2fb029e2-71c4-420b-b009-c7cb1df122df.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=669&id=u7c5db81a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1338&originWidth=2056&originalType=binary&ratio=1&rotation=0&showTitle=false&size=866839&status=done&style=none&taskId=udf6d50b6-fded-45c9-96a5-e55f2ecf5b3&title=&width=1028)
<a name="s0J6R"></a>
### 配置文件
![image.png](https://cdn.nlark.com/yuque/0/2021/png/2194774/1640246013513-7a2a445b-dea7-4e37-b739-4efb9ae04a00.png#clientId=u65b246ec-2667-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=308&id=u100b6626&margin=%5Bobject%20Object%5D&name=image.png&originHeight=317&originWidth=280&originalType=binary&ratio=1&rotation=0&showTitle=false&size=24596&status=done&style=none&taskId=u96b08c96-1eba-437b-9cde-f31701a9eed&title=&width=272)<br />其中的 config.yaml 写入涉密信息<br />各个服务的配置文件中需要填入两部分内容,分别是 deployment 和 service,以 account-svc 为例:
```yaml
# https://matthewpalmer.net/kubernetes-app-developer/articles/kubernetes-apiversion-definition-guide.html
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: account-svc-deployment
spec:
replicas: 1
template:
metadata:
labels:
app: account-svc
env: test
spec:
containers:
- name: account-svc
image: boboweike/account-svc
imagePullPolicy: Never
ports:
- name: http-port
containerPort: 80
envFrom:
- configMapRef:
name: common-config
---
apiVersion: v1
kind: Service
metadata:
name: account-service
spec:
selector:
app: account-svc
env: test
ports:
- protocol: TCP
port: 80
targetPort: 80
安装 k8s 环境
直接在 docker desktop 勾选即可。
安装 k8s 可视化服务
终端中输入:
macos@macosdeMacBook-Pro ~ % kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.4.0/aio/deploy/recommended.yaml
安装好后使用代理登录:
macos@macosdeMacBook-Pro ~ % kubectl proxy
Starting to serve on 127.0.0.1:8001
点击以下链接:
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
首次登录的页面为:
在终端中输入指令:
macos@macosdeMacBook-Pro ~ % kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk'{print $1}')
镜像构建
- mvn clean package -DskipTests
- docker-compose build
- docker images
部署 MySQL 数据库
主要就是将 mysql 服务设置为任何 ip 主机都可以访问并建立连接
登录 MySQL ```bash mysql -u root -p
…
mysql> update user set host = ‘%’ where user = ‘root’; mysql> select user, host from user; +—————————+—————-+ | user | host | +—————————+—————-+ | root | % | | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | +—————————+—————-+
<a name="VZ5aN"></a>
### 部署 staffjoy (k8s)
在 ./k8s/test/config/ 目录下,执行指令:
```bash
macos@macosdeMBP config % kubectl apply -f config.yaml
configmap/common-config created
可以通过指令查看配置情况:
macos@macosdeMBP config % kubectl get configmaps
NAME DATA AGE
common-config 22 9m18s
kube-root-ca.crt 1 163m
端口转发
查询faraday pod 名:
macos@macosdeMacBook-Pro config % kubectl get pods
NAME READY STATUS RESTARTS AGE
account-svc-deployment-66d996748b-2gv6x 1/1 Running 1 (45s ago) 27h
app-spa-deployment-788c64bc7c-vstgm 1/1 Running 1 (45s ago) 27h
bot-svc-deployment-6bb664885b-vkkqn 1/1 Running 1 (45s ago) 27h
company-svc-deployment-67594649f8-8lc87 1/1 Running 1 (45s ago) 27h
email-svc-deployment-576b99d6d9-fc8px 1/1 Running 1 (45s ago) 27h
faraday-svc-deployment-7f56896ddf-jn5dd 1/1 Running 1 (45s ago) 27h
myaccount-spa-deployment-6cc5846895-gwcl8 1/1 Running 1 (45s ago) 27h
whoami-svc-deployment-7cfd774b5d-7gtd9 1/1 Running 1 (45s ago) 27h
www-web-deployment-b74c45dd6-fcvgp 1/1 Running 1 (45s ago) 27h
然后配置端口转发:
macos@macosdeMacBook-Pro config % sudo kubectl port-forward faraday-svc-deployment-7f56896ddf-jn5dd 80:80
Password:
Forwarding from 127.0.0.1:80 -> 80
Forwarding from [::1]:80 -> 80
命令行验证
macos@macosdeMacBook-Pro config % kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
account-svc-deployment-66d996748b-2gv6x 1/1 Running 1 (3m41s ago) 27h 10.1.0.21 docker-desktop <none> <none>
app-spa-deployment-788c64bc7c-vstgm 1/1 Running 1 (3m41s ago) 27h 10.1.0.17 docker-desktop <none> <none>
bot-svc-deployment-6bb664885b-vkkqn 1/1 Running 1 (3m41s ago) 27h 10.1.0.18 docker-desktop <none> <none>
company-svc-deployment-67594649f8-8lc87 1/1 Running 1 (3m41s ago) 27h 10.1.0.27 docker-desktop <none> <none>
email-svc-deployment-576b99d6d9-fc8px 1/1 Running 1 (3m41s ago) 27h 10.1.0.20 docker-desktop <none> <none>
faraday-svc-deployment-7f56896ddf-jn5dd 1/1 Running 1 (3m41s ago) 27h 10.1.0.31 docker-desktop <none> <none>
myaccount-spa-deployment-6cc5846895-gwcl8 1/1 Running 1 (3m41s ago) 27h 10.1.0.23 docker-desktop <none> <none>
whoami-svc-deployment-7cfd774b5d-7gtd9 1/1 Running 1 (3m41s ago) 27h 10.1.0.22 docker-desktop <none> <none>
www-web-deployment-b74c45dd6-fcvgp 1/1 Running 1 (3m41s ago) 27h 10.1.0.30 docker-desktop <none> <none>
macos@macosdeMacBook-Pro config % kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
account-service ClusterIP 10.101.119.92 <none> 80/TCP 28h
app-service ClusterIP 10.111.114.253 <none> 80/TCP 28h
bot-service ClusterIP 10.101.245.172 <none> 80/TCP 28h
company-service ClusterIP 10.110.159.235 <none> 80/TCP 28h
email-service ClusterIP 10.105.117.193 <none> 80/TCP 28h
faraday-service NodePort 10.102.219.97 <none> 80:30001/TCP 28h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 31h
myaccount-service ClusterIP 10.108.247.178 <none> 80/TCP 28h
mysql-svc ClusterIP 10.97.213.40 <none> 3306/TCP 28h
whoami-service ClusterIP 10.100.236.242 <none> 80/TCP 28h
www-service ClusterIP 10.107.100.198 <none> 80/TCP 28h
macos@macosdeMacBook-Pro config % kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
account-svc-deployment 1/1 1 1 27h
app-spa-deployment 1/1 1 1 27h
bot-svc-deployment 1/1 1 1 27h
company-svc-deployment 1/1 1 1 27h
email-svc-deployment 1/1 1 1 27h
faraday-svc-deployment 1/1 1 1 27h
myaccount-spa-deployment 1/1 1 1 27h
whoami-svc-deployment 1/1 1 1 27h
www-web-deployment 1/1 1 1 27h
清除服务
通过一下指令删除服务:
macos@macosdeMacBook-Pro config % kubectl delete deployments --all
deployment.apps "account-svc-deployment" deleted
deployment.apps "app-spa-deployment" deleted
deployment.apps "bot-svc-deployment" deleted
deployment.apps "company-svc-deployment" deleted
deployment.apps "email-svc-deployment" deleted
deployment.apps "faraday-svc-deployment" deleted
deployment.apps "myaccount-spa-deployment" deleted
deployment.apps "whoami-svc-deployment" deleted
deployment.apps "www-web-deployment" deleted
macos@macosdeMacBook-Pro config % kubectl delete services --all
service "account-service" deleted
service "app-service" deleted
service "bot-service" deleted
service "company-service" deleted
service "email-service" deleted
service "faraday-service" deleted
service "kubernetes" deleted
service "myaccount-service" deleted
service "mysql-svc" deleted
service "whoami-service" deleted
service "www-service" deleted
macos@macosdeMacBook-Pro config % kubectl delete configmaps --all
configmap "common-config" deleted
configmap "kube-root-ca.crt" deleted