OnCallReady

Lesson 30.2 · OpenShift · 23 min read

The oc CLI and logging in

In plain words

Imagine a Swiss army knife that already includes your favourite screwdriver. Everything you did with the screwdriver still works exactly the same, but now there are extra tools folded in: a key to open the building, a badge that proves who you are, a button to switch rooms.

oc is that knife: it contains kubectl, plus OpenShift commands. oc login exchanges your username and password with the cluster's OAuth server (its built-in login service) for a token starting with sha256~ and writes it into ~/.kube/config; oc whoami shows who you are, oc project switches rooms. The token is a bearer token: whoever holds it is you until it expires, so oc logout revokes it on the server.

Why logging in is a topic

On the kubeadm lab you never "logged in": the kubeconfig held an admin certificate (15.1). On OpenShift every person logs in with their own name, gets a token that expires, and RBAC decides what they may do. When "oc does not work", nine times out of ten it is the login: wrong server, expired token, wrong context.

What you need to know already: kubeconfig - clusters, users, contexts (15.1); RBAC and kubectl auth can-i (17.30, 17.35); ServiceAccount tokens (17.33); TLS certificates and CAs (9.15); HTTP status codes 401 and 403 (9.21); the OAuth server and oc from 30.1.

oc = kubectl + OpenShift

oc contains kubectl. Literally: oc get, describe, logs, exec, apply, rollout, scale, set image, auth can-i, port-forward, debug are the kubectl code, with the same flags and the same output. On top it adds commands for the OpenShift APIs and the OpenShift way of working:

you want tokubectloc
log inedit a kubeconfig by handoc login
who am Ikubectl auth whoamioc whoami
switch namespacekubectl config set-context --current --namespace=xoc project x
create a namespacekubectl create ns x (needs cluster rights)oc new-project x (self-service)
shell in a podkubectl exec -it pod -- shoc rsh pod
deploy from source/imagewrite YAMLoc new-app
expose over HTTPIngress YAMLoc expose svc/x (a Route)
node shellkubectl debug node/x -it --image=...oc debug node/x
cluster admin-oc adm ...

