Gravitee使用指南(三)APIM部署

1,483 阅读6分钟

前两篇文章我们已经介绍了如何使用官方镜像部署和使用源码编译部署,这一篇我们来介绍一下如何部署网关的管理平台。
Gravitee的网关管理平台并不是开源的,所以我们没有办法使用源码编译的方式进行APIM的部署,我们只能使用官方提供的现成镜像或者下载官方编译好的压缩包然后自行打包镜像进行部署。

首先我们来看一下官方文档的镜像部署方式,命令十分简单,和网关部署类似,但是这里有个巨坑就是版本问题:网关的版本和APIM的版本一定要是同一版本,否则会无法正常使用网关

 docker run \
          --publish 81:8083 \
          --name management-api \
          --env GRAVITEE_MANAGEMENT_MONGODB_URI=mongodb://username:password@mongohost:27017/dbname
          --detach  \
          graviteeio/apim-management-api:latest

同理APIM和网关一样不可能只有这么简单的配置,APIM的配置依然十分复杂,我在这里贴一份全量的配置文件,大家慢慢看,其中大部分配置其实都不需要配置,在UI界面都可以直接进行修改。

############################################################################################################
################################ Gravitee.IO Management API - Configuration ################################
############################################################################################################

############################################################################################################
# This file is the general configuration of Gravitee.IO Management API:
# - Properties (and respective default values) in comment are provided for information.
# - You can reference other property by using ${property.name} syntax
# - gravitee.home property is automatically set-up by launcher and refers to the installation path. Do not override it !
#
# Please have a look to http://docs.gravitee.io/ for more options and fine-grained granularity
############################################################################################################

# Specify the URL of the Management API and UI of this instance, mandatory if you want to connect it to Cockpit
#console:
#  ui:
#    url: http://localhost:3000
#  api:
#    url: http://localhost:8083/management

# HTTP Server
#jetty:
#  IP/hostname to bind to. Default is 0.0.0.0
#  host: 0.0.0.0
#  port: 8083
#  idleTimeout: 30000
#  acceptors: -1
#  selectors: -1
#  pool:
#    minThreads: 10
#    maxThreads: 200
#    idleTimeout: 60000
#    queueSize: 6000
#  jmx: false
#  statistics: false
#  accesslog:
#    enabled: true
#    path: ${gravitee.home}/logs/gravitee_accesslog_yyyy_mm_dd.log
#  secured: false
#  ssl:
#    keystore:
#      type: jks # Supports jks, pkcs12
#      path: ${gravitee.home}/security/keystore.jks
#      password: secret
#    truststore:
#      type: jks # Supports jks, pkcs12
#      path: ${gravitee.home}/security/truststore.jks
#      password: secret

http:
  api:
    # Configure the listening path for the API. Default to /
#    entrypoint: /
    # Configure Management API and Portal API.
#    management:
#      enabled: true
#      entrypoint: ${http.api.entrypoint}management
#      cors:
# Allows to configure the header Access-Control-Allow-Origin (default value: *)
# '*' is a valid value but is considered as a security risk as it will be opened to cross origin requests from anywhere.
#       allow-origin: http://developer.mycompany.com
# Allows to define how long the result of the preflight request should be cached for (default value; 1728000 [20 days])
#       max-age: 864000
# Which methods to allow (default value: OPTIONS, GET, POST, PUT, DELETE)
#      allow-methods: 'OPTIONS, GET, POST, PUT, DELETE'
# Which headers to allow (default values: Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With, If-Match, X-Xsrf-Token)
#      allow-headers: 'X-Requested-With'
#    portal:
#      enabled: true
#      entrypoint: ${http.api.entrypoint}portal
#      cors:
    # Allows to configure the header Access-Control-Allow-Origin (default value: *)
    # '*' is a valid value but is considered as a security risk as it will be opened to cross origin requests from anywhere.
#       allow-origin: http://developer.mycompany.com
    # Allows to define how long the result of the preflight request should be cached for (default value; 1728000 [20 days])
