NATS 中文文档
  • 引言
  • 发布日志
  • NATS 2.0
  • 对比 NATS
  • FAQ
  • NATS Concepts
    • What is NATS
    • Subject-Based Messaging
    • Publish-Subscribe
    • Request-Reply
    • Queue Groups
    • Acknowledgements
    • Sequence Numbers
  • Developing With NATS
    • Introduction
    • Connecting
      • Connecting to the Default Server
      • Connecting to a Specific Server
      • Connecting to a Cluster
      • Connection Name
      • Setting a Connect Timeout
      • Ping/Pong Protocol
      • Turning Off Echo'd Messages
      • Miscellaneous functionalities
    • Automatic Reconnections
      • Disabling Reconnect
      • Set the Number of Reconnect Attempts
      • Avoiding the Thundering Herd
      • Pausing Between Reconnect Attempts
      • Listening for Reconnect Events
      • Buffering Messages During Reconnect Attempts
    • Securing Connections
      • Authenticating with a User and Password
      • Authenticating with a Token
      • Authenticating with an NKey
      • Authenticating with a Credentials File
      • Encrypting Connections with TLS
    • Receiving Messages
      • Synchronous Subscriptions
      • Asynchronous Subscriptions
      • Unsubscribing
      • Unsubscribing After N Messages
      • Replying to a Message
      • Wildcard Subscriptions
      • Queue Subscriptions
      • Draining Messages Before Disconnect
      • Structured Data
    • Sending Messages
      • Including a Reply Subject
      • Request-Reply Semantics
      • Caches, Flush and Ping
      • Sending Structured Data
    • Monitoring the Connection
      • Listen for Connection Events
      • Slow Consumers
    • Tutorials
      • Explore NATS Pub/Sub
      • Explore NATS Request/Reply
      • Explore NATS Queueing
      • Advanced Connect and Custom Dialer in Go
  • NATS Server
    • Installing
    • Running
      • Windows Service
    • Clients
    • Flags
    • Configuration
      • Securing NATS
        • Enabling TLS
        • Authentication
          • Tokens
          • Username/Password
          • TLS Authentication
          • NKeys
          • Authentication Timeout
        • Authorization
        • Multi Tenancy using Accounts
        • Decentralized JWT Authentication/Authorization
          • Account lookup using Resolver
          • Memory Resolver Tutorial
          • Mixed Authentication/Authorization Setup
      • Clustering
        • Configuration
        • TLS Authentication
      • Super-cluster with Gateways
        • Configuration
      • Leaf Nodes
        • Configuration
      • Logging
      • Monitoring
      • System Events
        • System Events & Decentralized JWT Tutorial
    • Managing A NATS Server
      • Upgrading a Cluster
      • Slow Consumers
      • Signals
    • NATS and Docker
      • Tutorial
      • Docker Swarm
      • Python and NGS Running in Docker
  • NATS Tools
    • Introduction
    • mkpasswd
    • nk
    • nsc
      • Basics
      • Streams
      • Services
      • Signing Keys
      • Revocation
      • Managed Operators
    • nats-account-server
      • Basics
      • Inspecting JWTs
      • Directory Store
      • Update Notifications
    • nats-top
      • Tutorial
    • nats-bench
  • NATS Streaming Concepts
    • Introduction
    • Relation to NATS
    • Client Connections
    • Channels
      • Message Log
      • Subscriptions
        • Regular
        • Durable
        • Queue Group
        • Redelivery
    • Store Interface
    • Store Encryption
    • Clustering
      • Supported Stores
      • Configuration
      • Auto Configuration
      • Containers
    • Fault Tolerance
      • Active Server
      • Standby Servers
      • Shared State
      • Failover
    • Partitioning
    • Monitoring
      • Endpoints
  • Developing With NATS Streaming
    • Introduction
    • Connecting to NATS Streaming
    • Publishing to a Channel
    • Receiving Messages from a Channel
    • Durable Subscriptions
    • Queue Subscriptions
    • Acknowledgements
    • The Streaming Protocol
  • NATS Streaming Server
    • Important Changes
    • Installing
    • Running
    • Configuring
      • Command Line Arguments
      • Configuration File
      • Store Limits
      • 持久化
        • 文件存储
        • SQL 存储
      • Securing
    • Process Signaling
    • Windows Service
    • Embedding NATS Streaming Server
    • Docker Swarm
  • NATS Protocol
    • Protocol Demo
    • Client Protocol
      • Developing a Client
    • NATS Cluster Protocol
  • 在 Kubernetes中使用NATS
    • 序言
    • 安装 NATS 和 NATS Streaming
    • 创建一个 Kubernetes 集群
    • 容错(Fault Tolerance)模式下的NATS Streaming 集群
    • NATS 和 Prometheus Operator
    • NATS 集群和证书管理
    • 使用 cfssl 来提高 NATS 集群的安全性
    • 使用负载均衡器(Load Balancer) 为NATS提供外部访问
    • 使用Helm在Digital Ocean 创建一个NATS 超级集群
    • 使用Helm从0到 K8s到 子节点
