概要
Dockerコンテナphp:7.0-apache
をminikubeを使って構築したkubernetes環境にdeployし、WEBブラウザからページが閲覧できるようにしてみる。
目次
関連記事
環境
- CentOS 7.6
- Minikube v1.1.1
- Kubernetes v1.14.3
minikube(クラスタ)起動
まずはクラスタ起動
$ sudo /usr/local/bin/minikube start --vm-driver=none
DockerHubで公開されているphp:7.0-apache
をdeployする
podを定義
apiVersion: v1
kind: Pod
metadata:
# pod名
name: sample-web-pod
labels:
app: http-app
spec:
containers:
# Dockerコンテナ名
- name: web-container
# 利用するDockerイメージ
image: php:7.0-apache
# コンテナ内のport
ports:
- name: http-port
containerPort: 80
# mountするディレクトリ:コンテナ側の設定
volumeMounts:
- name: documentroot
mountPath: /var/www/html
# mountするディレクトリ:ホストOS側の設定
volumes:
- name: documentroot
hostPath:
path: /home/username/containers/web/html
serviceを定義
kind: Service
apiVersion: v1
metadata:
# service名
name: http-service
labels:
app: http-app
spec:
selector:
app: http-app
# 公開するport
ports:
- port: 8080
targetPort: http-port
type: NodePort
pod、serviceを作成
$ sudo kubectl create -f pod.yml -f service.yml
curlでwebアクセス
http-serviceにアクセスしてみる
$ curl $(sudo minikube service http-service --url)
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /
on this server.<br />
</p>
<hr>
<address>Apache/2.4.25 (Debian) Server at xxx.xxx.xxx.xxx Port 32016</address>
</body></html>
ブラウザからアクセス
URLを取得
$ sudo minikube service http-service --url
http://xxx.xxx.xxx.xxx:32016
ApacheのForbiddenページが表示されればOK。
index.phpを作成
mountした領域にindex.phpを作成
<?php phpinfo(); ?>
URLを取得
$ sudo minikube service http-service --url
http://xxx.xxx.xxx.xxx:32016
ブラウザからhttp://xxx.xxx.xxx.xxx:32016 にアクセス
<?php phpinfo(); ?>
の内容が表示されればOK。
podの状態を確認
$ sudo kubectl describe pod sample-web-pod
# **snip**
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2s default-scheduler Successfully assigned default/sample-web-pod to minikube
Normal Pulling 2s kubelet, minikube Pulling image "php:7.0-apache"
serviceの状態を確認
$ sudo kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
http-service NodePort 10.109.95.198 <none> 8080:32269/TCP 7m41s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7h4m
localのDockerイメージを利用する場合
local(ホストOS上)のDockerイメージを利用しようとすると、イメージをpullすることができず、以下のエラーが出る。
$ sudo minikube logs -f
container start failed: ErrImagePull: rpc error: code = Unknown desc = Error response from daemon: repository my-web-server not found: does not exist or no pull access
イメージがpullできないということは、当然コンテナが立ち上がらないのでアクセスできない。
$ curl `sudo minikube service http-service --url`
curl: (7) Failed connect to xxx.xxx.xxx.xxx:31528; Connection refused
コンテナにも入れない。
$ sudo kubectl exec sample-web-pod /bin/sh
error: unable to upgrade connection: container not found ("web-container")
podをdescribeすることでもエラーを確認できる。
$ sudo kubectl describe pod sample-web-pod
# **snip**
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 10m default-scheduler Successfully assigned default/sample-web-pod to minikube
Normal Pulling 9m4s (x4 over 10m) kubelet, minikube Pulling image "web-container:latest"
Warning Failed 9m2s (x4 over 10m) kubelet, minikube Failed to pull image "web-container:latest": rpc error: code = Unknown desc = Error response from daemon: repository web-container not found: does not exist or no pull access
Warning Failed 9m2s (x4 over 10m) kubelet, minikube Error: ErrImagePull
Warning Failed 8m38s (x6 over 10m) kubelet, minikube Error: ImagePullBackOff
Normal BackOff 32s (x41 over 10m) kubelet, minikube Back-off pulling image "web-container:latest"
解決策
以下コマンドで、minikube VM上のDockerイメージを使うように設定できる。
$ eval $(sudo minikube docker-env)
これにより以下が設定される。
- DOCKER_TLS_VERIFY
- DOCKER_HOST
- DOCKER_CERT_PATH
- DOCKER_API_VERSION
--vm-driver=none
でminikubeを起動している場合
sudo minikube docker-env
を実行すると以下のエラーが出る。
'none' driver does not support 'minikube docker-env' command
--vm-driver=none
でminikubeを起動している場合、$(minikube docker-env)
は利用できない。
そもそも、localにイメージが存在しているので、pullする必要がない。
参考:https://github.com/kubernetes/minikube/issues/2575#issuecomment-410145576
your locally available images are also available to kubernetes with vm-driver=none.
Not that I'm aware of. Note that you don't even have to pull them: with vm-driver=none it's the same docker daemon as on your desktop
pod.ymlのDockerイメージの定義部分で、imagePullPolicy
を指定することで、localのDockerイメージを利用することができるようになる。
-
imagePullPolicy: IfNotPresent
- localイメージ利用。ただし、localに指定したイメージが存在しない場合はレポジトリを参照する。
-
imagePullPolicy: Never
- localイメージのみを利用。
自作Dockerイメージを作成
以上を踏まえて、自作Dockerイメージを作成し、pod、serviceを作成してみる。
From php:7.0-apache
buildする。
タグをlatest
にすると、k8sはrepositoryからpullしようとしてしまうので、versionを明記する。
$ sudo docker build -t my-web-server:v1.0 ./
pod.ymlを定義
今回はimagePullPolicy: Never
を指定する。
apiVersion: v1
kind: Pod
metadata:
# pod名
name: sample-web-pod
labels:
app: http-app
spec:
containers:
# Dockerコンテナ名
- name: web-container
# 利用するDockerイメージ
- image: php:7.0-apache
+ # localの自作イメージ
+ image: my-web-server:v1.0
+ imagePullPolicy: Never
+ #imagePullPolicy: IfNotPresent
# コンテナ内のport
ports:
- name: http-port
containerPort: 80
# mountするディレクトリ:コンテナ側の設定
volumeMounts:
- name: documentroot
mountPath: /var/www/html
# mountするディレクトリ:ホストOS側の設定
volumes:
- name: documentroot
hostPath:
path: /home/username/containers/web/html
service.yml
先程と同じ
pod、serviceを作成
$ sudo kubectl create -f pod.yml -f service.yml
podの状態を確認
$ sudo kubectl describe pod sample-web-pod
# **snip**
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3s default-scheduler Successfully assigned default/sample-web-pod to minikube
Normal Pulled 2s kubelet, minikube Container image "my-web-server:v1.0" already present on machine
Normal Created 2s kubelet, minikube Created container web-container-name
Normal Started 2s kubelet, minikube Started container web-container-name
$ sudo kubectl get pod
NAME READY STATUS RESTARTS AGE
sample-web-pod 1/1 Running 0 23s
webアクセス
$ curl $(sudo minikube service http-service --url)
# omitted...
# <?php phpinfo(); ?>の内容が表示されればOK
ブラウザからアクセス
URLを取得
$ sudo minikube service http-service --url
http://xxx.xxx.xxx.xxx:30910
ブラウザから http://xxx.xxx.xxx.xxx:30910 にアクセスして、<?php phpinfo(); ?>
の内容が表示されればOK
Delete
$ sudo kubectl delete services http-service
$ sudo kubectl delete pods sample-web-pod