在 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这个用户了