Kubernetes ポッドの/etc/hosts に静的ドメイン解決を追加する設定手順

DNS 解決とホストエイリアスの必要性

Kubernetes クラスター内で構築されたアプリケーションが、社内向けのサービス(Git、Nexus、Nacos など)へ依存している場合、それらのドメイン名がパブリック DNS に登録されていないことが一般的です。この場合、Pod からはこれらのエンドポイントへの接続が不可能になります。

この問題を解決するためには、各 Pod のコンテナイメージに含まれる `/etc/hosts` ファイルに手動で IP アドレスとドメインのマッピングを追加する必要があります。Kubernetes においては、Deployment マニフェストの `spec.template.spec.hostAliases` フィールドを使用することで、これが自動的に実行されます。

RBAC 権限設定

Jenkins や CI/CD ツールとして動作する Pod がクラスター内の他のポッドやログ、シークレットにアクセスするには、適切なロールベースのアクセス制御(RBAC)設定が必要です。以下は、ServiceAccount とそれに紐づく Role、RoleBinding の定義例です。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: pipeline-agent
  namespace: production-env

---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: pod-manager
  namespace: production-env
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-binding
  namespace: production-env
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-manager
subjects:
  - kind: ServiceAccount
    name: pipeline-agent
    namespace: production-env

永続ストレージの準備

CI ツールの設定情報やビルド成果物を保持するために、NFS プロトコルを使用した永続ボリュームが必要です。PersistentVolume(PV) と PersistentVolumeClaim(PVC) を定義します。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: app-storage
spec:
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 192.168.10.50
    path: /srv/shared/jenkins-workspace

---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: app-claim
  namespace: production-env
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 100Gi

アプリケーションデプロイメントとホストエイリアス

ここが重要な箇所です。`hostAliases` セクションで内部ネットワークの IP とドメイン名を指定し、Pod 起動時に `/etc/hosts` に書き込みます。また、セキュリティコンテキストやリソース制限も適切に設定しています。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: build-service
  namespace: production-env
spec:
  selector:
    matchLabels:
      app: build-service
  template:
    metadata:
      labels:
        app: build-service
    spec:
      serviceAccountName: pipeline-agent
      terminationGracePeriodSeconds: 30
      
      # ポッド内部の /etc/hosts にエントリを追加
      hostAliases:
      - ip: "192.168.10.60"
        hostnames:
        - "git.internal.local"
        - "maven.internal.local"
        - "docker-registry.internal.local"
        - "nexus.internal.local"
      
      containers:
      - name: build-tool
        image: jenkins/jenkins:lts
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        - containerPort: 50000
          name: agent-port
          protocol: TCP
        
        env:
        - name: JAVA_OPTS
          value: "-Xmx5g -Duser.timezone=Asia/Tokyo"
          
        livenessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 90
          timeoutSeconds: 10
        readinessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 5
        
        volumeMounts:
        - name: workspace
          mountPath: /var/jenkins_home
        resources:
          requests:
            cpu: "2"
            memory: "4Gi"
          limits:
            cpu: "4"
            memory: "8Gi"
            
      securityContext:
        fsGroup: 1000
      
      volumes:
      - name: workspace
        persistentVolumeClaim:
          claimName: app-claim

Ingress リソースによる外部公開

定義したデプロイメントを外部からアクセス可能にするために、nginx インゲレスコントローラー向けにルールを設定します。古い API バージョンではなく、最新の networking.k8s.io/v1 を使用する推奨構成です。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: build-access
  namespace: production-env
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "2g"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "900"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "900"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - host: "build-platform.example.com"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: build-service
            port:
              number: 8080

タグ: Kubernetes hostAliases nginx-ingress persistent-volume rbac

10月14日 06:49 投稿