概要
以前投稿した「GitHub Actionsを使用してOKEへのDevOps実施」を元に以下の点を改善しました
- できるだけハンズオンできるよう作成手順を追加
- イメージタグに作成日付(YYYYMMDDhhmm)を追加
- イメージを世代管理する(今回は3世代管理)
構成
ソースコードリポジトリはGitHubを利用しています。
GitHub ActionsにてBuild、コンテナレジストリへのPushとKubernetesのマニフェストを使用したdeployを行っています。

GithubにCode Pushしたタイミングで以下を実施します
- Build
- コンテナレジストリにコンテナイメージPush
- KubernetesにDeploy
- コンテナイメージ3世代保持するため古いイメージは削除します
前提
GitHub Actionsを使用してOKEへのDevOps実施することをターゲットとしていますので環境については
既に利用していることを前提にしています
- GitHubを利用したことがある
- OCI OKEクラスターを構築済み
- OCI コンテナレジストリにイメージをPushしたことがある
- OCI CLIを利用したことがある
- Linux上のDockerまたはPodman環境 (筆者環境はOracle Linuxを利用)
Oracle Linuxは、オラクル社が開発・提供する、Red Hat Enterprise Linux (RHEL) とバイナリ互換性を持つ無償のLinuxディストリビューションです。
https://www.oracle.com/jp/linux/
コンテンツ作成とGitHubへのPush
サンプルアプリケーションとしてNginxを使用しました。
Local build
サンプルアプリケーションを準備してLocalでBuildできることを確認します
- ファイル準備
|--Dockerfile
+--conf
| +--default.conf
+--src
+--index.html
FROM nginx:latest
COPY ./conf/default.conf /etc/nginx/conf.d/default.conf
COPY ./src/ /var/www/html/
server {
listen 8080 default_server;
server_name localhost;
location / {
root /var/www/html;
index index.php index.html index.htm;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>nginx test</title>
</head>
<body>
<h1>Hello, Nginx! ver0.1</h1>
</body>
</html>
- Build,Runして実施確認
$ podman build ./ -t nginxtest
$ podman run -d -p 8080:8080 nginxtest
$ curl http://127.0.0.1:8080
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>nginx test</title>
</head>
<body>
<h1>Hello, Nginx! ver0.1</h1>
</body>
</html>
- 確認できたら不要リソースは削除
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
<<ContainerID>> localhost/nginxtest:latest nginx -g daemon o... 4 minutes ago Up 4 minutes 0.0.0.0:8080->8080/tcp ecstatic_galileo
$ podman stop <<ContainerID>>
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/nginxtest latest <<ImageID>> 2 minutes ago 197 MB
$ podman rmi --force <<ImageID>>
Github環境準備
GithubリポジトリやGithub Actionsの実行環境を準備します
リポジトリ作成
- Github login後Repositoriesに移動
- Newを押下
- 以下を設定してcreate repositoryを押下
- Create a new repository
- Repository name: nginxtest
- Choose visibility : Private
- 作業PCにgithub clone用のフォルダを作成
- create a new repository on the command lineの手順を実施
echo "# nginxtest" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/<<Username>>/nginxtest.git
git push -u origin main
Github Actions workflow
- GithubメニューからActionsに移動
- Simple workflowのConfigureを押下
- Commit changesを押下
- そのままCommit changesを押下
- 作業PCにpullしてblank.ymlがあることを確認
$ git pull
$ ls .github/workflows/blank.yml
.github/workflows/blank.yml
Github Actions secrets
- Github repositoryからSettings>>Secrets and variables>>Actionsに移動
- New repository secretを押下
- GitHub Repository secretsに以下を設定してAdd secretを押下
- OCI_CLI_USER: OCI UserのOCID
- OCI_CLI_TENANCY: OCIテナンシーのOCID
- OCI_CLI_FINGERPRINT: OCI Userで追加したAPIキーFingerprintのOCID
- OCI_CLI_KEY_CONTENT: OCI Userで追加したAPIキーの秘密キー
注:認証トークンに"OCI_API_KEY"を追加することが推奨とされています
Oracle Cloud Infrastructureドキュメント 必要なキーとOCIDを確認してください - OCI_CLI_REGION: リージョン(例:ap-tokyo-1)
- OKE_CLUSTER_OCID: OKEクラスターのOCID
- OCI_AUTH_TOKEN: OCI Userで追加した認証トークン
OCI ポリシー設定
Github ActionsからOCI操作を行うために以下のOCIにポリシーを設定します。
-
OCIRを管理可能とするポリシー
Allow Group ‘userが所属するグループ名’ to manage all-artifacts in compartment ‘コンパートメント名’ -
OKEを管理するためのポリシー
Allow Group ‘userが所属するグループ名’ to manage cluster-family in compartment ‘コンパートメント名’
コンテナ・レジストリ作成
コンテナイメージの格納先を作成します。
- OCIナビゲーションメニューから開発者サービス>>コンテナとアーティファクト>>コンテナ・レジストリを選択して「リポジトリの作成」を押下
- リポジトリ名に<>で設定した値を入力して「作成」を押下
ファイル準備
|--README.md
|--.github
| +--workflows
| +--Build_Push_Deploy.yml
|--.git
|--Dockerfile
|--conf
| +--default.conf
|--src
| +--index.html
+--deployment.yaml
-
Dockerfile,default.conf,index.html
Local Buildで確認したファイルをコピーします -
deployment.yaml
container imageタグはGitHub Actions Workflowで変更するので0000000000としています
また、docker-registry-secretは未設定の場合は以下を参考に設定します
## Replace << >> with the appropriate value
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginxtest-deployment
labels:
app: nginxtest
spec:
replicas: 1
selector:
matchLabels:
app: nginxtest
template:
metadata:
labels:
app: nginxtest
spec:
containers:
- name: nginxtest
image: <<OCIR endpoint>>/<<namespace>>/<<repository>>:000000000000
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
imagePullSecrets:
- name: <<docker-registry-secret>> # secretとして登録したOCIRのlogin情報を使用
---
apiVersion: v1
kind: Service
metadata:
name: nginxtest-svc
spec:
selector:
app: nginxtest
ports:
- port: 8086 # ServiceのExpose port
targetPort: 8080 # nginx confファイルで設定したnginxのlisten port
nodePort: 30991 # nodeで公開するport
type: NodePort
- GitHub Actions Workflow
Build, Push, Deployしてコンテナイメージ3世代保持するため古いイメージは削除します
## Replace << >> with the appropriate value
name: Build_Push_Deploy
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
env:
OCI_CLI_USER: ${{ secrets.OCI_CLI_USER }}
OCI_CLI_TENANCY: ${{ secrets.OCI_CLI_TENANCY }}
OCI_CLI_FINGERPRINT: ${{ secrets.OCI_CLI_FINGERPRINT }}
OCI_CLI_KEY_CONTENT: ${{ secrets.OCI_CLI_KEY_CONTENT }}
OCI_CLI_REGION: ${{ secrets.OCI_CLI_REGION }}
COMPARTMENT_ID: <<Compartment OCID>>
DOMAIN_NS: <<OCIR endpoint>>/<<namespace>>
REPOSITORY_NAME: <<repository>>
steps:
# ソースコードをclone
- uses: actions/checkout@v3
# GitHub Actions で日時タグを取得
- name: Set timestamp tag
run: echo "IMAGE_TAG=$(date +'%Y%m%d%H%M')" >> $GITHUB_ENV
# Dockerfileを元にbuild
- name: Build the docker image
id: build-docker-image
run: docker build . --file Dockerfile --tag ${DOMAIN_NS}/${REPOSITORY_NAME}:${IMAGE_TAG}
# OCI コンテナレジストリにlogin
- name: Log into OCIR
uses: oracle-actions/login-ocir@v1.2.1
id: login-into-ocir
with:
auth_token: ${{ secrets.OCI_AUTH_TOKEN }}
# コンテナをOCI コンテナレジストリにpush
- name: Push a container image
id: push-container-image
run: docker push ${DOMAIN_NS}/${REPOSITORY_NAME}:${IMAGE_TAG}
# OCI OKEの構成
- name: Kubectl cluter
uses: oracle-actions/configure-kubectl-oke@v1.5.0
id: kubectl-cluster
with:
cluster: ${{ secrets.OKE_CLUSTER_OCID }}
# コンテナイメージタグを書き換えてdeployment.yamlをapply
- name: Kubectl apply
id: kubectl-apply
run: |
sed -i "s/000000000000/${IMAGE_TAG}/g" deployment.yaml
kubectl apply -f deployment.yaml
# OCI CLIをインストール
- name: Install OCI CLI
run: pip install oci-cli
# OCI CLIを構成
- name: Configure OCI CLI
run: |
mkdir -p ~/.oci
echo -e "${OCI_CLI_KEY_CONTENT}" > ~/.oci/oci_api_key.pem
chmod 600 ~/.oci/oci_api_key.pem
cat <<EOF > ~/.oci/config
[DEFAULT]
user=${OCI_CLI_USER}
fingerprint=${OCI_CLI_FINGERPRINT}
tenancy=${OCI_CLI_TENANCY}
region=${OCI_CLI_REGION}
key_file=~/.oci/oci_api_key.pem
EOF
# 古いイメージを削除
- name: Delete old image versions
run: |
IMAGE_JSON=$(oci artifacts container image list \
--compartment-id $COMPARTMENT_ID \
--repository-name $REPOSITORY_NAME \
--region $OCI_CLI_REGION \
--all \
--output json)
DELETE_IDS=$(echo "$IMAGE_JSON" | jq -r "
.data.items
| sort_by(.[\"time-created\"]) | reverse
| map(select(.\"lifecycle-state\" == \"AVAILABLE\"))
| .[3:][] | [.id] | @tsv
")
if [ -z "$DELETE_IDS" ]; then
echo "No image IDs found to delete."
else
echo "$DELETE_IDS" | while read OLD_IMAGEID; do
echo "Deleting image id: $OLD_IMAGEID"
oci artifacts container image delete \
--image-id "$OLD_IMAGEID" \
--force
done
fi
実行結果
Code PushするとWorkflowが開始します。
$ git add -A
$ git commit -m "update"
$ git push
$ kubectl get all #4世代更新後
NAME READY STATUS RESTARTS AGE
pod/nginxtest-deployment-cbfff6659-qqv9r 2/2 Running 0 2m28s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginxtest-svc NodePort 10.96.113.232 <none> 8086:30991/TCP 2m28s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginxtest-deployment 1/1 1 1 2m28s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginxtest-deployment-6b9fd68b4 0 0 0
replicaset.apps/nginxtest-deployment-7b6dd76b8d 0 0 0
replicaset.apps/nginxtest-deployment-cbfff6659 0 0 0
replicaset.apps/nginxtest-deployment-fc79775db 1 1 1
稼働確認します
以下は4世代めの更新です
## Replace << >> with the appropriate value
$ curl http://<<node ip address>>:30991/
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>nginx test</title>
</head>
<body>
<h1>Hello, Nginx! ver0.4</h1>
</body>
</html>
更新すると一番古いイメージが削除され3世代維持しています
更新前
<<repository>>(プライベート) [3 images]
<<repository>>:202510030839
<<repository>>:202510030845
<<repository>>:202510030849
更新後
<<repository>>(プライベート) [3 images]
<<repository>>:202510030845
<<repository>>:202510030849
<<repository>>:202510030854