0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

OpenShift の上で TCP80を Listen するコンテナが標準で動かない事の確認

Last updated at Posted at 2023-06-26

目的

OpenShift は標準では、Port 80 を Listen するコンテナを動かす事は許可してなかったはず(どうもこれは 1023番以下の well known port の事のような気がする) ...と思ってググってみたものの情報が見つからなかった(見つけられなかった) ので、あらためて確認してみる。

使用したファイル類

以下のレポジトリからビルドしたものを使用

実験 (動かない事の確認)

実験用コンテナの作成

以下の Dockerfile をビルド

# FROM registry.access.redhat.com/ubi8/ubi:latest
FROM redhat/ubi8
MAINTAINER "yuhkih" 

RUN dnf install -y nginx
COPY index.html /usr/share/nginx/html/index.html
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80

CMD ["-g","daemon off;"]
ENTRYPOINT ["nginx"]

ビルド

docker build . -t yuhkih/nginx-port80:latest 

Docker Hub にプッシュ

 docker push yuhkih/nginx-port80 

以上で実験用のコンテナの準備は完了。

OpenShift の作業

OpenShift の新しいプロジェクトを作成

一般ユーザーでログイン。

oc login https://api.f5cluster.m51o.p1.openshiftapps.com:6443  -u yuhkih -p xxxxxxx 

projectを作成。

oc new-project testp

コンテナを oc new-app でデプロイ

oc new-app --image=docker.io/yuhkih/nginx-port80 -l=app=test

Pod がエラーになっている。

$ oc get pods
NAME                            READY   STATUS             RESTARTS       AGE
nginx-port80-78f75798bc-qjftq   0/1     CrashLoopBackOff   7 (5m2s ago)   15m
$ 

Logを確認。 Permission Denied になっている。

$ oc logs nginx-port80-78f75798bc-qjftq
2023/06/26 02:43:10 [emerg] 1#0: bind() to 0.0.0.0:80 failed (13: Permission denied)
nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)
$ 

権限を与えて動かしてみる

cluster-admin での作業

本筋は別の Port を Listen させる事だが、適当なSCC (Security Context Contrain) を与えて動かしてみる。
project の管理者に権限を与えるのは、クラスター の管理者の仕事なので cluster-admin の権限のユーザーで作業を行う。

Pod の権限は Podを起動する Serivce Account に紐付く。何もしない場合は default という Service Account で動いている。

まず、このPod を動かすための新しいService Account を作成する。

cluster-admin ユーザーでログイン。

oc login https://api.f5cluster.m51o.p1.openshiftapps.com:6443  -u cluster-admin -p xxxxxxx 

testp projectに移動

oc project testp

testsa という Service Account を作成する

oc create sa testsa

Service AccountSCCanyuid を与えてみる。

$ oc adm policy add-scc-to-user anyuid -z testsa
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:anyuid added: "saport80"
$ 

SCCSA の紐付は clusterrolebindings リソースに記載される。わかりにくい。

$ oc describe clusterrolebindings  system:openshift:scc:anyuid
Name:         system:openshift:scc:anyuid
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  system:openshift:scc:anyuid
Subjects:
  Kind            Name      Namespace
  ----            ----      ---------
  ServiceAccount  testsa    testp
$ 

projectの管理ユーザーでの作業

ここからは cluster-admin ではなく、project の管理ユーザー (projectの作成者) で作業を行う。

projectの作成者でログイン。

oc login https://api.f5cluster.m51o.p1.openshiftapps.com:6443  -u yuhkih -p xxxxxxx 

Deployment の名前を確認。(oc new-app で以下の Deployment が自動で作られている。便利。)

$ oc get deployment
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-port80   0/1     1            0           22m
$ 

Deployment に作成した SAsaport80 を紐付ける。

oc set serviceaccount deployment nginx-port80 saport80

コンテナが起動したのを確認。anyuid で起動させる事ができた。

$ oc get pods
NAME                            READY   STATUS              RESTARTS        AGE
nginx-port80-54746447ff-n4k5t   0/1     ContainerCreating   0               9s
nginx-port80-78f75798bc-qjftq   0/1     CrashLoopBackOff    11 (113s ago)   32m
$ oc get pods
NAME                            READY   STATUS    RESTARTS   AGE
nginx-port80-54746447ff-n4k5t   1/1     Running   0          32s
$ 

