用Docker或minikube(kubernetes)在容器中运行nginx,并模拟静态内容的发布过程

首先

以上所提到的信息与 CI/CD 相关。我希望能够以我在工作中接触到的环境和功能的身边信息来分享,因此开始了这篇文章的发布。在学习过程中,我们将选择不需要花费金钱的方式。

通过以下步骤,使用nginx的Docker镜像模拟运维人员使用静态内容进行发布的过程。

与人相关的环境和功能

这篇文章的目标读者如下所述。

    • CI/CD 初学者

 

    • プログラミング初学者

 

    駆け出しエンジニア

以下是记录的环境和功能。

    • nginx

 

    • nginx.conf

 

    • default.conf.template

 

    • Docker

 

    minikube(kubernetes)

声明

我被要求设计使用nginx容器公开静态内容的特定部分。然后,我有点尴尬地去查了nginx的发音(是”恩吉恩艾克斯”吗?)。由于设计已经开始,时间很紧迫,我不知道该从哪里着手,但我正在努力保留最近查找到的信息。

起初,我听说过 Apache 作为一个 Web 服务器,可能是因为它作为一个著名的多用途工具而闻名。
这次选择了 “nginx”,可能是因为它被确认为处理 “静态内容” 的工具。
(大概可以说它擅长处理 “静态内容的展示”、”反向代理” 以及 “负载均衡器” 等功能的 Web 服务器吧。)

另外,在OpenShift和Kubernetes上访问其他卷也是初次尝试。
嗯,实际上,我在本地的Docker上也没有进行过挂载,这是我自学的结果。

计划或观点

我打算按照以下的流程继续进行。

    • nginx のコンテナを動かす

 

    • nginx のコンテナを Dockerfile で作って動かす

 

    • nginx の利用上で必要になるであろう、port 番号やルートパスの指定方法を抑えておく

 

    • 作った nginx イメージに Docker 上でマウントしてみる

 

    Docker でマウントする方法と、kubernetes でマウントする方法でどんな具合の差になるのかを抑えておく

也许,如果能够理解到这个程度,即使环境有所变化,也可以通过部分修改或其他方式应对。

前提任务

    • ubuntu に Docker をインストールする Install Docker Engine on Ubuntu

minikube、kuectl のインストール

minikube Get Started!
Linux へ kubectl をインストールする

运行nginx容器

我首先查看的是Docker Hub上的nginx官方镜像。总之,我想尽快使其运行。

$ docker pull nginx:latest  ※latestをプル
latest: Pulling from library/nginx
Digest: sha256:943c25b4b66b332184d5ba6bb18234273551593016c0e0ae906bab111548239f
Status: Image is up to date for nginx:latest
docker.io/library/nginx:latest
$ docker run -d -p 8080:80 nginx:latest  ※起動
513779d0aaa6b8e3486a4809fa4aa1bd769a7bf78993255007ccf096c5f7238f
$ curl http://localhost:8080/  ※接続OK
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

使用 Dockerfile 创建并运行一个 Nginx 容器。

这里也可以使用原始的信息去了。

FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf

那么,nginx.conf 是设置文件对吧。是的,很感激。
刚才用启动的nginx查看了一下,如下所示。
嗯,这难道不是指定端口号和根路径的方法吗?

$ docker exec -it 0a3df5313506 bash
root@0a3df5313506:/# cat /etc/nginx/nginx.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;  ※ここが怪しい
}

记住在nginx中,你可能需要指定端口号和根路径的方法。

这个主页上有写的。。懂的人可能知道,但对我来说有点难懂。。

So if you place templates/default.conf.template file, which contains variable references like this:

listen       ${NGINX_PORT};
outputs to /etc/nginx/conf.d/default.conf like this:

listen       80;

没有default.conf.template这样的文件存在。

root@0a3df5313506:/etc/nginx# pwd
/etc/nginx
root@0a3df5313506:/etc/nginx# ls -la
total 48
drwxr-xr-x 1 root root 4096 Oct 25 10:23 .
drwxr-xr-x 1 root root 4096 Nov 13 03:05 ..
drwxr-xr-x 1 root root 4096 Nov 13 03:05 conf.d
-rw-r--r-- 1 root root 1007 Oct 19 07:56 fastcgi_params
-rw-r--r-- 1 root root 5349 Oct 19 07:56 mime.types
lrwxrwxrwx 1 root root   22 Oct 19 09:32 modules -> /usr/lib/nginx/modules
-rw-r--r-- 1 root root  648 Oct 19 09:32 nginx.conf
-rw-r--r-- 1 root root  636 Oct 19 07:56 scgi_params
-rw-r--r-- 1 root root  664 Oct 19 07:56 uwsgi_params

