Install k8s based on minikube (best practice, one step)

Install k8s based on minikube (suitable for local environment)

  1. update system

    sudo yum update -y
    
  2. Install Docker and set it to start automatically at boot

     sudo yum install -y docker
     sudo systemctl start docker
     sudo systemctl enable docker
    
  3. install kubectl

    kubectl is a command-line management tool for Kubernetes

     curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux /amd64/kubectl"
     chmod +x kubectl
     sudo mv kubectl /usr/local/bin/
    
  4. Install Minikube

    It is not recommended to install under the root user

    First create a user and add it to the docker user group

    useradd -m minikubeuser
    usermod -aG docker minikubeuser
    

    set password

    sudo passwd minikubeuser

    switch to new user

    su minikubeuser

    curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
    chmod +x minikube
    sudo mv minikube /usr/local/bin/
    
  5. Start the cluster environment

    minikube start --driver=docker
    

    or

    minikube start --driver=docker --image-mirror-country=CN
    

Install helm (optional)

Note: It is best not to install based on the binary version, there will be many problems

Method 1: Download, compile and install the source code (go environment is required)

git clone https://github.com/helm/helm.git
cd helm
make
sudo cp ./bin/helm /usr/local/bin/
helm version

If there is no go environment

Download GO (helm depends on go at least V1.2 version)

curl -O https://golang.org/dl/go1.20.linux-amd64.tar.gz

After the download is complete, extract the tar.gz file to the /usr/local directory

sudo tar -C /usr/local -xzf go1.20.linux-amd64.tar.gz

Add the bin directory of the Go language to the PATH environment variable, and add it at the end of /etc/profile
export PATH=$PATH:/usr/local/go/bin

Save and exit, then execute
source /etc/profile
Change to a proxy address that can be accessed in China: https://goproxy.cn,
go env -w GOPROXY=https://goproxy.cn

Method 2: Directly download the compressed package and decompress it
https://github.com/kubernetes/helm/releases

tar -xvzf $HELM.tar.gz
mv linux-amd64/helm /usr/local/bin/helm

Install kubernetes-dashboard

Method 1: Install based on helm

helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
helm repo update
kubectl create namespace kubernetes-dashboard
helm install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --namespace kubernetes-dashboard

Method 2: Install based on yaml file

For the configuration scenarios that need to be adjusted, such as custom certificates, manually set nodeport

Download the file deploy.yaml

https://github.com/alan-et/k8s-components/blob/main/kubernetes-dashboard/deploy.yaml

Prepare certificate

Create k8s secret
kubectl create secret tls custom naming --key certificate key path/certificate name.key --cert certificate key path/certificate name.pem or crt -n kubernetes-dashboard
View secret
kubectl describe secret xxxxxx-secret

output sample

Name: xxxxxx-secret
Namespace: default
Labels: <none>
Annotations: <none>

Type: kubernetes.io/tls

Data
====
tls.crt: 3805 bytes
tls.key: 1675 bytes

Found in deploy.yaml
 containers:
        - name: kubernetes-dashboard
          image: kubernetesui/dashboard:v2.3.1
          imagePullPolicy: Always
          ports:
            - containerPort: 8443
              protocol: TCP
          args:
            --auto-generate-certificates
            - --namespace=kubernetes-dashboard
            - --tls-key-file=tls.key
            - --tls-cert-file=tls.crt
            - --bind-address=0.0.0.0
            - --token-ttl=3600
            # Uncomment the following line to manually specify Kubernetes API server Host
            # If not specified, Dashboard will attempt to auto discover the API server and connect
            # to it. Uncomment only if the default does not work.
            # - --apiserver-host=http://my-address:port
          volumeMounts:
            - name: kubernetes-dashboard-certs

Change the certificate to the actual name (the one specified by the –key parameter does not need to be modified, and the one specified by the –from parameter can be viewed by viewing the output of the secret command above)

 - --tls-key-file=tls.key
            - --tls-cert-file=tls.crt
Then find it in deploy.yaml
 volumes:
        - name: kubernetes-dashboard-certs
          secret:
            secretName: xxxxxx-secret
        - name: tmp-volume
          emptyDir: {}
      serviceAccountName: kubernetes-dashboard

Modify secretName to your own custom certificate name

Specify NodePort for access (no need to comment)
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: 30001
  selector:
    k8s-app: kubernetes-dashboard

Deployment and installation

kubectl apply -f deploy.yaml

Visit

Create an administrator account
  1. Execute vim admin-user.yaml

  2. Enter the following code

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: admin-user
      namespace: kubernetes-dashboard
    
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: admin-user
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
      - kind: ServiceAccount
        name: admin-user
        namespace: kubernetes-dashboard
    
    

    save and exit

  3. kubectl apply -f apply admin-user.yaml

