New to Guard? Please start here.
Installation Guide
Guard binary works as a cli and server. In cli mode, you can use guard
to generate various configuration to easily deploy Guard server. Guard server uses TLS client auth to secure the communication channel between Kubernetes api server and Guard server. You can run Guard server external to a Kubernetes cluster. This document shows you how to self-host
Guard server in a Kubernetes cluster. To that end, we run Guard server using a predefined Service ClusterIP 10.96.10.96
and port 443
. This ClusterIP is chosen so that it falls in the default –service-cidr range for Kubeadm. If the service CIDR range for your cluster is different, please pick an appropriate ClusterIP.
If you want to set up guard via Kops visit here to see differences in setup.
If you want to set up guard via Kubespray visit here.
Install Guard as CLI
Download pre-built binaries from appscode/guard Github releases and put the binary to some directory in your PATH
. To install on Linux 64-bit and MacOS 64-bit you can run the following commands:
# Linux amd 64-bit:
wget -O guard https://github.com/kubeguard/guard/releases/download/v0.16.3/guard-linux-amd64 \
&& chmod +x guard \
&& sudo mv guard /usr/local/bin/
# Mac 64-bit
wget -O guard https://github.com/kubeguard/guard/releases/download/v0.16.3/guard-darwin-amd64 \
&& chmod +x guard \
&& sudo mv guard /usr/local/bin/
If you prefer to install Guard cli from source code, you will need to set up a GO development environment following these instructions. Then, install guard
CLI using go get
from source code.
go get go.kubeguard.dev/guard
Please note that this will install Guard cli from master branch which might include breaking and/or undocumented changes.
Initialize PKI
Guard uses TLS client certs to secure the communication between guard server and Kubernetes api server. Guard also uses the CommonName
and Organization
in client certificate to identify which auth provider to use. Follow the steps below to initialize a self-signed ca, generate a pair of server and client certificates.
# initialize self signed ca
$ guard init ca
Wrote ca certificates in $HOME/.guard/pki
# generate server certificate pair
$ guard init server --ips=10.96.10.96
Wrote server certificates in $HOME/.guard/pki
# generate client certificate pair for Github organization `appscode`
$ guard init client appscode -o github
Wrote client certificates in $HOME/.guard/pki
$ guard init client appscode.com -o google
Wrote client certificates in $HOME/.guard/pki
$ guard init client qacode -o appscode
Wrote client certificates in $HOME/.guard/pki
# generate client certificate pair for Gitlab
$ guard init client -o gitlab
Wrote client certificates in $HOME/.guard/pki
# for azure, commonName is optional
$ guard init client -o azure
Wrote client certificates in $HOME/.guard/pki
# generate client certificate pair for LDAP
$ guard init client appscode -o ldap
Wrote client certificates in $HOME/.guard/pki
$ ls -l $HOME/.guard/pki
total 32
-rwxr-xr-- 1 tamal tamal 1054 Aug 28 07:42 qacode@appscode.crt
-rw------- 1 tamal tamal 1679 Aug 28 07:42 qacode@appscode.key
-rwxr-xr-- 1 tamal tamal 1054 Aug 28 07:42 appscode.com@google.crt
-rw------- 1 tamal tamal 1679 Aug 28 07:42 appscode.com@google.key
-rwxr-xr-- 1 tamal tamal 1050 Aug 28 07:12 appscode@github.crt
-rw------- 1 tamal tamal 1675 Aug 28 07:12 appscode@github.key
-rwxr-xr-- 1 tamal tamal 1050 Aug 28 07:12 gitlab@gitlab.crt
-rw------- 1 tamal tamal 1675 Aug 28 07:12 gitlab@gitlab.key
-rwxr-xr-- 1 tamal tamal 1050 Aug 28 07:12 azure@azure.crt
-rw------- 1 tamal tamal 1675 Aug 28 07:12 azure@azure.key
-rwxr-xr-- 1 tamal tamal 1050 Aug 28 07:12 ldap@ldap.crt
-rw------- 1 tamal tamal 1675 Aug 28 07:12 ldap@ldap.key
-rwxr-xr-- 1 tamal tamal 1005 Aug 28 07:12 ca.crt
-rw------- 1 tamal tamal 1675 Aug 28 07:12 ca.key
-rwxr-xr-- 1 tamal tamal 1046 Aug 28 07:12 server.crt
-rw------- 1 tamal tamal 1675 Aug 28 07:12 server.key
As you can see, Guard stores the generated certificates in .guard
subdirectory of home directory of user executing these commands. You can change the location by either setting GUARD_DATA_DIR
environment variable or by passing the path to a different directory using --pki-dir
flag. For example:
$ export GUARD_DATA_DIR=/tmp/guard
$ guard init ca
I0621 14:09:30.582429 17769 types.go:16] Using data dir /tmp/guard found in GUARD_DATA_DIR env variable
I0621 14:09:30.606327 17769 logs.go:19] FLAG: --alsologtostderr="false"
I0621 14:09:30.606350 17769 logs.go:19] FLAG: --analytics="true"
I0621 14:09:30.606356 17769 logs.go:19] FLAG: --help="false"
I0621 14:09:30.606363 17769 logs.go:19] FLAG: --log_backtrace_at=":0"
I0621 14:09:30.606369 17769 logs.go:19] FLAG: --log_dir=""
I0621 14:09:30.606377 17769 logs.go:19] FLAG: --logtostderr="false"
I0621 14:09:30.606385 17769 logs.go:19] FLAG: --pki-dir="/tmp/guard"
I0621 14:09:30.606392 17769 logs.go:19] FLAG: --stderrthreshold="0"
I0621 14:09:30.606407 17769 logs.go:19] FLAG: --v="0"
I0621 14:09:30.606415 17769 logs.go:19] FLAG: --vmodule=""
Wrote ca certificates in /tmp/guard/pki
Guard can use supported authenticator to authenticate users for a Kubernetes cluster. A Kubernetes cluster can use one of these organization to authenticate users. But you can configure a single Guard server to perform authentication for multiple clusters, where each cluster uses a different auth provider.
Deploy Guard server
Now deploy Guard server so that your Kubernetes api server can access it. Use the command below to generate YAMLs for your particular setup. Then use kubectl apply -f
to install Guard server.
# generate Kubernetes YAMLs for deploying guard server
$ guard get installer \
--auth-providers=<auth_providers_name> \
> installer.yaml
$ kubectl apply -f installer.yaml
By default, the installer.yaml will deploy Guard server on master instances. If your cluster is provisioned by Kubespray, change
the node selector in installer.yaml to "node-role.kubernetes.io/master": "true"
due to kubernetes-incubator/kubespray#2108.
Configure Kubernetes API Server
To use webhook authentication, you need to set --authentication-token-webhook-config-file
flag of your Kubernetes api server to a kubeconfig file describing how to access the Guard webhook service. You can use the following command to generate a sample kubeconfig
file.
# print auth token webhook config file. Change the server address to your guard server address.
$ guard get webhook-config appscode -o github --addr=10.96.10.96:443
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN1RENDQWFDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFOTVFzd0NRWURWUVFERXdKallUQWUKRncweE56QTRNamt4TkRJek16aGFGdzB5TnpBNE1qY3hOREl6TXpoYU1BMHhDekFKQmdOVkJBTVRBbU5oTUlJQgpJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBclF3aGRweVE3KzBaVzBDMFpEblI1VS85CjdaVmgyODRtYjdYSmVVaHM0QmI0UHE2Mk1remZpc2lzdXZQZmJzK2Y3dW1oeXhyOGVLak10RlJyc3ZQakhUeDUKTG5rM0hvdE1wNGtCbGJjOTl4dExqN0VwazlXSVNNUW42OEo4K0NCU2N3aFZ1Zlg4NndrNFo3cTZuYXdEUTlRbApyMG1qNWZCVFZ1K3gzYWhXa1F4Rzczd3QxRUdZRkRFMFR1UlV6OXpDclk2bFZzdnZJcXlHL04wWHlUVHNMeFQxCmtOOHRnU3cwVWJOakhGMFVmejhpN05wK1RBZkRFT1pUMWx3SllkSlJ2RjMvYTBRRmdHWTg3K1BJQmhvQklZd1YKU2RXZkRjVWVjcUVuWXkxMEF5MDhZeEZxUTlSNTM4djlpUUxYenZqSVdsYWdDSXBCejB2UDB3dFp4a0lGaFFJRApBUUFCb3lNd0lUQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTkJna3Foa2lHCjl3MEJBUXNGQUFPQ0FRRUFsanRtbzJwMklvVmhKTXZ4MEFNM08xUkxHMGVRbHY5QTNQWm14dTlWemJkaWZjUFYKTWFaeHp3blVtcjRFa2Y2RmY4WGI4Sk90ZWJUdWo4eDA4UWVaSFRnY3JJYitXdk9jVHJLTkFyeE1Ud0JHcnRRTwp0eWhxanJUSXE5SS9kZUNNeCt4RkNPSFVzdmNEa1FmRVVoZ21YWW5TVEdOU3poNmFmdlU5STFUVUNlWXRFeHlDCm5aaDlPd3hzcGFmcFhBRWdmdStTL0F6WFpLV255bjgyVHpGVTZnaFpFZnVDcndMd2JQRmlaS25ESm1mYlNWM1YKVGljTWdsSkNmZldsdk96OUN3eGtxQlRHNDZvUGZraFZVNElKS3pwekVXQXU2Q3lua09RalkvN2VDd1VFc1NWMQpwM0hZTXpNa05aRzlDNldSakd4VlF4NUo4djRuR1UzcXo2UTk4dz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
server: https://10.96.10.96:443/apis/authentication.k8s.io/v1/tokenreviews
name: guard-server
contexts:
- context:
cluster: guard-server
user: appscode@Github
name: webhook
current-context: webhook
kind: Config
preferences: {}
users:
- name: appscode@Github
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMyakNDQWNLZ0F3SUJBZ0lJQTZJZmR0dEIzTlV3RFFZSktvWklodmNOQVFFTEJRQXdEVEVMTUFrR0ExVUUKQXhNQ1kyRXdIaGNOTVRjd09ESTVNVFF5TXpNNFdoY05NVGd3T0RJNU1UUXlOREEwV2pBa01ROHdEUVlEVlFRSwpFd1pIYVhSb2RXSXhFVEFQQmdOVkJBTVRDR0Z3Y0hOamIyUmxNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DCkFROEFNSUlCQ2dLQ0FRRUE3NG5nc25IcldkeHovZUNWdEVwVUdVcmQ1dWkwSVhteGFkZlVuM3hpVTduZHdsYzgKc2loT1hLQ2pEaWM5cjZweW16MTJ5Ry93WCtZM1diOUU5a0VxQzg5L2oyR0ZrSFNVOU40VFlsQlZka0pSRUQ2dAoySjZpVnNPZE9BeE9MeDNidG5QR3RYNi9KRTZSTVFCLzhkcUYyenFUZm5ST3FFNFE0N01wL0NKYmdkcEpjbm9mCmdKVzN5Z2pJYk96WHhIZVNNcjlIclhveGRLbGFPVk1hU3BmY0RVREZrQXV1MEREZCszT3hwbG03TlNpS2JpbnUKM0d3VDc4YkRtNzZCTCtEOWhKeXB2OVZDTFkyMVB3WnB3ejJmaThYdzN2WDM3VVdPenA0OXlCMyttYnVjWkpGSgpCRTNORVJyZFVvWFhyeUJrdDhEdXp0SzhYM3dhOExGdmsvOWxWd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFCkJBTUNCYUF3RXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFFN0YKZkdpOWpDSzc0eGZZdmY3b3Byb1NxSVpoYmdyODVkcENCZ2FVbEhlK0ZJYkpVeWhnL2c2OVNCOUlhWitpTWYxNgpNWkJVTWs4Tmg5dUZWYWVQVUdCWG0vTUtBeGx0V0J0UHh0VFFMV0cycU9LbXczK3Z5UUJ4R2JMaytycndXVS9YCjR5SzcxbWc5ZG5GVXdWOGI2UWtwM1IxMVdCZzlCeHExU1RQL210S2NyNVVDS3ZWVmlEYlpobzRkRy9ZUHdMbEUKS1N4UGtqS3NPVU54dDlHZkdNTHVRMVFQWXZDYTZjZ1MxN3BERWZacWVqdmthc0UxeTNSQWpPa2pubTJ2KzIzbgpBN2kxYWwwMDZjTEpQdTl3S3IyMzhJQ0Q3N2ZxQzhTaXJhN3V3NUgxbkVvMTh1am94NmI2UG5XazdmeTZabDRHCjBWMXBCSDJtL1JqK0RudGVTM0k9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBNzRuZ3NuSHJXZHh6L2VDVnRFcFVHVXJkNXVpMElYbXhhZGZVbjN4aVU3bmR3bGM4CnNpaE9YS0NqRGljOXI2cHltejEyeUcvd1grWTNXYjlFOWtFcUM4OS9qMkdGa0hTVTlONFRZbEJWZGtKUkVENnQKMko2aVZzT2RPQXhPTHgzYnRuUEd0WDYvSkU2Uk1RQi84ZHFGMnpxVGZuUk9xRTRRNDdNcC9DSmJnZHBKY25vZgpnSlczeWdqSWJPelh4SGVTTXI5SHJYb3hkS2xhT1ZNYVNwZmNEVURGa0F1dTBERGQrM094cGxtN05TaUtiaW51CjNHd1Q3OGJEbTc2QkwrRDloSnlwdjlWQ0xZMjFQd1pwd3oyZmk4WHczdlgzN1VXT3pwNDl5QjMrbWJ1Y1pKRkoKQkUzTkVScmRVb1hYcnlCa3Q4RHV6dEs4WDN3YThMRnZrLzlsVndJREFRQUJBb0lCQVFDam9LdTlPZFJyTGd5TwpBRHhEVEFMbXhCMlEvcVVOdVBOWU9mY2tldk12L21kZHVmbmNPV3hPR2UxSVhjWGxtYWx3SWl4aC94VlViUTZpClgrWGIwZWZHNlpkWmVtU2lxUUNYeEp1NUxPYzBRVmplbi9KaFp2dStDU0g4aDJ0aEJDUnlIZVEvVnJWN043QTIKcVFDOVZXamF1TWpJT09zQ1RWRjhPWWNVbE9PdGJ2MFFRSUFNRDdxak1jcTdIRlJMbjlHSXJjSGVZWTd2RTdONQpucFdOMWZOT25BZXNnaVNRcGYxdGNYcmJUckNkb1JweExlU2RFUngyVnBkdFE1V3hFTm9YYURJT3FJVXB2anJaCjIwSUZqazY3eVVOTlBCLzJkU3VmZzVaekxEYWNGUy9lenYvUDVJYnVEazBHZWQyZGhkT2t3K2duVFNabjg0Sk4KMDg4TlMvVUJBb0dCQVBGOG44dEVmTURDNjlTc1RGWWh4NUc2aE1PWThlS0kxTDJQeTVVaEN4WCtXUlpoQndaVQpWaGhVMVpOcTgvUXkwb201WEQyT1UwR0tGQjY3aE9kU1l6TUc3a0NqKzl3bHZDM0loRmxLd2R1ZC8relBWTFkvCngxRjFtVnA3aTllZXZiZmdZdUQxdDRvTDVxc2lveldGZ2g2UndSZzVWTXpGd0N2WXZwUk9CcGZUQW9HQkFQM3YKUjNyRit1cW96YU9IcldrUjFEL3E5MHlRd3ZpamlRWDhyNEg3QVZTVVpnQmhwbEpmUDRTVU84NWdUbmhBLzl4ZQp3R1NTQzFGWkpVeDRmOW41MFN0dFlkNFhIMTZiU1lyOEpWQWxVRWY5QWR1czBkc1pKdkZLSEM5S3VjNEFPeUFPClYvUGR0Rk1FV2J5WERSQXdBTTVwNzZsU1pZVXA5cDFLVTZ6SndHM3RBb0dCQUlmdzdRK0RmV3NTRDZwSVdDekEKbFZUL0Y4LzRZR3B6TnJlRHBFcE9NS3h2NDN6S29DYTdBVUJ2T1Uva2pISnl6YnlFSVYzeHFnS2lGVk43b29TSwpCNWZwRmVSRHEvdXhMbTdqaTBXczVOYVo2a0ZJTWRycXFteTc4OWxRNVZjN1lIZUxsSDRwTk9vOGF0ejZBY0NXCmFMcUd1Sm5IWkdwbUJCbHF5Vlk1V2xMTEFvR0FPWVlBelVFWURCeGRLUlJOSmlZUnpNRHZjSHJDa0F5THQ3MTgKREpmTnYxazJtaE9FMTlnWHpYSys4WXREZTE1T0Y1K25PYUVUeTBQRWZVUTJ3aXdqUkJFdFFHQkFqTy9rZ3dXSApkbFpkajFFeklJNVBvN0JZOEFQM3lvYkUvSE4wOFZnT2VJSGFuWXU0d0UzL2VaRkdQWHdsL0ZkY0JBUnpoMElWCkhtazluQ2tDZ1lFQXJyNGQ3WFBUNlBvTTA5TjFSYnVtQnROUW96cGxpb0wwb0tqZUxHL0RHcUd5Q3lpcDVsNnMKUW5vblpPcW9BVzdqZlRiMThvVVVzVkJTdDJvd20zempac05XZFdZcEptL1ZCSDQvY0dOeFJuSXN1OFNsdFdBZAp1YjVZQS9YcnEvUTRNcUJnZEVwYm9HTnlzUVlscE0rMmxHZWpiZ0pDUTI4b3dJYndLQ3JSY2t3PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
Using Guard service name instead of IP in authentication webhook config file
So far, we have used a preset ClusterIP address in Guard service. This cluster ip was used in the authentication webhook config file and used by Kubernetes api server to connect to guard server.
It is possible to use Guard service name in authentication webhook config file so that Kubernetes api server connects to Guard using its domain name. This requires the following additional steps:
Since Kubernetes api server pod uses
HostNetwok
, change the DNS policy for Kubernetes api server toClusterFirstWithHostNet
. The actual process depends on your cluster provisioning process. Usually this involves updating the kube-apiserver manifest file in /etc/kubernetes/manifests folder in Master machines.When issuing server certificate for Guard server, provide the domain name so that it is included in CN/SANS for server cert.
$ guard init server --domains=guard.<namespace>.svc
- Now, pass the Guard service name when generating webhook config.
$ guard get webhook-config appscode -o github --addr=guard.<namespace>.svc:443
``