アプリケーションコンテナへの Python エージェントの展開

Python アプリケーションをインストゥルメント化するには、必要な Python エージェントパッケージをアプリケーションコンテナに展開し、スタートアップ時にアプリケーションによってロードする必要があります。次のオプションを使用できます。

  • Dockerfile の使用:このオプションでは、作成時に Dockerfile を使用して、アプリケーションの Docker イメージに Python エージェントを展開します。
  • Init コンテナの使用:このオプションでは、アプリケーションのスタートアップ時に Kubernetes init コンテナを使用して、アプリケーションコンテナに Python エージェントを展開します。init コンテナのオプションを使用する場合でも、アプリケーションの Docker イメージを変更する必要はありません。

各オプションについて、この手順では、サイドカーを使用してダイナミック言語プロキシを実行してること、および以下のことを前提としています。

Python エージェントを展開したら、「Python エージェントのインストールの検証」を参照してください。

注: クラスタエージェントの自動インストルメンテーションは、クラスタエージェントがインストールされている Kubernetes クラスタで実行されている Python アプリケーションではサポートされないことに注意してください。「コンテナのインストールオプション」を参照してください。

Dockerfile の使用

注: このオプションは、Docker および Kubernetes で実行されているコンテナに適用されます。

このオプションでは、作成時に Dockerfile を使用して、Docker イメージに Python エージェントを展開します。作成された Docker イメージには、アプリケーションと Python エージェントが含まれている必要があります。

イメージの作成時にエージェントをアプリケーションイメージに展開するには、次の手順を実行します。

  1. イメージへのアプリケーションファイルのコピー
  2. PIP インストールの実行
  3. (オンプレミスコントローラのみ)コントローラ証明書のイメージへのコピーイメージへのコントローラ証明書のコピー(オンプレミスコントローラのみ)イメージへのコントローラ証明書のコピー(オンプレミスコントローラのみ)
  4. Pyagent を使用したアプリケーションの実行
  5. Python エージェント環境変数の設定
  6. Python エージェントのインストールの検証

イメージへのアプリケーションファイルのコピー

Dockerfile を編集してアプリケーションフォルダをコピーし、要件を設定してスクリプトを開始します。

COPY mypythonapp/ /app/
WORKDIR /app
COPY requirements.txt .
RUN chmod +x ./app.py
EXPOSE 8080

PIP インストールの実行

pip install appdynamics Python エージェントのインストールを実行します。最新の AppDynamics Python プロジェクトのバージョンを指定します。例:

RUN pip install -U appdynamics==21.12.2.4693 -r requirements.txt

イメージへのコントローラ証明書のコピー(オンプレミスコントローラのみ)

オンプレミスコントローラと通信する Python エージェントの場合は、Dockerfile を編集して APPDYNAMICS_CONTROLLER_SSL_CERTFILE の cacerts をコピーします。

例:

COPY ./onprem-cacerts /opt/appdynamics/cacerts
ENV APPDYNAMICS_CONTROLLER_SSL_CERTFILE=/opt/appdynamics/cacerts

Pyagent を使用したアプリケーションの実行

WSGI フレームワークの追加サポートには、pyagent --use-manual-proxy Python エージェントのインストールを使用します。必要な場合は、

CMD pyagent run --use-manual-proxy python ./app.py

完全な Dockerfile Pyagent の例:

FROM python:3.7
# Use latest version from https://pypi.org/project/appdynamics/#history
ENV APPD_AGENT_VERSION=21.12.2.4693
COPY mypythonapp/ /app/
WORKDIR /app
RUN chmod +x ./app.py
EXPOSE 8080
RUN pip install -U appdynamics==${APPD_AGENT_VERSION} -r requirements.txt
CMD pyagent run --use-manual-proxy python ./app.py

Python エージェント環境変数の設定

注: APPDYNAMICS_TCP_COMM_POR は、アプリケーションおよびプロキシコンテナで使用可能なポートに設定する必要があり、エージェントからプロキシへの通信に使用されることに注意してください。「TCP モードの設定」を参照してください。

