DockerとKubernetesのPerlのための2、3のヒント


FBの上で糸を始めたPerl Community and Perl Programmers アバウトdocker-perl , そして、その管理者として、私はこれについていくつかのヒントを共有しすぎています.

使用するPerlイメージのカスタム名/タグを使用します
Dockerハブに記載されているようにperl のようなイメージ
docker pull perl
docker run -it perl perl -E 'say "hi there from Docker!"'
これを行うのは単純であるか探索的なケースのために十分である間、それは開発または展開シナリオのために不十分ですperl だけでは、最新のPerlイメージを最新のサポートされているPerlのバージョンのビルドをプルします5.32.0 しかし、後には違うかもしれません.幸いにも、Docker Perlは特定のバージョンを示すためにタグを提供します:threaded ) またはサイズのvariant:slim ) そうすることもできます
docker pull perl:5.32-buster
docker run -it perl:5.32-buster perl -E 'say qq{hi again!}'
もう一つの懸念があります:Dockerイメージがタグを持っている間、これらのタグは、タグが別の層を指すように更新されることができるので、それらが常に作成時に同じ基礎的なイメージ層を指しているとは限らないという意味で浮いています.これは:latest dockerはデフォルトでは名前を付けて画像を呼び出すときに使用しますが、この動作は他のタグにも存在します:5 を指す:5.32.0 , しかし、後に:5.32.1 あるいは:5.34.0 , 時perl manifest on docker-library/official-images が更新される.
これらのタグはまた、間接的に自分のベースの画像の更新方法によって更新されますDocker Perlが使用するように buildpack-deps or debian:slim これらのパッチが最終的にセキュリティパッチのために更新されると、これらのパッチは最終的にperl を通してのイメージofficial-images build tooling .
イメージのより細かい制御を必要とする場合には、docker perlを使うとき、カスタムイメージ名、タグ、またはその両方を使うのが役に立つかもしれません.
docker pull perl:5.32-slim-threaded-buster
docker tag perl:5.32-slim-threaded-buster myorg/perl:5.32
docker run -it myorg/perl:5.32 perl -e 'printf "hello from myorg/perl v%vd!\n", $^V'
これは、更新と開発の間のいくつかの独立性をperl ドッカーハブとmyorg 'Sカスタムperl イメージ
# docker build -t myorg/myapp:dev .
FROM myorg/perl:5.32
ADD . /app
WORKDIR /app
RUN cpanm --installdeps .
CMD ["perl", "myapp.pl"]
...

