この記事は「Kubernetesのラボ、初期構築(前編)」の続きとなります。
これまでやったこと
前編が終わった段階のKubernetes環境構築はこんな感じ。
- Masterノード(LoadBalancer以外)
- Workerノード(1と2)
残ってる作業は以下となります。
- LBノード(LoadBalancer)
- MasterノードからLoadBalancerの初期設定
終わったら簡単な稼働確認を行います。
LB Nodeの設定
LB Nodeの設定です。
手順は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の導入については以下の記事を参考にさせていただきました。
今回のラボでも上記の「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じゃないです)
上記のメッセージがでたら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%くらいの作業は「自分が何をやってるかわからない」状態だったと思います。
次回から色々内容を解説する予定です。
コメント
いつも細かく丁寧な記事を有難うございます。
日頃から拝見させて頂いております。
前編から通してほぼ同じ構成で構築をしており、途中まで順調にできていたのですが、「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の設定の設定をしており、問題なく動作しています。
訪問ありがとうございます!
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”]
早速のご回答有難うございます!
ご教示いただいた設定と差分を無くしてもやはり駄目で、「 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
——————————————————
記事の通り、スナップショットを取得していたお陰で解決の時間を早めることができたと思います。
この度はアドバイス頂き有難うございました。
引き続き一読者としてブログの更新を心待ちにしております。
おおおおおお!
おめでとうございます!
今回の件、私も非常に勉強になりました。
今後とも、ぜひ宜しくお願いいたします!