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