Get token
  1. View the version installed by kubectl

    kubectl version --short

    If it is v1.23 and below, execute this command to get it

    kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')

    output sample

    Name: admin-user-token-xpm5v
    Namespace: kubernetes-dashboard
    Labels: <none>
    Annotations: kubernetes.io/service-account.name=admin-user
                  kubernetes.io/service-account.uid=0610610c-84e7-11e8-98de-00163e02d9ff
    
    Type: kubernetes.io/service-account-token
    
    Data
    ====
    ca.crt: 1090 bytes
    namespace: 11 bytes
    token: eyGciOiJSUzI1NiIsImtpZCI6Im5HeEp6UEphRmc3czV3dVBvc01PNllHLXNhckEzb094bmZGd1d6cTBUNncifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3 ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg0ODEzNzk4LCJpYXQiOjE2ODQ4MTAxOTgsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2Fs Iiwia3ViZXJuZXRlLTg5ZWItNjBmMjhjMTgxOWI4In19LCJuYmYiOjE2ODQ4MTAxOTgsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDphZG1pbi11c2V yIn0.O7PURPuf53UY69T73DTijk60QbGG58uHec4htxIVYMdazQveN9rEUj8HXGAsZGD3ZzmdD2FUU8kG1JAKB_9prD2SFlKrF9nQ_-xBDxaYrJKn3CZaeisX3Ly9NKayOvINjoxxzoLd OyX47uTzVg8eaQt5mDTbUyZaTjuRoQu_yXAh65RU45fA55yuN5BerfVJ1qADM-oAWcJ1afU4W1aRZxaT26O5dMzILKI2xh3zSNmmsndkfRfu6FyybpVF56x3aXjlRDUBao8HlYhU JKIEvC-HAusC9_QKyHOh1kdTb5RgA3aixyB7SXJopFfYKUcOy5xp6Nwh5IEUHHjb1MrCOg
    

    If it is v1.24 and above the above methods cannot be obtained, and the secret will not be generated when creating an account; it needs to be obtained through the kubectl api

    Enable kubectl port proxy

    kubectl proxy

    Execute commands to access api services

    curl -X POST -H "Content-Type:application/json" 'http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/serviceaccounts/admin-user/token' -d '{} '

    output sample

    {
      "kind": "TokenRequest",
      "apiVersion": "authentication.k8s.io/v1",
      "metadata": {
        "name": "admin-user",
        "namespace": "kubernetes-dashboard",
        "creationTimestamp": "2023-05-23T02:49:58Z",
        "managedFields": [
          {
            "manager": "curl",
            "operation": "Update",
            "apiVersion": "authentication.k8s.io/v1",
            "time": "2023-05-23T02:49:58Z",
            "fieldsType": "FieldsV1",
            "fieldsV1": {
              "f:spec": {
                "f:expirationSeconds": {}
              }
            },
            "subresource": "token"
          }
        ]
      },
      "spec": {
        "audiences": [
          "https://kubernetes.default.svc.cluster.local"
        ],
        "expirationSeconds": 3600,
        "boundObjectRef": null
      },
      "status": {
        "token": "eyJGciOiJSUzI1NiIsImtpZCI6Im5HeEp6UEphRmc3czV3dVBvc01PNllHLXNhckEzb094bmZGd1d6cTBUNncifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bH Quc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg0ODEzNzk4LCJpYXQiOjE2ODQ4MTAxOTgsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY 2FsIiwia3ViZXJuZXRljBmMjhjMTgxOWI4In19LCJuYmYiOjE2ODQ4MTAxOTgsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDphZG1pbi11c2VyIn0. O7PURPuf53UY69T73DTijk60QbGG58uHec4htxIVYMdazQveN9rEUj8HXGAsZGD3ZzmdD2FUU8kG1JAKB_9prD2SFlKrF9nQ_-xBDxaYrJKn3CZaeisX3Ly9NKayOvINjoxxzoLdOyX4 7uTzVg8eaQt5mDTbUyZaTjuRoQu_yXAh65RU45fA55yuN5BerfVJ1qADM-oAWcJ1afU4W1aRZxaT26O5dMzILKI2xh3zSNmmsndkfRfu6FyybpVF56x3aXjlRDUBao8HhUJKIEvC- HAusC9_QKyHOh1kdTb5RgA3aixyB7SXJopFfYKUcOy5xp6Nwh5IEUHHjb1MrCOg",
        "expirationTimestamp": "2023-05-23T03:49:58Z"
      }
    }
    
kubectl proxy access method

Only http access

nohup kubectl proxy &

If you want external ip to be accessible, execute the following command

nohup kubectl proxy --address='0.0.0.0' --accept-hosts='^*$' &

Then the browser opens

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ console, select token to log in

port-forward access method

kubectl -n kubernetes-dashboard port-forward --address 0.0.0.0 service/kubernetes-dashboard 8002:443

Then the browser opens (can be accessed with the previously configured domain name)

https://localhost:8002/ console, select token to log in

nodeport mode access

Prerequisite: The nodeport mode configured when publishing the service, and the port is set; mentioned in the above steps

