Kubernetesのラボ、初期構築(後編)

この記事は約29分で読めます。
スポンサーリンク

この記事は「Kubernetesのラボ、初期構築(前編)」の続きとなります。

Kubernetesのラボ、初期構築(前編)
あくまでも試みレベルですが、「Kubernetes勉強記事」の連載を始めてみようと思います。 はじめに ラボの構築について、以下のリンクの記事を参考にさせていただきました。決して全ての手順が私の独自アイデアで完成できた訳ではあり...

これまでやったこと

前編が終わった段階のKubernetes環境構築はこんな感じ。

  • Masterノード(LoadBalancer以外)
  • Workerノード(1と2)

残ってる作業は以下となります。

  • LBノード(LoadBalancer)
  • MasterノードからLoadBalancerの初期設定

終わったら簡単な稼働確認を行います。

LB Nodeの設定

LB Nodeの設定です。

topology4

手順はMasterNodeと殆ど同じです。最後が違うだけ。

Kubenetes Repositoryの設定

/etc/yum.repos.d/kubernetes.repoを「作成」してください。

[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
        https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg

KubeadmとDockerの導入

以下をコピペしてください。

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum makecache fast -y
yum remove docker docker-common docker-selinux docker-engine -y
yum install docker-ce-17.06.0.ce-1.el7.centos -y
yum install kubectl-1.12.3-0.x86_64 -y
yum install kubelet-1.12.3-0.x86_64 -y
yum install kubeadm-1.12.3-0.x86_64 -y

docker-ceとkubeadmのインストールにバージョンを指定しているのがミソです。現時点でバージョンを指定しなければ、Dockerのバージョンが新しくて、以降のKubernetes init時にエラーが発生します。

とりあえずコピペしてください。

Serviceの初期設定

インストールしたDockerとKubeadmをsystemctlに登録&起動します。firewalldは停止します。ついでにswapをoffします。

systemctl restart docker && systemctl enable docker
systemctl restart kubelet && systemctl enable kubelet
systemctl stop firewalld && systemctl disable firewalld
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

結果はこんな感じ。

[root@master ~]# systemctl restart docker && systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@master ~]# systemctl restart kubelet && systemctl enable kubelet
Created symlink from /etc/systemd/system/multi-user.target.wants/kubelet.service to /etc/systemd/system/kubelet.service.
[root@master ~]# systemctl stop firewalld && systemctl disable firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@master ~]# swapoff -a
[root@master ~]# sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

以下を実行してiptablesを修正します。これをやらないと後述のjoinでエラーが発生します。

echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables

Masterのinit時に取得したコマンドを実行します(環境によってstringが違います)。このコマンドでMasterに参加します。つまり、初めてMasterと通信してます。

kubeadm join 192.168.1.80:6443 --token ef3cdn.70o8xcpksoech0eo --discovery-token-ca-cert-hash sha256:15c8eb4774268670a344c8b4d2b2fc891b0527e1049f5ef5e482b68d67d79e9e

うまくいけば、こんな感じになります。

[root@node1 ~]# kubeadm join 192.168.1.80:6443 --token ef3cdn.70o8xcpksoech0eo --discovery-token-ca-cert-hash sha256:15c8eb4774268670a344c8b4d2b2fc891b0527e1049f5ef5e482b68d67d79e9e
[preflight] running pre-flight checks
	[WARNING RequiredIPVSKernelModulesAvailable]: the IPVS proxier will not be used, because the following required kernel modules are not loaded: [ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack_ipv4] or no builtin kernel ipvs support: map[ip_vs:{} ip_vs_rr:{} ip_vs_wrr:{} ip_vs_sh:{} nf_conntrack_ipv4:{}]
you can solve this problem with following methods:
 1. Run 'modprobe -- ' to load missing kernel modules;
2. Provide the missing builtin kernel ipvs support

[discovery] Trying to connect to API Server "192.168.1.80:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://192.168.1.80:6443"
[discovery] Requesting info from "https://192.168.1.80:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "192.168.1.80:6443"
[discovery] Successfully established connection with API Server "192.168.1.80:6443"
[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.12" ConfigMap in the kube-system namespace
[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[preflight] Activating the kubelet service
[tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap...
[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "node1" as an annotation

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the master to see this node join the cluster.

失敗したかもしれません。大丈夫です。

もし前回の記事から少し時間を置いて構築している場合、以下のメッセージがLBノード側で表示されてたかもしれません。

[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.12" ConfigMap in the kube-system namespace
Unauthorized

実は、このメッセージを表示させるために記事を分けたという意図があったのでした。

初回にMasterノードをinitした時に以下のコマンドをコピーしましたね。

kubeadm join 192.168.1.80:6443 --token ef3cdn.70o8xcpksoech0eo --discovery-token-ca-cert-hash sha256:15c8eb4774268670a344c8b4d2b2fc891b0527e1049f5ef5e482b68d67d79e9e

このtokenは24時間しか有効じゃないんです。以下のコマンドをMasterノードで実行してみてください。

[root@master ~]# kubeadm token list
TOKEN                     TTL         EXPIRES                USAGES                   DESCRIPTION                                                EXTRA GROUPS
ef3cdn.70o8xcpksoech0eo   <invalid>   2018-12-02T11:51:23Z   authentication,signing   The default bootstrap token generated by 'kubeadm init'.   system:bootstrappers:kubeadm:default-node-token

「EXPIRES」が、initコマンドを実行した際のトークンの有効期限です。この有効期限以降にjoinコマンドで同じトークンを使用しても、unauthorizedになります。

なので、このトークンは使えないので、もう一つトークンを作ります。

Masterノードで以下を実行してください。

[root@master ~]# kubeadm token generate
ghx3fc.d5u4tu7tm4dputkk
[root@master ~]# kubeadm token create ghx3fc.d5u4tu7tm4dputkk --print-join-command --ttl=0
kubeadm join 192.168.1.80:6443 --token ghx3fc.d5u4tu7tm4dputkk --discovery-token-ca-cert-hash sha256:15c8eb4774268670a344c8b4d2b2fc891b0527e1049f5ef5e482b68d67d79e9e

後は出力された結果のコマンドをLBノードで実行するだけです。(ちなみに–ttl=0とは有効期限なしという意味なので、本番で使用してはいけません)

[preflight] Some fatal errors occurred:
	[ERROR FileAvailable--etc-kubernetes-bootstrap-kubelet.conf]: /etc/kubernetes/bootstrap-kubelet.conf already exists
	[ERROR FileAvailable--etc-kubernetes-pki-ca.crt]: /etc/kubernetes/pki/ca.crt already exists
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`

今度はLBNode側で違うエラーが表示されました。これは初回のjoin時にファイルが作られていて、ゴミが残ってるからです。

以下のコマンドで、一度LBNode側をリセットします。(MasterNodeじゃなくてLBNodeでやること)

[root@nodelb ~]# kubeadm reset
[reset] WARNING: changes made to this host by 'kubeadm init' or 'kubeadm join' will be reverted.
[reset] are you sure you want to proceed? [y/N]: y
[preflight] running pre-flight checks
[reset] stopping the kubelet service
[reset] unmounting mounted directories in "/var/lib/kubelet"
[reset] no etcd manifest found in "/etc/kubernetes/manifests/etcd.yaml". Assuming external etcd
[reset] please manually reset etcd to prevent further issues
[reset] deleting contents of stateful directories: [/var/lib/kubelet /etc/cni/net.d /var/lib/dockershim /var/run/kubernetes]
[reset] deleting contents of config directories: [/etc/kubernetes/manifests /etc/kubernetes/pki]
[reset] deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf]

これでリセットされたはずなので、再度joinコマンドを実行します。

[root@nodelb ~]# kubeadm join 192.168.1.80:6443 --token ghx3fc.d5u4tu7tm4dputkk --discovery-token-ca-cert-hash sha256:15c8eb4774268670a344c8b4d2b2fc891b0527e1049f5ef5e482b68d67d79e9e
[preflight] running pre-flight checks
	[WARNING RequiredIPVSKernelModulesAvailable]: the IPVS proxier will not be used, because the following required kernel modules are not loaded: [ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack_ipv4 ip_vs] or no builtin kernel ipvs support: map[ip_vs:{} ip_vs_rr:{} ip_vs_wrr:{} ip_vs_sh:{} nf_conntrack_ipv4:{}]
you can solve this problem with following methods:
 1. Run 'modprobe -- ' to load missing kernel modules;
2. Provide the missing builtin kernel ipvs support

[discovery] Trying to connect to API Server "192.168.1.80:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://192.168.1.80:6443"
[discovery] Requesting info from "https://192.168.1.80:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "192.168.1.80:6443"
[discovery] Successfully established connection with API Server "192.168.1.80:6443"
[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.12" ConfigMap in the kube-system namespace
[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[preflight] Activating the kubelet service
[tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap...
[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "nodelb" as an annotation

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the master to see this node join the cluster.

今回は正常に登録できたようですね。

MasterでLBNodeの登録を確認

Workerノードのときと同じです。

以下のコマンドでNodeの登録を確認します。

kubectl get node

結果は以下の出力になるはずです。

[root@master ~]# kubectl get node
NAME     STATUS   ROLES    AGE   VERSION
master   Ready    master   42h   v1.12.3
node1    Ready    <none>   41h   v1.12.3
node2    Ready    <none>   41h   v1.12.3
nodelb   Ready    <none>   64s   v1.12.3

重要なのは「master/node1/node2/nodelb」の全てが「Ready」になってることです。

繰り返しになりますが、ここまではWorkerノードをMasterに参加させる手順と同じでした。

ここからKubernetesのLoadBalancerとして使える「MetalLB」を導入していきます。

MetalLBの導入

前回の記事でも説明しましたが、MetalLBの導入については以下の記事を参考にさせていただきました。

>>Kubernetes on CentOS7

今回のラボでも上記の「MetalLBのデプロイ」のL2モードを参考に構築しています。

IPアドレスレンジは「192.168.1.85-192.168.1.89」としました。

[root@master ~]# cat metallb-l2.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.1.185-192.168.1.189

 

上記の記事ではtaint/tolerationの設定が紹介されていますが、node affinityで対応することも可能です。Flannel初期設定のセクションでtaint/tolerationはやったので、今回はnode affinityの設定を行ってみます。

既に上記の記事のapplyを行った方は、まずcontrollerを削除します。

[root@master ~]# kubectl get deployment -n metallb-system
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
controller   1         1         1            1           94s
[root@master ~]# kubectl delete deployment controller -n metallb-system
deployment.extensions "controller" deleted

次に、nodelbにnode affinityに認識させるラベルを付与します。

kubectl label nodes nodelb node.role=lb

ラベルが付与されたかの確認は「kubectl describe node nodelb」で確認します。

[root@master ~]# kubectl describe node nodelb
Name:               nodelb
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/hostname=nodelb
                    node.role=lb
以下省略

ちなみに、以下のコマンドでもラベルだけを確認できます。

[root@master ~]# kubectl get nodes nodelb --show-labels
NAME     STATUS   ROLES    AGE   VERSION   LABELS
nodelb   Ready    <none>   50m   v1.12.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=nodelb,node.role=lb

metallb.yamlにnode affinityの設定を追加します。

      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: "node.role"
                operator: In
                values: ["lb"]

再度適用します。

[root@master ~]# kubectl apply -f metallb.yaml
namespace/metallb-system unchanged
serviceaccount/controller unchanged
serviceaccount/speaker unchanged
clusterrole.rbac.authorization.k8s.io/metallb-system:controller unchanged
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker unchanged
role.rbac.authorization.k8s.io/config-watcher unchanged
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller unchanged
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker unchanged
rolebinding.rbac.authorization.k8s.io/config-watcher unchanged
daemonset.apps/speaker unchanged
deployment.apps/controller created

これでnodelbにcontrollerのPODが起動しました。

[root@master ~]# kubectl get pod -n metallb-system -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE
controller-567586546b-tg9rv   1/1     Running   0          14s   10.244.3.2     nodelb   <none>
speaker-5vxsx                 1/1     Running   0          17m   192.168.1.83   nodelb   <none>
speaker-df48d                 1/1     Running   0          17m   192.168.1.82   node2    <none>
speaker-hfpsq                 1/1     Running   0          17m   192.168.1.81   node1    <none>

簡単な動作確認

これでKubernetesラボ環境は終了です。

ざっくりと動作確認をしてみましょう。

この時点では「deploymentとは?」とか「podとは?」とかの説明を一切していない状態なので、とりあえず「ほぉ〜」と思っていただければ結構です。

この時点の学習レベルだと「環境を汚さないか?削除できないか怖い!」という不安があると思いますので、作成したオブジェクトの削除まで全部やるのでご安心ください。

全てMasterノード(192.168.1.80)で行います。

まず、Kubernetesのオフィシャルサイトでも使われている「kubernetes-bootcamp」イメージをデプロイします。このイメージを使う理由は以下の通り。

  • 初めからweb-serverが入ってるので確認しやすい
  • トップページにpod名を表示する機能があるので、LBの確認がしやすい
  • execでcontainerそのものに入った後にip -aができる。iproutingが予め入ってる。ネットワークの確認がしやすい
[root@master ~]# kubectl run kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1 --port=8080
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
deployment.apps/kubernetes-bootcamp created

これだけで、WebServerが動きました!地味に嬉しい!

[root@master ~]# kubectl get pod -o wide
NAME                                   READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE
kubernetes-bootcamp-598f57b95c-4g8f7   1/1     Running   0          7m16s   10.244.2.3   node2   <none>

上の「Node」列を見ると「node2」との記載があります。つまり、「たまたま」node2上で動きました。

次に外部(192.168.1.0/24のどのホストからでも)アクセスできるように設定します。

以下のファイルをbootcamp.yamlとして保存してください。

apiVersion: v1
kind: Service
metadata:
  name: kubernetes-bootcamp
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    run: kubernetes-bootcamp
  type: LoadBalancer

適用します。

[root@master ~]# kubectl apply -f bootcamp.yaml
service/kubernetes-bootcamp created

これでMetalLB設定時のIPレンジからIPが一つ払い出されてLBのVIPとしての役割を担ってるはずです。

確認します。

[root@master ~]# kubectl get svc -o wide
NAME                  TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE   SELECTOR
kubernetes            ClusterIP      10.96.0.1        <none>          443/TCP        43h   <none>
kubernetes-bootcamp   LoadBalancer   10.104.143.241   192.168.1.185   80:32070/TCP   5s    run=kubernetes-bootcamp

「EXTERNAL-IP」の列が、払い出されたIPです。

つまり、今回は「192.168.1.185」が払い出されました。

192.168.1.0/24のパソコンから「http://192.168.1.185」にアクセスします。(http://192.168.1.185:32070じゃないです)

bootcamp1

上記のメッセージがでたらOKです。kubernetes-bootcamp-XXの部分は文字列的に違うかもしれませんが、この画面が表示されたということは、Webサーバーの確認ができたということです。

 

では、後処理をします。

まずServiceを削除します。

[root@master ~]# kubectl get svc
NAME                  TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE
kubernetes            ClusterIP      10.96.0.1        <none>          443/TCP        43h
kubernetes-bootcamp   LoadBalancer   10.104.143.241   192.168.1.185   80:32070/TCP   12m
[root@master ~]# kubectl delete svc kubernetes-bootcamp
service "kubernetes-bootcamp" deleted
[root@master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   43h

次にDeploymentを削除します。

[root@master ~]# kubectl get deployment
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   1         1         1            1           14m
[root@master ~]# kubectl delete deployment kubernetes-bootcamp
deployment.extensions "kubernetes-bootcamp" deleted
[root@master ~]# kubectl get deployment
No resources found.

これで検証用に作ったオブジェクトが全て削除されました。

当然、再度同じオブジェクトを作ることもできます。

この時点のスナップショットを取ってください

これでラボ環境が出来上がりました!

嬉しくないですか?私だけでしょうか・・・

喜び勇んで色々試す前に、全4VMのスナップショットを取っておいてください。これで最悪色々試して壊したときにも元に戻れます。

 

ここまで色々やりました。多分90%くらいの作業は「自分が何をやってるかわからない」状態だったと思います。

次回から色々内容を解説する予定です。

コメント

  1. くらびす より:

    いつも細かく丁寧な記事を有難うございます。
    日頃から拝見させて頂いております。

    前編から通してほぼ同じ構成で構築をしており、途中まで順調にできていたのですが、「MetalLBの導入」で躓いてしまいました。
    speakerのStatusがどうしてもRunningとなりません。
    ———————————
    [root@k8smaster ~]# kubectl get pod -n metallb-system -o wide
    NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
    controller-7cc4fd9fbb-2b2mq 1/1 Running 0 35m 10.244.3.3 k8slb.localdomain
    speaker-kmh2s 0/1 CreateContainerConfigError 0 27m 172.16.88.238 k8snode2.localdomain
    speaker-mkmdd 0/1 CreateContainerConfigError 0 27m 172.16.88.239 k8snode1.localdomain
    speaker-q4r5j 0/1 CreateContainerConfigError 0 27m 172.16.88.237 k8slb.localdomain
    ———————————
    metallb.yamlの「speaker」のPod配置(?)の記述は下記にしております。
    ———————————
    tolerations:
    – key: “node-role.kubernetes.io/lb”
    operator: “Equal”
    effect: “NoSchedule”
    ———————————
    masterにラベル「master」を設定しspeakerの記述を以下に差し替えてもみたのですが、結果は変わりません。
    ———————————
    affinity:
    nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    – matchExpressions:
    – key: “node.role”
    operator: NotIn
    values: [“master”]
    ———————————
    尚、controllerは記載いただいているnode affinityの設定の設定をしており、問題なく動作しています。

    • CCIE_TOZAI より:

      訪問ありがとうございます!

      Metallbですが、参照いただいている記事からバージョンが変わっている可能性があり、最新情報は以下を参照してみてください。
      https://ccie-go.com/kubernetes-118-flannel-metallb/

      先程念の為、上記の手順でのMetallbを再構成(kubectl delete -f/kubectl apply -f)をしてみてController/Speaker両方とも動作しています。
      [root@master-prod ~]# kubectl get pod -n metallb-system
      NAME READY STATUS RESTARTS AGE
      controller-b6fff6579-qmgwc 1/1 Running 0 11s
      speaker-5dtn6 1/1 Running 0 11s
      speaker-9kv47 1/1 Running 0 11s
      speaker-g6qxg 1/1 Running 0 11s
      speaker-nsc9p 1/1 Running 0 11s

      参考までに、私の環境で動作しているmetallb.yamlをベタ出ししました。
      以下をコピペしたら私が使用しているmetallb.yamlと同一のはずです。

      また、動作しなかったPod(今回はSpeaker)のエラーは「kubectl describe pod [SpeakerPod名] -n metallb-system]で
      詳細のエラーが見れるはずなので、ヒントになるかもです。

      ——ここから——–
      apiVersion: policy/v1beta1
      kind: PodSecurityPolicy
      metadata:
      labels:
      app: metallb
      name: controller
      namespace: metallb-system
      spec:
      allowPrivilegeEscalation: false
      allowedCapabilities: []
      allowedHostPaths: []
      defaultAddCapabilities: []
      defaultAllowPrivilegeEscalation: false
      fsGroup:
      ranges:
      – max: 65535
      min: 1
      rule: MustRunAs
      hostIPC: false
      hostNetwork: false
      hostPID: false
      privileged: false
      readOnlyRootFilesystem: true
      requiredDropCapabilities:
      – ALL
      runAsUser:
      ranges:
      – max: 65535
      min: 1
      rule: MustRunAs
      seLinux:
      rule: RunAsAny
      supplementalGroups:
      ranges:
      – max: 65535
      min: 1
      rule: MustRunAs
      volumes:
      – configMap
      – secret
      – emptyDir

      apiVersion: policy/v1beta1
      kind: PodSecurityPolicy
      metadata:
      labels:
      app: metallb
      name: speaker
      namespace: metallb-system
      spec:
      allowPrivilegeEscalation: false
      allowedCapabilities:
      – NET_ADMIN
      – NET_RAW
      – SYS_ADMIN
      allowedHostPaths: []
      defaultAddCapabilities: []
      defaultAllowPrivilegeEscalation: false
      fsGroup:
      rule: RunAsAny
      hostIPC: false
      hostNetwork: true
      hostPID: false
      hostPorts:
      – max: 7472
      min: 7472
      privileged: true
      readOnlyRootFilesystem: true
      requiredDropCapabilities:
      – ALL
      runAsUser:
      rule: RunAsAny
      seLinux:
      rule: RunAsAny
      supplementalGroups:
      rule: RunAsAny
      volumes:
      – configMap
      – secret
      – emptyDir

      apiVersion: v1
      kind: ServiceAccount
      metadata:
      labels:
      app: metallb
      name: controller
      namespace: metallb-system

      apiVersion: v1
      kind: ServiceAccount
      metadata:
      labels:
      app: metallb
      name: speaker
      namespace: metallb-system

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
      labels:
      app: metallb
      name: metallb-system:controller
      rules:
      – apiGroups:
      – ”
      resources:
      – services
      verbs:
      – get
      – list
      – watch
      – update
      – apiGroups:
      – ”
      resources:
      – services/status
      verbs:
      – update
      – apiGroups:
      – ”
      resources:
      – events
      verbs:
      – create
      – patch
      – apiGroups:
      – policy
      resourceNames:
      – controller
      resources:
      – podsecuritypolicies
      verbs:
      – use

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
      labels:
      app: metallb
      name: metallb-system:speaker
      rules:
      – apiGroups:
      – ”
      resources:
      – services
      – endpoints
      – nodes
      verbs:
      – get
      – list
      – watch
      – apiGroups:
      – ”
      resources:
      – events
      verbs:
      – create
      – patch
      – apiGroups:
      – policy
      resourceNames:
      – speaker
      resources:
      – podsecuritypolicies
      verbs:
      – use

      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
      labels:
      app: metallb
      name: config-watcher
      namespace: metallb-system
      rules:
      – apiGroups:
      – ”
      resources:
      – configmaps
      verbs:
      – get
      – list
      – watch

      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
      labels:
      app: metallb
      name: pod-lister
      namespace: metallb-system
      rules:
      – apiGroups:
      – ”
      resources:
      – pods
      verbs:
      – list

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
      labels:
      app: metallb
      name: metallb-system:controller
      roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: metallb-system:controller
      subjects:
      – kind: ServiceAccount
      name: controller
      namespace: metallb-system

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
      labels:
      app: metallb
      name: metallb-system:speaker
      roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: metallb-system:speaker
      subjects:
      – kind: ServiceAccount
      name: speaker
      namespace: metallb-system

      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
      labels:
      app: metallb
      name: config-watcher
      namespace: metallb-system
      roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: config-watcher
      subjects:
      – kind: ServiceAccount
      name: controller
      – kind: ServiceAccount
      name: speaker

      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
      labels:
      app: metallb
      name: pod-lister
      namespace: metallb-system
      roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: pod-lister
      subjects:
      – kind: ServiceAccount
      name: speaker

      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
      labels:
      app: metallb
      component: speaker
      name: speaker
      namespace: metallb-system
      spec:
      selector:
      matchLabels:
      app: metallb
      component: speaker
      template:
      metadata:
      annotations:
      prometheus.io/port: ‘7472’
      prometheus.io/scrape: ‘true’
      labels:
      app: metallb
      component: speaker
      spec:
      containers:
      – args:
      – –port=7472
      – –config=config
      env:
      – name: METALLB_NODE_NAME
      valueFrom:
      fieldRef:
      fieldPath: spec.nodeName
      – name: METALLB_HOST
      valueFrom:
      fieldRef:
      fieldPath: status.hostIP
      – name: METALLB_ML_BIND_ADDR
      valueFrom:
      fieldRef:
      fieldPath: status.podIP
      – name: METALLB_ML_LABELS
      value: “app=metallb,component=speaker”
      – name: METALLB_ML_NAMESPACE
      valueFrom:
      fieldRef:
      fieldPath: metadata.namespace
      – name: METALLB_ML_SECRET_KEY
      valueFrom:
      secretKeyRef:
      name: memberlist
      key: secretkey
      image: metallb/speaker:v0.9.3
      imagePullPolicy: Always
      name: speaker
      ports:
      – containerPort: 7472
      name: monitoring
      resources:
      limits:
      cpu: 100m
      memory: 100Mi
      securityContext:
      allowPrivilegeEscalation: false
      capabilities:
      add:
      – NET_ADMIN
      – NET_RAW
      – SYS_ADMIN
      drop:
      – ALL
      readOnlyRootFilesystem: true
      hostNetwork: true
      nodeSelector:
      beta.kubernetes.io/os: linux
      serviceAccountName: speaker
      terminationGracePeriodSeconds: 2
      tolerations:
      – effect: NoSchedule
      key: node-role.kubernetes.io/master

      apiVersion: apps/v1
      kind: Deployment
      metadata:
      labels:
      app: metallb
      component: controller
      name: controller
      namespace: metallb-system
      spec:
      revisionHistoryLimit: 3
      selector:
      matchLabels:
      app: metallb
      component: controller
      template:
      metadata:
      annotations:
      prometheus.io/port: ‘7472’
      prometheus.io/scrape: ‘true’
      labels:
      app: metallb
      component: controller
      spec:
      containers:
      – args:
      – –port=7472
      – –config=config
      image: metallb/controller:v0.9.3
      imagePullPolicy: Always
      name: controller
      ports:
      – containerPort: 7472
      name: monitoring
      resources:
      limits:
      cpu: 100m
      memory: 100Mi
      securityContext:
      allowPrivilegeEscalation: false
      capabilities:
      drop:
      – all
      readOnlyRootFilesystem: true
      nodeSelector:
      beta.kubernetes.io/os: linux
      securityContext:
      runAsNonRoot: true
      runAsUser: 65534
      serviceAccountName: controller
      terminationGracePeriodSeconds: 0
      affinity:
      nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      – matchExpressions:
      – key: “node.role”
      operator: In
      values: [“lb”]

  2. くらびす より:

    早速のご回答有難うございます!

    ご教示いただいた設定と差分を無くしてもやはり駄目で、「 kubectl describe pod speaker -n metallb-system」を確認したところ「Error: secret “memberlist” not found」というエラーが出ていました。
    方々をググって解決策を探してみたのですが、結局どうしても解決できず、スナップショットからやり直し、最新バージョンのDocker/Kubernetesをインストールし、
    https://ccie-go.com/kubernetes-118-flannel-metallb/のページを参考とさせて頂くことで、全てREADYとなったことを確認致しました!
    ——————————————————
    [root@k8smaster ~]# kubectl get pod -n metallb-system
    NAME READY STATUS RESTARTS AGE
    controller-b6fff6579-5cnqw 1/1 Running 0 39m
    speaker-4hn49 1/1 Running 0 39m
    speaker-7nlmv 1/1 Running 0 39m
    speaker-dgq4j 1/1 Running 0 39m
    speaker-nwskv 1/1 Running 0 39m
    ——————————————————
    また、こちらの記事のkubernetes-bootcampもデプロイし、EXTERNAL-IPが割り当てることも確認致しました!
    ——————————————————
    [root@k8smaster ~]# kubectl get svc -o wide
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
    kubernetes ClusterIP 10.96.0.1 443/TCP 103m
    kubernetes-bootcamp LoadBalancer 10.110.167.95 172.16.88.241 80:30031/TCP 23m run=kubernetes-bootcamp
    ——————————————————

    記事の通り、スナップショットを取得していたお陰で解決の時間を早めることができたと思います。

    この度はアドバイス頂き有難うございました。
    引き続き一読者としてブログの更新を心待ちにしております。

    • CCIE_TOZAI より:

      おおおおおお!
      おめでとうございます!

      今回の件、私も非常に勉強になりました。

      今後とも、ぜひ宜しくお願いいたします!

タイトルとURLをコピーしました