Python エージェント環境変数の設定方法は、イメージの展開方法によって異なります。Docker 展開の場合、Dockerfile または指定した外部ファイルのエージェント環境変数をパラメータとして docker run に設定します。

ENV APPDYNAMICS_TCP_COMM_PORT=9091
ENV APPDYNAMICS_AGENT_APPLICATION_NAME=<value>
ENV APPDYNAMICS_AGENT_TIER_NAME=<value>
ENV APPDYNAMICS_AGENT_REUSE_NODE_NAME=true
ENV APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX=<value>
ENV APPDYNAMICS_AGENT_ACCOUNT_NAME=<value>
ENV APPDYNAMICS_AGENT_ACCOUNT_ACCESS_KEY=<value>
ENV APPDYNAMICS_CONTROLLER_HOST_NAME=<value>
ENV APPDYNAMICS_CONTROLLER_PORT=<value>
ENV APPDYNAMICS_CONTROLLER_SSL_ENABLED=<value>
ENV APPDYNAMICS_AGENT_CONTAINER_ENABLED=true

Kubernetes アプリケーションの場合は、「Kubernetes でエージェントを設定するためのベストプラクティス」の説明に従って、configmap、秘密、および導入仕様を使用してこれらの環境変数を設定します。

  1. configmap appd-python-config.yaml の使用

    apiVersion: v1
    data:
    APPDYNAMICS_TCP_COMM_PORT: "9091"
    APPDYNAMICS_AGENT_APPLICATION_NAME: "<value>"
    APPDYNAMICS_AGENT_REUSE_NODE_NAME: "<value>"
    APPDYNAMICS_AGENT_ACCOUNT_NAME: "<value>"
    APPDYNAMICS_CONTROLLER_HOST_NAME: "<value>"
    APPDYNAMICS_CONTROLLER_PORT: "<value>"
    APPDYNAMICS_CONTROLLER_SSL_ENABLED: "<value>"
    kind: ConfigMap
    metadata:
    name: appd-python-config
  2. ConfigMap の適用

    $ kubectl -n <app-ns> apply -f appd-python-config.yaml
  3. 導入仕様を更新して ConfigMap を参照します。

    spec:
    containers:
    - name: python-app
    envFrom:
    - configMapRef:
    name: appd-python-config
    ...
  4. kubectl を使用してコントローラアクセスキーのシークレットを作成します。

    $ kubectl -n <app-ns> create secret generic appd-agent-secret --from-literal=access-key=<access-key>
  5. 導入仕様を更新して、秘密を参照します。

    spec:
    containers:
    - name: python-app
    env:
    - name: APPDYNAMICS_AGENT_ACCOUNT_ACCESS_KEY
    valueFrom:
    secretKeyRef:
    name: appd-agent-secret
    key: access-key
    ...
  6. アプリケーション固有の階層名環境変数(APPDYNAMICS_AGENT_TIER_NAME)を設定します。

    spec:
    containers:
    - name: python-app
    env:
    - name: APPDYNAMICS_AGENT_TIER_NAME
    value: python-service
    - name: APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX
    value: python-service
    ...
  7. プロキシコンテナを追加します

    spec:
    containers:
    ...
    - name: proxy
    image: appdynamics/dl-proxy:latest
    imagePullPolicy: Always
    env:
    - name: APPDYNAMICS_DEBUG_LOG
    value: "on"
    - name: APPDYNAMICS_LOGGING_LEVEL
    value: "debug"
    - name: APPDYNAMICS_TCP_COMM_HOST
    value: "0.0.0.0"
    - name: APPDYNAMICS_TCP_COMM_PORT
    value: "9091"
    - name: APPDYNAMICS_TCP_PORT_RANGE
    value: "10000-10100"
    ports:
    - containerPort: 9091
    protocol: TCP
    resources:
    limits:
    cpu: 500m
    memory: 900M
    requests:
    cpu: 400m
    memory: 600M
    ...

    Kubernetes 導入仕様の完全な例を以下に示します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: mypython-app
    spec:
    selector:
    matchLabels:
    name: mypython-app
    replicas: 1
    template:
    metadata:
    labels:
    name: mypython-app
    spec:
    containers:
    - name: mypython-app
    image: myrepo/python-app-with-appd:v1
    imagePullPolicy: Always
    env:
    - name: APPDYNAMICS_AGENT_TIER_NAME
    value: mypython-app
    - name: APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX
    value: python-service
    - name: APPDYNAMICS_AGENT_ACCOUNT_ACCESS_KEY
    valueFrom:
    secretKeyRef:
    key: access-key
    name: appd-agent-secret
    envFrom:
    - configMapRef:
    name: appd-python-config
    ports:
    - containerPort: 8080
    - name: proxy
    image: appdynamics/dl-proxy:latest
    imagePullPolicy: Always
    env:
    - name: APPDYNAMICS_DEBUG_LOG
    value: "on"
    - name: APPDYNAMICS_LOGGING_LEVEL
    value: "debug"
    - name: APPDYNAMICS_TCP_COMM_HOST
    value: "0.0.0.0"
    - name: APPDYNAMICS_TCP_COMM_PORT
    value: "9091"
    - name: APPDYNAMICS_TCP_PORT_RANGE
    value: "10000-10100"
    ports:
    - containerPort: 9091
    protocol: TCP
    resources:
    limits:
    cpu: 500m
    memory: 900M
    requests:
    cpu: 400m
    memory: 600M
    restartPolicy: Always
    ---
    apiVersion: v1
    kind: Service
    metadata:
    name: mypython-app
    spec:
    selector:
    name: mypython-app
    ports:
    - name: "8080"
    port: 8080
    targetPort: 8080
    type: LoadBalancer
    status:
    loadBalancer: {}