Then the browser opens

https://localhost:31001/ console, select token to log in

Access via ingress

Prerequisite: Ingress Controller has been installed

  1. vim dashboard-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /
    # The default is true, when TLS is enabled, http requests will be 308 redirected to https
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
  name: kubernetes-dashboard-ingress
  namespace: kubernetes-dashboard
spec:
  tls:
    - secretName: xxxxxx-secret #Set to the name of the certificate created in the previous steps
      hosts:
        - xxxxxx.com #The domain name bound to the certificate
  rules:
    - host: xxxxxx.com #The domain name bound to the certificate
      http:
        paths:
          -pathType: Prefix
            path: /
            backend:
              service:
                name: kubernetes-dashboard
                port:
                  number: 443
  1. kubectl apply -f dashboard-ingress.yaml

  2. Execute kubectl get ingress -n kubernetes-dashboard to check whether the Host is the set domain name and whether the address has an external IP assigned

    Correct output example

    NAME CLASS HOSTS ADDRESS PORTS AGE
    kubernetes-dashboard-ingress <none> k8s.alanpoi.com 10.108.249.35 80, 443 15h
    

    If it is as follows

    NAME CLASS HOSTS ADDRESS PORTS AGE
    kubernetes-dashboard-ingress <none> k8s.alanpoi.com 80, 443 15h
    

    It is a local cluster created by minikube, and the external ip cannot be assigned by default

    Tunnel can be opened to resolve

    minikube tunnel
    

    Then re-execute ingress to solve

    `kubectl apply -f dashboard-ingress.yaml`
    
  3. (The cluster created by minikube can only be accessed locally, and the domain name resolution is set in the hosts file) Direct domain name access is fine
    [External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-XGXvFbGA-1684820228593)(null)]

Deploy Ingress Controller

Please do not trust the steps of other people on the Internet for installation, basically your installation is not successful

  1. (I have uploaded it to my git) Download the deployment file https://github.com/alan-et/k8s-components/blob/main/Ingress-controller/deploy.yaml

  2. deploy

    kubectl apply -f deploy.yaml
    
  3. View the status (the job of the two webhooks is a one-time task, so it is completed, and the status of the ingress-nginx-controller must be Running)

    Execute kubectl get pods -n ingress-nginx

    output sample

    NAME READY STATUS RESTARTS AGE
    ingress-nginx-admission-create-mlqng 0/1 Completed 0 18h
    ingress-nginx-admission-patch-fvj6h 0/1 Completed 0 18h
    ingress-nginx-controller-57948bb7bd-x8d9v 1/1 Running 0 18h
    

    Execute kubectl get services -n ingress-nginx

    output sample

    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    ingress-nginx-controller LoadBalancer 10.108.249.35 10.108.249.35 80:31741/TCP,443:31871/TCP 18h
    ingress-nginx-controller-admission ClusterIP 10.107.34.40 <none> 443/TCP 18h
    

    If EXTERNAL-IP is always pending, it is a cluster created locally by minikube, and the external IP cannot be allocated. Create a tunnel through minikube tunnel to solve the problem

Common mistakes

Exiting due to PROVIDER_DOCKER_VERSION_EXIT_1: “docker version –format -:” exit status 1: template: :1:44: executing “” at <.Server.Platform.Nam…>: can’t evaluate field Platform in

type *types. Version

  1. remove old docker
sudo yum remove docker \
                docker-client \
                docker-client-latest \
                docker-common \
                docker-latest\
                docker-latest-logrotate \
                docker-logrotate \
                docker-selinux\
                docker-engine-selinux\
                docker-engine
  1. Install dependencies

    sudo yum install -y yum-utils\
      device-mapper-persistent-data \
      lvm2
    
  2. Set up the Docker repository:

    sudo yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
    
  3. Install the latest version of Docker CE:

    sudo yum install docker-ce docker-ce-cli containerd.io
    
  4. start docker

    sudo systemctl start docker
    

Execution phase certs/apiserver-kubelet-client: [certs] certificate apiserver-kubelet-client not signed by CA certificate ca: x509: certificate has expired or is not yet valid: current time 2023-05-18T03:26 appears. :25Z is after 2023-01-19T18:41:11Z

Cause: One of the Kubernetes cluster’s certificates (specifically, apiserver-kubelet-client) has expired, which prevents Kubernetes from functioning properly. Certificates are an important part of what Kubernetes uses to secure communications within a cluster.

For Minikube, delete the existing Minikube instance and recreate a new one, this will automatically generate new certificates

minikube delete

minikube start

can be solved

The connection to the server localhost:8080 was refused – did you specify the right host or port?

This problem generally occurs in the minikube cluster mode. When user A executes minikube start, and executes the kubectl command as root or other users, this error will be prompted.

The solution is to configure the kube of user A to cp to this user

cp ~/.kube/config /root/.kube/config

Originality is not easy, please indicate the original address for reprinting