MaruOpsInfrastructure and AI notes

About (Korean)Contact (Korean)

[Kubernetes Lab 06] Service DNS and Access from Windows

Small network switch with two cables connected

Reference photo · Small network switch with two cables connected · Photo: Simon A. Eugster / Source / CC BY-SA 3.0 · Resized for listings; illustrative photo, not the tested environment

Full series guide · Practice file ZIP

Windows 11 · VMware · Rocky Linux Kubernetes serial 06/10

A Service gives clients a stable way to reach the web application as its Pods are replaced. Trace the Windows request through the published node port and Service to a ready Pod. The example follows Windows → 노드:30080 → Service → 준비된 Pod:8080.

1. Service selector and port

Save it as web-service.yaml in ~/k8s-lab/app of cp01. Check that the Service selector and the previously created Pod label are the same, app: web.

apiVersion: v1
kind: Service
metadata:
  name: web
  namespace: lab
spec:
  type: NodePort
  selector:
    app: web
  ports:
    - name: http
      port: 80
      targetPort: http
      nodePort: 30080
kubectl apply -f web-service.yaml
kubectl -n lab get service web
kubectl -n lab get endpointslice -l kubernetes.io/service-name=web -o wide

Let’s divide port: 80 of Service, targetPort: http pointing to the named port of Pod, and nodePort: 30080 of Node. The Pod port pointed to by targetPort is 8080. If you only declare containerPort, the service or host port will not be opened automatically.

2. Connect from Windows·Pod

Test-NetConnection 192.168.80.11 -Port 30080
curl.exe http://192.168.80.11:30080/

Open http://192.168.80.11:30080/ in Windows to check the default page. This is a path to directly access the node using the VMnet8 adapter. In the default NodePort behavior, requests coming to wk01 can also be forwarded to Pods on other prepared workers. The node, network, and delivery destination must all be normal.

kubectl -n lab run netcheck --image=busybox:1.37.0 \
  --restart=Never --command -- sleep 3600
kubectl -n lab wait --for=condition=Ready pod/netcheck --timeout=120s
kubectl -n lab exec netcheck -- nslookup web.lab.svc.cluster.local
kubectl -n lab exec netcheck -- wget -qO- http://web.lab.svc.cluster.local/

A Pod’s DNS query goes through CoreDNS and usually obtains the Service’s ClusterIP. If you think of ClusterIP as a regular IP of a physical NIC, the path can be confusing. In this iptables mode, kernel rules and connection tracking created by kube-proxy handle forwarding. Because the same TCP connection may remain on the same backend, there is no guarantee that the two Pods will respond strictly alternately for each request.

3. ConfigMap Volume

cd ~/k8s-lab/app
cat > index.html <<'EOF'
<!doctype html>
<html lang="ko"><meta charset="utf-8">
<title>MaruOps Kubernetes Lab</title>
<h1>Windows에서 Kubernetes Pod까지 연결됐습니다.</h1>
<p>이 페이지는 ConfigMap 볼륨에서 읽습니다.</p></html>
EOF
kubectl -n lab create configmap web-content --from-file=index.html \
  --dry-run=client -o yaml > web-configmap.yaml
kubectl apply -f web-configmap.yaml

Merge the following fragment into the existing web-deployment.yaml. Add volumes under spec.template.spec at the same depth as containers, and volumeMounts inside the nginx container. Do not apply this fragment as a standalone resource.

# spec.template.spec 아래
volumes:
  - name: web-content
    configMap:
      name: web-content
# nginx 컨테이너 항목 아래, resources와 같은 깊이
volumeMounts:
  - name: web-content
    mountPath: /usr/share/nginx/html
    readOnly: true
kubectl apply --dry-run=server -f web-deployment.yaml
kubectl apply -f web-deployment.yaml
kubectl -n lab rollout status deployment/web --timeout=180s
kubectl -n lab exec netcheck -- wget -qO- http://web/

If you change the ConfigMap, run the create/apply command again. Updating directory mounts may take kubelet synchronization time. The subPath mount cannot expect the same automatic update, and environment variables are not injected into the running process. Depending on when the app reads the file, it also determines whether a restart is necessary.

4. Secret’s scope of protection

General settings are classified into ConfigMap, and credentials to restrict access are classified into Secret. Secret’s base64 is not encryption, so RBAC and etcd storage encryption and backup permissions are also required. The examples do not use actual passwords. If you mount the Secret in NGINX’s HTML directory, it may be exposed on the web, so do not place it there.

5. Check failures by request path

symptomsWhat to see next
Node IP works on WindowsVMnet8 connection·Windows path·Guest IP
NodePort connection failureService type/port conflict/host path
Service exists but no responseDoes EndpointSlice have a prepared address?
It works with Pod IP, but not with Service.kube-proxy · Rule · Service port
The IP is working, but the name is not working.CoreDNS·Pod resolv.conf·DNS communication
kubectl -n lab get pods --show-labels
kubectl -n lab describe service web
kubectl -n lab get endpointslice -l kubernetes.io/service-name=web -o yaml
kubectl -n lab delete pod netcheck

ConfigMap is used to pass settings to be deployed. The role of the volume is to store data written by the user. In the next article, we’ll cover configuring to read the same file even after recreating the Pod.

reference material

official documents and distribution files confirmed: October 18, 2026. The output is an example to determine completion and may vary depending on the environment.


← Part 05 · 07 →

Expand the table of contents for all 10 episodes

Full series guide and practice standards