Init コンテナを使用する

注: このオプションは、Kubernetes で実行されているコンテナに適用されます。

このオプションでは、アプリケーションのスタートアップ時に Kubernetes init コンテナを使用して、アプリケーションコンテナに Python エージェントをインストールします。init コンテナを使用するには、Python エージェントを使用せずにアプリケーションイメージを作成する必要があります。このオプションの利点は、アプリケーションイメージを変更する必要がないことです。

init コンテナは、デフォルトのアプリケーション スタートアップ コマンドを上書きするために使用されるスタートアップスクリプトを提供します。これは、pip APP_ENTRY_POINT を実行します。

init コンテナを使用して Python アプリケーションをインストゥルメント化するには、次の手順を実行します。

  1. Python エージェントを使用しないアプリケーションイメージの作成
  2. 導入仕様への Init コンテナの追加
  3. Python エージェント環境変数の設定
  4. Python エージェントのインストールの検証

Python エージェントを使用しないアプリケーションイメージの作成

Python エージェントの依存関係を含めずにアプリケーションイメージを作成する Dockerfile の例を以下に示します。

FROM python:3.7
COPY mypythonapp/ /app/
WORKDIR /app
RUN chmod +x ./app.py
EXPOSE 8080
RUN pip install -r requirements.txt
CMD pyagent run python ./app.py

導入仕様への Init コンテナの追加

以下の導入仕様は、init コンテナを使用するために必要な変更を示しています。

  • 16 行目:appd-python-init init コンテナが定義され、init コンテナの内容がアプリケーションコンテナにコピーされます。
  • 22 行目:init コンテナが、Docker Hub からの python-agent-init イメージを参照します。
  • 78 行目:init コンテナの内容をアプリケーションコンテナと共有するために、ボリュームマウントが定義されます。
  • 30 行目:アプリケーション スタートアップ コマンドが、スクリプトを実行するように上書きされます。

  • 34 行目:APP_ENTRY_POINT APPDYNAMICS_AGENT_VERSION run-with-agent.sh。APPDYNAMICS_AGENT_VERSION PyPi AppDynamics リリースページ

注: パフォーマンスを向上させるために、ダイナミック言語プロキシを展開することをお勧めします。

プロキシタイプに応じて、次のサンプルコードを使用します。