本筋はコンテナで公開するポートを変更しておく事。
コンテナレベルで変更しても公開するポートは 80/443 にできるし、後々のトラブルも減る。

restricted-v2

SCC は、現在 14種類ある。

 oc get scc
NAME                              PRIV    CAPS                      SELINUX     RUNASUSER          FSGROUP     SUPGROUP    PRIORITY     READONLYROOTFS   VOLUMES
anyuid                            false   <no value>                MustRunAs   RunAsAny           RunAsAny    RunAsAny    10           false            ["configMap","csi","downwardAPI","emptyDir","ephemeral","persistentVolumeClaim","projected","secret"]
hostaccess                        false   <no value>                MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <no value>   false            ["configMap","csi","downwardAPI","emptyDir","ephemeral","hostPath","persistentVolumeClaim","projected","secret"]
hostmount-anyuid                  false   <no value>                MustRunAs   RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["configMap","csi","downwardAPI","emptyDir","ephemeral","hostPath","nfs","persistentVolumeClaim","projected","secret"]
hostnetwork                       false   <no value>                MustRunAs   MustRunAsRange     MustRunAs   MustRunAs   <no value>   false            ["configMap","csi","downwardAPI","emptyDir","ephemeral","persistentVolumeClaim","projected","secret"]
hostnetwork-v2                    false   ["NET_BIND_SERVICE"]      MustRunAs   MustRunAsRange     MustRunAs   MustRunAs   <no value>   false            ["configMap","csi","downwardAPI","emptyDir","ephemeral","persistentVolumeClaim","projected","secret"]
machine-api-termination-handler   false   <no value>                MustRunAs   RunAsAny           MustRunAs   MustRunAs   <no value>   false            ["downwardAPI","hostPath"]
node-exporter                     true    <no value>                RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["*"]
nonroot                           false   <no value>                MustRunAs   MustRunAsNonRoot   RunAsAny    RunAsAny    <no value>   false            ["configMap","csi","downwardAPI","emptyDir","ephemeral","persistentVolumeClaim","projected","secret"]
nonroot-v2                        false   ["NET_BIND_SERVICE"]      MustRunAs   MustRunAsNonRoot   RunAsAny    RunAsAny    <no value>   false            ["configMap","csi","downwardAPI","emptyDir","ephemeral","persistentVolumeClaim","projected","secret"]
pcap-dedicated-admins             false   ["NET_ADMIN","NET_RAW"]   RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["awsElasticBlockStore","azureDisk","azureFile","cephFS","cinder","configMap","csi","downwardAPI","emptyDir","ephemeral","fc","flexVolume","flocker","gcePersistentDisk","gitRepo","glusterfs","iscsi","nfs","persistentVolumeClaim","photonPersistentDisk","portworxVolume","projected","quobyte","rbd","scaleIO","secret","storageOS","vsphere"]
privileged                        true    ["*"]                     RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["*"]
restricted                        false   <no value>                MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <no value>   false            ["configMap","csi","downwardAPI","emptyDir","ephemeral","persistentVolumeClaim","projected","secret"]
restricted-v2                     false   ["NET_BIND_SERVICE"]      MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <no value>   false            ["configMap","csi","downwardAPI","emptyDir","ephemeral","persistentVolumeClaim","projected","secret"]
splunkforwarder                   true    ["*"]                     RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["*"]
$ 

# 全部で 14種類ある
$ oc get scc | grep -v NAME | wc -l
14
$ 

良く見ると restricted-v2 では、 NET_BIND_SERVICE が Capability として追加されている。

これの restricted-v2は、OpenShift のデフォルトなので、何もしなくても Port 80 を LISTEN する Pod を起動できたのでは?と思ったのですが、以下の Kubernetes の issue があるため、そのままでは動作しないそう。

中身を見ると長い経緯があるため、簡単には解決しないような気が...

NET_BIND_SERVICE を許可した動作をさせたい場合は、spec.containers.securityContext.capabilities.add 等を使って Deployment に定義する事で動作させることができた。

<省略>
        app: test
        deployment: nginx-port80
    spec:
      containers:
      - image: docker.io/yuhkih/nginx-port80
        imagePullPolicy: IfNotPresent
        name: nginx-port80
        ports:
        - containerPort: 80
          protocol: TCP
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        capabilities:
          add: ["NET_BIND_SERVICE"]
<省略>
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?