DevOpsエンジニア完全ロードマップ
技術
DevOpsエンジニア完全ロードマップ
概要
DevOpsエンジニアは、開発と運用の橋渡しとなり、自動化、効率化、そして信頼性の高いソフトウェアデリバリーを実現する専門家です。2025年において、DevOpsはプラットフォームエンジニアリングへと進化し、開発者が高速に価値を提供できる再利用可能なセルフサービスインフラストラクチャを構築することが中心となっています。GitOps、AI駆動の自動化、そしてクラウドネイティブ技術が主流となっています。
詳細
フェーズ1: 基礎固め(3-6ヶ月)
Linux基礎とシステム管理
-
Linuxマスタリー
- シェルスクリプティング(Bash、Zsh)
- ファイルシステムとパーミッション
- プロセス管理とシステムリソース
- ネットワーク基礎(TCP/IP、DNS、HTTP/HTTPS)
- systemdとサービス管理
-
基本的なツール
- テキスト処理(grep、sed、awk)
- システム監視(top、htop、iostat、netstat)
- パッケージ管理(apt、yum、dnf)
- SSH設定とセキュリティ
プログラミングスキル
-
スクリプティング言語
- Python(自動化スクリプト)
- Go(ツール開発)
- JavaScript(Node.js環境)
-
バージョン管理
- Git完全理解(ブランチ戦略、マージ、リベース)
- GitLab/GitHub/Bitbucket
- コードレビューのベストプラクティス
クラウド基礎
- 主要クラウドプラットフォーム
- AWS(EC2、S3、IAM、VPC)
- Google Cloud Platform(Compute Engine、Cloud Storage)
- Azure(Virtual Machines、Storage Accounts)
フェーズ2: コンテナとオーケストレーション(6-12ヶ月)
Docker完全習得
-
コンテナ基礎
- Dockerfileの最適化
- マルチステージビルド
- イメージレイヤーの理解
- セキュリティスキャン(Trivy、Snyk)
-
実践的なDocker
- Docker Compose
- ボリュームとネットワーク
- レジストリ管理(Docker Hub、Harbor)
- イメージサイズの最小化(distroless、Alpine)
Kubernetes習得
-
コア概念
- アーキテクチャ(Control Plane、Worker Nodes)
- 基本リソース(Pod、Service、Deployment、StatefulSet)
- ストレージ(PV、PVC、StorageClass)
- ネットワーキング(Service、Ingress、NetworkPolicy)
-
高度な機能
- ConfigMapとSecrets管理
- RBAC(Role-Based Access Control)
- Helm Charts
- オートスケーリング(HPA、VPA、Cluster Autoscaler)
- Service Mesh(Istio、Linkerd)
Infrastructure as Code
-
Terraform
- HCL構文
- モジュール開発
- 状態管理とリモートバックエンド
- Terraformワークスペース
- プロバイダー開発
-
その他のIaCツール
- Ansible(構成管理)
- Pulumi(プログラマブルIaC)
- CloudFormation(AWS専用)
フェーズ3: CI/CDとGitOps(12-18ヶ月)
CI/CDパイプライン
-
GitHub Actions
- ワークフロー構築
- カスタムアクション開発
- マトリックスビルド
- セキュリティスキャン統合
- デプロイメント自動化
-
その他のCI/CDツール
- Jenkins(パイプラインas Code)
- GitLab CI/CD
- CircleCI
- ArgoCD(GitOps)
GitOps実践
-
GitOpsの原則
- 宣言的設定
- Gitを信頼できる唯一の情報源として使用
- 自動化されたデプロイメント
- 継続的な同期
-
実装パターン
- ArgoCD/Flux
- Kustomize
- Progressive Delivery(Flagger)
- ロールバック戦略
モニタリングとオブザーバビリティ
-
メトリクス収集
- Prometheus
- Grafana
- アラート設定(Alertmanager)
-
ログ管理
- ELK Stack(Elasticsearch、Logstash、Kibana)
- Fluentd/Fluent Bit
- Loki
-
分散トレーシング
- Jaeger
- Zipkin
- OpenTelemetry
フェーズ4: 高度なDevOpsとプラットフォームエンジニアリング(18-24ヶ月)
セキュリティ(DevSecOps)
-
コンテナセキュリティ
- イメージスキャン
- ランタイムセキュリティ(Falco)
- Pod Security Standards
- OPA(Open Policy Agent)
-
シークレット管理
- HashiCorp Vault
- Kubernetes Secrets
- External Secrets Operator
- SOPS
-
コンプライアンス自動化
- CIS Benchmarks
- STIG compliance
- 監査ログ
AI駆動の自動化
-
AIとMLOps統合
- 自己修復インフラストラクチャ
- 予測的スケーリング
- 異常検知
- インテリジェントアラート
-
ChatOpsとAI
- Slackボット自動化
- インシデント対応の自動化
- AI支援のトラブルシューティング
プラットフォームエンジニアリング
-
開発者エクスペリエンス
- セルフサービスポータル
- 内部開発者プラットフォーム(IDP)
- ゴールデンパス提供
- 開発環境の標準化
-
Platform as a Service構築
- Backstage(開発者ポータル)
- Crossplane(クラウドリソース管理)
- サービスカタログ
- コスト管理と最適化
SRE(Site Reliability Engineering)
-
信頼性の原則
- SLI/SLO/SLA定義
- エラーバジェット
- トイルの削減
- ポストモーテム文化
-
カオスエンジニアリング
- Chaos Monkey
- Litmus
- 障害注入テスト
- 復旧手順の自動化
メリット・デメリット
メリット
- 高い需要: DevOpsスキルは2025年も最も求められるスキルセットの一つ
- 幅広いスキル: インフラ、開発、セキュリティ全般の知識が身につく
- 自動化の達成感: 手作業を自動化し、効率を大幅に向上できる
- キャリアの柔軟性: SRE、プラットフォームエンジニア、クラウドアーキテクトへの道
- イノベーションの最前線: 最新技術を常に扱える環境
デメリット
- 学習範囲の広さ: 多岐にわたる技術スタックの習得が必要
- 常時待機の可能性: 24/7のシステム運用で緊急対応が必要
- 変化の速さ: ツールや技術の更新速度が非常に速い
- 責任の重さ: インフラ障害は全体に影響を与える
- ストレス: 複数チーム間の調整とコミュニケーション
参考ページ
- Kubernetes公式ドキュメント - Kubernetesの完全ガイド
- Terraform公式ドキュメント - Terraformリファレンス
- AWS Well-Architected Framework - AWSベストプラクティス
- Google SRE Books - Google SREハンドブック
- CNCF Landscape - クラウドネイティブツール一覧
- DevOps Roadmap - インタラクティブDevOpsロードマップ
- The Phoenix Project - DevOps小説
- GitOps Working Group - GitOps標準
書き方の例
GitHub ActionsによるCI/CDパイプライン
# .github/workflows/deploy.yml
name: Build and Deploy to Kubernetes
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-test:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results to GitHub Security
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
deploy:
needs: build-and-test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install kubectl
uses: azure/setup-kubectl@v3
with:
version: 'v1.28.0'
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Update kubeconfig
run: |
aws eks update-kubeconfig --name production-cluster --region ap-northeast-1
- name: Deploy to Kubernetes
run: |
kubectl set image deployment/app app=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sha-${GITHUB_SHA::7} -n production
kubectl rollout status deployment/app -n production
Terraform によるインフラストラクチャ構築
# main.tf - EKSクラスター構築
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.23"
}
}
backend "s3" {
bucket = "terraform-state-bucket"
key = "eks/terraform.tfstate"
region = "ap-northeast-1"
}
}
# VPCモジュール
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "${var.cluster_name}-vpc"
cidr = "10.0.0.0/16"
azs = data.aws_availability_zones.available.names
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
single_nat_gateway = false
enable_dns_hostnames = true
tags = {
"kubernetes.io/cluster/${var.cluster_name}" = "shared"
}
public_subnet_tags = {
"kubernetes.io/cluster/${var.cluster_name}" = "shared"
"kubernetes.io/role/elb" = "1"
}
private_subnet_tags = {
"kubernetes.io/cluster/${var.cluster_name}" = "shared"
"kubernetes.io/role/internal-elb" = "1"
}
}
# EKSクラスター
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "19.15.3"
cluster_name = var.cluster_name
cluster_version = "1.28"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
cluster_endpoint_public_access = true
eks_managed_node_group_defaults = {
instance_types = ["t3.medium"]
}
eks_managed_node_groups = {
main = {
name = "node-group-1"
instance_types = ["t3.medium"]
min_size = 2
max_size = 10
desired_size = 3
pre_bootstrap_user_data = <<-EOT
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p
EOT
}
}
# OIDC Provider for IRSA
enable_irsa = true
# クラスターアドオン
cluster_addons = {
coredns = {
most_recent = true
}
kube-proxy = {
most_recent = true
}
vpc-cni = {
most_recent = true
}
}
tags = var.tags
}
# ALB Controller用のIRSA
module "load_balancer_controller_irsa" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "5.30.0"
role_name = "${var.cluster_name}-aws-load-balancer-controller"
attach_load_balancer_controller_policy = true
oidc_providers = {
main = {
provider_arn = module.eks.oidc_provider_arn
namespace_service_accounts = ["kube-system:aws-load-balancer-controller"]
}
}
}
# Helm provider設定
provider "helm" {
kubernetes {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
args = ["eks", "get-token", "--cluster-name", var.cluster_name]
}
}
}
# AWS Load Balancer Controller
resource "helm_release" "aws_load_balancer_controller" {
name = "aws-load-balancer-controller"
repository = "https://aws.github.io/eks-charts"
chart = "aws-load-balancer-controller"
namespace = "kube-system"
version = "1.6.0"
set {
name = "clusterName"
value = var.cluster_name
}
set {
name = "serviceAccount.create"
value = "true"
}
set {
name = "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn"
value = module.load_balancer_controller_irsa.iam_role_arn
}
depends_on = [
module.eks
]
}
Kubernetes マニフェストとGitOps
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production
resources:
- deployment.yaml
- service.yaml
- ingress.yaml
- configmap.yaml
- hpa.yaml
configMapGenerator:
- name: app-config
envs:
- config.env
secretGenerator:
- name: app-secrets
envs:
- secrets.env
patchesStrategicMerge:
- replica-patch.yaml
images:
- name: myapp
newName: ghcr.io/myorg/myapp
newTag: v1.2.3
---
# argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: production-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-configs
targetRevision: HEAD
path: apps/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Prometheus による監視設定
# prometheus-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
data:
prometheus.yml: |
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
rule_files:
- /etc/prometheus/rules/*.yml
scrape_configs:
- job_name: 'kubernetes-apiservers'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
- job_name: 'kubernetes-nodes'
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
---
# alert-rules.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-rules
data:
node-alerts.yml: |
groups:
- name: node-alerts
interval: 30s
rules:
- alert: NodeCPUHigh
expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "Node CPU usage is high"
description: "CPU usage is above 80% (current value: {{ $value }}%)"
- alert: NodeMemoryHigh
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 85
for: 5m
labels:
severity: warning
annotations:
summary: "Node memory usage is high"
description: "Memory usage is above 85% (current value: {{ $value }}%)"
シェルスクリプトによる自動化
#!/bin/bash
# deploy.sh - 自動デプロイメントスクリプト
set -euo pipefail
# 変数定義
NAMESPACE="${NAMESPACE:-production}"
APP_NAME="${APP_NAME:-myapp}"
IMAGE_TAG="${IMAGE_TAG:-latest}"
TIMEOUT="${TIMEOUT:-300}"
# 関数定義
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*"
}
error() {
log "ERROR: $*" >&2
exit 1
}
# 前提条件チェック
check_prerequisites() {
log "Checking prerequisites..."
command -v kubectl >/dev/null 2>&1 || error "kubectl is not installed"
command -v helm >/dev/null 2>&1 || error "helm is not installed"
kubectl cluster-info >/dev/null 2>&1 || error "Cannot connect to Kubernetes cluster"
log "Prerequisites check passed"
}
# デプロイメント実行
deploy_application() {
log "Starting deployment of ${APP_NAME} with tag ${IMAGE_TAG}..."
# Namespace作成(存在しない場合)
kubectl create namespace "${NAMESPACE}" --dry-run=client -o yaml | kubectl apply -f -
# ConfigMapとSecret更新
kubectl apply -f configs/ -n "${NAMESPACE}"
# Helmチャートでデプロイ
helm upgrade --install "${APP_NAME}" ./charts/"${APP_NAME}" \
--namespace "${NAMESPACE}" \
--set image.tag="${IMAGE_TAG}" \
--set replicaCount=3 \
--wait \
--timeout="${TIMEOUT}s"
log "Deployment completed successfully"
}
# ヘルスチェック
health_check() {
log "Performing health check..."
# Deploymentの状態確認
kubectl rollout status deployment/"${APP_NAME}" -n "${NAMESPACE}" --timeout="${TIMEOUT}s"
# Podの準備状態確認
ready_pods=$(kubectl get pods -n "${NAMESPACE}" -l app="${APP_NAME}" -o json | jq '.items | map(select(.status.conditions[] | select(.type=="Ready" and .status=="True"))) | length')
total_pods=$(kubectl get pods -n "${NAMESPACE}" -l app="${APP_NAME}" -o json | jq '.items | length')
if [[ "${ready_pods}" -ne "${total_pods}" ]]; then
error "Not all pods are ready: ${ready_pods}/${total_pods}"
fi
log "Health check passed: ${ready_pods}/${total_pods} pods are ready"
}
# メイン処理
main() {
log "Deployment script started"
check_prerequisites
deploy_application
health_check
log "Deployment completed successfully!"
}
# スクリプト実行
main "$@"