ダイナミック言語プロキシ(手動)
apiVersion: apps/v1
kind: Deployment
metadata:
name: mypython-app-init
spec:
selector:
matchLabels:
name: mypython-app-init
replicas: 1
template:
metadata:
labels:
name: mypython-app-init
spec:
initContainers:
- name: appd-python-init
command:
- cp
- -r
- /opt/appdynamics/.
- /opt/temp
image: docker.io/appdynamics/python-agent-init:1.0
imagePullPolicy: Always
volumeMounts:
- mountPath: /opt/temp
name: appd-python-init
containers:
- name: mypython-app-init
image: myrepo/python-app-no-appd:v1
command: ["/bin/sh"]
args: ["-c", "/opt/appdynamics-python/run-with-agent.sh"]
imagePullPolicy: Always
env:
- name: APP_ENTRY_POINT
value: "--use-manual-proxy python /app/app.py"
- name: APPDYNAMICS_AGENT_VERSION
# Use latest version from https://pypi.org/project/appdynamics/#history
value: 21.12.2.4693
- name: APPDYNAMICS_AGENT_TIER_NAME
value: mypython-app-init
- name: APPDYNAMICS_AGENT_ACCOUNT_ACCESS_KEY
valueFrom:
secretKeyRef:
key: access-key
name: appd-agent-secret
envFrom:
- configMapRef:
name: appd-python-config
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /opt/appdynamics-python
name: appd-python-init
- name: proxy
image: appdynamics/dl-proxy:latest
imagePullPolicy: Always
env:
- name: APPDYNAMICS_DEBUG_LOG
value: "on"
- name: APPDYNAMICS_LOGGING_LEVEL
value: "debug"
- name: APPDYNAMICS_TCP_COMM_HOST
value: "0.0.0.0"
- name: APPDYNAMICS_TCP_COMM_PORT
value: "9091"
- name: APPDYNAMICS_TCP_PORT_RANGE
value: "10000-10100"
ports:
- containerPort: 9091
protocol: TCP
resources:
limits:
cpu: 500m
memory: 900M
requests:
cpu: 400m
memory: 600M
volumes:
- name: appd-python-init
emptyDir: {}
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: mypython-app-init
spec:
selector:
name: mypython-app-init
ports:
- name: "8080"
port: 8080
targetPort: 8080
type: LoadBalancer
status:
loadBalancer: {}]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader-binding
namespace: default
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
デフォルトプロキシ
apiVersion: apps/v1
kind: Deployment
metadata:
name: mypython-app-init
spec:
selector:
matchLabels:
name: mypython-app-init
replicas: 1
template:
metadata:
labels:
name: mypython-app-init
spec:
initContainers:
- name: appd-python-init
command:
- cp
- -r
- /opt/appdynamics/.
- /opt/temp
image: docker.io/appdynamics/python-agent-init:1.0
imagePullPolicy: Always
volumeMounts:
- mountPath: /opt/temp
name: appd-python-init
containers:
- name: mypython-app-init
image: myrepo/python-app-no-appd:v1
command: ["/bin/sh"]
args: ["-c", "/opt/appdynamics-python/run-with-agent.sh"]
imagePullPolicy: Always
env:
- name: APP_ENTRY_POINT
value: "python /app/app.py"
- name: APPDYNAMICS_AGENT_VERSION
# Use latest version from https://pypi.org/project/appdynamics/#history
value: 21.12.2.4693
- name: APPDYNAMICS_AGENT_TIER_NAME
value: mypython-app-init
- name: APPDYNAMICS_AGENT_ACCOUNT_ACCESS_KEY
valueFrom:
secretKeyRef:
key: access-key
name: appd-agent-secret
envFrom:
- configMapRef:
name: appd-python-config
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /opt/appdynamics-python
name: appd-python-init
volumes:
- name: appd-python-init
emptyDir: {}
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: mypython-app-init
spec:
selector:
name: mypython-app-init
ports:
- name: "8080"
port: 8080
targetPort: 8080
type: LoadBalancer
status:
loadBalancer: {}
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader-binding
namespace: default
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io

Python エージェント環境変数の設定

init コンテナを使用する場合は、「Dockerfile の使用」の説明に従って、Kubernetes の Python エージェント環境変数を設定します。