使用Golang为kubernetes创建用户

Kubernetes User Account 中我们使用OPENSSL创建了CSR和私钥,并且为kubernetes创建了一个新用户,这里提供一个相对简单的方法,使用golang和shell

创建 main.go

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/pem"
	"os"
)

func main() {
	name := os.Args[1]
	user := os.Args[2]

	key, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		panic(err)
	}

	keyDer := x509.MarshalPKCS1PrivateKey(key)
	keyBlock := pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: keyDer,
	}
	keyFile, err := os.Create(name + "-key.pem")
	if err != nil {
		panic(err)
	}

	pem.Encode(keyFile, &keyBlock)
	keyFile.Close()
	commonName := user

	emailAddress := "hello@lizhe.name"

	org := "lizhe"
	orgUnit := "lz"
	city := "DL"
	state := "LN"
	country := "CN"

	subject := pkix.Name{
		CommonName:         commonName,
		Country:            []string{country},
		Locality:           []string{city},
		Organization:       []string{org},
		OrganizationalUnit: []string{orgUnit},
		Province:           []string{state},
	}

	asn1, err := asn1.Marshal(subject.ToRDNSequence())
	if err != nil {
		panic(err)
	}

	csr := x509.CertificateRequest{
		RawSubject:         asn1,
		EmailAddresses:     []string{emailAddress},
		SignatureAlgorithm: x509.SHA256WithRSA,
	}

	bytes, err := x509.CreateCertificateRequest(rand.Reader, &csr, key)
	if err != nil {
		panic(err)
	}

	csrFile, err := os.Create(name + ".csr")
	if err != nil {
		panic(err)
	}

	pem.Encode(csrFile, &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: bytes})
	csrFile.Close()
}

调用脚本,此脚本需要两个参数 client 和 lizhe

client 会得到一个 client.csr 而 lizhe 将会是这个 csr的 subject

go run main.go client lizhe

创建一个 main.sh 文件,填入以下内容

#!/bin/sh

csr_name="my-client-csr"
name="${1}"
csr="${2}"

cat <<EOF | kubectl create -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: ${csr_name}
spec:
  groups:
  - system:authenticated
  request: $(cat ${csr} | base64 | tr -d '\n')
  usages:
  - digital signature
  - key encipherment
  - client auth
EOF

echo
echo "Approving signing request."
kubectl certificate approve ${csr_name}

echo 
echo "Downloading certificate."
kubectl get csr ${csr_name} -o jsonpath='{.status.certificate}' \
        | base64 --decode > $(basename ${csr} .csr).crt

echo
echo "Cleaning up"
kubectl delete csr ${csr_name}

echo
echo "Add the following to the 'users' list in your kubeconfig file:"
echo "- name: ${name}"
echo "  user:"
echo "    client-certificate: ${PWD}/$(basename ${csr} .csr).crt"
echo "    client-key: ${PWD}/$(basename ${csr} .csr)-key.pem"

echo
echo "Next you may want to add a role-binding for this user."

调用这个shell,注意因为没有太多的异常处理,请确认可以成功运行

./main.sh lizhe client.csr

正常的配置文件是这样的

我们需要使用以下内容,所以我copy一份上面的config文件,并且进行一些改动

- name: lizhe
  user:
    client-certificate: /home/lizhe/works/createuser/client.crt
    client-key: /home/lizhe/works/createuser/client-key.pem

拷贝文件到工作目录

sudo cp /etc/rancher/k3s/k3s.yaml /home/lizhe/works/createuser/k3s_lizhe.yaml