#       max-age: 864000
    # Which methods to allow (default value: OPTIONS, GET, POST, PUT, DELETE)
#      allow-methods: 'OPTIONS, GET, POST, PUT, DELETE'
    # Which headers to allow (default values: Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With, If-Match, X-Xsrf-Token)
#      allow-headers: 'X-Requested-With'
  csrf:
    # Allows to enable or disable the CSRF protection. Enabled by default.
    enabled: true
  hsts:
    enabled: true
    include-sub-domains: true
    max-age: 31536000

# Plugins repository
#plugins:
#  path:
#    - ${gravitee.home}/plugins
#    - ${gravitee.home}/my-custom-plugins
# If a external is already installed (but with a different version), management node does not start anymore
#  failOnDuplicate: true

# Management repository is used to store global configuration such as APIs, applications, apikeys, ...
# This is the default configuration using MongoDB (single server)
# For more information about MongoDB configuration, please have a look to:
# - http://api.mongodb.org/java/current/com/mongodb/MongoClientOptions.html
management:
  type: mongodb
  mongodb:
    dbname: ${ds.mongodb.dbname}
    host: ${ds.mongodb.host}
    port: ${ds.mongodb.port}
#    username:
#    password:
#    connectionsPerHost: 0
#    connectTimeout: 500
#    maxWaitTime: 120000
#    socketTimeout: 500
#    socketKeepAlive: false
#    maxConnectionLifeTime: 0
#    maxConnectionIdleTime: 0
#    serverSelectionTimeout: 0
#    description: gravitee.io
#    heartbeatFrequency: 10000
#    minHeartbeatFrequency: 500
#    heartbeatConnectTimeout: 1000
#    heartbeatSocketTimeout: 20000
#    localThreshold: 15
#    minConnectionsPerHost: 0
#    sslEnabled: false
#    threadsAllowedToBlockForConnectionMultiplier: 5
#    cursorFinalizerEnabled: true
# possible values are 1,2,3... (the number of node) or 'majority'
#    writeConcern: 1
#    wtimeout: 0
#    journal: true

# Management repository: single MongoDB using URI
# For more information about MongoDB configuration using URI, please have a look to:
# - http://api.mongodb.org/java/current/com/mongodb/MongoClientURI.html
#management:
#  type: mongodb
#  mongodb:
#    uri: mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

# Management repository: clustered MongoDB
#management:
#  type: mongodb
#  mongodb:
#    servers:
#      - host: mongo1
#        port: 27017
#      - host: mongo2
#        port: 27017
#    dbname: ${ds.mongodb.dbname}
#    connectTimeout: 500
#    socketTimeout: 250

services:
  core:
    http:
      enabled: true
      port: 18083
      host: localhost
      authentication:
        # authentication type to be used for the core services
        # - none : to disable authentication
        # - basic : to use basic authentication
        # default is "basic"
        type: basic
        users:
          admin: adminadmin

  # metrics service
  metrics:
    enabled: false
    prometheus:
      enabled: true

  # v3 upgrader service. Can be disabled after first launch.
  v3-upgrader:
    enabled: true
  # AutoFetch service. (since 3.2)
  # Use to fetch periodically documentation pages.
  auto_fetch:
    enabled: true
    cron: "0 */5 * * * *"

  # Subscription service
  subscription:
    enabled: true
    #  Pre-expiration notification, number of days before the expiration an email should be send to subscriber and primary owner
    pre-expiration-notification-schedule: 90,45,30


# Analytics repository is used to store all reporting, metrics, health-checks stored by gateway instances
# This is the default configuration using Elasticsearch
analytics:
  type: elasticsearch
  elasticsearch:
    endpoints:
      - http://${ds.elastic.host}:${ds.elastic.port}