由 GitBook 提供支持
在本页
  • 使用NATS Operator 来加固 Kubernetes 中的 NATS 集群
  • 功能:
  • 证书创建
  • 生成CA根证书
  • 生成 NATS service 证书
  • Generating the NATS server routes certs 生成NATS server 路由证书
  • 为客户端生成证书(CNCF && ACME)
  • Kubectl Create
  • 创建授权密钥
  • 使用证书创建应用

这有帮助吗?

  1. 在 Kubernetes中使用NATS

使用 cfssl 来提高 NATS 集群的安全性

使用NATS Operator 来加固 Kubernetes 中的 NATS 集群

功能:

  • Clients TLS setup

  • 客户端 TLS 配置

  • 通过密钥来授权基于 TLS 的证书

    • 只有更新密钥才能重载证书

  • 路由TLS设置

  • 为每个NATS service 发布公共IP以供外部访问

证书创建

生成CA根证书

{
    "CN": "nats.io",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "OU": "nats.io"
        }
    ]
}
(
  cd certs

  # CA certs
  cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
)

Setup the profiles for the Root CA, we will have 3 main profiles: one for the clients connecting, one for the servers, and another one for the full mesh routing connections between the servers.

CA根证书有三个主要的配置文件:一个用于客户端的连接,一个用于服务端,一个用于服务间的网格路由连接。

{
    "signing": {
        "default": {
            "expiry": "43800h"
        },
        "profiles": {
            "server": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            },
            "client": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            },
            "route": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            }
        }
    }
}

生成 NATS service 证书

首先我们生成server的证书。

{
    "CN": "nats.io",
    "hosts": [
        "localhost",
        "*.nats-cluster.default.svc",
        "*.nats-cluster-mgmt.default.svc",
        "nats-cluster",
        "nats-cluster-mgmt",
        "nats-cluster.default.svc",
        "nats-cluster-mgmt.default.svc",
        "nats-cluster.default.svc.cluster.local",
        "nats-cluster-mgmt.default.svc.cluster.local",
        "*.nats-cluster.default.svc.cluster.local",
        "*.nats-cluster-mgmt.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "OU": "Operator"
        }
    ]
}
(
  # Generating the peer certificates
  cd certs
  cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server.json | cfssljson -bare server
)

Generating the NATS server routes certs 生成NATS server 路由证书

我们当然也需要为网格路由配置TLS。

{
    "CN": "nats.io",
    "hosts": [
        "localhost",
        "*.nats-cluster.default.svc",
        "*.nats-cluster-mgmt.default.svc",
        "nats-cluster",
        "nats-cluster-mgmt",
        "nats-cluster.default.svc",
        "nats-cluster-mgmt.default.svc",
        "nats-cluster.default.svc.cluster.local",
        "nats-cluster-mgmt.default.svc.cluster.local",
        "*.nats-cluster.default.svc.cluster.local",
        "*.nats-cluster-mgmt.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "OU": "Operator"
        }
    ]
}
# Generating the peer certificates
(
  cd certs
  cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=route route.json | cfssljson -bare route
)

为客户端生成证书(CNCF && ACME)

{
    "CN": "nats.io",
    "hosts": [""],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "OU": "CNCF"
        }
    ]
}
(
  cd certs
  # Generating NATS client certs
  cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client
)

Kubectl Create

cd certs kubectl create secret generic nats-tls-example --from-file=ca.pem --from-file=server-key.pem --from-file=server.pem kubectl create secret generic nats-tls-routes-example --from-file=ca.pem --from-file=route-key.pem --from-file=route.pem kubectl create secret generic nats-tls-client-example --from-file=ca.pem --from-file=client-key.pem --from-file=client.pem

创建授权密钥

{
  "users": [
    { "username": "CN=nats.io,OU=ACME" },
    { "username": "CN=nats.io,OU=CNCF",
      "permissions": {
    "publish": ["hello.*"],
    "subscribe": ["hello.world"]
      }
    }
  ],
  "default_permissions": {
    "publish": ["SANDBOX.*"],
    "subscribe": ["PUBLIC.>"]
  }
}
kubectl create secret generic nats-tls-users --from-file=users.json

创建支持TLS的集群

echo '
apiVersion: "nats.io/v1alpha2"
kind: "NatsCluster"
metadata:
  name: "nats-cluster"
spec:
  size: 3

  # Using custom edge nats server image for TLS verify and map support.
  serverImage: "wallyqs/nats-server"
  version: "edge-2.0.0-RC5"

  tls:
    enableHttps: true

    # Certificates to secure the NATS client connections:
    serverSecret: "nats-tls-example"

    # Certificates to secure the routes.
    routesSecret: "nats-tls-routes-example"

  auth:
    tlsVerifyAndMap: true
    clientsAuthSecret: "nats-tls-users"

    # How long to wait for authentication
    clientsAuthTimeout: 5

  pod:
    # To be able to reload the secret changes
    enableConfigReload: true
    reloaderImage: connecteverything/nats-server-config-reloader

    # Bind the port 4222 as the host port to allow external access.
    enableClientsHostPort: true

    # Initializer container that resolves the external IP from the
    # container where it is running.
    advertiseExternalIP: true

    # Image of container that resolves external IP from K8S API
    bootconfigImage: "wallyqs/nats-boot-config"
    bootconfigImageTag: "0.5.0"

  # Service account required to be able to find the external IP
  template:
    spec:
      serviceAccountName: "nats-server"