修改 k3s_lizhe.yaml

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkekNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdGMyVnkKZG1WeUxXTmhRREUyTVRnd01UazNNREF3SGhjTk1qRXdOREV3TURFMU5UQXdXaGNOTXpFd05EQTRNREUxTlRBdwpXakFqTVNFd0h3WURWUVFEREJock0zTXRjMlZ5ZG1WeUxXTmhRREUyTVRnd01UazNNREF3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFSL1NnS2NVeGM4T01ZeHhMcDZWeDVyak9JSUJnNUpGS3lBV3d5WXRpWG8KM3NxdHVMQXVnUldXVVpwQklKbXRsQ1htcjg0ZFR4ejJmbXpuV3ZSa3ZKOC9vMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVTZsemFvSjdVKy9qUnNHYVZqOWxqCjRiam1aMGt3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUlnTUxQcEF2ejFuTzFKTWR6QnhKMmY3UnUzWTlVd0VkYkkKbXphOXBLZTlOdlFDSVFEQWh1WFp4SlJuMGxwVDQvdVFUUEtIck9DYjZNMExncXNDYXgyMjVIVFNOdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    server: https://127.0.0.1:6443
  name: default
contexts:
- context:
    cluster: default
    user: default
  name: default
current-context: default
kind: Config
preferences: {}
users:
- name: lizhe
  user:
    client-certificate: /home/lizhe/works/createuser/client.crt
    client-key: /home/lizhe/works/createuser/client-key.pem

我们来使用curl检查一下生成的 x509 文件是不是能正常工作

curl --key ./client-key.pem --cert ./client.crt --insecure https://localhost:6443/api

下面我们去创建 rolebinding

cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  namespace: default
  name: podrole
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]
EOF
kubectl create rolebinding podrolebinding  -n default --clusterrole podrole --user lizhe

尝试使用lizhe这个用户来查询 default namespace 下的 pods

curl --cert ./client.crt --key ./client-key.pem --insecure -s https://localhost:6443/api/v1/namespaces/default/pods

什么都没有得到,我们创建一个pod再试

配置对应的 kubeconfig文件

sudo kubectl config --kubeconfig=./k3s.yaml set-credentials lizhe --client-certificate=/home/lizhe/works/createuser/client.crt --client-key=/home/lizhe/works/createuser/client-key.pem
sudo kubectl config --kubeconfig=./k3s.yaml set-context lizhe_context --cluster=default --namespace=default --user=lizhe
sudo kubectl config --kubeconfig=./k3s.yaml use-context lizhe_context

也可以直接创建一个新的 kubeconfig文件,这样这个文件就只包含 lizhe 这一个用户

kubectl config --kubeconfig=./k3s_lizhe.yaml set-credentials lizhe --client-certificate=/home/lizhe/works/createuser/client.crt --client-key=/home/lizhe/works/createuser/client-key.pem
kubectl config --kubeconfig=./k3s_lizhe.yaml set-context lizhe_context --cluster=default --namespace=default --user=lizhe

这样创建的文件没有cluster信息,需要手动拷贝

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkekNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdGMyVnkKZG1WeUxXTmhRREUyTVRnd01UazNNREF3SGhjTk1qRXdOREV3TURFMU5UQXdXaGNOTXpFd05EQTRNREUxTlRBdwpXakFqTVNFd0h3WURWUVFEREJock0zTXRjMlZ5ZG1WeUxXTmhRREUyTVRnd01UazNNREF3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFSL1NnS2NVeGM4T01ZeHhMcDZWeDVyak9JSUJnNUpGS3lBV3d5WXRpWG8KM3NxdHVMQXVnUldXVVpwQklKbXRsQ1htcjg0ZFR4ejJmbXpuV3ZSa3ZKOC9vMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVTZsemFvSjdVKy9qUnNHYVZqOWxqCjRiam1aMGt3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUlnTUxQcEF2ejFuTzFKTWR6QnhKMmY3UnUzWTlVd0VkYkkKbXphOXBLZTlOdlFDSVFEQWh1WFp4SlJuMGxwVDQvdVFUUEtIck9DYjZNMExncXNDYXgyMjVIVFNOdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    server: https://127.0.0.1:6443
  name: default
contexts:
- context:
    cluster: default
    namespace: default
    user: lizhe
  name: lizhe_context
current-context: ""
kind: Config
preferences: {}
users:
- name: lizhe
  user:
    client-certificate: client.crt
    client-key: client-key.pem

每次打开 shell,通过直接使用这个 KUBECONFIG,都能切换lizhe这个用户了

Send a Message