Every file and directory has two pieces of ownership information. The file owner refers to a user on the machine. Each file may only have one owner at a time, however ownership may be transferred.
Files and directories also belong to a group. Groups are a construct handled by the operating system and used to define permissions across multiple users. Each group may have more than one user, and each user may belong to multiple groups. A user can check their group membership with the groups command.
$ groups
myuser wheel libvirt
The owner and group information is displayed in the long listing as described above.
$ ls -l
drwxr-xr-x. 2 myuser myuser 40 May 19 10:52 existing-dir
-rw-r--r--. 1 myuser myuser 12 May 19 10:52 my-file
In that output, the first instance of myuser refers to the owner and the second is the group.
Note: Many distributions will automatically create an specific group for each user, typically with the same name.
Each file and directory has a specified set of permissions associated with it. These permissions drive who can read, write to, and execute files.
There are three different levels of access:
  • read - indicates if the file or directory contents may be displayed
  • write - indicates if a file's contents may be changed, or if files may be created/deleted in a directory
  • execute - indicates if the file can be run (for executable files), or if a directory may be entered (using cd)
Access to a file or directory is granted at three different granularity:
  • file owner
  • members of the file's group
  • all other users that don't fit into the above two categories
Putting these together, there are 9 different permission settings that exist on every file: read, write, execute for each of owner, group, and other.
File permissions are displayed in the long output of the list command.
$ ls -l
drwxr-xr-x. 2 myuser myuser 40 May 19 10:52 existing-dir
-rw-r--r--. 1 myuser myuser 12 May 19 10:52 my-file
The first column (except for the first character, which is a flag indicating if it is a file or a directory) contains all 9 of these permissions. It can be broken down into three tuples:
User Owner Other
rwx r-x r-x
In each tuple, the specific permissions for that set of users is specified as a single character in the order: Read, Write, eXecute. If the letter is present, the permission is granted. A - will be indicated in the permission slot if it is not granted to those users.
Translating the example above, the file's owner has the ability to read, write, and execute the file (which is common for the owner). Other users in the same group may read and execute the file, but not make any changes to it. Similarly, all other users have the same permissions.
Permissions are changed through the chmod command. The arguments to this command (besides the name of the file itself) carry three pieces of information:
  • the users to which the permission change applies (user, group, or other)
  • plus or minus, depending on if the access is being granted or removed respectively
  • the ability itself (read, write, or execute)

Each of those pieces of information is abbreviated to a single character:

user u
group p
other o
read r
write w
execute x


For example, the following command grants write permissions to the file's group:
$ chmod g+w my-file
$ ls -l my-file
-rw-rw-r--. 1 jdob jdob 12 May 19 10:52 my-file
This is obviously a very high level view of permissions and other sources should be consulted for a more thorough discussion. For the purposes of this site, the most relevant thing to keep in mind is that these permissions should be taken into account when building images. For example, the command that's run when a container is started must have execute permissions. More details can be found in the image building lessons themselves.

Viewing File Contents

The contents of a file can be displayed using the cat command.
$ cat my-file
Hello KubernetesByExample

The cat command outputs the entire file. For longer files, consider using either the more or less commands instead. The former, more, pauses output that exceeds the length of the terminal. Pressing the "Enter" key will scroll the output one line at a time, while the spacebar scrolls by pages.

A newer version of the more command, named less, is available on most systems. The biggest difference is that the arrow keys allow for scrolling downward and upward, unlike its predecessor which only allows scrolling in one direction.

Another common use of more and less is when output is piped into them. Piping a command's output is the act of passing its output into the input of another command through the use of the | operator. Generally speaking, the syntax to pass the output of command_1 into command_2 as input is:
command_1 | command_2

For example, the command kubectl logs will display the logging output of a running pod. This output may be long, so it is common to pipe that output into less to enable pagination through the contents.

kubectl logs my-pod | less
There are times when simply scrolling through a file's contents isn't enough. One extremely useful tool for lightweight text processing is awk. AWK can do a variety of functions and its full capabilities are well beyond the scope of this lesson.
However, it is worthwhile to look at a few examples of where AWK comes in handy in conjunction with the Kubernetes CLI. Below is the output when viewing the list of pods (kubectl get pods).
my-pod-1 1/1 Running 0 9s
my-pod-2 0/1 Pending 0 9s
The awk command is well suited to parsing columns, which are numbered starting at 1. Arguments may be passed to AWK to control which of these columns are outputted, which can be used to only display the pod names.
$ kubectl get pods | awk '{ print $1 }'
AWK isn't limited to simply displaying a single column. Multiple may be used, along with other text as well.
$ kubectl get pods | awk '{ print $1 " is " $3 }'
my-pod-1 is Running
my-pod-2 is Pending
AWK implicitly assigns line numbers to each result (starting with 1), which can be used to control which rows are displayed. Line number controls are invoked using the NR flag. For example, the following will display all lines after the first (effectivey removing the header output from the kubectl command):
$ kubectl get pods | awk 'NR>1 { print $1 " is " $3 }'
my-pod-1 is Running
my-pod-2 is Pending

Another valuable tool for working with text is grep. This command provides pattern matching for each line it sees. A pattern is passed to grep which will be matched against the input; if a row matches the pattern, it is then output.

Using the above pod example, the following command will only display rows that contain the text "Running":

$ kubectl get pods | grep Running
my-pod-1 1/1 Running 0 9s
Both awk and grep are tremendously powerful and customizable tools for working with text from the command line. This lesson simply scratched the surface of what can be accomplished.