Kubernetes提示和技巧:访问开发站点

我们将继续介绍有关如何使维护人员和开发人员在使用Kubernetes的日常工作中更轻松的生活的系列方法文章。 所有这些都是从我们解决客户问题的经验中收集的,并且随着时间的流逝而有所改进,但仍然不能说是理想的-将它们更多地视为想法和空白,在评论中提出解决方案和改进建议。


这次,将考虑两个主题,有条件地与一个主题相关:用户对开发环境的访问。

1.我们如何关闭不必要用户的开发电路?


我们经常面临关闭基本auth或白名单背后的整个开发电路(数十个/数百个应用程序)的任务,以使搜索bot或非常第三方的人员无法到达那里。

通常,为了限制访问,每个Ingress和应用程序都需要创建单独的基本身份验证密钥 。 使用十几个应用程序键入内容时,管理它们非常麻烦。 因此,我们组织了集中式访问控制。

为此,使用以下类型的配置创建了nginx:

location / { satisfy any; auth_basic "Authentication or whitelist!"; auth_basic_user_file /etc/nginx/htpasswd/htpasswd; allow 10.0.0.0/8; allow 175.28.12.2/32; deny all; try_files FAKE_NON_EXISTENT @return200; } location @return200 { return 200 Ok; } 

在应用程序的Ingress中,我们只需添加注释:

ingress.kubernetes.io/auth-url: "http://dev-auth.dev-auth-infra.svc.cluster.local"

因此,在访问应用程序时,请求将转到dev-auth ,该dev-auth检查是否输入了正确的基本auth或客户端输入了白名单。 如果满足条件之一,则确认请求并将其传递给应用程序。



在使用这种服务的情况下,一个存储库就足够了,其中存储了所有访问的列表,我们可以通过它方便地配置“单一授权中心”。 通过基本添加批注将其分发到新应用程序。

2.我们如何在开发环境中提供对Kubernetes内部应用程序的访问?


...是Redis,RabbitMQ,PostgreSQL或Xdebug最受欢迎的PHP开发人员。

通常,将应用程序转换为Kubernetes时,为了确保更好的安全性,我们必须完全阻止来自外部的访问。 然后,习惯于将其IDE“转到数据库或Xdebug中”的开发人员会遇到严重的困难。

为了解决这个问题,我们直接在Kubernetes集群中使用VPN。 通用方案看起来像这样,当连接到在K8s中运行的VPN服务器时,在OpenVPN配置文件中我们推送DNS服务器的地址,该地址也位于K8s中。 OpenVPN以如下方式配置VPN:当它请求Kubernetes内部的资源时,它首先进入Kubernetes DNS服务器-例如,在redis.production.svc.cluster.local服务的地址之后。 Kubernetes中的DNS将其解析为10.244.1.15,并且对该IP地址的请求直接通过OpenVPN到达Kubernetes集群。

在此解决方案的运行过程中,我们设法对其进行了反复扩展。 特别是:

  1. 由于我们找不到用于说明对VPN的访问的简单且适当的(对于我们的情况而言) 管理面板 ,因此我们不得不创建自己的简单界面- 官方图表仅提供了启动控制台命令来颁发证书的选项。

    生成的管理面板 (另请参阅Docker Hub上 )看起来非常禁欲:


    您可以结交新用户或撤销旧证书:


    您还可以看到此客户端的配置:

  2. 我们在GitLab中基于用户在VPN中添加了授权 ,其中会检查密码以及用户是否在GitLab中处于活动状态。 这是针对客户端仅在不使用其他管理员的情况下仅希望管理基于GitLab才能连接到dev VPN的用户的情况下-从某种意义上说,这就是“穷人的SSO”。 他们以已经提到的现成图表为基础

    为此,我们编写了一个Python脚本,当使用用户名和密码将用户连接到OpenVPN时,它会比较GitLab数据库中的哈希并检查其状态(是否处于活动状态)。



    这是脚本本身:

     #!/usr/bin/env python3 # pip3 install psycopg2-binary bcrypt import bcrypt import sys import os import psycopg2 import yaml with open("/etc/openvpn/setup/config.yaml", 'r') as ymlfile: cfg = yaml.load(ymlfile) def get_user_info(username=''): try: connect_str = "dbname=%s user=%s host=%s password=%s" % (cfg['db'], cfg['user'], cfg['host'], cfg['pass']) # use our connection values to establish a connection conn = psycopg2.connect(connect_str) # create a psycopg2 cursor that can execute queries cursor = conn.cursor() # create a new table with a single column called "name" cursor.execute("""SELECT encrypted_password,state FROM users WHERE username='%s';""" % username) # run a SELECT statement - no data in there, but we can try it rows = cursor.fetchall() print(rows) return(rows[0]) except Exception as e: print("Uh oh, can't connect. Invalid dbname, user or password?") print(e) def check_user_auth(): username = os.environ['username'] password = bytes(os.environ['password'], 'utf-8') # hashed = bcrypt.hashpw(password, bcrypt.gensalt()) user_info = get_user_info(username=username) user_encrypted_password = bytes(user_info[0], 'utf-8') user_state = True if user_info[1] == 'active' else False if bcrypt.checkpw(password, user_encrypted_password) and user_state: print("It matches!") sys.exit(0) else: print("It does not match :(") sys.exit(1) def main(): check_user_auth() if __name__ == '__main__': main() 

    并在OpenVPN配置中指定以下内容:

    auth-user-pass-verify /etc/openvpn/auth-user.py via-env
    script-security 3
    client-cert-not-required


    因此,如果一名雇员离开了客户端,他们只是在GitLab中将其停用,之后他将无法连接到VPN。

而不是结论


继续阅读有关Kubernetes操作的实用Flant食谱的系列文章,我将讨论诸如突出显示特定任务(为什么以及如何?)的各个节点以及配置诸如php-fpm / gunicorn之类的服务以在重负载的容器中运行的主题。 订阅我们的博客,以免错过更新!

聚苯乙烯


K8s提示和技巧周期中的其他内容:


另请参阅我们的博客:

Source: https://habr.com/ru/post/zh-CN427745/


All Articles