概要
IBMCloudでOpenshiftの内部イメージにdockerhubから取得したnginxをアップロードし、openshift環境でnginxコンテナを動作させるための手順・ログを備忘録も兼ねて記事としています。
以下のIBMCloud Docsを参考に実行しております
内部レジストリーのためのセキュアな外部経路のセットアップ
環境情報
以下の環境での操作を実施しました。
- IBMCloud Openshift 4.13.43 on VPC
- Macbook(M1)
作業手順
- Step1. OpenShiftにログイン
% oc login --token=sha256~0g_kxEI8rPoxxxxxxxxxxxxxxxxxxxdYY --server=https://xxxxxx.jp-tok.containers.cloud.ibm.com:30916
Logged into "https://xxxxxx.jp-tok.containers.cloud.ibm.com:30916" as "IAM#xxxxxxxxxxx@xxx.com" using the token provided.
You have access to 65 projects, the list has been suppressed. You can list all projects with 'oc projects'
Using project "default".
%
- Step2. Openshift上にimage-registryサービスが存在することを確認
% oc get svc -n openshift-image-registry
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
image-registry ClusterIP 172.21.164.24 <none> 5000/TCP 105m
image-registry-operator ClusterIP None <none> 60000/TCP 129m
%
- Step3. image-registryサービスのためにTLS終端処理を使用したセキュアな経路を作成する(Dockerファイルをアップロードするための経路)
% oc create route reencrypt --service=image-registry -n openshift-image-registry
route.route.openshift.io/image-registry created
%
- Step4. ルート情報を取得(Host部分のFQDNを後ほど利用する)
% oc get route image-registry -n openshift-image-registry
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
image-registry image-registry-openshift-image-registry.acs-paas-oc-cluster3-jp-t-d13c20a30062048xxxxxxxxxxxxxxxxxx.jp-tok.containers.appdomain.cloud image-registry 5000-tcp reencrypt None
%
-
Step5. HAエンドポイントにアクセスするクライアントが同じイメージレジストリ(Node?)接続先に振られるようにLB設定をSource指定にしておく
- image-registryファイルをoc editで編集する
$ oc edit route image-registry -n openshift-image-registry
-
Step7. Step5のホスト名(ルート情報)を使用してOpenshiftのレジストリーにログイン
% docker login -u $(oc whoami) -p $(oc whoami -t) image-registry-openshift-image-registry.acs-paas-oc-cluster3-jp-t-d13c20a3006204xxxxxxxxxxxxxxx-0000.jp-tok.containers.appdomain.cloud
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded
%
-
Step6. DockerHubからnginxイメージをPullする
- まず、ローカルマシンにNginxのイメージをPullします
(MAC端末がM1(ARMアーキテクチャ)CPUのため、platform指定を忘れずに行う)
- まず、ローカルマシンにNginxのイメージをPullします
$ docker pull --platform linux/x86_64 nginx:latest
DockerHubからnginxイメージをPullするには、Dockerにログインしている必要があります。
公式サイトを参照
- Step7. openshiftでnginxを動かすプロジェクトを作成
% oc new-project nginx-project
- Step8. LocalPCにあるnginxイメージファイルへのイメージタグ付けとOpenshiftへのPush
$ docker tag nginx:latest image-registry-openshift-image-registry.xxx-paas-oc-cluster3-jp-t-d13c20a300620486546182a0effecxxxxxxxx.jp-tok.containers.appdomain.cloud/nginx-project/nginx:latest
$ docker push image-registry-openshift-image-registry.xxx-paas-oc-cluster3-jp-t-d13c20a300620486546182a0effecxxxxxxxx.jp-tok.containers.appdomain.cloud/nginx-project/nginx:latest
- Step9. Push後、Openshift上にnginxのイメージストリームが作成されていることを確認
% oc get imagestream
NAME IMAGE REPOSITORY TAGS UPDATED
nginx image-registry.openshift-image-registry.svc:5000/nginx-project/nginx latest 3 minutes ago
%
-
Step10. プロジェクトのデプロイメントで、この内部レジストリーからイメージをプルできるように、内部レジストリーにアクセスするための資格情報を保持するイメージ・プル・シークレットをプロジェクト内に作成
- デフォルトのイメージプルで利用されているシークレット情報をメモ
-> "Image pull secrets: default-dockercfg-bd4kd"
- デフォルトのイメージプルで利用されているシークレット情報をメモ
% oc describe sa default
Name: default
Namespace: nginx-project
Labels: <none>
Annotations: <none>
Image pull secrets: default-dockercfg-bd4kd
Mountable secrets: default-dockercfg-bd4kd
Tokens: default-token-grl5w
Events: <none>
%
- Step11. 構成ファイルの data フィールドから、エンコードされたシークレット情報を取得(Dataフィールドは長文情報のためここでは出力結果は省略しています)
$ oc get secret default-dockercfg-bd4kd -o yaml
- Step12. 出力されたdataフィールドの値をbase64でデコードします
$ echo "<ey...=>" | base64 -D
- Step13. 上記デコードした情報を利用し、内部レジストリーの新規ImagePullSecretを作成する
公式Docs(2024/7/4時点)では"oc create secret image-registry xxxx"とありますが、エラーになりコマンド構文としては、"oc create secret docker-registry xxxx"が正しいと思われます。
% oc create secret docker-registry internal-registry --namespace nginx-project --docker-server image-registry-openshift-image-registry.xxx-paas-oc-cluster2-jp-t-d13c20a300620486546182a0xxxxxxxxxx-0000.jp-tok.containers.appdomain.cloud:5000 --docker-username serviceaccount --docker-password <eyxxxxxxxxxxxxxxx> --docker-email serviceaccount@example.org
secret/internal-registry created
eranaoki@Naokis-MBP ~ %
eranaoki@Naokis-MBP ~ % oc get secret -n nginx-project
NAME TYPE DATA AGE
builder-dockercfg-z6gsn kubernetes.io/dockercfg 1 126m
builder-token-9g6nx kubernetes.io/service-account-token 4 126m
(一部省略)
internal-registry kubernetes.io/dockerconfigjson 1 7s
%
- Step14. イメージ・プル・シークレットをプロジェクトのデフォルトの"サービス・アカウント"に追加
oc patch -n nginx-project serviceaccount/default --type='json' -p='[{"op":"add","path":"/imagePullSecrets/-","value":{"name":"<image_pull_secret_name>"}}]'
(補足説明)
サービス・アカウントとは、通常のUserとは別に、Podや各種コンポーネントがAPI呼び出しを行うために設計されたKubernetesのオブジェクトです。Jenkinsなどでアプリケーションを自動化する際にも利用されます。普段使っているPodにも必ず1つのService Accountが紐づいています。Pod作成時にService Accountを明示的に指定しなかった場合そのnamespaceのdefaultという名前のService Accountが紐づけられます。
- Step15. サービスアカウント"default"に対して anyuid SCC を適用
% oc adm policy add-scc-to-user anyuid -z default
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:anyuid added: "default"
%
要確認:
OpenShiftでは、Security Context Constraints (SCC) を使用して、ポッドがどのように実行されるかを制御します。デフォルトでは、ポッドは特定の制限の下で実行されますが、これにより一部のアプリケーション(特にrootユーザーとしての実行を必要とするnginxのようなソフトウェア)が正常に動作しないことがあります。
今回はNginxを起動するためにサービス・アカウント("default")でroot権限にてコンテナ起動ができるようにするため上記コマンドを実行しています。セキュリティ設計の考慮は別途ご検討が必要な点に注意ください。
- Step16. nginxを内部イメージレジストリから起動する (YAMLファイルで定義)
(今回はimageに先述の"oc get imagestream"で確認したイメージストリーム"image-registry.openshift-image-registry.svc:5000/nginx-project/nginx:latest"を指定します)
#nginxを内部イメージレジストリから起動し、80portをListenさせる
#nginx-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: >-
image-registry.openshift-image-registry.svc:5000/nginx-project/nginx:latest
ports:
- containerPort: 80
securityContext:
runAsUser: 0
runAsGroup: 0
volumeMounts:
- name: nginx-cache
mountPath: /var/cache/nginx
volumes:
- name: nginx-cache
emptyDir: {}
- Step17. nginxのPod起動および確認
# Project(namespace)をnginx-projectに切替
% oc project nginx-project
Now using project "nginx-project" on server "https://c115-e.jp-tok.containers.cloud.ibm.com:30916".
%
# nginx pod起動
% oc apply -f nginx-test.yml
deployment.apps/nginx-deployment created
# podの確認
# 172.17.139.252のIPアドレスで稼働していることが確認できる
% oc get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-8cfddb7b5-dcbmw 1/1 Running 0 13s 172.17.139.252 10.244.0.5 <none> <none>
%
- Step18. nginx稼働確認のためにalpineイメージのPodを作成し、curl確認を行う
# alpine Podを起動
% oc run alpine-temp --image=alpine --command -- sleep 3600
pod/alpine-temp created
% oc get pod
NAME READY STATUS RESTARTS AGE
alpine-temp 1/1 Running 0 6s
nginx-deployment-8cfddb7b5-dcbmw 1/1 Running 0 17m
%
# alpineへログインし、Curlを追加
% oc exec -it alpine-temp -- sh
/ #
/ # apk add curl
fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/community/x86_64/APKINDEX.tar.gz
(1/10) Installing ca-certificates (20240226-r0)
(2/10) Installing brotli-libs (1.1.0-r2)
(3/10) Installing c-ares (1.28.1-r0)
(4/10) Installing libunistring (1.2-r0)
(5/10) Installing libidn2 (2.3.7-r0)
(6/10) Installing nghttp2-libs (1.62.1-r0)
(7/10) Installing libpsl (0.21.5-r1)
(8/10) Installing zstd-libs (1.5.6-r0)
(9/10) Installing libcurl (8.8.0-r0)
(10/10) Installing curl (8.8.0-r0)
Executing busybox-1.36.1-r29.trigger
Executing ca-certificates-20240226-r0.trigger
OK: 13 MiB in 24 packages
/ #
# curlでのnginx稼働確認し、"Welcome to nginx!"のHTML情報が取得できることを確認
/ # curl http://172.17.139.252
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
/ #
これで内部イメージレジストリからnginxが起動できるようになりました。