在ROKS集群之外的虚拟机上引入Calico,并直接访问Pod
IBM Cloud的Managed OpenShift(ROKS,Red Hat OpenShift on IBM Cloud Kubernetes Service)有一个特点是使用Calico作为SDN驱动程序(通常情况下是VXLAN的OpenShift SDN)。我了解到Calico作为功能的一部分,有一种方法可以让集群外的主机加入到Kubernetes SDN的网络中,并进行了尝试。
Calico – 关于非集群主机
https://docs.projectcalico.org/getting-started/bare-metal/about
首先要说明的是,尽管能够实现这一点,但从构成上来说并没有特别令人高兴的地方。这只是在告诉大家,如果想要与集群外的任意Pod进行通信,应该使用NodePort。
ROKS集群
既然如此,就在VPC gen2上创建。只需要2个节点。
https://cloud.ibm.com/kubernetes/catalog/create?platformType=openshift
需要进行标准计划的ICOS并在SecurityGroup中创建空间来创建集群。最终发现image-registry的Pod未能启动,因为证书不匹配或者出现错误(p11-kit: 无法完成文件的写入操作:/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt:操作不允许)。
尽管不稳定,但这次验证与此无关,所以我们跳过这一点。
虚拟服务器
在创建ROKS集群的相同子网中创建一个VPC虚拟服务器,使用最小的CentOS7。
虚拟服务器的名称示例为“neighbor”。
另外,由于CentOS8不再使用iptables,可能与Calico不兼容,所以我决定放弃。根据我初步搜索的结果,它似乎是可以运行的。
在OpenShift上创建Cluster Admin的SA。
为了让虚拟服务器中的Calico能够访问,我需要在OpenShift集群中创建具有Cluster Admin角色的SA,并获取其令牌。
获得oc命令。
https://mirror.openshift.com/pub/openshift-v4/clients/oc/
登录OpenShift集群的Web管理界面,在右上方选择”账户名称”,然后点击”复制登录命令”获取CLI登录的字符串。
3. 使用oc命令登录到集群。
# oc login --token=Y4PsrZ4LSgWHMd7gnB0G-ZXuHv9Vlyi6q0P67GyAcgw --server=https://c100-e.jp-tok.containers.cloud.ibm.com:31248
创建一个SA并将其分配cluster-admin角色。
# oc create sa admin
# oc adm policy add-cluster-role-to-user cluster-admin -z admin
5. 获取SA的令牌,并将其嵌入到kubeconfig中。
# oc get sa admin -o jsonpath='{.secrets}'
→ 「admin-token-*」のシークレット名を取得する。
# token=$(oc get secret <シークレット名> -o jsonpath='{.data.token}' | base64 -d)
# echo $token
→ eyJhbGciOiJSUzI1NiIsIm...みたいな、10行ぐらいのランダム文字列が表示
# server=$(grep -o 'https://.*$' .kube/config | head -n 1)
# cat > .kube/config << EOF
apiVersion: v1
kind: Config
preferences: {}
clusters:
- name: cluster
cluster:
server: ${server}
contexts:
- name: default
context:
cluster: cluster
namespace: default
user: admin
current-context: default
users:
- name: admin
user:
token: ${token}
EOF
完成后,请确保kubeconfig是有效的。
# oc get svc
(実行結果)
[root@neighbor ~]# oc get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 172.21.0.1 <none> 443/TCP 6h55m
openshift ExternalName <none> kubernetes.default.svc.cluster.local <none> 6h27m
openshift-apiserver ClusterIP 172.21.34.217 <none> 443/TCP 6h55m
安装 Calico Felix
需要引入容器版本(在文章创建时点)。
安装Docker。
# sudo yum install -y yum-utils
# sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# sudo yum install docker-ce docker-ce-cli containerd.io
# sudo systemctl start docker
在OpenShift集群中创建一个虚拟节点。
oc create -f - <<EOF
apiVersion: v1
kind: Node
metadata:
name: neighbor
EOF
确认运行在OpenShift集群上的Calico版本。
# oc get ds -n calico-system calico-node -o jsonpath='{.spec.template.spec.containers[0].image}'
→ ~calico/node:v3.16.5
4.启动 Calico。
在启动之前,可以确认当前的路由状态。
# route -n
(実行結果)
[root@neighbor ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.244.64.1 0.0.0.0 UG 0 0 0 eth0
10.244.64.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
开始运行。
# docker run -d --rm --net=host --privileged \
--name="calico-node" \
-e DATASTORE_TYPE="kubernetes" \
-e KUBECONFIG="/tmp/kube_config" \
-e CALICO_NODENAME="neighbor" \
-e CALICO_NETWORKING_BACKEND="bird" \
-v /var/log/calico:/var/log/calico \
-v /run/docker/plugins:/run/docker/plugins \
-v /lib/modules:/lib/modules \
-v /var/run/calico:/var/run/calico \
-v /etc/pki:/pki \
-v /root/.kube/config:/tmp/kube_config \
calico/node:v3.16.5
如果在启动后,路由表中添加了以下三行内容:「172.17.9.64 10.244.64.4」、「172.17.43.128 10.244.64.5」、「172.17.55.192 0.0.0.0」,那么就算是成功了。
[root@neighbor ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.244.64.1 0.0.0.0 UG 0 0 0 eth0
10.244.64.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.17.9.64 10.244.64.4 255.255.255.192 UG 0 0 0 eth0
172.17.43.128 10.244.64.5 255.255.255.192 UG 0 0 0 eth0
172.17.55.192 0.0.0.0 255.255.255.192 U 0 0 0 *
此外,假设我们连接到calico-node集群,我们应该能够确认虚拟服务器的地址(在这里是10.244.64.8)已添加到路由表作为路由器。
# oc exec -it -n calico-system calico-node-g4dpg bash
# ip route
...
172.17.55.192/26 via 10.244.64.8 dev eth0 proto bird
...
试着访问Pod
在使用oc get pod -o wide命令检查Pod时,所显示的Pod IP地址应属于172.17.9.64或172.17.43.128的子网之一。
请确认从虚拟服务器可以直接访问这些Pod IP地址。
比如,举个例子,普罗米修斯?
# ipaddr=$(oc get pod -n openshift-monitoring prometheus-k8s-0 -o jsonpath='{.status.podIP}')
# echo $ipaddr
→ 172.17.9.98
# start=$(date -d yesterday +%s)
# end=$(date +%s)
# curl -k -H "Authorization:Bearer $token" \
https://${ipaddr}:9091/api/v1/query_range \
--data-urlencode "start=$start" \
--data-urlencode "end=$end" \
--data-urlencode "step=30" \
--data-urlencode 'query=sum(rate(container_cpu_usage_seconds_total{namespace="default"}[5m])) by (pod_name) * 100'
“状态:成功,若成功输出大约100行的数据,即为成功。”
顺便说一下 shuō
最初に書いたが、実際には特に嬉しいことはなく、例えば、上記のPrometheusはデフォルトでルートが公開されているし、もしルートが公開されていなかったとしても、以下のようなNodePortを追加して、そこからアクセスするだけで良いです。
# oc expose pod -n openshift-monitoring prometheus-k8s-0 --type=NodePort --port 9091
# oc get node
# ipaddr=<適当なノードのIPアドレス>
# nodeport=$(oc get svc -n openshift-monitoring prometheus-k8s-0 -o jsonpath='{.spec.ports[0].nodePort}')
# curl -k -H "Authorization:Bearer $token" \
https://${ipaddr}:${nodeport}/api/v1/query_range \
--data-urlencode "start=$start" \
--data-urlencode "end=$end" \
--data-urlencode "step=30" \
--data-urlencode 'query=sum(rate(container_cpu_usage_seconds_total{namespace="default"}[5m])) by (pod_name) * 100'