这里将尝试使用之前编译完的源码来构建一个最小化启动的集群
要运行一个最小级别的 Kubernetes 至少要包括如下三个基本组件:
- kubelet:在集群中每个节点上运行的代理,负责容器真正运行的核心组件
- kube-apiserver:Kubernetes 控制平面的组件,提供资源操作的唯一入口
- 容器运行时(Docker)
我们创建一个 minik8s 的文件夹用来实验
拷贝 kubectl 和 kubelet 两个可执行二进制文件到这个文件夹中,然后创建一个 pods 文件夹
启动 kubelet 来试一下
sudo ./kubelet --pod-manifest-path=pods --fail-swap-on=false
然后创建一个 helloworld pod
apiVersion: v1
kind: Pod
metadata:
name: hello
spec:
containers:
- image: busybox
name: hello
command: ["echo", "hello world!"]
kubelet 进程会自动加载这个文件,并且尝试启动对应的pod,但是这里报错了
这是因为 Kubernetes 的 Pod 默认情况下会优先启动一个 k8s.gcr.io/pause:3.2
的 pause 镜像,而该镜像由于某些原因获取不到,我们可以 --pod-infra-container-image
参数重新指定一个可以访问到的镜像:
sudo ./kubelet --pod-manifest-path=pods --fail-swap-on=false --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2
为了启动 apiserver,要先启动一个 etcd 服务
apiVersion: v1
kind: Pod
metadata:
name: etcd
namespace: kube-system
spec:
containers:
- name: etcd
command:
- etcd
- --data-dir=/var/lib/etcd
image: registry.aliyuncs.com/google_containers/etcd:3.4.3-0
volumeMounts:
- mountPath: /var/lib/etcd
name: etcd-data
hostNetwork: true
volumes:
- hostPath:
path: /var/lib/etcd
type: DirectoryOrCreate
name: etcd-data
然后来启动 apiserver
apiVersion: v1
kind: Pod
metadata:
name: kube-apiserver
namespace: kube-system
spec:
containers:
- name: kube-apiserver
command:
- kube-apiserver
- --etcd-servers=http://127.0.0.1:2379
image: cnych/kube-apiserver:v1.18.5
hostNetwork: true
尝试一下 kubectl 命令行
这里没取到 pod 信息是因为缺少 kubeconfig 配置
创建 kubeconfig.yaml
apiVersion: v1
kind: Config
clusters:
- cluster:
server: http://127.0.0.1:8080
name: mink8s
contexts:
- context:
cluster: mink8s
name: mink8s
current-context: mink8s
重启kubelet 进程,加入 kubeconfig 参数
sudo ./kubelet --pod-manifest-path=pods --fail-swap-on=false --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2 --kubeconfig=kubeconfig.yaml
接下来尝试在这个环境中部署一个nginx
创建一个 nginx yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
因为没有默认的 service account ,所以会直接报错
创建 默认的 service account
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
namespace: default
然后再重试,发现缺少token
修改一下 service account 配置,关闭 token
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
namespace: default
automountServiceAccountToken: false
这里可以看到 nginx pod 和 helloworld 都没有正常启动
这是因为没有调度器, scheduler 负责调度,这里直接使用 nodeName 将pod 固定到节点上,编辑 nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
nodeName: ubuntu
这里有一个点需要注意,直接 apply 会报错,需要先删除原来的 pod,再创建
调用一下 curl
./kubectl get pods -owide
./kubectl logs curl
apiVersion: v1
kind: Pod
metadata:
name: curl
spec:
containers:
- image: curlimages/curl
name: curl
command: ["curl", "172.17.0.3"]
nodeName: ubuntu
这里稍微再扩展一下,如果不使用 docker,也可以直接使用 二进制文件 启动 apiserver
sudo ./kube-apiserver –etcd-servers=http://127.0.0.1:2379 –service-cluster-ip-range=10.0.0.0/24