kubectl keeps working on OpenShift: oc login writes a standard kubeconfig and kubectl reads it. You will see teams use both; scripts written with kubectl run unchanged. (oc rsh = "remote shell": a shell inside the pod's container. oc adm = the admin sub-commands, most of which need cluster-wide rights. The others come later in this chapter.)

Logging in with a password

oc login <api-url> -u <user>: the argument is the address of the cluster's API server; -u is the username. -p <password> exists too, but then the password lands in your shell history (1.7), so leave it off and let oc ask.

# the lab cluster comes up with the next mission; you type these there
oc login https://api.ocp.lab:6443 -u developer
Authentication required for https://api.ocp.lab:6443 (openshift)
Username: developer
Password:
Login successful.

You don't have any projects. You can try to create a new project, by running

    oc new-project <projectname>

What happened: oc asked the API where its OAuth server is (/.well-known/oauth-authorization-server), sent your username and password to it, and got back an access token. It never stores the password. "You don't have any projects" is normal for a new user: a project is OpenShift's name for a namespace you are a member of (30.4).

A wrong password:

oc login https://api.ocp.lab:6443 -u developer -p wrong
Login failed (401 Unauthorized)
Verify you have provided the correct credentials.

A wrong host - the very first thing to check when "login does not work". connection refused means nothing listens on that port (9.1); no such host means DNS has no such name (8.16):

$ oc login https://api.ocp.lab:6444 -u developer
error: dial tcp 10.64.0.20:6444: connect: connection refused - verify you have provided the correct host and port and that the server is currently running.
$ oc login https://api.ocp.labs:6443 -u developer
error: dial tcp: lookup api.ocp.labs on 127.0.0.53:53: no such host - verify you have provided the correct host and port and that the server is currently running.

The API URL is always https://api.<cluster>.<base domain>:6443. The console (the web UI) lives at https://console-openshift-console.apps.<cluster>.<base domain> - a different host. Every name ending in .apps.<cluster>.<base domain> points at the router: that is the apps wildcard, a DNS record *.apps... that matches any name under it (30.13).

On clusters whose API certificate is signed by a CA your machine does not trust, the first login asks:

The server uses a certificate signed by an unknown authority.
You can bypass the certificate check, but any data you send to the server could be intercepted by others.
Use insecure connections? (y/n):

The right answer in a bank is n and --certificate-authority=ca.crt (a flag that tells oc which CA file to trust, 9.15) with the company CA. --insecure-skip-tls-verify works and prints WARNING: Using insecure TLS client config. Setting this option is not supported!. (simulator) The lab API's certificate is trusted by oncall-lab, so you are not asked.

Tokens

oc whoami prints who you are logged in as; -t prints your token instead:

oc whoami
developer
oc whoami -t
sha256~ZjM2YWNhMjZiOWYwYzMwMDZhMjY2N2RiNzQ5ZGI0Njk

OpenShift OAuth tokens start with sha256~. They are bearer tokens ("whoever bears it"): whoever has the string is you until it expires (24 hours by default, configurable). You can log in with one instead of a password - --token= gives the token, --server= the API URL. This is what the console's Copy login command gives you, and what CI pipelines used before they switched to ServiceAccount tokens (17.33):

oc login --token=sha256~ZjM2YWNhMjZiOWYwYzMwMDZhMjY2N2RiNzQ5ZGI0Njk --server=https://api.ocp.lab:6443
Logged into "https://api.ocp.lab:6443" as "developer" using the token provided.

You don't have any projects. You can try to create a new project, by running

    oc new-project <projectname>

An expired or revoked token:

oc login --token=sha256~old... --server=https://api.ocp.lab:6443
error: The token provided is invalid or expired.

and for any other command with a dead token in your kubeconfig:

oc get pods
error: You must be logged in to the server (Unauthorized)

That message is 401: the apiserver does not know who you are. Compare 403, Error from server (Forbidden): ... cannot list resource "pods": it knows who you are and says no. Different problems, different fixes (log in again vs ask for a RoleBinding).

What oc login wrote

Three more oc whoami flags answer "where am I?": --show-server (the API URL), --show-context (the kubeconfig context in use), --show-console (the web UI's URL). grep -A4 prints the matching line and the 4 after it (7.1):

oc whoami --show-server
https://api.ocp.lab:6443
oc whoami --show-context
/api-ocp-lab:6443/developer
oc whoami --show-console
https://console-openshift-console.apps.ocp.lab
grep -A4 'name: developer' ~/.kube/config
- name: developer/api-ocp-lab:6443
  user:
    token: sha256~ZjM2YWNhMjZiOWYwYzMwMDZhMjY2N2RiNzQ5ZGI0Njk

oc login added three entries to ~/.kube/config (and kept your kubeadm context):

The token sits in that file in clear text. Mode 600 matters; so does not copying your kubeconfig into a container image or a Git repo.

$ kubectl config get-contexts
CURRENT   NAME                                    CLUSTER            AUTHINFO                       NAMESPACE
          kubernetes-admin@kubernetes             kubernetes         kubernetes-admin
*         /api-ocp-lab:6443/developer             api-ocp-lab:6443   developer/api-ocp-lab:6443

kubectl config use-context kubernetes-admin@kubernetes takes you back to the kubeadm cluster; oc login again (or use-context the OpenShift one) takes you back.

kubeadmin and system:admin

Two identities are special:

The KUBECONFIG environment variable (1.7) tells oc and kubectl to read a different kubeconfig file than ~/.kube/config; unset goes back to the default:

export KUBECONFIG=~/oncall-lab/labs/4-ocp/auth/kubeconfig
oc whoami
system:admin
oc whoami -t
error: no token is currently in use for this session
unset KUBECONFIG

Logging out

oc logout
Logged "developer" out on "https://api.ocp.lab:6443"

oc logout deletes the token on the server (the OAuthAccessToken object) and from your kubeconfig. Anyone who copied it is locked out too. Just deleting the kubeconfig does not revoke anything.

Versions

$ oc version
Client Version: 4.21.25
Kustomize Version: v5.6.0
Server Version: 4.21.25
Kubernetes Version: v1.34.1

Keep the client within one minor of the cluster - the same skew rule as kubectl (18.15). The console's ? menu > Command line tools downloads the matching oc. (Kustomize, listed in the output, is the overlay tool from 26.2, built into oc and kubectl.)

What you can now do

Why it helps

Login problems are the first thing you debug on any new OpenShift cluster, and they come in distinct flavours: a 401 Unauthorized (bad password or expired token, log in again), a 403 Forbidden (you are known but lack a RoleBinding, ask for access), connection refused or no such host (wrong API URL, which is always https://api.<cluster>.<domain>:6443). Knowing which is which saves a ticket round-trip.

Tokens matter for security reviews and CI: a sha256~ token pasted into a pipeline variable or a kubeconfig baked into an image is a credential leak, and deleting the kubeconfig does not revoke it. And knowing that system:admin from the installer kubeconfig bypasses OAuth, making it the break-glass credential when the identity provider is down, is exactly the kind of answer senior interviewers want.

Commands in this lesson

oc kubectl

FAQ

What is the difference between 401 Unauthorized and 403 Forbidden?

401, shown as You must be logged in to the server (Unauthorized), means the API server does not know who you are: the token is missing, expired or revoked. Log in again. 403, Error from server (Forbidden): ... cannot list resource, means it knows who you are and your RBAC does not allow the action. Logging in again will not help; you need a RoleBinding in that namespace.

Where does oc login store my credentials?

In your kubeconfig, ~/.kube/config by default: a cluster entry named after the API host, a user entry holding the OAuth access token in clear text, and a context combining project, cluster and user. The password is never stored. Protect the file with mode 600 and never copy it into images or repositories. oc whoami --show-context shows the active context.

Does deleting my kubeconfig log me out?

No. The token remains valid on the server until it expires, 24 hours by default, so anyone who copied it can still use it. oc logout deletes the OAuthAccessToken on the server and removes it from your kubeconfig. For automation, use ServiceAccount tokens with limited scope rather than personal OAuth tokens.

What are kubeadmin and system:admin?

kubeadmin is a temporary cluster-admin user created by the installer, with its password in the install directory; best practice is to configure a real identity provider, grant cluster-admin to real people and delete the kubeadmin secret. system:admin is the identity in the installer's kubeconfig, a client certificate that does not use OAuth, so it still works when OAuth or the identity provider is broken. Guard it as a break-glass credential.

What should I do when oc asks "Use insecure connections?"

In a company environment, answer no. The prompt means the API server's certificate is signed by a CA your machine does not trust. Get the company or cluster CA certificate and log in with --certificate-authority=ca.crt, or install the CA in your system trust store. --insecure-skip-tls-verify disables verification entirely and exposes your password and token to anyone able to intercept the connection.

In an interview Mid

How do you log in to an OpenShift cluster from the command line, and what do you check when it fails?

oc login https://api.<cluster>.<domain>:6443 -u <user> - oc finds the cluster's OAuth server, sends your credentials, and gets an access token (sha256~..., 24 h by default). It never stores the password; it writes a cluster, user and context into ~/.kube/config, which kubectl reads too. Or oc login --token=... --server=... with the console's Copy login command.

Where am I: oc whoami, -t (token), --show-server, --show-context.

Failures, read in order:

Plus the special identities: kubeadmin (temporary, delete it once a real identity provider exists) and system:admin (the installer's certificate kubeconfig, the break-glass when OAuth is down). oc logout revokes the token on the server.

Also asked: How should a pipeline authenticate to OpenShift? · The cluster's identity provider is down and nobody can log in. What do you do? · What is the difference between a 401 and a 403 from the OpenShift API?

Practise this lesson in the terminal Free, in your browser - a real Ubuntu terminal to try it in, with missions that check your work.