Kubernetes

K8S v1.16.1 - Ubuntu 18.04.2 LTS 安装指南

软硬件环境:

Processor:AMD® Ryzen 7 2700x eight-core processor × 16
Memory:32 GiB 
Storage:Samsung SSD 970 PRO 512GB / GPT Part

OS:Ubuntu 18.04.2 LTS 
OS type:64-bit

一.docker 容器的安装

1.【 卸载 】旧版本docker
sudo apt remove docker docker-engine docker.io
2.安装所需依赖工具
sudo apt install apt-transport-https ca-certificates  curl software-properties-common
3.安装 docker.com gpg key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -`
sudo apt-key fingerprint 0EBFCD88`
4.添加 docker.com 软件源
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
5.安装 docker
sudo apt install -y docker-ce=18.06.0~ce~3-0~ubuntu
6.设置启动 docker 服务
systemctl enable docker && systemctl start docker

二.k8s 安装

1.安装软件源 key
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
# key 因为网络安装失败,可以通过浏览器代理下载后使用  cat apt-key.gpg | apt-key add -
2.写入k8s软件源
# 使用国内电子科大源 
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main
EOF

# 官方源,梯子警告
# deb https://apt.kubernetes.io/ kubernetes-xenial main

apt-get update
3.安装 k8s 相关工具
sudo apt install -y docker kubelet=1.16.1-00 kubeadm=1.16.1-00 kubectl=1.16.1-00 kubernetes-cni

#忽略 apt update 更新
sudo apt-mark hold kubelet kubeadm kubectl kubernetes-cni
4.启动 kubelet服务
systemctl enable kubelet && systemctl start kubelet
tip.列出需要的镜像
kubeadm config images list
5.下载需要的镜像
kubeadm config images pull
5.1镜像下载失败 墙内办法 预先下载所需镜像 更改标签 以下为 k8s v1.16.1 版本所需镜像

docker pull trustxz/kube-apiserver:v1.16.1
docker pull trustxz/kube-controller-manager:v1.16.1
docker pull trustxz/kube-scheduler:v1.16.1
docker pull trustxz/kube-proxy:v1.16.1
docker pull fengzos/pause:3.1
docker pull trustxz/etcd:3.3.15-0
docker pull trustxz/coredns:1.6.2


docker tag trustxz/kube-apiserver:v1.16.1 k8s.gcr.io/kube-apiserver:v1.16.1
docker tag trustxz/kube-controller-manager:v1.16.1 k8s.gcr.io/kube-controller-manager:v1.16.1
docker tag trustxz/kube-scheduler:v1.16.1 k8s.gcr.io/kube-scheduler:v1.16.1
docker tag trustxz/kube-proxy:v1.16.1 k8s.gcr.io/kube-proxy:v1.16.1
docker tag fengzos/pause:3.1 k8s.gcr.io/pause:3.1
docker tag trustxz/etcd:3.3.15-0 k8s.gcr.io/etcd:3.3.15-0
docker tag trustxz/coredns:1.6.2 k8s.gcr.io/coredns:1.6.2

docker rmi trustxz/kube-apiserver:v1.16.1
docker rmi trustxz/kube-controller-manager:v1.16.1
docker rmi trustxz/kube-scheduler:v1.16.1
docker rmi trustxz/kube-proxy:v1.16.1
docker rmi fengzos/pause:3.1
docker rmi trustxz/etcd:3.3.15-0
docker rmi trustxz/coredns:1.6.2
tip.管理工具版本信息
kubeadm version
6.关闭交换内存, 所有node,master关闭swap,selinux
sudo swapoff -a
#修改/etc/fstab文件,注销掉swap相关的行也行
7.1 初始化 k8s
sudo kubeadm init
7.2 初始化 k8s
sudo kubeadm init --kubernetes-version=1.16.1 --apiserver-advertise-address=192.168.0.202 --pod-network-cidr=10.244.0.0/16 --token-ttl=0 --ignore-preflight-errors=Swap
--kubernetes-version=v1.14.1 指定K8S版本 与部分所需镜像版本号一致

--apiserver-advertise-address 绑定IP 指明用 Master 的哪个 interface 与 Cluster 的其他节点通信。如果 Master 有多个 interface,建议明确指定,如果不指定,kubeadm 会自动选择有默认网关的 interface

--pod-network-cidr=10.244.0.0/16 指定 Pod 网络的范围,Kubernetes 支持多种网络方案,不同网络方案对 --pod-network-cidr 有自己的要求

tip.kubeadm init 报错停止,你可能需要执行以下命令重置然后再初始化
sudo kubeadm reset 
8.初始化成功后输出以下关键信息
# 复制执行以下命令 设定kube配置
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

以下为加入集群包含token 命令 ,妥善保存
每个人生成的都不一样哦
eg:

kubeadm join 192.168.0.202:6443 --token utefqi.mu2ldkfly1rm5w09 \
    --discovery-token-ca-cert-hash sha256:2535c92bfe4f7647cb873f91bf2f54c2d39c10ee693c55abbd353cf0477bd3bb 

token 查询

kubeadm token list

生成永不过期的token