Perl画像をホストするローカル/プライベートレジストリを維持することを検討してください
Perlイメージ(特に前のセクションのように)を使用することは、これらが通常、ローカルのDockerホストイメージ記憶にコピーされることを意味します/var/lib/docker/images しかし、何によって変化するかstorage driver あなたのホストが使用しています.これは通常、単純なケースで十分ですが、ベースperl イメージは通常大きい(およそ700 - 800 MBのアンパックをします)ので、ネットワークの上に複数のコンテナホストの上にこのイメージを払い戻してください.
したがって、通常、ホストまたはネットワーク上のいくつかの種類のローカルまたはプライベートのレジストリを持つことを推奨されている場合は頻繁にコンテナーと一緒に動作している場合これを行うにはいくつかのアプローチがあり、以前のブログでこれらについて書きました.
  • Composing a Docker Hub mirror and private registry
  • Mirroring the Docker Hub
  • 最近では、ローカル/プライベートレジストリを使用するためのより多くのオプションがありますmicrok8s , または内部のDockerコンテナクラスタKinD or k3d ,) 普通はアドオンがある
    これはクラスタ上のローカルレジストリを有効にします.こちらですan example Microk 8 sのために、私は私自身のローカルネットワークのためにATLS ingress :
    microk8s enable registry
    microk8s kubectl apply -f - <<REGISTRY_SVC
    apiVersion: v1
    kind: Service
    metadata:
      name: registry
      namespace: default
    spec:
      # microk8s deploys registry in its own namespace, so reach out
      externalName: registry.container-registry.svc.cluster.local
      ports:
      - name: registry
        port: 5000
        protocol: TCP
        targetPort: 5000
      type: ExternalName
    REGISTRY_SVC
    microk8s kubectl apply -f - <<REGISTRY_INGRESS
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: registry
      namespace: default
    spec:
      rules:
      # I don't own home.example btw, just for illustration;
      # I use globally-accessible subdomains pointing to private IP
      - host: registry.home.example
        http:
          paths:
          - backend:
              serviceName: registry
              servicePort: 5000
      tls:
      - hosts:
        - registry.home.example
        secretName: wildcard-home-example
    REGISTRY_INGRESS
    
    私はLetsEncrypt ワイルドカードSSL CERTは、私のMicro 8 sによってインストールされて、維持されますcert-manager , だから、これは私のローカルネットワーク上のどこでも、このレジストリにプッシュすることができます
    docker push myorg/perl:5.32 registry.home.example/myorg/perl:5.32
    docker push myorg/myapp:dev registry.home.example/myorg/myapp:dev
    
    そしてどこか他のどこかに走るかもしれないPodman 代わりに
    podman run -it registry.home.example/myorg/perl:5.32 perl -V
    podman run -d registry.home.example/myorg/myapp:dev
    
    また、オーサリングで動作しますDockerfile s、特にgitopsワークフローを実装するときに便利です.
    # docker build -t myorg/mojo:8.65
    # docker push myorg/mojo:8.65 registry.home.example/myorg/mojo:8.65
    FROM registry.home.example/myorg/perl:5.32
    RUN cpanm [email protected]
    EXPOSE 3000
    CMD ["/usr/local/bin/mojo", "daemon"]
    
    より洗練された/生産展開のためにHarbor などのベンダーAmazon ECR , Google Container Registry or Red Hat Quay .

    Perlで適切なシグナル処理のためにContainer EntryPointを使用します
    これは既にofficial-images docs Perlのために、しかし、ここで繰り返しているベアーズ:コンテナはデフォルトで親initプロセスを提供しませんENTRYPOINT or CMD コンテナが起動するイメージにセットされると、通常このコンテナの中で親プロセスになります.これはPerlのためにここで注意しなければなりません(そして他の言語に対しても)、これらはシグナルを処理するための親のinitプロセスに戻る傾向があります.
    docker run perl:5.32 perl -E 'sleep 300'
    ^C
    [refuses to die, even if sent SIGINT like above]
    
    これは特にKubernetesにとって重要であるcontainer pod lifecycle これらのシグナルが正しく扱われないならば、動かないPOD/コンテナは無期限に「ハングする」ように見えることができます.
    Perl用には %SIG handler もし必要なら/PID 1としてPerlを直接実行する必要があります.
    docker run perl:5.32 perl -E '$SIG{TERM} = sub { $sig++; say "recv TERM" }; sleep 300; say "waking up" if $sig'
    ^C
    waking up
    recv TERM
    
    しかし、大部分の通常の配備のために、それはツールのような使いやすいですtini , catatonit , or dumb-init コンテナ用ENTRYPOINT , Perlスクリプト/実行可能ファイルと一緒にCMD , 例えば、この小さいMojolicious デモ:
    # docker build -t mojo-with-tini:dev .
    FROM perl:5.32-buster
    RUN apt-get update && \
        apt-get install -y --no-install-recommends tini && \
        cpanm Mojolicious
    ENTRYPOINT ["/usr/bin/tini", "--"]
    EXPOSE 3000
    CMD ["/usr/local/bin/mojo", "daemon"]
    
    Kubernetesのために、また、1をセットすることができます command and args PODの場合:
    kubectl apply -f - <<MOJO_POD
    apiVersion: v1
    kind: Pod
    metadata:
      name: mojo-with-tini-demo
      labels:
        purpose: demonstrate-perl-signal-handling
    spec:
      containers:
      - name: mojo-with-tini-demo-container
        image: mojo-with-tini:dev
        # redundant as we already set these in the Dockerfile above,
        # but showing here for illustration
        command: ["/usr/bin/tini", "--"]
        args: ["/usr/local/bin/mojo", "daemon"]
    MOJO_POD
    

    アウトロ
    キューにいくつかのヒントがありますが、ここでもっと書きたいと思いますが、このポストはかなり長くなっています.
    私は人々がどのようにDocker Perlを使用するかについての詳細を聞きたいです、そして、特に開発するPerlプロジェクトをコンテナ環境でより簡単にする方法についてもっと詳しく!