kubectl for CKAD - exercise 9 - expose a pod with NodePort service, delete lines in Vim
Previous: kubectl for CKAD - exercise 8 - use bash exported variables in Vim 2
First things first
Put your mouse away, forget you have a touchpad and keep your hands on the keyboard.
In this exercise we will learn how to create a NodePort service with kubectl expose.
Also - we will learn to delete unwanted lines in a yaml file, which is a very important skill for the CKAD and other CK* exams.
For resources which can not be created with kubectl we must copy yaml definitions from kubernetes.io. We will have to delete unwanted lines in Vim - and, you guessed it - we need to be fast and effective deleting them.
Scenario
Expose a running pod nginxpod on a node through a NodePort service named nginx-service on port 30100. Let’s look at how using different --dry-run modes affects the generated YAML.
Run a pod
Run an nginxpod using the kubectl command with port 80 specified.
kubectl run nginxpod --image=nginx:alpine --port=80
Create a NodePort service for the nginxpod,using kubectl expose with --dry-run=client
k expose pod nginxpod --name=nginx-service --type=NodePort --port=80 --dry-run=client -o yaml | vim -
As you can see, thenodePort field in this yaml definition is missing
...
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
...
To include the nodePort field, let kubectl create it for you with --dry-run=server
k expose pod nginxpod --name=nginx-service --type=NodePort --port=80 --dry-run=server -o yaml | vim -
Observe that --dry-run=server creates the nodePort field and populates it with a random port number:
...
spec:
ports:
- nodePort: 34567
port: 80
protocol: TCP
targetPort: 80
...
Replace the autoassigned port with the specified one: 30100.
/34567 # start searching from top, replace 34567 with the generated number you see in your nodePort:
Enter
C # 'C'lear (delete) everything from the cursor to the end of this line and start writing
30100
ESC # 'ESC'ape from INSERT mode
:w nginx-service.yaml # Save the YAML definition
There is one more little problem, let us apply the yaml to see it.
Apply the yaml - without leaving Vim!
:!kubectl apply -f % # Run `kubectl apply` directly from inside Vim
If you have already set up the bash variable / shortcut ka in the previous exercise, use it like this:
:!$ka -f %
It throws an error:
The Service "nginx-service" is invalid: spec.clusterIPs: Invalid value: ...
shell returned 1
Press ENTER or type command to continue
The error tells us that by using --dry-run=server -o yaml we created some unwanted lines - the perfect opportunity to learn deleting lines in Vim.
For fast navigation, set Vim up to show line numbers and relative line numbers
:set nu # show 'nu'mbers
:set rnu # show 'r'elative 'nu'mbers
Or do it in one line
:set nu rnu
Line 1 is the one with the cursor so it shows the real line number, all others are relative line numbers, which we will use to make our navigation in Vim fast and effective!
1 apiVersion: v1
1 kind: Service
2 metadata:
3 creationTimestamp: "2025-01-14T18:27:29Z"
4 labels:
5 run: nginxpod
6 name: nginx-service
7 namespace: default
8 uid: 0d175654-b5d4-4306-85c3-924c6f64e62f
9 spec:
10 clusterIP: 10.96.0.0
11 clusterIPs:
12 - 10.96.0.0
13 externalTrafficPolicy: Cluster
14 internalTrafficPolicy: Cluster
15 ipFamilies:
16 - IPv4
17 ipFamilyPolicy: SingleStack
18 ports:
19 - nodePort: 32769
20 port: 80
21 protocol: TCP
22 targetPort: 80
...
We need to delete lines from10 clusterIP: 10.96.0.0 down to (including) 17 ipFamilyPolicy: SingleStack
10 lines jumpdown, to the first line we want to delete
10j # 10 lines 'j'umpdown
We landed on the line with the real number 11, the first line we want to delete:
10 apiVersion: v1
9 kind: Service
8 metadata:
7 creationTimestamp: "2025-01-14T18:27:29Z"
6 labels:
5 run: nginxpod
4 name: nginx-service
3 namespace: default
2 uid: 0d175654-b5d4-4306-85c3-924c6f64e62f
1 spec:
11 clusterIP: 10.96.0.0
1 clusterIPs:
2 - 10.96.0.0
3 externalTrafficPolicy: Cluster
4 internalTrafficPolicy: Cluster
5 ipFamilies:
6 - IPv4
7 ipFamilyPolicy: SingleStack
8 ports:
9 - nodePort: 32769
10 port: 80
11 protocol: TCP
12 targetPort: 80
Delete 7 lines jumping down, including the current line
d7j # 'd'elete 7 lines 'j'umping down
The unwanted lines should now be gone:
10 apiVersion: v1
9 kind: Service
8 metadata:
7 creationTimestamp: "2025-01-14T18:27:29Z"
6 labels:
5 run: nginxpod
4 name: nginx-service
3 namespace: default
2 uid: 0d175654-b5d4-4306-85c3-924c6f64e62f
1 spec:
11 ports:
1 - nodePort: 32769
2 port: 80
3 protocol: TCP
4 targetPort: 80
...
With the unwanted lines deleted we can now apply the service yaml.
Save and apply the yaml - again - without leaving Vim!
ESC # 'ESC'ape from INSERT mode
:w nginx-service.yaml # Save the YAML definition
:!kubectl apply -f % # Run `kubectl apply` directly from inside Vim
If you have already set up the bash variable / shortcut ka in the previous exercises use it like this:
ESC # 'ESC'ape from INSERT mode
:w nginx-service.yaml # Save the YAML definition
:!$ka -f % # Run `kubectl apply` directly from inside Vim
If everything is fine with the yaml definition, nginx-service.yaml gets applied, service is created.
k get svc -o wide # view the service, -o wide shows more info about resources
Don’t forget to define a shortcut for --dry-run=server -o yaml in your .bashrc:
vim ~/.bashrc
G # Go to the last line
i # Switch to INSERT mode
export drys='--dry-run=server -o yaml' # use your own shortcut, if you don't like 'drys'
write (save), quit, source (reload) the .bashrc
ESC
:wq
source ~/.bashrc
Congratulations!
You have learned how to use --dry-run=server to expose a pod with a NodePort service and how to delete unwanted lines in YAML definitions using fast navigation by line numbers. Practice, practice, practice…
Next: kubectl for CKAD - exercise 10 - copy from browser, paste into Vim, indent