Kubernetes集群中的容器访问集群外的服务

集群内部python项目链接集群外的mysql服务案例

案例:企业需要所有本地运行的服务全部上云做容器化,因为数据库迁移的复杂度较高也比较麻烦风险系数也比较高因此,数据库还是由本地部署,业务代码上Kubernetes管理
架构图:
架构图

在集群外启动一个Mysql服务

# 集群外的一台机子使用docker启动了mysql服务(当然可以手动部署一个也行)
[root@master ~]# docker run --name mysql-server -e MYSQL_ROOT_PASSWORD=000000 -p 3306:3306 -d mysql:8.0
df2573ca48c9d390b7727634550e8700a8fd64f6f649fac38d5a288f4fe3160f

创建一个简单的python连接数据库的web服务镜像

编写简单的python代码

[root@master apps]# cat app.py
from flask import Flask
import os
import mysql.connector

app = Flask(__name__)

@app.route('/')
def index():
    try:
        # 从环境变量获取数据库连接信息
        db_name = os.getenv('DB_NAME')
        db_user = os.getenv('DB_USER')
        db_password = os.getenv('DB_PASSWORD')
        db_host = os.getenv('DB_HOST', 'localhost')
        db_port = os.getenv('DB_PORT', '3306')  # MySQL 默认端口是 3306

        # 连接到 MySQL 数据库
        connection = mysql.connector.connect(
            database=db_name,
            user=db_user,
            password=db_password,
            host=db_host,
            port=db_port,
            ssl_disabled=True  # 禁用 SSL,视情况而定
        )
        return f"成功连接到数据库: {db_name}"
    except Exception as e:
        return f"连接数据库失败: {e}"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)	# 服务启动端口
    
# 编写依赖包文件
[root@master apps]# vim requirements.txt
Flask
mysql-connector-python

编写Dockerfile文件并打包镜像

# 编写Dockerfile
[root@master apps]# cat Dockerfile
# 使用Python官方镜像
FROM python:3.9-slim

# 设置工作目录
WORKDIR /app

# 复制应用代码和依赖文件
COPY app.py requirements.txt ./

# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt --index-url https://pypi.tuna.tsinghua.edu.cn/simple

# 暴露应用端口
EXPOSE 5000

# 启动应用
CMD ["python", "app.py"]

# 打包镜像并导出到本地
[root@master apps]# docker build -t flask-db-app:v0.0.2 .
[+] Building 14.3s (9/9) FINISHED                                                                                        docker:default
 => [internal] load build definition from Dockerfile                                                                               0.0s
 => => transferring dockerfile: 386B                                                                                               0.0s
 => [internal] load metadata for docker.io/library/python:3.9-slim                                                                 0.0s
 => [internal] load .dockerignore                                                                                                  0.0s
 => => transferring context: 2B                                                                                                    0.0s
 => [1/4] FROM docker.io/library/python:3.9-slim                                                                                   0.0s
 => [internal] load build context                                                                                                  0.0s
 => => transferring context: 1.02kB                                                                                                0.0s
 => CACHED [2/4] WORKDIR /app                                                                                                      0.0s
 => [3/4] COPY app.py requirements.txt ./                                                                                          0.0s
 => [4/4] RUN pip install --no-cache-dir -r requirements.txt --index-url https://pypi.tuna.tsinghua.edu.cn/simple                 14.0s
 => exporting to image                                                                                                             0.2s
 => => exporting layers                                                                                                            0.2s
 => => writing image sha256:d1782897e9ba74db9387659d54db5aad9f48911bac44ed593d24823bbb52b451                                       0.0s
 => => naming to docker.io/library/flask-db-app:v0.0.2                                                                             0.0s

上传镜像到Kubernetes各节点

# 把镜像保存到本地(因为需要导入到k8s集群,我使用的容器进行时是containerd)
[root@master ~]# docker save -o flask-db-app-0.0.2.tar flask-db-app:v0.0.2

