大家好!这篇是 Kubernetes 部署的下篇,主要内容会聚焦在 Worker 节点组件 和 Ingress Controller 的安装。再坚持一下,等所有组件部署完,就能正式开始在集群里跑自己的应用啦!
下面这张图展示了部署完成后,流量在我实际网站中的大致走向,仅供参考
文章的内容比较多,我将其分成上下两篇来写。这是上篇的传送门:轻量云上二进制部署 Kubernetes(上篇)。下篇主要聚焦在以下部分:
kubernetes worker 节点运行如下组件:
kubelet 运行在每个 worker 节点上,接收 kube-apiserver 发送的请求,管理 Pod 容器,执行交互式命令,如 exec、run、logs 等
kubelet 启动时自动向 kube-apiserver 注册节点信息,内置的 cadvisor 统计和监控节点的资源使用情况
为确保安全,部署时关闭了 kubelet 的非安全 http 端口,对请求进行认证和授权,拒绝未授权的访问(如 apiserver、heapster 的请求)
TODO
TODO
Kuberneters 集群支持多种网络插件,例如:Flannel、Cilium、Calico、Weave。生产环境中用的比较多的是 Cilium。所以这里我们选择 Cilium 作为集群的网络插件
注意,在安装 Cilium 前,要前安装好 kube-proxy
我们可以根据 Cilium 官方提供的 安装文档 来安装
安装 Cilium 命令
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm -f cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}安装 Cilium 网络插件
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
helm repo add cilium https://helm.cilium.io/
helm repo update
helm install cilium cilium/cilium --namespace kube-system --set image.tag=1.17.6执行完上述命令之后,会在集群中安装 Cilium 网络插件。通过以下命令可以查看安装进度:
kubectl -n kube-system get pods | grep cilium输出:

如果 Pod 都处在 Running 状态,说明 Cilium 被正确安装。可以看到,helm install cilium cilium/cilium 会在 Kubernetes 集群中安装以下组件:
也可以通过以下命令来查看 Cilium 是否被正确安装:
cilium status --wait输出:

最后,验证一下集群网络
cd /opt/k8s/work
cat > busybox-for-cilium-test-ds.yaml <<EOF
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: busybox-for-cilium-test
labels:
addonmanager.kubernetes.io/mode: Reconcile
spec:
selector:
matchLabels:
app: busybox-for-cilium-test
template:
metadata:
labels:
app: busybox-for-cilium-test
spec:
containers:
- name: my-busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command:
- tail
- "-f"
- "/dev/null"
ports:
- containerPort: 80
EOF
kubectl create -f busybox-for-cilium-test-ds.yaml获取 Pod 创建状态:
kubectl get pods -o wide -l app=busybox-for-cilium-test
待 Pod 都处在 Running 状态后,测试是否可以从一个 Pod 内 ping 通另外一个 Pod 的 IP 地址:
kubectl exec -it busybox-for-cilium-test-kxv4x -- ping 10.0.0.120输出:

部署完网络插件之后,还需要部署 DNS 服务。要在 Kubernetes 集群内实现服务发现,必须具备 DNS 组件,以便将服务域名解析为 Pod IP,从而通过 IP 地址进行通信。目前,CoreDNS 是 Kubernetes 环境中最常用的 DNS 解决方案
下载和配置 CoreDNS
cd /opt/k8s/work
git clone https://github.com/coredns/deployment.git
mv deployment coredns-deployment部署 coredns
cd /opt/k8s/work/coredns-deployment/kubernetes
source /opt/k8s/bin/environment.sh
./deploy.sh -i ${CLUSTER_DNS_SVC_IP} -d ${CLUSTER_DNS_DOMAIN} | kubectl apply -f -我们检查下 CoreDNS 组件是否正常运行
$ kubectl get pods -n kube-system -l k8s-app=kube-dnscoredns Pod 处在 Running 状态,说明 coredns 部署成功
经过上面的部署,我们已经成功安装了 Kuberentes 正常工作需要的组件。下面我们来看下如何验证 Kubernetes 集群,查看其是否能正常工作,以确保 Kubernetes 集群被成功部署
检查节点状态

都为 Ready 且版本为 v1.31.1 时正常
创建一个用来测试的 nginx-ds DaemonSet 和 nginx-ds Service
cd /opt/k8s/work
cat > nginx-ds.yml <<EOF
apiVersion: v1
kind: Service
metadata:
name: nginx-ds
labels:
app: nginx-ds
spec:
type: NodePort
selector:
app: nginx-ds
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-ds
labels:
addonmanager.kubernetes.io/mode: Reconcile
spec:
selector:
matchLabels:
app: nginx-ds
template:
metadata:
labels:
app: nginx-ds
spec:
containers:
- name: my-nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
EOF创建 DaemonSet 和 Service 资源:
kubectl create -f nginx-ds.yml检查各节点的 Pod IP 连通性
kubectl get pods -o wide -l app=nginx-ds输出:

在所有 Node 上分别 ping 上面 2 个 Pod IP,看是否连通:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh ${node_ip} "ping -c 1 10.0.1.128"
ssh ${node_ip} "ping -c 1 10.0.0.64"
done输出:

检查服务 IP 和端口可达性
kubectl get svc -l app=nginx-ds
可以发现:
10.254.128.1098030784在所有 Node 上 curl Service IP:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh ${node_ip} "curl -s 10.254.128.109"
done预期输出 Nginx 欢迎页面内容:

检查服务的 NodePort 可达性
在所有 Node 上执行:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh ${node_ip} "curl -s ${node_ip}:30784"
done预期输出 Nginx 欢迎页面内容

Ingress Controller 的实现有很多种,像 Ingress-NGINX、Traefik、HAProxy、Contour、Kong、Istio Gateway 等,其中 Ingress-NGINX 是最脱颖而出的
Ingress-NGINX 是 Kubernetes 官方维护的项目,目前生态最成熟、而且有官方背书。生产环境使用最多的就是它,因此这里我选择使用 Ingress-NGINX 作为 Ingress Controller
使用 Helm 安装 Ingress-NGINX
在 Debain 12 系统上,准备 values-nodeport.yaml 文件
controller:
service:
type: NodePort
nodePorts:
http: 30080
https: 30443然后执行命令启动 Ingress-NGINX
helm install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespace -f values-nodeport.yaml注意,macOS 上使用 Docker Desktop 启动 Kubernetes 集群时,无需指定其它配置,可以直接使用下面命令安装
helm install my-ingress ingress-nginx/ingress-nginx --namespace ingress-nginx-helm --create-namespace查看 Ingress-NGINX 以及安装成功
helm list -n ingress-nginx
kubectl get svc -n ingress-nginx输出:

目前,ingress-nginx-controller 已通过 NodePort 暴露服务
接下来,我们将在宿主机上配置 Nginx 反向代理,将外部流量转发至 Ingress Controller,从而实现从宿主机到集群内部的访问链路
具体而言,只需在宿主机的 Nginx 配置中添加反向代理规则:
server {
listen 443 ssl;
listen [::]:443 ssl;
...
location / {
proxy_pass http://10.254.66.199:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port 443;
}
}
...OK 这样就大功告成了!完结撒花 🎉
以上