#    index: gravitee
#    index_per_type: true
#    cross_cluster:
#      mapping:
#        tenant_id: cluster_name
#        tenant_id: cluster_name
#    security:
#      username: user
#      password: secret
#    http:
#      timeout: 10000 # in milliseconds
#      proxy:
#        type: HTTP #HTTP, SOCK4, SOCK5
#        http:
#          host: localhost
#          port: 3128
#          username: user
#          password: secret
#        https:
#          host: localhost
#          port: 3128
#          username: user
#          password: secret

# Authentication and identity sources
# Users can have following roles (authorities):
#  USER: Can access portal and be a member of an API
#  API_PUBLISHER: Can create and manage APIs
#  API_CONSUMER: Can create and manage Applications
#  ADMIN: Can manage global system
security:
  # When using an authentication providers, use trustAll mode for TLS connections
  # trustAll: false
  providers:  # authentication providers
    - type: memory
      # allow search results to display the user email. Be careful, It may be contrary to the user privacy.
#      allow-email-in-search-results: true
      # password encoding/hashing algorithm. One of:
      # - bcrypt : passwords are hashed with bcrypt (supports only $2a$ algorithm)
      # - none : passwords are not hashed/encrypted
      # default value is bcrypt
      password-encoding-algo: bcrypt
      users:
        - user:
          username: user
          #firstname:
          #lastname:
          # Passwords are encoded using BCrypt
          # Password value: password
          password: $2a$10$9kjw/SH9gucCId3Lnt6EmuFreUAcXSZgpvAYuW2ISv7hSOhHRH1AO
          roles: ORGANIZATION:USER,ENVIRONMENT:USER
          # Useful to receive notifications
          #email:
        - user:
          username: admin
          #firstname:
          #lastname:
          # Password value: admin
          password: $2a$10$Ihk05VSds5rUSgMdsMVi9OKMIx2yUvMz7y9VP3rJmQeizZLrhLMyq
          roles: ORGANIZATION:ADMIN,ENVIRONMENT:ADMIN
          #email:
        - user:
          username: api1
          #firstname:
          #lastname:
          # Password value: api1
          password: $2a$10$iXdXO4wAYdhx2LOwijsp7.PsoAZQ05zEdHxbriIYCbtyo.y32LTji
          # You can declare multiple roles using comma separator
          roles: ORGANIZATION:USER,ENVIRONMENT:API_PUBLISHER
          #email:
        - user:
          username: application1
          #firstname:
          #lastname:
          # Password value: application1
          password: $2a$10$2gtKPYRB9zaVaPcn5RBx/.3T.7SeZoDGs9GKqbo9G64fKyXFR1He.
          roles: ORGANIZATION:USER,ENVIRONMENT:USER
          #email:
    # Enable authentication using internal repository
    - type: gravitee
      # allow search results to display the user email. Be careful, It may be contrary to the user privacy.
#      allow-email-in-search-results: true
    # Enable authentication using an LDAP/Active Directory
#    - type: ldap
      # This is default LDAP configuration for ApacheDS
#      context:
#        username: "uid=admin,ou=system"
#        password: "secret"
#        url: "ldap://localhost:10389/c=io,o=gravitee"
#        base: "c=io,o=gravitee" # the context source base
#      authentication:
#        user:
          # Search base for user authentication. Defaults to "". Only used with user filter.
          # It should be relative to the Base DN. If the whole DN is o=user accounts,c=io,o=gravitee then the base should be like this:
#          base: "o=user accounts"
          # The LDAP filter used to search for user during authentication. For example "(uid={0})". The substituted parameter is the user's login name.
#          filter: "mail={0}"
          # Specifies the attribute name which contains the user photo (URL or binary)
#          photo-attribute: "jpegPhoto"
#        group:
          # Search base for groups searches. Defaults to "". Only used with group filter.
          # It should be relative to the Base DN. If the whole DN is o=authorization groups,c=io,o=gravitee then the base should be like this:
