一、安装k8s
参考 Creating a single master cluster with kubeadm
1. 安装 kubeadm,kubelet和kubectl
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
$ cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
$ sudo apt-get update
$ sudo apt-get install kubeadm kubelet kubectl
2. 禁用swap
$ sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
$ sudo swapoff -a
3. 初始化master节点
$ sudo kubeadm init --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=<your_ip_address>
# e.g. sudo kubeadm init --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=10.10.23.114
输出:
...
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join 10.10.23.114:6443 --token 8fssei.60vi31sjkpoinj4w --discovery-token-ca-cert-hash sha256:3b460e190cfbc9ad2cf7d3900559871efb831e252b6b8e5452a01a875229a3d7
继续执行:
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
4. 安装网络插件
$ kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml
$ kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml
5. 查看
$ kubectl get nodes
输出
NAME STATUS ROLES AGE VERSION
desktop-280 Ready master 11m v1.13.0
如果通过 kubectl get pods --all-namespaces
发现有 coredns 报错:
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system pod/coredns-86c58d9df4-ccwhd 0/1 CrashLoopBackOff 6 9m57s
kube-system pod/coredns-86c58d9df4-t9gvs 0/1 CrashLoopBackOff 6 9m57s
参考 nameserver 127.0.1.1 in resolv.conf won't go away!
首先编辑 /etc/NetworkManager/NetworkManager.conf
,注释 dns=dnsmasq
这一行,然后执行 sudo service network-manager restart
,然后查看 /etc/resolv.conf
, 如果有 nameserver 127.0.0.1
这一行,则注释掉。
然后执行 sudo kubeadm reset -f
,再重新执行上述步骤初始化master节点即可。
二、基本概念
该部分内容可参考:
k8s集群的基本结构可以参考下图:
图片来源 http://omerio.com/2015/12/18/learn-the-kubernetes-key-concepts-in-10-minutes/
注:图中 master 节点的 Replication Controller,现在是 Controller Manager
1. Master, Node
Master 节点主要运行的是:
- kube-apiserver:提供 RESTful API。kubectl 等工具以及其它组件通过 apiserver 来管理集群内的各种资源
- kube-controller-manager
- kube-scheduler
Node 节点主要运行的是:
- kubelet:与master节点进行通信
- kube-proxy:网络通信
2. Pod
Pod是k8s集群调度的最小工作单元,通常是由一个容器或者多个共同工作的容器组成。最常见的模式是一个Pod内有一个容器,在这种情况下,可以把Pod简单理解为对容器的一层包装,k8s直接管理的是Pod,而不是容器。如果一个Pod内有多个容器,那么这些容器应当是紧密关联共同协作的。
每个Pod有一个唯一的IP,并且可以挂载若干个Volume,Pod内的容器共享网络资源和存储资源,它们之间可以直接使用localhost来进行通信。
Pod的模板定义为:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
3. Service
Pod会被创建或者销毁,销毁后重新创建的Pod是一个新的Pod,IP也会发生变化。因此通过Pod的IP直接访问Pod是不现实的。因此在Pod之上加了一层Service,用户通过访问Service来访问Pod。Service是对一组Pod的一个抽象,通过Pod中定义的labels来选择出相应的Pod,组成一个Service。
每个Service都会分配一个全局唯一的虚拟IP,称为Cluster IP,并且在该Service的生命周期内,Cluster IP不会改变。同时Service也对Pod做了负载均衡。
Service的模板定义如下:
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
上面的定义选择了所有 app=MyApp
标签的Pod,并且访问该Service的80端口的时候,实际上会去访问Pod的9376端口。
4. Namespace
k8s支持在一个物理集群上分出多个虚拟集群,这就是Namespace。Namespace可用来实现多租户的资源隔离。k8s默认创建的集群有三个:
- default
- kube-public
- kube-system:k8s系统创建的资源位于该namesapce下
5. Controller
k8s通过Controller来管理Pod,Controller中会定义Pod的一些特性,例如副本数等。k8s中提供了多种Controller,用来使用不同的场景。常见的有:
- ReplicaSet:副本管理。主要定义了Pod的期望副本数,选择Pod的Label Selector以及当副本数不足时,用于创建新副本的Pod模板。
- Deployment:Deployment与ReplicaSet比较类似,是ReplicaSet更高一层的抽象,用于管理多个Pod,并确保Pod按照期望的方式运行。
- StatefulSet:用来管理有状态的应用。StatefulSet可以确保所管理的Pod副本在整个生命周期内的名称是不变的,即使销毁了重新创建,也会拥有固定的标识。
- DaemonSet:用于在每个Node上只运行一个Pod副本的场景。
- Job:运行结束后,相应的Pod就会被销毁。