关于 TKE 容器网络插件

创建 TKE 时有三种容器网络插件可供选择[1]

  1. GlobalRouter 模式
  2. VPC-CNI 模式
  3. Cilium-Overlay 模式

Cilium-Overlay 模式只有在混用云上节点和第三方节点时才会用到,所以当时就在 GlobalRouter 模式和 VPC-CNI 模式之间做选择。最终由于 VPC-CNI 模式的网络性能较高,选择了这个模式。

之后用了近两年,一直没有出现什么问题,最近在调整节点规格时才发现新加的服务器仍然有很多资源,但是 Deployment 部署不过去。容器事件中显示了 Insufficient tke.cloud.tencent.com/eni-ip. 错误消息。这才注意到每个节点上都有一个 ENI-IP 的资源限制,可以在 Worker 节点页面看到类似 ENI-IP : 27 / 27 这样的数值。

TKE:记一次由于看不到的 Pod 导致 PVC 无法删除的调查

删除测试环境的一个 PVC( pvc-mmdz-webfont )时,状态一直显示为 “ 已于 2023-05-05 15:48:38 标记删除,待绑定的 Pod 删除后删除。 ” 。但奇怪的是使用这个 PVC 的 Pod 早就关掉了,在 TKE 的门户页面上对应的 Deployment 下也已经没有任何 Pod 了。

TKE Node.js 服务接入应用性能监测 SkyWalking

接入步骤

  1. 获取接入点和 Token

    通过腾讯云的应用性能观测页面的接入应用按钮,可以查看 SkyWalking 的接入点和 Token。

  2. 使用 npm 安装 skywalking-backend-js

    npm i skywalking-backend-js
    
  3. 数据上报

    在入口文件引入 SDK, 通过 start 方法执行数据上报。

    下面的示例使用环境变量的方式获取具体的配置参数,在 TKE 中配置环境变量的方式可参考之前 SpringBoot 服务接入 APM 的博客

    const {default: agent} = require('skywalking-backend-js');
    agent.start({
        // 服务名
        serviceName: `${process.env.SW_AGENT_NAME}|${process.env.SW_AGENT_NAMESPACE}|${process.env.SW_AGENT_CLUSTER}`,
        // 服务实例名
        serviceInstance: `${process.env.SW_AGENT_NAME}|${currentPodIp}`,
        // APM 上报路径 (来自第一步)
        collectorAddress: process.env.SW_AGENT_COLLECTOR_BACKEND_SERVICES,
        // Token (来自第一步)
        authorization: process.env.SW_AGENT_AUTHENTICATION,
    });
    
TKE SpringBoot 接入应用性能观测 SkyWalking

