在运行Docker的主机上显示主机名的Nginx容器
首先
在使用Kubernetes进行工作时,我创建了一个容器,用于确定在浏览器上连接的容器是在哪个Worker上运行的。我会有意停止Worker来检查连接目标。
我已经确认了操作环境。
-
- Raspberry Pi 4
-
- Ubuntu 20.04
- Docker 19.03.13
形象
我已经将其上传到 https://hub.docker.com/r/yasthon/nginx-display-hostname。
试着动一动
在这里,我们正运行在主机名为”dockerhost.example.jp”的环境中。
$ docker pull yasthon/nginx-display-hostname
$ docker container run -d -v /etc/hostname:/usr/share/nginx/html/hostname -p 80:80 yasthon/nginx-display-hostname
$ curl http://localhost/index.sh
<html><head>
<title>dockerhost.example.jp</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
</head><body>
HOSTNAME : dockerhost.example.jp
</body></html>
我将从浏览器中确认。
访问 http://[Docker主机的IP地址]/index.sh。
HOSTNAME : dockerhost.example.jp
行动
在容器启动时,将/etc/hostname挂载。
使用Nginx运行sh,并读取主机名。
Dockerfile => 镜像文件
这是在本地构建时使用的文件。
FROM debian:buster-slim
COPY default.conf /etc/nginx/conf.d/
COPY index.sh /usr/share/nginx/html/
RUN apt-get update && \
apt-get install -y --no-install-recommends nginx fcgiwrap && \
apt-get autoclean && \
rm -rf /var/lib/apt/lists/* && \
echo "daemon off;" >> /etc/nginx/nginx.conf && \
rm -f /etc/nginx/sites-enabled/default && \
chmod 744 /usr/share/nginx/html/index.sh && \
chown www-data:www-data /usr/share/nginx/html/index.sh
CMD /etc/init.d/fcgiwrap start && nginx
当我在普通的操作系统上安装时,它非常顺利地运行,但在容器中执行时出现了问题。
-
- Nginxのdefault rootは/usr/share/nginx/html/だと思いこんでいたら、/var/www/htmlを参照していました。コンテナの用途が限定的なので、調査はせずに/etc/nginx/sites-enabled/defaultを削除することで解決しました。
fcgiwrap.socketが無かったです。CMDに /etc/init.d/fcgiwrap startを追加してコンテナ起動時に作成しています。
permissionエラーでました。chmodとchownを追加しました。
DockerHubからpullしたNginx Official イメージでは、思うように動作できなかったです。パッケージでインストールを行い動作させました。
默认配置文件.conf
这是Nginx的配置文件。
server {
listen 80;
server_name localhost;
location ~ \.sh$ {
root /usr/share/nginx/html/;
include /etc/nginx/fastcgi_params;
fastcgi_index index.sh;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
}
}
相比Dockerfile,没有任何问题。
index.sh 索引.sh
读取并显示已装载的hostname文件。
#!/bin/sh
host_name=$(cat hostname)
echo "Content-type:text/html"
echo ""
echo "<html><head>"
echo "<title>${host_name}</title>"
echo '<meta http-equiv="Content-type" content="text/html;charset=UTF-8">'
echo "</head><body>"
echo "HOSTNAME : ${host_name}"
echo "</body></html>"
同样,没有任何问题。
本地构建
我将镜像名称设为”nginx-display-hostname”。将三个文件放置在同一目录中,然后执行docker build命令。
$ docker image build -t nginx-display-hostname .
$ docker container run -d -v /etc/hostname:/usr/share/nginx/html/hostname -p 80:80 nginx-display-hostname
$ curl http://localhost/index.sh
<html><head>
<title>dockerhost.example.jp</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
</head><body>
HOSTNAME : dockerhost.example.jp
</body></html>
我会从浏览器上确认。
访问http://[Docker主机的IP地址]/index.sh。
HOSTNAME : dockerhost.example.jp
运行在Kubernetes上
需要使用volumeMounts和volumes来挂载/etc/hostname。
apiVersion: v1
kind: Namespace
metadata:
name: nginx-prod # namespace の名前
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment # deployment の名前(replicaset の名前もこれになる)
namespace: nginx-prod # namespace の名前
spec:
selector:
matchLabels: # ラベルがマッチしたPodを対象とするreplicasetの作成
app: nginx-pod
replicas: 2
template: # Pod のテンプレート
metadata:
name: nginx-pod # Pod の名前
namespace: nginx-prod # Pod のnamespace の名前
labels: # Pod のラベル
app: nginx-pod
spec:
containers: # コンテナの設定
- name: nginx-container # コンテナの名前
image: yasthon/nginx-display-hostname # イメージの名前
env:
- name: nginx-container
ports:
- containerPort: 80 # コンテナのポート
volumeMounts:
- name: file-hostname
mountPath: /usr/share/nginx/html/hostname
volumes:
- name: file-hostname
hostPath:
path: /etc/hostname
我会启动Pod。
$ kubectl apply -f sample.yaml
namespace/nginx-prod created
deployment.apps/nginx-deployment created
我会确认Pod的名字。
$ kubectl get all -n nginx-prod
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-7ff4cc65cd-6r4qv 1/1 Running 0 3m52s
pod/nginx-deployment-7ff4cc65cd-djm9r 1/1 Running 0 3m52s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 2/2 2 2 3m53s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-7ff4cc65cd 2 2 2 3m53s
在Pod的详细信息中查看IP。
$ kubectl describe pod/nginx-deployment-7ff4cc65cd-djm9r -n nginx-prod | grep ^IP:
IP: 10.244.1.5
工人会从上方访问确认过的IP地址。
$ curl http://10.244.1.5/index.sh
<html><head>
<title>worker.example.jp</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
</head><body>
HOSTNAME : worker.example.jp
</body></html>
我确认 Pod(nginx-deployment-7ff4cc65cd-6r4qv) 正在 worker.example.jp 主机上运行。
如果要从集群外用浏览器访问,您将需要一个 Service。
最后
我立刻開始製作,但花了比預期更多的時間。如果能幫到需要的人,我將感到非常幸福。