Kubernetes 中用 Sidecar 为应用添加 Oauth 功能
Kubernetes 的 Pod 中可以同时运行共享网络栈的多个容器,使得 Sidecar 这种服务协作方式更加易于实施。这里我们就使用 Sidecar 方式,将 Keycloak 集成到 httpbin 服务上去,为没有认证的 httpbin 服务添加认证功能。
概要
Keycloak(链接 1) 是 JBoss 的一个认证服务软件,使用代理的方式,为其他应用提供认证能力,除了本文说到的 Oauth 之外,还提供二次认证、LDAP 等丰富的相关功能。
在 Kubernetes 上部署 Keycloak 服务,对其进行初始化,建立用户和认证系统,然后将 Keycloak-Proxy 和 Httpbin 集成在同一个 Pod 中进行部署运行,测试集成效果。
集成后的访问路径如图所示:
Keycloak 服务的初始化
Keycloak 支持多种数据库存储,这里为了方便,就直接使用内置的 H2 数据库了。这里选用的镜像是jboss/keycloak:3.4.2.Final
,开放服务端口 8080,并设置了三个环境变量:
-
KEYCLOAK_USER
:KeyCloak 初始管理员账号 -
KEYCLOAK_PASSWORD
:KeyCloak 初始管理员密码 -
PROXY_ADDRESS_FORWARDING
:KeyCloak 部署在反向代理之后(Kubernetes 部署方式就在此列),就必须设置此变量为true
接下来部署相关的 Service,如果有必要,还需要部署相关的 Ingress。
设置 Keycloak 服务器
启动 Keycloak Server 之后,我们访问https://[keycloak service url]/auth/admin/
,使用环境变量中设置的用户名密码登录,进行后续的安全设置,界面如图所示:
创建登录域
- 鼠标在左上角的
Master
字样上悬停,在弹出的菜单中选择Add Realm
。 - 在左侧菜单
Configure
下面,打开Clients
项,点击Create
设置httpbin
作为 Client ID 并保存。 - 设置
Access Type
为confidential
,Valid Redirect URIs
设置为*
,并保存。 - 打开
Installation
标签,选择Keycloak OIDC JSON
,并拷贝显示出来的 JSON 代码,其中的部分内容可能不一致。
{
"realm": "httpbin",
"auth-server-url": "https://[keycloak-server]/auth",
"ssl-required": "external",
"resource": "httpbin",
"credentials": {
"secret": "d97cfa70-8eb1-443a-8320-4cde9da34de6"},
"confidential-port": 0}
创建用户
- 在左侧的
Configure
菜单上打开Roles
页面,点击Add role
。 - 设置角色名称为
httpbin-role
,保存。 - 在左手的
Manage
菜单中,打开Users
页面,点击Add user
。 - 填写表单,设置
Email verified
为ON
,保存内容。 - 打开这一用户的
Role mappings
标签,在Available Roles
列表中选择角色httpbin-role
,点击Add selected
。
这样我们就完成了登录域的创建,并为后面将要启动的 httpbin 应用创建了相关的角色和用户。
部署应用
根据前面的流程图,我们需要把 keycloak-proxy 组件用 sidecar 的方式和 httpbin 集成在一起,用反向代理的形式拦截请求,完成登录任务。
创建 proxy 配置
Proxy 配置文件内容可以参考官方文档(链接 2)
keycloak-proxy 需要一个配置文件/opt/jboss/conf
,这里我们使用 configmap 的形式将其加载进来,配置文件的内容如下:
{
"target-url": "http://localhost:8000",
"send-access-token": true,
"bind-address": "0.0.0.0",
"http-port": "8080",
"applications": [
{
"base-path": "/",
"adapter-config": {
"realm": "httpbin",
"auth-server-url": "https://[keycloak-server]/auth",
"ssl-required": "external",
"resource": "httpbin",
"credentials": {
"secret": "d97cfa70-8eb1-443a-8320-4cde9da34de6"}},
"constraints": [
{
"pattern": "/*",
"roles-allowed": ["httpbin-role"]}
]}
]}
这一配置要求 Proxy 代理本机 8000 端口(httpbin 的服务端口)的通信,并以 0.0.0.0:8080 对外提供服务,secret 字段内容来自于上面Keycloak OIDC JSON
的输出。
创建 httpbin deployment
在原有的应用部署的基础上,需要加入两个内容:
- 加载 ConfigMap
- 加入 Sidecar
节选 yaml 代码:
containers:
- image: citizenstig/httpbin
imagePullPolicy: IfNotPresent
name: httpd
ports:
- containerPort: 8000
name: http-httpbin
- image: jboss/keycloak-proxy:3.4.2.Final
name: httpbin-proxy
volumeMounts:
- mountPath: /opt/jboss/conf
name: config
ports:
- containerPort: 8080
name: http-proxy
volumes:
- name: config
configMap:
name: httpbin-proxy
这里完成了上述的任务。
创建服务
上面创建的 Deployment 之中有了两个端口,8080 是 keycloak 端口;8000 是 httpbin 端口,为了达到认证目的,服务应该指向 keycloak proxy 所在的 8080 端口。
测试
依次完成业务应用部署之后,就可以进行测试了。
在浏览器打开 httpbin 服务,会看到对这一服务的访问会被转向 Keycloak 的登录页面。如果输入的是管理员的账号密码,是无法成功访问服务的;而输入我们新建账号的登录凭据,则可以顺利返回。
所有 yaml 代码(链接 3)
链接
https://www.keycloak.org/
http://www.keycloak.org/docs/3.0/server_installation/topics/proxy.html
https://gist.github.com/fleeto/e4d2996b3c0dba41831504747974cf0a
参考
https://medium.com/jaegertracing/protecting-jaeger-ui-with-an-oauth-sidecar-proxy-34205cca4bb1
- XMLHttpRequest对象如何兼容各浏览器使用?
- Java使用wsdl生成axis版本webservice服务端/客户端代码
- Java微信支付快速入门&工具类
- redis集群 - linux安装与配置笔记
- Apache RocketMQ 4.0.0 - linux安装与配置笔记
- 数据库连接池-tomcat-jdbc食用笔记
- Java.NIO编程一览笔录
- Hbase 学习(三)Coprocessors
- Spring4+Spring MVC+MyBatis整合思路
- Zookeeper ACL权限配置及zkclient示例
- Spring Session 实现分布式会话管理
- 通过ambari安装hadoop集群(一)
- Hbase 学习(十) HBase Snapshots
- sqoop 常用命令整理(二)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 参数注解所引发的思考
- kali安装webdav服务
- NiFi.java 源码解读
- Spring,Spring MVC及Spring Boot区别
- RunNiFi.java 源码解读
- nifi.sh 脚本解读
- 关于当前PHP脚本运行时系统信息相关函数
- NIFI启动源码解读
- 高并发系统三大利器之降级
- 简单学习PHP中的层次性能分析器
- 常见乱码问题分析
- 深入理解 Vue 模板渲染:Vue 模板反编译
- 彻底搞懂 etcd 系列文章(七):etcd gRPC 服务 API
- NIFI 开发注解详述
- [已解决]java请求爬取https网站报错javax.net.ssl.SSLHandshakeException的解决办法