#          base: "o=authorization groups"
#          filter: "member={0}"
#          role:
#            attribute: "cn"
#            mapper: {
#              GRAVITEE-CONSUMERS: API_CONSUMER,
#              GRAVITEE-PUBLISHERS: API_PUBLISHER,
#              GRAVITEE-ADMINS: ADMIN,
#              GRAVITEE-USERS: USER
#            }
#      lookup:
         # allow search results to display the user email. Be careful, It may be contrary to the user privacy.
#         allow-email-in-search-results: true
#        user:
          # Search base for user searches. Defaults to "". Only used with user filter.
          # It should be relative to the Base DN. If the whole DN is o=user accounts,c=io,o=gravitee then the base should be like this:
#          base: "o=user accounts"
          # The LDAP filter used to search for user during authentication. For example "(uid={0})". The substituted parameter is the user's login name.
#          filter: "(&(objectClass=Person)(|(cn=*{0}*)(uid={0})))"

# Define absolute path for the a default API icon (png format)
# If not define, an API without icon with display a random image
#configuration:
#  default-api-icon:

# SMTP configuration used to send mails
email:
  enabled: false
  host: smtp.my.domain
  subject: "[Gravitee.io] %s"
  port: 587
  from: noreply@my.domain
#  username: user@my.domain
#  password: password
#  properties:
#    auth: true
#    starttls.enable: true
#    ssl.trust: smtp.gmail.com

# Mail templates
#templates:
#  path: ${gravitee.home}/templates

# Console dashboards
#console:
#  dashboards:
#    path: ${gravitee.home}/dashboards

#portal:
#  themes:
#    path: ${gravitee.home}/themes
  # Allows domains to be used while generating some emails from the portal. ie. registration, forget password
  # Empty whitelist means all urls are allowed.
#  whitelist:
#    - https://portal.domain.com
#    - https://private-portal.domain.com

# Referenced properties
ds:
  mongodb:
    dbname: gravitee
    host: localhost
    port: 27017
  elastic:
    host: localhost
    port: 9200

jwt:
  secret: myJWT4Gr4v1t33_S3cr3t
  # Allows to define the end of validity of the token in seconds (default 604800 = a week)
  #expire-after: 604800
  # Allows to define the end of validity of the token in seconds for email registration (default 86400 = a day)
  #email-registration-expire-after: 86400
  # Allows to define issuer (default gravitee-management-auth)
  #issuer: gravitee-management-auth
  # Allows to define cookie context path (default /)
  #cookie-path: /
  # Allows to define cookie domain (default "")
  #cookie-domain: .gravitee.io
  # Allows to define if cookie secure only (default false)
  #cookie-secure: true

swagger:
  # Default scheme used when creating an API from a Swagger descriptor if there is no scheme specified.
  scheme: https