接入步骤

  1. 应用性能观测中新建应用。

  2. 点击新创建的应用,点击【接入应用】,选择 Skywalking + 内网上报

  3. 点击下一步会看到应用的 接入点 和 Token,这两个值在部署时会用到。

  4. 创建带 Java Agent 的基础镜像。

    • 下载 Skywalking Jave Agent

      这两个地址都可以,下载自己需要的版本,这里用的是 8.13.0

      • https://skywalking.apache.org/downloads/#Agents
      • https://archive.apache.org/dist/skywalking/java-agent/
    • 构建带 Agent 的基础镜像

      • 创建 Dockerfile

        这里使用单独的镜像解压文件,然后再复制解压的文件到 jre 的镜像。

        FROM busybox:1.33 AS unzip
        
        WORKDIR /sw
        COPY apache-skywalking-java-agent-8.13.0.tgz /sw/apache-skywalking-java-agent-8.13.0.tgz
        RUN /bin/busybox tar -xzvf apache-skywalking-java-agent-8.13.0.tgz
        
        FROM openjdk:8u201-jre-alpine
        COPY --from=unzip /sw/skywalking-agent /sw/agent
        
      • 构建镜像

        docker build java-8-skywalking-agent:8.13.0 .
        
      • 可以使用 docker logindocker tagdocker push 命令推送镜像到私有仓库

  5. 构建服务镜像

    修改 Java 服务 Dockerfile:

    • 修改基础镜像为上一步构建的镜像

    • 在启动命令中添加 -javaagent 参数

    FROM java-8-skywalking-agent:8.13.0
    
    COPY target/*.jar app.jar
    
    ENTRYPOINT exec java -javaagent:/sw/agent/skywalking-agent.jar -jar /app.jar
    
  6. 修改服务部署清单

    由于使用环境变量的方式配置 agent,需要在部署清单文件中配置环境变量。

    另外,为了统一管理,这里将通用的配置项保存在了 ConfigMap 中。

    • ConfigMap

      apiVersion: v1
      data:
        sw.agent.authentication: 接入应用页面提供的 Token
        sw.agent.backend_service: 接入应用页面提供的接入点
        sw.agent.cluster: my-cluster
        sw.agent.namespace: my-namespace
      kind: ConfigMap
      metadata:
        name: my-config
        namespace: test
      
    • 在部署清单中配置环境变量

      这里共设置了 5 个环境:

      • SW_AGENT_NAME :当前服务的名字
      • SW_AGENT_NAMESPACE :命名空间
      • SW_AGENT_CLUSTER :集群
      • SW_AGENT_COLLECTOR_BACKEND_SERVICES :接入点
      • SW_AGENT_AUTHENTICATION : Token

      其中,命名空间和集群不是必须的,如果设置了,服务名称会变成 {SW_AGENT_NAME}|{SW_AGENT_NAMESPACE}|{SW_AGENT_CLUSTER} 的样式。

      其它的环境变量可以参考 skywalking-agent/config 目录中的 agent.config 文件。

      spec:
        template:
          spec:
            containers:
              - env:
                  - name: SW_AGENT_NAME
                    value: my-app-name
                  - name: SW_AGENT_NAMESPACE
                    valueFrom:
                      configMapKeyRef:
                        key: sw.agent.namespace
                        name: my-config
                  - name: SW_AGENT_CLUSTER
                    valueFrom:
                      configMapKeyRef:
                        key: sw.agent.cluster
                        name: my-config
                  - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
                    valueFrom:
                      configMapKeyRef:
                        key: sw.agent.backend_service
                        name: my-config
                  - name: SW_AGENT_AUTHENTICATION
                    valueFrom:
                      configMapKeyRef:
                        key: sw.agent.authentication
                        name: my-config
      
  7. 重新应用清单就可以在【应用列表】中看到接入的应用了。

TKE Nginx Ingress Controller 路径跳转

通过腾讯云容器服务 TKE 创建的 Nginx Ingress Controller 类型的 Ingresspath 指定为默认的 / 时可以正常访问站点,指定了二级路径时则无法访问。

此时清单文件大概如下:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx-ingress-test
    kubernetes.io/ingress.rule-mix: "true"
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: svc-test
          servicePort: 80
        path: /test/
        pathType: ImplementationSpecific
腾讯云 Nginx Ingress 启用 gzip

修改 kube-system 命名空间下名为 {nginx-ingress-name}-ingress-nginx-controllerConfigMap ,在其中添加如下配置:

data:
  use-gzip: "true"
Nginx Ingress Controller x WebSocket

关于在 K8S 中通过 Nginx Ingress Controller 暴露 WebSocket 服务的方法,查到两篇官方文档,说法并不一致。

  1. Miscellaneous #Websockets

    Support for websockets is provided by NGINX out of the box. No special configuration required.

    这里说是不需要额外配置即可以支持 WebSocket。

    另外还建议增加 proxy-read-timeoutproxy-send-timeout 的值。这两个默认都是 60 秒,建议改成大于 3600 秒。

  2. nginxinc / kubernetes-ingress - WebSocket support

    To load balance a WebSocket application with NGINX Ingress controllers, you need to add the nginx.org/websocket-services annotation to your Ingress resource definition. The annotation specifies which services are websocket services. The annotation syntax is as follows:

    nginx.org/websocket-services: "service1[,service2,...]"
    

    这里是说需要添加 nginx.org/websocket-services 注解,另外还提供了一个完整的示例