' | kubectl apply -f -

使用证书创建应用

添加一个使用证书的pod

Development

package main

import (
    "encoding/json"
    "flag"
    "fmt"
    "log"
    "time"

    "github.com/nats-io/go-nats"
    "github.com/nats-io/nuid"
)

func main() {
    var (
        serverList     string
        rootCACertFile string
        clientCertFile string
        clientKeyFile  string
    )
    flag.StringVar(&serverList, "s", "tls://nats-1.nats-cluster.default.svc:4222", "List of NATS of servers available")
    flag.StringVar(&rootCACertFile, "cacert", "./certs/ca.pem", "Root CA Certificate File")
    flag.StringVar(&clientCertFile, "cert", "./certs/client.pem", "Client Certificate File")
    flag.StringVar(&clientKeyFile, "key", "./certs/client-key.pem", "Client Private key")
    flag.Parse()

    log.Println("NATS endpoint:", serverList)
    log.Println("Root CA:", rootCACertFile)
    log.Println("Client Cert:", clientCertFile)
    log.Println("Client Key:", clientKeyFile)

    // Connect options
    rootCA := nats.RootCAs(rootCACertFile)
    clientCert := nats.ClientCert(clientCertFile, clientKeyFile)
    alwaysReconnect := nats.MaxReconnects(-1)

    var nc *nats.Conn
    var err error
    for {
        nc, err = nats.Connect(serverList, rootCA, clientCert, alwaysReconnect)
        if err != nil {
            log.Printf("Error while connecting to NATS, backing off for a sec... (error: %s)", err)
            time.Sleep(1 * time.Second)
            continue
        }
        break
    }

    nc.Subscribe("discovery.*.status", func(m *nats.Msg) {
        log.Printf("[Received on %q] %s", m.Subject, string(m.Data))
    })

    discoverySubject := fmt.Sprintf("discovery.%s.status", nuid.Next())
    info := struct {
        InMsgs        uint64   `json:"in_msgs"`
        OutMsgs       uint64   `json:"out_msgs"`
        Reconnects    uint64   `json:"reconnects"`
        CurrentServer string   `json:"current_server"`
        Servers       []string `json:"servers"`
    }{}

    for range time.NewTicker(1 * time.Second).C {
        stats := nc.Stats()
        info.InMsgs = stats.InMsgs
        info.OutMsgs = stats.OutMsgs
        info.Reconnects = stats.Reconnects
        info.CurrentServer = nc.ConnectedUrl()
        info.Servers = nc.Servers()
        payload, err := json.Marshal(info)
        if err != nil {
            log.Printf("Error marshalling data: %s", err)
        }
        err = nc.Publish(discoverySubject, payload)
        if err != nil {
            log.Printf("Error during publishing: %s", err)
        }
        nc.Flush()
    }
}
FROM golang:1.11.0-alpine3.8 AS builder
COPY . /go/src/github.com/nats-io/nats-kubernetes/examples/nats-cluster-routes-tls/app
WORKDIR /go/src/github.com/nats-io/nats-kubernetes/examples/nats-cluster-routes-tls/app
RUN apk add --update git
RUN go get -u github.com/nats-io/go-nats
RUN go get -u github.com/nats-io/nuid
RUN CGO_ENABLED=0 go build -o nats-client-app -v -a ./client.go

FROM scratch
COPY --from=builder /go/src/github.com/nats-io/nats-kubernetes/examples/nats-cluster-routes-tls/app/nats-client-app /nats-client-app
ENTRYPOINT ["/nats-client-app"]
docker build . -t wallyqs/nats-client-app
docker run wallyqs/nats-client-app
docker push wallyqs/nats-client-app

Pod spec

echo ' apiVersion: apps/v1beta2 kind: Deployment

## The name of the deployment

metadata: name: nats-client-app

spec:

## This selector has to match the template.metadata.labels section

## which is below in the PodSpec

selector: matchLabels: name: nats-client-app

## Number of instances

replicas: 1

## PodSpec

template: metadata: labels: name: nats-client-app spec: volumes:

* name: "client-tls-certs"

  secret:

    secretName: "nats-tls-client-example"

  containers:

* name: nats-client-app

  command: \["/nats-client-app", "-s", "tls://nats-cluster.default.svc:4222", "-cacert", '/etc/nats-client-tls-certs/ca.pem', '-cert', '/etc/nats-client-tls-certs/client.pem', '-key', '/etc/nats-client-tls-certs/client-key.pem'\]

  image: wallyqs/nats-client-app:latest

  imagePullPolicy: Always

  volumeMounts:

  * name: "client-tls-certs"

    mountPath: "/etc/nats-client-tls-certs/"

    ' \| kubectl apply -f -
上一页NATS 集群和证书管理下一页使用负载均衡器(Load Balancer) 为NATS提供外部访问

最后更新于4年前

这有帮助吗?