# User management configuration
user:
  login:
    # Create a default application when user connects to the portal for the very first time (default true)
    #defaultApplication: true

  # Password complexity validation policy
  # Applications should enforce password complexity rules to discourage easy to guess passwords.
  # Passwords should require a minimum level of complexity that makes sense for the application and its user population.
  password:
    policy:
      # Regex pattern for password validation (default to OWASP recommendations).
      # 8 to 32 characters, no more than 2 consecutive equal characters, min 1 special characters (@ & # ...), min 1 upper case character.
      pattern: ^(?:(?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))(?!.*(.)\1{2,})[A-Za-z0-9!~<>,;:_\-=?*+#."'&§`£€%°()\\\|\[\]\-\$\^\@\/]{8,32}$
              # Example : ^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$
              # ^                # start-of-string
              #(?=.*[0-9])       # a digit must occur at least once
              #(?=.*[a-z])       # a lower case letter must occur at least once
              #(?=.*[A-Z])       # an upper case letter must occur at least once
              #(?=.*[@#$%^&+=])  # a special character must occur at least once
              #(?=\S+$)          # no whitespace allowed in the entire string
              #.{8,}             # anything, at least eight places though
              #$                 # end-of-string
  creation:
    token:
      #expire-after: 86400
  reference:
      # Secret key used to generate reference of a user which is unique (default: s3cR3t4grAv1t33.1Ous3D4R3f3r3nc3)
      # Must contains 32 chars (256 bits)
      #secret:
  anonymize-on-delete:
    #enabled: true

# Enable / disable documentation sanitize. Enabled by default.
documentation:
  markdown:
    sanitize: true

#imports:
  # Enable / disable import from private hosts. Enabled by default. (See https://en.wikipedia.org/wiki/Private_network)
#  allow-from-private: true
  # Empty whitelist means all urls are allowed. Note: allow-from-private is ignored when whitelist is defined.
#  whitelist:
#      - https://whitelist.domain1.com
#      - https://restricted.domain2.com/whitelisted/path

search:
  data: ${gravitee.home}/data

# global configuration of the http client
#httpClient:
#  timeout: 10000 # in milliseconds
#  proxy:
#    exclude-hosts: # list of hosts to exclude from proxy (wildcard hosts are supported)
#      - '*.internal.com'
#      - internal.mycompany.com
#    type: HTTP #HTTP, SOCK4, SOCK5
#    http:
#      host: localhost
#      port: 3128
#      username: user
#      password: secret
#    https:
#      host: localhost
#      port: 3128
#      username: user
#      password: secret

notifiers:
  email:
    enabled: true
    host: ${email.host}
    subject: ${email.subject}
    port: ${email.port}
#    username: ${email.username}
#    password: ${email.password}
#    starttls.enabled: false
#    ssl:
#      trustAll: false
#      keyStore:
#      keyStorePassword:
#  webhook:
#    enabled: true
    # Empty whitelist means all urls are allowed.
#    whitelist:
#      - https://whitelist.domain1.com
#      - https://restricted.domain2.com/whitelisted/path

# Allows to enable or disable recaptcha (see https://developers.google.com/recaptcha/docs/v3). Currently, it only affect the user registration route.
#reCaptcha:
#  enabled: false
#  siteKey:
#  secretKey:
#  minScore: 0.5
#  serviceUrl: https://www.google.com/recaptcha/api/siteverify

#el:
  # Allows to define which methods or classes are accessible to the Expression Language engine (/!\ caution, changing default whitelist may expose you to security issues).
  # A complete list of default whitelist methods can be found here (https://raw.githubusercontent.com/gravitee-io/gravitee-expression-language/master/src/main/resources/whitelist).
#  whitelist:
    # Allows to define if the specified list of method or classes should be append to the default one or should replace it.
    # We recommend you to always choose 'append' unless you absolutely kwnow what you are doing.
#    mode: append
    # Define the list of classes or methods to append (or set) to made accessible to the Expression Language.
    # start with 'method' to allow a specific method (complete signature).
    # start with 'class' to allow a complete class. All methods of the class will then be accessible.
#    list:
      # Ex: allow access to DateTimeFormatter.ofLocalizedDate(FormatStyle) method
      # - method java.time.format.DateTimeFormatter ofLocalizedDate java.time.format.FormatStyle
      # Ex: allow access to all methods of DateTimeFormatter class
      # - class java.time.format.DateTimeFormatter

#groovy:
  # Allows to define which methods, fields, constructors, annotations or classes are accessible to the Groovy Script (/!\ caution, changing default whitelist may expose you to security issues).
  # A complete list of default whitelist methods can be found here (https://raw.githubusercontent.com/gravitee-io/gravitee-policy-groovy/master/src/main/resources/groovy-whitelist).
#  whitelist:
    # Allows to define if the specified list of methods, fields, constructors or classes should be append to the default one or should replace it.
    # We recommend you to always choose 'append' unless you absolutely know what you are doing.
#    mode: append
    # Define the list of classes, methods, constructors, fields or annotations to append (or set) to made accessible to the Groovy Script.
    # start with 'method' to allow a specific method (complete signature).
    # start with 'class' to allow a complete class. All methods, constructors and fields of the class will then be accessible.
    # start with 'new' to allow a specific constructor (complete signature).
    # start with 'field' to allow access to a specific field of a class.
    # start with 'annotation' to allow use of a specific annotation.
#    list:
      # Ex: allow access to DateTimeFormatter.ofLocalizedDate(FormatStyle) method
      # - method java.time.format.DateTimeFormatter ofLocalizedDate java.time.format.FormatStyle
      # Ex: allow access to all methods, constructors and fields of DateTimeFormatter class
      # - class java.time.format.DateTimeFormatter
      # Ex: allow usage of field Integer.MAX_VALUE
      # - field java.lang.Integer MAX_VALUE
      # Ex: allow usage of @Override annotation
      # - annotation java.lang.Override

# Allows to enable or disable the 'Subscribe to newsletter' feature when user completes his profile on first log in. Default is enabled.
#newsletter:
#  enabled: true

# Specify the visibility duration of a gateway in Unknown State (in seconds)
# Default : 604800 seconds (7 days)
#gateway:
#  unknown-expire-after: 604800

# Cockpit
# Specify the URL to cockpit instance. Default is the Gravitee SAAS instance
#cockpit:
#  url: https://cockpit.gravitee.io

这里我给大家贴一份最基础版本的配置文件出来,APIM的基础配置要比网关多,我们需要配置一个基础的管理员用户上去,其次就是我们还需要配置跨域,当然这个可以使用NGINX代劳。

management:
  type: mongodb
  mongodb:
    uri: mongodb://root:QmWLCipjnaBtUyvcB_7W2%40KM@dds-2ze2c0ee6403fe841.mongodb.rds.aliyuncs.com:3717,dds-2ze2c0ee6403fe842.mongodb.rds.aliyuncs.com:3717/admin?replicaSet=mgset-50070402
cache:
  type: ehcache
analytics:
  type: elasticsearch
  elasticsearch:
    enabled: true
    endpoints:
      - http://172.17.0.1:9200
security:
  providers:
    - type: memory
      password-encoding-algo: bcrypt #用户密码的加密方式,根据这个生成password
      users:
        - user:
          username: admin
          password: $2a$10$3hWK.D6quYLCaBv/thzf.OBp5awWa5ZvRUdfC80/Xr10FSRgT/4oW
          roles: ORGANIZATION:ADMIN,ENVIRONMENT:ADMIN
jwt:
  secret: diunilaomu
http:
  api:
   management:
    allow-origin: '*'
    allow-methods: 'OPTIONS, GET, POST, PUT, DELETE'
    allow-headers: 'X-Requested-With'
   portal:
    allow-origin: '*'
    allow-methods: 'OPTIONS, GET, POST, PUT, DELETE'
    allow-headers: 'X-Requested-With'

然后运行命令启动,和网关一样,需要外部挂载一个配置文件进去,只是配置文件的目录变了。

sudo docker run -p 8083:8083 --name openapi-mg -v /home/openapi/api:/etc/gravitee-management  graviteeio/apim-management-api:latest

也可以下载好官方的压缩包,然后自己进行镜像的变异,这里贴一下Dockerfile,你会发现他和网关一样都是通过脚本启动的,可以像网关一样去改里面的参数

FROM adoptopenjdk/openjdk11:jre-11.0.11_9-alpine
ENV GRAVITEEIO_HOME /opt/graviteeio-management-api
COPY ./ ${GRAVITEEIO_HOME}
WORKDIR ${GRAVITEEIO_HOME}
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk update \
	&& apk add --update --no-cache zip unzip netcat-openbsd wget \
    && chgrp -R 0 ${GRAVITEEIO_HOME} \
    && chmod -R g=u ${GRAVITEEIO_HOME}
RUN ls
EXPOSE 8082
RUN chmod 777 ./bin/gravitee
ENTRYPOINT ["./bin/gravitee"]

编译好后,启动一下我们的APIM就可以看到端口已经正常监听并且提供服务,下一篇我们介绍一下如何部署APIM的前端UI页面。

image.png