kubeadm token create --ttl 0 --print-join-command
8.1集群节点添加
使用 6步骤完成的环境虚拟机
使用加入集群的命令
9.设置网络模式
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# kubectl apply -f kube-flannel.yml
tip.查看节点列表信息,等待Ready
kubectl get nodes 
tip.查看 pod 列表
kubectl get pods --all-namespaces
# more info
kubectl get pods -A  -o wide
tip.查看 pod 详细状态信息
kubectl describe pod <<name>> --namespace kube-system

三.可视化管理面板

1.下载部署文件
# 首先下载官网提供的dashboard配置文件
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml
2.修改yaml,添加NodePort.
kind: Service
apiVersion: v1
metadata:
labels:
    k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
# 添加Service的type为NodePort
type: NodePort
ports:
    - port: 443
    targetPort: 8443
    # 添加映射到虚拟机的端口,k8s只支持30000以上的端口
    nodePort: 30001
selector:
    k8s-app: kubernetes-dashboard
3.部署 dashboard
kubectl create -f dashboard.yaml
# 查看
kubectl get service -n kubernetes-dashboard  -o wide
tip.登陆地址
https://<node-ip>:<node-port> 
4.1快速获取 dashboard 登陆令牌
kubectl -n kube-system describe $(kubectl -n kube-system get secret -n kube-system -o name | grep namespace) | grep token
4.2手动查询
# 输入下面命令查询kube-system命名空间下的所有secret
kubectl get secret -n kube-system
# 然后获取token。只要是type为service-account-token的secret的token都可以使用。
# 比如我们获取replicaset-controller-token-wsv4v的touken
kubectl -n kube-system describe replicaset-controller-token-wsv4v
tip.认证的两种方式ps -ef
# 通过我们刚刚获取的token直接认证
# 通过Kubeconfig文件认证
# 只需要在kubeadm生成的admin.conf文件末尾加上刚刚获取的token就好了。
name: kubernetes-admin
user:
    client-certificate-data: xxxxxxxx
    client-key-data: xxxxxx
    token: "在这里加上token"

三.K8S集群搭建完了

你需要出去走一趟,去按摩或者活动一下颈椎/腰椎

四.应用部署测试

dotnet web deploy

create project

dotnet new webApp -o HelloWebApp --no-https
cd HelloWebApp
dotnet run

modify index.cshtml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Net;
using System.Net.Sockets;

namespace HelloWebApp.Pages
{
    public class IndexModel : PageModel
    {
        public void OnGet(){
            string HostName = Dns.GetHostName();
            string HostIP = Dns.GetHostEntry(HostName).AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork).ToString();

            this.ViewData["HostName"] = HostName;
            this.ViewData["HostIP"] = HostIP;
        }
    }
}

modify index.cshtml

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <h2> 
        @ViewData["HostName"],
        @ViewData["HostIP"]
    </h2>
</div>

create Dockerfile

FROM microsoft/dotnet:2.2-aspnetcore-runtime
MAINTAINER demo                  

WORKDIR /app 

COPY ./bin/Release/netcoreapp2.2/publish/ app/
EXPOSE 80
ENTRYPOINT ["dotnet", "app/HelloWebApp.dll"]

build docker image

docker build -t dotnet/hellowebapp . 

test docker image

docker run -it --rm --name=demo-hellowebapp -p 8080:80 dotnet/hellowebapp 
#vist http://localhost:8080
#exit

deploy to k8s

# navbar > click create > create application
# app name          =>  helloweb
# container image   =>  dotnet/hellowebapp
# container count   =>  2
# service           =>  inner
# port              =>  33610   80  TCP
# create
# vist http://cluserip:33610
# publish service to public
# edit service config yaml,set type as NodePort 


五.你可能需要跑路或重装系统

sudo rm -rf /* &

其他问题

kubelet 实时运行日志查看

journalctl -f -u kubelet 

1 node(s) had taints that the pod didn't tolerate.
有时候一个pod创建之后一直是pending,没有日志,也没有pull镜像,describe的时候发现里面有一句话: 1 node(s) had taints that the pod didn't tolerate.
直译意思是节点有了污点无法容忍,执行 kubectl get no -o yaml | grep taint -A 5 之后发现该节点是不可调度的。这是因为kubernetes出于安全考虑默认情况下无法在master节点上部署pod,于是用下面方法解决:

kubectl taint nodes --all node-role.kubernetes.io/master-

POD部署不使用本地镜像导致部署失败
tip:k8s默认会从远端拉取镜像,其配置参数imagePullPolicy为Always。所以,如果yaml文件中没有定义那就是使用默认的,因此我们可以通过将该参数显示设置为Never或者IfNotPresent,k8s就会从本地拉取镜像了。
配置文件修改

"containers": [
    {
    "name": "yoghurt-cls",
    "image": "yoghurt:1.0",
    "resources": {},
    "terminationMessagePath": "/dev/termination-log",
    "terminationMessagePolicy": "File",
    "imagePullPolicy": "Never",
    "securityContext": {
        "privileged": false,
        "procMount": "Default"
    }
    }
]
This is just a placeholder img.