zoukankan      html  css  js  c++  java
  • Openstack之二:服务认证keystone

    一:keystone介绍及安装:

    OpenStack的身份服务提供了集成的管理身份验证,授权和服务目录服务的单点,其他的OpenStack服务使用的身份服务作为一个通用统一的API,此外,提供有关用户的信息,但该服务不包括开栈(如LDAP服务)可以被集成到一个预先存在的基础设施,为了从身份服务中受益,其他的OpenStack服务需要与它合作。当一个开栈服务从用户接收请求时,它检查与用户是否被授权作出该请求的标识服务。

    身份服务包含以下组件:

    服务器:中央服务器提供了一种使用RESTful接口验证和授权服务。
    驱动程序:驱动程序或服务后端被集成到中央服务器。它们被用于在库外的OpenStack访问身份信息,并且可以在开栈中部署(例如,SQL数据库或LDAP服务器)的基础设施已经存在。
    模块:中间件模块中正在使用该标识服务的开栈组件的地址空间中运行。这些模块拦截服务请求,提取用户凭据,并将它们发送到中央服务器进行授权。中间件模块和OpenStack的组件之间的集成使用Python的Web服务器网关接口。
    当安装OpenStack的身份服务,您必须在您的OpenStack安装注册的每个服务。然后身份服务可以跟踪安装哪些开栈的服务,并且它们的位置在网络上。
    OpenStack的身份服务提供了集成的管理身份验证,授权和服务目录服务的单点。
    用户与认证:用户权限与用户登录密码认证等。。
    服务目录:提供一个服务目录,记录所有服务对应的IP地址信息。
    
    user:用户,即登录账号
    project:项目,按照项目划分公司,一个项目可以有多个用户。
    token:令牌,使用用户密码访问之后分配给访问者一个令牌,使用令牌即可进行操作。
    role:角色,项目中每个用户拥有不同的权限。
    
    用户目录两大名词:
    service:服务,比如nova/galce/swift都是服务,就是记录服务的作用,每个服务都需要在keystone进行注册标示改服务的作用。
    endpoint:端点,可以理解为服务对外暴露的URL地址,并且具有public、private和admin

    二、配置数据库

    1、创建数据库,并授权

    1、在数据库创建数据库,并在数据库中授权

    [root@mysql1 ~]# mysql -pcentos
    Welcome to the MariaDB monitor.  Commands end with ; or g.
    Your MariaDB connection id is 10
    Server version: 10.3.10-MariaDB MariaDB Server
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    MariaDB [(none)]> CREATE DATABASE keystone;
    Query OK, 1 row affected (0.078 sec)
    
    MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'centos';
    Query OK, 0 rows affected (0.124 sec)
    
    MariaDB [(none)]> 
    

     2、在控制端服务安装mysql客户端验证

    [root@openstack-1 ~]# yum install mysql -y
    

    在控制端将VIP地址进行域名解析,有几个控制端,就写几个hosts文件,为了后期维护好维护:vim  /etc/hosts

    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    
    192.168.7.248  openstack-vip.net

    开始远程连接数据库,此时可以看到已经连接进来。

    [root@openstack-1 ~]# mysql -ukeystone -pcentos -hopenstack-vip.net
    Welcome to the MariaDB monitor.  Commands end with ; or g.
    Your MariaDB connection id is 14
    Server version: 10.3.10-MariaDB MariaDB Server
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    MariaDB [(none)]> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | keystone           |
    +--------------------+
    2 rows in set (0.001 sec)
    

    三、在控制端安装组件  

     1、运行以下命令来安装包,有几个控制端,都将安装此包

    # yum install openstack-keystone httpd mod_wsgi
    

    2、编辑文件 /etc/keystone/keystone.conf 并完成如下动作:  

       在 [database] 部分,配置数据库访问:vim  /etc/keystone/keystone.conf 

    [database]
    connection = mysql+pymysql://keystone:centos@openstack-vip.net/keystone   #centos为数据库密码,openstack-vip.net为VIP地址的域名解析
    

     3、在``[token]``部分,配置Fernet UUID令牌的提供者

    [token]
    provider = fernet
    

    4、随机生成10进制数字,绕过keystone管理员密码验证,直接拥有管理员权限。

    [root@openstack-1 ~]# openssl rand -hex 10
    f0c29329cb611ddd407b
    
    vim  /etc/keystone/keystone.conf  #修改配置文件
    admin_token =  f0c29329cb611ddd407b
    

    5、 在控制端初始化身份认证服务的数据库: 

    [root@openstack-1 ~]# su -s /bin/sh -c "keystone-manage db_sync" keystone
    

    6、初始化Fernet key:  

    # keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
    # keystone-manage credential_setup --keystone-user keystone --keystone-group keystone
    

     7、需要修改配置文件:vim /usr/share/keystone/wsgi-keystone.conf,保证其监听5000端口和35357端口。

    Listen 5000
    Listen 35357
    
    <VirtualHost *:5000>
        WSGIDaemonProcess keystone-public processes=5 threads=1 user=keystone group=keystone display-name=%{GROUP}
        WSGIProcessGroup keystone-public
        WSGIScriptAlias / /usr/bin/keystone-wsgi-public
        WSGIApplicationGroup %{GLOBAL}
        WSGIPassAuthorization On
        LimitRequestBody 114688
        <IfVersion >= 2.4>
          ErrorLogFormat "%{cu}t %M"
        </IfVersion>
        ErrorLog /var/log/httpd/keystone.log
        CustomLog /var/log/httpd/keystone_access.log combined
    
        <Directory /usr/bin>
            <IfVersion >= 2.4>
                Require all granted
            </IfVersion>
            <IfVersion < 2.4>
                Order allow,deny
                Allow from all
            </IfVersion>
        </Directory>
    </VirtualHost>
    
    <VirtualHost *:35357>
        WSGIDaemonProcess keystone-admin processes=5 threads=1 user=keystone group=keystone display-name=%{GROUP}
        WSGIProcessGroup keystone-admin
        WSGIScriptAlias / /usr/bin/keystone-wsgi-admin
        WSGIApplicationGroup %{GLOBAL}
        WSGIPassAuthorization On
        LimitRequestBody 114688
        <IfVersion >= 2.4>
          ErrorLogFormat "%{cu}t %M"
        </IfVersion>
        ErrorLog /var/log/httpd/keystone.log
        CustomLog /var/log/httpd/keystone_access.log combined
    <Directory /usr/bin>
            <IfVersion >= 2.4>
                Require all granted
            </IfVersion>
            <IfVersion < 2.4>
                Order allow,deny
                Allow from all
            </IfVersion>
        </Directory>
    </VirtualHost>
    
    Alias /identity /usr/bin/keystone-wsgi-public
    <Location /identity>
        SetHandler wsgi-script
        Options +ExecCGI
    
        WSGIProcessGroup keystone-public
        WSGIApplicationGroup %{GLOBAL}
        WSGIPassAuthorization On
    </Location>
    
    Alias /identity_admin /usr/bin/keystone-wsgi-admin
    <Location /identity_admin>
        SetHandler wsgi-script
        Options +ExecCGI
    
        WSGIProcessGroup keystone-admin
        WSGIApplicationGroup %{GLOBAL}
        WSGIPassAuthorization On
    </Location>
    

    8、创建软链接  /usr/share/keystone/wsgi-keystone.conf

    # ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/
    

    9、安装httpd服务,并启动,查看端口是否监听到5000和35357端口

    [root@openstack-1 keystone]#yum install httpd -y
    [root@openstack-1 keystone]# systemctl start httpd
    [root@openstack-1 keystone]# systemctl enable httpd
    [root@openstack-1 keystone]# ss -ntl
    State       Recv-Q Send-Q                           Local Address:Port                                          Peer Address:Port              
    LISTEN      0      100                                  127.0.0.1:25                                                       *:*                  
    LISTEN      0      128                                          *:22                                                       *:*                  
    LISTEN      0      100                                      [::1]:25                                                    [::]:*                  
    LISTEN      0      511                                       [::]:35357                                                 [::]:*                  
    LISTEN      0      511                                       [::]:5000                                                  [::]:*                  
    LISTEN      0      511                                       [::]:80                                                    [::]:*                  
    LISTEN      0      128                                       [::]:22                                                    [::]:*   
    

     10、通过admin的token设置环境变量进行操作,直接绕过token管理员权限。

    [root@openstack-1 ~]# export OS_TOKEN=f0c29329cb611ddd407b    #上面创建的admin_token随机数
    [root@openstack-1 ~]# export OS_URL=http://192.168.7.100:35357/v3
    [root@openstack-1 ~]# export OS_IDENTITY_API_VERSION=3

    四、在控制端创建域、项目、用户和角色

    1、创建默认域

    一定要在上一步设置完成环境变量的前提下 方可 操作成功,否则会提示未认证 。
    #命令格式为: openstack domain create description " 描述信息 " 域名

    1、在控制端创建domain域

    [root@openstack-1 ~]# openstack domain create --description "Default Domain" default
    +-------------+----------------------------------+
    | Field       | Value                            |
    +-------------+----------------------------------+
    | description | Default Domain                   |
    | enabled     | True                             |
    | id          | 8e295428192547d3a70b364676eb14ec |
    | name        | default                          |
    | tags        | []                               |
    +-------------+----------------------------------+
    

     2、删除默认域的命令,创建好就不要删除了

    [root@openstack-1 ~]# openstack domain delete 8e295428192547d3a70b364676eb14ec
    

    2、创建一个项目

    [root@openstack-1 ~]# openstack project create --domain default --description "Admin Project" admin
    +-------------+----------------------------------+
    | Field       | Value                            |
    +-------------+----------------------------------+
    | description | Admin Project                    |
    | domain_id   | 8e295428192547d3a70b364676eb14ec |
    | enabled     | True                             |
    | id          | 7f3a9cccf0714a02a20c48006e1aa681 |
    | is_domain   | False                            |
    | name        | admin                            |
    | parent_id   | 8e295428192547d3a70b364676eb14ec |
    | tags        | []                               |
    +-------------+----------------------------------+
    

     3、创建一个用户账号和密码,账号和密码都是admin。

    [root@openstack-1 ~]# openstack user create --domain default --password-prompt admin
    User Password:
    Repeat User Password:
    +---------------------+----------------------------------+
    | Field               | Value                            |
    +---------------------+----------------------------------+
    | domain_id           | 8e295428192547d3a70b364676eb14ec |
    | enabled             | True                             |
    | id                  | 545853265f0346b88a0624061ebaa6c0 |
    | name                | admin                            |
    | options             | {}                               |
    | password_expires_at | None                             |
    +---------------------+----------------------------------+
    

     查看此时创建的用户名,可以看到账号是admin

    [root@openstack-1 ~]# openstack user list
    +----------------------------------+-------+
    | ID                               | Name  |
    +----------------------------------+-------+
    | 545853265f0346b88a0624061ebaa6c0 | admin |
    +----------------------------------+-------+
    

     4、给admin创建角色

    [root@openstack-1 ~]# openstack role create admin
    +-------------+----------------------------------+
    | Field       | Value                            |
    +-------------+----------------------------------+
    | description | None                             |
    | domain_id   | None                             |
    | id          | b84435b0ec1d428cbfcad4eaaaaa4a36 |
    | name        | admin                            |
    +-------------+----------------------------------+
    

    5、给admin用户授权

    此时创建的域、用户、角色及项目都已完成。

    将admin用户授予admin项目的admin角色,即给admin项目添加一个用户叫admin,并将其添加至admin角色,角色是权限的一种集合:

    [root@openstack-1 ~]# openstack role add --project admin --user admin admin
    

    下面是演示部分,可以在此部分做实验 

    1、创建demo项目

    [root@openstack-1 ~]# openstack project create --domain default --description "Demo Project" demo
    +-------------+----------------------------------+
    | Field       | Value                            |
    +-------------+----------------------------------+
    | description | Demo Project                     |
    | domain_id   | 8e295428192547d3a70b364676eb14ec |
    | enabled     | True                             |
    | id          | 4df34d7e5fa641c48256855f9732c988 |
    | is_domain   | False                            |
    | name        | demo                             |
    | parent_id   | 8e295428192547d3a70b364676eb14ec |
    | tags        | []                               |
    +-------------+----------------------------------+
    

     2、创建demo用户并设置密码为demo

    [root@openstack-1 ~]# openstack user create --domain default --password-prompt demo
    User Password:
    Repeat User Password:
    +---------------------+----------------------------------+
    | Field               | Value                            |
    +---------------------+----------------------------------+
    | domain_id           | 8e295428192547d3a70b364676eb14ec |
    | enabled             | True                             |
    | id                  | 50c33973910e4594af2299fb3bea0ff2 |
    | name                | demo                             |
    | options             | {}                               |
    | password_expires_at | None                             |
    +---------------------+----------------------------------+
    

    3、创建一个 user角色

    [root@openstack-1 ~]# openstack role create user
    +-------------+----------------------------------+
    | Field       | Value                            |
    +-------------+----------------------------------+
    | description | None                             |
    | domain_id   | None                             |
    | id          | 88815f7cc0b249008bdcf32ae81e4b2b |
    | name        | user                             |
    +-------------+----------------------------------+
    

    4、把 demo用户添加到demo项目:

    [root@openstack-1 ~]# openstack role add --project demo --user demo user

    五、在控制端注册服务

     1、创建一个keystone认证服务:

    1、将keystone服务地址注册到openstack,创建一个 keystone 认证服务:

    [root@openstack-1 ~]# openstack service create --name keystone --description "OpenStack  Identity" identity
    
    +-------------+----------------------------------+
    | Field       | Value                            |
    +-------------+----------------------------------+
    | description | OpenStack  Identity              |
    | enabled     | True                             |
    | id          | 53231b516cdd47ebbe991ed998861c59 |
    | name        | keystone                         |
    | type        | identity                         |
    +-------------+----------------------------------+
    

    2、创建endpoint

    [root@openstack-1 ~]# openstack endpoint create --region RegionOne identity internal http://openstack-vip.net:5000/v3 # 私有端点
    +--------------+----------------------------------+
    | Field        | Value                            |
    +--------------+----------------------------------+
    | enabled      | True                             |
    | id           | 6aea541fb7964bdbb7d261e1ad7a64a2 |
    | interface    | internal                         |
    | region       | RegionOne                        |
    | region_id    | RegionOne                        |
    | service_id   | 53231b516cdd47ebbe991ed998861c59 |
    | service_name | keystone                         |
    | service_type | identity                         |
    | url          | http://openstack-vip.net:5000/v3 |
    +--------------+----------------------------------+
    [root@openstack-1 ~]# openstack endpoint create --region RegionOne identity public http://openstack-vip.net:5000/v3  #公有端点
    +--------------+----------------------------------+
    | Field        | Value                            |
    +--------------+----------------------------------+
    | enabled      | True                             |
    | id           | c830d8e3ef8c49688e453c6ec3037420 |
    | interface    | public                           |
    | region       | RegionOne                        |
    | region_id    | RegionOne                        |
    | service_id   | 53231b516cdd47ebbe991ed998861c59 |
    | service_name | keystone                         |
    | service_type | identity                         |
    | url          | http://openstack-vip.net:5000/v3 |
    +--------------+----------------------------------+
    [root@openstack-1 ~]# openstack endpoint create --region RegionOne identity admin http://openstack-vip.net:35357/v3 # 管理端点
    +--------------+-----------------------------------+
    | Field        | Value                             |
    +--------------+-----------------------------------+
    | enabled      | True                              |
    | id           | f4c9d8b557304a7183f4e65ed89099d7  |
    | interface    | admin                             |
    | region       | RegionOne                         |
    | region_id    | RegionOne                         |
    | service_id   | 53231b516cdd47ebbe991ed998861c59  |
    | service_name | keystone                          |
    | service_type | identity                          |
    | url          | http://openstack-vip.net:35357/v3 |
    +--------------+-----------------------------------+
    

     查看创建结果

    [root@openstack-1 ~]# openstack endpoint list
    +----------------------------------+-----------+--------------+--------------+---------+-----------+-----------------------------------+
    | ID                               | Region    | Service Name | Service Type | Enabled | Interface | URL                               |
    +----------------------------------+-----------+--------------+--------------+---------+-----------+-----------------------------------+
    | 6aea541fb7964bdbb7d261e1ad7a64a2 | RegionOne | keystone     | identity     | True    | internal  | http://openstack-vip.net:5000/v3  |
    | c830d8e3ef8c49688e453c6ec3037420 | RegionOne | keystone     | identity     | True    | public    | http://openstack-vip.net:5000/v3  |
    | f4c9d8b557304a7183f4e65ed89099d7 | RegionOne | keystone     | identity     | True    | admin     | http://openstack-vip.net:35357/v3 |
    +----------------------------------+-----------+--------------+--------------+---------+-----------+-----------------------------------+
    

     六、再次配置haproxy服务器

    1、修改配置文件,监听keystone的5000端口和35357端口,前面的端口都已经监听过,这里不再细说,且配置文件中都只是监听部分文件,其他部分见openstack之一详解。

     vim  /etc/haproxy/haproxy.cfg

    listen openstack_web_port
        bind 192.168.7.248:3306
        mode tcp
        log global
        server 192.168.7.106 192.168.7.106:3306 check inter 3000 fall 3 rise 5
    
    listen openstack_rabbitmq_port
        bind 192.168.7.248:5672
        mode tcp
        log global
        server 192.168.7.106 192.168.7.106:5672 check inter 3000 fall 3 rise 5
        server 192.168.7.107 192.168.7.107:5672 check inter 3000 fall 3 rise 5 backup
    
    [root@mysql1 ~]# vim /etc/haproxy/haproxy.cfg
    listen openstack_rabbitmq_port
        bind 192.168.7.248:11211
        mode tcp
        log global
        server 192.168.7.106 192.168.7.106:11211 check inter 3000 fall 3 rise 5
        server 192.168.7.107 192.168.7.107:11211 check inter 3000 fall 3 rise 5 backup
            
    
    listen openstack_keystone_port_5000
        bind 192.168.7.248:5000
        mode tcp
        log global
        server 192.168.7.100 192.168.7.100:5000 check inter 3000 fall 3 rise 5
    
    listen openstack_keystone_port_35357
        bind 192.168.7.248:35357
        mode tcp
        log global
        server 192.168.7.100 192.168.7.100:35357 check inter 3000 fall 3 rise 5
    

     2、重启haproxy服务,并查看是否监听了5000端口和35357端口

    [root@mysql1 ~]# systemctl restart haproxy
    

     3、可以在控制端进行telnet进行测试,是否可以连接

    [root@openstack-1 keystone]# telnet 192.168.7.248 5000
    [root@openstack-1 keystone]# telnet 192.168.7.248 35357
    

    七、在控制端测试keystone是否可以做用户验证:

    1、需要新打开一个shell窗口,在没有声明环境变量的情况下执行下面命令

    [root@openstack-1 ~]# export OS_IDENTITY_API_VERSION=3
    

    2、创建一个脚本,设置用户环境变量,以后就不需要每次都使用这么长的命令啦,创建一个admin账户和demo用户。

    #官方文档:http://docs.openstack.org/mitaka/zh_CN/install-guide-rdo/keystone-openrc.html

    admin账号:

    #!/bin/bash
    export OS_PROJECT_DOMAIN_NAME=default
    export OS_USER_DOMAIN_NAME=default
    export OS_PROJECT_NAME=admin
    export OS_USERNAME=admin
    export OS_PASSWORD=admin
    export OS_AUTH_URL=http://192.168.7.100:35357/v3
    export OS_IDENTITY_API_VERSION=3
    export OS_IMAGE_API_VERSION=2
    

    #官方文档:http://docs.openstack.org/mitaka/zh_CN/install-guide-rdo/keystone-openrc.html

    demo账号:

    #!/bin/bash
    export OS_PROJECT_DOMAIN_NAME=default
    export OS_USER_DOMAIN_NAME=default
    export OS_PROJECT_NAME=demo
    export OS_USERNAME=demo
    export OS_PASSWORD=demo
    export OS_AUTH_URL=http://192.168.7.100:35357/v3
    export OS_IDENTITY_API_VERSION=3
    export OS_IMAGE_API_VERSION=2

    3、让其脚本生效,并验证效果

    [root@openstack-1 ~]# . admin.sh
    [root@openstack-1 ~]# . demo.sh
    [root@openstack-1 ~]# echo $OS_PASSWORD admin

    4、执行验证命令,验证用户名,此时就不需要输入密码验证。

    [root@openstack-1 ~]# openstack --os-auth-url http://192.168.7.100:35357/v3 --os-project-domain-name default --os-user-domain-name default --os-project-name admin --os-username admin token issue
    +------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Field      | Value                                                                                                                                                                                   |
    +------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | expires    | 2020-01-05T16:12:34+0000                                                                                                                                                                |
    | id         | gAAAAABeEfziRVpPQbKDKadzND1hBaFgNP0cnUdj8gcxROH2jJf4hhKqSgCpN1_wSPOGID-ydaPVcnPCspjdtXTDsMtdsHz5zFTCc6NzkM41O6GwCkvuh03f69DuRzUVzJs_fYkrK_r5FQTOCOrZfBzyLHtbWyAROOW6xRWuMv5q1VaC_NELAxg |
    | project_id | 7f3a9cccf0714a02a20c48006e1aa681                                                                                                                                                        |
    | user_id    | 545853265f0346b88a0624061ebaa6c0                                                                                                                                                        |
    +------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    

    八、控制台一备份控制端keystone数据

    1、备份控制端服务器数据,传给另一台控制端指定目录,就不需要再进行配置

    [root@openstack-1 ~]# cd /etc/keystone/
    [root@openstack-1 keystone]# tar -zcvf keystone-conller.tar.gz  ./*
    ./credential-keys/
    ./credential-keys/1
    ./credential-keys/0
    ./default_catalog.templates
    ./fernet-keys/
    ./fernet-keys/1
    ./fernet-keys/0
    ./keystone.conf
    ./logging.conf
    ./policy.json
    ./sso_callback_template.html
    

    2、控制台二要安装httpd服务

    # yum install httpd  -y

    3、将备份的数据和关联的httpd监听的5000端口和35357端口的配置文件,都传递到控制台二,解压并做软连接

    [root@openstack-1 keystone]# scp keystone-conller.tar.gz  192.168.7.101:/etc/keystone/
    [root@openstack-1 conf.d]# scp /etc/httpd/conf.d/wsgi-keystone.conf  192.168.7.101:/etc/httpd/conf.d/

    4、在控制端台二将备份的文件解压

    [root@openstack-2 keystone]# tar -xvf keystone-conller.tar.gz
    

    5、在控制台二创建软链接,并启动httpd服务。

    # ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/
    # systemctl start httpd 
    

    再次配置haproxy服务

    已经配置了新的控制端,在haproxy配置IP地址,主要监听的IP地址修改,其他不变。

    listen openstack_keystone_port_5000
        bind 192.168.7.248:5000
        mode tcp
        log global
        server 192.168.7.100 192.168.7.100:5000 check inter 3000 fall 3 rise 5
        server 192.168.7.101 192.168.7.100:5000 check inter 3000 fall 3 rise 5 backup
    
    listen openstack_keystone_port_35357
        bind 192.168.7.248:35357
        mode tcp
        log global
        server 192.168.7.100 192.168.7.100:35357 check inter 3000 fall 3 rise 5
        server 192.168.7.101 192.168.7.100:35357 check inter 3000 fall 3 rise 5 backup
    

    重启haproxy服务

    # systemctl restart haproxy
    

    当我们的主机宕机之后,不知道哪个VIP跑在负载均衡服务器上,怎么办? 

    我们可以通过远程连接提供服务的服务器,然后查看服务器的IP地址,就可以查看到VIP地址。 

     

      

     

      

      

      

     

     

     

      

     

     

      

      

     

     

     

     

     

  • 相关阅读:
    Spark——为数据分析处理提供更为灵活的赋能
    秋读|10本热门图书(人工智能、编程开发、架构、区块链等)免费送!
    使用Phaser开发你的第一个H5游戏(一)
    Java web 服务启动时Xss溢出异常处理笔记
    为什么我打的jar包没有注解?
    收集、分析线上日志数据实战——ELK
    阿里云PolarDB及其共享存储PolarFS技术实现分析(下)
    14.5 富文本编辑【JavaScript高级程序设计第三版】
    【收藏】15个常用的javaScript正则表达式
    C# 网络请求
  • 原文地址:https://www.cnblogs.com/struggle-1216/p/12154342.html
Copyright © 2011-2022 走看看