Skip to content

LoadBalancer service doesn't expose the TCP port #224

@jefferson-lima

Description

@jefferson-lima

I want to expose the DNS server through both TCP and UDP ports, so I configured my values.yml with the use_tcp: true option:

  zones:
  - use_tcp: true
    zone: .

I can see that the pod exposes both protocols:

kubectl describe pod coredns-5cf978495c-5rzlz -n coredns
Name:             coredns-5cf978495c-5rzlz
Namespace:        coredns
Priority:         0
Service Account:  default
Node:             localhost/192.168.0.51
Start Time:       Mon, 04 Aug 2025 15:21:05 +0100
Labels:           app.kubernetes.io/instance=coredns
                  app.kubernetes.io/name=coredns
                  pod-template-hash=5cf978495c
Annotations:      checksum/config: ddd0a44f1bc90169194431d4d47855800b203fea991373c980c4184dda6de01d
Status:           Running
IP:               10.42.0.47
IPs:
  IP:           10.42.0.47
Controlled By:  ReplicaSet/coredns-5cf978495c
Containers:
  coredns:
    Container ID:  containerd://33b41813ac4428e3a1ad9fb9d87e2fb106191fdeb4aad955847bc654ed8ced90
    Image:         coredns/coredns:1.12.0
    Image ID:      docker.io/coredns/coredns@sha256:40384aa1f5ea6bfdc77997d243aec73da05f27aed0c5e9d65bfa98933c519d97
    Ports:         53/UDP, 53/TCP
    Host Ports:    0/UDP, 0/TCP
    Args:
      -conf
      /etc/coredns/Corefile
    State:          Running
      Started:      Mon, 04 Aug 2025 15:21:07 +0100
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     100m
      memory:  128Mi
    Requests:
      cpu:        100m
      memory:     128Mi
    Liveness:     http-get http://:8080/health delay=60s timeout=5s period=10s #success=1 #failure=5
    Readiness:    http-get http://:8181/ready delay=30s timeout=5s period=5s #success=1 #failure=1
    Environment:  <none>
    Mounts:
      /etc/coredns from config-volume (rw)
      /opt/coredns/config from coredns-zone (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mcxb7 (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  config-volume:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      coredns
    Optional:  false
  coredns-zone:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      coredns-zone
    Optional:  false
  kube-api-access-mcxb7:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    Optional:                false
    DownwardAPI:             true
QoS Class:                   Guaranteed
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  9m1s   default-scheduler  Successfully assigned coredns/coredns-5cf978495c-5rzlz to localhost
  Normal  Pulled     8m59s  kubelet            Container image "coredns/coredns:1.12.0" already present on machine
  Normal  Created    8m59s  kubelet            Created container: coredns
  Normal  Started    8m59s  kubelet            Started container coredns

But the service only exposes the UDP port:

kubectl get services -n coredns
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
coredns   LoadBalancer   10.43.152.91   192.168.0.54   53:30422/UDP   8m35s

If I manually edit the service to expose the TCP port by adding this to the service definition:

  ports:
    - name: udp-53
      protocol: UDP
      port: 53
      targetPort: 53
      nodePort: 30422

It works as expected.


Full Helm release:

affinity: {}
autoscaler:
  affinity: {}
  configmap:
    annotations: {}
  coresPerReplica: 256
  enabled: false
  extraContainers: []
  image:
    pullPolicy: IfNotPresent
    pullSecrets: []
    repository: registry.k8s.io/cpa/cluster-proportional-autoscaler
    tag: v1.9.0
  includeUnschedulableNodes: false
  livenessProbe:
    enabled: true
    failureThreshold: 3
    initialDelaySeconds: 10
    periodSeconds: 5
    successThreshold: 1
    timeoutSeconds: 5
  max: 0
  min: 0
  nodeSelector: {}
  nodesPerReplica: 16
  podAnnotations: {}
  preventSinglePointFailure: true
  priorityClassName: ""
  resources:
    limits:
      cpu: 20m
      memory: 10Mi
    requests:
      cpu: 20m
      memory: 10Mi
  tolerations: []
clusterRole:
  nameOverride: ""
customAnnotations: {}
customLabels: {}
deployment:
  annotations: {}
  enabled: true
  name: ""
  selector: {}
  skipConfig: false
env: []
extraConfig: {}
extraContainers: []
extraSecrets: []
extraVolumeMounts:
- mountPath: /opt/coredns/config
  name: coredns-zone
extraVolumes:
- configMap:
    items:
    - key: coredns.zone
      path: coredns-zone
    name: coredns-zone
  name: coredns-zone
hpa:
  enabled: false
  maxReplicas: 2
  metrics: []
  minReplicas: 1
image:
  pullPolicy: IfNotPresent
  pullSecrets: []
  repository: coredns/coredns
  tag: ""
isClusterService: false
livenessProbe:
  enabled: true
  failureThreshold: 5
  initialDelaySeconds: 60
  periodSeconds: 10
  successThreshold: 1
  timeoutSeconds: 5
nodeSelector: {}
podAnnotations: {}
podDisruptionBudget: {}
podSecurityContext: {}
priorityClassName: ""
prometheus:
  monitor:
    additionalLabels: {}
    enabled: false
    interval: ""
    namespace: ""
    selector: {}
  service:
    annotations:
      prometheus.io/port: "9153"
      prometheus.io/scrape: "true"
    enabled: false
    selector: {}
rbac:
  create: true
readinessProbe:
  enabled: true
  failureThreshold: 1
  initialDelaySeconds: 30
  periodSeconds: 5
  successThreshold: 1
  timeoutSeconds: 5
replicaCount: 1
resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 100m
    memory: 128Mi
rollingUpdate:
  maxSurge: 25%
  maxUnavailable: 1
securityContext:
  allowPrivilegeEscalation: false
  capabilities:
    add:
    - NET_BIND_SERVICE
    drop:
    - ALL
  readOnlyRootFilesystem: true
servers:
- plugins:
  - name: health
  - name: ready
  - name: errors
  - name: log
  - name: file
    parameters: /opt/coredns/config/coredns-zone sub.domain.com
  - name: forward
    parameters: . 8.8.8.8
  port: 53
  zones:
  - use_tcp: true
    zone: .
service:
  annotations: {}
  loadBalancerIP: 192.168.0.54
  name: ""
  selector: {}
serviceAccount:
  annotations: {}
  create: false
  name: ""
serviceType: LoadBalancer
terminationGracePeriodSeconds: 30
tolerations: []
topologySpreadConstraints: []
zoneFiles: []

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions