# Kubernetes 中用 Sidecar 为应用添加 Oauth 功能

Kubernetes 的 Pod 中可以同时运行共享网络栈的多个容器，使得 Sidecar 这种服务协作方式更加易于实施。这里我们就使用 Sidecar 方式，将 Keycloak 集成到 httpbin 服务上去，为没有认证的 httpbin 服务添加认证功能。

## 概要

[Keycloak（链接 1）](https://www.keycloak.org/) 是 JBoss 的一个认证服务软件，使用代理的方式，为其他应用提供认证能力，除了本文说到的 Oauth 之外，还提供二次认证、LDAP 等丰富的相关功能。

在 Kubernetes 上部署 Keycloak 服务，对其进行初始化，建立用户和认证系统，然后将 Keycloak-Proxy 和 Httpbin 集成在同一个 Pod 中进行部署运行，测试集成效果。

集成后的访问路径如图所示：

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745945048651/869d62a4-6332-4544-8b24-1e0f6f5043f4.jpeg align="center")

## 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/`，使用环境变量中设置的用户名密码登录，进行后续的安全设置，界面如图所示：

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745945056202/408cbeb2-4edb-4d9d-b96f-961f1be98bf3.png align="center")

### 创建登录域

1. 鼠标在左上角的`Master`字样上悬停，在弹出的菜单中选择`Add Realm`。
    
2. 在左侧菜单`Configure`下面，打开`Clients`项，点击`Create`设置`httpbin`作为 Client ID 并保存。
    
3. 设置`Access Type`为`confidential`，`Valid Redirect URIs`设置为`*`，并保存。
    
4. 打开`Installation`标签，选择`Keycloak OIDC JSON`，并拷贝显示出来的 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
  }
```

### 创建用户

1. 在左侧的`Configure`菜单上打开`Roles`页面，点击`Add role`。
    
2. 设置角色名称为`httpbin-role`，保存。
    
3. 在左手的`Manage`菜单中，打开`Users`页面，点击`Add user`。
    
4. 填写表单，设置`Email verified`为`ON`，保存内容。
    
5. 打开这一用户的`Role mappings`标签，在`Available Roles`列表中选择角色`httpbin-role`，点击`Add selected`。
    

这样我们就完成了登录域的创建，并为后面将要启动的 httpbin 应用创建了相关的角色和用户。

## 部署应用

根据前面的流程图，我们需要把 keycloak-proxy 组件用 sidecar 的方式和 httpbin 集成在一起，用反向代理的形式拦截请求，完成登录任务。

### 创建 proxy 配置

Proxy 配置文件内容可以参考[官方文档（链接 2）](http://www.keycloak.org/docs/3.0/server_installation/topics/proxy.html)

keycloak-proxy 需要一个配置文件`/opt/jboss/conf`，这里我们使用 configmap 的形式将其加载进来，配置文件的内容如下：

```json
{
    "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 代码：

```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://gist.github.com/fleeto/e4d2996b3c0dba41831504747974cf0a)

## 链接

1. `https://www.keycloak.org/`
    
2. `http://www.keycloak.org/docs/3.0/server_installation/topics/proxy.html`
    
3. `https://gist.github.com/fleeto/e4d2996b3c0dba41831504747974cf0a`