然而,存在conf.d/default.conf,并且在nginx.conf中的定义”include /etc/nginx/conf.d/*.conf; ※此处可能有问题”似乎是在读取它。
这样做”default.conf.template是将要注入到default.conf的环境变量变量化并自行配置”似乎是合理的。
实际尝试后,结果与预期相符。

FROM nginx
COPY static-html-directory /usr/share/nginx/html    ※静的コンテンツを配置
COPY nginx.conf /etc/nginx/nginx.conf          ※ここは変更加えていませんが、後で外からも注入できるように一応コピー
COPY default.conf.template /etc/nginx/templates/default.conf.template ※default.conf を元に作ったテンプレートを配置
server {
    listen       ${NGINX_PORT};  ※ここにコンテナ起動時に注入する環境変数が入る想定
    listen  [::]:80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /app;
省略
$ docker build -t oad3jp999/my-nginx:1.0.0 .
Sending build context to Docker daemon  14.85kB
Step 1/4 : FROM nginx
 ---> 76c69feac34e
Step 2/4 : COPY static-html-directory /usr/share/nginx/html
 ---> Using cache
 ---> 00de7b966f5c
Step 3/4 : COPY nginx.conf /etc/nginx/nginx.conf
 ---> Using cache
 ---> c0a6076cded2
Step 4/4 : COPY default.conf.template /etc/nginx/templates/default.conf.template
 ---> 35f5ff0e0e9e
Successfully built 35f5ff0e0e9e
Successfully tagged oad3jp999/my-nginx:1.0.0
$ docker run -d \
>   -it \
>   -p 8080:81 \      ※コンテナの81番ポートに、外より8080でつながる
>   --name my-nginx \
>   --env NGINX_PORT=81 \ ※コンテナ起動時に注入するポート番号
>   oad3jp999/my-nginx:1.0.0

b4d4e29956b8fa146e6bbfc9e2d02dfd455d506e8379aa0bcdb7f36813d871a6
$
$ curl http://localhost:8080/  ※接続OK
hello this is static-text from docker coppy

在Docker上尝试将创建的nginx镜像挂载上去。

试着稍微改变一下模板。

server {
    listen       ${NGINX_PORT};
    listen  [::]:80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /app; ※コンテナ内の何も入っていない/appにマウントしていきます
        # root   /usr/share/nginx/html;
        index  send.txt; ※/appに置いたsend.txtがindexとして読みだされる想定
        # index  index.html index.htm send.txt;
    }

使用Docker进行构建,并重新布置模板。

$ docker build -t oad3jp999/my-nginx:1.0.0 .
Sending build context to Docker daemon  13.82kB
Step 1/4 : FROM nginx
 ---> 76c69feac34e
Step 2/4 : COPY static-html-directory /usr/share/nginx/html
 ---> Using cache
 ---> 00de7b966f5c
Step 3/4 : COPY nginx.conf /etc/nginx/nginx.conf
 ---> Using cache
 ---> c0a6076cded2
Step 4/4 : COPY default.conf.template /etc/nginx/templates/default.conf.template
 ---> 39f088b173e2
Successfully built 39f088b173e2
Successfully tagged oad3jp999/my-nginx:1.0.0
$ docker run -d \
>   -it \
>   -p 8080:81 \
>   --name my-nginx \
>   --mount type=bind,source="$(pwd)"/target,target=/app,readonly \  ※ここで、ホストマシン側の「"$(pwd)"/target」を、コンテナ内の「/app」へマウント
>   --env NGINX_PORT=81 \
>   oad3jp999/my-nginx:1.0.0
cc97265d50624a1d5455665b83c1af58f288ca067e07c454269b7ca659c2a0c1
$ curl http://localhost:8080/  ※接続OK
hello this is mount target with nginx!
add text
$ docker exec -it my-nginx bash
root@cc97265d5062:/# cat /app/send.txt  ※ディレクトリがマウントされて、send.txtなるファイルがルートアクセスで表示。ホスト側で「add text」を追記したらコンテナ側でも認識OK
hello this is mount target with nginx!
add text
root@cc97265d5062:/#

请记住在Docker中挂载的方法和在Kubernetes中挂载的方法之间的区别。

结论是在容器启动时指定挂载相似。(从Docker的理念来看,重视环境无关性,因此,在容器启动时进行指定似乎是一个好主意。我同意这个观点。)接下来是存在多个可连接存储的问题,只需将”volumes”的写法与OpenShift的PVC进行比较并做出修改,应该就可以搞定了。因此,使用minikube来进行准备工作。

$ minikube start --driver=docker  ※minikube起動
* Ubuntu 20.04 上の minikube v1.22.0
* プロフィールを元に、 docker ドライバを使用します
* コントロールプレーンのノード minikube を minikube 上で起動しています
* イメージを Pull しています...
* 既存の docker container を "minikube" のために再起動しています...
* Docker 20.10.7 で Kubernetes v1.21.2 を準備しています...
* Kubernetes コンポーネントを検証しています...
  - イメージ kubernetesui/metrics-scraper:v1.0.4 を使用しています
  - イメージ kubernetesui/dashboard:v2.1.0 を使用しています
  - イメージ gcr.io/k8s-minikube/storage-provisioner:v5 を使用しています
* 有効なアドオン: storage-provisioner, default-storageclass, dashboard

! /usr/local/bin/kubectl is version 1.23.5, which may have incompatibilites with Kubernetes 1.21.2.
  - Want kubectl v1.21.2? Try 'minikube kubectl -- get pods -A'
* 完了しました! kubectl が「"minikube"」クラスタと「"default"」ネームスペースを使用するよう構成されました

$ cd /tmp
$ mkdir hostpath_pv   ※マウント用ディレクトり作成
$ ls -la
合計 96
drwxrwxrwt 21 root  root  4096 11月 13 12:54 .
drwxr-xr-x 21 root  root  4096  3月 14  2021 ..
drwxrwxr-x  2 senju senju 4096 11月 13 12:54 hostpath_pv
$ cd hostpath_pv
$ vi send.txt
$ cat send.txt
This is mount from hostpath for minikube!   ※マウントされた際には、nginxがこちらを返す想定
$ cd ..
$ minikube mount /tmp/hostpath_pv:/host   ※前段として、minikubeのVMが認識するようにマウントしておく必要がある模様
* Mounting host path /tmp/hostpath_pv into VM as /host ...
  - マウントタイプ:
  - ユーザー ID:      docker
  - グループ ID:     docker
  - バージョン:      9p2000.L
  - メッセージのサイズ: 262144
  - Permissions:  755 (-rwxr-xr-x)
  - Options:      map[]
  - アドレスをバインドします: 192.168.58.1:40645
* Userspace file server: ufs starting
* Successfully mounted /tmp/hostpath_pv to /host  ※ホストマシンの「/tmp/hostpath_pv」が「/host」としてマウントされた

* NOTE: This process must stay alive for the mount to be accessible ...

准备用于挂载 Pod 的 yml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
    - image: oad3jp999/my-nginx:1.0.0
      name: nginx
      env:
      - name: NGINX_PORT  ※テンプレートで変数化したポート番号を環境変数として注入
        value: "81"
      volumeMounts:
        - name: storage
          mountPath: /app  ※nginxの「/app」にマウントする。⇒ルートディレクトリに指定してあるので、例の「send.txt」なるものが読まれる。
  volumes:
    - name: storage
      hostPath:   ※本来、kubernetesではホストパスのストレージマウントは極めて限定的な目的での利用とされているが、いまはymlの書きっぷりが把握したいので、うってつけ
        path: /host ※ホストマシンの「/tmp/hostpath_pv」がマウントされた「/host」を指定
        type: DirectoryOrCreate ※直アクセス、無ければ作る

悬浮式盒子连接成功。

$ kubectl apply -f my-nginx.yml
pod/nginx created
$ kubectl get all -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
pod/nginx   1/1     Running   0          7s    172.17.0.5   minikube   <none>           <none>

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   28h   <none>
$ kubectl exec -it nginx bash  ※面倒なので、中から突きます
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx:/# curl http://localhost:81/  ※接続OK
This is mount from hostpath for minikube!  ※想定通り!
root@nginx:/#

相关文章

    • CI/CD とは?

 

    • Azure Devops (Artifacts) を無償、無料で使う

 

    • Spring Tool Suite 4 インストール、Spring Initializr 、gradlew の利用

 

    • Spring Boot Web アプリケーションを作る

 

    • Jar の Library を作り、Azure Artifacts を利用して成果物を配布する

 

    • ライブラリ開発者より指定されたバージョンを利用してアプリを作る

 

    • アプリを Docker 、Docker Compose でコンテナを動かしてみる

 

    • Azure Devops (PileLines) を無償、無料で使う

 

    • Azure Devops (PileLines) でテスト、ビルド、イメージプッシュをする

 

    • minikube(kubernetes) でコンテナを動かしてみる

 

    nginx のコンテナを Docker や minikube(kubernetes) で動かし、静的コンテンツ公開工程を模倣
广告
将在 10 秒后关闭
bannerAds