kubernetes 环境搭建之 minikube for Debian
官方文档:https://minikube.sigs.k8s.io/docs/start/
minikube 下载
# 可访问 github 下载最新版本
curl -LO https://github.com/kubernetes/minikube/releases/download/v1.38.1/minikube_latest_amd64.deb
# 安装
sudo dpkg -i minikube_latest_amd64.deb
# 可选择移除安装包
rm -rf minikube_latest_amd64.deb
# 检查安装
minikube version启动 minikube
注意:每次开机都需要运行 minikube start 命令来启动。
# 非 root 用户启动,需要把当前用户添加到 docker 用户组
sudo usermod -aG docker $USER
newgrp docker
# 若是以 root 用户启动,则需要添加 --force 参数。
#minikube start --force
# 启动(会拉取镜像,但国内 docker hub 会有网络问题)
# 从而,安装过程会转向从 github 拉取 kicbase-v0.0.50-amd64.tar 包。
# ,而 github 也不稳定,可以多试几次
minikube start
# 加 --alsologtostderr 参数打印详细日志
minikube start --alsologtostderr
# 解决方案一:
# 从加速地址直接拉取镜像(注意:版本可能不同,可根据日志信息修改)
docker pull kicbase/stable:v0.0.50
# 解决方案二:
# 多尝试若干次后,直到出现下面信息:
# Downloading: https://github.com/kubernetes/minikube/releases/download/v1.38.1/kicbase-v0.0.50-amd64.tar -> /home/aday/.minikube/cache/kic/amd64/stable_v0.0.50.tar
# 此时如果网速可以,那就等它下载完(大约 1.3GB),如果很慢,可以直接去 github 链接下载,然后 SFTP 上传到上面指定的缓存位置。
# 安装成功出现:
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
# 安装完毕后,在命令行输入以下命令来验证是否安装成功。
minikube status
# 停止 minikube
minikube stop
# 此命令会删除所有 minikube 资源。即:需要重新 minikube start
minikube delete --all --purge使用 minikube 自带的 kubuctl
# 第一次运行会下载并初始化 kubectl(如果网络问题失败,可多尝试几次)
minikube kubectl -- get pods -A
# 实在下载不下来可通过 `sudo apt install kubectl` 直接安装 kubectl 命令。具体安装教程参考下一章节。
# 临时增加别名,就可以不用单独安装 kubectl 了
alias kubectl="minikube kubectl --"
# 永久增加别名
echo 'alias kubectl="minikube kubectl --"' >> ~/.bashrc
# 立即生效
source ~/.bashrc
# 验证安装是否成功
kubectl version --client
# 这样查询
kubectl get po -A安装 kubectl
sudo apt update
sudo apt install -y kubectl
# 卸载
sudo apt remove --purge kubectl -y启动 dashboard
# dashboard 需要启用 metrics-server
minikube addons enable metrics-server
# 打开 Kubernetes dashboard。使用 --alsologtostderr 参数打印详细日志
minikube dashboard --url --alsologtostderr
# 会由于拉取镜像问题出现 ImagePullBackOff 的问题导致 dashboard 无法正常启动。
# 1. 查看Dashboard相关 Pod 的详细状态
kubectl get pods -n kubernetes-dashboard
# 2. 描述具体出错的Pod,获取事件详情
kubectl describe pod <pod-name> -n kubernetes-dashboard
# 示例
kubectl describe pod dashboard-metrics-scraper-5565989548-8lj25 -n kubernetes-dashboard
kubectl describe pod kubernetes-dashboard-b84665fb8-wsm6v -n kubernetes-dashboard
# 可以找到所需要的镜像:
# docker.io/kubernetesui/metrics-scraper:v1.0.8@sha256:2e500usjuu877h7hh7......
# docker.io/kubernetesui/dashboard:v2.7.0@sha256:2e500usjuu877h7hh7......
# 3. 进入 Minikube 节点内部的 docker,测试网络连通性
# 注意:这个 docker 是 minikube 内部的,不是虚拟机宿主机上的。
minikube ssh
# 进入后,尝试直接拉取镜像(需要科学上网)
docker pull kubernetesui/metrics-scraper:v1.0.8
docker pull kubernetesui/dashboard:v2.7.0
# 可考虑从镜像加速地址下载。如:registry.cn-hangzhou.aliyuncs.com
# 1. 拉取镜像
# 2.重新 tag 为原始镜像名称和版本
# 3. 移除加速地址镜像 tag
# 退出 minikube 内部 SSH
exit
# 由于本人使用自己打的 kubernetesui/dashboard:v2.7.0 和 kubernetesui/metrics-scraper:v1.0.8 镜像。
# 因此 @sha256 值发生了变化,所以需要修改这两个镜像的拉取策略。
# 干脆直接把 image 配置改为 kubernetesui/dashboard:v2.7.0 和 kubernetesui/metrics-scraper:v1.0.8
# 去掉后面的 @sha225 值,只通过名称和版本号匹配镜像。
# 注意:如果没有修改原始镜像的 @sha256 值,则不需要编辑。
# 编辑 dashboard(vim 编辑完记得保存)
kubectl edit deployment kubernetes-dashboard -n kubernetes-dashboard
# 编辑 metrics-scraper(vim 编辑完记得保存)
kubectl edit deployment dashboard-metrics-scraper -n kubernetes-dashboard
# 4. 强制删除旧的 Pod,让系统用本地镜像重建(不行的话使用 minikube stop 和 minikube start 重启)
kubectl delete pod -n kubernetes-dashboard --all
# 再次查看状态(已经变为 Running 状态了)
kubectl get pods -n kubernetes-dashboard
# 正式启动
minikube dashboard --url
# 输出
🤔 Verifying dashboard health ...
🚀 Launching proxy ...
🤔 Verifying proxy health ...
http://127.0.0.1:41859/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
# 由于是在Vmware中的 Debian 启动的dashboard, 要在Windows下的浏览器中访问:
# 用SSH工具新开一个连接窗口,开启代理(aday 用户)
# kube-proxy 端口转发
kubectl proxy --address=0.0.0.0 --disable-filter=true
# 输出
W0406 00:50:07.757716 31140 proxy.go:177] Request filter disabled, your proxy is vulnerable to XSRF attacks, please be cautious
Starting to serve on [::]:8001
# 不能关闭当前SSH进程和窗口,Windows 浏览器访问 dashboard:
http://<Debian虚拟机的IP>:<端口为上面proxy中显示的端口,默认8001>/api/v1/namespaces/<服务的namespace>/services/http:<服务名称>:<服务端口>/proxy/
# Windows 浏览器访问示例:
http://192.168.233.132:8001/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/kubectl proxy
kubectl proxy
让外部网络访问 K8S service 的 ClusterIP
# 使用kubectl proxy命令就可以使API server监听在本地的8001端口上:
kubectl proxy
Starting to serve on 127.0.0.1:8001
# 如果想通过其它主机访问就需要指定监听的地址:
kubectl proxy --address=0.0.0.0
# 此时通过curl访问会出现未认证的提示:
curl -X GET -L http://k8s-master:8009/
<h3>Unauthorized</h3>
# 设置API server接收所有主机的请求:
kubectl proxy --address='0.0.0.0' --accept-hosts='^*$'
Starting to serve on [::]:8001
# 访问正常:
curl -X GET -L http://k8s-master:8009/
{
"paths": [
"/api",
"/api/v1",
...
]
}
# 指定一个端口:
kubectl proxy --address='0.0.0.0' --accept-hosts='^*$' --port=8009
Starting to serve on [::]:8009
# 关于未认证的问题,干脆禁用:
kubectl proxy --address='0.0.0.0' --disable-filter=true启用 Ingress
官方文档:https://kubernetes.io/zh/docs/tasks/access-application-cluster/ingress-minikube/
# 用时较长,耐心等待,如果第一遍开启失败,多尝试几遍
minikube addons enable ingress
# 查看
minikube addons list
# 检查验证 NGINX Ingress 控制器处于运行状态
kubectl get pods -n kube-system部署 nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.1
# IfNotPresent, Always, Never
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
# #如果使用Ingress, 这里可以不通过NodePort暴露端口,即可以注释掉。这里为了测试Service, 所以暴露出来
type: NodePort
selector:
app: nginx
ports:
# 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
- port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
annotations:
# 指定了我们使用后端ingress controller的类别,如果后端有多个ingress controller的时候很重要
kubernetes.io/ingress.class: 'nginx'
# nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: mengweijin.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80说明
查看当前可用的 API 版本
kubectl api-versions
关于限制 cpu 和内存,建议学习环境不要限制,限制了容易启动卡死,必须分配足够的资源才行。
minikube ssh : 进入 Docker 容器
执行部署命令:
# --record 标志将所执行的命令写入资源注解 kubernetes.io/change-cause 中。 这对于以后的检查是有用的。例如,要查看针对每个 Deployment 修订版本所执行过的命令。
kubectl apply -f nginx.yaml --record使用 Service 访问应用
# 方式一 VMware 虚拟机中访问
# 显示访问 service 的 url: 然后把这个 url 放到浏览器里
minikube service nginx --url
# port 通过 kubectl get service nginx 查看
curl url:port
# 方式二 Windows 下访问
# 或者通过 kubectl port-forward 端口转发的方式访问 K8S 中的应用
kubectl port-forward service/nginx 7000:80
# Windows 下访问(或用浏览器访问 mengweijin.com)
curl http://localhost:7000
# 方式三 Windows 下访问
# kube-proxy 端口转发(在新的 ssh 窗口下运行),转发端口:8001
kubectl proxy --address=0.0.0.0 --disable-filter=true
# Windows 下访问:
http://192.168.171.131:8001/api/v1/namespaces/default/services/http:nginx:80/proxy/使用 Ingress 访问应用
kubectl get ingress
# 命令行输出
PS C:\Users\mengweijin\Documents\MobaXterm\home> kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx <none> mengweijin.com 192.168.49.2 80 14mIngress 中没有配置 host 路由
# 如果 Ingress 中没有配置host路由: host: mengweijin.com,直接可以使用如下IP访问到。
curl 192.168.49.2Ingress 中配置了 host 路由
# (root用户)
vi /etc/hosts
# 在 hosts 文件的末尾添加以下内容
192.168.49.2 mengweijin.com
# 使hosts立刻生效
/etc/init.d/network restart
# 说明: 如果你在本地运行 Minikube 环境,需要使用下面命令获得外部 IP 地址。 Ingress 列表中显示的 IP 地址会是内部 IP 地址。
minikube ip
# 查看 ingress 映射详情
kubectl describe ingress nginx
# 在CentOS虚拟机中访问(或用CentOS中的浏览器访问 mengweijin.com)能看到 nginx 首页
curl mengweijin.comWindows 浏览器访问 ingress 服务
类似于访问 dashboard, 开启 proxy 后:
http://192.168.171.131:8001/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
# 照猫画虎
http://192.168.171.131:8001/api/v1/namespaces/default/services/http:nginx:/proxy/Manage your cluster
# Pause Kubernetes without impacting deployed applications:
minikube pause
# Halt the cluster:
minikube stop
# Increase the default memory limit (requires a restart):
minikube config set memory 16384
# Browse the catalog of easily installed Kubernetes services:
minikube addons list
# Create a second cluster running an older Kubernetes release:
minikube start -p aged --kubernetes-version=v1.16.1
# Delete all of the minikube clusters:
minikube delete --allkubectl
kubectl version
kubectl get namespace
kubectl get nodes
kubectl describe node nodeName
kubectl apply -f nginx.yaml --record
kubectl get deployment
kubectl get deployments
kubectl get pods
kubectl get pods -o wide
kubectl get pods --all-namespaces
kubectl get service
kubectl get all
kubectl get all --all-namespaces
kubectl describe pod nginx
kubectl delete -f nginx.yaml
kubectl delete deployment nginx
kubectl delete service nginx
kubectl logs -f podName
kubectl exec -it podName -- /bin/bash
kubectl port-forward service/nginx 7000:8888
kubectl describe quota # 查看当前 namespace 下的cpu, memory, storage 的限制和使用情况
kubectl get pods/podname -o yaml
kubectl get deployment ingress-nginx-controller -n kube-system -o yaml
kubectl get deployment ingress-nginx-controller -n kube-system -o yaml > ingress-nginx-controller-deploy.yaml
--enable-ssl-passthrough
kubectl patch deployment ingress-nginx-controller --patch "$(cat ingress-nginx-patch.yaml)" -n kube-system
# 监控 ingress-nginx-controller 日志
kubectl get pods -n kube-system
kubectl -n kube-system logs -f ingress-nginx-controller-84db5fd745-xqdc4
# 在 ingress-nginx-controller pod 中可以测试请求外面的服务
kubectl exec -n kube-system <ingress pod> -- curl -v <service name>:8080
kubectl exec -it -n kube-system ingress-nginx-controller-6c8559fd4d-2r8xf -- cat /etc/nginx/nginx.conf
kubectl label namespace default istio-injection-
# 从本地复制 aaa.txt 文件到 容器 application-demo-deployment-823726322c-9ssfd9 中的 /tmp 目录下
kubectl cp -n default aaa.txt application-demo-deployment-823726322c-9ssfd9:/tmp
# 从Pod容器中copy文件至本地
kubectl cp <some-namespace>/<some-pod>:<root_dir>/<parent_dir>/temp/lalalaB ./lalalaC
kubectl cp default/cloud-786d84c554-p7jz7:app/logs/app/cloud.log cloud.logk8s 对外暴露服务的方法
向 k8s 集群外部暴露服务的方式有三种: nodePort,LoadBalancer 和本文要介绍的 Ingress。每种方式都有各自的优缺点。
- nodePort 方式在服务变多的情况下会导致节点要开的端口越来越多,不好管理。
- LoadBalancer 更适合结合云提供商的 LB 来使用,但是在 LB 越来越多的情况下对成本的花费也是不可小觑。
- Ingress 是 k8s 官方提供的用于对外暴露服务的方式,也是在生产环境用的比较多的方式,一般在云环境下是 LB + Ingress Controller 方式对外提供服务,这样就可以在一个 LB 的情况下根据域名路由到对应后端的 Service,有点类似于 Nginx 反向代理,只不过在 k8s 集群中,这个反向代理是集群外部流量的统一入口。
K8S 中同一集群服务之间的访问
k8s 的服务名 DNS 解析
Kubernetes 目前使用的 kube-dns 来实现集群内部的 service dns 记录解析。默认情况下/etc/resolv.conf 里,它的内容是统一的格式。
/ # more /etc/resolv.conf
nameserver 172.19.0.10
search saas.svc.cluster.local svc.cluster.local cluster.local
options ndots:5search doamin 列表默认情况下,它只包含本地域名。这可以通过在 search 关键字后面列出所需的域搜索路径来添加。kubernetes 为每个容器配置默认是${namespace}.svc.cluster.local svc.cluster.local cluster.local。在一次 dns 域名查询时,将会尝试使用每个 search doamin 依次搜索少于 ndots 点(默认值为 1)的解析器查询,直到找到匹配项。对于具有多个子域的环境,建议调整选项 ndots:n,以避免 man-in-the-middle 攻击和 root-dns-servers 的不必要通信。
这个我们可以把它理解成服务名 dns 解析的层次,例如{服务名}是一级,而{服务名}.{命名空间}为二层,{服务名}.{命名空间}.svc.cluster.local 是第三层,上面的配置一共有 5 层,同时也开启了 5 层,这样做可以保证最大限度的找到你的服务,但对于解析的性能是有影响的。
同一 namespace 下的 pod 之间的访问
假如 A 服务(serviceName=aaaa) 调用 B 服务(serviceName=bbbb)中的接口:http://localhost:8080/test
那么在 A 工程中可以通过 B 服务的 serviceName 来调用 B 服务。例如在 A 服务中配置 B 服务中的接口格式为:http://bbbb:8080/test
跨 namespace 下的 pod 之间的访问
假如 A 服务(namespace=ns1, serviceName=aaaa) 调用 B 服务(namespace=ns2, serviceName=bbbb)中的接口:http://localhost:8080/test
A 服务调用 B 服务的调用方式为:http://bbbb.ns2:8080/test
