c2sr bootcamp docs Help

SunSpec Client Deployment Task

This is the final tutorial in the deployment sequence. Your goal is to deploy the sunspec-client application, which serves two purposes: it reads data from the inverter's Modbus port to verify the end-to-end data flow, and it exposes a web dashboard so you can visualize the data in real-time.

This task will teach you how to deploy a client application that connects to another service using its external NodePort address and how to expose a web UI from a Kubernetes deployment.

In this tutorial, you will be tasked to:

  • Deploy a client application that runs on a specific node (agx).

  • Configure the client with the IP address and NodePort of the inverter service.

  • Create a NodePort service to expose the client's web dashboard.

  • Access the web dashboard in your browser to confirm the entire pipeline is working.

Before you start

Make sure that:

  • All previous components (Zookeeper, Kafka, Streamer, and Inverter) are deployed and running successfully.

  • You are SSHed into the k3smain node and have switched to the shared user account.

Part 1: Create the SunSpec Client Deployment Manifest

Your first goal is to create the deployment file sunspec-client-deployment.yaml.

Deployment Requirements

The SunSpec Client instance must be configured with the following specifications:

  1. Deployment Name: The deployment must be named sunsclient.

  2. Node Affinity: The pod must be scheduled to run on the node named agx.

  3. Container Image: Use the ghcr.io/decsresearch/c2sr-bootcamp-sunspec-client:latest image.

  4. Image Pull Secret: Reference the ghcr-pull-secret.

  5. Environment Configuration: This configuration is critical for connecting to the inverter.

    • KAFKA_HOST and KAFKA_PORT: Set to kafka-service and 9092 respectively.

    • NODE_NAME: A logical name for the client, set to agx.

    • INVERTER_IP: The IP address of the nano node where the inverter is running. You will need to find this IP address and hardcode it.

    • NODE_IP: Dynamically set to the IP of the host node (agx) where this pod is running.

    • agx: A mapping variable, set to nano.

    • INVERTER_PORT: The port to connect to. This must be the NodePort of the inverter service, which is 30502.

Skeleton File for Deployment

Create a file named sunspec-client-deployment.yaml and fill it out according to the requirements.

# sunspec-client-deployment.yaml --- apiVersion: apps/v1 kind: Deployment metadata: # Requirement 1: Specify the deployment name name: <Your-Deployment-Name> spec: replicas: 1 selector: matchLabels: app: sunsclient template: metadata: labels: app: sunsclient spec: containers: - name: sunsclient # Requirement 3: Specify the container image image: <Your-Image-Path> # Requirement 5: Add all 7 required environment variables env: - name: KAFKA_HOST value: <Value> - name: KAFKA_PORT value: <Value> - name: NODE_NAME value: <Value> - name: INVERTER_IP value: <IP address of the nano node> - name: NODE_IP valueFrom: fieldRef: fieldPath: <Path-To-Host-IP> - name: agx value: <Value> - name: INVERTER_PORT value: <Inverter-NodePort> # Requirement 4: Add the image pull secret imagePullSecrets: - name: <Your-Secret-Name> # Requirement 2: Add the correct node selector for the 'agx' node nodeSelector: kubernetes.io/hostname: <Your-Node-Name>

Part 2: Expose the Client's Dashboard with a Service

To view the data being read by the client, you need to expose its web dashboard.

Service Requirements

The Service must:

  1. Have the name sunsclient-dashboard-service.

  2. Be of type NodePort.

  3. Expose the dashboard's TCP port 8050 and map it to a static nodePort of 30080.

  4. Use a selector to correctly identify the SunSpec client pod (app: sunsclient).

Skeleton File for Service

Create a second file named sunspec-client-service.yaml and complete the skeleton below.

# sunspec-client-service.yaml apiVersion: v1 kind: Service metadata: # Requirement 1: Specify the service name name: <Your-Service-Name> spec: # Requirement 2: Set the service type type: <Your-Service-Type> selector: # Requirement 4: Add the correct selector app: <Your-App-Label> ports: # Requirement 3: Define protocol, port, targetPort, and nodePort - protocol: <Protocol> port: <Service-Port> targetPort: <Pod-Port> nodePort: <Your-Node-Port>

Part 3: Final Verification

Once both YAML files are created, apply them and perform the final check by accessing the web dashboard.

  1. Apply the manifests: kubectl apply -f sunspec-client-deployment.yaml kubectl apply -f sunspec-client-service.yaml

  2. Verify the deployment: kubectl get pods -l app=sunsclient -o wide (Confirm it is running on the agx node).

  3. Check the logs: The logs should indicate a successful connection to the inverter. kubectl logs -f <pod name>

  4. Access the Dashboard: Open a web browser and navigate to the IP address of the agx node on port 30080. URL: http://<IP-of-agx-node>:30080

If you can see the dashboard and it is displaying changing data, you have successfully deployed the entire pipeline!

Solutions

# sunspec-client-deployment.yaml --- apiVersion: apps/v1 kind: Deployment metadata: name: sunsclient spec: replicas: 1 selector: matchLabels: app: sunsclient template: metadata: labels: app: sunsclient spec: containers: - name: sunsclient image: ghcr.io/decsresearch/c2sr-bootcamp-sunspec-client:latest env: - name: KAFKA_HOST value: "kafka-service" - name: KAFKA_PORT value: "9092" - name: NODE_NAME value: agx - name: INVERTER_IP value: <nano ip address> - name: NODE_IP valueFrom: fieldRef: fieldPath: status.hostIP - name: agx value: "nano" - name: INVERTER_PORT value: "30502" imagePullSecrets: - name: ghcr-pull-secret nodeSelector: kubernetes.io/hostname: agx
# sunspec-client-service apiVersion: v1 kind: Service metadata: name: sunsclient-dashboard-service spec: type: NodePort selector: app: sunsclient ports: - protocol: TCP port: 8050 targetPort: 8050 nodePort: 30080
Last modified: 22 June 2025