K8S简记
Kubernetes 是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署,规划,更新,维护的一种机制。
目录
概念
组织结构
安装
常用命令
K8S配置文件编写
概念 Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。
Kubernetes 提供如下服务 :
服务发现和负载均衡
存储编排
自动部署和回滚
自动完成装箱计算
自我修复
密钥与配置管理
这张图表展示了包含所有相互关联组件的 Kubernetes 集群。
控制平面组件
控制平面的组件对集群做出全局决策(比如调度),以及检测和响应集群事件(例如,当不满足部署的 replicas
字段时,启动新的 pod )。
kube-apiserver
etcd
kube-scheduler
kube-controller-manager
节点控制器
任务控制器
端点控制器
服务帐户和令牌控制器
cloud-controller-manager
Node 组件
节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行环境。
插件
插件使用 Kubernetes 资源(DaemonSet 、 Deployment 等)实现集群功能。 因为这些插件提供集群级别的功能,插件中命名空间域的资源属于 kube-system
命名空间。
DNS
Web 界面 Dashboard
容器资源监控
集群层面日志
Kubernetes 使用Kubernetes 对象实体去表示整个集群的状态。
哪些容器化应用在运行(以及在哪些节点上)
可以被应用使用的资源
关于应用运行时表现的策略,比如重启策略、升级策略,以及容错策略
操作 Kubernetes 对象 —— 无论是创建、修改,或者删除 —— 需要使用 Kubernetes API
对象 spec
(规约) 和 对象 status
(状态)
当使用 Kubernetes API 创建对象时(或者直接创建,或者基于kubectl
), API 请求必须在请求体中包含 JSON 格式的信息。 大多数情况下,需要在 .yaml 文件中为 kubectl
提供这些信息 。 kubectl
在发起 API 请求时,将这些信息转换成 JSON 格式。
如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 2 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
在想要创建的 Kubernetes 对象对应的 .yaml
文件中,需要配置如下的字段:
apiVersion
- 创建该对象所使用的 Kubernetes API 的版本
kind
- 想要创建的对象的类别
metadata
- 帮助唯一性标识对象的一些数据,包括一个 name
字符串、UID 和可选的 namespace
spec
- 你所期望的该对象的状态
组织结构
K8S : 节点(容器)的集合
node:K8S的工作机器
Pod:表示集群上正在运行的一组容器
ReplicaSet:容器的副本
Deployment:用于部署应用的对象
container:容器(docker)
service:将pods上的应用的网络映射出去的抽象方法
Pod创建流程:
安装 1.0 常用命令 1 2 3 4 5 6 7 8 9 10 apt download tree apt download libonig5 libjq1 jq apt download socat apt downlaod conntrack dpkg -i tree_1.8.0-1_amd64.deb dpkg -i libonig5_6.9.4-1_amd64.deb dpkg -i libjq1_1.6-1ubuntu0.20.04.1_amd64.deb dpkg -i jq_1.6-1ubuntu0.20.04.1_amd64.deb dpkg -i socat_1.7.3.3-2_amd64.deb dpkg -i conntrack_1.3a1.4.5-2_amd64.deb
1.1 Docker 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 apt-get purge docker-ce docker-ce-cli containerd.io -y rm -rf /var/lib/docker rm -rf /var/lib/containerd sudo apt-get remove docker docker-engine docker.io containerd runc -y wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/containerd.io_1.4.12-1_amd64.deb wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/docker-ce-cli_19.03.15~3-0~ubuntu-focal_amd64.deb wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/docker-ce_19.03.15~3-0~ubuntu-focal_amd64.deb dpkg -i containerd.io_1.4.12-1_amd64.deb dpkg -i docker-ce-cli_19.03.15~3-0~ubuntu-focal_amd64.deb dpkg -i docker-ce_19.03.15~3-0~ubuntu-focal_amd64.deb apt-mark hold containerd.io apt-mark hold docker-ce-cli apt-mark hold docker-ce sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s) -$(uname -m) " -o docker-compose sudo chmod +x docker-compose cp docker-compose /usr/local /bin
参考
Install Docker Compose | Docker Documentation
Install Docker Engine on Ubuntu | Docker Documentation
Index of linux/ubuntu/dists/ (docker.com)
1.2 Kubernetes 允许 iptables 检查桥接流量
1 2 3 4 5 cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF sudo sysctl --system
安装 cni 命令
1 2 3 4 CNI_VERSION="v0.8.2" wget "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION} /cni-plugins-linux-amd64-${CNI_VERSION} .tgz" sudo mkdir -p /opt/cni/bin sudo tar -f cni-plugins-linux-amd64-${CNI_VERSION} .tgz -C /opt/cni/bin -xz
安装 crictl 命令
1 2 3 CRICTL_VERSION="v1.19.0" wget "https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION} /crictl-${CRICTL_VERSION} -linux-amd64.tar.gz" sudo tar -f crictl-${CRICTL_VERSION} -linux-amd64.tar.gz -C /usr/local /bin -xz
安装 kube 命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 DOWNLOAD_DIR="/usr/local/bin" RELEASE_VERSION="v1.19.16" sudo curl -L --remote-name-all https://dl.k8s.io/${RELEASE_VERSION} /bin/linux/amd64/{kubeadm,kubelet,kubectl} sudo chmod +x {kubeadm,kubelet,kubectl} cp {kubeadm,kubelet,kubectl} $DOWNLOAD_DIR RELEASE_VERSION="v0.4.0" curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION} /cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:${DOWNLOAD_DIR} :g" | sudo tee kubelet.service curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION} /cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:${DOWNLOAD_DIR} :g" | sudo tee 10-kubeadm.conf sudo mkdir -p /etc/systemd/system/kubelet.service.d cp kubelet.service /etc/systemd/system/ cp 10-kubeadm.conf /etc/systemd/system/kubelet.service.d/ systemctl enable --now kubelet systemctl daemon-reload systemctl restart kubelet
配置 docker 驱动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 mkdir /etc/docker cat > daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "registry-mirrors": [ "https://registry.docker-cn.com", "https://docker.mirrors.ustc.edu.cn", "http://hub-mirror.c.163.com", "https://cr.console.aliyun.com/" ], "log-driver": "json-file", "log-opts": { "max-size": "256m" }, "storage-driver": "overlay2" } EOF cp daemon.json /etc/docker/ sudo systemctl daemon-reload service docker restart service docker status
参考:
Download Kubernetes
Install and Set Up kubectl on Linux | Kubernetes
Installing kubeadm | Kubernetes
Install Tools | Kubernetes
2. 集群搭建 2.1 网络配置 开始安装前确保每台机器的主机名、网卡MAC地址都是唯一的。
依次配置静态IP地址192.168.200.128、192.168.200.129、192.168.200.130。
VMware的虚拟机如果要让其他机器访问,要先把虚拟机设置为桥接模式(不需要复制物理网络连接状态),然后把IP迁移到所桥接的网卡的网段下面。最好到网络适配器里面充值一下MAC地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 network: ethernets: ens32: addresses: - 192.168 .200 .130 /24 gateway4: 192.168 .200 .2 nameservers: addresses: - 223.5 .5 .5 - 223.6 .6 .6 search: [] version: 2
Master节点开放如下端口:
6443 kubernetes api server
2379-2380 etcd server client api
10250 kubelet api
10251 kube-scheduler
10252 kube-controller-manager
10255 read-only kubelet api (heapster)
1 2 3 4 5 6 7 ufw allow 6443 ufw allow 2379 ufw allow 2380 ufw allow 10250 ufw allow 10251 ufw allow 10252 ufw allow 10255
Worker节点
10250 kubelet api
10255 read-only kubelet api (heapster)
30000-32767 default port range for NodePort Services
1 2 3 4 ufw allow 10250 ufw allow 10255 ufw allow 30000:32767/tcp ufw allow 30000:32767/udp
其他防火墙规则自行定义。
2.2 启动节点 启动 Master
1 2 3 4 5 6 7 8 hostnamectl set-hostname kubemaster kubeadm init --pod-network-cidr 192.168.0.0/16 --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers --kubernetes-version v1.19.16 --v=6 rm -rf $HOME /.kube mkdir -p $HOME /.kube sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown $(id -u):$(id -g) $HOME /.kube/config
启动 Worker1
1 2 hostnamectl set-hostname kubeworker1 kubeadm join 192.168.200.128:6443 --token cv46y9.itvzhbzn0wyyx5k1 --discovery-token-ca-cert-hash sha256:4eba29149c287ef57c01bf8310cb5d202afd88906e67665352ad2919f0b4ad6b
启动 Worker2
1 2 hostnamectl set-hostname kubeworker2 kubeadm join 192.168.200.128:6443 --token cv46y9.itvzhbzn0wyyx5k1 --discovery-token-ca-cert-hash sha256:4eba29149c287ef57c01bf8310cb5d202afd88906e67665352ad2919f0b4ad6b
如果之后有新的节点需要加入网络,则需要在Master上执行如下命令
1 2 3 4 5 kubeadm token create openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' kubeadm join 172.18.118.194:6443 --token pxyrmw.g19twnwtchqtvr58 --discovery-token-ca-cert-hash sha256:9210114b1234d10a38837c7f2ee95d9c1cc875caa504aba6f2d3509ffdcc3066 -v=6
安装网络插件
1 2 3 wget https://docs.projectcalico.org/manifests/calico.yaml kubectl apply -f calico.yaml kubectl get pods -o wide -n kube-system
设置节点角色
1 2 3 4 5 kubectl label nodes kubeworker1 node-role.kubernetes.io/node= kubectl label nodes kubeworker2 node-role.kubernetes.io/node= kubectl taint nodes --all node-role.kubernetes.io/master-
备份 docker 镜像
1 2 3 4 5 6 7 8 9 10 11 docker save -o calico-node-v3.21.1.tar calico/node:v3.21.1 docker save -o calico-pod2daemon-flexvol-v3.21.1.tar calico/pod2daemon-flexvol:v3.21.1 docker save -o calico-cni-v3.21.1.tar calico/cni:v3.21.1 docker save -o calico-kube-controllers-v3.21.1.tar calico/kube-controllers:v3.21.1 docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-kube-apiserver-v1.19.16.tar registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.19.16 docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-kube-controller-manager-v1.19.16.tar registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.19.16 docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-kube-proxy-v1.19.16.tar registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.19.16 docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-kube-scheduler-v1.19.16.tar registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.19.16 docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-etcd-3.4.13-0.tar registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.13-0 docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-coredns-1.7.0.tar registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.7.0 docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-pause-3.2.tar registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
移除节点命令
1 kubectl drain ideacentre-geekpro-15ick --delete-local-data --force --ignore-daemonsets
2.3 高可用集群 kubeadm实现高可用的思路是先搭建负载均衡服务,在使用kubeadm init 的时候增加选项—control-plane-endpoint 和—upload-certs 即可。--control-plane-endpoint
标志应该被设置成负载均衡器的地址或 DNS 和端口;--upload-certs
标志用来将在所有控制平面实例之间的共享证书上传到集群。
然后节点使用kubeadm join 加入集群的时候通过增加两个额外的选项—control-plane 和—certificate-key 即可。—certificate-key 的值在kubeadm init 的时候会默认输出一个。过期之后也可用类似于token通过sudo kubeadm init phase upload-certs —upload-certs 重新生成。
参考:
Cluster Networking | Kubernetes
Installing Addons | Kubernetes
Install Calico networking and network policy for on-premises deployments (tigera.io)
使用 Kops 安装 Kubernetes | Kubernetes
使用 Kubespray 安装 Kubernetes | Kubernetes
利用 kubeadm 创建高可用集群 | Kubernetes
3. 可视化界面 3.1 部署容器 1 2 3 4 5 6 7 8 wget -O dashboard.yaml https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml docker save -o kubernetesui-dashboard-v2.2.0.tar kubernetesui/dashboard:v2.2.0 docker save -o kubernetesui-metrics-scraper-v1.0.6.tar kubernetesui/metrics-scraper:v1.0.6 kubectl label node kubemaster dashboard-allowed=true
可以修改配置文件dashboard.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 kind: Service apiVersion: v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard spec: type: NodePort ports: - port: 443 targetPort: 8443 nodePort: 30000 selector: k8s-app: kubernetes-dashboard kind: Deployment apiVersion: apps/v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard spec: replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: k8s-app: kubernetes-dashboard template: metadata: labels: k8s-app: kubernetes-dashboard spec: nodeSelector: "kubernetes.io/hostname": "kubemaster" "dashboard-allowed": "true"
执行以下命令将Kubernetes Dashboard部署到集群中
1 2 3 4 5 6 7 8 9 10 11 12 13 kubectl apply -f dashboard.yaml kubectl create serviceaccount dashboard-admin -n kube-system kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}' ) kubectl get deployment --namespace=kubernetes-dashboard kubernetes-dashboard kubectl describe deployment --namespace=kubernetes-dashboard kubernetes-dashboard kubectl get service --namespace=kubernetes-dashboard kubernetes-dashboard kubectl --namespace=kubernetes-dashboard get pod -o wide | grep dashboard kubectl describe pod --namespace=kubernetes-dashboard kubectl get pod --all-namespaces
常用命令 k8s对象管理 创建配置文件中定义的对象:
1 kubectl create -f nginx.yaml
删除两个配置文件中定义的对象:
1 kubectl delete -f nginx.yaml -f redis.yaml
通过覆盖活动配置来更新配置文件中定义的对象:
1 kubectl replace -f nginx.yaml
命名空间 将同一任务的虚拟集群称为命名空间。
Kubernetes 会创建四个初始名字空间:
default
没有指明使用其它名字空间的对象所使用的默认名字空间
kube-system
Kubernetes 系统创建对象所使用的名字空间
kube-public
这个名字空间是自动创建的,所有用户(包括未经过身份验证的用户)都可以读取它。 这个名字空间主要用于集群使用,以防某些资源在整个集群中应该是可见和可读的。 这个名字空间的公共方面只是一种约定,而不是要求。
你可以使用以下命令列出集群中现存的名字空间:
为当前请求设置名字空间,请使用 --namespace
参数。
1 2 kubectl run nginx --image=nginx --namespace=<名字空间名称> kubectl get pods --namespace=<名字空间名称>
删除命名空间。下面的命令会删除你根据这个任务创建的所有 Pod:
1 kubectl delete namespace mem-example
节点 你可以使用 kubectl
来查看节点状态和其他细节信息:
1 kubectl describe node <节点名称>
Pod 创建 Pod:
1 kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit-3.yaml --namespace=mem-example
查看 Pod 状态:
1 kubectl get pod memory-demo-3 --namespace=mem-example
查看关于 Pod 的详细信息,包括事件:
1 kubectl describe pod memory-demo-3 --namespace=mem-example
删除 Pod:
1 kubectl delete pod memory-demo-3 --namespace=mem-example
K8S配置文件编写 基础服务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 apiVersion: v1 kind: Pod metadata: name: django-pod labels: k8s-app: django version: v1 kubernetes.io/cluster-service: "true" annotations: - name: String spec: restartPolicy: Always nodeSelector: containers: - name: django-pod image: django:v1.1 imagePullPolicy: Never command: ['sh' ] args: ["$(str)" ] env: - name: str value: "/etc/run.sh" resources: requests: cpu: 0.1 memory: 32Mi limits: cpu: 0.5 memory: 32Mi ports: - containerPort: 8080 name: uwsgi protocol: TCP livenessProbe: httpGet: path: / port: 8080 scheme: HTTP initialDelaySeconds: 180 timeoutSeconds: 5 periodSeconds: 15 lifecycle: postStart: exec: command: - 'sh' - 'yum upgrade -y' preStop: exec: command: ['service httpd stop' ] volumeMounts: - name: volume mountPath: /data readOnly: True volumes: - name: volume hostPath: path: /opt
kind的集中类型:
Pod:
Deployment : 主要用于部署pod,支持滚动升级。(Pod与Deployment类似,推荐使用Deployment)
Service:服务定义,主要用于暴露pods容器中的服务。
ConfigMap:主要用于容器配置管理。
Ingress:http路由规则定义,主要用于将service暴露到外网中。
CronJob :负责定时任务,在指定的时间周期运行指定的任务。
Job:用于批量处理短暂的一次性任务,并保证指定数量的Pod成功结束。
Service服务
Kubernetes Service 从逻辑上代表了一组 Pod,具体是哪些 Pod 则是由 label 来挑选。
Service 有自己 IP,而且这个 IP 是不变的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 apiVersion: v1 kind: Service metadata: name: namespace: spec: selector: app: nginx type: clusterIP: sessionAffinity: ports: - port: 8080 protocol: TCP targetPort : nodePort:
ClusterIP:默认类型,处于该模式下K8S会自动为service分配地址,其只能在集群内部访问。
NodePort:将Service通过指定的Node上的端口暴露给外部,通过此方法,就可以在集群外部访问服务。
LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境的支持。
ExternalName:把集群外部的服务引入集群内部,直接使用。
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 apiVersion: /v1 kind: Deployment metadata: name: httpd spec: selector: matchLabels: run: httpd replicas: 3 template: metadata: labels: run: httpd spec: containers: - name: httpd image: httpd ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: httpd-svc spec: selector: run: httpd ports: - protocol: TCP port: 8080 targetPort: 80
参考:官方文档
service详解