# 上传镜像到各个节点并导入containerd中(自己写了脚本)
[root@master ~]# ./scpFile.sh
请输入源文件或文件夹路径: ./flask-db-app-0.0.2.tar
请输入目标主机域名(用空格分隔): mastera masterb masterc worka workb workc
请输入目标路径: /root/flask-db-app-0.0.2
请输入Kubernetes命名空间: k8s.io
flask-db-app-0.0.2.tar                                                                                100%  196MB  64.5MB/s   00:03
文件成功传输到 mastera:/root/flask-db-app-0.0.2
在 mastera 上执行导入命令: ctr -n k8s.io image import /root/flask-db-app-0.0.2/flask-db-app-0.0.2.tar
导入输出: unpacking docker.io/library/flask-db-app:v0.0.2 (sha256:7192f27b626f35b014757daf6e5f42f9c0ffc25fc964d16bea45a76f575b2c71)...done
文件成功导入到 k8s.io 命名空间
flask-db-app-0.0.2.tar                                                                                100%  196MB  96.5MB/s   00:02
文件成功传输到 masterb:/root/flask-db-app-0.0.2
在 masterb 上执行导入命令: ctr -n k8s.io image import /root/flask-db-app-0.0.2/flask-db-app-0.0.2.tar
导入输出: unpacking docker.io/library/flask-db-app:v0.0.2 (sha256:7192f27b626f35b014757daf6e5f42f9c0ffc25fc964d16bea45a76f575b2c71)...done
文件成功导入到 k8s.io 命名空间
flask-db-app-0.0.2.tar                                                                                100%  196MB  49.0MB/s   00:03
文件成功传输到 masterc:/root/flask-db-app-0.0.2
在 masterc 上执行导入命令: ctr -n k8s.io image import /root/flask-db-app-0.0.2/flask-db-app-0.0.2.tar
导入输出: unpacking docker.io/library/flask-db-app:v0.0.2 (sha256:7192f27b626f35b014757daf6e5f42f9c0ffc25fc964d16bea45a76f575b2c71)...done
文件成功导入到 k8s.io 命名空间
flask-db-app-0.0.2.tar                                                                                100%  196MB  56.9MB/s   00:03
文件成功传输到 worka:/root/flask-db-app-0.0.2
在 worka 上执行导入命令: ctr -n k8s.io image import /root/flask-db-app-0.0.2/flask-db-app-0.0.2.tar
导入输出: unpacking docker.io/library/flask-db-app:v0.0.2 (sha256:7192f27b626f35b014757daf6e5f42f9c0ffc25fc964d16bea45a76f575b2c71)...done
文件成功导入到 k8s.io 命名空间
flask-db-app-0.0.2.tar                                                                                100%  196MB  67.0MB/s   00:02
文件成功传输到 workb:/root/flask-db-app-0.0.2
在 workb 上执行导入命令: ctr -n k8s.io image import /root/flask-db-app-0.0.2/flask-db-app-0.0.2.tar
导入输出: unpacking docker.io/library/flask-db-app:v0.0.2 (sha256:7192f27b626f35b014757daf6e5f42f9c0ffc25fc964d16bea45a76f575b2c71)...done
文件成功导入到 k8s.io 命名空间
flask-db-app-0.0.2.tar                                                                                100%  196MB  68.8MB/s   00:02
文件成功传输到 workc:/root/flask-db-app-0.0.2
在 workc 上执行导入命令: ctr -n k8s.io image import /root/flask-db-app-0.0.2/flask-db-app-0.0.2.tar
导入输出: unpacking docker.io/library/flask-db-app:v0.0.2 (sha256:7192f27b626f35b014757daf6e5f42f9c0ffc25fc964d16bea45a76f575b2c71)...done
文件成功导入到 k8s.io 命名空间

使用打包的镜像在Kubernetes中部署

编写Pod资源清单并创建

# 编写Pod资源清单
[root@masterA apps]# vim apps-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
  labels:
    app: py-web
spec:
  containers:
  - name: flask-db-app
    image: docker.io/library/flask-db-app:v0.0.2
    imagePullPolicy: Never	# 只使用本地镜像
    env:
    - name: DB_NAME
      value: 'isExternalMysqlOne'	# 根据访问的数据库服务器选择对应的数据库
    - name: DB_USER
      value: 'root'
    - name: DB_PASSWORD
      value: '000000'
    - name: DB_HOST
      value: 'external-svc'	# 外部数据库的svc,目前还没创建
    - name: DB_PORT
      value: '3306'	# 更改端口就可以访问另外一个数据库
    ports:
    - name: app-port
      containerPort: 5000	# 容器服务的端口
      
# 部署服务
[root@masterA apps]# kubectl apply -f apps-pod.yaml
# 验证Pod是否启动
[root@masterA apps]# kubectl get pod -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP             NODE              NOMINATED NODE   READINESS GATES
app-pod   1/1     Running   0          24m   172.16.38.21   workc.k8s.local   <none>           <none>

编写对外访问Service(NodePort)资源清单并创建

[root@masterA apps]# cat app-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-svc
spec:
  selector:
    app: py-web
  type: NodePort
  ports:
  - name: web-port
    nodePort: 30050
    port: 5000
    protocol: TCP
    targetPort: 5000
    
# 创建svc并验证
[root@masterA apps]# kubectl apply -f app-svc.yaml
[root@masterA apps]# kubectl get svc
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)              AGE
kubernetes     ClusterIP   10.92.0.1       <none>        443/TCP              25d
web-svc        NodePort    10.92.177.237   <none>        5000:30050/TCP       136m

这时候通过ip+端口已经可以访问到web页面了如下

访问web成功但链接数据库失败

可以看见虽然访问成功了但是并没有连上我们外部的数据库

创建外部数据库与集群内部的访问入口svc以及EndpointSlice

# 编写svc资源清单
[root@masterA app]# cat external-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: external-svc
spec:
  ports:
    - name: one-mysql-port
      protocol: TCP
      port: 3306
      targetPort: 3306
# 创建svc
[root@masterA app]# kubectl apply -f external-svc.yaml
# 编写EndpointSlice资源清单
[root@masterA app]# cat external-edp.yaml
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: external-svc-1 # 按惯例将 Service 的名称用作 EndpointSlice 名称的前缀
  labels:
    # 你应设置 "kubernetes.io/service-name" 标签。
    # 设置其值以匹配 Service 的名称
    kubernetes.io/service-name: external-svc
addressType: IPv4
ports:
  - name: 'one-mysql-port' # 应与上面定义的 Service 端口的名称匹配
    appProtocol: http
    protocol: TCP
    port: 3306
endpoints:  # 此列表中的 IP 地址可以按任何顺序显示
  - addresses:
      - "192.168.100.123"
# 创建EndpointSlice
[root@masterA app]# kubectl apply -f external-edp.yaml

访问验证

web访问成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值