{"id":5090,"date":"2023-07-15T11:38:12","date_gmt":"2023-07-15T09:38:12","guid":{"rendered":"http:\/\/miro.borodziuk.eu\/?p=5090"},"modified":"2023-09-22T09:19:12","modified_gmt":"2023-09-22T07:19:12","slug":"secrets-and-service-accounts-on-openshift","status":"publish","type":"post","link":"http:\/\/miro.borodziuk.eu\/index.php\/2023\/07\/15\/secrets-and-service-accounts-on-openshift\/","title":{"rendered":"Secrets and Service Accounts on Openshift"},"content":{"rendered":"<p><!--more--><\/p>\n<p><span style=\"color: #3366ff;\">Secrets<\/span><\/p>\n<ul>\n<li>A secret is a base64 encoded ConfigMap<\/li>\n<li>To really protect data in a secret, the Etcd can be encrypted<\/li>\n<li>Secrets are commonly used to decouple configuration and data from the applications running in OpenShift<\/li>\n<li>Using secrets allows OpenShift to load site-specific data from external sources<\/li>\n<li>Secrets can be used to store different kinds of data\n<ul>\n<li>Passwords<\/li>\n<li>Sensitive configuration files<\/li>\n<li>Credentials such as SSH keys or OAuth tokens<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><span style=\"color: #3366ff;\">Secret Types<\/span><\/p>\n<ul>\n<li>Different types of secrets exist:\n<ul>\n<li>docker-registry<\/li>\n<li>generic<\/li>\n<li>tls<\/li>\n<\/ul>\n<\/li>\n<li>When information is stored in a secret, OpenShift validates that the data conforms to the type of secret<\/li>\n<li>In OpenShift, secrets are mainly used for two reasons\n<ul>\n<li>To store credentials which is used by Pods in a MicroService architecture<\/li>\n<li>To store TLS certificates and keys<\/li>\n<li>A TLS secret stores the certificate as tls.crt and the certificate key as tls.key<\/li>\n<li>Developers can mount the secret as a volume and create a pass-through route to the application<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><span style=\"color: #3366ff;\">Creating Secrets<\/span><\/p>\n<ul>\n<li>Generic secrets: <code>oc create secret generic secretvars --from-literal user=root --from-literal password=verysecret<\/code><\/li>\n<li>Generic secrets, containing SSH keys: <code>oc create secret generic ssh-keys --from-file id_rsa=nissh\/id_rsa --from-file id_rsa.pub=\"sissh\/id_rsa.pub<\/code><\/li>\n<li>Secrets containing TLS certificate and key:<code> oc create secret tls secret-tls -- cert certsitls.crt keysitls.key<\/code><\/li>\n<\/ul>\n<p><span style=\"color: #3366ff;\">Exposing Secrets to Pods<\/span><\/p>\n<ul>\n<li>Secrets can be referred to as variables, or as files from the Pod<\/li>\n<li>Use <code>oc set env<\/code> to write the environment variables obtained from a secret to a pod or deployment\n<ul>\n<li><code>oc set env deployment\/mysql --from secret\/mysql --prefix MYSQL_<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Use oc set volume to mount secrets as volumes<\/li>\n<li>Notice that when using oc set volume, all files currently in the target directory are no longer accessible\n<ul>\n<li><code>oc set volume deployment\/mysql --add --type secret --mount-path \/run\/secrets\/mysql --secret-name mysql<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Notice that <code>oc set env<\/code> can use <code>--prefix<\/code> to add a prefix to the environment variables defined in the secret<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">$ oc create secret generic mysql --from-literal user=sqluser --from-literal password=password --from-literal database=secretdb --from-literal hostname=mysql --from-literal root          _password=password\r\nsecret\/mysql created\r\n\r\n$ oc new-app --name mysql --docker-image bitnami\/mysql\r\n$ oc get pods -w\r\nNAME             READY     STATUS              RESTARTS   AGE\r\nmysql-1-deploy   0\/1       ContainerCreating   0          23s\r\n\r\n$ oc logs mysql-1-deploy\r\nError from server (BadRequest): container \"deployment\" in pod \"mysql-1-deploy\" is waiting to start: ContainerCreating\r\n\r\n$ oc get all\r\nNAME                 READY     STATUS              RESTARTS   AGE\r\npod\/mysql-2-deploy   0\/1       ContainerCreating   0          47s\r\n\r\nNAME                            DESIRED   CURRENT   READY     AGE\r\nreplicationcontroller\/mysql-1   0         0         0         12m\r\nreplicationcontroller\/mysql-2   0         0         0         47s\r\n\r\nNAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE\r\nservice\/mysql   ClusterIP   172.30.55.23   &lt;none&gt;        3306\/TCP   12m\r\n\r\nNAME                                       REVISION   DESIRED   CURRENT   TRIGGERED BY\r\ndeploymentconfig.apps.openshift.io\/mysql   2          1         0         config,image(mysql:latest)\r\n\r\nNAME                                   DOCKER REPO                       TAGS      UPDATED\r\nimagestream.image.openshift.io\/mysql   172.30.1.1:5000\/userstaff\/mysql   latest    12 minutes ago\r\n\r\n$ oc set env --from=secret\/mysql --prefix=MYSQL_ deploymentconfig.apps.openshift.io\/mysql\r\ndeploymentconfig.apps.openshift.io\/mysql updated\r\n\r\n$ oc get pods -w\r\nNAME             READY     STATUS              RESTARTS   AGE\r\nmysql-2-deploy   0\/1       ContainerCreating   0          25s\r\n\r\n\r\n$ oc get all\r\nNAME                 READY     STATUS              RESTARTS   AGE\r\npod\/mysql-2-deploy   0\/1       ContainerCreating   0          1m\r\n\r\nNAME                            DESIRED   CURRENT   READY     AGE\r\nreplicationcontroller\/mysql-1   0         0         0         12m\r\nreplicationcontroller\/mysql-2   0         0         0         1m\r\n\r\nNAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE\r\nservice\/mysql   ClusterIP   172.30.55.23   &lt;none&gt;        3306\/TCP   12m\r\n\r\nNAME                                       REVISION   DESIRED   CURRENT   TRIGGERED BY\r\ndeploymentconfig.apps.openshift.io\/mysql   2          1         0         config,image(mysql:latest)\r\n\r\nNAME                                   DOCKER REPO                       TAGS      UPDATED\r\nimagestream.image.openshift.io\/mysql   172.30.1.1:5000\/userstaff\/mysql   latest    12 minutes ago\r\n[root@okd ~]# oc exec -it pod\/mysql-2-deploy -- env\r\nerror: invalid resource name \"pod\/mysql-2-deploy\": [may not contain '\/']\r\n[root@okd ~]#\r\n[root@okd ~]# oc exec -it mysql-2-deploy -- env\r\nerror: unable to upgrade connection: container not found (\"deployment\")\r\n[root@okd ~]#\r\n[root@okd ~]# oc get pods -w\r\nNAME             READY     STATUS              RESTARTS   AGE\r\nmysql-2-deploy   0\/1       ContainerCreating   0          2m\r\n^C[root@okd ~]#\r\n[root@okd ~]# oc get pods\r\nNAME             READY     STATUS              RESTARTS   AGE\r\nmysql-2-deploy   0\/1       ContainerCreating   0          2m\r\n\r\n[root@okd ~]# oc get pods\r\nNAME             READY     STATUS              RESTARTS   AGE\r\nmysql-2-deploy   0\/1       ContainerCreating   0          4m\r\n[root@okd ~]# oc logs mysql-2-deploy\r\nError from server (BadRequest): container \"deployment\" in pod \"mysql-2-deploy\" is waiting to start: ContainerCreating\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\">ServiceAccounts<\/span><\/p>\n<ul>\n<li>A ServiceAccount (SA) is a user account that is used by a Pod to determine Pod access privileges to system resources<\/li>\n<li>The default ServiceAccount used by Pods allows for very limited access to cluster resources<\/li>\n<li>Sometimes a Pod cannot run with this very restricted ServiceAccount<\/li>\n<li>After creating the ServiceAccount, specific access privileges need to be set<\/li>\n<\/ul>\n<p><span style=\"color: #3366ff;\">Configuring ServiceAccount Access Restrictions<\/span><\/p>\n<ul>\n<li>To create a ServiceAccount, use<code> oc create serviceaccount mysa <\/code><\/li>\n<li>Optionally, add <code>-n namespace<\/code> to assign the SA to a specific namespace<\/li>\n<li>After creating the SA, use a role binding to connect the SA to a specific role<\/li>\n<li>Or associate the SA with a specific Security Context Constraint<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true\"># oc login -u kubeadmin -p redahat\r\n$ oc get pods\r\nNAME             READY     STATUS    RESTARTS   AGE\r\nmysql-2-deploy   0\/1       Error     0          17h\r\n\r\n$ oc get pods mysql-2-deploy -o yaml\r\napiVersion: v1\r\nkind: Pod\r\nmetadata:\r\n  annotations:\r\n    openshift.io\/deployment-config.name: mysql\r\n    openshift.io\/deployment.name: mysql-2\r\n    openshift.io\/scc: restricted\r\n  creationTimestamp: 2023-08-05T20:09:07Z\r\n  labels:\r\n    openshift.io\/deployer-pod-for.name: mysql-2\r\n  name: mysql-2-deploy\r\n  namespace: userstaff\r\n  ownerReferences:\r\n  - apiVersion: v1\r\n    kind: ReplicationController\r\n    name: mysql-2\r\n    uid: eeb46f7e-33cb-11ee-8f96-8e5760356a66\r\n  resourceVersion: \"4936318\"\r\n  selfLink: \/api\/v1\/namespaces\/userstaff\/pods\/mysql-2-deploy\r\n  uid: eeb9b6b4-33cb-11ee-8f96-8e5760356a66\r\nspec:\r\n  activeDeadlineSeconds: 21600\r\n  containers:\r\n  - env:\r\n    - name: OPENSHIFT_DEPLOYMENT_NAME\r\n      value: mysql-2\r\n    - name: OPENSHIFT_DEPLOYMENT_NAMESPACE\r\n      value: userstaff\r\n    image: openshift\/origin-deployer:v3.11\r\n    imagePullPolicy: IfNotPresent\r\n    name: deployment\r\n    resources: {}\r\n    securityContext:\r\n      capabilities:\r\n        drop:\r\n        - KILL\r\n        - MKNOD\r\n        - SETGID\r\n        - SETUID\r\n      runAsUser: 1000460000\r\n    terminationMessagePath: \/dev\/termination-log\r\n    terminationMessagePolicy: File\r\n    volumeMounts:\r\n    - mountPath: \/var\/run\/secrets\/kubernetes.io\/serviceaccount\r\n      name: deployer-token-snmch\r\n      readOnly: true\r\n  dnsPolicy: ClusterFirst\r\n  imagePullSecrets:\r\n  - name: deployer-dockercfg-rbbvc\r\n  nodeName: localhost\r\n  priority: 0\r\n  restartPolicy: Never\r\n  schedulerName: default-scheduler\r\n  securityContext:\r\n    fsGroup: 1000460000\r\n    seLinuxOptions:\r\n      level: s0:c21,c20\r\n  serviceAccount: deployer\r\n  serviceAccountName: deployer\r\n  terminationGracePeriodSeconds: 10\r\n  volumes:\r\n  - name: deployer-token-snmch\r\n    secret:\r\n      defaultMode: 420\r\n      secretName: deployer-token-snmch\r\nstatus:\r\n  conditions:\r\n  - lastProbeTime: null\r\n    lastTransitionTime: 2023-08-05T20:09:07Z\r\n    status: \"True\"\r\n    type: Initialized\r\n  - lastProbeTime: null\r\n    lastTransitionTime: 2023-08-05T21:03:58Z\r\n    message: 'containers with unready status: [deployment]'\r\n    reason: ContainersNotReady\r\n    status: \"False\"\r\n    type: Ready\r\n  - lastProbeTime: null\r\n    lastTransitionTime: null\r\n    message: 'containers with unready status: [deployment]'\r\n    reason: ContainersNotReady\r\n    status: \"False\"\r\n    type: ContainersReady\r\n  - lastProbeTime: null\r\n    lastTransitionTime: 2023-08-05T20:09:07Z\r\n    status: \"True\"\r\n    type: PodScheduled\r\n  containerStatuses:\r\n  - containerID: docker:\/\/50203c3593f8c4ed15fc43514ec64c8ee126b788e709ea7b70ee97262f5c7762\r\n    image: openshift\/origin-deployer:v3.11\r\n    imageID: docker-pullable:\/\/openshift\/origin-deployer@sha256:0b09d18f5616617b222394b726be2a860250c10a41737057dba69147ec894ad0\r\n    lastState: {}\r\n    name: deployment\r\n    ready: false\r\n    restartCount: 0\r\n    state:\r\n      terminated:\r\n        containerID: docker:\/\/50203c3593f8c4ed15fc43514ec64c8ee126b788e709ea7b70ee97262f5c7762\r\n        exitCode: 1\r\n        finishedAt: 2023-08-05T21:03:57Z\r\n        reason: Error\r\n        startedAt: 2023-08-05T20:53:55Z\r\n  hostIP: 172.30.9.22\r\n  phase: Failed\r\n  podIP: 172.17.0.38\r\n  qosClass: BestEffort\r\n  startTime: 2023-08-05T20:09:07Z\r\n\r\n$ oc create sa newsa\r\nserviceaccount\/newsa created\r\n\r\n$ oc get sa\r\nNAME       SECRETS   AGE\r\nbuilder    2         19h\r\ndefault    2         19h\r\ndeployer   2         19h\r\nnewsa      2         12m\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\">Security Context Constraints<\/span><\/p>\n<ul>\n<li>A Security Context Constraint (SCC) is an OpenShift resource, similar to the Kubernetes Security Context resource, that restricts access to resources<\/li>\n<li>The purpose is to limit access from a Pod to the host environment<\/li>\n<li>Different SCCs are available to control:\n<ul>\n<li>Running privileged containers<\/li>\n<li>Requesting additional capabilities to a container<\/li>\n<li>Using host directories as volumes<\/li>\n<li>Changing SELinux context of a container<\/li>\n<li>Changing the user ID<\/li>\n<\/ul>\n<\/li>\n<li>Using SCCs may be necessary to run community containers that by default don&#8217;t work under the tight OpenShift security restrictions<\/li>\n<\/ul>\n<p><span style=\"color: #3366ff;\">Exploring SCCs<\/span><\/p>\n<ul>\n<li>Use <code>oc get scc<\/code> for an overview of SCCs<\/li>\n<li>For more details, use <code>oc describe scc &lt;name&gt;<\/code>, as in <code>oc describe scc nonroot<\/code><\/li>\n<li>Use <code>oc describe pod &lt;podname&gt; | grep scc<\/code> to see which SCC is currently used by a Pod<\/li>\n<li>If a Pod can&#8217;t run due to an SCC, use <code>oc get pod &lt;name&gt; -o yaml | oc adm policy scc-subject-review -f -<\/code><\/li>\n<li>To change a container to run with a different SCC, you must create a service account and use that in the Pod<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">$ oc login -u kubeadmin -p redahat\r\n$ oc get scc\r\nNAME               PRIV      CAPS      SELINUX     RUNASUSER          FSGROUP     SUPGROUP    PRIORITY   READONLYROOTFS   VOLUMES\r\nanyuid             false     []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    10         false            [configMap downwardAPI emptyDir persistentVolumeClaim                                                               projected secret]\r\nhostaccess         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    &lt;none&gt;     false            [configMap downwardAPI emptyDir hostPath persistentVo                                                              lumeClaim projected secret]\r\nhostmount-anyuid   false     []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    &lt;none&gt;     false            [configMap downwardAPI emptyDir hostPath nfs persiste                                                              ntVolumeClaim projected secret]\r\nhostnetwork        false     []        MustRunAs   MustRunAsRange     MustRunAs   MustRunAs   &lt;none&gt;     false            [configMap downwardAPI emptyDir persistentVolumeClaim                                                               projected secret]\r\nnonroot            false     []        MustRunAs   MustRunAsNonRoot   RunAsAny    RunAsAny    &lt;none&gt;     false            [configMap downwardAPI emptyDir persistentVolumeClaim                                                               projected secret]\r\nprivileged         true      [*]       RunAsAny    RunAsAny           RunAsAny    RunAsAny    &lt;none&gt;     false            [*]\r\nrestricted         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    &lt;none&gt;     false            [configMap downwardAPI emptyDir persistentVolumeClaim                                                               projected secret]\r\n[root@okd ~]# oc describe scc nonroot\r\nName:                                           nonroot\r\nPriority:                                       &lt;none&gt;\r\nAccess:\r\n  Users:                                        &lt;none&gt;\r\n  Groups:                                       &lt;none&gt;\r\nSettings:\r\n  Allow Privileged:                             false\r\n  Allow Privilege Escalation:                   0xc42111004c\r\n  Default Add Capabilities:                     &lt;none&gt;\r\n  Required Drop Capabilities:                   KILL,MKNOD,SETUID,SETGID\r\n  Allowed Capabilities:                         &lt;none&gt;\r\n  Allowed Seccomp Profiles:                     &lt;none&gt;\r\n  Allowed Volume Types:                         configMap,downwardAPI,emptyDir,persistentVolumeClaim,projected,secret\r\n  Allowed Flexvolumes:                          &lt;all&gt;\r\n  Allowed Unsafe Sysctls:                       &lt;none&gt;\r\n  Forbidden Sysctls:                            &lt;none&gt;\r\n  Allow Host Network:                           false\r\n  Allow Host Ports:                             false\r\n  Allow Host PID:                               false\r\n  Allow Host IPC:                               false\r\n  Read Only Root Filesystem:                    false\r\n  Run As User Strategy: MustRunAsNonRoot\r\n    UID:                                        &lt;none&gt;\r\n    UID Range Min:                              &lt;none&gt;\r\n    UID Range Max:                              &lt;none&gt;\r\n  SELinux Context Strategy: MustRunAs\r\n    User:                                       &lt;none&gt;\r\n    Role:                                       &lt;none&gt;\r\n    Type:                                       &lt;none&gt;\r\n    Level:                                      &lt;none&gt;\r\n  FSGroup Strategy: RunAsAny\r\n    Ranges:                                     &lt;none&gt;\r\n  Supplemental Groups Strategy: RunAsAny\r\n    Ranges:                                     &lt;none&gt;\r\n\r\n\r\n$ oc run nginx --image=ngninx\r\ndeploymentconfig.apps.openshift.io\/nginx created\r\n\r\n$ oc run pod --image=ngninx\r\ndeploymentconfig.apps.openshift.io\/pod created\r\n\r\n\r\n$ oc get all\r\nNAME                 READY     STATUS              RESTARTS   AGE\r\npod\/auto-1-build     0\/1       Error               0          8d\r\npod\/nginx-1-deploy   0\/1       ContainerCreating   0          1m\r\npod\/pod-1-deploy     0\/1       ContainerCreating   0          53s\r\n\r\nNAME                            DESIRED   CURRENT   READY     AGE\r\nreplicationcontroller\/nginx-1   0         0         0         1m\r\nreplicationcontroller\/pod-1     0         0         0         53s\r\n\r\nNAME                                       REVISION   DESIRED   CURRENT   TRIGGERED BY\r\ndeploymentconfig.apps.openshift.io\/auto    0          1         0         config,image(auto:latest)\r\ndeploymentconfig.apps.openshift.io\/nginx   1          1         0         config\r\ndeploymentconfig.apps.openshift.io\/pod     1          1         0         config\r\n\r\nNAME                                  TYPE      FROM      LATEST\r\nbuildconfig.build.openshift.io\/auto   Docker    Git       1\r\n\r\nNAME                              TYPE      FROM          STATUS                       STARTED      DURATION\r\nbuild.build.openshift.io\/auto-1   Docker    Git@a6c13bc   Failed (DockerBuildFailed)   8 days ago   26s\r\n\r\nNAME                                    DOCKER REPO                   TAGS      UPDATED\r\nimagestream.image.openshift.io\/auto     172.30.1.1:5000\/auto\/auto\r\nimagestream.image.openshift.io\/centos   172.30.1.1:5000\/auto\/centos   latest    8 days ago\r\n\r\n\r\n$ oc get pod\/pod-1-deploy -o yaml\r\napiVersion: v1\r\nkind: Pod\r\nmetadata:\r\n  annotations:\r\n    openshift.io\/deployment-config.name: pod\r\n    openshift.io\/deployment.name: pod-1\r\n    openshift.io\/scc: restricted\r\n  creationTimestamp: 2023-08-06T13:37:56Z\r\n  labels:\r\n    openshift.io\/deployer-pod-for.name: pod-1\r\n  name: pod-1-deploy\r\n  namespace: auto\r\n  ownerReferences:\r\n  - apiVersion: v1\r\n    kind: ReplicationController\r\n    name: pod-1\r\n    uid: 73cbd6d5-345e-11ee-8f96-8e5760356a66\r\n  resourceVersion: \"5178541\"\r\n  selfLink: \/api\/v1\/namespaces\/auto\/pods\/pod-1-deploy\r\n  uid: 73cff627-345e-11ee-8f96-8e5760356a66\r\nspec:\r\n  activeDeadlineSeconds: 21600\r\n  containers:\r\n  - env:\r\n    - name: OPENSHIFT_DEPLOYMENT_NAME\r\n      value: pod-1\r\n    - name: OPENSHIFT_DEPLOYMENT_NAMESPACE\r\n      value: auto\r\n    image: openshift\/origin-deployer:v3.11\r\n    imagePullPolicy: IfNotPresent\r\n    name: deployment\r\n    resources: {}\r\n    securityContext:\r\n      capabilities:\r\n        drop:\r\n        - KILL\r\n        - MKNOD\r\n        - SETGID\r\n        - SETUID\r\n      runAsUser: 1000290000\r\n    terminationMessagePath: \/dev\/termination-log\r\n    terminationMessagePolicy: File\r\n    volumeMounts:\r\n    - mountPath: \/var\/run\/secrets\/kubernetes.io\/serviceaccount\r\n      name: deployer-token-r2dtz\r\n      readOnly: true\r\n  dnsPolicy: ClusterFirst\r\n  imagePullSecrets:\r\n  - name: deployer-dockercfg-xtpcd\r\n  nodeName: localhost\r\n  priority: 0\r\n  restartPolicy: Never\r\n  schedulerName: default-scheduler\r\n  securityContext:\r\n    fsGroup: 1000290000\r\n    seLinuxOptions:\r\n      level: s0:c17,c9\r\n  serviceAccount: deployer\r\n  serviceAccountName: deployer\r\n  terminationGracePeriodSeconds: 10\r\n  volumes:\r\n  - name: deployer-token-r2dtz\r\n    secret:\r\n      defaultMode: 420\r\n      secretName: deployer-token-r2dtz\r\nstatus:\r\n  conditions:\r\n  - lastProbeTime: null\r\n    lastTransitionTime: 2023-08-06T13:37:56Z\r\n    status: \"True\"\r\n    type: Initialized\r\n  - lastProbeTime: null\r\n    lastTransitionTime: 2023-08-06T13:37:56Z\r\n    message: 'containers with unready status: [deployment]'\r\n    reason: ContainersNotReady\r\n    status: \"False\"\r\n    type: Ready\r\n  - lastProbeTime: null\r\n    lastTransitionTime: null\r\n    message: 'containers with unready status: [deployment]'\r\n    reason: ContainersNotReady\r\n    status: \"False\"\r\n    type: ContainersReady\r\n  - lastProbeTime: null\r\n    lastTransitionTime: 2023-08-06T13:37:56Z\r\n    status: \"True\"\r\n    type: PodScheduled\r\n  containerStatuses:\r\n  - image: openshift\/origin-deployer:v3.11\r\n    imageID: \"\"\r\n    lastState: {}\r\n    name: deployment\r\n    ready: false\r\n    restartCount: 0\r\n    state:\r\n      waiting:\r\n        reason: ContainerCreating\r\n  hostIP: 172.30.9.22\r\n  phase: Pending\r\n  qosClass: BestEffort\r\n  startTime: 2023-08-06T13:37:56Z\r\n\r\n\r\n$ oc get pod\/pod-1-deploy -o yaml | oc adm policy scc-subject-review -f -\r\nRESOURCE           ALLOWED BY\r\nPod\/pod-1-deploy   anyuid\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\">Using SCCs<\/span><\/p>\n<ul>\n<li><code>oc get scc<\/code> gives an overview of all SCCs<\/li>\n<li><code>oc describe scc anyuid<\/code> shows information about a specific SCC<\/li>\n<li><code>oc describe pod<\/code> shows a line openshift.io\/scc: restricted; most Pods run as restricted<\/li>\n<li>Some Pods require access beyond the scope of their own containers, such as S21 Pods. To provide this access, SAs are needed<\/li>\n<li>To change the container to run using a different SCC, you need to create a service account and use that with the Pod or Deployment<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\">Understanding SCC and ServiceAccount<\/span><\/p>\n<ul>\n<li>The service account is used to connect to an SCC<\/li>\n<li>Once the service account is connected to the SCC it can be bound to a deployment or pod to make sure that it is working<\/li>\n<li>This allows you for instance to run a Pod that requires root access to use the anyuid SCC so that it can run anyway<\/li>\n<\/ul>\n<p><span style=\"color: #3366ff;\">Demo: using SCCs<\/span><\/p>\n<ul>\n<li>As developer:<code> oc new-project sccs<\/code><\/li>\n<li><code>oc new-app --name sccnginx --docker-image nginx<\/code><\/li>\n<li><code>oc get pods<\/code> will show an error<\/li>\n<li><code>oc logs pod\/nginx[Tab]<\/code> will show that is fails because of a permission problem<\/li>\n<li>as admin: <code>oc get pod nginx[Tab] -o yaml | oc adm policy scc-subject-review -f -<\/code> will show which scc to use<\/li>\n<li>as admin: <code>oc create sa nginx-sa<\/code> creates the dedicated service account<\/li>\n<li>As administrator: <code>oc adm policy add-scc-to-user anyuid -z nginx-sa<\/code><\/li>\n<li>As developer: <code>oc set serviceaccount deployment sccnginx nginx-sa<\/code><\/li>\n<li><code>oc get pods sccs[Tab] -o yaml<\/code>; look for serviceAccount<\/li>\n<li><code>oc get pods<\/code> should show the pod as running (may have to wait a minute)<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true \">$ oc login -u kubeadmin -p redahat\r\n$ oc new-project scc-demo\r\n$ oc new-app --name sccnginx --docker-image nginx\r\n$ oc get pods\r\nNAME                        READY   STATUS             RESTARTS      AGE\r\nsccnginx-784bd9587d-6lpw8   0\/1     CrashLoopBackOff   4 (60s ago)   2m44s\r\n\r\n$ oc logs sccnginx-784bd9587d-6lpw8\r\n\/docker-entrypoint.sh: \/docker-entrypoint.d\/ is not empty, will attempt to perform configuration\r\n\/docker-entrypoint.sh: Looking for shell scripts in \/docker-entrypoint.d\/\r\n\/docker-entrypoint.sh: Launching \/docker-entrypoint.d\/10-listen-on-ipv6-by-default.sh\r\n10-listen-on-ipv6-by-default.sh: info: can not modify \/etc\/nginx\/conf.d\/default.conf (read-only file system?)\r\n\/docker-entrypoint.sh: Sourcing \/docker-entrypoint.d\/15-local-resolvers.envsh\r\n\/docker-entrypoint.sh: Launching \/docker-entrypoint.d\/20-envsubst-on-templates.sh\r\n\/docker-entrypoint.sh: Launching \/docker-entrypoint.d\/30-tune-worker-processes.sh\r\n\/docker-entrypoint.sh: Configuration complete; ready for start up\r\n2023\/09\/10 12:32:14 [warn] 1#1: the \"user\" directive makes sense only if the master process runs with super-user privileges, ignored in \/etc\/nginx\/nginx.conf:2\r\nnginx: [warn] the \"user\" directive makes sense only if the master process runs with super-user privileges, ignored in \/etc\/nginx\/nginx.conf:2\r\n2023\/09\/10 12:32:14 [emerg] 1#1: mkdir() \"\/var\/cache\/nginx\/client_temp\" failed (13: Permission denied)\r\nnginx: [emerg] mkdir() \"\/var\/cache\/nginx\/client_temp\" failed (13: Permission denied)\r\n\r\n\r\n$ oc get pod sccnginx-784bd9587d-6lpw8 -o yaml | grep message\r\n    message: 'containers with unready status: [sccnginx]'\r\n    message: 'containers with unready status: [sccnginx]'\r\n        message: back-off 5m0s restarting failed container=sccnginx pod=sccnginx-784bd9587d-6lpw8_scc(877967db-9891-4576-b440-86d792629f6e)\r\n\r\n\r\n$ oc get pod sccnginx-784bd9587d-6lpw8 -o yaml | oc adm policy scc-subject-review -f -\r\nRESOURCE                ALLOWED BY\r\nPod\/sccnginx-1-deploy   anyuid\r\n\r\n$ oc create sa nginx-sa\r\nserviceaccount\/nginx-sa created\r\n\r\n$ oc adm policy add-scc-to-user anyuid -z nginx-sa\r\nscc \"anyuid\" added to: [\"system:serviceaccount:scc-demo:nginx-sa\"]\r\n\r\n\r\n$ oc set sa deployment sccnginx nginx-sa\r\n\r\n$ oc get pods\r\nNAME                       READY   STATUS    RESTARTS   AGE\r\nsccnginx-bf44d4dd6-2v2zv   1\/1     Running   0          19s\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\">Running Containers as Non-root<\/span><\/p>\n<ul>\n<li>By default, OpenShift denies containers to run as root<\/li>\n<li>Many containers run as root by default<\/li>\n<li>A container that runs as root has root privileges on the container host as well, and should be avoided<\/li>\n<li>If you build your own container images, specify which user it should run<\/li>\n<li>Frequently, non-root alternatives are available for the images you&#8217;re using\n<ul>\n<li><strong> quay.io<\/strong> images are made with OpenShift in mind<\/li>\n<li><strong>bitnami<\/strong> has reworked common images to be started as non-root: https:\/\/engineering.bitnami.com\/articles\/running-non-root-containers-on-openshift.html<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><span style=\"color: #3366ff;\">Managing Non-root Container Ports<\/span><\/p>\n<ul>\n<li>Non-root containers cannot bind to a privileged port<\/li>\n<li>In OpenShift, this is not an issue, as containers are accessed through services and routes<\/li>\n<li>Configure the port on the service\/route, not on the Pod<\/li>\n<li>Also, non-root containers will have limitations accessing files<\/li>\n<\/ul>\n<p><span style=\"color: #3366ff;\">Running Bitnami non-root Nginx<\/span><\/p>\n<ul>\n<li><code>oc new-app --docker-image bitnami\/nginx:latest --name=bginx <\/code><\/li>\n<li><code>oc get pods -o wide <\/code><\/li>\n<li><code>oc describe pods bginx-&lt;xxx&gt;<\/code><\/li>\n<li><code>oc get services<\/code><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true\">$ oc whoami\r\nsystem:admin\r\n\r\n\r\n$ oc new-app --docker-image bitnami\/nginx:latest --name=bginx\r\n--&gt; Found Docker image c80f470 (2 days old) from Docker Hub for \"bitnami\/nginx:latest\"\r\n\r\n    * An image stream tag will be created as \"bginx:latest\" that will track this image\r\n    * This image will be deployed in deployment config \"bginx\"\r\n    * Ports 8080\/tcp, 8443\/tcp will be load balanced by service \"bginx\"\r\n      * Other containers can access this service through the hostname \"bginx\"\r\n\r\n--&gt; Creating resources ...\r\n    imagestream.image.openshift.io \"bginx\" created\r\n    deploymentconfig.apps.openshift.io \"bginx\" created\r\n    service \"bginx\" created\r\n--&gt; Success\r\n    Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:\r\n     'oc expose svc\/bginx'\r\n    Run 'oc status' to view your app.\r\n\r\n\r\n$ oc get pods -o wide\r\nNAME                READY     STATUS              RESTARTS   AGE       IP            NODE        NOMINATED NODE\r\nauto-1-build        0\/1       Error               0          8d        172.17.0.22   localhost   &lt;none&gt;\r\nbginx-1-deploy      0\/1       ContainerCreating   0          11s       &lt;none&gt;        localhost   &lt;none&gt;\r\n\r\n\r\n$ oc get all\r\nNAME                 READY     STATUS              RESTARTS   AGE\r\npod\/bginx-1-deploy   0\/1       ContainerCreating   0          8m\r\n\r\nNAME                            DESIRED   CURRENT   READY     AGE\r\nreplicationcontroller\/bginx-1   0         0         0         8m\r\n\r\nNAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE\r\nservice\/bginx   ClusterIP   172.30.66.189   &lt;none&gt;        8080\/TCP,8443\/TCP   8m\r\n\r\nNAME                                       REVISION   DESIRED   CURRENT   TRIGGERED BY\r\ndeploymentconfig.apps.openshift.io\/auto    0          1         0         config,image(auto:latest)\r\ndeploymentconfig.apps.openshift.io\/bginx   1          1         0         config,image(bginx:latest)\r\n\r\nNAME                                   DOCKER REPO                  TAGS      UPDATED\r\nimagestream.image.openshift.io\/bginx   172.30.1.1:5000\/auto\/bginx   latest    8 minutes ago\r\n\r\n\r\n\r\n$ oc describe pod\/bginx-1-deploy\r\nName:               bginx-1-deploy\r\nNamespace:          auto\r\nPriority:           0\r\nPriorityClassName:  &lt;none&gt;\r\nNode:               localhost\/172.30.9.22\r\nStart Time:         Sun, 06 Aug 2023 16:49:07 +0200\r\nLabels:             openshift.io\/deployer-pod-for.name=bginx-1\r\nAnnotations:        openshift.io\/deployment-config.name=bginx\r\n                    openshift.io\/deployment.name=bginx-1\r\n                    openshift.io\/scc=restricted\r\nStatus:             Pending\r\nIP:\r\nContainers:\r\n  deployment:\r\n    Container ID:\r\n    Image:          openshift\/origin-deployer:v3.11\r\n    Image ID:\r\n    Port:           &lt;none&gt;\r\n    Host Port:      &lt;none&gt;\r\n    State:          Waiting\r\n      Reason:       ContainerCreating\r\n    Ready:          False\r\n    Restart Count:  0\r\n    Environment:\r\n      OPENSHIFT_DEPLOYMENT_NAME:       bginx-1\r\n      OPENSHIFT_DEPLOYMENT_NAMESPACE:  auto\r\n    Mounts:\r\n      \/var\/run\/secrets\/kubernetes.io\/serviceaccount from deployer-token-r2dtz (ro)\r\nConditions:\r\n  Type              Status\r\n  Initialized       True\r\n  Ready             False\r\n  ContainersReady   False\r\n  PodScheduled      True\r\nVolumes:\r\n  deployer-token-r2dtz:\r\n    Type:        Secret (a volume populated by a Secret)\r\n    SecretName:  deployer-token-r2dtz\r\n    Optional:    false\r\nQoS Class:       BestEffort\r\nNode-Selectors:  &lt;none&gt;\r\nTolerations:     &lt;none&gt;\r\nEvents:\r\n  Type     Reason                  Age                From                Message\r\n  ----     ------                  ----               ----                -------\r\n  Normal   Scheduled               9m                 default-scheduler   Successfully assigned auto\/bginx-1-deploy to localhost\r\n  Warning  FailedCreatePodSandBox  8m (x13 over 9m)   kubelet, localhost  Failed create pod sandbox: rpc error: code = Unknown desc = failed to start sandbox container for pod \"bginx-1-deploy\": Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: can't get final child's PID from pipe: EOF: unknown\r\n  Normal   SandboxChanged          4m (x225 over 9m)  kubelet, localhost  Pod sandbox changed, it will be killed and re-created.\r\n\r\n\r\n$ oc get services\r\nNAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE\r\nbginx     ClusterIP   172.30.66.189   &lt;none&gt;        8080\/TCP,8443\/TCP   10m\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[93],"tags":[],"_links":{"self":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/5090"}],"collection":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/comments?post=5090"}],"version-history":[{"count":10,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/5090\/revisions"}],"predecessor-version":[{"id":5094,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/5090\/revisions\/5094"}],"wp:attachment":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/media?parent=5090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/categories?post=5090"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/tags?post=5090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}