nginxコンテナ1つで構成されるPodを2つ作成する。Podの数は任意。 Deploymentを作成する。 Podに割り当てられたIPアドレスを確認する。 このIPアドレスはKubernetesクラスタ内部のものなので、クラスタ外部からのアクセスは通らない。以下はノードと同一ネットワークに所属するWindowsマシンからcurlを実行した例。 クラスタ内部からのアクセスは通る。以下はPod
先に結論だが、この構成ではクラスタ外部にアプリケーションを公開できない。ClusterIPはクラスタ内部からのみアクセス可能。 ClusterIPタイプのServiceを作成する。 クラスタ内部からアクセス可能なClusterIPが割り当てられた。 Endpointsが各PodのIPアドレスとなっている。Serviceにアクセスが来るとkube-proxyによりEndpointsに分散される。 念のためクラスタ外部からはアクセスできないことを確認。 クラスタ内部からはアクセスできる。 未稿 kubernetes.io
metallb.universe.tf
クラウド環境においてLoadBalancerタイプのServiceをデプロイすると、クラウド環境上にロードバランサを作成し、クラスタ外部のIPアドレスを割り当ててくれるらしい。 MetalLBのインストール準備をする。 なにやらつまづいている様子。 暫定対処として、 の順に試したが状況変わらず。最終的に ことで解消した。追って必要なポートを調査せねば。 LoadBalancerタイプのServiceを作成する。 クラスタ外部のIPにアクセスできた。
※アクセスできないこともあったが、Serviceを再作成したらうまくいった。しかしそれは正常とは言えないので、原因を調査する必要がある。 未稿 未稿 LoadBalancerかIngressが実用性がありそう。 kubernetes.io
metallb.universe.tf
blog.framinal.life
blog.yumenomatayume.net全編目次
概要
環境
構成
ホスト名
IPアドレス
OS
用途
備考
k8sctrpln01
172.16.0.11/24
CentOS 7.9.2009
コントロールプレーンノード
QEMU+KVM仮想ゲスト
k8sworker01
172.16.0.12/24
CentOS 7.9.2009
ワーカノード
QEMU+KVM仮想ゲスト
k8sworker02
172.16.0.13/24
CentOS 7.9.2009
ワーカノード
QEMU+KVM仮想ゲスト
-
172.16.0.21/24
MetalLB
ソフトウェアロードバランサ
address pool: 172.16.0.21-172.16.0.25/24
client01
172.16.0.100/24
Windows 10
クライアント
CLI: Git Bash
Web UI: Google Chrome
前提
kubectl
コマンドの実行は、クライアントマシン(Windows 10)上で行う。Windowsへのkubectl
コマンドのインストールは以下を参照。
kubernetes.ioSTEP1 - Podの作成
ソース
概要図
概要
実践
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
run: nginx
replicas: 2
template:
metadata:
labels:
run: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
$ kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
NOMINATED NODE READINESS GATES
nginx-deployment-89b88cd64-6dbwl 1/1 Running 0 14s 10.244.1.21 k8sworker01 <none> <none>
nginx-deployment-89b88cd64-r6mhd 1/1 Running 0 14s 10.244.2.18 k8sworker02 <none> <none>
※当環境のプロキシが邪魔をしたので--noproxy
オプションを使用。$ curl.exe --noproxy "*" -o /dev/null -w '%{http_code}\n' -s http://10.244.1.21:80
000
nginx-deployment-89b88cd64-6dbwl
から10.244.1.21
、10.244.2.18
にcurlを実行した例。$ kubectl exec nginx-deployment-89b88cd64-6dbwl -- curl -o /dev/null -w '%{http_code}\n' -s http://10.244.1.21:80
200
$ kubectl exec nginx-deployment-89b88cd64-6dbwl -- curl -o /dev/null -w '%{http_code}\n' -s http://10.244.2.18:80
200
STEP2 - Serviceの作成
CASE1 - ClusterIPタイプのServiceを使用した構成
ソース
概要図
概要
実践
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
run: nginx
spec:
type: ClusterIP # 公式ドキュメントでは省略している(省略時はClusterIPになる)
ports:
- port: 80
protocol: TCP
selector:
run: nginx
$ kubectl apply -f nginx-service-clusterip.yaml
service/nginx-service created
$ kubectl get services nginx-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.109.120.89 <none> 80/TCP 68s
$ kubectl describe services nginx-service
Name: nginx-service
Namespace: default
Labels: run=nginx
Annotations: <none>
Selector: run=nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.109.120.89
IPs: 10.109.120.89
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.21:80,10.244.2.18:80
Session Affinity: None
Events: <none>
$ curl.exe --noproxy "*" -o /dev/null -w '%{http_code}\n' -s http://10.109.120.89:80
000
$ kubectl exec nginx-deployment-89b88cd64-6dbwl -- curl -o /dev/null -w '%{http_code}\n' -s http://10.109.120.89:80
200
CASE2 - NodePortタイプのServiceを使用した構成
CASE3 - LoadBalancerタイプのServiceを使用した構成
ソース
概要図
概要
オンプレ環境ではロードバランサの作成処理が進まないため、ソフトウェアロードバランサであるMetalLBをインストールすることで代替することができる。実践
MetalLBの作成
$ kubectl describe configmap -n kube-system kube-proxy | grep strictARP
strictARP: false
$ kubectl get configmap kube-proxy -n kube-system -o yaml | sed -e "s/strictARP: false/strictARP: true/" | kubectl diff -f - -n kube-system
diff -u -N "C:\\Users\\root\\AppData\\Local\\Temp\\LIVE-1938845299/v1.ConfigMap.kube-system.kube-proxy" "C:\\Users\\root\\AppData\\Local\\Temp\\MERGED-1255996808/v1.ConfigMap.kube-system.kube-proxy"
--- "C:\\Users\\root\\AppData\\Local\\Temp\\LIVE-1938845299/v1.ConfigMap.kube-system.kube-proxy" 2022-06-04 01:33:37.477912900 +0900
+++ "C:\\Users\\root\\AppData\\Local\\Temp\\MERGED-1255996808/v1.ConfigMap.kube-system.kube-proxy" 2022-06-04 01:33:37.479487200 +0900
@@ -33,7 +33,7 @@
excludeCIDRs: null
minSyncPeriod: 0s
scheduler: ""
- strictARP: false
+ strictARP: true
syncPeriod: 0s
tcpFinTimeout: 0s
tcpTimeout: 0s
@@ -100,9 +100,9 @@
fieldsV1:
f:data:
f:config.conf: {}
- manager: kubectl-edit
+ manager: kubectl-client-side-apply
operation: Update
- time: "2022-06-03T12:03:26Z"
+ time: "2022-06-03T16:33:36Z"
name: kube-proxy
namespace: kube-system
resourceVersion: "667909"
$ kubectl get configmap kube-proxy -n kube-system -o yaml | sed -e "s/strictARP: false/strictARP: true/" | kubectl apply -f - -n kube-system
Warning: resource configmaps/kube-proxy is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
configmap/kube-proxy configured
$ kubectl describe configmap -n kube-system kube-proxy | grep strictARP
strictARP: true
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
namespace/metallb-system created
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/controller created
podsecuritypolicy.policy/speaker created
serviceaccount/controller created
serviceaccount/speaker created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
role.rbac.authorization.k8s.io/config-watcher created
role.rbac.authorization.k8s.io/pod-lister created
role.rbac.authorization.k8s.io/controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/config-watcher created
rolebinding.rbac.authorization.k8s.io/pod-lister created
rolebinding.rbac.authorization.k8s.io/controller created
daemonset.apps/speaker created
deployment.apps/controller created
$ kubectl -n metallb-system get pods
NAME READY STATUS RESTARTS AGE
controller-7476b58756-dp7hd 0/1 CrashLoopBackOff 1 (12s ago) 18s
speaker-427rt 0/1 CreateContainerConfigError 0 18s
speaker-mkbcr 0/1 CreateContainerConfigError 0 18s
$ kubectl -n metallb-system logs controller-7476b58756-dp7hd
{"branch":"HEAD","caller":"level.go:63","commit":"v0.12.1","goversion":"gc / go1.16.14 / amd64","level":"info","msg":"MetalLB controller starting version 0.12.1 (commit v0.12.1, branch HEAD)","ts":"2022-06-04T13:35:16.862838665Z","version":"0.12.1"}
{"caller":"level.go:63","error":"Get \"https://10.96.0.1:443/api/v1/namespaces/metallb-system/secrets?fieldSelector=metadata.name%3Dmemberlist\": dial tcp 10.96.0.1:443: connect: no route to host","level":"error","msg":"failed to create memberlist secret","op":"startup","ts":"2022-06-04T13:35:17.865843229Z"}
dial tcp 10.96.0.1:443: connect: no route to host
とのことで、以下のServiceへの疎通ができていないように見える。$ kubectl get services kubernetes
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d3h
$ ssh k8sctrpln03 systemctl stop firewalld
$ ssh k8sworker01 systemctl stop firewalld
$ ssh k8sworker02 systemctl stop firewalld
$ kubectl -n metallb-system get pods
NAME READY STATUS RESTARTS AGE
controller-7476b58756-dp7hd 1/1 Running 8 (6m50s ago) 17m
speaker-427rt 1/1 Running 0 17m
speaker-mkbcr 1/1 Running 0 17m
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 172.16.0.21-172.16.0.25
$ kubectl apply -f metallb-config.yaml
configmap/config created
$ kubectl -n metallb-system get configmap config
NAME DATA AGE
config 1 6s
Serviceの作成
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
run: nginx
spec:
type: LoadBalancer
ports:
- port: 80
protocol: TCP
selector:
run: nginx
$ kubectl delete services nginx-service
service "nginx-service" deleted
$ kubectl apply -f nginx-service-loadbalancer.yaml
service/nginx-service created
EXTERNAL-IP
が割り当てられている。$ kubectl get services nginx-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service LoadBalancer 10.96.239.88 172.16.0.21 80:32191/TCP 8s
$ kubectl describe services nginx-service
Name: nginx-service
Namespace: default
Labels: run=nginx
Annotations: <none>
Selector: run=nginx
Type: LoadBalancer
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.96.239.88
IPs: 10.96.239.88
LoadBalancer Ingress: 172.16.0.21
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 32191/TCP
Endpoints: 10.244.1.30:80,10.244.2.28:80
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal IPAllocated 22s metallb-controller Assigned IP ["172.16.0.21"]
Normal nodeAssigned 22s metallb-speaker announcing from node "k8sworker02"
$ curl.exe --noproxy "*" -o /dev/null -w '%{http_code}\n' -s http://172.16.0.21:80
200
CASE4 - IngressとClusterIPタイプのServiceを使用した構成
CASE5 - ExternalIPsとClusterIPタイプのServiceを使用した構成
あとがき
参考記事